removed unused t_vb_arbprogram stage
authorBrian <brian@yutani.localnet.net>
Mon, 16 Apr 2007 17:03:14 +0000 (11:03 -0600)
committerBrian <brian@yutani.localnet.net>
Mon, 16 Apr 2007 17:03:14 +0000 (11:03 -0600)
src/mesa/tnl/t_vb_arbprogram.c [deleted file]
src/mesa/tnl/t_vb_arbprogram.h [deleted file]
src/mesa/tnl/t_vb_arbprogram_sse.c [deleted file]

diff --git a/src/mesa/tnl/t_vb_arbprogram.c b/src/mesa/tnl/t_vb_arbprogram.c
deleted file mode 100644 (file)
index 58c82cf..0000000
+++ /dev/null
@@ -1,1617 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.3
- *
- * Copyright (C) 1999-2007  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.
- */
-
-/**
- * \file t_arb_program.c
- * Compile vertex programs to an intermediate representation.
- * Execute vertex programs over a buffer of vertices.
- * \author Keith Whitwell, Brian Paul
- */
-
-#include "glheader.h"
-#include "context.h"
-#include "imports.h"
-#include "macros.h"
-#include "mtypes.h"
-#include "arbprogparse.h"
-#include "light.h"
-#include "program.h"
-#include "prog_instruction.h"
-#include "prog_parameter.h"
-#include "prog_statevars.h"
-#include "programopt.h"
-#include "math/m_matrix.h"
-#include "t_context.h"
-#include "t_pipeline.h"
-#include "t_vb_arbprogram.h"
-#include "tnl.h"
-
-
-#define DISASSEM 0
-
-
-struct compilation {
-   GLuint reg_active;
-   union instruction *csr;
-};
-
-
-#define ARB_VP_MACHINE(stage) ((struct arb_vp_machine *)(stage->privatePtr))
-
-#define PUFF(x) ((x)[1] = (x)[2] = (x)[3] = (x)[0])
-
-
-
-/* Lower precision functions for the EXP, LOG and LIT opcodes.  The
- * LOG2() implementation is probably not accurate enough, and the
- * attempted optimization for Exp2 is definitely not accurate
- * enough - it discards all of t's fractional bits!
- */
-static GLfloat RoughApproxLog2(GLfloat t)
-{
-   return LOG2(t);
-}
-
-static GLfloat RoughApproxExp2(GLfloat t)
-{   
-#if 0
-   fi_type fi;
-   fi.i = (GLint) t;
-   fi.i = (fi.i << 23) + 0x3f800000;
-   return fi.f;
-#else
-   return (GLfloat) _mesa_pow(2.0, t);
-#endif
-}
-
-static GLfloat RoughApproxPower(GLfloat x, GLfloat y)
-{
-   if (x == 0.0 && y == 0.0)
-      return 1.0;  /* spec requires this */
-   else
-      return RoughApproxExp2(y * RoughApproxLog2(x));
-}
-
-
-/* Higher precision functions for the EX2, LG2 and POW opcodes:
- */
-static GLfloat ApproxLog2(GLfloat t)
-{
-   return (GLfloat) (LOGF(t) * 1.442695F);
-}
-
-static GLfloat ApproxExp2(GLfloat t)
-{   
-   return (GLfloat) _mesa_pow(2.0, t);
-}
-
-static GLfloat ApproxPower(GLfloat x, GLfloat y)
-{
-   return (GLfloat) _mesa_pow(x, y);
-}
-
-
-/**
- * Perform a reduced swizzle:
- */
-static void do_RSW( struct arb_vp_machine *m, union instruction op ) 
-{
-   GLfloat *result = m->File[0][op.rsw.dst];
-   const GLfloat *arg0 = m->File[op.rsw.file0][op.rsw.idx0];
-   const GLuint swz = op.rsw.swz;
-   const GLuint neg = op.rsw.neg;
-   GLfloat tmp[4];
-
-   /* Need a temporary to be correct in the case where result == arg0.
-    */
-   COPY_4V(tmp, arg0);
-
-   result[0] = tmp[GET_SWZ(swz, 0)];
-   result[1] = tmp[GET_SWZ(swz, 1)];
-   result[2] = tmp[GET_SWZ(swz, 2)];
-   result[3] = tmp[GET_SWZ(swz, 3)];
-
-   if (neg) {
-      if (neg & 0x1) result[0] = -result[0];
-      if (neg & 0x2) result[1] = -result[1];
-      if (neg & 0x4) result[2] = -result[2];
-      if (neg & 0x8) result[3] = -result[3];
-   }
-}
-
-/**
- * Perform a full swizzle
- */
-static void do_SWZ( struct arb_vp_machine *m, union instruction op ) 
-{
-   GLfloat *result = m->File[0][op.rsw.dst];
-   const GLfloat *arg0 = m->File[op.rsw.file0][op.rsw.idx0];
-   const GLuint swz = op.rsw.swz;
-   const GLuint neg = op.rsw.neg;
-   GLfloat tmp[6];
-   tmp[4] = 0.0;
-   tmp[5] = 1.0;
-
-   /* Need a temporary to be correct in the case where result == arg0.
-    */
-   COPY_4V(tmp, arg0);
-
-   result[0] = tmp[GET_SWZ(swz, 0)];
-   result[1] = tmp[GET_SWZ(swz, 1)];
-   result[2] = tmp[GET_SWZ(swz, 2)];
-   result[3] = tmp[GET_SWZ(swz, 3)];
-
-   if (neg) {
-      if (neg & 0x1) result[0] = -result[0];
-      if (neg & 0x2) result[1] = -result[1];
-      if (neg & 0x4) result[2] = -result[2];
-      if (neg & 0x8) result[3] = -result[3];
-   }
-}
-
-/* Used to implement write masking.  To make things easier for the sse
- * generator I've gone back to a 1 argument version of this function
- * (dst.msk = arg), rather than the semantically cleaner (dst = SEL
- * arg0, arg1, msk)
- *
- * That means this is the only instruction which doesn't write a full
- * 4 dwords out.  This would make such a program harder to analyse,
- * but it looks like analysis is going to take place on a higher level
- * anyway.
- */
-static void do_MSK( struct arb_vp_machine *m, union instruction op )
-{
-   GLfloat *dst = m->File[0][op.msk.dst];
-   const GLfloat *arg = m->File[op.msk.file][op.msk.idx];
-   if (op.msk.mask & WRITEMASK_X) dst[0] = arg[0];
-   if (op.msk.mask & WRITEMASK_Y) dst[1] = arg[1];
-   if (op.msk.mask & WRITEMASK_Z) dst[2] = arg[2];
-   if (op.msk.mask & WRITEMASK_W) dst[3] = arg[3];
-}
-
-
-static void do_PRT( struct arb_vp_machine *m, union instruction op )
-{
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-   
-   _mesa_printf("%d: %f %f %f %f\n", m->vtx_nr, 
-               arg0[0], arg0[1], arg0[2], arg0[3]);
-}
-
-
-/**
- * The traditional ALU and texturing instructions.  All operate on
- * internal registers and ignore write masks and swizzling issues.
- */
-
-static void do_ABS( struct arb_vp_machine *m, union instruction op ) 
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-
-   result[0] = (arg0[0] < 0.0) ? -arg0[0] : arg0[0];
-   result[1] = (arg0[1] < 0.0) ? -arg0[1] : arg0[1];
-   result[2] = (arg0[2] < 0.0) ? -arg0[2] : arg0[2];
-   result[3] = (arg0[3] < 0.0) ? -arg0[3] : arg0[3];
-}
-
-static void do_ADD( struct arb_vp_machine *m, union instruction op )
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-   const GLfloat *arg1 = m->File[op.alu.file1][op.alu.idx1];
-
-   result[0] = arg0[0] + arg1[0];
-   result[1] = arg0[1] + arg1[1];
-   result[2] = arg0[2] + arg1[2];
-   result[3] = arg0[3] + arg1[3];
-}
-
-
-static void do_DP3( struct arb_vp_machine *m, union instruction op )
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-   const GLfloat *arg1 = m->File[op.alu.file1][op.alu.idx1];
-
-   result[0] = (arg0[0] * arg1[0] + 
-               arg0[1] * arg1[1] + 
-               arg0[2] * arg1[2]);
-
-   PUFF(result);
-}
-
-
-
-static void do_DP4( struct arb_vp_machine *m, union instruction op )
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-   const GLfloat *arg1 = m->File[op.alu.file1][op.alu.idx1];
-
-   result[0] = (arg0[0] * arg1[0] + 
-               arg0[1] * arg1[1] + 
-               arg0[2] * arg1[2] + 
-               arg0[3] * arg1[3]);
-
-   PUFF(result);
-}
-
-static void do_DPH( struct arb_vp_machine *m, union instruction op )
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-   const GLfloat *arg1 = m->File[op.alu.file1][op.alu.idx1];
-
-   result[0] = (arg0[0] * arg1[0] + 
-               arg0[1] * arg1[1] + 
-               arg0[2] * arg1[2] + 
-               1.0     * arg1[3]);
-   
-   PUFF(result);
-}
-
-static void do_DST( struct arb_vp_machine *m, union instruction op )
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-   const GLfloat *arg1 = m->File[op.alu.file1][op.alu.idx1];
-
-   /* This should be ok even if result == arg0 or result == arg1.
-    */
-   result[0] = 1.0F;
-   result[1] = arg0[1] * arg1[1];
-   result[2] = arg0[2];
-   result[3] = arg1[3];
-}
-
-
-/* Intended to be high precision:
- */
-static void do_EX2( struct arb_vp_machine *m, union instruction op ) 
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-
-   result[0] = ApproxExp2(arg0[0]);
-   PUFF(result);
-}
-
-
-/* Allowed to be lower precision:
- */
-static void do_EXP( struct arb_vp_machine *m, union instruction op )
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-   const GLfloat tmp = arg0[0];
-   const GLfloat flr_tmp = FLOORF(tmp);
-   const GLfloat frac_tmp = tmp - flr_tmp;
-
-   result[0] = LDEXPF(1.0, (int)flr_tmp);
-   result[1] = frac_tmp;
-   result[2] = RoughApproxExp2(tmp);
-   result[3] = 1.0F;
-}
-
-static void do_FLR( struct arb_vp_machine *m, union instruction op ) 
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-
-   result[0] = FLOORF(arg0[0]);
-   result[1] = FLOORF(arg0[1]);
-   result[2] = FLOORF(arg0[2]);
-   result[3] = FLOORF(arg0[3]);
-}
-
-static void do_FRC( struct arb_vp_machine *m, union instruction op ) 
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-
-   result[0] = arg0[0] - FLOORF(arg0[0]);
-   result[1] = arg0[1] - FLOORF(arg0[1]);
-   result[2] = arg0[2] - FLOORF(arg0[2]);
-   result[3] = arg0[3] - FLOORF(arg0[3]);
-}
-
-static void do_INT( struct arb_vp_machine *m, union instruction op ) 
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-
-   result[0] = (GLfloat) (GLint) arg0[0];
-   result[1] = (GLfloat) (GLint) arg0[1];
-   result[2] = (GLfloat) (GLint) arg0[2];
-   result[3] = (GLfloat) (GLint) arg0[3];
-}
-
-/* High precision log base 2:
- */
-static void do_LG2( struct arb_vp_machine *m, union instruction op ) 
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-
-   result[0] = ApproxLog2(arg0[0]);
-   PUFF(result);
-}
-
-
-
-static void do_LIT( struct arb_vp_machine *m, union instruction op )
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-   GLfloat tmp[4]; /* use temp in case arg0 == result register */
-
-   tmp[0] = 1.0;
-   tmp[1] = arg0[0];
-   if (arg0[0] > 0.0) {
-      tmp[2] = RoughApproxPower(arg0[1], arg0[3]);
-   }
-   else {
-      tmp[2] = 0.0;
-   }
-   tmp[3] = 1.0;
-
-   COPY_4V(result, tmp);
-}
-
-
-/* Intended to allow a lower precision than required for LG2 above.
- */
-static void do_LOG( struct arb_vp_machine *m, union instruction op )
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-   const GLfloat tmp = FABSF(arg0[0]);
-   int exponent;
-   const GLfloat mantissa = FREXPF(tmp, &exponent);
-
-   result[0] = (GLfloat) (exponent - 1);
-   result[1] = 2.0 * mantissa; /* map [.5, 1) -> [1, 2) */
-   result[2] = exponent + LOG2(mantissa);
-   result[3] = 1.0;
-}
-
-static void do_MAX( struct arb_vp_machine *m, union instruction op )
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-   const GLfloat *arg1 = m->File[op.alu.file1][op.alu.idx1];
-
-   result[0] = (arg0[0] > arg1[0]) ? arg0[0] : arg1[0];
-   result[1] = (arg0[1] > arg1[1]) ? arg0[1] : arg1[1];
-   result[2] = (arg0[2] > arg1[2]) ? arg0[2] : arg1[2];
-   result[3] = (arg0[3] > arg1[3]) ? arg0[3] : arg1[3];
-}
-
-
-static void do_MIN( struct arb_vp_machine *m, union instruction op )
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-   const GLfloat *arg1 = m->File[op.alu.file1][op.alu.idx1];
-
-   result[0] = (arg0[0] < arg1[0]) ? arg0[0] : arg1[0];
-   result[1] = (arg0[1] < arg1[1]) ? arg0[1] : arg1[1];
-   result[2] = (arg0[2] < arg1[2]) ? arg0[2] : arg1[2];
-   result[3] = (arg0[3] < arg1[3]) ? arg0[3] : arg1[3];
-}
-
-static void do_MOV( struct arb_vp_machine *m, union instruction op )
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-
-   result[0] = arg0[0];
-   result[1] = arg0[1];
-   result[2] = arg0[2];
-   result[3] = arg0[3];
-}
-
-static void do_MUL( struct arb_vp_machine *m, union instruction op )
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-   const GLfloat *arg1 = m->File[op.alu.file1][op.alu.idx1];
-
-   result[0] = arg0[0] * arg1[0];
-   result[1] = arg0[1] * arg1[1];
-   result[2] = arg0[2] * arg1[2];
-   result[3] = arg0[3] * arg1[3];
-}
-
-
-/* Intended to be "high" precision
- */
-static void do_POW( struct arb_vp_machine *m, union instruction op ) 
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-   const GLfloat *arg1 = m->File[op.alu.file1][op.alu.idx1];
-
-   result[0] = (GLfloat)ApproxPower(arg0[0], arg1[0]);
-   PUFF(result);
-}
-
-static void do_REL( struct arb_vp_machine *m, union instruction op )
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLuint idx = (op.alu.idx0 + (GLint)m->File[0][REG_ADDR][0]) & (MAX_NV_VERTEX_PROGRAM_PARAMS-1);
-   const GLfloat *arg0 = m->File[op.alu.file0][idx];
-
-   result[0] = arg0[0];
-   result[1] = arg0[1];
-   result[2] = arg0[2];
-   result[3] = arg0[3];
-}
-
-static void do_RCP( struct arb_vp_machine *m, union instruction op )
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-
-   result[0] = 1.0F / arg0[0];  
-   PUFF(result);
-}
-
-static void do_RSQ( struct arb_vp_machine *m, union instruction op )
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-
-   result[0] = INV_SQRTF(FABSF(arg0[0]));
-   PUFF(result);
-}
-
-
-static void do_SGE( struct arb_vp_machine *m, union instruction op )
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-   const GLfloat *arg1 = m->File[op.alu.file1][op.alu.idx1];
-
-   result[0] = (arg0[0] >= arg1[0]) ? 1.0F : 0.0F;
-   result[1] = (arg0[1] >= arg1[1]) ? 1.0F : 0.0F;
-   result[2] = (arg0[2] >= arg1[2]) ? 1.0F : 0.0F;
-   result[3] = (arg0[3] >= arg1[3]) ? 1.0F : 0.0F;
-}
-
-
-static void do_SLT( struct arb_vp_machine *m, union instruction op )
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-   const GLfloat *arg1 = m->File[op.alu.file1][op.alu.idx1];
-
-   result[0] = (arg0[0] < arg1[0]) ? 1.0F : 0.0F;
-   result[1] = (arg0[1] < arg1[1]) ? 1.0F : 0.0F;
-   result[2] = (arg0[2] < arg1[2]) ? 1.0F : 0.0F;
-   result[3] = (arg0[3] < arg1[3]) ? 1.0F : 0.0F;
-}
-
-static void do_SUB( struct arb_vp_machine *m, union instruction op ) 
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-   const GLfloat *arg1 = m->File[op.alu.file1][op.alu.idx1];
-
-   result[0] = arg0[0] - arg1[0];
-   result[1] = arg0[1] - arg1[1];
-   result[2] = arg0[2] - arg1[2];
-   result[3] = arg0[3] - arg1[3];
-}
-
-
-static void do_XPD( struct arb_vp_machine *m, union instruction op ) 
-{
-   GLfloat *result = m->File[0][op.alu.dst];
-   const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0];
-   const GLfloat *arg1 = m->File[op.alu.file1][op.alu.idx1];
-   GLfloat tmp[3];
-
-   tmp[0] = arg0[1] * arg1[2] - arg0[2] * arg1[1];
-   tmp[1] = arg0[2] * arg1[0] - arg0[0] * arg1[2];
-   tmp[2] = arg0[0] * arg1[1] - arg0[1] * arg1[0];
-
-   /* Need a temporary to be correct in the case where result == arg0
-    * or result == arg1.
-    */
-   result[0] = tmp[0];
-   result[1] = tmp[1];
-   result[2] = tmp[2];
-}
-
-static void do_NOP( struct arb_vp_machine *m, union instruction op ) 
-{
-}
-
-/* Some useful debugging functions:
- */
-static void print_mask( GLuint mask )
-{
-   _mesa_printf(".");
-   if (mask & WRITEMASK_X) _mesa_printf("x");
-   if (mask & WRITEMASK_Y) _mesa_printf("y");
-   if (mask & WRITEMASK_Z) _mesa_printf("z");
-   if (mask & WRITEMASK_W) _mesa_printf("w");
-}
-
-static void print_reg( GLuint file, GLuint reg )
-{
-   static const char *reg_file[] = {
-      "REG",
-      "LOCAL_PARAM",
-      "ENV_PARAM",
-      "STATE_VAR",
-   };
-
-   if (file == 0) {
-      if (reg == REG_RES) 
-        _mesa_printf("RES");
-      else if (reg >= REG_ARG0 && reg <= REG_ARG1)
-        _mesa_printf("ARG%d", reg - REG_ARG0);
-      else if (reg >= REG_TMP0 && reg <= REG_TMP11)
-        _mesa_printf("TMP%d", reg - REG_TMP0);
-      else if (reg >= REG_IN0 && reg <= REG_IN31)
-        _mesa_printf("IN%d", reg - REG_IN0);
-      else if (reg >= REG_OUT0 && reg <= REG_OUT23)
-        _mesa_printf("OUT%d", reg - REG_OUT0);
-      else if (reg == REG_ADDR)
-        _mesa_printf("ADDR");
-      else if (reg == REG_ID)
-        _mesa_printf("ID");
-      else
-        _mesa_printf("REG%d", reg);
-   }
-   else 
-      _mesa_printf("%s:%d", reg_file[file], reg);
-}
-
-
-static void print_RSW( union instruction op )
-{
-   GLuint swz = op.rsw.swz;
-   GLuint neg = op.rsw.neg;
-   GLuint i;
-
-   _mesa_printf("RSW ");
-   print_reg(0, op.rsw.dst);
-   _mesa_printf(", ");
-   print_reg(op.rsw.file0, op.rsw.idx0);
-   _mesa_printf(".");
-   for (i = 0; i < 4; i++, swz >>= 3) {
-      const char *cswz = "xyzw01";
-      if (neg & (1<<i))   
-        _mesa_printf("-");
-      _mesa_printf("%c", cswz[swz&0x7]);
-   }
-   _mesa_printf("\n");
-}
-
-static void print_SWZ( union instruction op )
-{
-   GLuint swz = op.rsw.swz;
-   GLuint neg = op.rsw.neg;
-   GLuint i;
-
-   _mesa_printf("SWZ ");
-   print_reg(0, op.rsw.dst);
-   _mesa_printf(", ");
-   print_reg(op.rsw.file0, op.rsw.idx0);
-   _mesa_printf(".");
-   for (i = 0; i < 4; i++, swz >>= 3) {
-      const char *cswz = "xyzw01";
-      if (neg & (1<<i))   
-        _mesa_printf("-");
-      _mesa_printf("%c", cswz[swz&0x7]);
-   }
-   _mesa_printf("\n");
-}
-
-
-static void print_ALU( union instruction op )
-{
-   _mesa_printf("%s ", _mesa_opcode_string((enum prog_opcode) op.alu.opcode));
-   print_reg(0, op.alu.dst);
-   _mesa_printf(", ");
-   print_reg(op.alu.file0, op.alu.idx0);
-   if (_mesa_num_inst_src_regs((enum prog_opcode) op.alu.opcode) > 1) {
-      _mesa_printf(", ");
-      print_reg(op.alu.file1, op.alu.idx1);
-   }
-   _mesa_printf("\n");
-}
-
-static void print_MSK( union instruction op )
-{
-   _mesa_printf("MSK ");
-   print_reg(0, op.msk.dst);
-   print_mask(op.msk.mask);
-   _mesa_printf(", ");
-   print_reg(op.msk.file, op.msk.idx);
-   _mesa_printf("\n");
-}
-
-static void print_NOP( union instruction op )
-{
-}
-
-void
-_tnl_disassem_vba_insn( union instruction op )
-{
-   switch (op.alu.opcode) {
-   case OPCODE_ABS:
-   case OPCODE_ADD:
-   case OPCODE_DP3:
-   case OPCODE_DP4:
-   case OPCODE_DPH:
-   case OPCODE_DST:
-   case OPCODE_EX2:
-   case OPCODE_EXP:
-   case OPCODE_FLR:
-   case OPCODE_FRC:
-   case OPCODE_INT:
-   case OPCODE_LG2:
-   case OPCODE_LIT:
-   case OPCODE_LOG:
-   case OPCODE_MAX:
-   case OPCODE_MIN:
-   case OPCODE_MOV:
-   case OPCODE_MUL:
-   case OPCODE_POW:
-   case OPCODE_PRINT:
-   case OPCODE_RCP:
-   case OPCODE_RSQ:
-   case OPCODE_SGE:
-   case OPCODE_SLT:
-   case OPCODE_SUB:
-   case OPCODE_XPD:
-      print_ALU(op);
-      break;
-   case OPCODE_ARA:
-   case OPCODE_ARL:
-   case OPCODE_ARL_NV:
-   case OPCODE_ARR:
-   case OPCODE_BRA:
-   case OPCODE_CAL:
-   case OPCODE_END:
-   case OPCODE_MAD:
-   case OPCODE_POPA:
-   case OPCODE_PUSHA:
-   case OPCODE_RCC:
-   case OPCODE_RET:
-   case OPCODE_SSG:
-      print_NOP(op);
-      break;
-   case OPCODE_SWZ:
-      print_SWZ(op);
-      break;
-   case RSW:
-      print_RSW(op);
-      break;
-   case MSK:
-      print_MSK(op);
-      break;
-   case REL:
-      print_ALU(op);
-      break;
-   default:
-      _mesa_problem(NULL, "Bad opcode in _tnl_disassem_vba_insn()");
-   }
-}
-
-typedef void (*gpu_function)(struct arb_vp_machine *m, union instruction op);
-
-static gpu_function opcode_func[MAX_OPCODE+3] =
-{
-   do_NOP,
-   do_ABS,
-   do_ADD,
-   do_NOP,/*ARA*/
-   do_NOP,/*ARL*/
-   do_NOP,/*ARL_NV*/
-   do_NOP,/*ARR*/
-   do_NOP,/*BGNLOOP*/
-   do_NOP,/*BGNSUB*/
-   do_NOP,/*BRA*/
-   do_NOP,/*BRK*/
-   do_NOP,/*CAL*/
-   do_NOP,/*CMP*/
-   do_NOP,/*CONT*/
-   do_NOP,/*COS*/
-   do_NOP,/*DDX*/
-   do_NOP,/*DDY*/
-   do_DP3,
-   do_DP4,
-   do_DPH,
-   do_DST,
-   do_NOP,/*ELSE*/
-   do_NOP,/*END*/
-   do_NOP,/*ENDIF*/
-   do_NOP,/*ENDLOOP*/
-   do_NOP,/*ENDSUB*/
-   do_EX2,
-   do_EXP,
-   do_FLR,
-   do_FRC,
-   do_NOP,/*IF*/
-   do_INT,
-   do_NOP,/*KIL*/
-   do_NOP,/*KIL_NV*/
-   do_LG2,
-   do_LIT,
-   do_LOG,
-   do_NOP,/*LRP*/
-   do_NOP,/*MAD*/
-   do_MAX,
-   do_MIN,
-   do_MOV,
-   do_MUL,
-   do_NOP,/*NOISE1*/
-   do_NOP,/*NOISE2*/
-   do_NOP,/*NOISE3*/
-   do_NOP,/*NOISE4*/
-   do_NOP,/*PK2H*/
-   do_NOP,/*PK2US*/
-   do_NOP,/*PK4B*/
-   do_NOP,/*PK4UB*/
-   do_POW,
-   do_NOP,/*POPA*/
-   do_PRT,
-   do_NOP,/*PUSHA*/
-   do_NOP,/*RCC*/
-   do_RCP,/*RCP*/
-   do_NOP,/*RET*/
-   do_NOP,/*RFL*/
-   do_RSQ,
-   do_NOP,/*SCS*/
-   do_NOP,/*SEQ*/
-   do_NOP,/*SFL*/
-   do_SGE,
-   do_NOP,/*SGT*/
-   do_NOP,/*SIN*/
-   do_NOP,/*SLE*/
-   do_SLT,
-   do_NOP,/*SNE*/
-   do_NOP,/*SSG*/
-   do_NOP,/*STR*/
-   do_SUB,
-   do_SWZ,/*SWZ*/
-   do_NOP,/*TEX*/
-   do_NOP,/*TXB*/
-   do_NOP,/*TXD*/
-   do_NOP,/*TXL*/
-   do_NOP,/*TXP*/
-   do_NOP,/*TXP_NV*/
-   do_NOP,/*UP2H*/
-   do_NOP,/*UP2US*/
-   do_NOP,/*UP4B*/
-   do_NOP,/*UP4UB*/
-   do_NOP,/*X2D*/
-   do_XPD,
-   do_RSW,
-   do_MSK,
-   do_REL,
-};
-
-static union instruction *cvp_next_instruction( struct compilation *cp )
-{
-   union instruction *op = cp->csr++;
-   _mesa_bzero(op, sizeof(*op));
-   return op;
-}
-
-static struct reg cvp_make_reg( GLuint file, GLuint idx )
-{
-   struct reg reg;
-   reg.file = file;
-   reg.idx = idx;
-   return reg;
-}
-
-static struct reg cvp_emit_rel( struct compilation *cp,
-                               struct reg reg,
-                               struct reg tmpreg )
-{
-   union instruction *op = cvp_next_instruction(cp);
-   op->alu.opcode = REL;
-   op->alu.file0 = reg.file;
-   op->alu.idx0 = reg.idx;
-   op->alu.dst = tmpreg.idx;
-   return tmpreg;
-}
-
-
-static struct reg cvp_load_reg( struct compilation *cp,
-                               GLuint file,
-                               GLuint index,
-                               GLuint rel,
-                               GLuint tmpidx )
-{
-   struct reg tmpreg = cvp_make_reg(FILE_REG, tmpidx);
-   struct reg reg;
-
-   switch (file) {
-   case PROGRAM_TEMPORARY:
-      assert(REG_TMP0 + index <= REG_TMP11);
-      return cvp_make_reg(FILE_REG, REG_TMP0 + index);
-
-   case PROGRAM_INPUT:
-      return cvp_make_reg(FILE_REG, REG_IN0 + index);
-
-   case PROGRAM_OUTPUT:
-      return cvp_make_reg(FILE_REG, REG_OUT0 + index);
-
-      /* These two aren't populated by the parser?
-       */
-   case PROGRAM_LOCAL_PARAM: 
-      reg = cvp_make_reg(FILE_LOCAL_PARAM, index);
-      if (rel) 
-        return cvp_emit_rel(cp, reg, tmpreg);
-      else
-        return reg;
-
-   case PROGRAM_ENV_PARAM: 
-      reg = cvp_make_reg(FILE_ENV_PARAM, index);
-      if (rel) 
-        return cvp_emit_rel(cp, reg, tmpreg);
-      else
-        return reg;
-
-   case PROGRAM_STATE_VAR:
-   case PROGRAM_CONSTANT:
-   case PROGRAM_UNIFORM:
-      reg = cvp_make_reg(FILE_STATE_PARAM, index);
-      if (rel) 
-        return cvp_emit_rel(cp, reg, tmpreg);
-      else
-        return reg;
-
-      /* Invalid values:
-       */
-   case PROGRAM_WRITE_ONLY:
-   case PROGRAM_ADDRESS:
-   default:
-      _mesa_problem(NULL, "Invalid register file %d in cvp_load_reg()", file);
-      assert(0);
-      return tmpreg;           /* can't happen */
-   }
-}
-
-static struct reg cvp_emit_arg( struct compilation *cp,
-                               const struct prog_src_register *src,
-                               GLuint arg )
-{
-   struct reg reg = cvp_load_reg( cp, src->File, src->Index, src->RelAddr, arg );
-   union instruction rsw, noop;
-
-   /* Emit any necessary swizzling.  
-    */
-   _mesa_bzero(&rsw, sizeof(rsw));
-   rsw.rsw.neg = src->NegateBase ? WRITEMASK_XYZW : 0;
-
-   /* we're expecting 2-bit swizzles below... */
-#if 1 /* XXX THESE ASSERTIONS CURRENTLY FAIL DURING GLEAN TESTS! */
-/* hopefully no longer happens? */
-   ASSERT(GET_SWZ(src->Swizzle, 0) < 4);
-   ASSERT(GET_SWZ(src->Swizzle, 1) < 4);
-   ASSERT(GET_SWZ(src->Swizzle, 2) < 4);
-   ASSERT(GET_SWZ(src->Swizzle, 3) < 4);
-#endif
-   rsw.rsw.swz = src->Swizzle;
-
-   _mesa_bzero(&noop, sizeof(noop));
-   noop.rsw.neg = 0;
-   noop.rsw.swz = SWIZZLE_NOOP;
-
-   if (_mesa_memcmp(&rsw, &noop, sizeof(rsw)) !=0) {
-      union instruction *op = cvp_next_instruction(cp);
-      struct reg rsw_reg = cvp_make_reg(FILE_REG, REG_ARG0 + arg);
-      *op = rsw;
-      op->rsw.opcode = RSW;
-      op->rsw.file0 = reg.file;
-      op->rsw.idx0 = reg.idx;
-      op->rsw.dst = rsw_reg.idx;
-      return rsw_reg;
-   }
-   else
-      return reg;
-}
-
-static GLuint cvp_choose_result( struct compilation *cp,
-                                const struct prog_dst_register *dst,
-                                union instruction *fixup )
-{
-   GLuint mask = dst->WriteMask;
-   GLuint idx;
-
-   switch (dst->File) {
-   case PROGRAM_TEMPORARY:
-      idx = REG_TMP0 + dst->Index;
-      break;
-   case PROGRAM_OUTPUT:
-      idx = REG_OUT0 + dst->Index;
-      break;
-   default:
-#if 0
-      /* IF/ELSE/ENDIF instructions will hit this */
-      assert(0);
-#endif
-      return REG_RES;          /* can't happen */
-   }
-
-   /* Optimization: When writing (with a writemask) to an undefined
-    * value for the first time, the writemask may be ignored. 
-    */
-   if (mask != WRITEMASK_XYZW && (cp->reg_active & (1 << idx))) {
-      fixup->msk.opcode = MSK;
-      fixup->msk.dst = idx;
-      fixup->msk.file = FILE_REG;
-      fixup->msk.idx = REG_RES;
-      fixup->msk.mask = mask;
-      cp->reg_active |= 1 << idx;
-      return REG_RES;
-   }
-   else {
-      _mesa_bzero(fixup, sizeof(*fixup));
-      cp->reg_active |= 1 << idx;
-      return idx;
-   }
-}
-
-
-static void cvp_emit_inst( struct compilation *cp,
-                          const struct prog_instruction *inst )
-{
-   union instruction *op;
-   union instruction fixup;
-   struct reg reg[3];
-   GLuint result, nr_args, i;
-
-   /* Need to handle SWZ, ARL specially.
-    */
-   switch (inst->Opcode) {
-      /* Split into mul and add:
-       */
-   case OPCODE_MAD:
-      result = cvp_choose_result( cp, &inst->DstReg, &fixup );
-      for (i = 0; i < 3; i++) 
-        reg[i] = cvp_emit_arg( cp, &inst->SrcReg[i], REG_ARG0+i );
-
-      op = cvp_next_instruction(cp);
-      op->alu.opcode = OPCODE_MUL;
-      op->alu.file0 = reg[0].file;
-      op->alu.idx0 = reg[0].idx;
-      op->alu.file1 = reg[1].file;
-      op->alu.idx1 = reg[1].idx;
-      op->alu.dst = REG_ARG0;
-
-      op = cvp_next_instruction(cp);
-      op->alu.opcode = OPCODE_ADD;
-      op->alu.file0 = FILE_REG;
-      op->alu.idx0 = REG_ARG0;
-      op->alu.file1 = reg[2].file;
-      op->alu.idx1 = reg[2].idx;
-      op->alu.dst = result;
-
-      if (result == REG_RES) {
-        op = cvp_next_instruction(cp);
-        *op = fixup;
-      }
-      break;
-
-   case OPCODE_ARL:
-      reg[0] = cvp_emit_arg( cp, &inst->SrcReg[0], REG_ARG0 );
-
-      op = cvp_next_instruction(cp);
-      op->alu.opcode = OPCODE_FLR;
-      op->alu.dst = REG_ADDR;
-      op->alu.file0 = reg[0].file;
-      op->alu.idx0 = reg[0].idx;
-      break;
-
-   case OPCODE_END:
-      break;
-
-   case OPCODE_SWZ:
-      result = cvp_choose_result( cp, &inst->DstReg, &fixup );
-      reg[0] = cvp_load_reg( cp, inst->SrcReg[0].File,
-                       inst->SrcReg[0].Index, inst->SrcReg[0].RelAddr, REG_ARG0 );
-      op = cvp_next_instruction(cp);
-      op->rsw.opcode = inst->Opcode;
-      op->rsw.file0 = reg[0].file;
-      op->rsw.idx0 = reg[0].idx;
-      op->rsw.dst = result;
-      op->rsw.swz = inst->SrcReg[0].Swizzle;
-      op->rsw.neg = inst->SrcReg[0].NegateBase;
-
-      if (result == REG_RES) {
-        op = cvp_next_instruction(cp);
-        *op = fixup;
-      }
-      break;
-
-   case OPCODE_NOP:
-      break;
-
-   case OPCODE_BRA:
-      /* XXX implement */
-      break;
-
-   default:
-      result = cvp_choose_result( cp, &inst->DstReg, &fixup );
-      nr_args = _mesa_num_inst_src_regs(inst->Opcode);
-      for (i = 0; i < nr_args; i++) 
-        reg[i] = cvp_emit_arg( cp, &inst->SrcReg[i], REG_ARG0 + i );
-
-      op = cvp_next_instruction(cp);
-      op->alu.opcode = inst->Opcode;
-      op->alu.file0 = reg[0].file;
-      op->alu.idx0 = reg[0].idx;
-      op->alu.file1 = reg[1].file;
-      op->alu.idx1 = reg[1].idx;
-      op->alu.dst = result;
-
-      if (result == REG_RES) {
-        op = cvp_next_instruction(cp);
-        *op = fixup;
-      }
-      break;
-   }
-}
-
-static void free_tnl_data( struct gl_vertex_program *program  )
-{
-   struct tnl_compiled_program *p = (struct tnl_compiled_program *) program->TnlData;
-   if (p->compiled_func)
-      _mesa_free((void *)p->compiled_func);
-   _mesa_free(p);
-   program->TnlData = NULL;
-}
-
-static void compile_vertex_program( struct gl_vertex_program *program,
-                                   GLboolean try_codegen )
-{ 
-   struct compilation cp;
-   struct tnl_compiled_program *p = CALLOC_STRUCT(tnl_compiled_program);
-   GLint i;
-
-#if 1
-   if (!program->IsNVProgram && program->IsPositionInvariant) {
-      printf("Adding MVP code\n");
-      if (!program->Base.Parameters)
-         program->Base.Parameters = _mesa_new_parameter_list();
-      _mesa_insert_mvp_code(NULL, program);
-      program->IsPositionInvariant = 0;
-   }
-#endif
-
-   if (program->TnlData) 
-      free_tnl_data( program );
-   
-   program->TnlData = p;
-
-   /* Initialize cp.  Note that ctx and VB aren't used in compilation
-    * so we don't have to worry about statechanges:
-    */
-   _mesa_memset(&cp, 0, sizeof(cp));
-   cp.csr = p->instructions;
-
-   /* Compile instructions:
-    */
-   for (i = 0; i < program->Base.NumInstructions; i++) {
-      cvp_emit_inst(&cp, &program->Base.Instructions[i]);
-   }
-
-   /* Finish up:
-    */
-   p->nr_instructions = cp.csr - p->instructions;
-
-   /* Print/disassemble:
-    */
-   if (DISASSEM) {
-      for (i = 0; i < p->nr_instructions; i++) {
-        _tnl_disassem_vba_insn(p->instructions[i]);
-      }
-      _mesa_printf("\n\n");
-   }
-   
-#ifdef USE_SSE_ASM
-   if (try_codegen)
-      _tnl_sse_codegen_vertex_program(p);
-#endif
-
-}
-
-
-
-/* ----------------------------------------------------------------------
- * Execution
- */
-static void userclip( GLcontext *ctx,
-                     GLvector4f *clip,
-                     GLubyte *clipmask,
-                     GLubyte *clipormask,
-                     GLubyte *clipandmask )
-{
-   GLuint p;
-
-   for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
-      if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
-        GLuint nr, i;
-        const GLfloat a = ctx->Transform._ClipUserPlane[p][0];
-        const GLfloat b = ctx->Transform._ClipUserPlane[p][1];
-        const GLfloat c = ctx->Transform._ClipUserPlane[p][2];
-        const GLfloat d = ctx->Transform._ClipUserPlane[p][3];
-         GLfloat *coord = (GLfloat *)clip->data;
-         GLuint stride = clip->stride;
-         GLuint count = clip->count;
-
-        for (nr = 0, i = 0 ; i < count ; i++) {
-           GLfloat dp = (coord[0] * a + 
-                         coord[1] * b +
-                         coord[2] * c +
-                         coord[3] * d);
-
-           if (dp < 0) {
-              nr++;
-              clipmask[i] |= CLIP_USER_BIT;
-           }
-
-           STRIDE_F(coord, stride);
-        }
-
-        if (nr > 0) {
-           *clipormask |= CLIP_USER_BIT;
-           if (nr == count) {
-              *clipandmask |= CLIP_USER_BIT;
-              return;
-           }
-        }
-      }
-   }
-}
-
-
-static GLboolean
-do_ndc_cliptest(GLcontext *ctx, struct arb_vp_machine *m)
-{
-   TNLcontext *tnl = TNL_CONTEXT(ctx);
-   struct vertex_buffer *VB = m->VB;
-
-   /* Cliptest and perspective divide.  Clip functions must clear
-    * the clipmask.
-    */
-   m->ormask = 0;
-   m->andmask = CLIP_FRUSTUM_BITS;
-
-   if (tnl->NeedNdcCoords) {
-      VB->NdcPtr =
-         _mesa_clip_tab[VB->ClipPtr->size]( VB->ClipPtr,
-                                            &m->ndcCoords,
-                                            m->clipmask,
-                                            &m->ormask,
-                                            &m->andmask );
-   }
-   else {
-      VB->NdcPtr = NULL;
-      _mesa_clip_np_tab[VB->ClipPtr->size]( VB->ClipPtr,
-                                            NULL,
-                                            m->clipmask,
-                                            &m->ormask,
-                                            &m->andmask );
-   }
-
-   if (m->andmask) {
-      /* All vertices are outside the frustum */
-      return GL_FALSE;
-   }
-
-   /* Test userclip planes.  This contributes to VB->ClipMask.
-    */
-   /** XXX NEW_SLANG _Enabled ??? */
-   if (ctx->Transform.ClipPlanesEnabled && (!ctx->VertexProgram._Enabled ||
-      ctx->VertexProgram.Current->IsPositionInvariant)) {
-      userclip( ctx,
-               VB->ClipPtr,
-               m->clipmask,
-               &m->ormask,
-               &m->andmask );
-
-      if (m->andmask) {
-        return GL_FALSE;
-      }
-   }
-
-   VB->ClipAndMask = m->andmask;
-   VB->ClipOrMask = m->ormask;
-   VB->ClipMask = m->clipmask;
-
-   return GL_TRUE;
-}
-
-
-static INLINE void call_func( struct tnl_compiled_program *p,
-                             struct arb_vp_machine *m )
-{
-   p->compiled_func(m);
-}
-
-
-/**
- * Execute the given vertex program.  
- * 
- * TODO: Integrate the t_vertex.c code here, to build machine vertices
- * directly at this point.
- *
- * TODO: Eliminate the VB struct entirely and just use
- * struct arb_vertex_machine.
- */
-static GLboolean
-run_arb_vertex_program(GLcontext *ctx, struct tnl_pipeline_stage *stage)
-{
-   const struct gl_vertex_program *program = ctx->VertexProgram._Current;
-   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
-   struct arb_vp_machine *m = ARB_VP_MACHINE(stage);
-   struct tnl_compiled_program *p;
-   GLuint i, j;
-   GLbitfield outputs;
-
-#define FORCE_PROG_EXECUTE_C 1
-#if FORCE_PROG_EXECUTE_C
-   return GL_TRUE;   
-#else
-   if (!program)
-      return GL_TRUE;   
-#endif
-
-   if (program->Base.Parameters) {
-      _mesa_load_state_parameters(ctx, program->Base.Parameters);
-   }   
-   
-   p = (struct tnl_compiled_program *)program->TnlData;
-   assert(p);
-
-
-   m->nr_inputs = m->nr_outputs = 0;
-
-   for (i = 0; i < VERT_ATTRIB_MAX; i++) {
-      if (program->Base.InputsRead & (1<<i)) {
-        GLuint j = m->nr_inputs++;
-        m->input[j].idx = i;
-        m->input[j].data = (GLfloat *)m->VB->AttribPtr[i]->data;
-        m->input[j].stride = m->VB->AttribPtr[i]->stride;
-        m->input[j].size = m->VB->AttribPtr[i]->size;
-        ASSIGN_4V(m->File[0][REG_IN0 + i], 0, 0, 0, 1);
-      }
-   }
-
-   for (i = 0; i < VERT_RESULT_MAX; i++) {
-      if (program->Base.OutputsWritten & (1 << i)) {
-        GLuint j = m->nr_outputs++;
-        m->output[j].idx = i;
-        m->output[j].data = (GLfloat *)m->attribs[i].data;
-      }
-   }
-
-
-   /* Run the actual program:
-    */
-   for (m->vtx_nr = 0; m->vtx_nr < VB->Count; m->vtx_nr++) {
-      for (j = 0; j < m->nr_inputs; j++) {
-        GLuint idx = REG_IN0 + m->input[j].idx;
-        switch (m->input[j].size) {
-        case 4: m->File[0][idx][3] = m->input[j].data[3];
-        case 3: m->File[0][idx][2] = m->input[j].data[2];
-        case 2: m->File[0][idx][1] = m->input[j].data[1];
-        case 1: m->File[0][idx][0] = m->input[j].data[0];
-        }
-#if 0
-         printf("  attr %d/%d: %g %g %g %g\n", j, idx-REG_IN0,
-                m->input[j].data[0],
-                m->input[j].data[1],
-                m->input[j].data[2],
-                m->input[j].data[3]);
-#endif
-        STRIDE_F(m->input[j].data, m->input[j].stride);
-      }
-
-
-      if (p->compiled_func) {
-        call_func( p, m );
-      }
-      else {
-         GLint pc;
-        for (pc = 0; pc < p->nr_instructions; pc++) {
-           union instruction inst = p->instructions[pc];        
-           opcode_func[inst.alu.opcode]( m, inst );
-        }
-      }
-
-      for (j = 0; j < m->nr_outputs; j++) {
-        GLuint idx = REG_OUT0 + m->output[j].idx;
-        m->output[j].data[0] = m->File[0][idx][0];
-        m->output[j].data[1] = m->File[0][idx][1];
-        m->output[j].data[2] = m->File[0][idx][2];
-        m->output[j].data[3] = m->File[0][idx][3];
-        m->output[j].data += 4;
-      }
-
-   }
-
-   /* Setup the VB pointers so that the next pipeline stages get
-    * their data from the right place (the program output arrays).
-    *
-    * TODO: 1) Have tnl use these RESULT values for outputs rather
-    * than trying to shoe-horn inputs and outputs into one set of
-    * values.
-    *
-    * TODO: 2) Integrate t_vertex.c so that we just go straight ahead
-    * and build machine vertices here.
-    */
-
-   /* XXX There seems to be confusion between using the VERT_ATTRIB_*
-    * values vs _TNL_ATTRIB_* tokens here:
-    */
-   outputs = program->Base.OutputsWritten;
-
-   if (program->IsPositionInvariant) {
-      /* We need the exact same transform as in the fixed function path here
-         to guarantee invariance, depending on compiler optimization flags results
-         could be different otherwise */
-      VB->ClipPtr = TransformRaw( &m->attribs[0],
-                                 &ctx->_ModelProjectMatrix,
-                                 m->VB->AttribPtr[0] );
-
-      /* Drivers expect this to be clean to element 4...
-       */
-      switch (VB->ClipPtr->size) {
-      case 1:
-        /* impossible */
-      case 2:
-        _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 );
-        /* fall-through */
-      case 3:
-        _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 );
-        /* fall-through */
-      case 4:
-        break;
-      }
-   }
-   else {
-      VB->ClipPtr = &m->attribs[VERT_RESULT_HPOS];
-      VB->ClipPtr->count = VB->Count;
-   }
-
-   if (outputs & (1<<VERT_RESULT_COL0)) {
-      VB->ColorPtr[0] =
-      VB->AttribPtr[VERT_ATTRIB_COLOR0] = &m->attribs[VERT_RESULT_COL0];
-   }
-
-   if (outputs & (1<<VERT_RESULT_BFC0)) {
-      VB->ColorPtr[1] = &m->attribs[VERT_RESULT_BFC0];
-   }
-
-   if (outputs & (1<<VERT_RESULT_COL1)) {
-      VB->SecondaryColorPtr[0] =
-      VB->AttribPtr[VERT_ATTRIB_COLOR1] = &m->attribs[VERT_RESULT_COL1];
-   }
-
-   if (outputs & (1<<VERT_RESULT_BFC1)) {
-      VB->SecondaryColorPtr[1] = &m->attribs[VERT_RESULT_BFC1];
-   }
-
-   if (outputs & (1<<VERT_RESULT_FOGC)) {
-      VB->FogCoordPtr =
-      VB->AttribPtr[VERT_ATTRIB_FOG] = &m->attribs[VERT_RESULT_FOGC];
-   }
-
-   if (outputs & (1<<VERT_RESULT_PSIZ)) {
-      VB->AttribPtr[_TNL_ATTRIB_POINTSIZE] = &m->attribs[VERT_RESULT_PSIZ];
-   }
-
-   for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
-      if (outputs & (1<<(VERT_RESULT_TEX0+i))) {
-        VB->TexCoordPtr[i] =
-        VB->AttribPtr[VERT_ATTRIB_TEX0+i] = &m->attribs[VERT_RESULT_TEX0 + i];
-      }
-   }
-
-   for (i = 0; i < ctx->Const.MaxVarying; i++) {
-      if (outputs & (1 << (VERT_RESULT_VAR0 + i))) {
-         /* Note: varying results get put into the generic attributes */
-        VB->AttribPtr[VERT_ATTRIB_GENERIC0+i]
-            = &m->attribs[VERT_RESULT_VAR0 + i];
-      }
-   }
-
-#if 0
-   for (i = 0; i < VB->Count; i++) {
-      printf("Out %d: %f %f %f %f %f %f %f %f\n", i,
-            VEC_ELT(VB->ClipPtr, GLfloat, i)[0],
-            VEC_ELT(VB->ClipPtr, GLfloat, i)[1],
-            VEC_ELT(VB->ClipPtr, GLfloat, i)[2],
-            VEC_ELT(VB->ClipPtr, GLfloat, i)[3],
-            VEC_ELT(VB->AttribPtr[VERT_ATTRIB_TEX0], GLfloat, i)[0],
-            VEC_ELT(VB->AttribPtr[VERT_ATTRIB_TEX0], GLfloat, i)[1],
-            VEC_ELT(VB->AttribPtr[VERT_ATTRIB_TEX0], GLfloat, i)[2],
-            VEC_ELT(VB->AttribPtr[VERT_ATTRIB_TEX0], GLfloat, i)[3]);
-   }
-#endif
-
-   /* Perform NDC and cliptest operations:
-    */
-   return do_ndc_cliptest(ctx, m);
-}
-
-
-static void
-validate_vertex_program( GLcontext *ctx, struct tnl_pipeline_stage *stage )
-{
-   struct arb_vp_machine *m = ARB_VP_MACHINE(stage);
-   struct gl_vertex_program *program = ctx->VertexProgram._Current;
-
-   /* don't use this module since it only handles 12 temp regs */
-   /* Need to allocate more bits for register indexes, etc. */
-#define  FORCE_OLD 1
-#if FORCE_OLD
-   if (0) {
-#else
-   if (program) {
-#endif
-      if (!program->TnlData)
-        compile_vertex_program( program, m->try_codegen );
-      
-      /* Grab the state GL state and put into registers:
-       */
-      m->File[FILE_LOCAL_PARAM] = program->Base.LocalParams;
-      m->File[FILE_ENV_PARAM] = ctx->VertexProgram.Parameters;
-      /* GL_NV_vertex_programs can't reference GL state */
-      if (program->Base.Parameters)
-         m->File[FILE_STATE_PARAM] = program->Base.Parameters->ParameterValues;
-      else
-         m->File[FILE_STATE_PARAM] = NULL;
-   }
-}
-
-
-/**
- * Called the first time stage->run is called.  In effect, don't
- * allocate data until the first time the stage is run.
- */
-static GLboolean init_vertex_program( GLcontext *ctx,
-                                     struct tnl_pipeline_stage *stage )
-{
-   TNLcontext *tnl = TNL_CONTEXT(ctx);
-   struct vertex_buffer *VB = &(tnl->vb);
-   struct arb_vp_machine *m;
-   const GLuint size = VB->Size;
-   GLuint i;
-
-   /* spot checks to be sure the opcode table is correct */
-   assert(opcode_func[OPCODE_SGE] == do_SGE);
-   assert(opcode_func[OPCODE_XPD] == do_XPD);
-
-   stage->privatePtr = _mesa_calloc(sizeof(*m));
-   m = ARB_VP_MACHINE(stage);
-   if (!m)
-      return GL_FALSE;
-
-   /* arb_vertex_machine struct should subsume the VB:
-    */
-   m->VB = VB;
-
-   m->File[0] = (GLfloat(*)[4])ALIGN_MALLOC(REG_MAX * sizeof(GLfloat) * 4, 16);
-
-   /* Initialize regs where necessary:
-    */
-   ASSIGN_4V(m->File[0][REG_ID], 0, 0, 0, 1);
-   ASSIGN_4V(m->File[0][REG_ONES], 1, 1, 1, 1);
-   ASSIGN_4V(m->File[0][REG_SWZ], 1, -1, 0, 0);
-   ASSIGN_4V(m->File[0][REG_NEG], -1, -1, -1, -1);
-   ASSIGN_4V(m->File[0][REG_LIT], 1, 0, 0, 1);
-   ASSIGN_4V(m->File[0][REG_LIT2], 1, .5, .2, 1); /* debug value */
-
-   if (_mesa_getenv("MESA_EXPERIMENTAL"))
-      m->try_codegen = GL_TRUE;
-
-   /* Allocate arrays of vertex output values */
-   for (i = 0; i < VERT_RESULT_MAX; i++) {
-      _mesa_vector4f_alloc( &m->attribs[i], 0, size, 32 );
-      m->attribs[i].size = 4;
-   }
-
-   /* a few other misc allocations */
-   _mesa_vector4f_alloc( &m->ndcCoords, 0, size, 32 );
-   m->clipmask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte)*size, 32 );
-
-   if (ctx->VertexProgram._MaintainTnlProgram)
-      _mesa_allow_light_in_model( ctx, GL_FALSE );
-
-   m->fpucntl_rnd_neg = RND_NEG_FPU; /* const value */
-   m->fpucntl_restore = RESTORE_FPU; /* const value */
-
-   return GL_TRUE;
-}
-
-
-/**
- * Destructor for this pipeline stage.
- */
-static void dtr( struct tnl_pipeline_stage *stage )
-{
-   struct arb_vp_machine *m = ARB_VP_MACHINE(stage);
-
-   if (m) {
-      GLuint i;
-
-      /* free the vertex program result arrays */
-      for (i = 0; i < VERT_RESULT_MAX; i++)
-         _mesa_vector4f_free( &m->attribs[i] );
-
-      /* free misc arrays */
-      _mesa_vector4f_free( &m->ndcCoords );
-      ALIGN_FREE( m->clipmask );
-      ALIGN_FREE( m->File[0] );
-
-      _mesa_free( m );
-      stage->privatePtr = NULL;
-   }
-}
-
-
-/**
- * Public description of this pipeline stage.
- */
-const struct tnl_pipeline_stage _tnl_arb_vertex_program_stage =
-{
-   "arb-vertex-program",
-   NULL,                       /* private_data */
-   init_vertex_program,                /* create */
-   dtr,                                /* destroy */
-   validate_vertex_program,    /* validate */
-   run_arb_vertex_program      /* run */
-};
-
-
-/**
- * Called via ctx->Driver.ProgramStringNotify() after a new vertex program
- * string has been parsed.
- */
-void
-_tnl_program_string(GLcontext *ctx, GLenum target, struct gl_program *program)
-{
-   if (target == GL_VERTEX_PROGRAM_ARB) {
-      /* free any existing tnl data hanging off the program */
-      struct gl_vertex_program *vprog = (struct gl_vertex_program *) program;
-      if (vprog->TnlData) {
-         free_tnl_data(vprog);
-      }
-   }
-}
diff --git a/src/mesa/tnl/t_vb_arbprogram.h b/src/mesa/tnl/t_vb_arbprogram.h
deleted file mode 100644 (file)
index 1bec2a4..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5
- *
- * Copyright (C) 1999-2005  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.
- */
-
-/**
- * \file t_arb_program.c
- * Compile vertex programs to an intermediate representation.
- * Execute vertex programs over a buffer of vertices.
- * \author Keith Whitwell, Brian Paul
- */
-
-
-#ifndef _T_VB_ARBPROGRAM_H_
-#define _T_VB_ARBPROGRAM_H_
-
-
-/* New, internal instructions:
- */
-#define RSW        (MAX_OPCODE)
-#define MSK        (MAX_OPCODE+1)
-#define REL        (MAX_OPCODE+2)
-
-/**
- * Register files for vertex programs
- */
-#define FILE_REG         0  /* temporaries */
-#define FILE_LOCAL_PARAM 1  /* local parameters */
-#define FILE_ENV_PARAM   2  /* global parameters */
-#define FILE_STATE_PARAM 3  /* GL state references */
-
-#define REG_ARG0   0
-#define REG_ARG1   1
-#define REG_ARG2   2
-#define REG_RES    3
-#define REG_ADDR   4
-#define REG_TMP0   5
-#define REG_TMP11  16
-#define REG_OUT0   17
-#define REG_OUT23  40
-#define REG_IN0    41
-#define REG_IN31   72
-#define REG_ID     73          /* 0,0,0,1 */
-#define REG_ONES   74          /* 1,1,1,1 */
-#define REG_SWZ    75          /* 1,-1,0,0 */
-#define REG_NEG    76          /* -1,-1,-1,-1 */
-#define REG_LIT    77           /* 1,0,0,1 */
-#define REG_LIT2    78           /* 1,0,0,1 */
-#define REG_SCRATCH 79         /* internal temporary. XXX we can't actually use this because 70 doesn't fit in the 5-bit 'dst' instruction field! */
-#define REG_UNDEF  127         /* special case - never used */
-#define REG_MAX    128
-#define REG_INVALID ~0
-
-
-#if 0
-#define REG_OUT14  31
-#define REG_IN0    32
-#define REG_IN31   63
-#define REG_ID     64          /* 0,0,0,1 */
-#define REG_ONES   65          /* 1,1,1,1 */
-#define REG_SWZ    66          /* 1,-1,0,0 */
-#define REG_NEG    67          /* -1,-1,-1,-1 */
-#define REG_LIT    68           /* 1,0,0,1 */
-#define REG_LIT2    69           /* 1,0,0,1 */
-#define REG_SCRATCH 70         /* internal temporary. XXX we can't actually use this because 70 doesn't fit in the 5-bit 'dst' instruction field! */
-#define REG_UNDEF  127         /* special case - never used */
-#define REG_MAX    128
-#define REG_INVALID ~0
-#endif
-
-/* ARB_vp instructions are broken down into one or more of the
- * following micro-instructions, each representable in a 64 bit packed
- * structure.
- */
-struct reg {
-   GLuint file:2;
-   GLuint idx:8;
-};
-
-
-union instruction {
-   struct {
-      GLuint opcode:7;
-      GLuint dst:6;
-      GLuint file0:2;
-      GLuint idx0:8;
-      GLuint file1:2;
-      GLuint idx1:7;
-      GLuint pad:2;
-      GLuint pad2;
-   } alu;
-
-   struct {
-      GLuint opcode:7;
-      GLuint dst:6;
-      GLuint file0:2;
-      GLuint idx0:8;
-      GLuint neg:4;
-      GLuint swz:12;           /* xyzw01 */
-   } rsw;
-
-   struct {
-      GLuint opcode:7;
-      GLuint dst:6;
-      GLuint file:2;
-      GLuint idx:8;
-      GLuint mask:4;
-      GLuint pad:7;
-      GLuint pad2;
-   } msk;
-};
-
-
-/**
- * Reduced swizzle is a 3-bit field, for simplicity same as normal swizzle, X/Y/Z/W/0/1 allowed.
- */
-
-struct input {
-   GLuint idx;
-   GLfloat *data;
-   GLuint stride;
-   GLuint size;
-};
-
-struct output {
-   GLuint idx;
-   GLfloat *data;
-};
-
-
-
-/*--------------------------------------------------------------------------- */
-#if defined(USE_SSE_ASM)
-#ifdef NO_FAST_MATH
-#define RESTORE_FPU (DEFAULT_X86_FPU)
-#define RND_NEG_FPU (DEFAULT_X86_FPU | 0x400)
-#else
-#define RESTORE_FPU (FAST_X86_FPU)
-#define RND_NEG_FPU (FAST_X86_FPU | 0x400)
-#endif
-#else
-#define RESTORE_FPU 0
-#define RND_NEG_FPU 0
-#endif
-
-
-/**
- * Private storage for the vertex program pipeline stage.
- */
-struct arb_vp_machine {
-   GLfloat (*File[4])[4];      /* All values referencable from the program. */
-
-   struct input input[VERT_ATTRIB_MAX];
-   GLuint nr_inputs;
-
-   struct output output[VERT_RESULT_MAX];
-   GLuint nr_outputs;
-
-   GLvector4f attribs[VERT_RESULT_MAX]; /**< result vectors. */
-   GLvector4f ndcCoords;              /**< normalized device coords */
-   GLubyte *clipmask;                 /**< clip flags */
-   GLubyte ormask, andmask;           /**< for clipping */
-
-   GLuint vtx_nr;              /**< loop counter */
-
-   struct vertex_buffer *VB;
-
-   GLshort fpucntl_rnd_neg;    /* constant value */
-   GLshort fpucntl_restore;    /* constant value */
-
-   GLboolean try_codegen;
-};
-
-struct tnl_compiled_program {
-   union instruction instructions[1024];
-   GLint nr_instructions;
-   void (*compiled_func)( struct arb_vp_machine * ); /**< codegen'd program */   
-};
-
-void _tnl_program_string_change( struct gl_vertex_program * );
-void _tnl_program_destroy( struct gl_vertex_program * );
-
-void _tnl_disassem_vba_insn( union instruction op );
-
-GLboolean _tnl_sse_codegen_vertex_program(struct tnl_compiled_program *p);
-
-#endif
diff --git a/src/mesa/tnl/t_vb_arbprogram_sse.c b/src/mesa/tnl/t_vb_arbprogram_sse.c
deleted file mode 100644 (file)
index d0f66fd..0000000
+++ /dev/null
@@ -1,1330 +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.
- */
-
-/**
- * \file t_vb_arb_program_sse.c
- *
- * Translate simplified vertex_program representation to
- * x86/x87/SSE/SSE2 machine code using mesa's rtasm runtime assembler.
- *
- * This is very much a first attempt - build something that works.
- * There are probably better approaches for applying SSE to vertex
- * programs, and the whole thing is crying out for static analysis of
- * the programs to avoid redundant operations.
- *
- * \author Keith Whitwell
- */
-
-#include "glheader.h"
-#include "context.h"
-#include "imports.h"
-#include "macros.h"
-#include "mtypes.h"
-#include "arbprogparse.h"
-#include "program.h"
-#include "prog_instruction.h"
-#include "math/m_matrix.h"
-#include "math/m_translate.h"
-#include "t_context.h"
-#include "t_vb_arbprogram.h"
-
-#if defined(USE_SSE_ASM)
-
-#include "x86/rtasm/x86sse.h"
-#include "x86/common_x86_asm.h"
-
-#define X    0
-#define Y    1
-#define Z    2
-#define W    3
-
-/* Reg usage:
- *
- * EAX - temp
- * EBX - point to 'm->File[0]'
- * ECX - point to 'm->File[3]'
- * EDX - holds 'm'
- * EBP,
- * ESI,
- * EDI
- */
-
-#define DISASSEM 0
-
-#define FAIL                                                           \
-do {                                                                   \
-   _mesa_printf("x86 translation failed in %s\n", __FUNCTION__);       \
-   return GL_FALSE;                                                    \
-} while (0)
-
-struct compilation {
-   struct x86_function func;
-   struct tnl_compiled_program *p;   
-   GLuint insn_counter;
-
-   struct {
-      GLuint file:2;
-      GLuint idx:7;
-      GLuint dirty:1;
-      GLuint last_used:10;
-   } xmm[8];
-
-   struct {
-      struct x86_reg base;
-   } file[4];
-
-   GLboolean have_sse2;
-   GLshort fpucntl;
-};
-
-static INLINE GLboolean 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);
-}
-      
-static GLint get_offset( const void *a, const void *b )
-{
-   return (const char *)b - (const char *)a;
-}
-
-
-static struct x86_reg get_reg_ptr(GLuint file,
-                                 GLuint idx )
-{
-   struct x86_reg reg;
-
-   switch (file) {
-   case FILE_REG:
-      reg = x86_make_reg(file_REG32, reg_BX);
-      assert(idx != REG_UNDEF);
-      break;
-   case FILE_STATE_PARAM:
-      reg = x86_make_reg(file_REG32, reg_CX);
-      break;
-   default:
-      assert(0);
-   }
-
-   return x86_make_disp(reg, 16 * idx);
-}
-                         
-
-static void spill( struct compilation *cp, GLuint idx )
-{
-   struct x86_reg oldval = get_reg_ptr(cp->xmm[idx].file,
-                                      cp->xmm[idx].idx);
-
-   assert(cp->xmm[idx].dirty);
-   sse_movups(&cp->func, oldval, x86_make_reg(file_XMM, idx));
-   cp->xmm[idx].dirty = 0;
-}
-
-static struct x86_reg get_xmm_reg( struct compilation *cp )
-{
-   GLuint i;
-   GLuint oldest = 0;
-
-   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 = FILE_REG;
-   cp->xmm[oldest].idx = REG_UNDEF;
-   cp->xmm[oldest].last_used = cp->insn_counter;
-   return x86_make_reg(file_XMM, oldest);
-}
-
-static void invalidate_xmm( struct compilation *cp, 
-                           GLuint file, GLuint idx )
-{
-   GLuint i;
-
-   /* Invalidate any old copy of this register in XMM0-7.  
-    */
-   for (i = 0; i < 8; i++) {
-      if (cp->xmm[i].file == file && cp->xmm[i].idx == idx) {
-        cp->xmm[i].file = FILE_REG;
-        cp->xmm[i].idx = REG_UNDEF;
-        cp->xmm[i].dirty = 0;
-        break;
-      }
-   }
-}
-      
-
-/* Return an XMM reg to receive the results of an operation.
- */
-static struct x86_reg get_dst_xmm_reg( struct compilation *cp, 
-                                      GLuint file, GLuint idx )
-{
-   struct x86_reg reg;
-
-   /* Invalidate any old copy of this register in XMM0-7.  Don't reuse
-    * as this may be one of the arguments.
-    */
-   invalidate_xmm( cp, file, idx );
-
-   reg = get_xmm_reg( cp );
-   cp->xmm[reg.idx].file = file;
-   cp->xmm[reg.idx].idx = idx;
-   cp->xmm[reg.idx].dirty = 1;
-   return reg;   
-}
-
-/* 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 compilation *cp, 
-                                  GLuint file, GLuint idx )
-{
-   /* Invalidate any old copy of this register in XMM0-7.  Don't reuse
-    * as this may be one of the arguments.
-    */
-   invalidate_xmm( cp, file, idx );
-
-   return get_reg_ptr(file, idx);
-}
-
-
-
-/* Return an XMM reg if the argument is resident, otherwise return a
- * base+offset pointer to the saved value.
- */
-static struct x86_reg get_arg( struct compilation *cp, GLuint file, GLuint idx )
-{
-   GLuint 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);
-      }
-   }
-
-   return get_reg_ptr(file, idx);
-}
-
-/* As above, but always return a pointer:
- */
-static struct x86_reg get_arg_ptr( struct compilation *cp, GLuint file, GLuint idx )
-{
-   GLuint i;
-
-   /* If there is a modified version of this register in one of the
-    * XMM regs, write it out to memory.
-    */
-   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(file, idx);
-}
-
-/* Emulate pshufd insn in regular SSE, if necessary:
- */
-static void emit_pshufd( struct compilation *cp,
-                        struct x86_reg dst,
-                        struct x86_reg arg0,
-                        GLubyte shuf )
-{
-   if (cp->have_sse2) {
-      sse2_pshufd(&cp->func, dst, arg0, shuf);
-      cp->func.fn = 0;
-   }
-   else {
-      if (!eq(dst, arg0)) 
-        sse_movups(&cp->func, dst, arg0);
-
-      sse_shufps(&cp->func, dst, dst, shuf);
-   }
-}
-
-static void set_fpu_round_neg_inf( struct compilation *cp )
-{
-   if (cp->fpucntl != RND_NEG_FPU) {
-      struct x86_reg regEDX = x86_make_reg(file_REG32, reg_DX);
-      struct arb_vp_machine *m = NULL;
-
-      cp->fpucntl = RND_NEG_FPU;
-      x87_fnclex(&cp->func);
-      x87_fldcw(&cp->func, x86_make_disp(regEDX, get_offset(m, &m->fpucntl_rnd_neg)));
-   }
-}
-
-
-/* Perform a reduced swizzle.  
- */
-static GLboolean emit_RSW( struct compilation *cp, union instruction op ) 
-{
-   struct x86_reg arg0 = get_arg(cp, op.rsw.file0, op.rsw.idx0);
-   struct x86_reg dst = get_dst_xmm_reg(cp, FILE_REG, op.rsw.dst);
-   GLuint swz = GET_SWZ(op.rsw.swz, 0) | (GET_SWZ(op.rsw.swz, 1) << 2) |
-               (GET_SWZ(op.rsw.swz, 2) << 4| (GET_SWZ(op.rsw.swz, 3) << 6));
-   GLuint neg = op.rsw.neg;
-
-   emit_pshufd(cp, dst, arg0, swz);
-
-   if (neg) {
-      struct x86_reg negs = get_arg(cp, FILE_REG, REG_SWZ);
-      struct x86_reg tmp = get_xmm_reg(cp);
-      /* Load 1,-1,0,0
-       * Use neg as arg to pshufd
-       * Multiply
-       */
-      /* is the emit_pshufd necessary? only SWZ can negate individual components */
-      emit_pshufd(cp, tmp, negs, 
-                 SHUF((neg & 1) ? 1 : 0,
-                      (neg & 2) ? 1 : 0,
-                      (neg & 4) ? 1 : 0,
-                      (neg & 8) ? 1 : 0));
-      sse_mulps(&cp->func, dst, tmp);
-   }
-
-   return GL_TRUE;
-}
-
-/* Perform a full swizzle
- */
-static GLboolean emit_SWZ( struct compilation *cp, union instruction op ) 
-{
-   struct x86_reg arg0 = get_arg(cp, op.rsw.file0, op.rsw.idx0);
-   struct x86_reg dst = get_dst_xmm_reg(cp, FILE_REG, op.rsw.dst);
-   struct x86_reg negs = get_arg(cp, FILE_REG, REG_SWZ);
-   struct x86_reg tmp = get_xmm_reg(cp);
-   GLubyte neg = op.rsw.neg;
-   GLubyte shuf2, swz, savepos, savemask, swizzle[4];
-
-   swizzle[0] = GET_SWZ(op.rsw.swz, 0);
-   swizzle[1] = GET_SWZ(op.rsw.swz, 1);
-   swizzle[2] = GET_SWZ(op.rsw.swz, 2);
-   swizzle[3] = GET_SWZ(op.rsw.swz, 3);
-
-   swz = SHUF((swizzle[0] & 3), (swizzle[1] & 3),
-             (swizzle[2] & 3), (swizzle[3] & 3));
-
-   emit_pshufd(cp, dst, arg0, swz);
-
-   /* can handle negation and replace with zero with the same shuffle/mul */
-   shuf2 = SHUF(swizzle[0] == 4 ? 2 : (neg & 1),
-               swizzle[1] == 4 ? 2 : ((neg & 2) >> 1),
-               swizzle[2] == 4 ? 2 : ((neg & 4) >> 2),
-               swizzle[3] == 4 ? 2 : ((neg & 8) >> 3));
-
-   /* now the hard part is getting those 1's in there... */
-   savepos = 0;
-   savemask = 0;
-   if (swizzle[0] == 5) savepos = 1;
-   if (swizzle[1] == 5) savepos = 2;
-   else savemask |= 1 << 2;
-   if (swizzle[2] == 5) savepos = 3;
-   else savemask |= 2 << 4;
-   if (swizzle[3] == 5) savepos = 4;
-   else savemask |= 3 << 6;
-   if (savepos) {
-      /* need a mov first as movss from memory will overwrite high bits of xmm reg */
-      sse_movups(&cp->func, tmp, negs);
-      /* can only replace lowest 32bits, thus move away that part first */
-      emit_pshufd(cp, dst, dst, savemask);
-      sse_movss(&cp->func, dst, tmp);
-      emit_pshufd(cp, dst, dst, (savepos - 1) | (savemask & 0xfc));
-   }
-
-   if (shuf2) {
-      /* Load 1,-1,0,0
-       * Use neg as arg to pshufd
-       * Multiply
-       */
-      emit_pshufd(cp, tmp, negs, shuf2);
-      sse_mulps(&cp->func, dst, tmp);
-   }
-
-   return GL_TRUE;
-}
-
-/* Helper for writemask:
- */
-static GLboolean emit_shuf_copy1( struct compilation *cp,
-                                 struct x86_reg dst,
-                                 struct x86_reg arg0,
-                                 struct x86_reg arg1,
-                                 GLubyte shuf )
-{
-   struct x86_reg tmp = get_xmm_reg(cp);
-   sse_movups(&cp->func, dst, arg1);
-   emit_pshufd(cp, dst, dst, shuf);
-   emit_pshufd(cp, tmp, arg0, shuf);
-
-   sse_movss(&cp->func, dst, tmp);
-
-   emit_pshufd(cp, dst, dst, shuf);
-   return GL_TRUE;
-}
-
-
-/* Helper for writemask:
- */
-static GLboolean emit_shuf_copy2( struct compilation *cp,
-                                 struct x86_reg dst,
-                                 struct x86_reg arg0,
-                                 struct x86_reg arg1,
-                                 GLubyte shuf )
-{
-   struct x86_reg tmp = 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);
-   return GL_TRUE;
-}
-
-
-static void emit_x87_ex2( struct compilation *cp )
-{
-   struct x86_reg st0 = x86_make_reg(file_x87, 0);
-   struct x86_reg st1 = x86_make_reg(file_x87, 1);
-   struct x86_reg st3 = x86_make_reg(file_x87, 3);
-
-   set_fpu_round_neg_inf( cp );
-
-   x87_fld(&cp->func, st0); /* a a */
-   x87_fprndint( &cp->func );  /* int(a) a */
-   x87_fld(&cp->func, st0); /* int(a) int(a) a */
-   x87_fstp(&cp->func, st3); /* int(a) a int(a)*/
-   x87_fsubp(&cp->func, st1); /* frac(a) int(a) */
-   x87_f2xm1(&cp->func);    /* (2^frac(a))-1 int(a)*/
-   x87_fld1(&cp->func);    /* 1 (2^frac(a))-1 int(a)*/
-   x87_faddp(&cp->func, st1);  /* 2^frac(a) int(a) */
-   x87_fscale(&cp->func);      /* 2^a */
-}
-
-#if 0
-static GLboolean emit_MSK2( struct compilation *cp, union instruction op )
-{
-   struct x86_reg arg0 = get_arg(cp, op.msk.file, op.msk.arg);
-   struct x86_reg arg1 = get_arg(cp, FILE_REG, op.msk.dst); /* NOTE! */
-   struct x86_reg dst = get_dst_xmm_reg(cp, FILE_REG, op.msk.dst);
-   
-   /* make full width bitmask in tmp 
-    * dst = ~tmp
-    * tmp &= arg0
-    * dst &= arg1
-    * dst |= tmp
-    */
-   emit_pshufd(cp, tmp, get_arg(cp, FILE_REG, REG_NEGS), 
-              SHUF((op.msk.mask & 1) ? 2 : 0,
-                   (op.msk.mask & 2) ? 2 : 0,
-                   (op.msk.mask & 4) ? 2 : 0,
-                   (op.msk.mask & 8) ? 2 : 0));
-   sse2_pnot(&cp->func, dst, tmp);
-   sse2_pand(&cp->func, arg0, tmp);
-   sse2_pand(&cp->func, arg1, dst);
-   sse2_por(&cp->func, tmp, dst);
-   return GL_TRUE;
-}
-#endif
-
-
-/* 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 GLboolean emit_MSK( struct compilation *cp, union instruction op )
-{
-   struct x86_reg arg = get_arg(cp, op.msk.file, op.msk.idx);
-   struct x86_reg dst0 = get_arg(cp, FILE_REG, op.msk.dst); /* NOTE! */
-   struct x86_reg dst = get_dst_xmm_reg(cp, FILE_REG, op.msk.dst);
-   
-   /* Note that dst and dst0 refer to the same program variable, but
-    * will definitely be different XMM registers.  We're effectively
-    * treating this as a 2 argument SEL now, just one of which happens
-    * always to be the same register as the destination.
-    */
-
-   switch (op.msk.mask) {
-   case 0:
-      sse_movups(&cp->func, dst, dst0);
-      return GL_TRUE;
-
-   case WRITEMASK_X:
-      if (arg.file == file_XMM) {
-        sse_movups(&cp->func, dst, dst0);
-        sse_movss(&cp->func, dst, arg);
-      }
-      else {
-        struct x86_reg tmp = get_xmm_reg(cp);
-        sse_movups(&cp->func, dst, dst0);
-        sse_movss(&cp->func, tmp, arg);
-        sse_movss(&cp->func, dst, tmp);
-      }
-      return GL_TRUE;
-
-   case WRITEMASK_XY:
-      sse_movups(&cp->func, dst, dst0);
-      sse_shufps(&cp->func, dst, arg, SHUF(X, Y, Z, W));
-      return GL_TRUE;
-
-   case WRITEMASK_ZW: 
-      sse_movups(&cp->func, dst, arg);
-      sse_shufps(&cp->func, dst, dst0, SHUF(X, Y, Z, W));
-      return GL_TRUE;
-
-   case WRITEMASK_YZW: 
-      if (dst0.file == file_XMM) {
-        sse_movups(&cp->func, dst, arg);
-        sse_movss(&cp->func, dst, dst0);
-      }
-      else {
-        struct x86_reg tmp = get_xmm_reg(cp);      
-        sse_movups(&cp->func, dst, arg);
-        sse_movss(&cp->func, tmp, dst0);
-        sse_movss(&cp->func, dst, tmp);
-      }
-      return GL_TRUE;
-
-   case WRITEMASK_Y:
-      emit_shuf_copy1(cp, dst, arg, dst0, SHUF(Y,X,Z,W));
-      return GL_TRUE;
-
-   case WRITEMASK_Z: 
-      emit_shuf_copy1(cp, dst, arg, dst0, SHUF(Z,Y,X,W));
-      return GL_TRUE;
-
-   case WRITEMASK_W: 
-      emit_shuf_copy1(cp, dst, arg, dst0, SHUF(W,Y,Z,X));
-      return GL_TRUE;
-
-   case WRITEMASK_XZ:
-      emit_shuf_copy2(cp, dst, arg, dst0, SHUF(X,Z,Y,W));
-      return GL_TRUE;
-
-   case WRITEMASK_XW: 
-      emit_shuf_copy2(cp, dst, arg, dst0, SHUF(X,W,Z,Y));
-
-   case WRITEMASK_YZ:      
-      emit_shuf_copy2(cp, dst, arg, dst0, SHUF(Z,Y,X,W));
-      return GL_TRUE;
-
-   case WRITEMASK_YW:
-      emit_shuf_copy2(cp, dst, arg, dst0, SHUF(W,Y,Z,X));
-      return GL_TRUE;
-
-   case WRITEMASK_XZW:
-      emit_shuf_copy1(cp, dst, dst0, arg, SHUF(Y,X,Z,W));
-      return GL_TRUE;
-
-   case WRITEMASK_XYW: 
-      emit_shuf_copy1(cp, dst, dst0, arg, SHUF(Z,Y,X,W));
-      return GL_TRUE;
-
-   case WRITEMASK_XYZ: 
-      emit_shuf_copy1(cp, dst, dst0, arg, SHUF(W,Y,Z,X));
-      return GL_TRUE;
-
-   case WRITEMASK_XYZW:
-      sse_movups(&cp->func, dst, arg);
-      return GL_TRUE;      
-
-   default:
-      assert(0);
-      break;
-   }
-}
-
-
-
-static GLboolean emit_PRT( struct compilation *cp, union instruction op )
-{
-   FAIL;
-}
-
-
-/**
- * The traditional instructions.  All operate on internal registers
- * and ignore write masks and swizzling issues.
- */
-
-static GLboolean emit_ABS( struct compilation *cp, union instruction op ) 
-{
-   struct x86_reg arg0 = get_arg(cp, op.alu.file0, op.alu.idx0);
-   struct x86_reg dst = get_dst_xmm_reg(cp, FILE_REG, op.alu.dst);
-   struct x86_reg neg = get_reg_ptr(FILE_REG, REG_NEG);
-
-   sse_movups(&cp->func, dst, arg0);
-   sse_mulps(&cp->func, dst, neg);
-   sse_maxps(&cp->func, dst, arg0);
-   return GL_TRUE;
-}
-
-static GLboolean emit_ADD( struct compilation *cp, union instruction op )
-{
-   struct x86_reg arg0 = get_arg(cp, op.alu.file0, op.alu.idx0);
-   struct x86_reg arg1 = get_arg(cp, op.alu.file1, op.alu.idx1);
-   struct x86_reg dst = get_dst_xmm_reg(cp, FILE_REG, op.alu.dst);
-
-   sse_movups(&cp->func, dst, arg0);
-   sse_addps(&cp->func, dst, arg1);
-   return GL_TRUE;
-}
-
-
-/* The dotproduct instructions don't really do that well in sse:
- */
-static GLboolean emit_DP3( struct compilation *cp, union instruction op )
-{
-   struct x86_reg arg0 = get_arg(cp, op.alu.file0, op.alu.idx0);
-   struct x86_reg arg1 = get_arg(cp, op.alu.file1, op.alu.idx1);
-   struct x86_reg dst = get_dst_xmm_reg(cp, FILE_REG, op.alu.dst);
-   struct x86_reg tmp = get_xmm_reg(cp); 
-
-   sse_movups(&cp->func, dst, 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);
-   sse_shufps(&cp->func, dst, dst, SHUF(X, X, X, X));
-   return GL_TRUE;
-}
-
-
-
-static GLboolean emit_DP4( struct compilation *cp, union instruction op )
-{
-   struct x86_reg arg0 = get_arg(cp, op.alu.file0, op.alu.idx0);
-   struct x86_reg arg1 = get_arg(cp, op.alu.file1, op.alu.idx1);
-   struct x86_reg dst = get_dst_xmm_reg(cp, FILE_REG, op.alu.dst);
-   struct x86_reg tmp = get_xmm_reg(cp);      
-
-   sse_movups(&cp->func, dst, 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);
-   sse_shufps(&cp->func, dst, dst, SHUF(X, X, X, X));
-   return GL_TRUE;
-}
-
-static GLboolean emit_DPH( struct compilation *cp, union instruction op )
-{
-   struct x86_reg arg0 = get_arg(cp, op.alu.file0, op.alu.idx0); 
-   struct x86_reg arg1 = get_arg(cp, op.alu.file1, op.alu.idx1); 
-   struct x86_reg dst = get_dst_xmm_reg(cp, FILE_REG, op.alu.dst);
-   struct x86_reg tmp = get_xmm_reg(cp);
-
-   sse_movups(&cp->func, dst, 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);
-   sse_shufps(&cp->func, dst, dst, SHUF(X, X, X, X));
-   return GL_TRUE;
-}
-
-#if 0
-static GLboolean emit_DST( struct compilation *cp, union instruction op )
-{
-    struct x86_reg arg0 = get_arg_ptr(cp, op.alu.file0, op.alu.idx0); 
-    struct x86_reg arg1 = get_arg_ptr(cp, op.alu.file1, op.alu.idx1); 
-    struct x86_reg dst = get_dst_ptr(cp, FILE_REG, op.alu.dst); 
-
-/*    dst[0] = 1.0     * 1.0F; */
-/*    dst[1] = arg0[1] * arg1[1]; */
-/*    dst[2] = arg0[2] * 1.0; */
-/*    dst[3] = 1.0     * arg1[3]; */
-
-    /* Would rather do some of this with integer regs, but:
-     *  1) No proper support for immediate values yet
-     *  2) I'd need to push/pop somewhere to get a free reg.
-     */ 
-    x87_fld1(&cp->func);
-    x87_fstp(&cp->func, dst); /* would rather do an immediate store... */
-    x87_fld(&cp->func, x86_make_disp(arg0, 4));
-    x87_fmul(&cp->func, x86_make_disp(arg1, 4));
-    x87_fstp(&cp->func, x86_make_disp(dst, 4));
-    
-    if (!eq(arg0, dst)) {
-       x86_fld(&cp->func, x86_make_disp(arg0, 8));
-       x86_stp(&cp->func, x86_make_disp(dst, 8));
-    }
-
-    if (!eq(arg1, dst)) {
-       x86_fld(&cp->func, x86_make_disp(arg0, 12));
-       x86_stp(&cp->func, x86_make_disp(dst, 12));
-    } 
-
-    return GL_TRUE;
-}
-#else
-static GLboolean emit_DST( struct compilation *cp, union instruction op )
-{
-    struct x86_reg arg0 = get_arg(cp, op.alu.file0, op.alu.idx0); 
-    struct x86_reg arg1 = get_arg(cp, op.alu.file1, op.alu.idx1); 
-    struct x86_reg dst = get_dst_xmm_reg(cp, FILE_REG, op.alu.dst); 
-    struct x86_reg tmp = get_xmm_reg(cp);
-    struct x86_reg ones = get_reg_ptr(FILE_REG, REG_ONES);
-
-    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);
-
-/*    dst[0] = 1.0     * 1.0F; */
-/*    dst[1] = arg0[1] * arg1[1]; */
-/*    dst[2] = arg0[2] * 1.0; */
-/*    dst[3] = 1.0     * arg1[3]; */
-
-    return GL_TRUE;
-}
-#endif
-
-static GLboolean emit_LG2( struct compilation *cp, union instruction op ) 
-{
-   struct x86_reg arg0 = get_arg_ptr(cp, op.alu.file0, op.alu.idx0); 
-   struct x86_reg dst = get_dst_ptr(cp, FILE_REG, op.alu.dst); 
-
-   x87_fld1(&cp->func);                /* 1 */
-   x87_fld(&cp->func, arg0);   /* a0 1 */
-   x87_fyl2x(&cp->func);       /* log2(a0) */
-   x87_fst(&cp->func, x86_make_disp(dst, 0));
-   x87_fst(&cp->func, x86_make_disp(dst, 4));
-   x87_fst(&cp->func, x86_make_disp(dst, 8));
-   x87_fstp(&cp->func, x86_make_disp(dst, 12));
-   
-   return GL_TRUE;
-}
-
-
-static GLboolean emit_EX2( struct compilation *cp, union instruction op ) 
-{
-   struct x86_reg arg0 = get_arg_ptr(cp, op.alu.file0, op.alu.idx0); 
-   struct x86_reg dst = get_dst_ptr(cp, FILE_REG, op.alu.dst);
-
-   /* CAUTION: dst may alias arg0!
-    */
-   x87_fld(&cp->func, arg0);   
-
-   emit_x87_ex2(cp);
-
-   x87_fst(&cp->func, x86_make_disp(dst, 0));    
-   x87_fst(&cp->func, x86_make_disp(dst, 4));    
-   x87_fst(&cp->func, x86_make_disp(dst, 8));    
-   x87_fst(&cp->func, x86_make_disp(dst, 12));    
-   return GL_TRUE;
-}
-
-static GLboolean emit_EXP( struct compilation *cp, union instruction op )
-{
-    struct x86_reg arg0 = get_arg_ptr(cp, op.alu.file0, op.alu.idx0); 
-    struct x86_reg dst = get_dst_ptr(cp, FILE_REG, op.alu.dst); 
-    struct x86_reg st0 = x86_make_reg(file_x87, 0);
-    struct x86_reg st1 = x86_make_reg(file_x87, 1);
-    struct x86_reg st3 = x86_make_reg(file_x87, 3);
-
-    /* CAUTION: dst may alias arg0!
-     */
-    x87_fld(&cp->func, arg0);  /* arg0.x */
-    x87_fld(&cp->func, st0); /* arg arg */
-
-    /* by default, fpu is setup to round-to-nearest.  We want to
-     * change this now, and track the state through to the end of the
-     * generated function so that it isn't repeated unnecessarily.
-     * Alternately, could subtract .5 to get round to -inf behaviour.
-     */
-    set_fpu_round_neg_inf( cp );
-    x87_fprndint( &cp->func ); /* flr(a) a */
-    x87_fld(&cp->func, st0); /* flr(a) flr(a) a */
-    x87_fld1(&cp->func);    /* 1 floor(a) floor(a) a */
-    x87_fst(&cp->func, x86_make_disp(dst, 12));  /* stack unchanged */
-    x87_fscale(&cp->func);  /* 2^floor(a) floor(a) a */
-    x87_fst(&cp->func, st3); /* 2^floor(a) floor(a) a 2^floor(a)*/
-    x87_fstp(&cp->func, x86_make_disp(dst, 0)); /* flr(a) a 2^flr(a) */
-    x87_fsubrp(&cp->func, st1); /* frac(a) 2^flr(a) */
-    x87_fst(&cp->func, x86_make_disp(dst, 4));    /* frac(a) 2^flr(a) */
-    x87_f2xm1(&cp->func);    /* (2^frac(a))-1 2^flr(a)*/
-    x87_fld1(&cp->func);    /* 1 (2^frac(a))-1 2^flr(a)*/
-    x87_faddp(&cp->func, st1); /* 2^frac(a) 2^flr(a) */
-    x87_fmulp(&cp->func, st1); /* 2^a */
-    x87_fst(&cp->func, x86_make_disp(dst, 8));    
-    
-
-
-/*    dst[0] = 2^floor(tmp); */
-/*    dst[1] = frac(tmp); */
-/*    dst[2] = 2^floor(tmp) * 2^frac(tmp); */
-/*    dst[3] = 1.0F; */
-    return GL_TRUE;
-}
-
-static GLboolean emit_LOG( struct compilation *cp, union instruction op )
-{
-    struct x86_reg arg0 = get_arg_ptr(cp, op.alu.file0, op.alu.idx0); 
-    struct x86_reg dst = get_dst_ptr(cp, FILE_REG, op.alu.dst); 
-    struct x86_reg st0 = x86_make_reg(file_x87, 0);
-    struct x86_reg st1 = x86_make_reg(file_x87, 1);
-    struct x86_reg st2 = x86_make_reg(file_x87, 2);
-    /* CAUTION: dst may alias arg0!
-     */
-    x87_fld(&cp->func, arg0);  /* arg0.x */
-    x87_fabs(&cp->func);       /* |arg0.x| */
-    x87_fxtract(&cp->func);    /* mantissa(arg0.x), exponent(arg0.x) */
-    x87_fst(&cp->func, st2);   /* mantissa, exponent, mantissa */
-    x87_fld1(&cp->func);       /* 1, mantissa, exponent, mantissa */
-    x87_fyl2x(&cp->func);      /* log2(mantissa), exponent, mantissa */
-    x87_fadd(&cp->func, st0, st1);     /* e+l2(m), e, m  */
-    x87_fstp(&cp->func, x86_make_disp(dst, 8)); /* e, m */
-
-    x87_fld1(&cp->func);       /* 1, e, m */
-    x87_fsub(&cp->func, st1, st0);     /* 1, e-1, m */
-    x87_fstp(&cp->func, x86_make_disp(dst, 12)); /* e-1,m */
-    x87_fstp(&cp->func, dst);  /* m */
-
-    x87_fadd(&cp->func, st0, st0);     /* 2m */
-    x87_fstp(&cp->func, x86_make_disp(dst, 4));        
-
-    return GL_TRUE;
-}
-
-static GLboolean emit_FLR( struct compilation *cp, union instruction op ) 
-{
-   struct x86_reg arg0 = get_arg_ptr(cp, op.alu.file0, op.alu.idx0); 
-   struct x86_reg dst = get_dst_ptr(cp, FILE_REG, op.alu.dst); 
-   int i;
-
-   set_fpu_round_neg_inf( cp );
-
-   for (i = 0; i < 4; i++) {
-      x87_fld(&cp->func, x86_make_disp(arg0, i*4));   
-      x87_fprndint( &cp->func );   
-      x87_fstp(&cp->func, x86_make_disp(dst, i*4));
-   }
-
-
-   return GL_TRUE;
-}
-
-static GLboolean emit_FRC( struct compilation *cp, union instruction op ) 
-{
-   struct x86_reg arg0 = get_arg_ptr(cp, op.alu.file0, op.alu.idx0); 
-   struct x86_reg dst = get_dst_ptr(cp, FILE_REG, op.alu.dst); 
-   struct x86_reg st0 = x86_make_reg(file_x87, 0);
-   struct x86_reg st1 = x86_make_reg(file_x87, 1);
-   int i;
-
-   set_fpu_round_neg_inf( cp );
-
-   /* Knowing liveness info or even just writemask would be useful
-    * here:
-    */
-   for (i = 0; i < 4; i++) {
-      x87_fld(&cp->func, x86_make_disp(arg0, i*4));   
-      x87_fld(&cp->func, st0); /* a a */
-      x87_fprndint( &cp->func );   /* flr(a) a */
-      x87_fsubrp(&cp->func, st1); /* frc(a) */
-      x87_fstp(&cp->func, x86_make_disp(dst, i*4));
-   }
-
-   return GL_TRUE;
-}
-
-
-
-static GLboolean emit_LIT( struct compilation *cp, union instruction op )
-{
-#if 1
-   struct x86_reg arg0 = get_arg_ptr(cp, op.alu.file0, op.alu.idx0); 
-   struct x86_reg dst = get_dst_ptr(cp, FILE_REG, op.alu.dst); 
-   struct x86_reg lit = get_arg(cp, FILE_REG, REG_LIT);
-   struct x86_reg tmp = get_xmm_reg(cp);
-   struct x86_reg st1 = x86_make_reg(file_x87, 1);
-   struct x86_reg regEAX = x86_make_reg(file_REG32, reg_AX);
-   GLubyte *fixup1, *fixup2;
-
-
-   /* Load the interesting parts of arg0:
-    */
-   x87_fld(&cp->func, x86_make_disp(arg0, 12));        /* a3 */
-   x87_fld(&cp->func, x86_make_disp(arg0, 4)); /* a1 a3 */
-   x87_fld(&cp->func, x86_make_disp(arg0, 0)); /* a0 a1 a3 */
-   
-   /* Intialize dst:
-    */
-   sse_movaps(&cp->func, tmp, lit);
-   sse_movaps(&cp->func, dst, tmp);
-   
-   /* Check arg0[0]:
-    */
-   x87_fldz(&cp->func);                /* 0 a0 a1 a3 */
-   x87_fucomp(&cp->func, st1); /* a0 a1 a3 */
-   x87_fnstsw(&cp->func, regEAX);
-   x86_sahf(&cp->func);
-   fixup1 = x86_jcc_forward(&cp->func, cc_AE); 
-   
-   x87_fstp(&cp->func, x86_make_disp(dst, 4)); /* a1 a3 */
-
-   /* Check arg0[1]:
-    */ 
-   x87_fldz(&cp->func);                /* 0 a1 a3 */
-   x87_fucomp(&cp->func, st1); /* a1 a3 */
-   x87_fnstsw(&cp->func, regEAX);
-   x86_sahf(&cp->func);
-   fixup2 = x86_jcc_forward(&cp->func, cc_AE); 
-
-   /* Compute pow(a1, a3)
-    */
-   x87_fyl2x(&cp->func);       /* a3*log2(a1) */
-
-   emit_x87_ex2( cp );         /* 2^(a3*log2(a1)) */
-
-   x87_fstp(&cp->func, x86_make_disp(dst, 8));
-   
-   /* Land jumps:
-    */
-   x86_fixup_fwd_jump(&cp->func, fixup1);
-   x86_fixup_fwd_jump(&cp->func, fixup2);
-#else
-   struct x86_reg dst = get_dst_xmm_reg(cp, FILE_REG, op.alu.dst); 
-   struct x86_reg ones = get_reg_ptr(FILE_REG, REG_LIT);
-   sse_movups(&cp->func, dst, ones);
-#endif   
-   return GL_TRUE;
-}
-
-
-
-static GLboolean emit_MAX( struct compilation *cp, union instruction op )
-{
-   struct x86_reg arg0 = get_arg(cp, op.alu.file0, op.alu.idx0);
-   struct x86_reg arg1 = get_arg(cp, op.alu.file1, op.alu.idx1);
-   struct x86_reg dst = get_dst_xmm_reg(cp, FILE_REG, op.alu.dst);
-
-   sse_movups(&cp->func, dst, arg0);
-   sse_maxps(&cp->func, dst, arg1);
-   return GL_TRUE;
-}
-
-
-static GLboolean emit_MIN( struct compilation *cp, union instruction op )
-{
-   struct x86_reg arg0 = get_arg(cp, op.alu.file0, op.alu.idx0);
-   struct x86_reg arg1 = get_arg(cp, op.alu.file1, op.alu.idx1);
-   struct x86_reg dst = get_dst_xmm_reg(cp, FILE_REG, op.alu.dst);
-
-   sse_movups(&cp->func, dst, arg0);
-   sse_minps(&cp->func, dst, arg1);
-   return GL_TRUE;
-}
-
-static GLboolean emit_MOV( struct compilation *cp, union instruction op )
-{
-   struct x86_reg arg0 = get_arg(cp, op.alu.file0, op.alu.idx0);
-   struct x86_reg dst = get_dst_xmm_reg(cp, FILE_REG, op.alu.dst);
-
-   sse_movups(&cp->func, dst, arg0);
-   return GL_TRUE;
-}
-
-static GLboolean emit_MUL( struct compilation *cp, union instruction op )
-{
-   struct x86_reg arg0 = get_arg(cp, op.alu.file0, op.alu.idx0);
-   struct x86_reg arg1 = get_arg(cp, op.alu.file1, op.alu.idx1);
-   struct x86_reg dst = get_dst_xmm_reg(cp, FILE_REG, op.alu.dst);
-
-   sse_movups(&cp->func, dst, arg0);
-   sse_mulps(&cp->func, dst, arg1);
-   return GL_TRUE;
-}
-
-
-static GLboolean emit_POW( struct compilation *cp, union instruction op ) 
-{
-   struct x86_reg arg0 = get_arg_ptr(cp, op.alu.file0, op.alu.idx0); 
-   struct x86_reg arg1 = get_arg_ptr(cp, op.alu.file1, op.alu.idx1); 
-   struct x86_reg dst = get_dst_ptr(cp, FILE_REG, op.alu.dst);
-
-   x87_fld(&cp->func, arg1);           /* a1 */
-   x87_fld(&cp->func, arg0);   /* a0 a1 */
-   x87_fyl2x(&cp->func);       /* a1*log2(a0) */
-
-   emit_x87_ex2( cp );         /* 2^(a1*log2(a0)) */
-
-   x87_fst(&cp->func, x86_make_disp(dst, 0));    
-   x87_fst(&cp->func, x86_make_disp(dst, 4));    
-   x87_fst(&cp->func, x86_make_disp(dst, 8));    
-   x87_fstp(&cp->func, x86_make_disp(dst, 12));    
-    
-   return GL_TRUE;
-}
-
-static GLboolean emit_REL( struct compilation *cp, union instruction op )
-{
-/*    GLuint idx = (op.alu.idx0 + (GLint)cp->File[0][REG_ADDR][0]) & (MAX_NV_VERTEX_PROGRAM_PARAMS-1); */
-/*    GLuint idx = 0; */
-/*    struct x86_reg arg0 = get_arg(cp, op.alu.file0, idx); */
-/*    struct x86_reg dst = get_dst_xmm_reg(cp, FILE_REG, op.alu.dst); */
-
-/*    dst[0] = arg0[0]; */
-/*    dst[1] = arg0[1]; */
-/*    dst[2] = arg0[2]; */
-/*    dst[3] = arg0[3]; */
-
-   FAIL;
-}
-
-static GLboolean emit_RCP( struct compilation *cp, union instruction op )
-{
-   struct x86_reg arg0 = get_arg(cp, op.alu.file0, op.alu.idx0);
-   struct x86_reg dst = get_dst_xmm_reg(cp, FILE_REG, op.alu.dst);
-
-   if (cp->have_sse2) {
-      sse2_rcpss(&cp->func, dst, arg0);
-   }
-   else {
-      struct x86_reg ones = get_reg_ptr(FILE_REG, REG_ONES);
-      sse_movss(&cp->func, dst, ones);
-      sse_divss(&cp->func, dst, arg0);
-   }
-
-   sse_shufps(&cp->func, dst, dst, SHUF(X, X, X, X));
-   return GL_TRUE;
-}
-
-static GLboolean emit_RSQ( struct compilation *cp, union instruction op )
-{
-   struct x86_reg arg0 = get_arg(cp, op.alu.file0, op.alu.idx0);
-   struct x86_reg dst = get_dst_xmm_reg(cp, FILE_REG, op.alu.dst);
-#if 0
-   struct x86_reg neg = get_reg_ptr(FILE_REG, REG_NEG);
-
-/* get abs value first. This STILL doesn't work.
-   Looks like we get bogus neg values ?
-*/
-   sse_movss(&cp->func, dst, arg0);
-   sse_mulss(&cp->func, dst, neg);
-   sse_maxss(&cp->func, dst, arg0);
-
-   sse_rsqrtss(&cp->func, dst, dst);
-#endif
-   sse_rsqrtss(&cp->func, dst, arg0);
-   sse_shufps(&cp->func, dst, dst, SHUF(X, X, X, X));
-   return GL_TRUE;
-}
-
-
-static GLboolean emit_SGE( struct compilation *cp, union instruction op )
-{
-   struct x86_reg arg0 = get_arg(cp, op.alu.file0, op.alu.idx0);
-   struct x86_reg arg1 = get_arg(cp, op.alu.file1, op.alu.idx1);
-   struct x86_reg dst = get_dst_xmm_reg(cp, FILE_REG, op.alu.dst);
-   struct x86_reg ones = get_reg_ptr(FILE_REG, REG_ONES);
-
-   sse_movups(&cp->func, dst, arg0);
-   sse_cmpps(&cp->func, dst, arg1, cc_NotLessThan);
-   sse_andps(&cp->func, dst, ones);
-   return GL_TRUE;
-}
-
-
-static GLboolean emit_SLT( struct compilation *cp, union instruction op )
-{
-   struct x86_reg arg0 = get_arg(cp, op.alu.file0, op.alu.idx0);
-   struct x86_reg arg1 = get_arg(cp, op.alu.file1, op.alu.idx1);
-   struct x86_reg dst = get_dst_xmm_reg(cp, FILE_REG, op.alu.dst);
-   struct x86_reg ones = get_reg_ptr(FILE_REG, REG_ONES);
-   
-   sse_movups(&cp->func, dst, arg0);
-   sse_cmpps(&cp->func, dst, arg1, cc_LessThan);
-   sse_andps(&cp->func, dst, ones);
-   return GL_TRUE;
-}
-
-static GLboolean emit_SUB( struct compilation *cp, union instruction op ) 
-{
-   struct x86_reg arg0 = get_arg(cp, op.alu.file0, op.alu.idx0);
-   struct x86_reg arg1 = get_arg(cp, op.alu.file1, op.alu.idx1);
-   struct x86_reg dst = get_dst_xmm_reg(cp, FILE_REG, op.alu.dst);
-
-   sse_movups(&cp->func, dst, arg0);
-   sse_subps(&cp->func, dst, arg1);
-   return GL_TRUE;
-}
-
-
-static GLboolean emit_XPD( struct compilation *cp, union instruction op ) 
-{
-   struct x86_reg arg0 = get_arg(cp, op.alu.file0, op.alu.idx0);
-   struct x86_reg arg1 = get_arg(cp, op.alu.file1, op.alu.idx1);
-   struct x86_reg dst = get_dst_xmm_reg(cp, FILE_REG, op.alu.dst);
-   struct x86_reg tmp0 = get_xmm_reg(cp);
-   struct x86_reg tmp1 = get_xmm_reg(cp);
-
-   /* Could avoid tmp0, tmp1 if we overwrote arg0, arg1.  Need a way
-    * to invalidate registers.  This will come with better analysis
-    * (liveness analysis) of the incoming program.
-    */
-   emit_pshufd(cp, dst, arg0, SHUF(Y, Z, X, W));
-   emit_pshufd(cp, tmp1, arg1, SHUF(Z, X, Y, W));
-   sse_mulps(&cp->func, dst, tmp1);
-   emit_pshufd(cp, tmp0, arg0, SHUF(Z, X, Y, W));
-   emit_pshufd(cp, tmp1, arg1, SHUF(Y, Z, X, W));
-   sse_mulps(&cp->func, tmp0, tmp1);
-   sse_subps(&cp->func, dst, tmp0);
-
-/*    dst[0] = arg0[1] * arg1[2] - arg0[2] * arg1[1]; */
-/*    dst[1] = arg0[2] * arg1[0] - arg0[0] * arg1[2]; */
-/*    dst[2] = arg0[0] * arg1[1] - arg0[1] * arg1[0]; */
-/*    dst[3] is undef */
-
-   return GL_TRUE;
-}
-
-static GLboolean emit_NOP( struct compilation *cp, union instruction op ) 
-{
-   return GL_TRUE;
-}
-
-
-static GLboolean (* const emit_func[])(struct compilation *, union instruction) = 
-{
-   emit_ABS,
-   emit_ADD,
-   emit_NOP, /* ARA */
-   emit_NOP, /* ARL */
-   emit_NOP, /* ARL_NV */
-   emit_NOP, /* ARR */
-   emit_NOP, /* BRA */
-   emit_NOP, /* CAL */
-   emit_NOP, /* CMP */
-   emit_NOP, /* COS */
-   emit_NOP, /* DDX */
-   emit_NOP, /* DDY */
-   emit_DP3,
-   emit_DP4,
-   emit_DPH,
-   emit_DST,
-   emit_NOP, /* END */
-   emit_EX2,
-   emit_EXP,
-   emit_FLR,
-   emit_FRC,
-   emit_NOP, /* KIL */
-   emit_NOP, /* KIL_NV */
-   emit_LG2,
-   emit_LIT,
-   emit_LOG,
-   emit_NOP, /* LRP */
-   emit_NOP, /* MAD */
-   emit_MAX,
-   emit_MIN,
-   emit_MOV,
-   emit_MUL,
-   emit_NOP, /* PK2H */
-   emit_NOP, /* PK2US */
-   emit_NOP, /* PK4B */
-   emit_NOP, /* PK4UB */
-   emit_POW,
-   emit_NOP, /* POPA */
-   emit_PRT,
-   emit_NOP, /* PUSHA */
-   emit_NOP, /* RCC */
-   emit_RCP,
-   emit_NOP, /* RET */
-   emit_NOP, /* RFL */
-   emit_RSQ,
-   emit_NOP, /* SCS */
-   emit_NOP, /* SEQ */
-   emit_NOP, /* SFL */
-   emit_SGE,
-   emit_NOP, /* SGT */
-   emit_NOP, /* SIN */
-   emit_NOP, /* SLE */
-   emit_SLT,
-   emit_NOP, /* SNE */
-   emit_NOP, /* SSG */
-   emit_NOP, /* STR */
-   emit_SUB,
-   emit_SWZ, /* SWZ */
-   emit_NOP, /* TEX */
-   emit_NOP, /* TXB */
-   emit_NOP, /* TXD */
-   emit_NOP, /* TXL */
-   emit_NOP, /* TXP */
-   emit_NOP, /* TXP_NV */
-   emit_NOP, /* UP2H */
-   emit_NOP, /* UP2US */
-   emit_NOP, /* UP4B */
-   emit_NOP, /* UP4UB */
-   emit_NOP, /* X2D */
-   emit_XPD,
-   emit_RSW,
-   emit_MSK,
-   emit_REL,
-};
-
-
-
-static GLboolean build_vertex_program( struct compilation *cp )
-{
-   struct arb_vp_machine *m = NULL;
-   GLuint j;
-
-   struct x86_reg regEBX = x86_make_reg(file_REG32, reg_BX);
-   struct x86_reg regECX = x86_make_reg(file_REG32, reg_CX);
-   struct x86_reg regEDX = x86_make_reg(file_REG32, reg_DX);
-
-   x86_push(&cp->func, regEBX);
-
-   x86_mov(&cp->func, regEDX, x86_fn_arg(&cp->func, 1));   
-   x86_mov(&cp->func, regEBX, x86_make_disp(regEDX, get_offset(m, m->File + FILE_REG)));
-   x86_mov(&cp->func, regECX, x86_make_disp(regEDX, get_offset(m, m->File + FILE_STATE_PARAM)));
-
-   for (j = 0; j < cp->p->nr_instructions; j++) {
-      union instruction inst = cp->p->instructions[j];  
-      cp->insn_counter = j+1;  /* avoid zero */
-      
-      if (DISASSEM) {
-        _mesa_printf("%p: ", cp->func.csr); 
-        _tnl_disassem_vba_insn( inst );
-      }
-      cp->func.fn = NULL;
-
-      if (!emit_func[inst.alu.opcode]( cp, inst )) {
-        return GL_FALSE;
-      }
-   }
-
-   /* TODO: only for outputs:
-    */
-   for (j = 0; j < 8; j++) {
-      if (cp->xmm[j].dirty) 
-        spill(cp, j);
-   }
-      
-
-   /* Exit mmx state?
-    */
-   if (cp->func.need_emms)
-      mmx_emms(&cp->func);
-
-   /* Restore FPU control word?
-    */
-   if (cp->fpucntl != RESTORE_FPU) {
-      x87_fnclex(&cp->func);
-      x87_fldcw(&cp->func, x86_make_disp(regEDX, get_offset(m, &m->fpucntl_restore)));
-   }
-
-   x86_pop(&cp->func, regEBX);
-   x86_ret(&cp->func);
-
-   return GL_TRUE;
-}
-
-/**
- * Execute the given vertex program.  
- * 
- * TODO: Integrate the t_vertex.c code here, to build machine vertices
- * directly at this point.
- *
- * TODO: Eliminate the VB struct entirely and just use
- * struct arb_vertex_machine.
- */
-GLboolean
-_tnl_sse_codegen_vertex_program(struct tnl_compiled_program *p)
-{
-   struct compilation cp;
-   
-   /* sanity checks */
-   assert(emit_func[OPCODE_ABS] == emit_ABS);
-   assert(emit_func[OPCODE_MUL] == emit_MUL);
-   assert(emit_func[OPCODE_XPD] == emit_XPD);
-
-   _mesa_memset(&cp, 0, sizeof(cp));
-   cp.p = p;
-   cp.have_sse2 = 1;
-
-   if (p->compiled_func) {
-      _mesa_free((void *)p->compiled_func);
-      p->compiled_func = NULL;
-   }
-
-   x86_init_func(&cp.func);
-
-   cp.fpucntl = RESTORE_FPU;
-
-
-   /* Note ctx state is not referenced in building the function, so it
-    * depends only on the list of instructions:
-    */
-   if (!build_vertex_program(&cp)) {
-      x86_release_func( &cp.func );
-      return GL_FALSE;
-   }
-
-
-   p->compiled_func = (void (*)(struct arb_vp_machine *))x86_get_func( &cp.func );
-   return GL_TRUE;
-}
-
-
-
-#else
-
-GLboolean
-_tnl_sse_codegen_vertex_program(struct tnl_compiled_program *p)
-{
-   /* Dummy version for when USE_SSE_ASM not defined */
-   return GL_FALSE;
-}
-
-#endif