From 7c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7 Mon Sep 17 00:00:00 2001
From: Keith Whitwell <keith@tungstengraphics.com>
Date: Thu, 21 Apr 2005 14:46:57 +0000
Subject: Reduce the size of mesa's internal fragment and vertex program
 representations by switching to packed structures for registers and
 instructions.

---
 src/mesa/drivers/dri/i915/i915_fragprog.c |  38 +--
 src/mesa/main/mtypes.h                    |  23 +-
 src/mesa/shader/arbfragparse.c            |  45 +--
 src/mesa/shader/arbprogparse.c            | 464 ++++++++++++++++++------------
 src/mesa/shader/arbvertparse.c            | 208 ++++++--------
 src/mesa/shader/arbvertparse.h            |   3 +
 src/mesa/shader/grammar.c                 |   1 -
 src/mesa/shader/nvfragparse.c             | 188 ++++++------
 src/mesa/shader/nvfragprog.h              |  48 ++--
 src/mesa/shader/nvvertexec.c              |  38 +--
 src/mesa/shader/nvvertparse.c             | 121 ++++----
 src/mesa/shader/nvvertprog.h              |  75 +++--
 src/mesa/shader/program.c                 |  48 +++-
 src/mesa/shader/program.h                 |  31 +-
 src/mesa/swrast/s_nvfragprog.c            |  73 ++---
 15 files changed, 774 insertions(+), 630 deletions(-)

(limited to 'src/mesa')

diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c
index 40e118ec414..dae28cb0bcb 100644
--- a/src/mesa/drivers/dri/i915/i915_fragprog.c
+++ b/src/mesa/drivers/dri/i915/i915_fragprog.c
@@ -130,7 +130,7 @@ static GLuint src_vector( struct i915_fragment_program *p,
       case PROGRAM_STATE_VAR:
       case PROGRAM_NAMED_PARAM:
          src = i915_emit_param4fv( 
-	    p, program->Parameters->Parameters[source->Index].Values );
+	    p, program->Parameters->ParameterValues[source->Index] );
 	 break;
 
       default:
@@ -139,10 +139,10 @@ static GLuint src_vector( struct i915_fragment_program *p,
    }
 
    src = swizzle(src, 
-		 source->Swizzle[0],
-		 source->Swizzle[1],
-		 source->Swizzle[2],
-		 source->Swizzle[3]);
+		 GET_SWZ(source->Swizzle, 0),
+		 GET_SWZ(source->Swizzle, 1),
+		 GET_SWZ(source->Swizzle, 2),
+		 GET_SWZ(source->Swizzle, 3));
 
    if (source->NegateBase)
       src = negate( src, 1,1,1,1 );
@@ -179,30 +179,30 @@ static GLuint get_result_flags( const struct fp_instruction *inst )
    GLuint flags = 0;
 
    if (inst->Saturate) flags |= A0_DEST_SATURATE;
-   if (inst->DstReg.WriteMask[0]) flags |= A0_DEST_CHANNEL_X;
-   if (inst->DstReg.WriteMask[1]) flags |= A0_DEST_CHANNEL_Y;
-   if (inst->DstReg.WriteMask[2]) flags |= A0_DEST_CHANNEL_Z;
-   if (inst->DstReg.WriteMask[3]) flags |= A0_DEST_CHANNEL_W;
+   if (inst->DstReg.WriteMask & WRITEMASK_X) flags |= A0_DEST_CHANNEL_X;
+   if (inst->DstReg.WriteMask & WRITEMASK_Y) flags |= A0_DEST_CHANNEL_Y;
+   if (inst->DstReg.WriteMask & WRITEMASK_Z) flags |= A0_DEST_CHANNEL_Z;
+   if (inst->DstReg.WriteMask & WRITEMASK_W) flags |= A0_DEST_CHANNEL_W;
 
    return flags;
 }
 
-static GLuint translate_tex_src_bit( struct i915_fragment_program *p,
+static GLuint translate_tex_src_idx( struct i915_fragment_program *p,
 				     GLubyte bit )
 {
    switch (bit) {
-   case TEXTURE_1D_BIT:   return D0_SAMPLE_TYPE_2D;
-   case TEXTURE_2D_BIT:   return D0_SAMPLE_TYPE_2D;
-   case TEXTURE_RECT_BIT: return D0_SAMPLE_TYPE_2D;
-   case TEXTURE_3D_BIT:   return D0_SAMPLE_TYPE_VOLUME;
-   case TEXTURE_CUBE_BIT: return D0_SAMPLE_TYPE_CUBE;
+   case TEXTURE_1D_INDEX:   return D0_SAMPLE_TYPE_2D;
+   case TEXTURE_2D_INDEX:   return D0_SAMPLE_TYPE_2D;
+   case TEXTURE_RECT_INDEX: return D0_SAMPLE_TYPE_2D;
+   case TEXTURE_3D_INDEX:   return D0_SAMPLE_TYPE_VOLUME;
+   case TEXTURE_CUBE_INDEX: return D0_SAMPLE_TYPE_CUBE;
    default: i915_program_error(p, "TexSrcBit"); return 0;
    }
 }
 
 #define EMIT_TEX( OP )						\
 do {								\
-   GLuint dim = translate_tex_src_bit( p, inst->TexSrcBit );	\
+   GLuint dim = translate_tex_src_idx( p, inst->TexSrcIdx );	\
    GLuint sampler = i915_emit_decl(p, REG_TYPE_S,		\
 				  inst->TexSrcUnit, dim);	\
    GLuint coord = src_vector( p, &inst->SrcReg[0], program);	\
@@ -592,10 +592,10 @@ static void upload_program( struct i915_fragment_program *p )
 			 swizzle(tmp, X,Y,X,Y), 
 			 swizzle(tmp, X,X,ONE,ONE), 0);
 
-	 if (inst->DstReg.WriteMask[1]) {
+	 if (inst->DstReg.WriteMask & WRITEMASK_Y) {
 	    GLuint tmp1;
 	    
-	    if (inst->DstReg.WriteMask[0])
+	    if (inst->DstReg.WriteMask & WRITEMASK_X)
 	       tmp1 = i915_get_utemp( p );
 	    else
 	       tmp1 = tmp;
@@ -614,7 +614,7 @@ static void upload_program( struct i915_fragment_program *p )
 			    i915_emit_const4fv( p, sin_constants ), 0);
 	 }
 
-	 if (inst->DstReg.WriteMask[0]) {
+	 if (inst->DstReg.WriteMask & WRITEMASK_X) {
 	    i915_emit_arith( p, 
 			    A0_MUL,
 			    tmp, A0_DEST_CHANNEL_XYZ, 0,
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 37803b7b4bd..ac9fc87d1e4 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -213,6 +213,27 @@ enum
 /*@}*/
 
 
+/**
+ * Indexes for vertex program result attributes
+ */
+#define VERT_RESULT_HPOS 0
+#define VERT_RESULT_COL0 1
+#define VERT_RESULT_COL1 2
+#define VERT_RESULT_BFC0 3
+#define VERT_RESULT_BFC1 4
+#define VERT_RESULT_FOGC 5
+#define VERT_RESULT_PSIZ 6
+#define VERT_RESULT_TEX0 7
+#define VERT_RESULT_TEX1 8
+#define VERT_RESULT_TEX2 9
+#define VERT_RESULT_TEX3 10
+#define VERT_RESULT_TEX4 11
+#define VERT_RESULT_TEX5 12
+#define VERT_RESULT_TEX6 13
+#define VERT_RESULT_TEX7 14
+#define VERT_RESULT_MAX  15
+
+
 /**
  * Indexes for fragment program input attributes.
  */
@@ -1679,7 +1700,7 @@ struct atifs_machine
  */
 enum register_file
 {
-   PROGRAM_TEMPORARY = 10,
+   PROGRAM_TEMPORARY,
    PROGRAM_INPUT,
    PROGRAM_OUTPUT,
    PROGRAM_LOCAL_PARAM,
diff --git a/src/mesa/shader/arbfragparse.c b/src/mesa/shader/arbfragparse.c
index 9c85d3413a1..5a2eb02eacc 100644
--- a/src/mesa/shader/arbfragparse.c
+++ b/src/mesa/shader/arbfragparse.c
@@ -35,6 +35,7 @@
 #include "imports.h"
 #include "macros.h"
 #include "mtypes.h"
+#include "program.h"
 #include "arbprogparse.h"
 #include "arbfragparse.h"
 
@@ -43,9 +44,9 @@ _mesa_debug_fp_inst(GLint num, struct fp_instruction *fp)
 {
    GLint a;
  
-   fprintf(stderr, "PROGRAM_OUTPUT: 0x%x\n",    PROGRAM_OUTPUT);
-   fprintf(stderr, "PROGRAM_INPUT: 0x%x\n",     PROGRAM_INPUT);
-   fprintf(stderr, "PROGRAM_TEMPORARY: 0x%x\n", PROGRAM_TEMPORARY);
+/*    fprintf(stderr, "PROGRAM_OUTPUT: 0x%x\n",    PROGRAM_OUTPUT); */
+/*    fprintf(stderr, "PROGRAM_INPUT: 0x%x\n",     PROGRAM_INPUT); */
+/*    fprintf(stderr, "PROGRAM_TEMPORARY: 0x%x\n", PROGRAM_TEMPORARY); */
 
    for (a=0; a<num; a++) {
       switch (fp[a].Opcode) {
@@ -153,28 +154,30 @@ _mesa_debug_fp_inst(GLint num, struct fp_instruction *fp)
       }
 
       fprintf(stderr, " D(0x%x:%d:%d%d%d%d) ", 
-         fp[a].DstReg.File, fp[a].DstReg.Index,
-         fp[a].DstReg.WriteMask[0], fp[a].DstReg.WriteMask[1], 
-         fp[a].DstReg.WriteMask[2], fp[a].DstReg.WriteMask[3]); 
-						 
+	      fp[a].DstReg.File, fp[a].DstReg.Index,
+	      GET_BIT(fp[a].DstReg.WriteMask, 0), 
+	      GET_BIT(fp[a].DstReg.WriteMask, 1), 
+	      GET_BIT(fp[a].DstReg.WriteMask, 2), 
+	      GET_BIT(fp[a].DstReg.WriteMask, 3));
+      
       fprintf(stderr, "S1(0x%x:%d:%d%d%d%d) ", fp[a].SrcReg[0].File, fp[a].SrcReg[0].Index,
-         fp[a].SrcReg[0].Swizzle[0],
-         fp[a].SrcReg[0].Swizzle[1],
-         fp[a].SrcReg[0].Swizzle[2],
-         fp[a].SrcReg[0].Swizzle[3]);
+	      GET_SWZ(fp[a].SrcReg[0].Swizzle, 0),
+	      GET_SWZ(fp[a].SrcReg[0].Swizzle, 1),
+	      GET_SWZ(fp[a].SrcReg[0].Swizzle, 2),
+	      GET_SWZ(fp[a].SrcReg[0].Swizzle, 3));
 
       fprintf(stderr, "S2(0x%x:%d:%d%d%d%d) ", fp[a].SrcReg[1].File, fp[a].SrcReg[1].Index,
-        fp[a].SrcReg[1].Swizzle[0],
-        fp[a].SrcReg[1].Swizzle[1],
-        fp[a].SrcReg[1].Swizzle[2],
-        fp[a].SrcReg[1].Swizzle[3]);
-
+	      GET_SWZ(fp[a].SrcReg[1].Swizzle, 0),
+	      GET_SWZ(fp[a].SrcReg[1].Swizzle, 1),
+	      GET_SWZ(fp[a].SrcReg[1].Swizzle, 2),
+	      GET_SWZ(fp[a].SrcReg[1].Swizzle, 3));
+       
       fprintf(stderr, "S3(0x%x:%d:%d%d%d%d)",  fp[a].SrcReg[2].File, fp[a].SrcReg[2].Index,
-        fp[a].SrcReg[2].Swizzle[0],
-        fp[a].SrcReg[2].Swizzle[1],
-        fp[a].SrcReg[2].Swizzle[2],
-        fp[a].SrcReg[2].Swizzle[3]);
-
+	      GET_SWZ(fp[a].SrcReg[2].Swizzle, 0),
+	      GET_SWZ(fp[a].SrcReg[2].Swizzle, 1),
+	      GET_SWZ(fp[a].SrcReg[2].Swizzle, 2),
+	      GET_SWZ(fp[a].SrcReg[2].Swizzle, 3));
+      
       fprintf(stderr, "\n");
    }
 }
diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c
index 2bf54c62158..4a907afc75f 100644
--- a/src/mesa/shader/arbprogparse.c
+++ b/src/mesa/shader/arbprogparse.c
@@ -2232,10 +2232,9 @@ parse_declaration (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
 static GLuint
 parse_masked_dst_reg (GLcontext * ctx, GLubyte ** inst,
                       struct var_cache **vc_head, struct arb_program *Program,
-                      GLint * File, GLint * Index, GLboolean * WriteMask)
+                      GLint * File, GLint * Index, GLint *WriteMask)
 {
-   GLuint result;
-   GLubyte mask;
+   GLuint result, tmp;
    struct var_cache *dst;
 
    /* We either have a result register specified, or a
@@ -2311,13 +2310,14 @@ parse_masked_dst_reg (GLcontext * ctx, GLubyte ** inst,
     *  z,b -> bit 1
     *  y,g -> bit 2
     *  x,r -> bit 3
+    *
+    * ==> Need to reverse the order of bits for this!
     */
-   mask = *(*inst)++;
-
-   WriteMask[0] = (GLboolean) (mask & (1 << 3)) >> 3;
-   WriteMask[1] = (GLboolean) (mask & (1 << 2)) >> 2;
-   WriteMask[2] = (GLboolean) (mask & (1 << 1)) >> 1;
-   WriteMask[3] = (GLboolean) (mask & (1));
+   tmp =  (GLint) *(*inst)++;
+   *WriteMask = (((tmp>>3) & 0x1) |
+		 ((tmp>>1) & 0x2) |
+		 ((tmp<<1) & 0x4) |
+		 ((tmp<<3) & 0x8));
 
    return 0;
 }
@@ -2498,6 +2498,8 @@ parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
    GLuint binding_state, binding_idx, is_generic, found;
    GLint offset;
 
+   *IsRelOffset = 0;
+
    /* And the binding for the src */
    switch (*(*inst)++) {
       case REGISTER_ATTRIB:
@@ -2652,45 +2654,94 @@ parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
 /**
  */
 static GLuint
-parse_vector_src_reg (GLcontext * ctx, GLubyte ** inst,
-                      struct var_cache **vc_head, struct arb_program *Program,
-                      GLint * File, GLint * Index, GLboolean * Negate,
-                      GLubyte * Swizzle, GLboolean *IsRelOffset)
+parse_fp_vector_src_reg (GLcontext * ctx, GLubyte ** inst,
+			 struct var_cache **vc_head, struct arb_program *Program,
+			 struct fp_src_register *reg )
 {
+
+   GLint File;
+   GLint Index;
+   GLboolean Negate;
+   GLubyte Swizzle[4];
+   GLboolean IsRelOffset;
+
    /* Grab the sign */
-   *Negate = (parse_sign (inst) == -1);
+   Negate = (parse_sign (inst) == -1) ? 0xf : 0x0;
 
    /* And the src reg */
-   if (parse_src_reg (ctx, inst, vc_head, Program, File, Index, IsRelOffset))
+   if (parse_src_reg (ctx, inst, vc_head, Program, &File, &Index, &IsRelOffset))
       return 1;
 
    /* finally, the swizzle */
    parse_swizzle_mask (inst, Swizzle, 4);
 
+   reg->File = File;
+   reg->Index = Index;
+   reg->Abs = 0;		/* NV only */
+   reg->NegateAbs = 0;		/* NV only */
+   reg->NegateBase = Negate;
+   reg->Swizzle = (Swizzle[0] << 0 |
+		   Swizzle[1] << 3 |
+		   Swizzle[2] << 6 |
+		   Swizzle[3] << 9);
+
    return 0;
 }
 
-/**
- */
+
+static GLuint 
+parse_fp_dst_reg(GLcontext * ctx, GLubyte ** inst,
+		 struct var_cache **vc_head, struct arb_program *Program,
+		 struct fp_dst_register *reg )
+{
+   GLint file, idx, mask;
+   
+   if (parse_masked_dst_reg (ctx, inst, vc_head, Program, &file, &idx, &mask))
+      return 1;
+
+   reg->CondMask = 0;		/* NV only */
+   reg->CondSwizzle = 0;	/* NV only */
+   reg->File = file;
+   reg->Index = idx;
+   reg->WriteMask = mask;
+   return 0;
+}
+
+
+
 static GLuint
-parse_scalar_src_reg (GLcontext * ctx, GLubyte ** inst,
-                      struct var_cache **vc_head, struct arb_program *Program,
-                      GLint * File, GLint * Index, GLboolean * Negate,
-                      GLubyte * Swizzle, GLboolean *IsRelOffset)
+parse_fp_scalar_src_reg (GLcontext * ctx, GLubyte ** inst,
+			 struct var_cache **vc_head, struct arb_program *Program,
+			 struct fp_src_register *reg )
 {
+
+   GLint File;
+   GLint Index;
+   GLboolean Negate;
+   GLubyte Swizzle[4];
+   GLboolean IsRelOffset;
+
    /* Grab the sign */
-   *Negate = (parse_sign (inst) == -1);
+   Negate = (parse_sign (inst) == -1) ? 0x1 : 0x0;
 
    /* And the src reg */
-   if (parse_src_reg (ctx, inst, vc_head, Program, File, Index, IsRelOffset))
+   if (parse_src_reg (ctx, inst, vc_head, Program, &File, &Index, &IsRelOffset))
       return 1;
 
-   /* Now, get the component and shove it into all the swizzle slots  */
+   /* finally, the swizzle */
    parse_swizzle_mask (inst, Swizzle, 1);
 
+   reg->File = File;
+   reg->Index = Index;
+   reg->Abs = 0;		/* NV only */
+   reg->NegateAbs = 0;		/* NV only */
+   reg->NegateBase = Negate;
+   reg->Swizzle = (Swizzle[0] << 0);
+
    return 0;
 }
 
+
 /**
  * This is a big mother that handles getting opcodes into the instruction
  * and handling the src & dst registers for fragment program instructions
@@ -2700,8 +2751,7 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst,
                       struct var_cache **vc_head, struct arb_program *Program,
                       struct fp_instruction *fp)
 {
-   GLint a, b;
-   GLubyte swz[4]; /* FP's swizzle mask is a GLubyte, while VP's is GLuint */
+   GLint a;
    GLuint texcoord;
    GLubyte instClass, type, code;
    GLboolean rel;
@@ -2774,20 +2824,11 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst,
                break;
          }
 
-         if (parse_masked_dst_reg
-             (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
-              &fp->DstReg.Index, fp->DstReg.WriteMask))
+         if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
             return 1;
 
-         fp->SrcReg[0].Abs = GL_FALSE;
-         fp->SrcReg[0].NegateAbs = GL_FALSE;
-         if (parse_vector_src_reg
-             (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
-              &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
-              swz, &rel))
+         if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
             return 1;
-         for (b=0; b<4; b++)
-            fp->SrcReg[0].Swizzle[b] = swz[b];
          break;
 
       case OP_ALU_SCALAR:
@@ -2836,19 +2877,11 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst,
                break;
          }
 
-         if (parse_masked_dst_reg
-             (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
-              &fp->DstReg.Index, fp->DstReg.WriteMask))
+         if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
             return 1;
-         fp->SrcReg[0].Abs = GL_FALSE;
-         fp->SrcReg[0].NegateAbs = GL_FALSE;
-         if (parse_scalar_src_reg
-             (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
-              &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
-              swz, &rel))
+
+         if (parse_fp_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
             return 1;
-         for (b=0; b<4; b++)
-            fp->SrcReg[0].Swizzle[b] = swz[b];
          break;
 
       case OP_ALU_BINSC:
@@ -2860,20 +2893,12 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst,
                break;
          }
 
-         if (parse_masked_dst_reg
-             (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
-              &fp->DstReg.Index, fp->DstReg.WriteMask))
+         if (parse_fp_dst_reg(ctx, inst, vc_head, Program, &fp->DstReg))
             return 1;
+
          for (a = 0; a < 2; a++) {
-            fp->SrcReg[a].Abs = GL_FALSE;
-            fp->SrcReg[a].NegateAbs = GL_FALSE;
-            if (parse_scalar_src_reg
-                (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File,
-                 &fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase,
-                 swz, &rel))
+	    if (parse_fp_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a]))
                return 1;
-            for (b=0; b<4; b++)
-               fp->SrcReg[a].Swizzle[b] = swz[b];
          }
          break;
 
@@ -2953,20 +2978,11 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst,
                break;
          }
 
-         if (parse_masked_dst_reg
-             (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
-              &fp->DstReg.Index, fp->DstReg.WriteMask))
+         if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
             return 1;
          for (a = 0; a < 2; a++) {
-            fp->SrcReg[a].Abs = GL_FALSE;
-            fp->SrcReg[a].NegateAbs = GL_FALSE;
-            if (parse_vector_src_reg
-                (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File,
-                 &fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase,
-                 swz, &rel))
-               return 1;
-            for (b=0; b<4; b++)
-               fp->SrcReg[a].Swizzle[b] = swz[b];
+	    if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a]))
+	       return 1;
          }
          break;
 
@@ -2991,20 +3007,12 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst,
                break;
          }
 
-         if (parse_masked_dst_reg
-             (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
-              &fp->DstReg.Index, fp->DstReg.WriteMask))
+         if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
             return 1;
+
          for (a = 0; a < 3; a++) {
-            fp->SrcReg[a].Abs = GL_FALSE;
-            fp->SrcReg[a].NegateAbs = GL_FALSE;
-            if (parse_vector_src_reg
-                (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File,
-                 &fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase,
-                 swz, &rel))
-               return 1;
-            for (b=0; b<4; b++)
-               fp->SrcReg[a].Swizzle[b] = swz[b];
+	    if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a]))
+	       return 1;
          }
          break;
 
@@ -3016,19 +3024,28 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst,
                fp->Opcode = FP_OPCODE_SWZ;
                break;
          }
-         if (parse_masked_dst_reg
-             (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
-              &fp->DstReg.Index, fp->DstReg.WriteMask))
+         if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
             return 1;
 
-         if (parse_src_reg
-             (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
-              &fp->SrcReg[0].Index, &rel))
-            return 1;
-         parse_extended_swizzle_mask (inst, swz,
-                                      &fp->SrcReg[0].NegateBase);
-         for (b=0; b<4; b++)
-            fp->SrcReg[0].Swizzle[b] = swz[b];
+	 {
+	    GLubyte Swizzle[4]; /* FP's swizzle mask is a GLubyte, while VP's is GLuint */
+	    GLubyte Negate[4];
+	    GLint File, Index;
+
+	    if (parse_src_reg(ctx, inst, vc_head, Program, &File, &Index, &rel))
+	       return 1;
+	    parse_extended_swizzle_mask (inst, Swizzle, Negate);
+	    fp->SrcReg[0].File = File;
+	    fp->SrcReg[0].Index = Index;
+	    fp->SrcReg[0].NegateBase = (Negate[0] << 0 |
+					Negate[1] << 1 |
+					Negate[2] << 2 |
+					Negate[3] << 3);
+	    fp->SrcReg[0].Swizzle = (Swizzle[0] << 0 |
+				     Swizzle[1] << 3 |
+				     Swizzle[2] << 6 |
+				     Swizzle[3] << 9);
+	 }
          break;
 
       case OP_TEX_SAMPLE:
@@ -3046,26 +3063,17 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst,
                break;
 
             case OP_TXB_SAT:
-
                fp->Saturate = 1;
             case OP_TXB:
                fp->Opcode = FP_OPCODE_TXB;
                break;
          }
 
-         if (parse_masked_dst_reg
-             (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
-              &fp->DstReg.Index, fp->DstReg.WriteMask))
+         if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
             return 1;
-         fp->SrcReg[0].Abs = GL_FALSE;
-         fp->SrcReg[0].NegateAbs = GL_FALSE;
-         if (parse_vector_src_reg
-             (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
-              &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
-              swz, &rel))
+
+	 if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
             return 1;
-         for (b=0; b<4; b++)
-            fp->SrcReg[0].Swizzle[b] = swz[b];
 
          /* texImageUnit */
          if (parse_texcoord_num (ctx, inst, Program, &texcoord))
@@ -3075,19 +3083,19 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst,
          /* texTarget */
          switch (*(*inst)++) {
             case TEXTARGET_1D:
-               fp->TexSrcBit = TEXTURE_1D_BIT;
+               fp->TexSrcIdx = TEXTURE_1D_INDEX;
                break;
             case TEXTARGET_2D:
-               fp->TexSrcBit = TEXTURE_2D_BIT;
+               fp->TexSrcIdx = TEXTURE_2D_INDEX;
                break;
             case TEXTARGET_3D:
-               fp->TexSrcBit = TEXTURE_3D_BIT;
+               fp->TexSrcIdx = TEXTURE_3D_INDEX;
                break;
             case TEXTARGET_RECT:
-               fp->TexSrcBit = TEXTURE_RECT_BIT;
+               fp->TexSrcIdx = TEXTURE_RECT_INDEX;
                break;
             case TEXTARGET_CUBE:
-               fp->TexSrcBit = TEXTURE_CUBE_BIT;
+               fp->TexSrcIdx = TEXTURE_CUBE_INDEX;
                break;
 	    case TEXTARGET_SHADOW1D:
 	    case TEXTARGET_SHADOW2D:
@@ -3095,26 +3103,131 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst,
 	       /* TODO ARB_fragment_program_shadow code */
 	       break;
          }
-         Program->TexturesUsed[texcoord] |= fp->TexSrcBit;
+         Program->TexturesUsed[texcoord] |= (1<<fp->TexSrcIdx);
          break;
 
       case OP_TEX_KIL:
-         fp->Opcode = FP_OPCODE_KIL;
-         fp->SrcReg[0].Abs = GL_FALSE;
-         fp->SrcReg[0].NegateAbs = GL_FALSE;
-         if (parse_vector_src_reg
-             (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
-              &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
-              swz, &rel))
+	 if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
             return 1;
-         for (b=0; b<4; b++)
-            fp->SrcReg[0].Swizzle[b] = swz[b];
          break;
    }
 
    return 0;
 }
 
+static GLuint 
+parse_vp_dst_reg(GLcontext * ctx, GLubyte ** inst,
+		 struct var_cache **vc_head, struct arb_program *Program,
+		 struct vp_dst_register *reg )
+{
+   GLint file, idx, mask;
+
+   if (parse_masked_dst_reg(ctx, inst, vc_head, Program, &file, &idx, &mask))
+      return 1;
+
+   reg->File = file;
+   reg->Index = idx;
+   reg->WriteMask = mask;
+   return 0;
+}
+
+/**
+ * Handle the parsing out of a masked address register
+ *
+ * \param Index     - The register index we write to
+ * \param WriteMask - The mask controlling which components we write (1->write)
+ *
+ * \return 0 on sucess, 1 on error
+ */
+static GLuint
+parse_vp_address_reg (GLcontext * ctx, GLubyte ** inst,
+		      struct var_cache **vc_head,
+		      struct arb_program *Program,
+		      struct vp_dst_register *reg)
+{
+   GLint idx;
+
+   if (parse_address_reg (ctx, inst, vc_head, Program, &idx))
+      return 1;
+
+   /* This should be 0x8 */
+   (*inst)++;
+
+   reg->File = PROGRAM_ADDRESS;
+   reg->Index = idx;
+
+   /* Writemask of .x is implied */
+   reg->WriteMask = 0x1;
+   return 0;
+}
+
+/**
+ */
+static GLuint
+parse_vp_vector_src_reg (GLcontext * ctx, GLubyte ** inst,
+			 struct var_cache **vc_head, struct arb_program *Program,
+			 struct vp_src_register *reg )
+{
+
+   GLint File;
+   GLint Index;
+   GLboolean Negate;
+   GLubyte Swizzle[4];
+   GLboolean IsRelOffset;
+
+   /* Grab the sign */
+   Negate = (parse_sign (inst) == -1) ? 0xf : 0x0;
+
+   /* And the src reg */
+   if (parse_src_reg (ctx, inst, vc_head, Program, &File, &Index, &IsRelOffset))
+      return 1;
+
+   /* finally, the swizzle */
+   parse_swizzle_mask (inst, Swizzle, 4);
+
+   reg->File = File;
+   reg->Index = Index;
+   reg->Swizzle = ((Swizzle[0] << 0) |
+		   (Swizzle[1] << 3) |
+		   (Swizzle[2] << 6) |
+		   (Swizzle[3] << 9));
+   reg->Negate = Negate;
+   reg->RelAddr = IsRelOffset;
+   return 0;
+}
+
+
+static GLuint
+parse_vp_scalar_src_reg (GLcontext * ctx, GLubyte ** inst,
+			 struct var_cache **vc_head, struct arb_program *Program,
+			 struct vp_src_register *reg )
+{
+
+   GLint File;
+   GLint Index;
+   GLboolean Negate;
+   GLubyte Swizzle[4];
+   GLboolean IsRelOffset;
+
+   /* Grab the sign */
+   Negate = (parse_sign (inst) == -1) ? 0x1 : 0x0;
+
+   /* And the src reg */
+   if (parse_src_reg (ctx, inst, vc_head, Program, &File, &Index, &IsRelOffset))
+      return 1;
+
+   /* finally, the swizzle */
+   parse_swizzle_mask (inst, Swizzle, 1);
+
+   reg->File = File;
+   reg->Index = Index;
+   reg->Swizzle = (Swizzle[0] << 0);
+   reg->Negate = Negate;
+   reg->RelAddr = IsRelOffset;
+   return 0;
+}
+
+
 /**
  * This is a big mother that handles getting opcodes into the instruction
  * and handling the src & dst registers for vertex program instructions
@@ -3135,17 +3248,12 @@ parse_vp_instruction (GLcontext * ctx, GLubyte ** inst,
 
    /* Record the position in the program string for debugging */
    vp->StringPos = Program->Position;
-
    vp->Data = NULL;
-
    vp->SrcReg[0].RelAddr = vp->SrcReg[1].RelAddr = vp->SrcReg[2].RelAddr = 0;
-
-   for (a = 0; a < 4; a++) {
-      vp->SrcReg[0].Swizzle[a] = a;
-      vp->SrcReg[1].Swizzle[a] = a;
-      vp->SrcReg[2].Swizzle[a] = a;
-      vp->DstReg.WriteMask[a] = 1;
-   }
+   vp->SrcReg[0].Swizzle = SWIZZLE_NOOP;
+   vp->SrcReg[1].Swizzle = SWIZZLE_NOOP;
+   vp->SrcReg[2].Swizzle = SWIZZLE_NOOP;
+   vp->DstReg.WriteMask = 0xf;
 
    switch (type) {
          /* XXX: */
@@ -3155,17 +3263,13 @@ parse_vp_instruction (GLcontext * ctx, GLubyte ** inst,
          /* Remember to set SrcReg.RelAddr; */
 
          /* Get the masked address register [dst] */
-         if (parse_masked_address_reg
-             (ctx, inst, vc_head, Program, &vp->DstReg.Index,
-              vp->DstReg.WriteMask))
+         if (parse_vp_address_reg(ctx, inst, vc_head, Program, &vp->DstReg))
             return 1;
+
          vp->DstReg.File = PROGRAM_ADDRESS;
 
          /* Get a scalar src register */
-         if (parse_scalar_src_reg
-             (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
-              &vp->SrcReg[0].Index, &vp->SrcReg[0].Negate,
-              vp->SrcReg[0].Swizzle, &vp->SrcReg[0].RelAddr))
+	 if (parse_vp_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0]))
             return 1;
 
          break;
@@ -3188,14 +3292,11 @@ parse_vp_instruction (GLcontext * ctx, GLubyte ** inst,
                vp->Opcode = VP_OPCODE_MOV;
                break;
          }
-         if (parse_masked_dst_reg
-             (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
-              &vp->DstReg.Index, vp->DstReg.WriteMask))
+
+         if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
             return 1;
-         if (parse_vector_src_reg
-             (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
-              &vp->SrcReg[0].Index, &vp->SrcReg[0].Negate,
-              vp->SrcReg[0].Swizzle, &vp->SrcReg[0].RelAddr))
+
+         if (parse_vp_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0]))
             return 1;
          break;
 
@@ -3220,14 +3321,10 @@ parse_vp_instruction (GLcontext * ctx, GLubyte ** inst,
                vp->Opcode = VP_OPCODE_RSQ;
                break;
          }
-         if (parse_masked_dst_reg
-             (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
-              &vp->DstReg.Index, vp->DstReg.WriteMask))
+         if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
             return 1;
-         if (parse_scalar_src_reg
-             (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
-              &vp->SrcReg[0].Index, &vp->SrcReg[0].Negate,
-              vp->SrcReg[0].Swizzle, &vp->SrcReg[0].RelAddr))
+
+	 if (parse_vp_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0]))
             return 1;
          break;
 
@@ -3237,15 +3334,11 @@ parse_vp_instruction (GLcontext * ctx, GLubyte ** inst,
                vp->Opcode = VP_OPCODE_POW;
                break;
          }
-         if (parse_masked_dst_reg
-             (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
-              &vp->DstReg.Index, vp->DstReg.WriteMask))
+         if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
             return 1;
+
          for (a = 0; a < 2; a++) {
-            if (parse_scalar_src_reg
-                (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File,
-                 &vp->SrcReg[a].Index, &vp->SrcReg[a].Negate,
-                 vp->SrcReg[a].Swizzle, &vp->SrcReg[a].RelAddr))
+	    if (parse_vp_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a]))
                return 1;
          }
          break;
@@ -3289,15 +3382,11 @@ parse_vp_instruction (GLcontext * ctx, GLubyte ** inst,
                vp->Opcode = VP_OPCODE_XPD;
                break;
          }
-         if (parse_masked_dst_reg
-             (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
-              &vp->DstReg.Index, vp->DstReg.WriteMask))
+         if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
             return 1;
+
          for (a = 0; a < 2; a++) {
-            if (parse_vector_src_reg
-                (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File,
-                 &vp->SrcReg[a].Index, &vp->SrcReg[a].Negate,
-                 vp->SrcReg[a].Swizzle, &vp->SrcReg[a].RelAddr))
+	    if (parse_vp_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a]))
                return 1;
          }
          break;
@@ -3309,15 +3398,11 @@ parse_vp_instruction (GLcontext * ctx, GLubyte ** inst,
                break;
          }
 
-         if (parse_masked_dst_reg
-             (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
-              &vp->DstReg.Index, vp->DstReg.WriteMask))
+         if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
             return 1;
+
          for (a = 0; a < 3; a++) {
-            if (parse_vector_src_reg
-                (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File,
-                 &vp->SrcReg[a].Index, &vp->SrcReg[a].Negate,
-                 vp->SrcReg[a].Swizzle, &vp->SrcReg[a].RelAddr))
+	    if (parse_vp_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a]))
                return 1;
          }
          break;
@@ -3328,17 +3413,30 @@ parse_vp_instruction (GLcontext * ctx, GLubyte ** inst,
                vp->Opcode = VP_OPCODE_SWZ;
                break;
          }
-         if (parse_masked_dst_reg
-             (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
-              &vp->DstReg.Index, vp->DstReg.WriteMask))
-            return 1;
-
-         if (parse_src_reg
-             (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
-              &vp->SrcReg[0].Index, &vp->SrcReg[0].RelAddr))
-            return 1;
-         parse_extended_swizzle_mask (inst, vp->SrcReg[0].Swizzle,
-                                      &vp->SrcReg[0].Negate);
+	 {
+	    GLubyte Swizzle[4]; /* FP's swizzle mask is a GLubyte, while VP's is GLuint */
+	    GLubyte Negate[4];
+	    GLboolean RelAddr;
+	    GLint File, Index;
+
+	    if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
+	       return 1;
+
+	    if (parse_src_reg(ctx, inst, vc_head, Program, &File, &Index, &RelAddr))
+	       return 1;
+	    parse_extended_swizzle_mask (inst, Swizzle, Negate);
+	    vp->SrcReg[0].File = File;
+	    vp->SrcReg[0].Index = Index;
+	    vp->SrcReg[0].Negate = (Negate[0] << 0 |
+				    Negate[1] << 1 |
+				    Negate[2] << 2 |
+				    Negate[3] << 3);
+	    vp->SrcReg[0].Swizzle = (Swizzle[0] << 0 |
+				     Swizzle[1] << 3 |
+				     Swizzle[2] << 6 |
+				     Swizzle[3] << 9);
+	    vp->SrcReg[0].RelAddr = RelAddr;
+	 }
          break;
    }
    return 0;
diff --git a/src/mesa/shader/arbvertparse.c b/src/mesa/shader/arbvertparse.c
index fd0666b3260..5545aff8b70 100644
--- a/src/mesa/shader/arbvertparse.c
+++ b/src/mesa/shader/arbvertparse.c
@@ -37,6 +37,7 @@
 #include "imports.h"
 #include "macros.h"
 #include "mtypes.h"
+#include "program.h"
 #include "nvprogram.h"
 #include "nvvertparse.h"
 #include "nvvertprog.h"
@@ -48,129 +49,104 @@
  * XXX this is probably redundant.  We've already got code like this
  * in the nvvertparse.c file.  Combine/clean-up someday.
  */
-static GLvoid
-debug_vp_inst(GLint num, struct vp_instruction *vp)
+void _mesa_debug_vp_inst(GLint num, struct vp_instruction *vp)
 {
    GLint a;
+   static const char *opcode_string[] = {
+      "ABS",
+      "ADD",
+      "ARL",
+      "DP3",
+      "DP4",
+      "DPH",
+      "DST",
+      "END",		/* Placeholder */
+      "EX2",		/* ARB only */
+      "EXP",
+      "FLR",		/* ARB */
+      "FRC",		/* ARB */
+      "LG2",		/* ARB only */
+      "LIT",
+      "LOG",
+      "MAD",
+      "MAX",
+      "MIN",
+      "MOV",
+      "MUL",
+      "POW",		/* ARB only */
+      "PRINT",		/* Mesa only */
+      "RCC",
+      "RCP",
+      "RSQ",
+      "SGE",
+      "SLT",
+      "SUB",
+      "SWZ",		/* ARB only */
+      "XPD"		/* ARB only */
+   };
+
+   static const char *file_string[] = {
+      "TEMP",
+      "INPUT",
+      "OUTPUT",
+      "LOCAL",
+      "ENV",
+      "NAMED",
+      "STATE",
+      "WRITE_ONLY",
+      "ADDR"
+   };
+
+   static const char swz[] = "xyzw01??";
 
    for (a=0; a<num; a++) {
-      switch (vp[a].Opcode) {
-         case VP_OPCODE_MOV:
-            fprintf(stderr, "VP_OPCODE_MOV"); break;
-
-         case VP_OPCODE_LIT:
-            fprintf(stderr, "VP_OPCODE_LIT"); break;
-
-         case VP_OPCODE_RCP:
-            fprintf(stderr, "VP_OPCODE_RCP"); break;
-
-         case VP_OPCODE_RSQ:
-            fprintf(stderr, "VP_OPCODE_RSQ"); break;
-
-         case VP_OPCODE_EXP:
-            fprintf(stderr, "VP_OPCODE_EXP"); break;
-
-         case VP_OPCODE_LOG:
-            fprintf(stderr, "VP_OPCODE_LOG"); break;
-
-         case VP_OPCODE_MUL:
-            fprintf(stderr, "VP_OPCODE_MUL"); break;
-
-         case VP_OPCODE_ADD:
-            fprintf(stderr, "VP_OPCODE_ADD"); break;
-				
-         case VP_OPCODE_DP3:
-            fprintf(stderr, "VP_OPCODE_DP3"); break;
-
-         case VP_OPCODE_DP4:
-            fprintf(stderr, "VP_OPCODE_DP4"); break;
-
-         case VP_OPCODE_DST:
-            fprintf(stderr, "VP_OPCODE_DST"); break;
-
-         case VP_OPCODE_MIN:
-            fprintf(stderr, "VP_OPCODE_MIN"); break;
-
-         case VP_OPCODE_MAX:
-            fprintf(stderr, "VP_OPCODE_MAX"); break;
-
-         case VP_OPCODE_SLT:
-            fprintf(stderr, "VP_OPCODE_SLT"); break;
-
-         case VP_OPCODE_SGE:
-            fprintf(stderr, "VP_OPCODE_SGE"); break;
-
-         case VP_OPCODE_MAD:
-            fprintf(stderr, "VP_OPCODE_MAD"); break;
-
-         case VP_OPCODE_ARL:
-            fprintf(stderr, "VP_OPCODE_ARL"); break;
-
-         case VP_OPCODE_DPH:
-            fprintf(stderr, "VP_OPCODE_DPH"); break;
-
-         case VP_OPCODE_RCC:
-            fprintf(stderr, "VP_OPCODE_RCC"); break;
-
-         case VP_OPCODE_SUB:
-            fprintf(stderr, "VP_OPCODE_SUB"); break;
-
-         case VP_OPCODE_ABS:
-            fprintf(stderr, "VP_OPCODE_ABS"); break;
-
-         case VP_OPCODE_FLR:
-            fprintf(stderr, "VP_OPCODE_FLR"); break;
-
-         case VP_OPCODE_FRC:
-            fprintf(stderr, "VP_OPCODE_FRC"); break;
-
-         case VP_OPCODE_EX2:
-            fprintf(stderr, "VP_OPCODE_EX2"); break;
-
-         case VP_OPCODE_LG2:
-            fprintf(stderr, "VP_OPCODE_LG2"); break;
-
-         case VP_OPCODE_POW:
-            fprintf(stderr, "VP_OPCODE_POW"); break;
+      _mesa_printf("%s", opcode_string[vp[a].Opcode]);
+
+      if (vp[a].DstReg.File != 0xf) {
+	 if (vp[a].DstReg.WriteMask != 0xf)
+	    _mesa_printf(" %s[%d].%s%s%s%s ", file_string[vp[a].DstReg.File], vp[a].DstReg.Index,
+			 GET_BIT(vp[a].DstReg.WriteMask, 0) ? "x" : "",
+			 GET_BIT(vp[a].DstReg.WriteMask, 1) ? "y" : "",
+			 GET_BIT(vp[a].DstReg.WriteMask, 2) ? "z" : "",
+			 GET_BIT(vp[a].DstReg.WriteMask, 3) ? "w" : "");
+	 else
+	    _mesa_printf(" %s[%d] ", file_string[vp[a].DstReg.File], vp[a].DstReg.Index);
+      }
 
-         case VP_OPCODE_XPD:
-            fprintf(stderr, "VP_OPCODE_XPD"); break;
+      if (vp[a].SrcReg[0].File != 0xf) {
+	 if (vp[a].SrcReg[0].Swizzle != SWIZZLE_NOOP)
+	    _mesa_printf("%s[%d].%c%c%c%c ", file_string[vp[a].SrcReg[0].File], vp[a].SrcReg[0].Index,
+			 swz[GET_SWZ(vp[a].SrcReg[0].Swizzle, 0)],
+			 swz[GET_SWZ(vp[a].SrcReg[0].Swizzle, 1)],
+			 swz[GET_SWZ(vp[a].SrcReg[0].Swizzle, 2)],
+			 swz[GET_SWZ(vp[a].SrcReg[0].Swizzle, 3)]);
+	 else
+	    _mesa_printf("%s[%d] ", file_string[vp[a].SrcReg[0].File], vp[a].SrcReg[0].Index);
+      }
 
-         case VP_OPCODE_SWZ:
-            fprintf(stderr, "VP_OPCODE_SWZ"); break;
-				
-         case VP_OPCODE_PRINT:
-            fprintf(stderr, "VP_OPCODE_PRINT"); break;
+      if (vp[a].SrcReg[1].File != 0xf) {
+	 if (vp[a].SrcReg[1].Swizzle != SWIZZLE_NOOP)
+	    _mesa_printf("%s[%d].%c%c%c%c ", file_string[vp[a].SrcReg[1].File], vp[a].SrcReg[1].Index,
+			 swz[GET_SWZ(vp[a].SrcReg[1].Swizzle, 0)],
+			 swz[GET_SWZ(vp[a].SrcReg[1].Swizzle, 1)],
+			 swz[GET_SWZ(vp[a].SrcReg[1].Swizzle, 2)],
+			 swz[GET_SWZ(vp[a].SrcReg[1].Swizzle, 3)]);
+	 else
+	    _mesa_printf("%s[%d] ", file_string[vp[a].SrcReg[1].File], vp[a].SrcReg[1].Index);
+      }
 
-         case VP_OPCODE_END:
-            fprintf(stderr, "VP_OPCODE_END"); break;
+      if (vp[a].SrcReg[2].File != 0xf) {
+	 if (vp[a].SrcReg[2].Swizzle != SWIZZLE_NOOP)
+	    _mesa_printf("%s[%d].%c%c%c%c ", file_string[vp[a].SrcReg[2].File], vp[a].SrcReg[2].Index,
+			 swz[GET_SWZ(vp[a].SrcReg[2].Swizzle, 0)],
+			 swz[GET_SWZ(vp[a].SrcReg[2].Swizzle, 1)],
+			 swz[GET_SWZ(vp[a].SrcReg[2].Swizzle, 2)],
+			 swz[GET_SWZ(vp[a].SrcReg[2].Swizzle, 3)]);
+	 else
+	    _mesa_printf("%s[%d] ", file_string[vp[a].SrcReg[2].File], vp[a].SrcReg[2].Index);
       }
 
-      fprintf(stderr, " D(0x%x:%d:%d%d%d%d) ", vp[a].DstReg.File, vp[a].DstReg.Index,
-          vp[a].DstReg.WriteMask[0],
-          vp[a].DstReg.WriteMask[1],
-          vp[a].DstReg.WriteMask[2],
-          vp[a].DstReg.WriteMask[3]);
-		
-      fprintf(stderr, "S1(0x%x:%d:%d%d%d%d) ", vp[a].SrcReg[0].File, vp[a].SrcReg[0].Index,
-          vp[a].SrcReg[0].Swizzle[0],
-          vp[a].SrcReg[0].Swizzle[1],
-          vp[a].SrcReg[0].Swizzle[2],
-          vp[a].SrcReg[0].Swizzle[3]);
-
-      fprintf(stderr, "S2(0x%x:%d:%d%d%d%d) ", vp[a].SrcReg[1].File, vp[a].SrcReg[1].Index,
-          vp[a].SrcReg[1].Swizzle[0],
-          vp[a].SrcReg[1].Swizzle[1],
-          vp[a].SrcReg[1].Swizzle[2],
-          vp[a].SrcReg[1].Swizzle[3]);
-
-      fprintf(stderr, "S3(0x%x:%d:%d%d%d%d)",  vp[a].SrcReg[2].File, vp[a].SrcReg[2].Index,	
-          vp[a].SrcReg[2].Swizzle[0],
-          vp[a].SrcReg[2].Swizzle[1],
-          vp[a].SrcReg[2].Swizzle[2],
-          vp[a].SrcReg[2].Swizzle[3]);
-
-      fprintf(stderr, "\n");
+      _mesa_printf("\n");
    }
 }
 
@@ -216,9 +192,7 @@ _mesa_parse_arb_vertex_program(GLcontext * ctx, GLenum target,
    program->Instructions   = ap.VPInstructions;
 
 #if DEBUG_VP
-   debug_vp_inst(ap.Base.NumInstructions, ap.VPInstructions);
-#else
-   (void) debug_vp_inst;
+   _mesa_debug_vp_inst(ap.Base.NumInstructions, ap.VPInstructions);
 #endif
 
 }
diff --git a/src/mesa/shader/arbvertparse.h b/src/mesa/shader/arbvertparse.h
index 3e4490b8be5..f2ac1570be0 100644
--- a/src/mesa/shader/arbvertparse.h
+++ b/src/mesa/shader/arbvertparse.h
@@ -30,4 +30,7 @@ _mesa_parse_arb_vertex_program(GLcontext * ctx, GLenum target,
 			       const GLubyte * str, GLsizei len,
 			       struct vertex_program *program);
 
+extern void 
+_mesa_debug_vp_inst(GLint num, struct vp_instruction *vp);
+
 #endif
diff --git a/src/mesa/shader/grammar.c b/src/mesa/shader/grammar.c
index 7864b36b380..1260bf29fb1 100644
--- a/src/mesa/shader/grammar.c
+++ b/src/mesa/shader/grammar.c
@@ -33,7 +33,6 @@
 #endif
 
 /*
-    $Id: grammar.c,v 1.10 2004/12/08 14:00:46 alanh Exp $
 */
 
 /*
diff --git a/src/mesa/shader/nvfragparse.c b/src/mesa/shader/nvfragparse.c
index bf1196cbf7f..e51ba314f54 100644
--- a/src/mesa/shader/nvfragparse.c
+++ b/src/mesa/shader/nvfragparse.c
@@ -692,11 +692,15 @@ Parse_CondCodeMask(struct parse_state *parseState,
    /* look for optional .xyzw swizzle */
    if (Parse_String(parseState, ".")) {
       GLubyte token[100];
+      GLuint swz[4];
+
       if (!Parse_Token(parseState, token))  /* get xyzw suffix */
          RETURN_ERROR;
 
-      if (!Parse_SwizzleSuffix(token, dstReg->CondSwizzle))
+      if (!Parse_SwizzleSuffix(token, swz))
          RETURN_ERROR1("Invalid swizzle suffix");
+
+      dstReg->CondSwizzle = MAKE_SWIZZLE(swz);
    }
 
    return GL_TRUE;
@@ -864,6 +868,7 @@ Parse_MaskedDstReg(struct parse_state *parseState,
                    struct fp_dst_register *dstReg)
 {
    GLubyte token[100];
+   GLint idx;
 
    /* Dst reg can be R<n>, H<n>, o[n], RC or HC */
    if (!Peek_Token(parseState, token))
@@ -873,20 +878,23 @@ Parse_MaskedDstReg(struct parse_state *parseState,
        _mesa_strcmp((const char *) token, "HC") == 0) {
       /* a write-only register */
       dstReg->File = PROGRAM_WRITE_ONLY;
-      if (!Parse_DummyReg(parseState, &dstReg->Index))
+      if (!Parse_DummyReg(parseState, &idx))
          RETURN_ERROR;
+      dstReg->Index = idx;
    }
    else if (token[0] == 'R' || token[0] == 'H') {
       /* a temporary register */
       dstReg->File = PROGRAM_TEMPORARY;
-      if (!Parse_TempReg(parseState, &dstReg->Index))
+      if (!Parse_TempReg(parseState, &idx))
          RETURN_ERROR;
+      dstReg->Index = idx;
    }
    else if (token[0] == 'o') {
       /* an output register */
       dstReg->File = PROGRAM_OUTPUT;
-      if (!Parse_OutputReg(parseState, &dstReg->Index))
+      if (!Parse_OutputReg(parseState, &idx))
          RETURN_ERROR;
+      dstReg->Index = idx;
    }
    else {
       RETURN_ERROR1("Invalid destination register name");
@@ -900,25 +908,22 @@ Parse_MaskedDstReg(struct parse_state *parseState,
       if (!Parse_Token(parseState, token))  /* get xyzw writemask */
          RETURN_ERROR;
 
-      dstReg->WriteMask[0] = GL_FALSE;
-      dstReg->WriteMask[1] = GL_FALSE;
-      dstReg->WriteMask[2] = GL_FALSE;
-      dstReg->WriteMask[3] = GL_FALSE;
+      dstReg->WriteMask = 0;
 
       if (token[k] == 'x') {
-         dstReg->WriteMask[0] = GL_TRUE;
+         dstReg->WriteMask |= WRITEMASK_X;
          k++;
       }
       if (token[k] == 'y') {
-         dstReg->WriteMask[1] = GL_TRUE;
+         dstReg->WriteMask |= WRITEMASK_Y;
          k++;
       }
       if (token[k] == 'z') {
-         dstReg->WriteMask[2] = GL_TRUE;
+         dstReg->WriteMask |= WRITEMASK_Z;
          k++;
       }
       if (token[k] == 'w') {
-         dstReg->WriteMask[3] = GL_TRUE;
+         dstReg->WriteMask |= WRITEMASK_W;
          k++;
       }
       if (k == 0) {
@@ -927,10 +932,7 @@ Parse_MaskedDstReg(struct parse_state *parseState,
 
    }
    else {
-      dstReg->WriteMask[0] = GL_TRUE;
-      dstReg->WriteMask[1] = GL_TRUE;
-      dstReg->WriteMask[2] = GL_TRUE;
-      dstReg->WriteMask[3] = GL_TRUE;
+      dstReg->WriteMask = WRITEMASK_XYZW;
    }
 
    /* optional condition code mask */
@@ -948,10 +950,7 @@ Parse_MaskedDstReg(struct parse_state *parseState,
    else {
       /* no cond code mask */
       dstReg->CondMask = COND_TR;
-      dstReg->CondSwizzle[0] = 0;
-      dstReg->CondSwizzle[1] = 1;
-      dstReg->CondSwizzle[2] = 2;
-      dstReg->CondSwizzle[3] = 3;
+      dstReg->CondSwizzle = SWIZZLE_NOOP;
       return GL_TRUE;
    }
 }
@@ -969,6 +968,7 @@ Parse_VectorSrc(struct parse_state *parseState,
 {
    GLfloat sign = 1.0F;
    GLubyte token[100];
+   GLint idx;
 
    /*
     * First, take care of +/- and absolute value stuff.
@@ -1004,20 +1004,23 @@ Parse_VectorSrc(struct parse_state *parseState,
     */
    if (token[0] == 'R' || token[0] == 'H') {
       srcReg->File = PROGRAM_TEMPORARY;
-      if (!Parse_TempReg(parseState, &srcReg->Index))
+      if (!Parse_TempReg(parseState, &idx))
          RETURN_ERROR;
+      srcReg->Index = idx;
    }
    else if (token[0] == 'f') {
       /* XXX this might be an identier! */
       srcReg->File = PROGRAM_INPUT;
-      if (!Parse_FragReg(parseState, &srcReg->Index))
+      if (!Parse_FragReg(parseState, &idx))
          RETURN_ERROR;
+      srcReg->Index = idx;
    }
    else if (token[0] == 'p') {
       /* XXX this might be an identier! */
       srcReg->File = PROGRAM_LOCAL_PARAM;
-      if (!Parse_ProgramParamReg(parseState, &srcReg->Index))
+      if (!Parse_ProgramParamReg(parseState, &idx))
          RETURN_ERROR;
+      srcReg->Index = idx;
    }
    else if (IsLetter(token[0])){
       GLubyte ident[100];
@@ -1058,18 +1061,19 @@ Parse_VectorSrc(struct parse_state *parseState,
    }
 
    /* init swizzle fields */
-   srcReg->Swizzle[0] = 0;
-   srcReg->Swizzle[1] = 1;
-   srcReg->Swizzle[2] = 2;
-   srcReg->Swizzle[3] = 3;
+   srcReg->Swizzle = SWIZZLE_NOOP;
 
    /* Look for optional swizzle suffix */
    if (Parse_String(parseState, ".")) {
+      GLuint swz[4];
+
       if (!Parse_Token(parseState, token))
          RETURN_ERROR;
 
-      if (!Parse_SwizzleSuffix(token, srcReg->Swizzle))
+      if (!Parse_SwizzleSuffix(token, swz))
          RETURN_ERROR1("Invalid swizzle suffix");
+
+      srcReg->Swizzle = MAKE_SWIZZLE(swz);
    }
 
    /* Finish absolute value */
@@ -1088,6 +1092,7 @@ Parse_ScalarSrcReg(struct parse_state *parseState,
    GLubyte token[100];
    GLfloat sign = 1.0F;
    GLboolean needSuffix = GL_TRUE;
+   GLint idx;
 
    /*
     * First, take care of +/- and absolute value stuff.
@@ -1120,13 +1125,15 @@ Parse_ScalarSrcReg(struct parse_state *parseState,
    /* Src reg can be R<n>, H<n> or a named fragment attrib */
    if (token[0] == 'R' || token[0] == 'H') {
       srcReg->File = PROGRAM_TEMPORARY;
-      if (!Parse_TempReg(parseState, &srcReg->Index))
+      if (!Parse_TempReg(parseState, &idx))
          RETURN_ERROR;
+      srcReg->Index = idx;
    }
    else if (token[0] == 'f') {
       srcReg->File = PROGRAM_INPUT;
-      if (!Parse_FragReg(parseState, &srcReg->Index))
+      if (!Parse_FragReg(parseState, &idx))
          RETURN_ERROR;
+      srcReg->Index = idx;
    }
    else if (token[0] == '{') {
       /* vector literal */
@@ -1154,6 +1161,7 @@ Parse_ScalarSrcReg(struct parse_state *parseState,
       RETURN_ERROR2("Invalid scalar source argument", token);
    }
 
+   srcReg->Swizzle = 0;
    if (needSuffix) {
       /* parse .[xyzw] suffix */
       if (!Parse_String(parseState, "."))
@@ -1163,25 +1171,21 @@ Parse_ScalarSrcReg(struct parse_state *parseState,
          RETURN_ERROR;
 
       if (token[0] == 'x' && token[1] == 0) {
-         srcReg->Swizzle[0] = 0;
+         srcReg->Swizzle = 0;
       }
       else if (token[0] == 'y' && token[1] == 0) {
-         srcReg->Swizzle[0] = 1;
+         srcReg->Swizzle = 1;
       }
       else if (token[0] == 'z' && token[1] == 0) {
-         srcReg->Swizzle[0] = 2;
+         srcReg->Swizzle = 2;
       }
       else if (token[0] == 'w' && token[1] == 0) {
-         srcReg->Swizzle[0] = 3;
+         srcReg->Swizzle = 3;
       }
       else {
          RETURN_ERROR1("Invalid scalar source suffix");
       }
    }
-   else {
-      srcReg->Swizzle[0] = 0;
-   }
-   srcReg->Swizzle[1] = srcReg->Swizzle[2] = srcReg->Swizzle[3] = 0;
 
    /* Finish absolute value */
    if (srcReg->Abs && !Parse_String(parseState, "|")) {
@@ -1199,6 +1203,7 @@ Parse_PrintInstruction(struct parse_state *parseState,
    const GLubyte *str;
    GLubyte *msg;
    GLuint len;
+   GLint idx;
 
    /* The first argument is a literal string 'just like this' */
    if (!Parse_String(parseState, "'"))
@@ -1220,8 +1225,9 @@ Parse_PrintInstruction(struct parse_state *parseState,
       GetToken(parseState, token);
       if (token[0] == 'o') {
          /* dst reg */
-         if (!Parse_OutputReg(parseState, &inst->SrcReg[0].Index))
+         if (!Parse_OutputReg(parseState, &idx))
             RETURN_ERROR;
+	 inst->SrcReg[0].Index = idx;
          inst->SrcReg[0].File = PROGRAM_OUTPUT;
       }
       else {
@@ -1235,10 +1241,7 @@ Parse_PrintInstruction(struct parse_state *parseState,
       inst->SrcReg[0].File = -1;
    }
 
-   inst->SrcReg[0].Swizzle[0] = 0;
-   inst->SrcReg[0].Swizzle[1] = 1;
-   inst->SrcReg[0].Swizzle[2] = 2;
-   inst->SrcReg[0].Swizzle[3] = 3;
+   inst->SrcReg[0].Swizzle = SWIZZLE_NOOP;
    inst->SrcReg[0].NegateBase = GL_FALSE;
    inst->SrcReg[0].Abs = GL_FALSE;
    inst->SrcReg[0].NegateAbs = GL_FALSE;
@@ -1261,10 +1264,7 @@ Parse_InstructionSequence(struct parse_state *parseState,
       inst->SrcReg[1].File = (enum register_file) -1;
       inst->SrcReg[2].File = (enum register_file) -1;
       inst->DstReg.File = (enum register_file) -1;
-      inst->DstReg.CondSwizzle[0] = 0;
-      inst->DstReg.CondSwizzle[1] = 1;
-      inst->DstReg.CondSwizzle[2] = 2;
-      inst->DstReg.CondSwizzle[3] = 3;
+      inst->DstReg.CondSwizzle = SWIZZLE_NOOP;
       inst->Data = NULL;
 
       /* special instructions */
@@ -1400,15 +1400,18 @@ Parse_InstructionSequence(struct parse_state *parseState,
             /* XXX to-do */
          }
          else if (instMatch.inputs == INPUT_1V_T) {
+	    GLubyte unit, idx;
             if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
                RETURN_ERROR;
             if (!Parse_String(parseState, ","))
                RETURN_ERROR1("Expected ,");
-            if (!Parse_TextureImageId(parseState, &inst->TexSrcUnit,
-                                      &inst->TexSrcBit))
+            if (!Parse_TextureImageId(parseState, &unit, &idx))
                RETURN_ERROR;
+	    inst->TexSrcUnit = unit;
+	    inst->TexSrcIdx = idx;
          }
          else if (instMatch.inputs == INPUT_3V_T) {
+	    GLubyte unit, idx;
             if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
                RETURN_ERROR;
             if (!Parse_String(parseState, ","))
@@ -1421,9 +1424,10 @@ Parse_InstructionSequence(struct parse_state *parseState,
                RETURN_ERROR;
             if (!Parse_String(parseState, ","))
                RETURN_ERROR1("Expected ,");
-            if (!Parse_TextureImageId(parseState, &inst->TexSrcUnit,
-                                      &inst->TexSrcBit))
+            if (!Parse_TextureImageId(parseState, &unit, &idx))
                RETURN_ERROR;
+	    inst->TexSrcUnit = unit;
+	    inst->TexSrcIdx = idx;
          }
          else if (instMatch.inputs == INPUT_1V_S) {
             if (!Parse_PrintInstruction(parseState, inst))
@@ -1586,10 +1590,10 @@ PrintSrcReg(const struct fragment_program *program,
    if (src->File == PROGRAM_NAMED_PARAM) {
       if (program->Parameters->Parameters[src->Index].Type == CONSTANT) {
          printf("{%g, %g, %g, %g}",
-                program->Parameters->Parameters[src->Index].Values[0],
-                program->Parameters->Parameters[src->Index].Values[1],
-                program->Parameters->Parameters[src->Index].Values[2],
-                program->Parameters->Parameters[src->Index].Values[3]);
+                program->Parameters->ParameterValues[src->Index][0],
+                program->Parameters->ParameterValues[src->Index][1],
+                program->Parameters->ParameterValues[src->Index][2],
+                program->Parameters->ParameterValues[src->Index][3]);
       }
       else {
          ASSERT(program->Parameters->Parameters[src->Index].Type
@@ -1619,20 +1623,17 @@ PrintSrcReg(const struct fragment_program *program,
       _mesa_problem(NULL, "Invalid fragment register %d", src->Index);
       return;
    }
-   if (src->Swizzle[0] == src->Swizzle[1] &&
-       src->Swizzle[0] == src->Swizzle[2] &&
-       src->Swizzle[0] == src->Swizzle[3]) {
-      _mesa_printf(".%c", comps[src->Swizzle[0]]);
+   if (GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 1) &&
+       GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 2) &&
+       GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 3)) {
+      _mesa_printf(".%c", comps[GET_SWZ(src->Swizzle, 0)]);
    }
-   else if (src->Swizzle[0] != 0 ||
-            src->Swizzle[1] != 1 ||
-            src->Swizzle[2] != 2 ||
-            src->Swizzle[3] != 3) {
+   else if (src->Swizzle != SWIZZLE_NOOP) {
       _mesa_printf(".%c%c%c%c",
-                   comps[src->Swizzle[0]],
-                   comps[src->Swizzle[1]],
-                   comps[src->Swizzle[2]],
-                   comps[src->Swizzle[3]]);
+                   comps[GET_SWZ(src->Swizzle, 0)],
+                   comps[GET_SWZ(src->Swizzle, 1)],
+                   comps[GET_SWZ(src->Swizzle, 2)],
+                   comps[GET_SWZ(src->Swizzle, 3)]);
    }
    if (src->Abs) {
       _mesa_printf("|");
@@ -1643,20 +1644,20 @@ static void
 PrintTextureSrc(const struct fp_instruction *inst)
 {
    _mesa_printf("TEX%d, ", inst->TexSrcUnit);
-   switch (inst->TexSrcBit) {
-   case TEXTURE_1D_BIT:
+   switch (inst->TexSrcIdx) {
+   case TEXTURE_1D_INDEX:
       _mesa_printf("1D");
       break;
-   case TEXTURE_2D_BIT:
+   case TEXTURE_2D_INDEX:
       _mesa_printf("2D");
       break;
-   case TEXTURE_3D_BIT:
+   case TEXTURE_3D_INDEX:
       _mesa_printf("3D");
       break;
-   case TEXTURE_RECT_BIT:
+   case TEXTURE_RECT_INDEX:
       _mesa_printf("RECT");
       break;
-   case TEXTURE_CUBE_BIT:
+   case TEXTURE_CUBE_INDEX:
       _mesa_printf("CUBE");
       break;
    default:
@@ -1673,20 +1674,17 @@ PrintCondCode(const struct fp_dst_register *dst)
    };
 
    _mesa_printf("%s", ccString[dst->CondMask]);
-   if (dst->CondSwizzle[0] == dst->CondSwizzle[1] &&
-       dst->CondSwizzle[0] == dst->CondSwizzle[2] &&
-       dst->CondSwizzle[0] == dst->CondSwizzle[3]) {
-      _mesa_printf(".%c", comps[dst->CondSwizzle[0]]);
-   }
-   else if (dst->CondSwizzle[0] != 0 ||
-            dst->CondSwizzle[1] != 1 ||
-            dst->CondSwizzle[2] != 2 ||
-            dst->CondSwizzle[3] != 3) {
+   if (GET_SWZ(dst->CondSwizzle, 0) == GET_SWZ(dst->CondSwizzle, 1) &&
+       GET_SWZ(dst->CondSwizzle, 0) == GET_SWZ(dst->CondSwizzle, 2) &&
+       GET_SWZ(dst->CondSwizzle, 0) == GET_SWZ(dst->CondSwizzle, 3)) {
+      _mesa_printf(".%c", comps[GET_SWZ(dst->CondSwizzle, 0)]);
+   }
+   else if (dst->CondSwizzle != SWIZZLE_NOOP) {
       _mesa_printf(".%c%c%c%c",
-                   comps[dst->CondSwizzle[0]],
-                   comps[dst->CondSwizzle[1]],
-                   comps[dst->CondSwizzle[2]],
-                   comps[dst->CondSwizzle[3]]);
+                   comps[GET_SWZ(dst->CondSwizzle, 0)],
+                   comps[GET_SWZ(dst->CondSwizzle, 1)],
+                   comps[GET_SWZ(dst->CondSwizzle, 2)],
+                   comps[GET_SWZ(dst->CondSwizzle, 3)]);
    }
 }
 
@@ -1694,9 +1692,6 @@ PrintCondCode(const struct fp_dst_register *dst)
 static void
 PrintDstReg(const struct fp_dst_register *dst)
 {
-   GLint w = dst->WriteMask[0] + dst->WriteMask[1]
-           + dst->WriteMask[2] + dst->WriteMask[3];
-
    if (dst->File == PROGRAM_OUTPUT) {
       _mesa_printf("o[%s]", OutputRegisters[dst->Index]);
    }
@@ -1716,23 +1711,20 @@ PrintDstReg(const struct fp_dst_register *dst)
       _mesa_printf("???");
    }
 
-   if (w != 0 && w != 4) {
+   if (dst->WriteMask != 0 && dst->WriteMask != 0xf) {
       _mesa_printf(".");
-      if (dst->WriteMask[0])
+      if (dst->WriteMask & 0x1)
          _mesa_printf("x");
-      if (dst->WriteMask[1])
+      if (dst->WriteMask & 0x2)
          _mesa_printf("y");
-      if (dst->WriteMask[2])
+      if (dst->WriteMask & 0x4)
          _mesa_printf("z");
-      if (dst->WriteMask[3])
+      if (dst->WriteMask & 0x8)
          _mesa_printf("w");
    }
 
    if (dst->CondMask != COND_TR ||
-       dst->CondSwizzle[0] != 0 ||
-       dst->CondSwizzle[1] != 1 ||
-       dst->CondSwizzle[2] != 2 ||
-       dst->CondSwizzle[3] != 3) {
+       dst->CondSwizzle != SWIZZLE_NOOP) {
       _mesa_printf(" (");
       PrintCondCode(dst);
       _mesa_printf(")");
diff --git a/src/mesa/shader/nvfragprog.h b/src/mesa/shader/nvfragprog.h
index ddfc4993ed5..fb846f11078 100644
--- a/src/mesa/shader/nvfragprog.h
+++ b/src/mesa/shader/nvfragprog.h
@@ -34,7 +34,7 @@
 #define NVFRAGPROG_H
 
 #include "config.h"
-
+#include "mtypes.h"
 
 /* output registers */
 #define FRAG_OUTPUT_COLR  0
@@ -62,8 +62,7 @@
 
 /* Fragment program instruction opcodes */
 enum fp_opcode {
-   FP_OPCODE_INVALID = -1,   /* Force signed enum */
-   FP_OPCODE_ABS = 1000,     /* ARB_f_p only */
+   FP_OPCODE_ABS,     /* ARB_f_p only */
    FP_OPCODE_ADD,
    FP_OPCODE_CMP,            /* ARB_f_p only */
    FP_OPCODE_COS,
@@ -125,41 +124,44 @@ enum fp_opcode {
 /* Instruction source register */
 struct fp_src_register
 {
-   enum register_file File;
-   GLint Index;
-   GLuint Swizzle[4];
-   GLboolean NegateBase; /* negate before absolute value? */
-   GLboolean Abs;        /* take absolute value? */
-   GLboolean NegateAbs;  /* negate after absolute value? */
+   GLuint File:4;
+   GLuint Index:8;
+   GLuint Swizzle:12;
+   GLuint NegateBase:4; /* ARB: negate/extended negate.
+			   NV: negate before absolute value? */
+   GLuint Abs:1;        /* NV: take absolute value? */
+   GLuint NegateAbs:1;  /* NV: negate after absolute value? */
 };
 
 
 /* Instruction destination register */
 struct fp_dst_register
 {
-   enum register_file File;
-   GLint Index;
-   GLboolean WriteMask[4];
-   GLuint CondMask;
-   GLuint CondSwizzle[4];
+   GLuint File:4;
+   GLuint Index:8;
+   GLuint WriteMask:4;
+   GLuint CondMask:4;		/* NV: enough bits? */
+   GLuint CondSwizzle:12;	/* NV: enough bits? */
 };
 
 
 /* Fragment program instruction */
 struct fp_instruction
 {
-   enum fp_opcode Opcode;
-   struct fp_src_register SrcReg[3];
-   struct fp_dst_register DstReg;
-   GLboolean Saturate;
-   GLboolean UpdateCondRegister;
-   GLubyte Precision;    /* FLOAT32, FLOAT16 or FIXED12 */
-   GLubyte TexSrcUnit;   /* texture unit for TEX, TXD, TXP instructions */
-   GLubyte TexSrcBit;    /* TEXTURE_1D,2D,3D,CUBE,RECT_BIT source target */
+   GLuint Opcode:6;
+   GLuint Saturate:1;	
+   GLuint UpdateCondRegister:1;	/* NV */
+   GLuint Precision:2;    /* NV: unused/unneeded? */
+   GLuint TexSrcUnit:4;   /* texture unit for TEX, TXD, TXP instructions */
+   GLuint TexSrcIdx:3;    /* TEXTURE_1D,2D,3D,CUBE,RECT_INDEX source target */
+
 #if FEATURE_MESA_program_debug
-   GLint StringPos;
+   GLint StringPos:15;		/* enough bits? */
 #endif
+
    void *Data;  /* some arbitrary data, only used for PRINT instruction now */
+   struct fp_src_register SrcReg[3];
+   struct fp_dst_register DstReg;
 };
 
 
diff --git a/src/mesa/shader/nvvertexec.c b/src/mesa/shader/nvvertexec.c
index f0558da1abf..679400c13ec 100644
--- a/src/mesa/shader/nvvertexec.c
+++ b/src/mesa/shader/nvvertexec.c
@@ -239,7 +239,7 @@ get_register_pointer( const struct vp_src_register *source,
       else if (source->File == PROGRAM_ENV_PARAM)
          return state->Parameters[reg];
       else
-         return state->Current->Parameters->Parameters[reg].Values;
+         return state->Current->Parameters->ParameterValues[reg];
    }
    else {
       switch (source->File) {
@@ -261,7 +261,7 @@ get_register_pointer( const struct vp_src_register *source,
             return state->Parameters[source->Index];
          case PROGRAM_STATE_VAR:
             ASSERT(source->Index < state->Current->Parameters->NumParameters);
-            return state->Current->Parameters->Parameters[source->Index].Values;
+            return state->Current->Parameters->ParameterValues[source->Index];
          default:
             _mesa_problem(NULL,
                           "Bad source register file in get_register_pointer");
@@ -284,16 +284,16 @@ fetch_vector4( const struct vp_src_register *source,
    const GLfloat *src = get_register_pointer(source, state);
 
    if (source->Negate) {
-      result[0] = -src[source->Swizzle[0]];
-      result[1] = -src[source->Swizzle[1]];
-      result[2] = -src[source->Swizzle[2]];
-      result[3] = -src[source->Swizzle[3]];
+      result[0] = -src[GET_SWZ(source->Swizzle, 0)];
+      result[1] = -src[GET_SWZ(source->Swizzle, 1)];
+      result[2] = -src[GET_SWZ(source->Swizzle, 2)];
+      result[3] = -src[GET_SWZ(source->Swizzle, 3)];
    }
    else {
-      result[0] = src[source->Swizzle[0]];
-      result[1] = src[source->Swizzle[1]];
-      result[2] = src[source->Swizzle[2]];
-      result[3] = src[source->Swizzle[3]];
+      result[0] = src[GET_SWZ(source->Swizzle, 0)];
+      result[1] = src[GET_SWZ(source->Swizzle, 1)];
+      result[2] = src[GET_SWZ(source->Swizzle, 2)];
+      result[3] = src[GET_SWZ(source->Swizzle, 3)];
    }
 }
 
@@ -310,10 +310,10 @@ fetch_vector1( const struct vp_src_register *source,
    const GLfloat *src = get_register_pointer(source, state);
 
    if (source->Negate) {
-      result[0] = -src[source->Swizzle[0]];
+      result[0] = -src[GET_SWZ(source->Swizzle, 0)];
    }
    else {
-      result[0] = src[source->Swizzle[0]];
+      result[0] = src[GET_SWZ(source->Swizzle, 0)];
    }
 }
 
@@ -347,13 +347,13 @@ store_vector4( const struct vp_dst_register *dest,
          return;
    }
 
-   if (dest->WriteMask[0])
+   if (dest->WriteMask & WRITEMASK_X)
       dst[0] = value[0];
-   if (dest->WriteMask[1])
+   if (dest->WriteMask & WRITEMASK_Y)
       dst[1] = value[1];
-   if (dest->WriteMask[2])
+   if (dest->WriteMask & WRITEMASK_Z)
       dst[2] = value[2];
-   if (dest->WriteMask[3])
+   if (dest->WriteMask & WRITEMASK_W)
       dst[3] = value[3];
 }
 
@@ -766,12 +766,12 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program)
 
                /* do extended swizzling here */
                for (i = 0; i < 3; i++) {
-                  if (source->Swizzle[i] == SWIZZLE_ZERO)
+                  if (GET_SWZ(source->Swizzle, i) == SWIZZLE_ZERO)
                      result[i] = 0.0;
-                  else if (source->Swizzle[i] == SWIZZLE_ONE)
+                  else if (GET_SWZ(source->Swizzle, i) == SWIZZLE_ONE)
                      result[i] = -1.0;
                   else
-                     result[i] = -src[source->Swizzle[i]];
+                     result[i] = -src[GET_SWZ(source->Swizzle, i)];
                   if (source->Negate)
                      result[i] = -result[i];
                }
diff --git a/src/mesa/shader/nvvertparse.c b/src/mesa/shader/nvvertparse.c
index b02143a2e66..23a01c7617f 100644
--- a/src/mesa/shader/nvvertparse.c
+++ b/src/mesa/shader/nvvertparse.c
@@ -563,6 +563,7 @@ static GLboolean
 Parse_MaskedDstReg(struct parse_state *parseState, struct vp_dst_register *dstReg)
 {
    GLubyte token[100];
+   GLint idx;
 
    /* Dst reg can be R<n> or o[n] */
    if (!Peek_Token(parseState, token))
@@ -571,22 +572,25 @@ Parse_MaskedDstReg(struct parse_state *parseState, struct vp_dst_register *dstRe
    if (token[0] == 'R') {
       /* a temporary register */
       dstReg->File = PROGRAM_TEMPORARY;
-      if (!Parse_TempReg(parseState, &dstReg->Index))
+      if (!Parse_TempReg(parseState, &idx))
          RETURN_ERROR;
+      dstReg->Index = idx;
    }
    else if (!parseState->isStateProgram && token[0] == 'o') {
       /* an output register */
       dstReg->File = PROGRAM_OUTPUT;
-      if (!Parse_OutputReg(parseState, &dstReg->Index))
+      if (!Parse_OutputReg(parseState, &idx))
          RETURN_ERROR;
+      dstReg->Index = idx;
    }
    else if (parseState->isStateProgram && token[0] == 'c' &&
             parseState->isStateProgram) {
       /* absolute program parameter register */
       /* Only valid for vertex state programs */
       dstReg->File = PROGRAM_ENV_PARAM;
-      if (!Parse_AbsParamReg(parseState, &dstReg->Index))
+      if (!Parse_AbsParamReg(parseState, &idx))
          RETURN_ERROR;
+      dstReg->Index = idx;
    }
    else {
       RETURN_ERROR1("Bad destination register name");
@@ -606,25 +610,22 @@ Parse_MaskedDstReg(struct parse_state *parseState, struct vp_dst_register *dstRe
       if (!Parse_Token(parseState, token))
          RETURN_ERROR;
 
-      dstReg->WriteMask[0] = GL_FALSE;
-      dstReg->WriteMask[1] = GL_FALSE;
-      dstReg->WriteMask[2] = GL_FALSE;
-      dstReg->WriteMask[3] = GL_FALSE;
+      dstReg->WriteMask = 0;
 
       if (token[k] == 'x') {
-         dstReg->WriteMask[0] = GL_TRUE;
+         dstReg->WriteMask |= WRITEMASK_X;
          k++;
       }
       if (token[k] == 'y') {
-         dstReg->WriteMask[1] = GL_TRUE;
+         dstReg->WriteMask |= WRITEMASK_Y;
          k++;
       }
       if (token[k] == 'z') {
-         dstReg->WriteMask[2] = GL_TRUE;
+         dstReg->WriteMask |= WRITEMASK_Z;
          k++;
       }
       if (token[k] == 'w') {
-         dstReg->WriteMask[3] = GL_TRUE;
+         dstReg->WriteMask |= WRITEMASK_W;
          k++;
       }
       if (k == 0) {
@@ -633,10 +634,7 @@ Parse_MaskedDstReg(struct parse_state *parseState, struct vp_dst_register *dstRe
       return GL_TRUE;
    }
    else {
-      dstReg->WriteMask[0] = GL_TRUE;
-      dstReg->WriteMask[1] = GL_TRUE;
-      dstReg->WriteMask[2] = GL_TRUE;
-      dstReg->WriteMask[3] = GL_TRUE;
+      dstReg->WriteMask = WRITEMASK_XYZW;
       return GL_TRUE;
    }
 }
@@ -646,6 +644,7 @@ static GLboolean
 Parse_SwizzleSrcReg(struct parse_state *parseState, struct vp_src_register *srcReg)
 {
    GLubyte token[100];
+   GLint idx;
 
    srcReg->RelAddr = GL_FALSE;
 
@@ -665,8 +664,9 @@ Parse_SwizzleSrcReg(struct parse_state *parseState, struct vp_src_register *srcR
    /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
    if (token[0] == 'R') {
       srcReg->File = PROGRAM_TEMPORARY;
-      if (!Parse_TempReg(parseState, &srcReg->Index))
+      if (!Parse_TempReg(parseState, &idx))
          RETURN_ERROR;
+      srcReg->Index = idx;
    }
    else if (token[0] == 'c') {
       if (!Parse_ParamReg(parseState, srcReg))
@@ -674,18 +674,16 @@ Parse_SwizzleSrcReg(struct parse_state *parseState, struct vp_src_register *srcR
    }
    else if (token[0] == 'v') {
       srcReg->File = PROGRAM_INPUT;
-      if (!Parse_AttribReg(parseState, &srcReg->Index))
+      if (!Parse_AttribReg(parseState, &idx))
          RETURN_ERROR;
+      srcReg->Index = idx;
    }
    else {
       RETURN_ERROR2("Bad source register name", token);
    }
 
    /* init swizzle fields */
-   srcReg->Swizzle[0] = 0;
-   srcReg->Swizzle[1] = 1;
-   srcReg->Swizzle[2] = 2;
-   srcReg->Swizzle[3] = 3;
+   srcReg->Swizzle = SWIZZLE_NOOP;
 
    /* Look for optional swizzle suffix */
    if (!Peek_Token(parseState, token))
@@ -699,13 +697,13 @@ Parse_SwizzleSrcReg(struct parse_state *parseState, struct vp_src_register *srcR
       if (token[1] == 0) {
          /* single letter swizzle */
          if (token[0] == 'x')
-            ASSIGN_4V(srcReg->Swizzle, 0, 0, 0, 0);
+            srcReg->Swizzle = MAKE_SWIZZLE4(0, 0, 0, 0);
          else if (token[0] == 'y')
-            ASSIGN_4V(srcReg->Swizzle, 1, 1, 1, 1);
+            srcReg->Swizzle = MAKE_SWIZZLE4(1, 1, 1, 1);
          else if (token[0] == 'z')
-            ASSIGN_4V(srcReg->Swizzle, 2, 2, 2, 2);
+            srcReg->Swizzle = MAKE_SWIZZLE4(2, 2, 2, 2);
          else if (token[0] == 'w')
-            ASSIGN_4V(srcReg->Swizzle, 3, 3, 3, 3);
+            srcReg->Swizzle = MAKE_SWIZZLE4(3, 3, 3, 3);
          else
             RETURN_ERROR1("Expected x, y, z, or w");
       }
@@ -714,13 +712,13 @@ Parse_SwizzleSrcReg(struct parse_state *parseState, struct vp_src_register *srcR
          GLint k;
          for (k = 0; token[k] && k < 5; k++) {
             if (token[k] == 'x')
-               srcReg->Swizzle[k] = 0;
+               srcReg->Swizzle |= 0 << (k*3);
             else if (token[k] == 'y')
-               srcReg->Swizzle[k] = 1;
+               srcReg->Swizzle |= 1 << (k*3);
             else if (token[k] == 'z')
-               srcReg->Swizzle[k] = 2;
+               srcReg->Swizzle |= 2 << (k*3);
             else if (token[k] == 'w')
-               srcReg->Swizzle[k] = 3;
+               srcReg->Swizzle |= 3 << (k*3);
             else
                RETURN_ERROR;
          }
@@ -737,6 +735,7 @@ static GLboolean
 Parse_ScalarSrcReg(struct parse_state *parseState, struct vp_src_register *srcReg)
 {
    GLubyte token[100];
+   GLint idx;
 
    srcReg->RelAddr = GL_FALSE;
 
@@ -756,8 +755,9 @@ Parse_ScalarSrcReg(struct parse_state *parseState, struct vp_src_register *srcRe
    /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
    if (token[0] == 'R') {
       srcReg->File = PROGRAM_TEMPORARY;
-      if (!Parse_TempReg(parseState, &srcReg->Index))
+      if (!Parse_TempReg(parseState, &idx))
          RETURN_ERROR;
+      srcReg->Index = idx;
    }
    else if (token[0] == 'c') {
       if (!Parse_ParamReg(parseState, srcReg))
@@ -765,8 +765,9 @@ Parse_ScalarSrcReg(struct parse_state *parseState, struct vp_src_register *srcRe
    }
    else if (token[0] == 'v') {
       srcReg->File = PROGRAM_INPUT;
-      if (!Parse_AttribReg(parseState, &srcReg->Index))
+      if (!Parse_AttribReg(parseState, &idx))
          RETURN_ERROR;
+      srcReg->Index = idx;
    }
    else {
       RETURN_ERROR2("Bad source register name", token);
@@ -780,21 +781,20 @@ Parse_ScalarSrcReg(struct parse_state *parseState, struct vp_src_register *srcRe
       RETURN_ERROR;
 
    if (token[0] == 'x' && token[1] == 0) {
-      srcReg->Swizzle[0] = 0;
+      srcReg->Swizzle = 0;
    }
    else if (token[0] == 'y' && token[1] == 0) {
-      srcReg->Swizzle[0] = 1;
+      srcReg->Swizzle = 1;
    }
    else if (token[0] == 'z' && token[1] == 0) {
-      srcReg->Swizzle[0] = 2;
+      srcReg->Swizzle = 2;
    }
    else if (token[0] == 'w' && token[1] == 0) {
-      srcReg->Swizzle[0] = 3;
+      srcReg->Swizzle = 3;
    }
    else {
       RETURN_ERROR1("Bad scalar source suffix");
    }
-   srcReg->Swizzle[1] = srcReg->Swizzle[2] = srcReg->Swizzle[3] = 0;
 
    return GL_TRUE;
 }
@@ -1042,6 +1042,7 @@ Parse_PrintInstruction(struct parse_state *parseState, struct vp_instruction *in
    GLuint len;
    GLubyte token[100];
    struct vp_src_register *srcReg = &inst->SrcReg[0];
+   GLint idx;
 
    inst->Opcode = VP_OPCODE_PRINT;
    inst->StringPos = parseState->curLine - parseState->start;
@@ -1069,18 +1070,16 @@ Parse_PrintInstruction(struct parse_state *parseState, struct vp_instruction *in
 
       srcReg->RelAddr = GL_FALSE;
       srcReg->Negate = GL_FALSE;
-      srcReg->Swizzle[0] = 0;
-      srcReg->Swizzle[1] = 1;
-      srcReg->Swizzle[2] = 2;
-      srcReg->Swizzle[3] = 3;
+      srcReg->Swizzle = SWIZZLE_NOOP;
 
       /* Register can be R<n>, c[n], c[n +/- offset], a named vertex attrib,
        * or an o[n] output register.
        */
       if (token[0] == 'R') {
          srcReg->File = PROGRAM_TEMPORARY;
-         if (!Parse_TempReg(parseState, &srcReg->Index))
+         if (!Parse_TempReg(parseState, &idx))
             RETURN_ERROR;
+	 srcReg->Index = idx;
       }
       else if (token[0] == 'c') {
          srcReg->File = PROGRAM_ENV_PARAM;
@@ -1089,13 +1088,15 @@ Parse_PrintInstruction(struct parse_state *parseState, struct vp_instruction *in
       }
       else if (token[0] == 'v') {
          srcReg->File = PROGRAM_INPUT;
-         if (!Parse_AttribReg(parseState, &srcReg->Index))
+         if (!Parse_AttribReg(parseState, &idx))
             RETURN_ERROR;
+	 srcReg->Index = idx;
       }
       else if (token[0] == 'o') {
          srcReg->File = PROGRAM_OUTPUT;
-         if (!Parse_OutputReg(parseState, &srcReg->Index))
+         if (!Parse_OutputReg(parseState, &idx))
             RETURN_ERROR;
+	 srcReg->Index = idx;
       }
       else {
          RETURN_ERROR2("Bad source register name", token);
@@ -1448,20 +1449,17 @@ PrintSrcReg(const struct vp_src_register *src)
       _mesa_printf("R%d", src->Index);
    }
 
-   if (src->Swizzle[0] == src->Swizzle[1] &&
-       src->Swizzle[0] == src->Swizzle[2] &&
-       src->Swizzle[0] == src->Swizzle[3]) {
-      _mesa_printf(".%c", comps[src->Swizzle[0]]);
+   if (GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 1) &&
+       GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 2) &&
+       GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 3)) {
+      _mesa_printf(".%c", comps[GET_SWZ(src->Swizzle, 0)]);
    }
-   else if (src->Swizzle[0] != 0 ||
-            src->Swizzle[1] != 1 ||
-            src->Swizzle[2] != 2 ||
-            src->Swizzle[3] != 3) {
+   else if (src->Swizzle != SWIZZLE_NOOP) {
       _mesa_printf(".%c%c%c%c",
-             comps[src->Swizzle[0]],
-             comps[src->Swizzle[1]],
-             comps[src->Swizzle[2]],
-             comps[src->Swizzle[3]]);
+             comps[GET_SWZ(src->Swizzle, 0)],
+             comps[GET_SWZ(src->Swizzle, 1)],
+             comps[GET_SWZ(src->Swizzle, 2)],
+             comps[GET_SWZ(src->Swizzle, 3)]);
    }
 }
 
@@ -1469,9 +1467,6 @@ PrintSrcReg(const struct vp_src_register *src)
 static void
 PrintDstReg(const struct vp_dst_register *dst)
 {
-   GLint w = dst->WriteMask[0] + dst->WriteMask[1]
-           + dst->WriteMask[2] + dst->WriteMask[3];
-
    if (dst->File == PROGRAM_OUTPUT) {
       _mesa_printf("o[%s]", OutputRegisters[dst->Index]);
    }
@@ -1486,15 +1481,15 @@ PrintDstReg(const struct vp_dst_register *dst)
       _mesa_printf("R%d", dst->Index);
    }
 
-   if (w != 0 && w != 4) {
+   if (dst->WriteMask != 0 && dst->WriteMask != 0xf) {
       _mesa_printf(".");
-      if (dst->WriteMask[0])
+      if (dst->WriteMask & 0x1)
          _mesa_printf("x");
-      if (dst->WriteMask[1])
+      if (dst->WriteMask & 0x2)
          _mesa_printf("y");
-      if (dst->WriteMask[2])
+      if (dst->WriteMask & 0x4)
          _mesa_printf("z");
-      if (dst->WriteMask[3])
+      if (dst->WriteMask & 0x8)
          _mesa_printf("w");
    }
 }
diff --git a/src/mesa/shader/nvvertprog.h b/src/mesa/shader/nvvertprog.h
index 583b9012079..ca9930a9749 100644
--- a/src/mesa/shader/nvvertprog.h
+++ b/src/mesa/shader/nvvertprog.h
@@ -37,38 +37,36 @@
 /* Vertex program opcodes */
 enum vp_opcode
 {
-   VP_OPCODE_MOV,
-   VP_OPCODE_LIT,
-   VP_OPCODE_RCP,
-   VP_OPCODE_RSQ,
-   VP_OPCODE_EXP,
-   VP_OPCODE_LOG,
-   VP_OPCODE_MUL,
+   VP_OPCODE_ABS,
    VP_OPCODE_ADD,
+   VP_OPCODE_ARL,
    VP_OPCODE_DP3,
    VP_OPCODE_DP4,
+   VP_OPCODE_DPH,
    VP_OPCODE_DST,
-   VP_OPCODE_MIN,
-   VP_OPCODE_MAX,
-   VP_OPCODE_SLT,
-   VP_OPCODE_SGE,
+   VP_OPCODE_END,		/* Placeholder */
+   VP_OPCODE_EX2,		/* ARB only */
+   VP_OPCODE_EXP,
+   VP_OPCODE_FLR,		/* ARB */
+   VP_OPCODE_FRC,		/* ARB */
+   VP_OPCODE_LG2,		/* ARB only */
+   VP_OPCODE_LIT,
+   VP_OPCODE_LOG,
    VP_OPCODE_MAD,
-   VP_OPCODE_ARL,
-   VP_OPCODE_DPH,
+   VP_OPCODE_MAX,
+   VP_OPCODE_MIN,
+   VP_OPCODE_MOV,
+   VP_OPCODE_MUL,
+   VP_OPCODE_POW,		/* ARB only */
+   VP_OPCODE_PRINT,		/* Mesa only */
    VP_OPCODE_RCC,
+   VP_OPCODE_RCP,
+   VP_OPCODE_RSQ,
+   VP_OPCODE_SGE,
+   VP_OPCODE_SLT,
    VP_OPCODE_SUB,
-   VP_OPCODE_ABS,
-   VP_OPCODE_END,
-   /* Additional opcodes for GL_ARB_vertex_program */ 
-   VP_OPCODE_FLR,
-   VP_OPCODE_FRC,
-   VP_OPCODE_EX2,
-   VP_OPCODE_LG2,
-   VP_OPCODE_POW,
-   VP_OPCODE_XPD,
-   VP_OPCODE_SWZ,
-   /* Special Mesa opcodes */
-   VP_OPCODE_PRINT
+   VP_OPCODE_SWZ,		/* ARB only */
+   VP_OPCODE_XPD		/* ARB only */
 };
 
 
@@ -76,34 +74,35 @@ enum vp_opcode
 /* Instruction source register */
 struct vp_src_register
 {
-   enum register_file File;  /* which register file */
-   GLint Index;              /* index into register file */
-   GLubyte Swizzle[4]; /* Each value is 0,1,2,3 for x,y,z,w or */
-                       /* SWIZZLE_ZERO or SWIZZLE_ONE for VP_OPCODE_SWZ. */
-   GLboolean Negate;
-   GLboolean RelAddr;
+   GLuint File:4;
+   GLuint Index:8;
+   GLuint Swizzle:12;
+   GLuint Negate:4;		/* ARB requires component-wise negation. */
+   GLuint RelAddr:1;
+   GLuint pad:3;
 };
 
 
 /* Instruction destination register */
 struct vp_dst_register
 {
-   enum register_file File;  /* which register file */
-   GLint Index;              /* index into register file */
-   GLboolean WriteMask[4];
+   GLuint File:4;
+   GLuint Index:8;
+   GLuint WriteMask:4;
+   GLuint pad:16;
 };
 
 
 /* Vertex program instruction */
 struct vp_instruction
 {
-   enum vp_opcode Opcode;
-   struct vp_src_register SrcReg[3];
-   struct vp_dst_register DstReg;
+   GLshort Opcode;
 #if FEATURE_MESA_program_debug
-   GLint StringPos;
+   GLshort StringPos;
 #endif
    void *Data;  /* some arbitrary data, only used for PRINT instruction now */
+   struct vp_src_register SrcReg[3];
+   struct vp_dst_register DstReg;
 };
 
 
diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
index faa4889a2ed..15b9021660a 100644
--- a/src/mesa/shader/program.c
+++ b/src/mesa/shader/program.c
@@ -368,6 +368,7 @@ _mesa_free_parameters(struct program_parameter_list *paramList)
       _mesa_free((void *) paramList->Parameters[i].Name);
    }
    _mesa_free(paramList->Parameters);
+   _mesa_free(paramList->ParameterValues);
    paramList->NumParameters = 0;
    paramList->Parameters = NULL;
 }
@@ -387,7 +388,13 @@ add_parameter(struct program_parameter_list *paramList,
       _mesa_realloc(paramList->Parameters,
                     n * sizeof(struct program_parameter),
                     (n + 1) * sizeof(struct program_parameter));
-   if (!paramList->Parameters) {
+   paramList->ParameterValues = (GLfloat (*)[4])
+      _mesa_realloc(paramList->ParameterValues,
+                    n * 4 * sizeof(GLfloat),
+                    (n + 1) * 4 * sizeof(GLfloat));
+
+   if (!paramList->Parameters ||
+       !paramList->ParameterValues) {
       /* out of memory */
       paramList->NumParameters = 0;
       return -1;
@@ -397,7 +404,7 @@ add_parameter(struct program_parameter_list *paramList,
       paramList->Parameters[n].Name = _mesa_strdup(name);
       paramList->Parameters[n].Type = type;
       if (values)
-         COPY_4V(paramList->Parameters[n].Values, values);
+         COPY_4V(paramList->ParameterValues[n], values);
       return (GLint) n;
    }
 }
@@ -491,7 +498,7 @@ _mesa_lookup_parameter_value(struct program_parameter_list *paramList,
       /* name is null-terminated */
       for (i = 0; i < paramList->NumParameters; i++) {
          if (_mesa_strcmp(paramList->Parameters[i].Name, name) == 0)
-            return paramList->Parameters[i].Values;
+            return paramList->ParameterValues[i];
       }
    }
    else {
@@ -499,7 +506,7 @@ _mesa_lookup_parameter_value(struct program_parameter_list *paramList,
       for (i = 0; i < paramList->NumParameters; i++) {
          if (_mesa_strncmp(paramList->Parameters[i].Name, name, nameLen) == 0
              && _mesa_strlen(paramList->Parameters[i].Name) == (size_t)nameLen)
-            return paramList->Parameters[i].Values;
+            return paramList->ParameterValues[i];
       }
    }
    return NULL;
@@ -629,14 +636,18 @@ _mesa_fetch_state(GLcontext *ctx, const enum state_index state[],
                /* Compute infinite half angle vector:
                 *   half-vector = light_position + (0, 0, 1) 
                 * and then normalize.  w = 0
-					 *
-					 * light.EyePosition.w should be 0 for infinite lights.
+		*
+		* light.EyePosition.w should be 0 for infinite lights.
                 */
-					ADD_3V(value, eye_z, ctx->Light.Light[ln].EyePosition);
-					NORMALIZE_3FV(value);
-					value[3] = 0;
+	       ADD_3V(value, eye_z, ctx->Light.Light[ln].EyePosition);
+	       NORMALIZE_3FV(value);
+	       value[3] = 0;
             }						  
             return;
+	 case STATE_POSITION_NORMALIZED:
+            COPY_4V(value, ctx->Light.Light[ln].EyePosition);
+	    NORMALIZE_3FV( value );
+            return;
          default:
             _mesa_problem(ctx, "Invalid light state in fetch_state");
             return;
@@ -879,6 +890,20 @@ _mesa_fetch_state(GLcontext *ctx, const enum state_index state[],
          }
       }
       return;
+
+   case STATE_INTERNAL:
+      {
+         switch (state[1]) {
+	    case STATE_NORMAL_SCALE:
+               ASSIGN_4V(value, ctx->_ModelViewInvScale, 0, 0, 1);
+               break;
+	    default:
+               _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()");
+               return;
+         }
+      }
+      return;
+
    default:
       _mesa_problem(ctx, "Invalid state in _mesa_fetch_state");
       return;
@@ -903,8 +928,9 @@ _mesa_load_state_parameters(GLcontext *ctx,
 
    for (i = 0; i < paramList->NumParameters; i++) {
       if (paramList->Parameters[i].Type == STATE) {
-         _mesa_fetch_state(ctx, paramList->Parameters[i].StateIndexes,
-                           paramList->Parameters[i].Values);
+         _mesa_fetch_state(ctx, 
+			   paramList->Parameters[i].StateIndexes,
+                           paramList->ParameterValues[i]);
       }
    }
 }
diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h
index dcd64adfe9d..e290c92ee3c 100644
--- a/src/mesa/shader/program.h
+++ b/src/mesa/shader/program.h
@@ -51,6 +51,29 @@
 #define SWIZZLE_ZERO 4		/* keep these values together: KW */
 #define SWIZZLE_ONE  5		/* keep these values together: KW */
 
+#define MAKE_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<3) | ((c)<<6) | ((d)<<9))
+#define MAKE_SWIZZLE(x)        MAKE_SWIZZLE4((x)[0], (x)[1], (x)[2], (x)[3])
+#define SWIZZLE_NOOP           MAKE_SWIZZLE4(0,1,2,3)
+#define GET_SWZ(swz, idx)      (((swz) >> ((idx)*3)) & 0x7)
+#define GET_BIT(msk, idx)      (((msk) >> (idx)) & 0x1)
+
+
+#define WRITEMASK_X     0x1
+#define WRITEMASK_Y     0x2
+#define WRITEMASK_XY    0x3
+#define WRITEMASK_Z     0x4
+#define WRITEMASK_XZ    0x5
+#define WRITEMASK_YZ    0x6
+#define WRITEMASK_XYZ   0x7
+#define WRITEMASK_W     0x8
+#define WRITEMASK_XW    0x9
+#define WRITEMASK_YW    0xa
+#define WRITEMASK_XYW   0xb
+#define WRITEMASK_ZW    0xc
+#define WRITEMASK_XZW   0xd
+#define WRITEMASK_YZW   0xe
+#define WRITEMASK_XYZW  0xf
+
 
 extern struct program _mesa_DummyProgram;
 
@@ -158,7 +181,11 @@ enum state_index {
    STATE_FRAGMENT_PROGRAM,
 
    STATE_ENV,
-   STATE_LOCAL
+   STATE_LOCAL,
+
+   STATE_INTERNAL,		/* Mesa additions */
+   STATE_NORMAL_SCALE,
+   STATE_POSITION_NORMALIZED
 };
 
 
@@ -183,7 +210,6 @@ struct program_parameter
    const char *Name;                   /* Null-terminated */
    enum parameter_type Type;
    enum state_index StateIndexes[6];   /* Global state reference */
-   GLfloat Values[4];
 };
 
 
@@ -191,6 +217,7 @@ struct program_parameter_list
 {
    GLuint NumParameters;
    struct program_parameter *Parameters;
+   GLfloat (*ParameterValues)[4];
 };
 
 
diff --git a/src/mesa/swrast/s_nvfragprog.c b/src/mesa/swrast/s_nvfragprog.c
index 5d9979c5c62..2fea568cc90 100644
--- a/src/mesa/swrast/s_nvfragprog.c
+++ b/src/mesa/swrast/s_nvfragprog.c
@@ -137,10 +137,10 @@ get_register_pointer( GLcontext *ctx,
          /* Fallthrough */
       case PROGRAM_NAMED_PARAM:
          ASSERT(source->Index < (GLint) program->Parameters->NumParameters);
-         src = program->Parameters->Parameters[source->Index].Values;
+         src = program->Parameters->ParameterValues[source->Index];
          break;
       default:
-         _mesa_problem(ctx, "Invalid input register file in fetch_vector4");
+         _mesa_problem(ctx, "Invalid input register file %d in fetch_vector4", source->File);
          src = NULL;
    }
    return src;
@@ -161,10 +161,10 @@ fetch_vector4( GLcontext *ctx,
    const GLfloat *src = get_register_pointer(ctx, source, machine, program);
    ASSERT(src);
 
-   result[0] = src[source->Swizzle[0]];
-   result[1] = src[source->Swizzle[1]];
-   result[2] = src[source->Swizzle[2]];
-   result[3] = src[source->Swizzle[3]];
+   result[0] = src[GET_SWZ(source->Swizzle, 0)];
+   result[1] = src[GET_SWZ(source->Swizzle, 1)];
+   result[2] = src[GET_SWZ(source->Swizzle, 2)];
+   result[3] = src[GET_SWZ(source->Swizzle, 3)];
 
    if (source->NegateBase) {
       result[0] = -result[0];
@@ -291,10 +291,10 @@ fetch_vector4_deriv( GLcontext *ctx,
       return GL_FALSE;
    }
 
-   result[0] = src[source->Swizzle[0]];
-   result[1] = src[source->Swizzle[1]];
-   result[2] = src[source->Swizzle[2]];
-   result[3] = src[source->Swizzle[3]];
+   result[0] = src[GET_SWZ(source->Swizzle, 0)];
+   result[1] = src[GET_SWZ(source->Swizzle, 1)];
+   result[2] = src[GET_SWZ(source->Swizzle, 2)];
+   result[3] = src[GET_SWZ(source->Swizzle, 3)];
 
    if (source->NegateBase) {
       result[0] = -result[0];
@@ -331,7 +331,7 @@ fetch_vector1( GLcontext *ctx,
    const GLfloat *src = get_register_pointer(ctx, source, machine, program);
    ASSERT(src);
 
-   result[0] = src[source->Swizzle[0]];
+   result[0] = src[GET_SWZ(source->Swizzle, 0)];
 
    if (source->NegateBase) {
       result[0] = -result[0];
@@ -397,8 +397,8 @@ store_vector4( const struct fp_instruction *inst,
    GLfloat *dstReg;
    GLfloat dummyReg[4];
    GLfloat clampedValue[4];
-   const GLboolean *writeMask = dest->WriteMask;
    GLboolean condWriteMask[4];
+   GLuint writeMask = dest->WriteMask;
 
    switch (dest->File) {
       case PROGRAM_OUTPUT:
@@ -433,33 +433,37 @@ store_vector4( const struct fp_instruction *inst,
    }
 
    if (dest->CondMask != COND_TR) {
-      condWriteMask[0] = writeMask[0]
-         && test_cc(machine->CondCodes[dest->CondSwizzle[0]], dest->CondMask);
-      condWriteMask[1] = writeMask[1]
-         && test_cc(machine->CondCodes[dest->CondSwizzle[1]], dest->CondMask);
-      condWriteMask[2] = writeMask[2]
-         && test_cc(machine->CondCodes[dest->CondSwizzle[2]], dest->CondMask);
-      condWriteMask[3] = writeMask[3]
-         && test_cc(machine->CondCodes[dest->CondSwizzle[3]], dest->CondMask);
-      writeMask = condWriteMask;
+      condWriteMask[0] = GET_BIT(writeMask, 0)
+         && test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 0)], dest->CondMask);
+      condWriteMask[1] = GET_BIT(writeMask, 1)
+         && test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 1)], dest->CondMask);
+      condWriteMask[2] = GET_BIT(writeMask, 2)
+         && test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 2)], dest->CondMask);
+      condWriteMask[3] = GET_BIT(writeMask, 3)
+         && test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 3)], dest->CondMask);
+
+      writeMask = ((condWriteMask[0] << 0) |
+		   (condWriteMask[1] << 1) |
+		   (condWriteMask[2] << 2) |
+		   (condWriteMask[3] << 3));
    }
 
-   if (writeMask[0]) {
+   if (GET_BIT(writeMask, 0)) {
       dstReg[0] = value[0];
       if (updateCC)
          machine->CondCodes[0] = generate_cc(value[0]);
    }
-   if (writeMask[1]) {
+   if (GET_BIT(writeMask, 1)) {
       dstReg[1] = value[1];
       if (updateCC)
          machine->CondCodes[1] = generate_cc(value[1]);
    }
-   if (writeMask[2]) {
+   if (GET_BIT(writeMask, 2)) {
       dstReg[2] = value[2];
       if (updateCC)
          machine->CondCodes[2] = generate_cc(value[2]);
    }
-   if (writeMask[3]) {
+   if (GET_BIT(writeMask, 3)) {
       dstReg[3] = value[3];
       if (updateCC)
          machine->CondCodes[3] = generate_cc(value[3]);
@@ -779,12 +783,12 @@ execute_program( GLcontext *ctx,
             break;
          case FP_OPCODE_KIL_NV: /* NV_f_p only */
             {
-               const GLuint *swizzle = inst->DstReg.CondSwizzle;
+               const GLuint swizzle = inst->DstReg.CondSwizzle;
                const GLuint condMask = inst->DstReg.CondMask;
-               if (test_cc(machine->CondCodes[swizzle[0]], condMask) ||
-                   test_cc(machine->CondCodes[swizzle[1]], condMask) ||
-                   test_cc(machine->CondCodes[swizzle[2]], condMask) ||
-                   test_cc(machine->CondCodes[swizzle[3]], condMask)) {
+               if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
+                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
+                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
+                   test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
                   return GL_FALSE;
                }
             }
@@ -1154,12 +1158,13 @@ execute_program( GLcontext *ctx,
 
                /* do extended swizzling here */
                for (i = 0; i < 3; i++) {
-                  if (source->Swizzle[i] == SWIZZLE_ZERO)
+                  if (GET_SWZ(source->Swizzle, i) == SWIZZLE_ZERO)
                      result[i] = 0.0;
-                  else if (source->Swizzle[i] == SWIZZLE_ONE)
+                  else if (GET_SWZ(source->Swizzle, i) == SWIZZLE_ONE)
                      result[i] = -1.0;
                   else
-                     result[i] = -src[source->Swizzle[i]];
+                     result[i] = -src[GET_SWZ(source->Swizzle, i)];
+
                   if (source->NegateBase)
                      result[i] = -result[i];
                }
@@ -1224,7 +1229,7 @@ execute_program( GLcontext *ctx,
             {
                GLfloat texcoord[4], color[4];
                fetch_vector4( ctx, &inst->SrcReg[0], machine, program, texcoord );
-               if (inst->TexSrcBit != TEXTURE_CUBE_BIT) {
+               if (inst->TexSrcIdx != TEXTURE_CUBE_INDEX) {
                   texcoord[0] /= texcoord[3];
                   texcoord[1] /= texcoord[3];
                   texcoord[2] /= texcoord[3];
-- 
cgit v1.2.3