Committing in .
authorJouk Jansen <joukj@hrem.stm.tudelft.nl>
Mon, 5 Apr 2004 06:12:01 +0000 (06:12 +0000)
committerJouk Jansen <joukj@hrem.stm.tudelft.nl>
Mon, 5 Apr 2004 06:12:01 +0000 (06:12 +0000)
 Updated OpenVMS compile support due to shader directory.
 Removed <CR>'s in arbprogparse.c

 Modified Files:
  Mesa/src/mesa/descrip.mms
  Mesa/src/mesa/drivers/common/descrip.mms
  Mesa/src/mesa/main/descrip.mms
  Mesa/src/mesa/shader/arbprogparse.c
  Mesa/src/mesa/shader/descrip.mms
  Mesa/src/mesa/swrast/descrip.mms Mesa/src/mesa/tnl/descrip.mms
 ----------------------------------------------------------------------

src/mesa/descrip.mms
src/mesa/drivers/common/descrip.mms
src/mesa/main/descrip.mms
src/mesa/shader/arbprogparse.c
src/mesa/shader/descrip.mms
src/mesa/swrast/descrip.mms
src/mesa/tnl/descrip.mms

index f1a58d7d65eb007602295eb8ccf9c34f0aef4e8c..a12e3fc1b74a1082ddcd748eff2b752691f47167 100644 (file)
@@ -6,6 +6,8 @@ all :
        $(MMS)$(MMSQUALIFIERS)
        set default [-.glapi]
        $(MMS)$(MMSQUALIFIERS)
+       set default [-.shader]
+       $(MMS)$(MMSQUALIFIERS)
        set default [-.drivers.common]
        $(MMS)$(MMSQUALIFIERS)
        set default [-.x11]
index 7a7765b9ae7eeaa485e8287ba408a003e6e6dc4e..eedac1a3a9408dbcf8da8dbe41b1fd12714d9423 100644 (file)
@@ -1,37 +1,37 @@
-# Makefile for core library for VMS
-# contributed by Jouk Jansen  joukj@hrem.stm.tudelft.nl
-# Last revision : 16 June 2003
-
-.first
-       define gl [----.include.gl]
-       define math [--.math]
-       define swrast [--.swrast]
-
-.include [----]mms-config.
-
-##### MACROS #####
-
-VPATH = RCS
-
-INCDIR = [----.include],[--.main],[--.glapi]
-LIBDIR = [----.lib]
-CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1)/name=(as_is,short)
-
-SOURCES = driverfuncs.c
-
-OBJECTS =driverfuncs.obj
-
-##### RULES #####
-
-VERSION=Mesa V3.4
-
-##### TARGETS #####
-# Make the library
-$(LIBDIR)$(GL_LIB) : $(OBJECTS)
-  @ library $(LIBDIR)$(GL_LIB) $(OBJECTS)
-
-clean :
-       purge
-       delete *.obj;*
-
-driverfuncs.obj : driverfuncs.c
+# Makefile for core library for VMS\r
+# contributed by Jouk Jansen  joukj@hrem.stm.tudelft.nl\r
+# Last revision : 16 June 2003\r
+\r
+.first\r
+       define gl [----.include.gl]\r
+       define math [--.math]\r
+       define swrast [--.swrast]\r
+\r
+.include [----]mms-config.\r
+\r
+##### MACROS #####\r
+\r
+VPATH = RCS\r
+\r
+INCDIR = [----.include],[--.main],[--.glapi],[--.shader]\r
+LIBDIR = [----.lib]\r
+CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1)/name=(as_is,short)\r
+\r
+SOURCES = driverfuncs.c\r
+\r
+OBJECTS =driverfuncs.obj\r
+\r
+##### RULES #####\r
+\r
+VERSION=Mesa V3.4\r
+\r
+##### TARGETS #####\r
+# Make the library\r
+$(LIBDIR)$(GL_LIB) : $(OBJECTS)\r
+  @ library $(LIBDIR)$(GL_LIB) $(OBJECTS)\r
+\r
+clean :\r
+       purge\r
+       delete *.obj;*\r
+\r
+driverfuncs.obj : driverfuncs.c\r
index 6591c0cf34ef00dde50cf951c5923bf96d55ed2f..d4fa04fd97f41241145e10a8d7268f3e39b7a99f 100644 (file)
-# Makefile for core library for VMS
-# contributed by Jouk Jansen  joukj@hrem.stm.tudelft.nl
-# Last revision : 16 June 2003
-
-.first
-       define gl [---.include.gl]
-       define math [-.math]
-
-.include [---]mms-config.
-
-##### MACROS #####
-
-VPATH = RCS
-
-INCDIR = [---.include],[-.glapi]
-LIBDIR = [---.lib]
-CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1)/name=(as_is,short)
-
-SOURCES =accum.c \
-       api_arrayelt.c \
-       api_loopback.c \
-       api_noop.c \
-       api_validate.c \
-       attrib.c \
-       blend.c \
-       bufferobj.c \
-       buffers.c \
-       clip.c \
-       colortab.c \
-       context.c \
-       convolve.c \
-       debug.c \
-       depth.c \
-       dispatch.c \
-       dlist.c \
-       drawpix.c \
-       enable.c \
-       enums.c \
-       eval.c \
-       extensions.c \
-       feedback.c \
-       fog.c \
-       get.c \
-       hash.c \
-       hint.c \
-       histogram.c \
-       image.c \
-       imports.c \
-       light.c \
-       lines.c \
-       matrix.c \
-       occlude.c \
-       pixel.c \
-       points.c \
-       polygon.c \
-       rastpos.c \
-       state.c \
-       stencil.c \
-       texcompress.c \
-       texformat.c \
-       teximage.c \
-       texobj.c \
-       texstate.c \
-       texstore.c \
-       texutil.c \
-       varray.c \
-       vtxfmt.c
-
-OBJECTS=accum.obj,\
-api_arrayelt.obj,\
-api_loopback.obj,\
-api_noop.obj,\
-api_validate.obj,\
-attrib.obj,\
-blend.obj,\
-bufferobj.obj,\
-buffers.obj,\
-clip.obj,\
-colortab.obj,\
-context.obj,\
-convolve.obj,\
-debug.obj,\
-depth.obj,\
-dispatch.obj,\
-dlist.obj,\
-drawpix.obj,\
-enable.obj,\
-enums.obj,\
-eval.obj,\
-extensions.obj,\
-feedback.obj,\
-fog.obj,\
-get.obj,\
-hash.obj,\
-hint.obj,\
-histogram.obj,\
-image.obj,\
-imports.obj,\
-light.obj,\
-lines.obj,\
-matrix.obj,\
-occlude.obj,\
-pixel.obj,\
-points.obj,\
-polygon.obj,\
-rastpos.obj,\
-state.obj,\
-stencil.obj,\
-texcompress.obj,\
-texformat.obj,\
-teximage.obj,\
-texobj.obj,\
-texstate.obj,\
-texstore.obj,\
-texutil.obj,\
-varray.obj,\
-vtxfmt.obj
-
-##### RULES #####
-
-VERSION=Mesa V3.4
-
-##### TARGETS #####
-# Make the library
-$(LIBDIR)$(GL_LIB) : $(OBJECTS)
-  @ $(MAKELIB) $(GL_LIB) $(OBJECTS)
-  @ rename $(GL_LIB)* $(LIBDIR)
-
-clean :
-       purge
-       delete *.obj;*
-
-accum.obj : accum.c
-api_arrayelt.obj : api_arrayelt.c
-api_loopback.obj : api_loopback.c
-api_noop.obj : api_noop.c
-api_validate.obj : api_validate.c
-attrib.obj : attrib.c
-blend.obj : blend.c
-bufferobj.obj : bufferobj.c
-buffers.obj : buffers.c
-clip.obj : clip.c
-colortab.obj : colortab.c
-context.obj : context.c
-convolve.obj : convolve.c
-debug.obj : debug.c
-depth.obj : depth.c
-dispatch.obj : dispatch.c
-dlist.obj : dlist.c
-drawpix.obj : drawpix.c
-enable.obj : enable.c
-enums.obj : enums.c
-eval.obj : eval.c
-extensions.obj : extensions.c
-feedback.obj : feedback.c
-fog.obj : fog.c
-get.obj : get.c
-hash.obj : hash.c
-hint.obj : hint.c
-histogram.obj : histogram.c
-image.obj : image.c
-imports.obj : imports.c vsnprintf.c
-light.obj : light.c
-lines.obj : lines.c
-matrix.obj : matrix.c
-occlude.obj : occlude.c
-pixel.obj : pixel.c
-points.obj : points.c
-polygon.obj : polygon.c
-rastpos.obj : rastpos.c
-state.obj : state.c
-stencil.obj : stencil.c
-texcompress.obj : texcompress.c
-texformat.obj : texformat.c
-teximage.obj : teximage.c
-texobj.obj : texobj.c
-texstate.obj : texstate.c
-texstore.obj : texstore.c
-texutil.obj : texutil.c
-varray.obj : varray.c
-vtxfmt.obj : vtxfmt.c
+# Makefile for core library for VMS\r
+# contributed by Jouk Jansen  joukj@hrem.stm.tudelft.nl\r
+# Last revision : 16 June 2003\r
+\r
+.first\r
+       define gl [---.include.gl]\r
+       define math [-.math]\r
+\r
+.include [---]mms-config.\r
+\r
+##### MACROS #####\r
+\r
+VPATH = RCS\r
+\r
+INCDIR = [---.include],[-.glapi],[-.shader]\r
+LIBDIR = [---.lib]\r
+CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1)/name=(as_is,short)\r
+\r
+SOURCES =accum.c \\r
+       api_arrayelt.c \\r
+       api_loopback.c \\r
+       api_noop.c \\r
+       api_validate.c \\r
+       attrib.c \\r
+       blend.c \\r
+       bufferobj.c \\r
+       buffers.c \\r
+       clip.c \\r
+       colortab.c \\r
+       context.c \\r
+       convolve.c \\r
+       debug.c \\r
+       depth.c \\r
+       dispatch.c \\r
+       dlist.c \\r
+       drawpix.c \\r
+       enable.c \\r
+       enums.c \\r
+       eval.c \\r
+       extensions.c \\r
+       feedback.c \\r
+       fog.c \\r
+       get.c \\r
+       hash.c \\r
+       hint.c \\r
+       histogram.c \\r
+       image.c \\r
+       imports.c \\r
+       light.c \\r
+       lines.c \\r
+       matrix.c \\r
+       occlude.c \\r
+       pixel.c \\r
+       points.c \\r
+       polygon.c \\r
+       rastpos.c \\r
+       state.c \\r
+       stencil.c \\r
+       texcompress.c \\r
+       texformat.c \\r
+       teximage.c \\r
+       texobj.c \\r
+       texstate.c \\r
+       texstore.c \\r
+       texutil.c \\r
+       varray.c \\r
+       vtxfmt.c\r
+\r
+OBJECTS=accum.obj,\\r
+api_arrayelt.obj,\\r
+api_loopback.obj,\\r
+api_noop.obj,\\r
+api_validate.obj,\\r
+attrib.obj,\\r
+blend.obj,\\r
+bufferobj.obj,\\r
+buffers.obj,\\r
+clip.obj,\\r
+colortab.obj,\\r
+context.obj,\\r
+convolve.obj,\\r
+debug.obj,\\r
+depth.obj,\\r
+dispatch.obj,\\r
+dlist.obj,\\r
+drawpix.obj,\\r
+enable.obj,\\r
+enums.obj,\\r
+eval.obj,\\r
+extensions.obj,\\r
+feedback.obj,\\r
+fog.obj,\\r
+get.obj,\\r
+hash.obj,\\r
+hint.obj,\\r
+histogram.obj,\\r
+image.obj,\\r
+imports.obj,\\r
+light.obj,\\r
+lines.obj,\\r
+matrix.obj,\\r
+occlude.obj,\\r
+pixel.obj,\\r
+points.obj,\\r
+polygon.obj,\\r
+rastpos.obj,\\r
+state.obj,\\r
+stencil.obj,\\r
+texcompress.obj,\\r
+texformat.obj,\\r
+teximage.obj,\\r
+texobj.obj,\\r
+texstate.obj,\\r
+texstore.obj,\\r
+texutil.obj,\\r
+varray.obj,\\r
+vtxfmt.obj\r
+\r
+##### RULES #####\r
+\r
+VERSION=Mesa V3.4\r
+\r
+##### TARGETS #####\r
+# Make the library\r
+$(LIBDIR)$(GL_LIB) : $(OBJECTS)\r
+  @ $(MAKELIB) $(GL_LIB) $(OBJECTS)\r
+  @ rename $(GL_LIB)* $(LIBDIR)\r
+\r
+clean :\r
+       purge\r
+       delete *.obj;*\r
+\r
+accum.obj : accum.c\r
+api_arrayelt.obj : api_arrayelt.c\r
+api_loopback.obj : api_loopback.c\r
+api_noop.obj : api_noop.c\r
+api_validate.obj : api_validate.c\r
+attrib.obj : attrib.c\r
+blend.obj : blend.c\r
+bufferobj.obj : bufferobj.c\r
+buffers.obj : buffers.c\r
+clip.obj : clip.c\r
+colortab.obj : colortab.c\r
+context.obj : context.c\r
+convolve.obj : convolve.c\r
+debug.obj : debug.c\r
+depth.obj : depth.c\r
+dispatch.obj : dispatch.c\r
+dlist.obj : dlist.c\r
+drawpix.obj : drawpix.c\r
+enable.obj : enable.c\r
+enums.obj : enums.c\r
+eval.obj : eval.c\r
+extensions.obj : extensions.c\r
+feedback.obj : feedback.c\r
+fog.obj : fog.c\r
+get.obj : get.c\r
+hash.obj : hash.c\r
+hint.obj : hint.c\r
+histogram.obj : histogram.c\r
+image.obj : image.c\r
+imports.obj : imports.c vsnprintf.c\r
+light.obj : light.c\r
+lines.obj : lines.c\r
+matrix.obj : matrix.c\r
+occlude.obj : occlude.c\r
+pixel.obj : pixel.c\r
+points.obj : points.c\r
+polygon.obj : polygon.c\r
+rastpos.obj : rastpos.c\r
+state.obj : state.c\r
+stencil.obj : stencil.c\r
+texcompress.obj : texcompress.c\r
+texformat.obj : texformat.c\r
+teximage.obj : teximage.c\r
+texobj.obj : texobj.c\r
+texstate.obj : texstate.c\r
+texstore.obj : texstore.c\r
+texutil.obj : texutil.c\r
+varray.obj : varray.c\r
+vtxfmt.obj : vtxfmt.c\r
index 9099fd8f42c30ca672fd79380f37630830813c88..6cbdd39d297668c7509224383970262cfe0323be 100644 (file)
-/*
- * Mesa 3-D graphics library
- * Version:  6.1
- *
- * 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.
- */
-
-#define DEBUG_PARSING 0
-
-/**
- * \file arbprogparse.c
- * ARB_*_program parser core
- * \author Karl Rasche
- */
-
-#include "mtypes.h"
-#include "glheader.h"
-#include "context.h"
-#include "hash.h"
-#include "imports.h"
-#include "macros.h"
-#include "program.h"
-#include "nvvertprog.h"
-#include "nvfragprog.h"
-#include "arbprogparse.h"
-#include "grammar_mesa.h"
-
-/* TODO:
- *    Fragment Program Stuff:
- *    -----------------------------------------------------
- *
- *    - things from Michal's email
- *       + overflow on atoi
- *       + not-overflowing floats (don't use parse_integer..)
- *       + can remove range checking in arbparse.c
- *
- *    - check all limits of number of various variables
- *      + parameters
- *
- *    - test! test! test!
- *
- *    Vertex Program Stuff:
- *    -----------------------------------------------------
- *    - Optimize param array usage and count limits correctly, see spec,
- *         section 2.14.3.7
- *       + Record if an array is reference absolutly or relatively (or both)
- *       + For absolute arrays, store a bitmap of accesses
- *       + For single parameters, store an access flag
- *       + After parsing, make a parameter cleanup and merging pass, where
- *           relative arrays are layed out first, followed by abs arrays, and
- *           finally single state.
- *       + Remap offsets for param src and dst registers
- *       + Now we can properly count parameter usage
- *
- *    - Multiple state binding errors in param arrays (see spec, just before
- *         section 2.14.3.3)
- *    - grep for XXX
- *
- *    Mesa Stuff
- *    -----------------------------------------------------
- *    - User clipping planes vs. PositionInvariant
- *    - Is it sufficient to just multiply by the mvp to transform in the
- *        PositionInvariant case? Or do we need something more involved?
- *
- *    - vp_src swizzle is GLubyte, fp_src swizzle is GLuint
- *    - fetch state listed in program_parameters list
- *       + WTF should this go???
- *       + currently in nvvertexec.c and s_nvfragprog.c
- *
- *    - allow for multiple address registers (and fetch address regs properly)
- *
- *    Cosmetic Stuff
- *    -----------------------------------------------------
- *     - remove any leftover unused grammer.c stuff (dict_ ?)
- *     - fix grammer.c error handling so its not static
- *     - #ifdef around stuff pertaining to extentions
- *
- *    Outstanding Questions:
- *    -----------------------------------------------------
- *    - ARB_matrix_palette / ARB_vertex_blend -- not supported
- *      what gets hacked off because of this:
- *       + VERTEX_ATTRIB_MATRIXINDEX
- *       + VERTEX_ATTRIB_WEIGHT
- *       + MATRIX_MODELVIEW
- *       + MATRIX_PALETTE
- *
- *    - When can we fetch env/local params from their own register files, and
- *      when to we have to fetch them into the main state register file?
- *      (think arrays)
- *
- *    Grammar Changes:
- *    -----------------------------------------------------
- */
-
-/* Changes since moving the file to shader directory
-
-2004-III-4 ------------------------------------------------------------
-- added #include "grammar_mesa.h"
-- removed grammar specific code part (it resides now in grammar.c)
-- added GL_ARB_fragment_program_shadow tokens
-- modified #include "arbparse_syn.h"
-- major changes inside _mesa_parse_arb_program()
-- check the program string for '\0' characters
-- copy the program string to a one-byte-longer location to have
-  it null-terminated
-- position invariance test (not writing to result.position) moved
-  to syntax part
-*/
-
-typedef GLubyte *production;
-
-/**
- * This is the text describing the rules to parse the grammar
- */
-static char arb_grammar_text[] =
-#include "arbprogram_syn.h"
-;
-
-/**
- * These should match up with the values defined in arbprogram.syn
- */
-
-/*
-    Changes:
-    - changed and merged V_* and F_* opcode values to OP_*.
-    - added GL_ARB_fragment_program_shadow specific tokens (michal)
-*/
-#define  REVISION                                   0x07
-
-/* program type */
-#define  FRAGMENT_PROGRAM                           0x01
-#define  VERTEX_PROGRAM                             0x02
-
-/* program section */
-#define  OPTION                                     0x01
-#define  INSTRUCTION                                0x02
-#define  DECLARATION                                0x03
-#define  END                                        0x04
-
-/* GL_ARB_fragment_program option flags */
-#define  ARB_PRECISION_HINT_FASTEST                 0x01
-#define  ARB_PRECISION_HINT_NICEST                  0x02
-#define  ARB_FOG_EXP                                0x04
-#define  ARB_FOG_EXP2                               0x08
-#define  ARB_FOG_LINEAR                             0x10
-
-/* GL_ARB_vertex_program option flags */
-#define  ARB_POSITION_INVARIANT                     0x20
-
-/* GL_ARB_fragment_program_shadow option flags */
-#define  ARB_FRAGMENT_PROGRAM_SHADOW                0x40
-
-/* GL_ARB_fragment_program instruction class */
-#define  OP_ALU_INST                                0x00
-#define  OP_TEX_INST                                0x01
-
-/* GL_ARB_vertex_program instruction class */
-/*       OP_ALU_INST */
-
-/* GL_ARB_fragment_program instruction type */
-#define  OP_ALU_VECTOR                               0x00
-#define  OP_ALU_SCALAR                               0x01
-#define  OP_ALU_BINSC                                0x02
-#define  OP_ALU_BIN                                  0x03
-#define  OP_ALU_TRI                                  0x04
-#define  OP_ALU_SWZ                                  0x05
-#define  OP_TEX_SAMPLE                               0x06
-#define  OP_TEX_KIL                                  0x07
-
-/* GL_ARB_vertex_program instruction type */
-#define  OP_ALU_ARL                                  0x08
-/*       OP_ALU_VECTOR */
-/*       OP_ALU_SCALAR */
-/*       OP_ALU_BINSC */
-/*       OP_ALU_BIN */
-/*       OP_ALU_TRI */
-/*       OP_ALU_SWZ */
-
-/* GL_ARB_fragment_program instruction code */
-#define  OP_ABS                                     0x00
-#define  OP_ABS_SAT                                 0x1B
-#define  OP_FLR                                     0x09
-#define  OP_FLR_SAT                                 0x26
-#define  OP_FRC                                     0x0A
-#define  OP_FRC_SAT                                 0x27
-#define  OP_LIT                                     0x0C
-#define  OP_LIT_SAT                                 0x2A
-#define  OP_MOV                                     0x11
-#define  OP_MOV_SAT                                 0x30
-#define  OP_COS                                     0x1F
-#define  OP_COS_SAT                                 0x20
-#define  OP_EX2                                     0x07
-#define  OP_EX2_SAT                                 0x25
-#define  OP_LG2                                     0x0B
-#define  OP_LG2_SAT                                 0x29
-#define  OP_RCP                                     0x14
-#define  OP_RCP_SAT                                 0x33
-#define  OP_RSQ                                     0x15
-#define  OP_RSQ_SAT                                 0x34
-#define  OP_SIN                                     0x38
-#define  OP_SIN_SAT                                 0x39
-#define  OP_SCS                                     0x35
-#define  OP_SCS_SAT                                 0x36
-#define  OP_POW                                     0x13
-#define  OP_POW_SAT                                 0x32
-#define  OP_ADD                                     0x01
-#define  OP_ADD_SAT                                 0x1C
-#define  OP_DP3                                     0x03
-#define  OP_DP3_SAT                                 0x21
-#define  OP_DP4                                     0x04
-#define  OP_DP4_SAT                                 0x22
-#define  OP_DPH                                     0x05
-#define  OP_DPH_SAT                                 0x23
-#define  OP_DST                                     0x06
-#define  OP_DST_SAT                                 0x24
-#define  OP_MAX                                     0x0F
-#define  OP_MAX_SAT                                 0x2E
-#define  OP_MIN                                     0x10
-#define  OP_MIN_SAT                                 0x2F
-#define  OP_MUL                                     0x12
-#define  OP_MUL_SAT                                 0x31
-#define  OP_SGE                                     0x16
-#define  OP_SGE_SAT                                 0x37
-#define  OP_SLT                                     0x17
-#define  OP_SLT_SAT                                 0x3A
-#define  OP_SUB                                     0x18
-#define  OP_SUB_SAT                                 0x3B
-#define  OP_XPD                                     0x1A
-#define  OP_XPD_SAT                                 0x43
-#define  OP_CMP                                     0x1D
-#define  OP_CMP_SAT                                 0x1E
-#define  OP_LRP                                     0x2B
-#define  OP_LRP_SAT                                 0x2C
-#define  OP_MAD                                     0x0E
-#define  OP_MAD_SAT                                 0x2D
-#define  OP_SWZ                                     0x19
-#define  OP_SWZ_SAT                                 0x3C
-#define  OP_TEX                                     0x3D
-#define  OP_TEX_SAT                                 0x3E
-#define  OP_TXB                                     0x3F
-#define  OP_TXB_SAT                                 0x40
-#define  OP_TXP                                     0x41
-#define  OP_TXP_SAT                                 0x42
-#define  OP_KIL                                     0x28
-
-/* GL_ARB_vertex_program instruction code */
-#define  OP_ARL                                     0x02
-/*       OP_ABS */
-/*       OP_FLR */
-/*       OP_FRC */
-/*       OP_LIT */
-/*       OP_MOV */
-/*       OP_EX2 */
-#define  OP_EXP                                     0x08
-/*       OP_LG2 */
-#define  OP_LOG                                     0x0D
-/*       OP_RCP */
-/*       OP_RSQ */
-/*       OP_POW */
-/*       OP_ADD */
-/*       OP_DP3 */
-/*       OP_DP4 */
-/*       OP_DPH */
-/*       OP_DST */
-/*       OP_MAX */
-/*       OP_MIN */
-/*       OP_MUL */
-/*       OP_SGE */
-/*       OP_SLT */
-/*       OP_SUB */
-/*       OP_XPD */
-/*       OP_MAD */
-/*       OP_SWZ */
-
-/* fragment attribute binding */
-#define  FRAGMENT_ATTRIB_COLOR                      0x01
-#define  FRAGMENT_ATTRIB_TEXCOORD                   0x02
-#define  FRAGMENT_ATTRIB_FOGCOORD                   0x03
-#define  FRAGMENT_ATTRIB_POSITION                   0x04
-
-/* vertex attribute binding */
-#define  VERTEX_ATTRIB_POSITION                     0x01
-#define  VERTEX_ATTRIB_WEIGHT                       0x02
-#define  VERTEX_ATTRIB_NORMAL                       0x03
-#define  VERTEX_ATTRIB_COLOR                        0x04
-#define  VERTEX_ATTRIB_FOGCOORD                     0x05
-#define  VERTEX_ATTRIB_TEXCOORD                     0x06
-#define  VERTEX_ATTRIB_MATRIXINDEX                  0x07
-#define  VERTEX_ATTRIB_GENERIC                      0x08
-
-/* fragment result binding */
-#define  FRAGMENT_RESULT_COLOR                      0x01
-#define  FRAGMENT_RESULT_DEPTH                      0x02
-
-/* vertex result binding */
-#define  VERTEX_RESULT_POSITION                     0x01
-#define  VERTEX_RESULT_COLOR                        0x02
-#define  VERTEX_RESULT_FOGCOORD                     0x03
-#define  VERTEX_RESULT_POINTSIZE                    0x04
-#define  VERTEX_RESULT_TEXCOORD                     0x05
-
-/* texture target */
-#define  TEXTARGET_1D                               0x01
-#define  TEXTARGET_2D                               0x02
-#define  TEXTARGET_3D                               0x03
-#define  TEXTARGET_RECT                             0x04
-#define  TEXTARGET_CUBE                             0x05
-/* GL_ARB_fragment_program_shadow */
-#define  TEXTARGET_SHADOW1D                         0x06
-#define  TEXTARGET_SHADOW2D                         0x07
-#define  TEXTARGET_SHADOWRECT                       0x08
-
-/* face type */
-#define  FACE_FRONT                                 0x00
-#define  FACE_BACK                                  0x01
-
-/* color type */
-#define  COLOR_PRIMARY                              0x00
-#define  COLOR_SECONDARY                            0x01
-
-/* component */
-#define  COMPONENT_X                                0x00
-#define  COMPONENT_Y                                0x01
-#define  COMPONENT_Z                                0x02
-#define  COMPONENT_W                                0x03
-#define  COMPONENT_0                                0x04
-#define  COMPONENT_1                                0x05
-
-/* array index type */
-#define  ARRAY_INDEX_ABSOLUTE                       0x00
-#define  ARRAY_INDEX_RELATIVE                       0x01
-
-/* matrix name */
-#define  MATRIX_MODELVIEW                           0x01
-#define  MATRIX_PROJECTION                          0x02
-#define  MATRIX_MVP                                 0x03
-#define  MATRIX_TEXTURE                             0x04
-#define  MATRIX_PALETTE                             0x05
-#define  MATRIX_PROGRAM                             0x06
-
-/* matrix modifier */
-#define  MATRIX_MODIFIER_IDENTITY                   0x00
-#define  MATRIX_MODIFIER_INVERSE                    0x01
-#define  MATRIX_MODIFIER_TRANSPOSE                  0x02
-#define  MATRIX_MODIFIER_INVTRANS                   0x03
-
-/* constant type */
-#define  CONSTANT_SCALAR                            0x01
-#define  CONSTANT_VECTOR                            0x02
-
-/* program param type */
-#define  PROGRAM_PARAM_ENV                          0x01
-#define  PROGRAM_PARAM_LOCAL                        0x02
-
-/* register type */
-#define  REGISTER_ATTRIB                            0x01
-#define  REGISTER_PARAM                             0x02
-#define  REGISTER_RESULT                            0x03
-#define  REGISTER_ESTABLISHED_NAME                  0x04
-
-/* param binding */
-#define  PARAM_NULL                                 0x00
-#define  PARAM_ARRAY_ELEMENT                        0x01
-#define  PARAM_STATE_ELEMENT                        0x02
-#define  PARAM_PROGRAM_ELEMENT                      0x03
-#define  PARAM_PROGRAM_ELEMENTS                     0x04
-#define  PARAM_CONSTANT                             0x05
-
-/* param state property */
-#define  STATE_MATERIAL_PARSER                      0x01
-#define  STATE_LIGHT_PARSER                         0x02
-#define  STATE_LIGHT_MODEL                          0x03
-#define  STATE_LIGHT_PROD                           0x04
-#define  STATE_FOG                                  0x05
-#define  STATE_MATRIX_ROWS                          0x06
-/* GL_ARB_fragment_program */
-#define  STATE_TEX_ENV                              0x07
-#define  STATE_DEPTH                                0x08
-/* GL_ARB_vertex_program */
-#define  STATE_TEX_GEN                              0x09
-#define  STATE_CLIP_PLANE                           0x0A
-#define  STATE_POINT                                0x0B
-
-/* state material property */
-#define  MATERIAL_AMBIENT                           0x01
-#define  MATERIAL_DIFFUSE                           0x02
-#define  MATERIAL_SPECULAR                          0x03
-#define  MATERIAL_EMISSION                          0x04
-#define  MATERIAL_SHININESS                         0x05
-
-/* state light property */
-#define  LIGHT_AMBIENT                              0x01
-#define  LIGHT_DIFFUSE                              0x02
-#define  LIGHT_SPECULAR                             0x03
-#define  LIGHT_POSITION                             0x04
-#define  LIGHT_ATTENUATION                          0x05
-#define  LIGHT_HALF                                 0x06
-#define  LIGHT_SPOT_DIRECTION                       0x07
-
-/* state light model property */
-#define  LIGHT_MODEL_AMBIENT                        0x01
-#define  LIGHT_MODEL_SCENECOLOR                     0x02
-
-/* state light product property */
-#define  LIGHT_PROD_AMBIENT                         0x01
-#define  LIGHT_PROD_DIFFUSE                         0x02
-#define  LIGHT_PROD_SPECULAR                        0x03
-
-/* state texture environment property */
-#define  TEX_ENV_COLOR                              0x01
-
-/* state texture generation coord property */
-#define  TEX_GEN_EYE                                0x01
-#define  TEX_GEN_OBJECT                             0x02
-
-/* state fog property */
-#define  FOG_COLOR                                  0x01
-#define  FOG_PARAMS                                 0x02
-
-/* state depth property */
-#define  DEPTH_RANGE                                0x01
-
-/* state point parameters property */
-#define  POINT_SIZE                                 0x01
-#define  POINT_ATTENUATION                          0x02
-
-/* declaration */
-#define  ATTRIB                                     0x01
-#define  PARAM                                      0x02
-#define  TEMP                                       0x03
-#define  OUTPUT                                     0x04
-#define  ALIAS                                      0x05
-/* GL_ARB_vertex_program */
-#define  ADDRESS                                    0x06
-
-/*-----------------------------------------------------------------------
- * From here on down is the semantic checking portion
- *
- */
-
-/**
- * Variable Table Handling functions
- */
-typedef enum
-{
-   vt_none,
-   vt_address,
-   vt_attrib,
-   vt_param,
-   vt_temp,
-   vt_output,
-   vt_alias
-} var_type;
-
-
-/*
- * Setting an explicit field for each of the binding properties is a bit wasteful
- * of space, but it should be much more clear when reading later on..
- */
-struct var_cache
-{
-   GLubyte *name;
-   var_type type;
-   GLuint address_binding;      /* The index of the address register we should
-                                 * be using                                        */
-   GLuint attrib_binding;       /* For type vt_attrib, see nvfragprog.h for values */
-   GLuint attrib_binding_idx;   /* The index into the attrib register file corresponding
-                                 * to the state in attrib_binding                  */
-   GLuint attrib_is_generic;    /* If the attrib was specified through a generic
-                                 * vertex attrib                                   */
-   GLuint temp_binding;         /* The index of the temp register we are to use    */
-   GLuint output_binding;       /* For type vt_output, see nvfragprog.h for values */
-   GLuint output_binding_idx;   /* This is the index into the result register file
-                                 * corresponding to the bound result state         */
-   struct var_cache *alias_binding;     /* For type vt_alias, points to the var_cache entry
-                                         * that this is aliased to                         */
-   GLuint param_binding_type;   /* {PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM,
-                                 *    PROGRAM_ENV_PARAM}                           */
-   GLuint param_binding_begin;  /* This is the offset into the program_parameter_list where
-                                 * the tokens representing our bound state (or constants)
-                                 * start */
-   GLuint param_binding_length; /* This is how many entries in the the program_parameter_list
-                                 * we take up with our state tokens or constants. Note that
-                                 * this is _not_ the same as the number of param registers
-                                 * we eventually use */
-   struct var_cache *next;
-};
-
-static GLvoid
-var_cache_create (struct var_cache **va)
-{
-   *va = (struct var_cache *) _mesa_malloc (sizeof (struct var_cache));
-   if (*va) {
-      (**va).name = NULL;
-      (**va).type = vt_none;
-      (**va).attrib_binding = ~0;
-      (**va).attrib_is_generic = 0;
-      (**va).temp_binding = ~0;
-      (**va).output_binding = ~0;
-      (**va).output_binding_idx = ~0;
-      (**va).param_binding_type = ~0;
-      (**va).param_binding_begin = ~0;
-      (**va).param_binding_length = ~0;
-      (**va).alias_binding = NULL;
-      (**va).next = NULL;
-   }
-}
-
-static GLvoid
-var_cache_destroy (struct var_cache **va)
-{
-   if (*va) {
-      var_cache_destroy (&(**va).next);
-      _mesa_free (*va);
-      *va = NULL;
-   }
-}
-
-static GLvoid
-var_cache_append (struct var_cache **va, struct var_cache *nv)
-{
-   if (*va)
-      var_cache_append (&(**va).next, nv);
-   else
-      *va = nv;
-}
-
-static struct var_cache *
-var_cache_find (struct var_cache *va, GLubyte * name)
-{
-   struct var_cache *first = va;
-
-   while (va) {
-      if (!strcmp ( (const char*) name, (const char*) va->name)) {
-         if (va->type == vt_alias)
-            return var_cache_find (first, va->name);
-         return va;
-      }
-
-      va = va->next;
-   }
-
-   return NULL;
-}
-
-/**
- * constructs an integer from 4 GLubytes in LE format
- */
-static GLuint
-parse_position (GLubyte ** inst)
-{
-   GLuint value;
-
-   value =  (GLuint) (*(*inst)++);
-   value += (GLuint) (*(*inst)++) * 0x100;
-   value += (GLuint) (*(*inst)++) * 0x10000;
-   value += (GLuint) (*(*inst)++) * 0x1000000;
-
-   return value;
-}
-
-/**
- * This will, given a string, lookup the string as a variable name in the
- * var cache. If the name is found, the var cache node corresponding to the
- * var name is returned. If it is not found, a new entry is allocated
- *
- * \param  I     Points into the binary array where the string identifier begins
- * \param  found 1 if the string was found in the var_cache, 0 if it was allocated
- * \return       The location on the var_cache corresponding the the string starting at I
- */
-static struct var_cache *
-parse_string (GLubyte ** inst, struct var_cache **vc_head,
-              struct arb_program *Program, GLuint * found)
-{
-   GLubyte *i = *inst;
-   struct var_cache *va = NULL;
-
-   *inst += _mesa_strlen ((char *) i) + 1;
-
-   va = var_cache_find (*vc_head, i);
-
-   if (va) {
-      *found = 1;
-      return va;
-   }
-
-   *found = 0;
-   var_cache_create (&va);
-   va->name = i;
-
-   var_cache_append (vc_head, va);
-
-   return va;
-}
-
-static char *
-parse_string_without_adding (GLubyte ** inst, struct arb_program *Program)
-{
-   GLubyte *i = *inst;
-
-   *inst += _mesa_strlen ((char *) i) + 1;
-
-   return (char *) i;
-}
-
-/**
- * \return 0 if sign is plus, 1 if sign is minus
- */
-static GLuint
-parse_sign (GLubyte ** inst)
-{
-   /*return *(*inst)++ != '+'; */
-
-   if (**inst == '-') {
-      (*inst)++;
-      return 1;
-   }
-   else if (**inst == '+') {
-      (*inst)++;
-      return 0;
-   }
-
-   return 0;
-}
-
-/**
- * parses and returns signed integer
- */
-static GLint
-parse_integer (GLubyte ** inst, struct arb_program *Program)
-{
-   GLint sign;
-   GLint value;
-
-   /* check if *inst points to '+' or '-'
-    * if yes, grab the sign and increment *inst
-    */
-   sign = parse_sign (inst);
-
-   /* now check if *inst points to 0
-    * if yes, increment the *inst and return the default value
-    */
-   if (**inst == 0) {
-      (*inst)++;
-      return 0;
-   }
-
-   /* parse the integer as you normally would do it */
-   value = _mesa_atoi (parse_string_without_adding (inst, Program));
-
-   /* now, after terminating 0 there is a position
-    * to parse it - parse_position()
-    */
-   Program->Position = parse_position (inst);
-
-   if (sign)
-      value *= -1;
-
-   return value;
-}
-
-/**
- */
-static GLfloat
-parse_float (GLubyte ** inst, struct arb_program *Program)
-{
-   GLint tmp[5], denom;
-   GLuint leading_zeros =0;
-   GLfloat value = 0;
-
-#if 0
-   tmp[0] = parse_sign (inst);  /* This is the sign of the number + - >0, - -> 1 */
-#endif
-   tmp[1] = parse_integer (inst, Program);   /* This is the integer portion of the number */
-
-   /* Now we grab the fractional portion of the number (the digits after
-       * the .). We can have leading 0's here, which parse_integer will ignore,
-       * so we'll check for those first
-       */
-   while ((**inst == '0') && ( *(*inst+1) != 0))
-   {
-         leading_zeros++;
-         (*inst)++;
-   }
-   tmp[2] = parse_integer (inst, Program);   /* This is the fractional portion of the number */
-   tmp[3] = parse_sign (inst);               /* This is the sign of the exponent */
-   tmp[4] = parse_integer (inst, Program);   /* This is the exponent */
-
-   value = (GLfloat) tmp[1];
-   denom = 1;
-   while (denom < tmp[2])
-      denom *= 10;
-   denom *= (GLint) _mesa_pow( 10, leading_zeros );
-   value += (GLfloat) tmp[2] / (GLfloat) denom;
-#if 0
-   if (tmp[0])
-      value *= -1;
-#endif
-   value *= (GLfloat) _mesa_pow (10, (GLfloat) tmp[3] * (GLfloat) tmp[4]);
-
-   return value;
-}
-
-
-/**
- */
-static GLfloat
-parse_signed_float (GLubyte ** inst, struct arb_program *Program)
-{
-   GLint negate;
-   GLfloat value;
-
-   negate = parse_sign (inst);
-
-   value = parse_float (inst, Program);
-
-   if (negate)
-      value *= -1;
-
-   return value;
-}
-
-/**
- * This picks out a constant value from the parsed array. The constant vector is r
- * returned in the *values array, which should be of length 4.
- *
- * \param values - The 4 component vector with the constant value in it
- */
-static GLvoid
-parse_constant (GLubyte ** inst, GLfloat *values, struct arb_program *Program,
-                GLboolean use)
-{
-   GLuint components, i;
-
-
-   switch (*(*inst)++) {
-      case CONSTANT_SCALAR:
-         if (use == GL_TRUE) {
-            values[0] =
-               values[1] =
-               values[2] = values[3] = parse_float (inst, Program);
-         }
-         else {
-            values[0] =
-               values[1] =
-               values[2] = values[3] = parse_signed_float (inst, Program);
-         }
-
-         break;
-      case CONSTANT_VECTOR:
-         values[0] = values[1] = values[2] = 0;
-         values[3] = 1;
-         components = *(*inst)++;
-         for (i = 0; i < components; i++) {
-            values[i] = parse_signed_float (inst, Program);
-         }
-         break;
-   }
-}
-
-/**
- * \param offset The offset from the address register that we should
- *                address
- *
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_relative_offset (GLcontext *ctx, GLubyte **inst, struct arb_program *Program,
-                        GLint *offset)
-{
-   *offset = parse_integer(inst, Program);
-   if ((*offset > 63) || (*offset < -64)) {
-      _mesa_set_program_error (ctx, Program->Position,
-                               "Relative offset out of range");
-      _mesa_error (ctx, GL_INVALID_OPERATION, "Relative offset %d out of range",
-                                                *offset);
-      return 1;
-   }
-
-   return 0;
-}
-
-/**
- * \param  color 0 if color type is primary, 1 if color type is secondary
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_color_type (GLcontext * ctx, GLubyte ** inst, struct arb_program *Program,
-                  GLint * color)
-{
-   *color = *(*inst)++ != COLOR_PRIMARY;
-   return 0;
-}
-
-/**
- * Get an integer corresponding to a generic vertex attribute.
- *
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_generic_attrib_num(GLcontext *ctx, GLubyte ** inst,
-                       struct arb_program *Program, GLuint *attrib)
-{
-   *attrib = parse_integer(inst, Program);
-
-   if ((*attrib < 0) || (*attrib > MAX_VERTEX_PROGRAM_ATTRIBS))
-   {
-      _mesa_set_program_error (ctx, Program->Position,
-                               "Invalid generic vertex attribute index");
-      _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid generic vertex attribute index");
-
-      return 1;
-   }
-
-   return 0;
-}
-
-
-/**
- * \param coord The texture unit index
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_texcoord_num (GLcontext * ctx, GLubyte ** inst,
-                    struct arb_program *Program, GLuint * coord)
-{
-   *coord = parse_integer (inst, Program);
-
-   if ((*coord < 0) || (*coord >= ctx->Const.MaxTextureUnits)) {
-      _mesa_set_program_error (ctx, Program->Position,
-                               "Invalid texture unit index");
-      _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid texture unit index");
-      return 1;
-   }
-
-   return 0;
-}
-
-/**
- * \param coord The weight index
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_weight_num (GLcontext * ctx, GLubyte ** inst, struct arb_program *Program,
-                  GLint * coord)
-{
-   *coord = parse_integer (inst, Program);
-
-   if ((*coord < 0) || (*coord >= 1)) {
-      _mesa_set_program_error (ctx, Program->Position,
-                               "Invalid weight index");
-      _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid weight index");
-      return 1;
-   }
-
-   return 0;
-}
-
-/**
- * \param coord The clip plane index
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_clipplane_num (GLcontext * ctx, GLubyte ** inst,
-                     struct arb_program *Program, GLint * coord)
-{
-   *coord = parse_integer (inst, Program);
-
-   if ((*coord < 0) || (*coord >= (GLint) ctx->Const.MaxClipPlanes)) {
-      _mesa_set_program_error (ctx, Program->Position,
-                               "Invalid clip plane index");
-      _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid clip plane index");
-      return 1;
-   }
-
-   return 0;
-}
-
-
-/**
- * \return 0 on front face, 1 on back face
- */
-static GLuint
-parse_face_type (GLubyte ** inst)
-{
-   switch (*(*inst)++) {
-      case FACE_FRONT:
-         return 0;
-
-      case FACE_BACK:
-         return 1;
-   }
-   return 0;
-}
-
-
-/**
- * Given a matrix and a modifier token on the binary array, return tokens
- * that _mesa_fetch_state() [program.c] can understand.
- *
- * \param matrix - the matrix we are talking about
- * \param matrix_idx - the index of the matrix we have (for texture & program matricies)
- * \param matrix_modifier - the matrix modifier (trans, inv, etc)
- * \return 0 on sucess, 1 on failure
- */
-static GLuint
-parse_matrix (GLcontext * ctx, GLubyte ** inst, struct arb_program *Program,
-              GLint * matrix, GLint * matrix_idx, GLint * matrix_modifier)
-{
-   GLubyte mat = *(*inst)++;
-
-   *matrix_idx = 0;
-
-   switch (mat) {
-      case MATRIX_MODELVIEW:
-         *matrix = STATE_MODELVIEW;
-         *matrix_idx = parse_integer (inst, Program);
-         if (*matrix_idx > 0) {
-            _mesa_set_program_error (ctx, Program->Position,
-               "ARB_vertex_blend not supported\n");
-            _mesa_error (ctx, GL_INVALID_OPERATION,
-               "ARB_vertex_blend not supported\n");
-            return 1;
-         }
-         break;
-
-      case MATRIX_PROJECTION:
-         *matrix = STATE_PROJECTION;
-         break;
-
-      case MATRIX_MVP:
-         *matrix = STATE_MVP;
-         break;
-
-      case MATRIX_TEXTURE:
-         *matrix = STATE_TEXTURE;
-         *matrix_idx = parse_integer (inst, Program);
-         if (*matrix_idx >= (GLint) ctx->Const.MaxTextureUnits) {
-            _mesa_set_program_error (ctx, Program->Position,
-                                     "Invalid Texture Unit");
-            _mesa_error (ctx, GL_INVALID_OPERATION,
-                         "Invalid Texture Unit: %d", *matrix_idx);
-            return 1;
-         }
-         break;
-
-         /* This is not currently supported (ARB_matrix_palette) */
-      case MATRIX_PALETTE:
-         *matrix_idx = parse_integer (inst, Program);
-         _mesa_set_program_error (ctx, Program->Position,
-              "ARB_matrix_palette not supported\n");
-         _mesa_error (ctx, GL_INVALID_OPERATION,
-              "ARB_matrix_palette not supported\n");
-         return 1;
-         break;
-
-      case MATRIX_PROGRAM:
-         *matrix = STATE_PROGRAM;
-         *matrix_idx = parse_integer (inst, Program);
-         if (*matrix_idx >= (GLint) ctx->Const.MaxProgramMatrices) {
-            _mesa_set_program_error (ctx, Program->Position,
-                                     "Invalid Program Matrix");
-            _mesa_error (ctx, GL_INVALID_OPERATION,
-                         "Invalid Program Matrix: %d", *matrix_idx);
-            return 1;
-         }
-         break;
-   }
-
-   switch (*(*inst)++) {
-      case MATRIX_MODIFIER_IDENTITY:
-         *matrix_modifier = 0;
-         break;
-      case MATRIX_MODIFIER_INVERSE:
-         *matrix_modifier = STATE_MATRIX_INVERSE;
-         break;
-      case MATRIX_MODIFIER_TRANSPOSE:
-         *matrix_modifier = STATE_MATRIX_TRANSPOSE;
-         break;
-      case MATRIX_MODIFIER_INVTRANS:
-         *matrix_modifier = STATE_MATRIX_INVTRANS;
-         break;
-   }
-
-   return 0;
-}
-
-
-/**
- * This parses a state string (rather, the binary version of it) into
- * a 6-token sequence as described in _mesa_fetch_state() [program.c]
- *
- * \param inst         - the start in the binary arry to start working from
- * \param state_tokens - the storage for the 6-token state description
- * \return             - 0 on sucess, 1 on error
- */
-static GLuint
-parse_state_single_item (GLcontext * ctx, GLubyte ** inst,
-                         struct arb_program *Program, GLint * state_tokens)
-{
-   switch (*(*inst)++) {
-      case STATE_MATERIAL_PARSER:
-         state_tokens[0] = STATE_MATERIAL;
-         state_tokens[1] = parse_face_type (inst);
-         switch (*(*inst)++) {
-            case MATERIAL_AMBIENT:
-               state_tokens[2] = STATE_AMBIENT;
-               break;
-            case MATERIAL_DIFFUSE:
-               state_tokens[2] = STATE_DIFFUSE;
-               break;
-            case MATERIAL_SPECULAR:
-               state_tokens[2] = STATE_SPECULAR;
-               break;
-            case MATERIAL_EMISSION:
-               state_tokens[2] = STATE_EMISSION;
-              break;
-            case MATERIAL_SHININESS:
-               state_tokens[2] = STATE_SHININESS;
-               break;
-         }
-         break;
-
-      case STATE_LIGHT_PARSER:
-         state_tokens[0] = STATE_LIGHT;
-         state_tokens[1] = parse_integer (inst, Program);
-
-         /* Check the value of state_tokens[1] against the # of lights */
-         if (state_tokens[1] >= (GLint) ctx->Const.MaxLights) {
-            _mesa_set_program_error (ctx, Program->Position,
-                                     "Invalid Light Number");
-            _mesa_error (ctx, GL_INVALID_OPERATION,
-                         "Invalid Light Number: %d", state_tokens[1]);
-            return 1;
-         }
-
-         switch (*(*inst)++) {
-            case LIGHT_AMBIENT:
-               state_tokens[2] = STATE_AMBIENT;
-               break;
-            case LIGHT_DIFFUSE:
-               state_tokens[2] = STATE_DIFFUSE;
-               break;
-            case LIGHT_SPECULAR:
-               state_tokens[2] = STATE_SPECULAR;
-               break;
-            case LIGHT_POSITION:
-               state_tokens[2] = STATE_POSITION;
-               break;
-            case LIGHT_ATTENUATION:
-               state_tokens[2] = STATE_ATTENUATION;
-               break;
-            case LIGHT_HALF:
-               state_tokens[2] = STATE_HALF;
-               break;
-            case LIGHT_SPOT_DIRECTION:
-               state_tokens[2] = STATE_SPOT_DIRECTION;
-               break;
-         }
-         break;
-
-      case STATE_LIGHT_MODEL:
-         switch (*(*inst)++) {
-            case LIGHT_MODEL_AMBIENT:
-               state_tokens[0] = STATE_LIGHTMODEL_AMBIENT;
-               break;
-            case LIGHT_MODEL_SCENECOLOR:
-               state_tokens[0] = STATE_LIGHTMODEL_SCENECOLOR;
-               state_tokens[1] = parse_face_type (inst);
-               break;
-         }
-         break;
-
-      case STATE_LIGHT_PROD:
-         state_tokens[0] = STATE_LIGHTPROD;
-         state_tokens[1] = parse_integer (inst, Program);
-
-         /* Check the value of state_tokens[1] against the # of lights */
-         if (state_tokens[1] >= (GLint) ctx->Const.MaxLights) {
-            _mesa_set_program_error (ctx, Program->Position,
-                                     "Invalid Light Number");
-            _mesa_error (ctx, GL_INVALID_OPERATION,
-                         "Invalid Light Number: %d", state_tokens[1]);
-            return 1;
-         }
-
-         state_tokens[2] = parse_face_type (inst);
-         switch (*(*inst)++) {
-            case LIGHT_PROD_AMBIENT:
-               state_tokens[3] = STATE_AMBIENT;
-               break;
-            case LIGHT_PROD_DIFFUSE:
-               state_tokens[3] = STATE_DIFFUSE;
-               break;
-            case LIGHT_PROD_SPECULAR:
-               state_tokens[3] = STATE_SPECULAR;
-               break;
-         }
-         break;
-
-
-      case STATE_FOG:
-         switch (*(*inst)++) {
-            case FOG_COLOR:
-               state_tokens[0] = STATE_FOG_COLOR;
-               break;
-            case FOG_PARAMS:
-               state_tokens[0] = STATE_FOG_PARAMS;
-               break;
-         }
-         break;
-
-      case STATE_TEX_ENV:
-         state_tokens[1] = parse_integer (inst, Program);
-         switch (*(*inst)++) {
-            case TEX_ENV_COLOR:
-               state_tokens[0] = STATE_TEXENV_COLOR;
-               break;
-         }
-         break;
-
-      case STATE_TEX_GEN:
-         {
-            GLuint type, coord;
-
-            state_tokens[0] = STATE_TEXGEN;
-            /*state_tokens[1] = parse_integer (inst, Program);*/    /* Texture Unit */
-
-            if (parse_texcoord_num (ctx, inst, Program, &coord))
-               return 1;
-           state_tokens[1] = coord;
-
-            /* EYE or OBJECT */
-            type = *(*inst++);
-
-            /* 0 - s, 1 - t, 2 - r, 3 - q */
-            coord = *(*inst++);
-
-            if (type == TEX_GEN_EYE) {
-               switch (coord) {
-                  case COMPONENT_X:
-                     state_tokens[2] = STATE_TEXGEN_EYE_S;
-                     break;
-                  case COMPONENT_Y:
-                     state_tokens[2] = STATE_TEXGEN_EYE_T;
-                     break;
-                  case COMPONENT_Z:
-                     state_tokens[2] = STATE_TEXGEN_EYE_R;
-                     break;
-                  case COMPONENT_W:
-                     state_tokens[2] = STATE_TEXGEN_EYE_Q;
-                     break;
-               }
-            }
-            else {
-               switch (coord) {
-                  case COMPONENT_X:
-                     state_tokens[2] = STATE_TEXGEN_OBJECT_S;
-                     break;
-                  case COMPONENT_Y:
-                     state_tokens[2] = STATE_TEXGEN_OBJECT_T;
-                     break;
-                  case COMPONENT_Z:
-                     state_tokens[2] = STATE_TEXGEN_OBJECT_R;
-                     break;
-                  case COMPONENT_W:
-                     state_tokens[2] = STATE_TEXGEN_OBJECT_Q;
-                     break;
-               }
-            }
-         }
-         break;
-
-      case STATE_DEPTH:
-         switch (*(*inst)++) {
-            case DEPTH_RANGE:
-               state_tokens[0] = STATE_DEPTH_RANGE;
-               break;
-         }
-         break;
-
-      case STATE_CLIP_PLANE:
-         state_tokens[0] = STATE_CLIPPLANE;
-         state_tokens[1] = parse_integer (inst, Program);
-         if (parse_clipplane_num (ctx, inst, Program, &state_tokens[1]))
-            return 1;
-         break;
-
-      case STATE_POINT:
-         switch (*(*inst++)) {
-            case POINT_SIZE:
-               state_tokens[0] = STATE_POINT_SIZE;
-               break;
-
-            case POINT_ATTENUATION:
-               state_tokens[0] = STATE_POINT_ATTENUATION;
-               break;
-         }
-         break;
-
-         /* XXX: I think this is the correct format for a matrix row */
-      case STATE_MATRIX_ROWS:
-         state_tokens[0] = STATE_MATRIX;
-         if (parse_matrix
-             (ctx, inst, Program, &state_tokens[1], &state_tokens[2],
-              &state_tokens[5]))
-            return 1;
-
-         state_tokens[3] = parse_integer (inst, Program);       /* The first row to grab */
-
-         if ((**inst) != 0) {                                   /* Either the last row, 0 */
-            state_tokens[4] = parse_integer (inst, Program);
-            if (state_tokens[4] < state_tokens[3]) {
-               _mesa_set_program_error (ctx, Program->Position,
-                     "Second matrix index less than the first");
-               _mesa_error (ctx, GL_INVALID_OPERATION,
-                     "Second matrix index (%d) less than the first (%d)",
-                     state_tokens[4], state_tokens[3]);
-               return 1;
-            }
-         }
-         else {
-            state_tokens[4] = state_tokens[3];
-            (*inst)++;
-         }
-         break;
-   }
-
-   return 0;
-}
-
-/**
- * This parses a state string (rather, the binary version of it) into
- * a 6-token similar for the state fetching code in program.c
- *
- * One might ask, why fetch these parameters into just like  you fetch
- * state when they are already stored in other places?
- *
- * Because of array offsets -> We can stick env/local parameters in the
- * middle of a parameter array and then index someplace into the array
- * when we execute.
- *
- * One optimization might be to only do this for the cases where the
- * env/local parameters end up inside of an array, and leave the
- * single parameters (or arrays of pure env/local pareameters) in their
- * respective register files.
- *
- * For ENV parameters, the format is:
- *    state_tokens[0] = STATE_FRAGMENT_PROGRAM / STATE_VERTEX_PROGRAM
- *    state_tokens[1] = STATE_ENV
- *    state_tokens[2] = the parameter index
- *
- * for LOCAL parameters, the format is:
- *    state_tokens[0] = STATE_FRAGMENT_PROGRAM / STATE_VERTEX_PROGRAM
- *    state_tokens[1] = STATE_LOCAL
- *    state_tokens[2] = the parameter index
- *
- * \param inst         - the start in the binary arry to start working from
- * \param state_tokens - the storage for the 6-token state description
- * \return             - 0 on sucess, 1 on failure
- */
-static GLuint
-parse_program_single_item (GLcontext * ctx, GLubyte ** inst,
-                           struct arb_program *Program, GLint * state_tokens)
-{
-   if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB)
-      state_tokens[0] = STATE_FRAGMENT_PROGRAM;
-   else
-      state_tokens[0] = STATE_VERTEX_PROGRAM;
-
-
-   switch (*(*inst)++) {
-      case PROGRAM_PARAM_ENV:
-         state_tokens[1] = STATE_ENV;
-         state_tokens[2] = parse_integer (inst, Program);
-
-         /* Check state_tokens[2] against the number of ENV parameters available */
-         if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) &&
-              (state_tokens[2] >= (GLint) ctx->Const.MaxFragmentProgramEnvParams))
-             ||
-             ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) &&
-              (state_tokens[2] >= (GLint) ctx->Const.MaxVertexProgramEnvParams))) {
-            _mesa_set_program_error (ctx, Program->Position,
-                                     "Invalid Program Env Parameter");
-            _mesa_error (ctx, GL_INVALID_OPERATION,
-                         "Invalid Program Env Parameter: %d",
-                         state_tokens[2]);
-            return 1;
-         }
-
-         break;
-
-      case PROGRAM_PARAM_LOCAL:
-         state_tokens[1] = STATE_LOCAL;
-         state_tokens[2] = parse_integer (inst, Program);
-
-         /* Check state_tokens[2] against the number of LOCAL parameters available */
-         if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) &&
-              (state_tokens[2] >= (GLint) ctx->Const.MaxFragmentProgramLocalParams))
-             ||
-             ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) &&
-              (state_tokens[2] >= (GLint) ctx->Const.MaxVertexProgramLocalParams))) {
-            _mesa_set_program_error (ctx, Program->Position,
-                                     "Invalid Program Local Parameter");
-            _mesa_error (ctx, GL_INVALID_OPERATION,
-                         "Invalid Program Local Parameter: %d",
-                         state_tokens[2]);
-            return 1;
-         }
-         break;
-   }
-
-   return 0;
-}
-
-/**
- * For ARB_vertex_program, programs are not allowed to use both an explicit
- * vertex attribute and a generic vertex attribute corresponding to the same
- * state. See section 2.14.3.1 of the GL_ARB_vertex_program spec.
- *
- * This will walk our var_cache and make sure that nobody does anything fishy.
- *
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-generic_attrib_check(struct var_cache *vc_head)
-{
-   int a;
-   struct var_cache *curr;
-   GLboolean explicitAttrib[MAX_VERTEX_PROGRAM_ATTRIBS],
-      genericAttrib[MAX_VERTEX_PROGRAM_ATTRIBS];
-
-   for (a=0; a<MAX_VERTEX_PROGRAM_ATTRIBS; a++) {
-      explicitAttrib[a] = GL_FALSE;
-      genericAttrib[a] = GL_FALSE;
-   }
-
-   curr = vc_head;
-   while (curr) {
-      if (curr->type == vt_attrib) {
-         if (curr->attrib_is_generic)
-            genericAttrib[ curr->attrib_binding_idx ] = GL_TRUE;
-         else
-            explicitAttrib[ curr->attrib_binding_idx ] = GL_TRUE;
-      }
-
-      curr = curr->next;
-   }
-
-   for (a=0; a<MAX_VERTEX_PROGRAM_ATTRIBS; a++) {
-      if ((explicitAttrib[a]) && (genericAttrib[a]))
-         return 1;
-   }
-
-   return 0;
-}
-
-/**
- * This will handle the binding side of an ATTRIB var declaration
- *
- * \param binding     - the fragment input register state, defined in nvfragprog.h
- * \param binding_idx - the index in the attrib register file that binding is associated with
- * \return returns 0 on sucess, 1 on error
- *
- * See nvfragparse.c for attrib register file layout
- */
-static GLuint
-parse_attrib_binding (GLcontext * ctx, GLubyte ** inst,
-                      struct arb_program *Program, GLuint * binding,
-                      GLuint * binding_idx, GLuint *is_generic)
-{
-   GLuint texcoord;
-   GLint coord;
-   GLint err = 0;
-
-   *is_generic = 0;
-   if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
-      switch (*(*inst)++) {
-         case FRAGMENT_ATTRIB_COLOR:
-            err = parse_color_type (ctx, inst, Program, &coord);
-            *binding = FRAG_ATTRIB_COL0 + coord;
-            *binding_idx = 1 + coord;
-            break;
-
-         case FRAGMENT_ATTRIB_TEXCOORD:
-            err = parse_texcoord_num (ctx, inst, Program, &texcoord);
-            *binding = FRAG_ATTRIB_TEX0 + texcoord;
-            *binding_idx = 4 + texcoord;
-            break;
-
-         case FRAGMENT_ATTRIB_FOGCOORD:
-            *binding = FRAG_ATTRIB_FOGC;
-            *binding_idx = 3;
-            break;
-
-         case FRAGMENT_ATTRIB_POSITION:
-            *binding = FRAG_ATTRIB_WPOS;
-            *binding_idx = 0;
-            break;
-
-         default:
-            err = 1;
-            break;
-      }
-   }
-   else {
-      switch (*(*inst)++) {
-         case VERTEX_ATTRIB_POSITION:
-            *binding = VERT_ATTRIB_POS;
-            *binding_idx = 0;
-            break;
-
-         case VERTEX_ATTRIB_WEIGHT:
-            {
-               GLint weight;
-
-               err = parse_weight_num (ctx, inst, Program, &weight);
-               *binding = VERT_ATTRIB_WEIGHT;
-               *binding_idx = 1;
-            }
-            _mesa_set_program_error (ctx, Program->Position,
-                 "ARB_vertex_blend not supported\n");
-            _mesa_error (ctx, GL_INVALID_OPERATION,
-                 "ARB_vertex_blend not supported\n");
-            return 1;
-            break;
-
-         case VERTEX_ATTRIB_NORMAL:
-            *binding = VERT_ATTRIB_NORMAL;
-            *binding_idx = 2;
-            break;
-
-         case VERTEX_ATTRIB_COLOR:
-            {
-               GLint color;
-
-               err = parse_color_type (ctx, inst, Program, &color);
-               if (color) {
-                  *binding = VERT_ATTRIB_COLOR1;
-                  *binding_idx = 4;
-               }
-               else {
-                  *binding = VERT_ATTRIB_COLOR0;
-                  *binding_idx = 3;
-               }
-            }
-            break;
-
-         case VERTEX_ATTRIB_FOGCOORD:
-            *binding = VERT_ATTRIB_FOG;
-            *binding_idx = 5;
-            break;
-
-         case VERTEX_ATTRIB_TEXCOORD:
-            {
-               GLuint unit;
-
-               err = parse_texcoord_num (ctx, inst, Program, &unit);
-               *binding = VERT_ATTRIB_TEX0 + unit;
-               *binding_idx = 8 + unit;
-            }
-            break;
-
-            /* It looks like we don't support this at all, atm */
-         case VERTEX_ATTRIB_MATRIXINDEX:
-            parse_integer (inst, Program);
-            _mesa_set_program_error (ctx, Program->Position,
-                  "ARB_palette_matrix not supported");
-            _mesa_error (ctx, GL_INVALID_OPERATION,
-                  "ARB_palette_matrix not supported");
-            return 1;
-            break;
-
-         case VERTEX_ATTRIB_GENERIC:
-            {
-               GLuint attrib;
-
-               if (!parse_generic_attrib_num(ctx, inst, Program, &attrib)) {
-                  *is_generic = 1;
-                  switch (attrib) {
-                     case 0:
-                        *binding = VERT_ATTRIB_POS;
-                        break;
-                     case 1:
-                        *binding = VERT_ATTRIB_WEIGHT;
-                        break;
-                     case 2:
-                        *binding = VERT_ATTRIB_NORMAL;
-                        break;
-                     case 3:
-                        *binding = VERT_ATTRIB_COLOR0;
-                        break;
-                     case 4:
-                        *binding = VERT_ATTRIB_COLOR1;
-                        break;
-                     case 5:
-                        *binding = VERT_ATTRIB_FOG;
-                        break;
-                     case 6:
-                        break;
-                     case 7:
-                        break;
-                     default:
-                        *binding = VERT_ATTRIB_TEX0 + (attrib-8);
-                        break;
-                  }
-                  *binding_idx = attrib;
-               }
-            }
-            break;
-
-         default:
-            err = 1;
-            break;
-      }
-   }
-
-   /* Can this even happen? */
-   if (err) {
-      _mesa_set_program_error (ctx, Program->Position,
-                               "Bad attribute binding");
-      _mesa_error (ctx, GL_INVALID_OPERATION, "Bad attribute binding");
-   }
-
-   Program->InputsRead |= (1 << *binding_idx);
-
-   return err;
-}
-
-/**
- * This translates between a binary token for an output variable type
- * and the mesa token for the same thing.
- *
- *
- * XXX: What is the 'name' for vertex program state? -> do we need it?
- *         I don't think we do;
- *
- * See nvfragprog.h for definitions
- *
- * \param inst        - The parsed tokens
- * \param binding     - The name of the state we are binding too
- * \param binding_idx - The index into the result register file that this is bound too
- *
- * See nvfragparse.c for the register file layout for fragment programs
- * See nvvertparse.c for the register file layout for vertex programs
- */
-static GLuint
-parse_result_binding (GLcontext * ctx, GLubyte ** inst, GLuint * binding,
-                      GLuint * binding_idx, struct arb_program *Program)
-{
-   GLuint b;
-
-   switch (*(*inst)++) {
-      case FRAGMENT_RESULT_COLOR:
-         /* for frag programs, this is FRAGMENT_RESULT_COLOR */
-         if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
-            *binding = FRAG_OUTPUT_COLR;
-            *binding_idx = 0;
-         }
-         /* for vtx programs, this is VERTEX_RESULT_POSITION */
-         else {
-            *binding_idx = 0;
-         }
-         break;
-
-      case FRAGMENT_RESULT_DEPTH:
-         /* for frag programs, this is FRAGMENT_RESULT_DEPTH */
-         if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
-            *binding = FRAG_OUTPUT_DEPR;
-            *binding_idx = 2;
-         }
-         /* for vtx programs, this is VERTEX_RESULT_COLOR */
-         else {
-            GLint color_type;
-            GLuint face_type = parse_face_type(inst);
-           GLint color_type_ret = parse_color_type(ctx, inst, Program, &color_type);
-
-            /* back face */
-            if (face_type) {
-               if (color_type_ret) return 1;
-
-               /* secondary color */
-               if (color_type) {
-                  *binding_idx = 4;
-               }
-               /*  primary color */
-               else {
-                  *binding_idx = 3;
-               }
-            }
-            /* front face */
-            else {
-               /* secondary color */
-               if (color_type) {
-                  *binding_idx = 2;
-               }
-               /* primary color */
-               else {
-                  *binding_idx = 1;
-               }
-            }
-         }
-         break;
-
-      case VERTEX_RESULT_FOGCOORD:
-         *binding_idx = 5;
-         break;
-
-      case VERTEX_RESULT_POINTSIZE:
-         *binding_idx = 6;
-         break;
-
-      case VERTEX_RESULT_TEXCOORD:
-         if (parse_texcoord_num (ctx, inst, Program, &b))
-            return 1;
-         *binding_idx = 7 + b;
-         break;
-   }
-
-   Program->OutputsWritten |= (1 << *binding_idx);
-
-   return 0;
-}
-
-/**
- * This handles the declaration of ATTRIB variables
- *
- * XXX: Still needs
- *      parse_vert_attrib_binding(), or something like that
- *
- * \return 0 on sucess, 1 on error
- */
-static GLint
-parse_attrib (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
-              struct arb_program *Program)
-{
-   GLuint found;
-   char *error_msg;
-   struct var_cache *attrib_var;
-
-   attrib_var = parse_string (inst, vc_head, Program, &found);
-   Program->Position = parse_position (inst);
-   if (found) {
-      error_msg = (char *)
-         _mesa_malloc (_mesa_strlen ((char *) attrib_var->name) + 40);
-      _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
-                     attrib_var->name);
-
-      _mesa_set_program_error (ctx, Program->Position, error_msg);
-      _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
-
-      _mesa_free (error_msg);
-      return 1;
-   }
-
-   attrib_var->type = vt_attrib;
-
-   /* I think this is ok now - karl */
-   /* XXX: */
-   /*if (Program->type == GL_FRAGMENT_PROGRAM_ARB) */
-   {
-      if (parse_attrib_binding
-          (ctx, inst, Program, &attrib_var->attrib_binding,
-           &attrib_var->attrib_binding_idx, &attrib_var->attrib_is_generic))
-         return 1;
-      if (generic_attrib_check(*vc_head)) {
-         _mesa_set_program_error (ctx, Program->Position,
-   "Cannot use both a generic vertex attribute and a specific attribute of the same type");
-         _mesa_error (ctx, GL_INVALID_OPERATION,
-   "Cannot use both a generic vertex attribute and a specific attribute of the same type");
-         return 1;
-      }
-
-   }
-
-   Program->Base.NumAttributes++;
-   return 0;
-}
-
-/**
- * \param use -- TRUE if we're called when declaring implicit parameters,
- *               FALSE if we're declaraing variables. This has to do with
- *               if we get a signed or unsigned float for scalar constants
- */
-static GLuint
-parse_param_elements (GLcontext * ctx, GLubyte ** inst,
-                      struct var_cache *param_var,
-                      struct arb_program *Program, GLboolean use)
-{
-   GLint idx;
-   GLuint err;
-   GLint state_tokens[6];
-   GLfloat const_values[4];
-
-   err = 0;
-
-   switch (*(*inst)++) {
-      case PARAM_STATE_ELEMENT:
-
-         if (parse_state_single_item (ctx, inst, Program, state_tokens))
-            return 1;
-
-         /* If we adding STATE_MATRIX that has multiple rows, we need to
-          * unroll it and call _mesa_add_state_reference() for each row
-          */
-         if ((state_tokens[0] == STATE_MATRIX)
-             && (state_tokens[3] != state_tokens[4])) {
-            GLint row;
-            GLint first_row = state_tokens[3];
-            GLint last_row = state_tokens[4];
-
-            for (row = first_row; row <= last_row; row++) {
-               state_tokens[3] = state_tokens[4] = row;
-
-               idx =
-                  _mesa_add_state_reference (Program->Parameters,
-                                             state_tokens);
-               if (param_var->param_binding_begin == ~0U)
-                  param_var->param_binding_begin = idx;
-               param_var->param_binding_length++;
-               Program->Base.NumParameters++;
-            }
-         }
-         else {
-            idx =
-               _mesa_add_state_reference (Program->Parameters, state_tokens);
-            if (param_var->param_binding_begin == ~0U)
-               param_var->param_binding_begin = idx;
-            param_var->param_binding_length++;
-            Program->Base.NumParameters++;
-         }
-         break;
-
-      case PARAM_PROGRAM_ELEMENT:
-
-         if (parse_program_single_item (ctx, inst, Program, state_tokens))
-            return 1;
-         idx = _mesa_add_state_reference (Program->Parameters, state_tokens);
-         if (param_var->param_binding_begin == ~0U)
-            param_var->param_binding_begin = idx;
-         param_var->param_binding_length++;
-         Program->Base.NumParameters++;
-
-         /* Check if there is more: 0 -> we're done, else its an integer */
-         if (**inst) {
-            GLuint out_of_range, new_idx;
-            GLuint start_idx = state_tokens[2] + 1;
-            GLuint end_idx = parse_integer (inst, Program);
-
-            out_of_range = 0;
-            if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
-               if (((state_tokens[1] == STATE_ENV)
-                    && (end_idx >= ctx->Const.MaxFragmentProgramEnvParams))
-                   || ((state_tokens[1] == STATE_LOCAL)
-                       && (end_idx >=
-                           ctx->Const.MaxFragmentProgramLocalParams)))
-                  out_of_range = 1;
-            }
-            else {
-               if (((state_tokens[1] == STATE_ENV)
-                    && (end_idx >= ctx->Const.MaxVertexProgramEnvParams))
-                   || ((state_tokens[1] == STATE_LOCAL)
-                       && (end_idx >=
-                           ctx->Const.MaxVertexProgramLocalParams)))
-                  out_of_range = 1;
-            }
-            if (out_of_range) {
-               _mesa_set_program_error (ctx, Program->Position,
-                                        "Invalid Program Parameter");
-               _mesa_error (ctx, GL_INVALID_OPERATION,
-                            "Invalid Program Parameter: %d", end_idx);
-               return 1;
-            }
-
-            for (new_idx = start_idx; new_idx <= end_idx; new_idx++) {
-               state_tokens[2] = new_idx;
-               idx =
-                  _mesa_add_state_reference (Program->Parameters,
-                                             state_tokens);
-               param_var->param_binding_length++;
-               Program->Base.NumParameters++;
-            }
-         }
-                       else
-                       {
-                               (*inst)++;
-                       }
-         break;
-
-      case PARAM_CONSTANT:
-         parse_constant (inst, const_values, Program, use);
-         idx =
-            _mesa_add_named_constant (Program->Parameters,
-                                      (char *) param_var->name, const_values);
-         if (param_var->param_binding_begin == ~0U)
-            param_var->param_binding_begin = idx;
-         param_var->param_binding_length++;
-         Program->Base.NumParameters++;
-         break;
-
-      default:
-         _mesa_set_program_error (ctx, Program->Position,
-                                  "Unexpected token in parse_param_elements()");
-         _mesa_error (ctx, GL_INVALID_OPERATION,
-                      "Unexpected token in parse_param_elements()");
-         return 1;
-   }
-
-   /* Make sure we haven't blown past our parameter limits */
-   if (((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) &&
-        (Program->Base.NumParameters >=
-         ctx->Const.MaxVertexProgramLocalParams))
-       || ((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB)
-           && (Program->Base.NumParameters >=
-               ctx->Const.MaxFragmentProgramLocalParams))) {
-      _mesa_set_program_error (ctx, Program->Position,
-                               "Too many parameter variables");
-      _mesa_error (ctx, GL_INVALID_OPERATION, "Too many parameter variables");
-      return 1;
-   }
-
-   return err;
-}
-
-/**
- * This picks out PARAM program parameter bindings.
- *
- * XXX: This needs to be stressed & tested
- *
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_param (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
-             struct arb_program *Program)
-{
-   GLuint found, specified_length, err;
-   char *error_msg;
-   struct var_cache *param_var;
-
-   err = 0;
-   param_var = parse_string (inst, vc_head, Program, &found);
-   Program->Position = parse_position (inst);
-
-   if (found) {
-      error_msg = (char *) _mesa_malloc (_mesa_strlen ((char *) param_var->name) + 40);
-      _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
-                     param_var->name);
-
-      _mesa_set_program_error (ctx, Program->Position, error_msg);
-      _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
-
-      _mesa_free (error_msg);
-      return 1;
-   }
-
-   specified_length = parse_integer (inst, Program);
-
-   if (specified_length < 0) {
-      _mesa_set_program_error (ctx, Program->Position,
-                               "Negative parameter array length");
-      _mesa_error (ctx, GL_INVALID_OPERATION,
-                   "Negative parameter array length: %d", specified_length);
-      return 1;
-   }
-
-   param_var->type = vt_param;
-   param_var->param_binding_length = 0;
-
-   /* Right now, everything is shoved into the main state register file.
-    *
-    * In the future, it would be nice to leave things ENV/LOCAL params
-    * in their respective register files, if possible
-    */
-   param_var->param_binding_type = PROGRAM_STATE_VAR;
-
-   /* Remember to:
-    * *   - add each guy to the parameter list
-    * *   - increment the param_var->param_binding_len
-    * *   - store the param_var->param_binding_begin for the first one
-    * *   - compare the actual len to the specified len at the end
-    */
-   while (**inst != PARAM_NULL) {
-      if (parse_param_elements (ctx, inst, param_var, Program, GL_FALSE))
-         return 1;
-   }
-
-   /* Test array length here! */
-   if (specified_length) {
-      if (specified_length != param_var->param_binding_length) {
-         _mesa_set_program_error (ctx, Program->Position,
-                                  "Declared parameter array lenght does not match parameter list");
-         _mesa_error (ctx, GL_INVALID_OPERATION,
-                      "Declared parameter array lenght does not match parameter list");
-      }
-   }
-
-   (*inst)++;
-
-   return 0;
-}
-
-/**
- *
- */
-static GLuint
-parse_param_use (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
-                 struct arb_program *Program, struct var_cache **new_var)
-{
-   struct var_cache *param_var;
-
-   /* First, insert a dummy entry into the var_cache */
-   var_cache_create (&param_var);
-   param_var->name = (GLubyte *) _mesa_strdup (" ");
-   param_var->type = vt_param;
-
-   param_var->param_binding_length = 0;
-   /* Don't fill in binding_begin; We use the default value of -1
-    * to tell if its already initialized, elsewhere.
-    *
-    * param_var->param_binding_begin  = 0;
-    */
-   param_var->param_binding_type = PROGRAM_STATE_VAR;
-
-   var_cache_append (vc_head, param_var);
-
-   /* Then fill it with juicy parameter goodness */
-   if (parse_param_elements (ctx, inst, param_var, Program, GL_TRUE))
-      return 1;
-
-   *new_var = param_var;
-
-   return 0;
-}
-
-
-/**
- * This handles the declaration of TEMP variables
- *
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_temp (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
-            struct arb_program *Program)
-{
-   GLuint found;
-   struct var_cache *temp_var;
-   char *error_msg;
-
-   while (**inst != 0) {
-      temp_var = parse_string (inst, vc_head, Program, &found);
-      Program->Position = parse_position (inst);
-      if (found) {
-         error_msg = (char *)
-            _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
-         _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
-                        temp_var->name);
-
-         _mesa_set_program_error (ctx, Program->Position, error_msg);
-         _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
-
-         _mesa_free (error_msg);
-         return 1;
-      }
-
-      temp_var->type = vt_temp;
-
-      if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) &&
-           (Program->Base.NumTemporaries >=
-            ctx->Const.MaxFragmentProgramTemps))
-          || ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB)
-              && (Program->Base.NumTemporaries >=
-                  ctx->Const.MaxVertexProgramTemps))) {
-         _mesa_set_program_error (ctx, Program->Position,
-                                  "Too many TEMP variables declared");
-         _mesa_error (ctx, GL_INVALID_OPERATION,
-                      "Too many TEMP variables declared");
-         return 1;
-      }
-
-      temp_var->temp_binding = Program->Base.NumTemporaries;
-      Program->Base.NumTemporaries++;
-   }
-   (*inst)++;
-
-   return 0;
-}
-
-/**
- * This handles variables of the OUTPUT variety
- *
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_output (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
-              struct arb_program *Program)
-{
-   GLuint found;
-   struct var_cache *output_var;
-
-   output_var = parse_string (inst, vc_head, Program, &found);
-   Program->Position = parse_position (inst);
-   if (found) {
-      char *error_msg;
-      error_msg = (char *)
-         _mesa_malloc (_mesa_strlen ((char *) output_var->name) + 40);
-      _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
-                     output_var->name);
-
-      _mesa_set_program_error (ctx, Program->Position, error_msg);
-      _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
-
-      _mesa_free (error_msg);
-      return 1;
-   }
-
-   output_var->type = vt_output;
-   return parse_result_binding (ctx, inst, &output_var->output_binding,
-                                &output_var->output_binding_idx, Program);
-}
-
-/**
- * This handles variables of the ALIAS kind
- *
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_alias (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
-             struct arb_program *Program)
-{
-   GLuint found;
-   struct var_cache *temp_var;
-   char *error_msg;
-
-
-   temp_var = parse_string (inst, vc_head, Program, &found);
-   Program->Position = parse_position (inst);
-
-   if (found) {
-      error_msg = (char *)
-         _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
-      _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
-                     temp_var->name);
-
-      _mesa_set_program_error (ctx, Program->Position, error_msg);
-      _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
-
-      _mesa_free (error_msg);
-      return 1;
-   }
-
-   temp_var->type = vt_alias;
-   temp_var->alias_binding =  parse_string (inst, vc_head, Program, &found);
-   Program->Position = parse_position (inst);
-
-   if (!found)
-   {
-      error_msg = (char *)
-         _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
-      _mesa_sprintf (error_msg, "Alias value %s is not defined",
-                     temp_var->alias_binding->name);
-
-      _mesa_set_program_error (ctx, Program->Position, error_msg);
-      _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
-
-      _mesa_free (error_msg);
-      return 1;
-   }
-
-   return 0;
-}
-
-/**
- * This handles variables of the ADDRESS kind
- *
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_address (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
-               struct arb_program *Program)
-{
-   GLuint found;
-   struct var_cache *temp_var;
-   char *error_msg;
-
-   while (**inst != 0) {
-      temp_var = parse_string (inst, vc_head, Program, &found);
-      Program->Position = parse_position (inst);
-      if (found) {
-         error_msg = (char *)
-            _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
-         _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
-                        temp_var->name);
-
-         _mesa_set_program_error (ctx, Program->Position, error_msg);
-         _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
-
-         _mesa_free (error_msg);
-         return 1;
-      }
-
-      temp_var->type = vt_address;
-
-      if (Program->Base.NumAddressRegs >=
-          ctx->Const.MaxVertexProgramAddressRegs) {
-         _mesa_set_program_error (ctx, Program->Position,
-                                  "Too many ADDRESS variables declared");
-         _mesa_error (ctx, GL_INVALID_OPERATION,
-                      "Too many ADDRESS variables declared");
-         return 1;
-      }
-
-      temp_var->address_binding = Program->Base.NumAddressRegs;
-      Program->Base.NumAddressRegs++;
-   }
-   (*inst)++;
-
-   return 0;
-}
-
-/**
- * Parse a program declaration
- *
- * \return 0 on sucess, 1 on error
- */
-static GLint
-parse_declaration (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
-                   struct arb_program *Program)
-{
-   GLint err = 0;
-
-   switch (*(*inst)++) {
-      case ADDRESS:
-         err = parse_address (ctx, inst, vc_head, Program);
-         break;
-
-      case ALIAS:
-         err = parse_alias (ctx, inst, vc_head, Program);
-         break;
-
-      case ATTRIB:
-         err = parse_attrib (ctx, inst, vc_head, Program);
-         break;
-
-      case OUTPUT:
-         err = parse_output (ctx, inst, vc_head, Program);
-         break;
-
-      case PARAM:
-         err = parse_param (ctx, inst, vc_head, Program);
-         break;
-
-      case TEMP:
-         err = parse_temp (ctx, inst, vc_head, Program);
-         break;
-   }
-
-   return err;
-}
-
-/**
- * Handle the parsing out of a masked destination register
- *
- * If we are a vertex program, make sure we don't write to
- * result.position of we have specified that the program is
- * position invariant
- *
- * \param File      - The register file we write to
- * \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_masked_dst_reg (GLcontext * ctx, GLubyte ** inst,
-                      struct var_cache **vc_head, struct arb_program *Program,
-                      GLint * File, GLint * Index, GLboolean * WriteMask)
-{
-   GLuint result;
-   GLubyte mask;
-   struct var_cache *dst;
-
-   /* We either have a result register specified, or a
-    * variable that may or may not be writable
-    */
-   switch (*(*inst)++) {
-      case REGISTER_RESULT:
-         if (parse_result_binding
-             (ctx, inst, &result, (GLuint *) Index, Program))
-            return 1;
-         *File = PROGRAM_OUTPUT;
-         break;
-
-      case REGISTER_ESTABLISHED_NAME:
-         dst = parse_string (inst, vc_head, Program, &result);
-         Program->Position = parse_position (inst);
-
-         /* If the name has never been added to our symbol table, we're hosed */
-         if (!result) {
-            _mesa_set_program_error (ctx, Program->Position,
-                                     "0: Undefined variable");
-            _mesa_error (ctx, GL_INVALID_OPERATION, "0: Undefined variable: %s",
-                         dst->name);
-            return 1;
-         }
-
-         switch (dst->type) {
-            case vt_output:
-               *File = PROGRAM_OUTPUT;
-               *Index = dst->output_binding_idx;
-               break;
-
-            case vt_temp:
-               *File = PROGRAM_TEMPORARY;
-               *Index = dst->temp_binding;
-               break;
-
-               /* If the var type is not vt_output or vt_temp, no go */
-            default:
-               _mesa_set_program_error (ctx, Program->Position,
-                                        "Destination register is read only");
-               _mesa_error (ctx, GL_INVALID_OPERATION,
-                            "Destination register is read only: %s",
-                            dst->name);
-               return 1;
-         }
-         break;
-
-      default:
-         _mesa_set_program_error (ctx, Program->Position,
-                                  "Unexpected opcode in parse_masked_dst_reg()");
-         _mesa_error (ctx, GL_INVALID_OPERATION,
-                      "Unexpected opcode in parse_masked_dst_reg()");
-         return 1;
-   }
-
-
-   /* Position invariance test */
-   /* This test is done now in syntax portion - when position invariance OPTION
-      is specified, "result.position" rule is disabled so there is no way
-      to write the position
-   */
-   /*if ((Program->HintPositionInvariant) && (*File == PROGRAM_OUTPUT) &&
-      (*Index == 0))   {
-      _mesa_set_program_error (ctx, Program->Position,
-                  "Vertex program specified position invariance and wrote vertex position");
-      _mesa_error (ctx, GL_INVALID_OPERATION,
-                  "Vertex program specified position invariance and wrote vertex position");
-   }*/
-
-   /* And then the mask.
-    *  w,a -> bit 0
-    *  z,b -> bit 1
-    *  y,g -> bit 2
-    *  x,r -> bit 3
-    */
-   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));
-
-   return 0;
-}
-
-
-/**
- * Handle the parsing of a address register
- *
- * \param Index     - The register index we write to
- *
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_address_reg (GLcontext * ctx, GLubyte ** inst,
-                          struct var_cache **vc_head,
-                          struct arb_program *Program, GLint * Index)
-{
-   struct var_cache *dst;
-   GLuint result;
-
-   dst = parse_string (inst, vc_head, Program, &result);
-   Program->Position = parse_position (inst);
-
-   /* If the name has never been added to our symbol table, we're hosed */
-   if (!result) {
-      _mesa_set_program_error (ctx, Program->Position, "Undefined variable");
-      _mesa_error (ctx, GL_INVALID_OPERATION, "Undefined variable: %s",
-                   dst->name);
-      return 1;
-   }
-
-   if (dst->type != vt_address) {
-      _mesa_set_program_error (ctx, Program->Position,
-                               "Variable is not of type ADDRESS");
-      _mesa_error (ctx, GL_INVALID_OPERATION,
-                   "Variable: %s is not of type ADDRESS", dst->name);
-      return 1;
-   }
-
-   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_masked_address_reg (GLcontext * ctx, GLubyte ** inst,
-                          struct var_cache **vc_head,
-                          struct arb_program *Program, GLint * Index,
-                          GLboolean * WriteMask)
-{
-   if (parse_address_reg (ctx, inst, vc_head, Program, Index))
-      return 1;
-
-   /* This should be 0x8 */
-   (*inst)++;
-
-   /* Writemask of .x is implied */
-   WriteMask[0] = 1;
-   WriteMask[1] = WriteMask[2] = WriteMask[3] = 0;
-
-   return 0;
-}
-
-
-/**
- * Parse out a swizzle mask.
- *
- * The values in the input stream are:
- *   COMPONENT_X -> x/r
- *   COMPONENT_Y -> y/g
- *   COMPONENT_Z-> z/b
- *   COMPONENT_W-> w/a
- *
- * The values in the output mask are:
- *   0 -> x/r
- *   1 -> y/g
- *   2 -> z/b
- *   3 -> w/a
- *
- * The len parameter allows us to grab 4 components for a vector
- * swizzle, or just 1 component for a scalar src register selection
- */
-static GLuint
-parse_swizzle_mask (GLubyte ** inst, GLubyte * mask, GLint len)
-{
-   GLint a;
-
-   for (a = 0; a < 4; a++)
-      mask[a] = a;
-
-   for (a = 0; a < len; a++) {
-      switch (*(*inst)++) {
-         case COMPONENT_X:
-            mask[a] = 0;
-            break;
-
-         case COMPONENT_Y:
-            mask[a] = 1;
-            break;
-
-         case COMPONENT_Z:
-            mask[a] = 2;
-            break;
-
-         case COMPONENT_W:
-            mask[a] = 3;
-            break;
-      }
-   }
-
-   return 0;
-}
-
-/**
- */
-static GLuint
-parse_extended_swizzle_mask (GLubyte ** inst, GLubyte * mask, GLboolean * Negate)
-{
-   GLint a;
-   GLubyte swz;
-
-   *Negate = GL_FALSE;
-   for (a = 0; a < 4; a++) {
-      if (parse_sign (inst))
-         *Negate = GL_TRUE;
-
-      swz = *(*inst)++;
-
-      switch (swz) {
-         case COMPONENT_0:
-            mask[a] = SWIZZLE_ZERO;
-            break;
-         case COMPONENT_1:
-            mask[a] = SWIZZLE_ONE;
-            break;
-         case COMPONENT_X:
-            mask[a] = SWIZZLE_X;
-            break;
-         case COMPONENT_Y:
-            mask[a] = SWIZZLE_Y;
-            break;
-         case COMPONENT_Z:
-            mask[a] = SWIZZLE_Z;
-            break;
-         case COMPONENT_W:
-            mask[a] = SWIZZLE_W;
-            break;
-
-      }
-#if 0
-      if (swz == 0)
-         mask[a] = SWIZZLE_ZERO;
-      else if (swz == 1)
-         mask[a] = SWIZZLE_ONE;
-      else
-         mask[a] = swz - 2;
-#endif
-
-   }
-
-   return 0;
-}
-
-
-static GLuint
-parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
-               struct arb_program *Program, GLint * File, GLint * Index,
-               GLboolean *IsRelOffset )
-{
-   struct var_cache *src;
-   GLuint binding_state, binding_idx, is_generic, found, offset;
-
-   /* And the binding for the src */
-   switch (*(*inst)++) {
-      case REGISTER_ATTRIB:
-         if (parse_attrib_binding
-             (ctx, inst, Program, &binding_state, &binding_idx, &is_generic))
-            return 1;
-         *File = PROGRAM_INPUT;
-         *Index = binding_idx;
-
-         /* We need to insert a dummy variable into the var_cache so we can
-          * catch generic vertex attrib aliasing errors
-          */
-         var_cache_create(&src);
-         src->type = vt_attrib;
-         src->name = (GLubyte *)_mesa_strdup("Dummy Attrib Variable");
-         src->attrib_binding     = binding_state;
-         src->attrib_binding_idx = binding_idx;
-         src->attrib_is_generic  = is_generic;
-         var_cache_append(vc_head, src);
-         if (generic_attrib_check(*vc_head)) {
-            _mesa_set_program_error (ctx, Program->Position,
-   "Cannot use both a generic vertex attribute and a specific attribute of the same type");
-            _mesa_error (ctx, GL_INVALID_OPERATION,
-   "Cannot use both a generic vertex attribute and a specific attribute of the same type");
-            return 1;
-         }
-         break;
-
-      case REGISTER_PARAM:
-         switch (**inst) {
-            case PARAM_ARRAY_ELEMENT:
-               (*inst)++;
-               src = parse_string (inst, vc_head, Program, &found);
-               Program->Position = parse_position (inst);
-
-               if (!found) {
-                  _mesa_set_program_error (ctx, Program->Position,
-                                           "2: Undefined variable");
-                  _mesa_error (ctx, GL_INVALID_OPERATION,
-                               "2: Undefined variable: %s", src->name);
-                  return 1;
-               }
-
-               *File = src->param_binding_type;
-
-               switch (*(*inst)++) {
-                  case ARRAY_INDEX_ABSOLUTE:
-                     offset = parse_integer (inst, Program);
-
-                     if ((offset < 0)
-                         || (offset >= src->param_binding_length)) {
-                        _mesa_set_program_error (ctx, Program->Position,
-                                                 "Index out of range");
-                        _mesa_error (ctx, GL_INVALID_OPERATION,
-                                     "Index %d out of range for %s", offset,
-                                     src->name);
-                        return 1;
-                     }
-
-                     *Index = src->param_binding_begin + offset;
-                     break;
-
-                  case ARRAY_INDEX_RELATIVE:
-                     {
-                        GLint addr_reg_idx, rel_off;
-
-                        /* First, grab the address regiseter */
-                        if (parse_address_reg (ctx, inst, vc_head, Program, &addr_reg_idx))
-                           return 1;
-
-                        /* And the .x */
-                        ((*inst)++);
-                        ((*inst)++);
-                        ((*inst)++);
-                        ((*inst)++);
-
-                        /* Then the relative offset */
-                        if (parse_relative_offset(ctx, inst, Program, &rel_off)) return 1;
-
-                        /* And store it properly */
-                        *Index = src->param_binding_begin + rel_off;
-                        *IsRelOffset = 1;
-                     }
-                     break;
-               }
-               break;
-
-            default:
-
-               if (parse_param_use (ctx, inst, vc_head, Program, &src))
-                  return 1;
-
-               *File = src->param_binding_type;
-               *Index = src->param_binding_begin;
-               break;
-         }
-         break;
-
-      case REGISTER_ESTABLISHED_NAME:
-
-         src = parse_string (inst, vc_head, Program, &found);
-         Program->Position = parse_position (inst);
-
-         /* If the name has never been added to our symbol table, we're hosed */
-         if (!found) {
-            _mesa_set_program_error (ctx, Program->Position,
-                                     "3: Undefined variable");
-            _mesa_error (ctx, GL_INVALID_OPERATION, "3: Undefined variable: %s",
-                         src->name);
-            return 1;
-         }
-
-         switch (src->type) {
-            case vt_attrib:
-               *File = PROGRAM_INPUT;
-               *Index = src->attrib_binding_idx;
-               break;
-
-               /* XXX: We have to handle offsets someplace in here!  -- or are those above? */
-            case vt_param:
-               *File = src->param_binding_type;
-               *Index = src->param_binding_begin;
-               break;
-
-            case vt_temp:
-               *File = PROGRAM_TEMPORARY;
-               *Index = src->temp_binding;
-               break;
-
-               /* If the var type is vt_output no go */
-            default:
-               _mesa_set_program_error (ctx, Program->Position,
-                                        "destination register is read only");
-               _mesa_error (ctx, GL_INVALID_OPERATION,
-                            "destination register is read only: %s",
-                            src->name);
-               return 1;
-         }
-         break;
-
-      default:
-         _mesa_set_program_error (ctx, Program->Position,
-                                  "Unknown token in parse_src_reg");
-         _mesa_error (ctx, GL_INVALID_OPERATION,
-                      "Unknown token in parse_src_reg");
-         return 1;
-   }
-
-   return 0;
-}
-
-/**
- */
-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)
-{
-   /* Grab the sign */
-   *Negate = parse_sign (inst);
-
-   /* 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);
-
-   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)
-{
-   /* Grab the sign */
-   *Negate = parse_sign (inst);
-
-   /* And the src reg */
-   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  */
-   parse_swizzle_mask (inst, Swizzle, 1);
-
-   return 0;
-}
-
-/**
- * This is a big mother that handles getting opcodes into the instruction
- * and handling the src & dst registers for fragment program instructions
- */
-static GLuint
-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 */
-   GLuint texcoord;
-   GLubyte instClass, type, code;
-   GLboolean rel;
-
-   /* No condition codes in ARB_fp */
-   fp->UpdateCondRegister = 0;
-
-   /* Record the position in the program string for debugging */
-   fp->StringPos = Program->Position;
-
-   /* OP_ALU_INST or OP_TEX_INST */
-   instClass = *(*inst)++;
-
-   /* OP_ALU_{VECTOR, SCALAR, BINSC, BIN, TRI, SWZ},
-    * OP_TEX_{SAMPLE, KIL}
-    */
-   type = *(*inst)++;
-
-   /* The actual opcode name */
-   code = *(*inst)++;
-
-   /* Increment the correct count */
-   switch (instClass) {
-      case OP_ALU_INST:
-         Program->NumAluInstructions++;
-         break;
-      case OP_TEX_INST:
-         Program->NumTexInstructions++;
-         break;
-   }
-
-   fp->Saturate = 0;
-   fp->Precision = FLOAT32;
-
-   fp->DstReg.CondMask = COND_TR;
-
-   switch (type) {
-      case OP_ALU_VECTOR:
-         switch (code) {
-            case OP_ABS_SAT:
-               fp->Saturate = 1;
-            case OP_ABS:
-               fp->Opcode = FP_OPCODE_ABS;
-               break;
-
-            case OP_FLR_SAT:
-               fp->Saturate = 1;
-            case OP_FLR:
-               fp->Opcode = FP_OPCODE_FLR;
-               break;
-
-            case OP_FRC_SAT:
-               fp->Saturate = 1;
-            case OP_FRC:
-               fp->Opcode = FP_OPCODE_FRC;
-               break;
-
-            case OP_LIT_SAT:
-               fp->Saturate = 1;
-            case OP_LIT:
-               fp->Opcode = FP_OPCODE_LIT;
-               break;
-
-            case OP_MOV_SAT:
-               fp->Saturate = 1;
-            case OP_MOV:
-               fp->Opcode = FP_OPCODE_MOV;
-               break;
-         }
-
-         if (parse_masked_dst_reg
-             (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
-              &fp->DstReg.Index, fp->DstReg.WriteMask))
-            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))
-            return 1;
-         for (b=0; b<4; b++)
-            fp->SrcReg[0].Swizzle[b] = swz[b];
-         break;
-
-      case OP_ALU_SCALAR:
-         switch (code) {
-            case OP_COS_SAT:
-               fp->Saturate = 1;
-            case OP_COS:
-               fp->Opcode = FP_OPCODE_COS;
-               break;
-
-            case OP_EX2_SAT:
-               fp->Saturate = 1;
-            case OP_EX2:
-               fp->Opcode = FP_OPCODE_EX2;
-               break;
-
-            case OP_LG2_SAT:
-               fp->Saturate = 1;
-            case OP_LG2:
-               fp->Opcode = FP_OPCODE_LG2;
-               break;
-
-            case OP_RCP_SAT:
-               fp->Saturate = 1;
-            case OP_RCP:
-               fp->Opcode = FP_OPCODE_RCP;
-               break;
-
-            case OP_RSQ_SAT:
-               fp->Saturate = 1;
-            case OP_RSQ:
-               fp->Opcode = FP_OPCODE_RSQ;
-               break;
-
-            case OP_SIN_SAT:
-               fp->Saturate = 1;
-            case OP_SIN:
-               fp->Opcode = FP_OPCODE_SIN;
-               break;
-
-            case OP_SCS_SAT:
-               fp->Saturate = 1;
-            case OP_SCS:
-
-               fp->Opcode = FP_OPCODE_SCS;
-               break;
-         }
-
-         if (parse_masked_dst_reg
-             (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
-              &fp->DstReg.Index, fp->DstReg.WriteMask))
-            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))
-            return 1;
-         for (b=0; b<4; b++)
-            fp->SrcReg[0].Swizzle[b] = swz[b];
-         break;
-
-      case OP_ALU_BINSC:
-         switch (code) {
-            case OP_POW_SAT:
-               fp->Saturate = 1;
-            case OP_POW:
-               fp->Opcode = FP_OPCODE_POW;
-               break;
-         }
-
-         if (parse_masked_dst_reg
-             (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
-              &fp->DstReg.Index, fp->DstReg.WriteMask))
-            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))
-               return 1;
-            for (b=0; b<4; b++)
-               fp->SrcReg[a].Swizzle[b] = swz[b];
-         }
-         break;
-
-
-      case OP_ALU_BIN:
-         switch (code) {
-            case OP_ADD_SAT:
-               fp->Saturate = 1;
-            case OP_ADD:
-               fp->Opcode = FP_OPCODE_ADD;
-               break;
-
-            case OP_DP3_SAT:
-               fp->Saturate = 1;
-            case OP_DP3:
-               fp->Opcode = FP_OPCODE_DP3;
-               break;
-
-            case OP_DP4_SAT:
-               fp->Saturate = 1;
-            case OP_DP4:
-               fp->Opcode = FP_OPCODE_DP4;
-               break;
-
-            case OP_DPH_SAT:
-               fp->Saturate = 1;
-            case OP_DPH:
-               fp->Opcode = FP_OPCODE_DPH;
-               break;
-
-            case OP_DST_SAT:
-               fp->Saturate = 1;
-            case OP_DST:
-               fp->Opcode = FP_OPCODE_DST;
-               break;
-
-            case OP_MAX_SAT:
-               fp->Saturate = 1;
-            case OP_MAX:
-               fp->Opcode = FP_OPCODE_MAX;
-               break;
-
-            case OP_MIN_SAT:
-               fp->Saturate = 1;
-            case OP_MIN:
-               fp->Opcode = FP_OPCODE_MIN;
-               break;
-
-            case OP_MUL_SAT:
-               fp->Saturate = 1;
-            case OP_MUL:
-               fp->Opcode = FP_OPCODE_MUL;
-               break;
-
-            case OP_SGE_SAT:
-               fp->Saturate = 1;
-            case OP_SGE:
-               fp->Opcode = FP_OPCODE_SGE;
-               break;
-
-            case OP_SLT_SAT:
-               fp->Saturate = 1;
-            case OP_SLT:
-               fp->Opcode = FP_OPCODE_SLT;
-               break;
-
-            case OP_SUB_SAT:
-               fp->Saturate = 1;
-            case OP_SUB:
-               fp->Opcode = FP_OPCODE_SUB;
-               break;
-
-            case OP_XPD_SAT:
-               fp->Saturate = 1;
-            case OP_XPD:
-               fp->Opcode = FP_OPCODE_XPD;
-               break;
-         }
-
-         if (parse_masked_dst_reg
-             (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
-              &fp->DstReg.Index, fp->DstReg.WriteMask))
-            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];
-         }
-         break;
-
-      case OP_ALU_TRI:
-         switch (code) {
-            case OP_CMP_SAT:
-               fp->Saturate = 1;
-            case OP_CMP:
-               fp->Opcode = FP_OPCODE_CMP;
-               break;
-
-            case OP_LRP_SAT:
-               fp->Saturate = 1;
-            case OP_LRP:
-               fp->Opcode = FP_OPCODE_LRP;
-               break;
-
-            case OP_MAD_SAT:
-               fp->Saturate = 1;
-            case OP_MAD:
-               fp->Opcode = FP_OPCODE_MAD;
-               break;
-         }
-
-         if (parse_masked_dst_reg
-             (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,
-              &fp->DstReg.Index, fp->DstReg.WriteMask))
-            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];
-         }
-         break;
-
-      case OP_ALU_SWZ:
-         switch (code) {
-            case OP_SWZ_SAT:
-               fp->Saturate = 1;
-            case OP_SWZ:
-               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))
-            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];
-         break;
-
-      case OP_TEX_SAMPLE:
-         switch (code) {
-            case OP_TEX_SAT:
-               fp->Saturate = 1;
-            case OP_TEX:
-               fp->Opcode = FP_OPCODE_TEX;
-               break;
-
-            case OP_TXP_SAT:
-               fp->Saturate = 1;
-            case OP_TXP:
-               fp->Opcode = FP_OPCODE_TXP;
-               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))
-            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))
-            return 1;
-         for (b=0; b<4; b++)
-            fp->SrcReg[0].Swizzle[b] = swz[b];
-
-         /* texImageUnit */
-         if (parse_texcoord_num (ctx, inst, Program, &texcoord))
-            return 1;
-         fp->TexSrcUnit = texcoord;
-
-         /* texTarget */
-         switch (*(*inst)++) {
-            case TEXTARGET_1D:
-               fp->TexSrcBit = TEXTURE_1D_BIT;
-               break;
-            case TEXTARGET_2D:
-               fp->TexSrcBit = TEXTURE_2D_BIT;
-               break;
-            case TEXTARGET_3D:
-               fp->TexSrcBit = TEXTURE_3D_BIT;
-               break;
-            case TEXTARGET_RECT:
-               fp->TexSrcBit = TEXTURE_RECT_BIT;
-               break;
-            case TEXTARGET_CUBE:
-               fp->TexSrcBit = TEXTURE_CUBE_BIT;
-               break;
-           case TEXTARGET_SHADOW1D:
-           case TEXTARGET_SHADOW2D:
-           case TEXTARGET_SHADOWRECT:
-              /* TODO ARB_fragment_program_shadow code */
-              break;
-         }
-         Program->TexturesUsed[texcoord] |= fp->TexSrcBit;
-         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))
-            return 1;
-         for (b=0; b<4; b++)
-            fp->SrcReg[0].Swizzle[b] = swz[b];
-         break;
-   }
-
-   return 0;
-}
-
-/**
- * This is a big mother that handles getting opcodes into the instruction
- * and handling the src & dst registers for vertex program instructions
- */
-static GLuint
-parse_vp_instruction (GLcontext * ctx, GLubyte ** inst,
-                      struct var_cache **vc_head, struct arb_program *Program,
-                      struct vp_instruction *vp)
-{
-   GLint a;
-   GLubyte type, code;
-
-   /* OP_ALU_{ARL, VECTOR, SCALAR, BINSC, BIN, TRI, SWZ} */
-   type = *(*inst)++;
-
-   /* The actual opcode name */
-   code = *(*inst)++;
-
-   /* Record the position in the program string for debugging */
-   vp->StringPos = Program->Position;
-
-   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;
-   }
-
-   switch (type) {
-         /* XXX: */
-      case OP_ALU_ARL:
-         vp->Opcode = VP_OPCODE_ARL;
-
-         /* 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))
-            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))
-            return 1;
-
-         break;
-
-      case OP_ALU_VECTOR:
-         switch (code) {
-            case OP_ABS:
-               vp->Opcode = VP_OPCODE_ABS;
-               break;
-            case OP_FLR:
-               vp->Opcode = VP_OPCODE_FLR;
-               break;
-            case OP_FRC:
-               vp->Opcode = VP_OPCODE_FRC;
-               break;
-            case OP_LIT:
-               vp->Opcode = VP_OPCODE_LIT;
-               break;
-            case OP_MOV:
-               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))
-            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))
-            return 1;
-         break;
-
-      case OP_ALU_SCALAR:
-         switch (code) {
-            case OP_EX2:
-               vp->Opcode = VP_OPCODE_EX2;
-               break;
-            case OP_EXP:
-               vp->Opcode = VP_OPCODE_EXP;
-               break;
-            case OP_LG2:
-               vp->Opcode = VP_OPCODE_LG2;
-               break;
-            case OP_LOG:
-               vp->Opcode = VP_OPCODE_LOG;
-               break;
-            case OP_RCP:
-               vp->Opcode = VP_OPCODE_RCP;
-               break;
-            case OP_RSQ:
-               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))
-            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))
-            return 1;
-         break;
-
-      case OP_ALU_BINSC:
-         switch (code) {
-            case OP_POW:
-               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))
-            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))
-               return 1;
-         }
-         break;
-
-      case OP_ALU_BIN:
-         switch (code) {
-            case OP_ADD:
-               vp->Opcode = VP_OPCODE_ADD;
-               break;
-            case OP_DP3:
-               vp->Opcode = VP_OPCODE_DP3;
-               break;
-            case OP_DP4:
-               vp->Opcode = VP_OPCODE_DP4;
-               break;
-            case OP_DPH:
-               vp->Opcode = VP_OPCODE_DPH;
-               break;
-            case OP_DST:
-               vp->Opcode = VP_OPCODE_DST;
-               break;
-            case OP_MAX:
-               vp->Opcode = VP_OPCODE_MAX;
-               break;
-            case OP_MIN:
-               vp->Opcode = VP_OPCODE_MIN;
-               break;
-            case OP_MUL:
-               vp->Opcode = VP_OPCODE_MUL;
-               break;
-            case OP_SGE:
-               vp->Opcode = VP_OPCODE_SGE;
-               break;
-            case OP_SLT:
-               vp->Opcode = VP_OPCODE_SLT;
-               break;
-            case OP_SUB:
-               vp->Opcode = VP_OPCODE_SUB;
-               break;
-            case OP_XPD:
-               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))
-            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))
-               return 1;
-         }
-         break;
-
-      case OP_ALU_TRI:
-         switch (code) {
-            case OP_MAD:
-               vp->Opcode = VP_OPCODE_MAD;
-               break;
-         }
-
-         if (parse_masked_dst_reg
-             (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,
-              &vp->DstReg.Index, vp->DstReg.WriteMask))
-            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))
-               return 1;
-         }
-         break;
-
-      case OP_ALU_SWZ:
-         switch (code) {
-            case OP_SWZ:
-               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);
-         break;
-   }
-   return 0;
-}
-
-#if DEBUG_PARSING
-
-static GLvoid
-print_state_token (GLint token)
-{
-   switch (token) {
-      case STATE_MATERIAL:
-         fprintf (stderr, "STATE_MATERIAL ");
-         break;
-      case STATE_LIGHT:
-         fprintf (stderr, "STATE_LIGHT ");
-         break;
-
-      case STATE_LIGHTMODEL_AMBIENT:
-         fprintf (stderr, "STATE_AMBIENT ");
-         break;
-
-      case STATE_LIGHTMODEL_SCENECOLOR:
-         fprintf (stderr, "STATE_SCENECOLOR ");
-         break;
-
-      case STATE_LIGHTPROD:
-         fprintf (stderr, "STATE_LIGHTPROD ");
-         break;
-
-      case STATE_TEXGEN:
-         fprintf (stderr, "STATE_TEXGEN ");
-         break;
-
-      case STATE_FOG_COLOR:
-         fprintf (stderr, "STATE_FOG_COLOR ");
-         break;
-
-      case STATE_FOG_PARAMS:
-         fprintf (stderr, "STATE_FOG_PARAMS ");
-         break;
-
-      case STATE_CLIPPLANE:
-         fprintf (stderr, "STATE_CLIPPLANE ");
-         break;
-
-      case STATE_POINT_SIZE:
-         fprintf (stderr, "STATE_POINT_SIZE ");
-         break;
-
-      case STATE_POINT_ATTENUATION:
-         fprintf (stderr, "STATE_ATTENUATION ");
-         break;
-
-      case STATE_MATRIX:
-         fprintf (stderr, "STATE_MATRIX ");
-         break;
-
-      case STATE_MODELVIEW:
-         fprintf (stderr, "STATE_MODELVIEW ");
-         break;
-
-      case STATE_PROJECTION:
-         fprintf (stderr, "STATE_PROJECTION ");
-         break;
-
-      case STATE_MVP:
-         fprintf (stderr, "STATE_MVP ");
-         break;
-
-      case STATE_TEXTURE:
-         fprintf (stderr, "STATE_TEXTURE ");
-         break;
-
-      case STATE_PROGRAM:
-         fprintf (stderr, "STATE_PROGRAM ");
-         break;
-
-      case STATE_MATRIX_INVERSE:
-         fprintf (stderr, "STATE_INVERSE ");
-         break;
-
-      case STATE_MATRIX_TRANSPOSE:
-         fprintf (stderr, "STATE_TRANSPOSE ");
-         break;
-
-      case STATE_MATRIX_INVTRANS:
-         fprintf (stderr, "STATE_INVTRANS ");
-         break;
-
-      case STATE_AMBIENT:
-         fprintf (stderr, "STATE_AMBIENT ");
-         break;
-
-      case STATE_DIFFUSE:
-         fprintf (stderr, "STATE_DIFFUSE ");
-         break;
-
-      case STATE_SPECULAR:
-         fprintf (stderr, "STATE_SPECULAR ");
-         break;
-
-      case STATE_EMISSION:
-         fprintf (stderr, "STATE_EMISSION ");
-         break;
-
-      case STATE_SHININESS:
-         fprintf (stderr, "STATE_SHININESS ");
-         break;
-
-      case STATE_HALF:
-         fprintf (stderr, "STATE_HALF ");
-         break;
-
-      case STATE_POSITION:
-         fprintf (stderr, "STATE_POSITION ");
-         break;
-
-      case STATE_ATTENUATION:
-         fprintf (stderr, "STATE_ATTENUATION ");
-         break;
-
-      case STATE_SPOT_DIRECTION:
-         fprintf (stderr, "STATE_DIRECTION ");
-         break;
-
-      case STATE_TEXGEN_EYE_S:
-         fprintf (stderr, "STATE_TEXGEN_EYE_S ");
-         break;
-
-      case STATE_TEXGEN_EYE_T:
-         fprintf (stderr, "STATE_TEXGEN_EYE_T ");
-         break;
-
-      case STATE_TEXGEN_EYE_R:
-         fprintf (stderr, "STATE_TEXGEN_EYE_R ");
-         break;
-
-      case STATE_TEXGEN_EYE_Q:
-         fprintf (stderr, "STATE_TEXGEN_EYE_Q ");
-         break;
-
-      case STATE_TEXGEN_OBJECT_S:
-         fprintf (stderr, "STATE_TEXGEN_EYE_S ");
-         break;
-
-      case STATE_TEXGEN_OBJECT_T:
-         fprintf (stderr, "STATE_TEXGEN_OBJECT_T ");
-         break;
-
-      case STATE_TEXGEN_OBJECT_R:
-         fprintf (stderr, "STATE_TEXGEN_OBJECT_R ");
-         break;
-
-      case STATE_TEXGEN_OBJECT_Q:
-         fprintf (stderr, "STATE_TEXGEN_OBJECT_Q ");
-         break;
-
-      case STATE_TEXENV_COLOR:
-         fprintf (stderr, "STATE_TEXENV_COLOR ");
-         break;
-
-      case STATE_DEPTH_RANGE:
-         fprintf (stderr, "STATE_DEPTH_RANGE ");
-         break;
-
-      case STATE_VERTEX_PROGRAM:
-         fprintf (stderr, "STATE_VERTEX_PROGRAM ");
-         break;
-
-      case STATE_FRAGMENT_PROGRAM:
-         fprintf (stderr, "STATE_FRAGMENT_PROGRAM ");
-         break;
-
-      case STATE_ENV:
-         fprintf (stderr, "STATE_ENV ");
-         break;
-
-      case STATE_LOCAL:
-         fprintf (stderr, "STATE_LOCAL ");
-         break;
-
-   }
-   fprintf (stderr, "[%d] ", token);
-}
-
-
-static GLvoid
-debug_variables (GLcontext * ctx, struct var_cache *vc_head,
-                 struct arb_program *Program)
-{
-   struct var_cache *vc;
-   GLint a, b;
-
-   fprintf (stderr, "debug_variables, vc_head: %x\n", vc_head);
-
-   /* First of all, print out the contents of the var_cache */
-   vc = vc_head;
-   while (vc) {
-      fprintf (stderr, "[%x]\n", vc);
-      switch (vc->type) {
-         case vt_none:
-            fprintf (stderr, "UNDEFINED %s\n", vc->name);
-            break;
-         case vt_attrib:
-            fprintf (stderr, "ATTRIB    %s\n", vc->name);
-            fprintf (stderr, "          binding: 0x%x\n", vc->attrib_binding);
-            break;
-         case vt_param:
-            fprintf (stderr, "PARAM     %s  begin: %d len: %d\n", vc->name,
-                     vc->param_binding_begin, vc->param_binding_length);
-            b = vc->param_binding_begin;
-            for (a = 0; a < vc->param_binding_length; a++) {
-               fprintf (stderr, "%s\n",
-                        Program->Parameters->Parameters[a + b].Name);
-               if (Program->Parameters->Parameters[a + b].Type == STATE) {
-                  print_state_token (Program->Parameters->Parameters[a + b].
-                                     StateIndexes[0]);
-                  print_state_token (Program->Parameters->Parameters[a + b].
-                                     StateIndexes[1]);
-                  print_state_token (Program->Parameters->Parameters[a + b].
-                                     StateIndexes[2]);
-                  print_state_token (Program->Parameters->Parameters[a + b].
-                                     StateIndexes[3]);
-                  print_state_token (Program->Parameters->Parameters[a + b].
-                                     StateIndexes[4]);
-                  print_state_token (Program->Parameters->Parameters[a + b].
-                                     StateIndexes[5]);
-               }
-               else
-                  fprintf (stderr, "%f %f %f %f\n",
-                           Program->Parameters->Parameters[a + b].Values[0],
-                           Program->Parameters->Parameters[a + b].Values[1],
-                           Program->Parameters->Parameters[a + b].Values[2],
-                           Program->Parameters->Parameters[a + b].Values[3]);
-            }
-            break;
-         case vt_temp:
-            fprintf (stderr, "TEMP      %s\n", vc->name);
-            fprintf (stderr, "          binding: 0x%x\n", vc->temp_binding);
-            break;
-         case vt_output:
-            fprintf (stderr, "OUTPUT    %s\n", vc->name);
-            fprintf (stderr, "          binding: 0x%x\n", vc->output_binding);
-            break;
-         case vt_alias:
-            fprintf (stderr, "ALIAS     %s\n", vc->name);
-            fprintf (stderr, "          binding: 0x%x (%s)\n",
-                     vc->alias_binding, vc->alias_binding->name);
-            break;
-      }
-      vc = vc->next;
-   }
-}
-
-#endif
-
-
-/**
- * The main loop for parsing a fragment or vertex program
- *
- * \return 0 on sucess, 1 on error
- */
-static GLint
-parse_arb_program (GLcontext * ctx, GLubyte * inst, struct var_cache **vc_head,
-                   struct arb_program *Program)
-{
-   GLint err = 0;
-
-   Program->MajorVersion = (GLuint) * inst++;
-   Program->MinorVersion = (GLuint) * inst++;
-
-   while (*inst != END) {
-      switch (*inst++) {
-
-         case OPTION:
-            switch (*inst++) {
-               case ARB_PRECISION_HINT_FASTEST:
-                  Program->PrecisionOption = GL_FASTEST;
-                  break;
-
-               case ARB_PRECISION_HINT_NICEST:
-                  Program->PrecisionOption = GL_NICEST;
-                  break;
-
-               case ARB_FOG_EXP:
-                  Program->FogOption = GL_EXP;
-                  break;
-
-               case ARB_FOG_EXP2:
-                  Program->FogOption = GL_EXP2;
-                  break;
-
-               case ARB_FOG_LINEAR:
-                  Program->FogOption = GL_LINEAR;
-                  break;
-
-               case ARB_POSITION_INVARIANT:
-                  if (Program->Base.Target == GL_VERTEX_PROGRAM_ARB)
-                     Program->HintPositionInvariant = 1;
-                  break;
-
-               case ARB_FRAGMENT_PROGRAM_SHADOW:
-                 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
-                    /* TODO ARB_fragment_program_shadow code */
-                 }
-                 break;
-            }
-            break;
-
-         case INSTRUCTION:
-            Program->Position = parse_position (&inst);
-
-            if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
-
-               /* Check the instruction count
-                * XXX: Does END count as an instruction?
-                */
-               if (Program->Base.NumInstructions+1 == MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS) {
-                  _mesa_set_program_error (ctx, Program->Position,
-                      "Max instruction count exceeded!");
-                  _mesa_error (ctx, GL_INVALID_OPERATION,
-                      "Max instruction count exceeded!");
-               }
-
-               /* Realloc Program->FPInstructions */
-               Program->FPInstructions =
-                  (struct fp_instruction *) _mesa_realloc (Program->FPInstructions,
-                                                           Program->Base.NumInstructions*sizeof(struct fp_instruction),
-                                                           (Program->Base.NumInstructions+1)*sizeof (struct fp_instruction));
-
-               /* parse the current instruction   */
-               err = parse_fp_instruction (ctx, &inst, vc_head, Program,
-                                           &Program->FPInstructions[Program->Base.NumInstructions]);
-
-            }
-            else {
-               /* Check the instruction count
-                * XXX: Does END count as an instruction?
-                */
-               if (Program->Base.NumInstructions+1 == MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS) {
-                  _mesa_set_program_error (ctx, Program->Position,
-                      "Max instruction count exceeded!");
-                  _mesa_error (ctx, GL_INVALID_OPERATION,
-                      "Max instruction count exceeded!");
-               }
-
-               /* Realloc Program->VPInstructions */
-               Program->VPInstructions =
-                  (struct vp_instruction *) _mesa_realloc (Program->VPInstructions,
-                                                           Program->Base.NumInstructions*sizeof(struct vp_instruction),
-                                                           (Program->Base.NumInstructions +1)*sizeof(struct vp_instruction));
-
-               /* parse the current instruction   */
-               err = parse_vp_instruction (ctx, &inst, vc_head, Program,
-                                           &Program->VPInstructions[Program->Base.NumInstructions]);
-            }
-
-            /* increment Program->Base.NumInstructions */
-            Program->Base.NumInstructions++;
-            break;
-
-         case DECLARATION:
-            err = parse_declaration (ctx, &inst, vc_head, Program);
-            break;
-
-         default:
-            break;
-      }
-
-      if (err)
-         break;
-   }
-
-   /* Finally, tag on an OPCODE_END instruction */
-   if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
-      Program->FPInstructions =
-         (struct fp_instruction *) _mesa_realloc (Program->FPInstructions,
-                                                 Program->Base.NumInstructions*sizeof(struct fp_instruction),
-                                                  (Program->Base.NumInstructions+1)*sizeof(struct fp_instruction));
-
-      Program->FPInstructions[Program->Base.NumInstructions].Opcode = FP_OPCODE_END;
-      /* YYY Wrong Position in program, whatever, at least not random -> crash
-        Program->Position = parse_position (&inst);
-      */
-      Program->FPInstructions[Program->Base.NumInstructions].StringPos = Program->Position;
-   }
-   else {
-      Program->VPInstructions =
-         (struct vp_instruction *) _mesa_realloc (Program->VPInstructions,
-                                                  Program->Base.NumInstructions*sizeof(struct vp_instruction),
-                                                  (Program->Base.NumInstructions+1)*sizeof(struct vp_instruction));
-
-      Program->VPInstructions[Program->Base.NumInstructions].Opcode = VP_OPCODE_END;
-      /* YYY Wrong Position in program, whatever, at least not random -> crash
-        Program->Position = parse_position (&inst);
-      */
-      Program->VPInstructions[Program->Base.NumInstructions].StringPos = Program->Position;
-   }
-
-   /* increment Program->Base.NumInstructions */
-   Program->Base.NumInstructions++;
-
-   return err;
-}
-
-/* XXX temporary */
-static char core_grammar_text[] =
-#include "grammar_syn.h"
-;
-
-static int set_reg8 (GLcontext *ctx, grammar id, const byte *name, byte value)
-{
-   char error_msg[300];
-   GLint error_pos;
-
-   if (grammar_set_reg8 (id, name, value))
-      return 0;
-
-   grammar_get_last_error ((byte *) error_msg, 300, &error_pos);
-   _mesa_set_program_error (ctx, error_pos, error_msg);
-   _mesa_error (ctx, GL_INVALID_OPERATION, "Grammar Register Error");
-   return 1;
-}
-
-static int extension_is_supported (const GLubyte *ext)
-{
-   const GLubyte *extensions = glGetString (GL_EXTENSIONS);
-   const GLubyte *end = extensions + _mesa_strlen ((const char *) extensions);
-   const GLint ext_len = _mesa_strlen ((const char *) ext);
-
+/*\r
+ * Mesa 3-D graphics library\r
+ * Version:  6.1\r
+ *\r
+ * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the "Software"),\r
+ * to deal in the Software without restriction, including without limitation\r
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
+ * and/or sell copies of the Software, and to permit persons to whom the\r
+ * Software is furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included\r
+ * in all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\r
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN\r
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ */\r
+\r
+#define DEBUG_PARSING 0\r
+\r
+/**\r
+ * \file arbprogparse.c\r
+ * ARB_*_program parser core\r
+ * \author Karl Rasche\r
+ */\r
+\r
+#include "mtypes.h"\r
+#include "glheader.h"\r
+#include "context.h"\r
+#include "hash.h"\r
+#include "imports.h"\r
+#include "macros.h"\r
+#include "program.h"\r
+#include "nvvertprog.h"\r
+#include "nvfragprog.h"\r
+#include "arbprogparse.h"\r
+#include "grammar_mesa.h"\r
+\r
+/* TODO:\r
+ *    Fragment Program Stuff:\r
+ *    -----------------------------------------------------\r
+ *\r
+ *    - things from Michal's email\r
+ *       + overflow on atoi\r
+ *       + not-overflowing floats (don't use parse_integer..)\r
+ *       + can remove range checking in arbparse.c\r
+ *\r
+ *    - check all limits of number of various variables\r
+ *      + parameters\r
+ *\r
+ *    - test! test! test!\r
+ *\r
+ *    Vertex Program Stuff:\r
+ *    -----------------------------------------------------\r
+ *    - Optimize param array usage and count limits correctly, see spec,\r
+ *         section 2.14.3.7\r
+ *       + Record if an array is reference absolutly or relatively (or both)\r
+ *       + For absolute arrays, store a bitmap of accesses\r
+ *       + For single parameters, store an access flag\r
+ *       + After parsing, make a parameter cleanup and merging pass, where\r
+ *           relative arrays are layed out first, followed by abs arrays, and\r
+ *           finally single state.\r
+ *       + Remap offsets for param src and dst registers\r
+ *       + Now we can properly count parameter usage\r
+ *\r
+ *    - Multiple state binding errors in param arrays (see spec, just before\r
+ *         section 2.14.3.3)\r
+ *    - grep for XXX\r
+ *\r
+ *    Mesa Stuff\r
+ *    -----------------------------------------------------\r
+ *    - User clipping planes vs. PositionInvariant\r
+ *    - Is it sufficient to just multiply by the mvp to transform in the\r
+ *        PositionInvariant case? Or do we need something more involved?\r
+ *\r
+ *    - vp_src swizzle is GLubyte, fp_src swizzle is GLuint\r
+ *    - fetch state listed in program_parameters list\r
+ *       + WTF should this go???\r
+ *       + currently in nvvertexec.c and s_nvfragprog.c\r
+ *\r
+ *    - allow for multiple address registers (and fetch address regs properly)\r
+ *\r
+ *    Cosmetic Stuff\r
+ *    -----------------------------------------------------\r
+ *     - remove any leftover unused grammer.c stuff (dict_ ?)\r
+ *     - fix grammer.c error handling so its not static\r
+ *     - #ifdef around stuff pertaining to extentions\r
+ *\r
+ *    Outstanding Questions:\r
+ *    -----------------------------------------------------\r
+ *    - ARB_matrix_palette / ARB_vertex_blend -- not supported\r
+ *      what gets hacked off because of this:\r
+ *       + VERTEX_ATTRIB_MATRIXINDEX\r
+ *       + VERTEX_ATTRIB_WEIGHT\r
+ *       + MATRIX_MODELVIEW\r
+ *       + MATRIX_PALETTE\r
+ *\r
+ *    - When can we fetch env/local params from their own register files, and\r
+ *      when to we have to fetch them into the main state register file?\r
+ *      (think arrays)\r
+ *\r
+ *    Grammar Changes:\r
+ *    -----------------------------------------------------\r
+ */\r
+\r
+/* Changes since moving the file to shader directory\r
+\r
+2004-III-4 ------------------------------------------------------------\r
+- added #include "grammar_mesa.h"\r
+- removed grammar specific code part (it resides now in grammar.c)\r
+- added GL_ARB_fragment_program_shadow tokens\r
+- modified #include "arbparse_syn.h"\r
+- major changes inside _mesa_parse_arb_program()\r
+- check the program string for '\0' characters\r
+- copy the program string to a one-byte-longer location to have\r
+  it null-terminated\r
+- position invariance test (not writing to result.position) moved\r
+  to syntax part\r
+*/\r
+\r
+typedef GLubyte *production;\r
+\r
+/**\r
+ * This is the text describing the rules to parse the grammar\r
+ */\r
+static char arb_grammar_text[] =\r
+#include "arbprogram_syn.h"\r
+;\r
+\r
+/**\r
+ * These should match up with the values defined in arbprogram.syn\r
+ */\r
+\r
+/*\r
+    Changes:\r
+    - changed and merged V_* and F_* opcode values to OP_*.\r
+    - added GL_ARB_fragment_program_shadow specific tokens (michal)\r
+*/\r
+#define  REVISION                                   0x07\r
+\r
+/* program type */\r
+#define  FRAGMENT_PROGRAM                           0x01\r
+#define  VERTEX_PROGRAM                             0x02\r
+\r
+/* program section */\r
+#define  OPTION                                     0x01\r
+#define  INSTRUCTION                                0x02\r
+#define  DECLARATION                                0x03\r
+#define  END                                        0x04\r
+\r
+/* GL_ARB_fragment_program option flags */\r
+#define  ARB_PRECISION_HINT_FASTEST                 0x01\r
+#define  ARB_PRECISION_HINT_NICEST                  0x02\r
+#define  ARB_FOG_EXP                                0x04\r
+#define  ARB_FOG_EXP2                               0x08\r
+#define  ARB_FOG_LINEAR                             0x10\r
+\r
+/* GL_ARB_vertex_program option flags */\r
+#define  ARB_POSITION_INVARIANT                     0x20\r
+\r
+/* GL_ARB_fragment_program_shadow option flags */\r
+#define  ARB_FRAGMENT_PROGRAM_SHADOW                0x40\r
+\r
+/* GL_ARB_fragment_program instruction class */\r
+#define  OP_ALU_INST                                0x00\r
+#define  OP_TEX_INST                                0x01\r
+\r
+/* GL_ARB_vertex_program instruction class */\r
+/*       OP_ALU_INST */\r
+\r
+/* GL_ARB_fragment_program instruction type */\r
+#define  OP_ALU_VECTOR                               0x00\r
+#define  OP_ALU_SCALAR                               0x01\r
+#define  OP_ALU_BINSC                                0x02\r
+#define  OP_ALU_BIN                                  0x03\r
+#define  OP_ALU_TRI                                  0x04\r
+#define  OP_ALU_SWZ                                  0x05\r
+#define  OP_TEX_SAMPLE                               0x06\r
+#define  OP_TEX_KIL                                  0x07\r
+\r
+/* GL_ARB_vertex_program instruction type */\r
+#define  OP_ALU_ARL                                  0x08\r
+/*       OP_ALU_VECTOR */\r
+/*       OP_ALU_SCALAR */\r
+/*       OP_ALU_BINSC */\r
+/*       OP_ALU_BIN */\r
+/*       OP_ALU_TRI */\r
+/*       OP_ALU_SWZ */\r
+\r
+/* GL_ARB_fragment_program instruction code */\r
+#define  OP_ABS                                     0x00\r
+#define  OP_ABS_SAT                                 0x1B\r
+#define  OP_FLR                                     0x09\r
+#define  OP_FLR_SAT                                 0x26\r
+#define  OP_FRC                                     0x0A\r
+#define  OP_FRC_SAT                                 0x27\r
+#define  OP_LIT                                     0x0C\r
+#define  OP_LIT_SAT                                 0x2A\r
+#define  OP_MOV                                     0x11\r
+#define  OP_MOV_SAT                                 0x30\r
+#define  OP_COS                                     0x1F\r
+#define  OP_COS_SAT                                 0x20\r
+#define  OP_EX2                                     0x07\r
+#define  OP_EX2_SAT                                 0x25\r
+#define  OP_LG2                                     0x0B\r
+#define  OP_LG2_SAT                                 0x29\r
+#define  OP_RCP                                     0x14\r
+#define  OP_RCP_SAT                                 0x33\r
+#define  OP_RSQ                                     0x15\r
+#define  OP_RSQ_SAT                                 0x34\r
+#define  OP_SIN                                     0x38\r
+#define  OP_SIN_SAT                                 0x39\r
+#define  OP_SCS                                     0x35\r
+#define  OP_SCS_SAT                                 0x36\r
+#define  OP_POW                                     0x13\r
+#define  OP_POW_SAT                                 0x32\r
+#define  OP_ADD                                     0x01\r
+#define  OP_ADD_SAT                                 0x1C\r
+#define  OP_DP3                                     0x03\r
+#define  OP_DP3_SAT                                 0x21\r
+#define  OP_DP4                                     0x04\r
+#define  OP_DP4_SAT                                 0x22\r
+#define  OP_DPH                                     0x05\r
+#define  OP_DPH_SAT                                 0x23\r
+#define  OP_DST                                     0x06\r
+#define  OP_DST_SAT                                 0x24\r
+#define  OP_MAX                                     0x0F\r
+#define  OP_MAX_SAT                                 0x2E\r
+#define  OP_MIN                                     0x10\r
+#define  OP_MIN_SAT                                 0x2F\r
+#define  OP_MUL                                     0x12\r
+#define  OP_MUL_SAT                                 0x31\r
+#define  OP_SGE                                     0x16\r
+#define  OP_SGE_SAT                                 0x37\r
+#define  OP_SLT                                     0x17\r
+#define  OP_SLT_SAT                                 0x3A\r
+#define  OP_SUB                                     0x18\r
+#define  OP_SUB_SAT                                 0x3B\r
+#define  OP_XPD                                     0x1A\r
+#define  OP_XPD_SAT                                 0x43\r
+#define  OP_CMP                                     0x1D\r
+#define  OP_CMP_SAT                                 0x1E\r
+#define  OP_LRP                                     0x2B\r
+#define  OP_LRP_SAT                                 0x2C\r
+#define  OP_MAD                                     0x0E\r
+#define  OP_MAD_SAT                                 0x2D\r
+#define  OP_SWZ                                     0x19\r
+#define  OP_SWZ_SAT                                 0x3C\r
+#define  OP_TEX                                     0x3D\r
+#define  OP_TEX_SAT                                 0x3E\r
+#define  OP_TXB                                     0x3F\r
+#define  OP_TXB_SAT                                 0x40\r
+#define  OP_TXP                                     0x41\r
+#define  OP_TXP_SAT                                 0x42\r
+#define  OP_KIL                                     0x28\r
+\r
+/* GL_ARB_vertex_program instruction code */\r
+#define  OP_ARL                                     0x02\r
+/*       OP_ABS */\r
+/*       OP_FLR */\r
+/*       OP_FRC */\r
+/*       OP_LIT */\r
+/*       OP_MOV */\r
+/*       OP_EX2 */\r
+#define  OP_EXP                                     0x08\r
+/*       OP_LG2 */\r
+#define  OP_LOG                                     0x0D\r
+/*       OP_RCP */\r
+/*       OP_RSQ */\r
+/*       OP_POW */\r
+/*       OP_ADD */\r
+/*       OP_DP3 */\r
+/*       OP_DP4 */\r
+/*       OP_DPH */\r
+/*       OP_DST */\r
+/*       OP_MAX */\r
+/*       OP_MIN */\r
+/*       OP_MUL */\r
+/*       OP_SGE */\r
+/*       OP_SLT */\r
+/*       OP_SUB */\r
+/*       OP_XPD */\r
+/*       OP_MAD */\r
+/*       OP_SWZ */\r
+\r
+/* fragment attribute binding */\r
+#define  FRAGMENT_ATTRIB_COLOR                      0x01\r
+#define  FRAGMENT_ATTRIB_TEXCOORD                   0x02\r
+#define  FRAGMENT_ATTRIB_FOGCOORD                   0x03\r
+#define  FRAGMENT_ATTRIB_POSITION                   0x04\r
+\r
+/* vertex attribute binding */\r
+#define  VERTEX_ATTRIB_POSITION                     0x01\r
+#define  VERTEX_ATTRIB_WEIGHT                       0x02\r
+#define  VERTEX_ATTRIB_NORMAL                       0x03\r
+#define  VERTEX_ATTRIB_COLOR                        0x04\r
+#define  VERTEX_ATTRIB_FOGCOORD                     0x05\r
+#define  VERTEX_ATTRIB_TEXCOORD                     0x06\r
+#define  VERTEX_ATTRIB_MATRIXINDEX                  0x07\r
+#define  VERTEX_ATTRIB_GENERIC                      0x08\r
+\r
+/* fragment result binding */\r
+#define  FRAGMENT_RESULT_COLOR                      0x01\r
+#define  FRAGMENT_RESULT_DEPTH                      0x02\r
+\r
+/* vertex result binding */\r
+#define  VERTEX_RESULT_POSITION                     0x01\r
+#define  VERTEX_RESULT_COLOR                        0x02\r
+#define  VERTEX_RESULT_FOGCOORD                     0x03\r
+#define  VERTEX_RESULT_POINTSIZE                    0x04\r
+#define  VERTEX_RESULT_TEXCOORD                     0x05\r
+\r
+/* texture target */\r
+#define  TEXTARGET_1D                               0x01\r
+#define  TEXTARGET_2D                               0x02\r
+#define  TEXTARGET_3D                               0x03\r
+#define  TEXTARGET_RECT                             0x04\r
+#define  TEXTARGET_CUBE                             0x05\r
+/* GL_ARB_fragment_program_shadow */\r
+#define  TEXTARGET_SHADOW1D                         0x06\r
+#define  TEXTARGET_SHADOW2D                         0x07\r
+#define  TEXTARGET_SHADOWRECT                       0x08\r
+\r
+/* face type */\r
+#define  FACE_FRONT                                 0x00\r
+#define  FACE_BACK                                  0x01\r
+\r
+/* color type */\r
+#define  COLOR_PRIMARY                              0x00\r
+#define  COLOR_SECONDARY                            0x01\r
+\r
+/* component */\r
+#define  COMPONENT_X                                0x00\r
+#define  COMPONENT_Y                                0x01\r
+#define  COMPONENT_Z                                0x02\r
+#define  COMPONENT_W                                0x03\r
+#define  COMPONENT_0                                0x04\r
+#define  COMPONENT_1                                0x05\r
+\r
+/* array index type */\r
+#define  ARRAY_INDEX_ABSOLUTE                       0x00\r
+#define  ARRAY_INDEX_RELATIVE                       0x01\r
+\r
+/* matrix name */\r
+#define  MATRIX_MODELVIEW                           0x01\r
+#define  MATRIX_PROJECTION                          0x02\r
+#define  MATRIX_MVP                                 0x03\r
+#define  MATRIX_TEXTURE                             0x04\r
+#define  MATRIX_PALETTE                             0x05\r
+#define  MATRIX_PROGRAM                             0x06\r
+\r
+/* matrix modifier */\r
+#define  MATRIX_MODIFIER_IDENTITY                   0x00\r
+#define  MATRIX_MODIFIER_INVERSE                    0x01\r
+#define  MATRIX_MODIFIER_TRANSPOSE                  0x02\r
+#define  MATRIX_MODIFIER_INVTRANS                   0x03\r
+\r
+/* constant type */\r
+#define  CONSTANT_SCALAR                            0x01\r
+#define  CONSTANT_VECTOR                            0x02\r
+\r
+/* program param type */\r
+#define  PROGRAM_PARAM_ENV                          0x01\r
+#define  PROGRAM_PARAM_LOCAL                        0x02\r
+\r
+/* register type */\r
+#define  REGISTER_ATTRIB                            0x01\r
+#define  REGISTER_PARAM                             0x02\r
+#define  REGISTER_RESULT                            0x03\r
+#define  REGISTER_ESTABLISHED_NAME                  0x04\r
+\r
+/* param binding */\r
+#define  PARAM_NULL                                 0x00\r
+#define  PARAM_ARRAY_ELEMENT                        0x01\r
+#define  PARAM_STATE_ELEMENT                        0x02\r
+#define  PARAM_PROGRAM_ELEMENT                      0x03\r
+#define  PARAM_PROGRAM_ELEMENTS                     0x04\r
+#define  PARAM_CONSTANT                             0x05\r
+\r
+/* param state property */\r
+#define  STATE_MATERIAL_PARSER                      0x01\r
+#define  STATE_LIGHT_PARSER                         0x02\r
+#define  STATE_LIGHT_MODEL                          0x03\r
+#define  STATE_LIGHT_PROD                           0x04\r
+#define  STATE_FOG                                  0x05\r
+#define  STATE_MATRIX_ROWS                          0x06\r
+/* GL_ARB_fragment_program */\r
+#define  STATE_TEX_ENV                              0x07\r
+#define  STATE_DEPTH                                0x08\r
+/* GL_ARB_vertex_program */\r
+#define  STATE_TEX_GEN                              0x09\r
+#define  STATE_CLIP_PLANE                           0x0A\r
+#define  STATE_POINT                                0x0B\r
+\r
+/* state material property */\r
+#define  MATERIAL_AMBIENT                           0x01\r
+#define  MATERIAL_DIFFUSE                           0x02\r
+#define  MATERIAL_SPECULAR                          0x03\r
+#define  MATERIAL_EMISSION                          0x04\r
+#define  MATERIAL_SHININESS                         0x05\r
+\r
+/* state light property */\r
+#define  LIGHT_AMBIENT                              0x01\r
+#define  LIGHT_DIFFUSE                              0x02\r
+#define  LIGHT_SPECULAR                             0x03\r
+#define  LIGHT_POSITION                             0x04\r
+#define  LIGHT_ATTENUATION                          0x05\r
+#define  LIGHT_HALF                                 0x06\r
+#define  LIGHT_SPOT_DIRECTION                       0x07\r
+\r
+/* state light model property */\r
+#define  LIGHT_MODEL_AMBIENT                        0x01\r
+#define  LIGHT_MODEL_SCENECOLOR                     0x02\r
+\r
+/* state light product property */\r
+#define  LIGHT_PROD_AMBIENT                         0x01\r
+#define  LIGHT_PROD_DIFFUSE                         0x02\r
+#define  LIGHT_PROD_SPECULAR                        0x03\r
+\r
+/* state texture environment property */\r
+#define  TEX_ENV_COLOR                              0x01\r
+\r
+/* state texture generation coord property */\r
+#define  TEX_GEN_EYE                                0x01\r
+#define  TEX_GEN_OBJECT                             0x02\r
+\r
+/* state fog property */\r
+#define  FOG_COLOR                                  0x01\r
+#define  FOG_PARAMS                                 0x02\r
+\r
+/* state depth property */\r
+#define  DEPTH_RANGE                                0x01\r
+\r
+/* state point parameters property */\r
+#define  POINT_SIZE                                 0x01\r
+#define  POINT_ATTENUATION                          0x02\r
+\r
+/* declaration */\r
+#define  ATTRIB                                     0x01\r
+#define  PARAM                                      0x02\r
+#define  TEMP                                       0x03\r
+#define  OUTPUT                                     0x04\r
+#define  ALIAS                                      0x05\r
+/* GL_ARB_vertex_program */\r
+#define  ADDRESS                                    0x06\r
+\r
+/*-----------------------------------------------------------------------\r
+ * From here on down is the semantic checking portion\r
+ *\r
+ */\r
+\r
+/**\r
+ * Variable Table Handling functions\r
+ */\r
+typedef enum\r
+{\r
+   vt_none,\r
+   vt_address,\r
+   vt_attrib,\r
+   vt_param,\r
+   vt_temp,\r
+   vt_output,\r
+   vt_alias\r
+} var_type;\r
+\r
+\r
+/*\r
+ * Setting an explicit field for each of the binding properties is a bit wasteful\r
+ * of space, but it should be much more clear when reading later on..\r
+ */\r
+struct var_cache\r
+{\r
+   GLubyte *name;\r
+   var_type type;\r
+   GLuint address_binding;      /* The index of the address register we should\r
+                                 * be using                                        */\r
+   GLuint attrib_binding;       /* For type vt_attrib, see nvfragprog.h for values */\r
+   GLuint attrib_binding_idx;   /* The index into the attrib register file corresponding\r
+                                 * to the state in attrib_binding                  */\r
+   GLuint attrib_is_generic;    /* If the attrib was specified through a generic\r
+                                 * vertex attrib                                   */\r
+   GLuint temp_binding;         /* The index of the temp register we are to use    */\r
+   GLuint output_binding;       /* For type vt_output, see nvfragprog.h for values */\r
+   GLuint output_binding_idx;   /* This is the index into the result register file\r
+                                 * corresponding to the bound result state         */\r
+   struct var_cache *alias_binding;     /* For type vt_alias, points to the var_cache entry\r
+                                         * that this is aliased to                         */\r
+   GLuint param_binding_type;   /* {PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM,\r
+                                 *    PROGRAM_ENV_PARAM}                           */\r
+   GLuint param_binding_begin;  /* This is the offset into the program_parameter_list where\r
+                                 * the tokens representing our bound state (or constants)\r
+                                 * start */\r
+   GLuint param_binding_length; /* This is how many entries in the the program_parameter_list\r
+                                 * we take up with our state tokens or constants. Note that\r
+                                 * this is _not_ the same as the number of param registers\r
+                                 * we eventually use */\r
+   struct var_cache *next;\r
+};\r
+\r
+static GLvoid\r
+var_cache_create (struct var_cache **va)\r
+{\r
+   *va = (struct var_cache *) _mesa_malloc (sizeof (struct var_cache));\r
+   if (*va) {\r
+      (**va).name = NULL;\r
+      (**va).type = vt_none;\r
+      (**va).attrib_binding = ~0;\r
+      (**va).attrib_is_generic = 0;\r
+      (**va).temp_binding = ~0;\r
+      (**va).output_binding = ~0;\r
+      (**va).output_binding_idx = ~0;\r
+      (**va).param_binding_type = ~0;\r
+      (**va).param_binding_begin = ~0;\r
+      (**va).param_binding_length = ~0;\r
+      (**va).alias_binding = NULL;\r
+      (**va).next = NULL;\r
+   }\r
+}\r
+\r
+static GLvoid\r
+var_cache_destroy (struct var_cache **va)\r
+{\r
+   if (*va) {\r
+      var_cache_destroy (&(**va).next);\r
+      _mesa_free (*va);\r
+      *va = NULL;\r
+   }\r
+}\r
+\r
+static GLvoid\r
+var_cache_append (struct var_cache **va, struct var_cache *nv)\r
+{\r
+   if (*va)\r
+      var_cache_append (&(**va).next, nv);\r
+   else\r
+      *va = nv;\r
+}\r
+\r
+static struct var_cache *\r
+var_cache_find (struct var_cache *va, GLubyte * name)\r
+{\r
+   struct var_cache *first = va;\r
+\r
+   while (va) {\r
+      if (!strcmp ( (const char*) name, (const char*) va->name)) {\r
+         if (va->type == vt_alias)\r
+            return var_cache_find (first, va->name);\r
+         return va;\r
+      }\r
+\r
+      va = va->next;\r
+   }\r
+\r
+   return NULL;\r
+}\r
+\r
+/**\r
+ * constructs an integer from 4 GLubytes in LE format\r
+ */\r
+static GLuint\r
+parse_position (GLubyte ** inst)\r
+{\r
+   GLuint value;\r
+\r
+   value =  (GLuint) (*(*inst)++);\r
+   value += (GLuint) (*(*inst)++) * 0x100;\r
+   value += (GLuint) (*(*inst)++) * 0x10000;\r
+   value += (GLuint) (*(*inst)++) * 0x1000000;\r
+\r
+   return value;\r
+}\r
+\r
+/**\r
+ * This will, given a string, lookup the string as a variable name in the\r
+ * var cache. If the name is found, the var cache node corresponding to the\r
+ * var name is returned. If it is not found, a new entry is allocated\r
+ *\r
+ * \param  I     Points into the binary array where the string identifier begins\r
+ * \param  found 1 if the string was found in the var_cache, 0 if it was allocated\r
+ * \return       The location on the var_cache corresponding the the string starting at I\r
+ */\r
+static struct var_cache *\r
+parse_string (GLubyte ** inst, struct var_cache **vc_head,\r
+              struct arb_program *Program, GLuint * found)\r
+{\r
+   GLubyte *i = *inst;\r
+   struct var_cache *va = NULL;\r
+\r
+   *inst += _mesa_strlen ((char *) i) + 1;\r
+\r
+   va = var_cache_find (*vc_head, i);\r
+\r
+   if (va) {\r
+      *found = 1;\r
+      return va;\r
+   }\r
+\r
+   *found = 0;\r
+   var_cache_create (&va);\r
+   va->name = i;\r
+\r
+   var_cache_append (vc_head, va);\r
+\r
+   return va;\r
+}\r
+\r
+static char *\r
+parse_string_without_adding (GLubyte ** inst, struct arb_program *Program)\r
+{\r
+   GLubyte *i = *inst;\r
+\r
+   *inst += _mesa_strlen ((char *) i) + 1;\r
+\r
+   return (char *) i;\r
+}\r
+\r
+/**\r
+ * \return 0 if sign is plus, 1 if sign is minus\r
+ */\r
+static GLuint\r
+parse_sign (GLubyte ** inst)\r
+{\r
+   /*return *(*inst)++ != '+'; */\r
+\r
+   if (**inst == '-') {\r
+      (*inst)++;\r
+      return 1;\r
+   }\r
+   else if (**inst == '+') {\r
+      (*inst)++;\r
+      return 0;\r
+   }\r
+\r
+   return 0;\r
+}\r
+\r
+/**\r
+ * parses and returns signed integer\r
+ */\r
+static GLint\r
+parse_integer (GLubyte ** inst, struct arb_program *Program)\r
+{\r
+   GLint sign;\r
+   GLint value;\r
+\r
+   /* check if *inst points to '+' or '-'\r
+    * if yes, grab the sign and increment *inst\r
+    */\r
+   sign = parse_sign (inst);\r
+\r
+   /* now check if *inst points to 0\r
+    * if yes, increment the *inst and return the default value\r
+    */\r
+   if (**inst == 0) {\r
+      (*inst)++;\r
+      return 0;\r
+   }\r
+\r
+   /* parse the integer as you normally would do it */\r
+   value = _mesa_atoi (parse_string_without_adding (inst, Program));\r
+\r
+   /* now, after terminating 0 there is a position\r
+    * to parse it - parse_position()\r
+    */\r
+   Program->Position = parse_position (inst);\r
+\r
+   if (sign)\r
+      value *= -1;\r
+\r
+   return value;\r
+}\r
+\r
+/**\r
+ */\r
+static GLfloat\r
+parse_float (GLubyte ** inst, struct arb_program *Program)\r
+{\r
+   GLint tmp[5], denom;\r
+   GLuint leading_zeros =0;\r
+   GLfloat value = 0;\r
+\r
+#if 0\r
+   tmp[0] = parse_sign (inst);  /* This is the sign of the number + - >0, - -> 1 */\r
+#endif\r
+   tmp[1] = parse_integer (inst, Program);   /* This is the integer portion of the number */\r
+\r
+   /* Now we grab the fractional portion of the number (the digits after\r
+       * the .). We can have leading 0's here, which parse_integer will ignore,\r
+       * so we'll check for those first\r
+       */\r
+   while ((**inst == '0') && ( *(*inst+1) != 0))\r
+   {\r
+         leading_zeros++;\r
+         (*inst)++;\r
+   }\r
+   tmp[2] = parse_integer (inst, Program);   /* This is the fractional portion of the number */\r
+   tmp[3] = parse_sign (inst);               /* This is the sign of the exponent */\r
+   tmp[4] = parse_integer (inst, Program);   /* This is the exponent */\r
+\r
+   value = (GLfloat) tmp[1];\r
+   denom = 1;\r
+   while (denom < tmp[2])\r
+      denom *= 10;\r
+   denom *= (GLint) _mesa_pow( 10, leading_zeros );\r
+   value += (GLfloat) tmp[2] / (GLfloat) denom;\r
+#if 0\r
+   if (tmp[0])\r
+      value *= -1;\r
+#endif\r
+   value *= (GLfloat) _mesa_pow (10, (GLfloat) tmp[3] * (GLfloat) tmp[4]);\r
+\r
+   return value;\r
+}\r
+\r
+\r
+/**\r
+ */\r
+static GLfloat\r
+parse_signed_float (GLubyte ** inst, struct arb_program *Program)\r
+{\r
+   GLint negate;\r
+   GLfloat value;\r
+\r
+   negate = parse_sign (inst);\r
+\r
+   value = parse_float (inst, Program);\r
+\r
+   if (negate)\r
+      value *= -1;\r
+\r
+   return value;\r
+}\r
+\r
+/**\r
+ * This picks out a constant value from the parsed array. The constant vector is r\r
+ * returned in the *values array, which should be of length 4.\r
+ *\r
+ * \param values - The 4 component vector with the constant value in it\r
+ */\r
+static GLvoid\r
+parse_constant (GLubyte ** inst, GLfloat *values, struct arb_program *Program,\r
+                GLboolean use)\r
+{\r
+   GLuint components, i;\r
+\r
+\r
+   switch (*(*inst)++) {\r
+      case CONSTANT_SCALAR:\r
+         if (use == GL_TRUE) {\r
+            values[0] =\r
+               values[1] =\r
+               values[2] = values[3] = parse_float (inst, Program);\r
+         }\r
+         else {\r
+            values[0] =\r
+               values[1] =\r
+               values[2] = values[3] = parse_signed_float (inst, Program);\r
+         }\r
+\r
+         break;\r
+      case CONSTANT_VECTOR:\r
+         values[0] = values[1] = values[2] = 0;\r
+         values[3] = 1;\r
+         components = *(*inst)++;\r
+         for (i = 0; i < components; i++) {\r
+            values[i] = parse_signed_float (inst, Program);\r
+         }\r
+         break;\r
+   }\r
+}\r
+\r
+/**\r
+ * \param offset The offset from the address register that we should\r
+ *                address\r
+ *\r
+ * \return 0 on sucess, 1 on error\r
+ */\r
+static GLuint\r
+parse_relative_offset (GLcontext *ctx, GLubyte **inst, struct arb_program *Program,\r
+                        GLint *offset)\r
+{\r
+   *offset = parse_integer(inst, Program);\r
+   if ((*offset > 63) || (*offset < -64)) {\r
+      _mesa_set_program_error (ctx, Program->Position,\r
+                               "Relative offset out of range");\r
+      _mesa_error (ctx, GL_INVALID_OPERATION, "Relative offset %d out of range",\r
+                                                *offset);\r
+      return 1;\r
+   }\r
+\r
+   return 0;\r
+}\r
+\r
+/**\r
+ * \param  color 0 if color type is primary, 1 if color type is secondary\r
+ * \return 0 on sucess, 1 on error\r
+ */\r
+static GLuint\r
+parse_color_type (GLcontext * ctx, GLubyte ** inst, struct arb_program *Program,\r
+                  GLint * color)\r
+{\r
+   *color = *(*inst)++ != COLOR_PRIMARY;\r
+   return 0;\r
+}\r
+\r
+/**\r
+ * Get an integer corresponding to a generic vertex attribute.\r
+ *\r
+ * \return 0 on sucess, 1 on error\r
+ */\r
+static GLuint\r
+parse_generic_attrib_num(GLcontext *ctx, GLubyte ** inst,\r
+                       struct arb_program *Program, GLuint *attrib)\r
+{\r
+   *attrib = parse_integer(inst, Program);\r
+\r
+   if ((*attrib < 0) || (*attrib > MAX_VERTEX_PROGRAM_ATTRIBS))\r
+   {\r
+      _mesa_set_program_error (ctx, Program->Position,\r
+                               "Invalid generic vertex attribute index");\r
+      _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid generic vertex attribute index");\r
+\r
+      return 1;\r
+   }\r
+\r
+   return 0;\r
+}\r
+\r
+\r
+/**\r
+ * \param coord The texture unit index\r
+ * \return 0 on sucess, 1 on error\r
+ */\r
+static GLuint\r
+parse_texcoord_num (GLcontext * ctx, GLubyte ** inst,\r
+                    struct arb_program *Program, GLuint * coord)\r
+{\r
+   *coord = parse_integer (inst, Program);\r
+\r
+   if ((*coord < 0) || (*coord >= ctx->Const.MaxTextureUnits)) {\r
+      _mesa_set_program_error (ctx, Program->Position,\r
+                               "Invalid texture unit index");\r
+      _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid texture unit index");\r
+      return 1;\r
+   }\r
+\r
+   return 0;\r
+}\r
+\r
+/**\r
+ * \param coord The weight index\r
+ * \return 0 on sucess, 1 on error\r
+ */\r
+static GLuint\r
+parse_weight_num (GLcontext * ctx, GLubyte ** inst, struct arb_program *Program,\r
+                  GLint * coord)\r
+{\r
+   *coord = parse_integer (inst, Program);\r
+\r
+   if ((*coord < 0) || (*coord >= 1)) {\r
+      _mesa_set_program_error (ctx, Program->Position,\r
+                               "Invalid weight index");\r
+      _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid weight index");\r
+      return 1;\r
+   }\r
+\r
+   return 0;\r
+}\r
+\r
+/**\r
+ * \param coord The clip plane index\r
+ * \return 0 on sucess, 1 on error\r
+ */\r
+static GLuint\r
+parse_clipplane_num (GLcontext * ctx, GLubyte ** inst,\r
+                     struct arb_program *Program, GLint * coord)\r
+{\r
+   *coord = parse_integer (inst, Program);\r
+\r
+   if ((*coord < 0) || (*coord >= (GLint) ctx->Const.MaxClipPlanes)) {\r
+      _mesa_set_program_error (ctx, Program->Position,\r
+                               "Invalid clip plane index");\r
+      _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid clip plane index");\r
+      return 1;\r
+   }\r
+\r
+   return 0;\r
+}\r
+\r
+\r
+/**\r
+ * \return 0 on front face, 1 on back face\r
+ */\r
+static GLuint\r
+parse_face_type (GLubyte ** inst)\r
+{\r
+   switch (*(*inst)++) {\r
+      case FACE_FRONT:\r
+         return 0;\r
+\r
+      case FACE_BACK:\r
+         return 1;\r
+   }\r
+   return 0;\r
+}\r
+\r
+\r
+/**\r
+ * Given a matrix and a modifier token on the binary array, return tokens\r
+ * that _mesa_fetch_state() [program.c] can understand.\r
+ *\r
+ * \param matrix - the matrix we are talking about\r
+ * \param matrix_idx - the index of the matrix we have (for texture & program matricies)\r
+ * \param matrix_modifier - the matrix modifier (trans, inv, etc)\r
+ * \return 0 on sucess, 1 on failure\r
+ */\r
+static GLuint\r
+parse_matrix (GLcontext * ctx, GLubyte ** inst, struct arb_program *Program,\r
+              GLint * matrix, GLint * matrix_idx, GLint * matrix_modifier)\r
+{\r
+   GLubyte mat = *(*inst)++;\r
+\r
+   *matrix_idx = 0;\r
+\r
+   switch (mat) {\r
+      case MATRIX_MODELVIEW:\r
+         *matrix = STATE_MODELVIEW;\r
+         *matrix_idx = parse_integer (inst, Program);\r
+         if (*matrix_idx > 0) {\r
+            _mesa_set_program_error (ctx, Program->Position,\r
+               "ARB_vertex_blend not supported\n");\r
+            _mesa_error (ctx, GL_INVALID_OPERATION,\r
+               "ARB_vertex_blend not supported\n");\r
+            return 1;\r
+         }\r
+         break;\r
+\r
+      case MATRIX_PROJECTION:\r
+         *matrix = STATE_PROJECTION;\r
+         break;\r
+\r
+      case MATRIX_MVP:\r
+         *matrix = STATE_MVP;\r
+         break;\r
+\r
+      case MATRIX_TEXTURE:\r
+         *matrix = STATE_TEXTURE;\r
+         *matrix_idx = parse_integer (inst, Program);\r
+         if (*matrix_idx >= (GLint) ctx->Const.MaxTextureUnits) {\r
+            _mesa_set_program_error (ctx, Program->Position,\r
+                                     "Invalid Texture Unit");\r
+            _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                         "Invalid Texture Unit: %d", *matrix_idx);\r
+            return 1;\r
+         }\r
+         break;\r
+\r
+         /* This is not currently supported (ARB_matrix_palette) */\r
+      case MATRIX_PALETTE:\r
+         *matrix_idx = parse_integer (inst, Program);\r
+         _mesa_set_program_error (ctx, Program->Position,\r
+              "ARB_matrix_palette not supported\n");\r
+         _mesa_error (ctx, GL_INVALID_OPERATION,\r
+              "ARB_matrix_palette not supported\n");\r
+         return 1;\r
+         break;\r
+\r
+      case MATRIX_PROGRAM:\r
+         *matrix = STATE_PROGRAM;\r
+         *matrix_idx = parse_integer (inst, Program);\r
+         if (*matrix_idx >= (GLint) ctx->Const.MaxProgramMatrices) {\r
+            _mesa_set_program_error (ctx, Program->Position,\r
+                                     "Invalid Program Matrix");\r
+            _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                         "Invalid Program Matrix: %d", *matrix_idx);\r
+            return 1;\r
+         }\r
+         break;\r
+   }\r
+\r
+   switch (*(*inst)++) {\r
+      case MATRIX_MODIFIER_IDENTITY:\r
+         *matrix_modifier = 0;\r
+         break;\r
+      case MATRIX_MODIFIER_INVERSE:\r
+         *matrix_modifier = STATE_MATRIX_INVERSE;\r
+         break;\r
+      case MATRIX_MODIFIER_TRANSPOSE:\r
+         *matrix_modifier = STATE_MATRIX_TRANSPOSE;\r
+         break;\r
+      case MATRIX_MODIFIER_INVTRANS:\r
+         *matrix_modifier = STATE_MATRIX_INVTRANS;\r
+         break;\r
+   }\r
+\r
+   return 0;\r
+}\r
+\r
+\r
+/**\r
+ * This parses a state string (rather, the binary version of it) into\r
+ * a 6-token sequence as described in _mesa_fetch_state() [program.c]\r
+ *\r
+ * \param inst         - the start in the binary arry to start working from\r
+ * \param state_tokens - the storage for the 6-token state description\r
+ * \return             - 0 on sucess, 1 on error\r
+ */\r
+static GLuint\r
+parse_state_single_item (GLcontext * ctx, GLubyte ** inst,\r
+                         struct arb_program *Program, GLint * state_tokens)\r
+{\r
+   switch (*(*inst)++) {\r
+      case STATE_MATERIAL_PARSER:\r
+         state_tokens[0] = STATE_MATERIAL;\r
+         state_tokens[1] = parse_face_type (inst);\r
+         switch (*(*inst)++) {\r
+            case MATERIAL_AMBIENT:\r
+               state_tokens[2] = STATE_AMBIENT;\r
+               break;\r
+            case MATERIAL_DIFFUSE:\r
+               state_tokens[2] = STATE_DIFFUSE;\r
+               break;\r
+            case MATERIAL_SPECULAR:\r
+               state_tokens[2] = STATE_SPECULAR;\r
+               break;\r
+            case MATERIAL_EMISSION:\r
+               state_tokens[2] = STATE_EMISSION;\r
+              break;\r
+            case MATERIAL_SHININESS:\r
+               state_tokens[2] = STATE_SHININESS;\r
+               break;\r
+         }\r
+         break;\r
+\r
+      case STATE_LIGHT_PARSER:\r
+         state_tokens[0] = STATE_LIGHT;\r
+         state_tokens[1] = parse_integer (inst, Program);\r
+\r
+         /* Check the value of state_tokens[1] against the # of lights */\r
+         if (state_tokens[1] >= (GLint) ctx->Const.MaxLights) {\r
+            _mesa_set_program_error (ctx, Program->Position,\r
+                                     "Invalid Light Number");\r
+            _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                         "Invalid Light Number: %d", state_tokens[1]);\r
+            return 1;\r
+         }\r
+\r
+         switch (*(*inst)++) {\r
+            case LIGHT_AMBIENT:\r
+               state_tokens[2] = STATE_AMBIENT;\r
+               break;\r
+            case LIGHT_DIFFUSE:\r
+               state_tokens[2] = STATE_DIFFUSE;\r
+               break;\r
+            case LIGHT_SPECULAR:\r
+               state_tokens[2] = STATE_SPECULAR;\r
+               break;\r
+            case LIGHT_POSITION:\r
+               state_tokens[2] = STATE_POSITION;\r
+               break;\r
+            case LIGHT_ATTENUATION:\r
+               state_tokens[2] = STATE_ATTENUATION;\r
+               break;\r
+            case LIGHT_HALF:\r
+               state_tokens[2] = STATE_HALF;\r
+               break;\r
+            case LIGHT_SPOT_DIRECTION:\r
+               state_tokens[2] = STATE_SPOT_DIRECTION;\r
+               break;\r
+         }\r
+         break;\r
+\r
+      case STATE_LIGHT_MODEL:\r
+         switch (*(*inst)++) {\r
+            case LIGHT_MODEL_AMBIENT:\r
+               state_tokens[0] = STATE_LIGHTMODEL_AMBIENT;\r
+               break;\r
+            case LIGHT_MODEL_SCENECOLOR:\r
+               state_tokens[0] = STATE_LIGHTMODEL_SCENECOLOR;\r
+               state_tokens[1] = parse_face_type (inst);\r
+               break;\r
+         }\r
+         break;\r
+\r
+      case STATE_LIGHT_PROD:\r
+         state_tokens[0] = STATE_LIGHTPROD;\r
+         state_tokens[1] = parse_integer (inst, Program);\r
+\r
+         /* Check the value of state_tokens[1] against the # of lights */\r
+         if (state_tokens[1] >= (GLint) ctx->Const.MaxLights) {\r
+            _mesa_set_program_error (ctx, Program->Position,\r
+                                     "Invalid Light Number");\r
+            _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                         "Invalid Light Number: %d", state_tokens[1]);\r
+            return 1;\r
+         }\r
+\r
+         state_tokens[2] = parse_face_type (inst);\r
+         switch (*(*inst)++) {\r
+            case LIGHT_PROD_AMBIENT:\r
+               state_tokens[3] = STATE_AMBIENT;\r
+               break;\r
+            case LIGHT_PROD_DIFFUSE:\r
+               state_tokens[3] = STATE_DIFFUSE;\r
+               break;\r
+            case LIGHT_PROD_SPECULAR:\r
+               state_tokens[3] = STATE_SPECULAR;\r
+               break;\r
+         }\r
+         break;\r
+\r
+\r
+      case STATE_FOG:\r
+         switch (*(*inst)++) {\r
+            case FOG_COLOR:\r
+               state_tokens[0] = STATE_FOG_COLOR;\r
+               break;\r
+            case FOG_PARAMS:\r
+               state_tokens[0] = STATE_FOG_PARAMS;\r
+               break;\r
+         }\r
+         break;\r
+\r
+      case STATE_TEX_ENV:\r
+         state_tokens[1] = parse_integer (inst, Program);\r
+         switch (*(*inst)++) {\r
+            case TEX_ENV_COLOR:\r
+               state_tokens[0] = STATE_TEXENV_COLOR;\r
+               break;\r
+         }\r
+         break;\r
+\r
+      case STATE_TEX_GEN:\r
+         {\r
+            GLuint type, coord;\r
+\r
+            state_tokens[0] = STATE_TEXGEN;\r
+            /*state_tokens[1] = parse_integer (inst, Program);*/    /* Texture Unit */\r
+\r
+            if (parse_texcoord_num (ctx, inst, Program, &coord))\r
+               return 1;\r
+           state_tokens[1] = coord;\r
+\r
+            /* EYE or OBJECT */\r
+            type = *(*inst++);\r
+\r
+            /* 0 - s, 1 - t, 2 - r, 3 - q */\r
+            coord = *(*inst++);\r
+\r
+            if (type == TEX_GEN_EYE) {\r
+               switch (coord) {\r
+                  case COMPONENT_X:\r
+                     state_tokens[2] = STATE_TEXGEN_EYE_S;\r
+                     break;\r
+                  case COMPONENT_Y:\r
+                     state_tokens[2] = STATE_TEXGEN_EYE_T;\r
+                     break;\r
+                  case COMPONENT_Z:\r
+                     state_tokens[2] = STATE_TEXGEN_EYE_R;\r
+                     break;\r
+                  case COMPONENT_W:\r
+                     state_tokens[2] = STATE_TEXGEN_EYE_Q;\r
+                     break;\r
+               }\r
+            }\r
+            else {\r
+               switch (coord) {\r
+                  case COMPONENT_X:\r
+                     state_tokens[2] = STATE_TEXGEN_OBJECT_S;\r
+                     break;\r
+                  case COMPONENT_Y:\r
+                     state_tokens[2] = STATE_TEXGEN_OBJECT_T;\r
+                     break;\r
+                  case COMPONENT_Z:\r
+                     state_tokens[2] = STATE_TEXGEN_OBJECT_R;\r
+                     break;\r
+                  case COMPONENT_W:\r
+                     state_tokens[2] = STATE_TEXGEN_OBJECT_Q;\r
+                     break;\r
+               }\r
+            }\r
+         }\r
+         break;\r
+\r
+      case STATE_DEPTH:\r
+         switch (*(*inst)++) {\r
+            case DEPTH_RANGE:\r
+               state_tokens[0] = STATE_DEPTH_RANGE;\r
+               break;\r
+         }\r
+         break;\r
+\r
+      case STATE_CLIP_PLANE:\r
+         state_tokens[0] = STATE_CLIPPLANE;\r
+         state_tokens[1] = parse_integer (inst, Program);\r
+         if (parse_clipplane_num (ctx, inst, Program, &state_tokens[1]))\r
+            return 1;\r
+         break;\r
+\r
+      case STATE_POINT:\r
+         switch (*(*inst++)) {\r
+            case POINT_SIZE:\r
+               state_tokens[0] = STATE_POINT_SIZE;\r
+               break;\r
+\r
+            case POINT_ATTENUATION:\r
+               state_tokens[0] = STATE_POINT_ATTENUATION;\r
+               break;\r
+         }\r
+         break;\r
+\r
+         /* XXX: I think this is the correct format for a matrix row */\r
+      case STATE_MATRIX_ROWS:\r
+         state_tokens[0] = STATE_MATRIX;\r
+         if (parse_matrix\r
+             (ctx, inst, Program, &state_tokens[1], &state_tokens[2],\r
+              &state_tokens[5]))\r
+            return 1;\r
+\r
+         state_tokens[3] = parse_integer (inst, Program);       /* The first row to grab */\r
+\r
+         if ((**inst) != 0) {                                   /* Either the last row, 0 */\r
+            state_tokens[4] = parse_integer (inst, Program);\r
+            if (state_tokens[4] < state_tokens[3]) {\r
+               _mesa_set_program_error (ctx, Program->Position,\r
+                     "Second matrix index less than the first");\r
+               _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                     "Second matrix index (%d) less than the first (%d)",\r
+                     state_tokens[4], state_tokens[3]);\r
+               return 1;\r
+            }\r
+         }\r
+         else {\r
+            state_tokens[4] = state_tokens[3];\r
+            (*inst)++;\r
+         }\r
+         break;\r
+   }\r
+\r
+   return 0;\r
+}\r
+\r
+/**\r
+ * This parses a state string (rather, the binary version of it) into\r
+ * a 6-token similar for the state fetching code in program.c\r
+ *\r
+ * One might ask, why fetch these parameters into just like  you fetch\r
+ * state when they are already stored in other places?\r
+ *\r
+ * Because of array offsets -> We can stick env/local parameters in the\r
+ * middle of a parameter array and then index someplace into the array\r
+ * when we execute.\r
+ *\r
+ * One optimization might be to only do this for the cases where the\r
+ * env/local parameters end up inside of an array, and leave the\r
+ * single parameters (or arrays of pure env/local pareameters) in their\r
+ * respective register files.\r
+ *\r
+ * For ENV parameters, the format is:\r
+ *    state_tokens[0] = STATE_FRAGMENT_PROGRAM / STATE_VERTEX_PROGRAM\r
+ *    state_tokens[1] = STATE_ENV\r
+ *    state_tokens[2] = the parameter index\r
+ *\r
+ * for LOCAL parameters, the format is:\r
+ *    state_tokens[0] = STATE_FRAGMENT_PROGRAM / STATE_VERTEX_PROGRAM\r
+ *    state_tokens[1] = STATE_LOCAL\r
+ *    state_tokens[2] = the parameter index\r
+ *\r
+ * \param inst         - the start in the binary arry to start working from\r
+ * \param state_tokens - the storage for the 6-token state description\r
+ * \return             - 0 on sucess, 1 on failure\r
+ */\r
+static GLuint\r
+parse_program_single_item (GLcontext * ctx, GLubyte ** inst,\r
+                           struct arb_program *Program, GLint * state_tokens)\r
+{\r
+   if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB)\r
+      state_tokens[0] = STATE_FRAGMENT_PROGRAM;\r
+   else\r
+      state_tokens[0] = STATE_VERTEX_PROGRAM;\r
+\r
+\r
+   switch (*(*inst)++) {\r
+      case PROGRAM_PARAM_ENV:\r
+         state_tokens[1] = STATE_ENV;\r
+         state_tokens[2] = parse_integer (inst, Program);\r
+\r
+         /* Check state_tokens[2] against the number of ENV parameters available */\r
+         if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) &&\r
+              (state_tokens[2] >= (GLint) ctx->Const.MaxFragmentProgramEnvParams))\r
+             ||\r
+             ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) &&\r
+              (state_tokens[2] >= (GLint) ctx->Const.MaxVertexProgramEnvParams))) {\r
+            _mesa_set_program_error (ctx, Program->Position,\r
+                                     "Invalid Program Env Parameter");\r
+            _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                         "Invalid Program Env Parameter: %d",\r
+                         state_tokens[2]);\r
+            return 1;\r
+         }\r
+\r
+         break;\r
+\r
+      case PROGRAM_PARAM_LOCAL:\r
+         state_tokens[1] = STATE_LOCAL;\r
+         state_tokens[2] = parse_integer (inst, Program);\r
+\r
+         /* Check state_tokens[2] against the number of LOCAL parameters available */\r
+         if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) &&\r
+              (state_tokens[2] >= (GLint) ctx->Const.MaxFragmentProgramLocalParams))\r
+             ||\r
+             ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) &&\r
+              (state_tokens[2] >= (GLint) ctx->Const.MaxVertexProgramLocalParams))) {\r
+            _mesa_set_program_error (ctx, Program->Position,\r
+                                     "Invalid Program Local Parameter");\r
+            _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                         "Invalid Program Local Parameter: %d",\r
+                         state_tokens[2]);\r
+            return 1;\r
+         }\r
+         break;\r
+   }\r
+\r
+   return 0;\r
+}\r
+\r
+/**\r
+ * For ARB_vertex_program, programs are not allowed to use both an explicit\r
+ * vertex attribute and a generic vertex attribute corresponding to the same\r
+ * state. See section 2.14.3.1 of the GL_ARB_vertex_program spec.\r
+ *\r
+ * This will walk our var_cache and make sure that nobody does anything fishy.\r
+ *\r
+ * \return 0 on sucess, 1 on error\r
+ */\r
+static GLuint\r
+generic_attrib_check(struct var_cache *vc_head)\r
+{\r
+   int a;\r
+   struct var_cache *curr;\r
+   GLboolean explicitAttrib[MAX_VERTEX_PROGRAM_ATTRIBS],\r
+      genericAttrib[MAX_VERTEX_PROGRAM_ATTRIBS];\r
+\r
+   for (a=0; a<MAX_VERTEX_PROGRAM_ATTRIBS; a++) {\r
+      explicitAttrib[a] = GL_FALSE;\r
+      genericAttrib[a] = GL_FALSE;\r
+   }\r
+\r
+   curr = vc_head;\r
+   while (curr) {\r
+      if (curr->type == vt_attrib) {\r
+         if (curr->attrib_is_generic)\r
+            genericAttrib[ curr->attrib_binding_idx ] = GL_TRUE;\r
+         else\r
+            explicitAttrib[ curr->attrib_binding_idx ] = GL_TRUE;\r
+      }\r
+\r
+      curr = curr->next;\r
+   }\r
+\r
+   for (a=0; a<MAX_VERTEX_PROGRAM_ATTRIBS; a++) {\r
+      if ((explicitAttrib[a]) && (genericAttrib[a]))\r
+         return 1;\r
+   }\r
+\r
+   return 0;\r
+}\r
+\r
+/**\r
+ * This will handle the binding side of an ATTRIB var declaration\r
+ *\r
+ * \param binding     - the fragment input register state, defined in nvfragprog.h\r
+ * \param binding_idx - the index in the attrib register file that binding is associated with\r
+ * \return returns 0 on sucess, 1 on error\r
+ *\r
+ * See nvfragparse.c for attrib register file layout\r
+ */\r
+static GLuint\r
+parse_attrib_binding (GLcontext * ctx, GLubyte ** inst,\r
+                      struct arb_program *Program, GLuint * binding,\r
+                      GLuint * binding_idx, GLuint *is_generic)\r
+{\r
+   GLuint texcoord;\r
+   GLint coord;\r
+   GLint err = 0;\r
+\r
+   *is_generic = 0;\r
+   if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {\r
+      switch (*(*inst)++) {\r
+         case FRAGMENT_ATTRIB_COLOR:\r
+            err = parse_color_type (ctx, inst, Program, &coord);\r
+            *binding = FRAG_ATTRIB_COL0 + coord;\r
+            *binding_idx = 1 + coord;\r
+            break;\r
+\r
+         case FRAGMENT_ATTRIB_TEXCOORD:\r
+            err = parse_texcoord_num (ctx, inst, Program, &texcoord);\r
+            *binding = FRAG_ATTRIB_TEX0 + texcoord;\r
+            *binding_idx = 4 + texcoord;\r
+            break;\r
+\r
+         case FRAGMENT_ATTRIB_FOGCOORD:\r
+            *binding = FRAG_ATTRIB_FOGC;\r
+            *binding_idx = 3;\r
+            break;\r
+\r
+         case FRAGMENT_ATTRIB_POSITION:\r
+            *binding = FRAG_ATTRIB_WPOS;\r
+            *binding_idx = 0;\r
+            break;\r
+\r
+         default:\r
+            err = 1;\r
+            break;\r
+      }\r
+   }\r
+   else {\r
+      switch (*(*inst)++) {\r
+         case VERTEX_ATTRIB_POSITION:\r
+            *binding = VERT_ATTRIB_POS;\r
+            *binding_idx = 0;\r
+            break;\r
+\r
+         case VERTEX_ATTRIB_WEIGHT:\r
+            {\r
+               GLint weight;\r
+\r
+               err = parse_weight_num (ctx, inst, Program, &weight);\r
+               *binding = VERT_ATTRIB_WEIGHT;\r
+               *binding_idx = 1;\r
+            }\r
+            _mesa_set_program_error (ctx, Program->Position,\r
+                 "ARB_vertex_blend not supported\n");\r
+            _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                 "ARB_vertex_blend not supported\n");\r
+            return 1;\r
+            break;\r
+\r
+         case VERTEX_ATTRIB_NORMAL:\r
+            *binding = VERT_ATTRIB_NORMAL;\r
+            *binding_idx = 2;\r
+            break;\r
+\r
+         case VERTEX_ATTRIB_COLOR:\r
+            {\r
+               GLint color;\r
+\r
+               err = parse_color_type (ctx, inst, Program, &color);\r
+               if (color) {\r
+                  *binding = VERT_ATTRIB_COLOR1;\r
+                  *binding_idx = 4;\r
+               }\r
+               else {\r
+                  *binding = VERT_ATTRIB_COLOR0;\r
+                  *binding_idx = 3;\r
+               }\r
+            }\r
+            break;\r
+\r
+         case VERTEX_ATTRIB_FOGCOORD:\r
+            *binding = VERT_ATTRIB_FOG;\r
+            *binding_idx = 5;\r
+            break;\r
+\r
+         case VERTEX_ATTRIB_TEXCOORD:\r
+            {\r
+               GLuint unit;\r
+\r
+               err = parse_texcoord_num (ctx, inst, Program, &unit);\r
+               *binding = VERT_ATTRIB_TEX0 + unit;\r
+               *binding_idx = 8 + unit;\r
+            }\r
+            break;\r
+\r
+            /* It looks like we don't support this at all, atm */\r
+         case VERTEX_ATTRIB_MATRIXINDEX:\r
+            parse_integer (inst, Program);\r
+            _mesa_set_program_error (ctx, Program->Position,\r
+                  "ARB_palette_matrix not supported");\r
+            _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                  "ARB_palette_matrix not supported");\r
+            return 1;\r
+            break;\r
+\r
+         case VERTEX_ATTRIB_GENERIC:\r
+            {\r
+               GLuint attrib;\r
+\r
+               if (!parse_generic_attrib_num(ctx, inst, Program, &attrib)) {\r
+                  *is_generic = 1;\r
+                  switch (attrib) {\r
+                     case 0:\r
+                        *binding = VERT_ATTRIB_POS;\r
+                        break;\r
+                     case 1:\r
+                        *binding = VERT_ATTRIB_WEIGHT;\r
+                        break;\r
+                     case 2:\r
+                        *binding = VERT_ATTRIB_NORMAL;\r
+                        break;\r
+                     case 3:\r
+                        *binding = VERT_ATTRIB_COLOR0;\r
+                        break;\r
+                     case 4:\r
+                        *binding = VERT_ATTRIB_COLOR1;\r
+                        break;\r
+                     case 5:\r
+                        *binding = VERT_ATTRIB_FOG;\r
+                        break;\r
+                     case 6:\r
+                        break;\r
+                     case 7:\r
+                        break;\r
+                     default:\r
+                        *binding = VERT_ATTRIB_TEX0 + (attrib-8);\r
+                        break;\r
+                  }\r
+                  *binding_idx = attrib;\r
+               }\r
+            }\r
+            break;\r
+\r
+         default:\r
+            err = 1;\r
+            break;\r
+      }\r
+   }\r
+\r
+   /* Can this even happen? */\r
+   if (err) {\r
+      _mesa_set_program_error (ctx, Program->Position,\r
+                               "Bad attribute binding");\r
+      _mesa_error (ctx, GL_INVALID_OPERATION, "Bad attribute binding");\r
+   }\r
+\r
+   Program->InputsRead |= (1 << *binding_idx);\r
+\r
+   return err;\r
+}\r
+\r
+/**\r
+ * This translates between a binary token for an output variable type\r
+ * and the mesa token for the same thing.\r
+ *\r
+ *\r
+ * XXX: What is the 'name' for vertex program state? -> do we need it?\r
+ *         I don't think we do;\r
+ *\r
+ * See nvfragprog.h for definitions\r
+ *\r
+ * \param inst        - The parsed tokens\r
+ * \param binding     - The name of the state we are binding too\r
+ * \param binding_idx - The index into the result register file that this is bound too\r
+ *\r
+ * See nvfragparse.c for the register file layout for fragment programs\r
+ * See nvvertparse.c for the register file layout for vertex programs\r
+ */\r
+static GLuint\r
+parse_result_binding (GLcontext * ctx, GLubyte ** inst, GLuint * binding,\r
+                      GLuint * binding_idx, struct arb_program *Program)\r
+{\r
+   GLuint b;\r
+\r
+   switch (*(*inst)++) {\r
+      case FRAGMENT_RESULT_COLOR:\r
+         /* for frag programs, this is FRAGMENT_RESULT_COLOR */\r
+         if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {\r
+            *binding = FRAG_OUTPUT_COLR;\r
+            *binding_idx = 0;\r
+         }\r
+         /* for vtx programs, this is VERTEX_RESULT_POSITION */\r
+         else {\r
+            *binding_idx = 0;\r
+         }\r
+         break;\r
+\r
+      case FRAGMENT_RESULT_DEPTH:\r
+         /* for frag programs, this is FRAGMENT_RESULT_DEPTH */\r
+         if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {\r
+            *binding = FRAG_OUTPUT_DEPR;\r
+            *binding_idx = 2;\r
+         }\r
+         /* for vtx programs, this is VERTEX_RESULT_COLOR */\r
+         else {\r
+            GLint color_type;\r
+            GLuint face_type = parse_face_type(inst);\r
+           GLint color_type_ret = parse_color_type(ctx, inst, Program, &color_type);\r
+\r
+            /* back face */\r
+            if (face_type) {\r
+               if (color_type_ret) return 1;\r
+\r
+               /* secondary color */\r
+               if (color_type) {\r
+                  *binding_idx = 4;\r
+               }\r
+               /*  primary color */\r
+               else {\r
+                  *binding_idx = 3;\r
+               }\r
+            }\r
+            /* front face */\r
+            else {\r
+               /* secondary color */\r
+               if (color_type) {\r
+                  *binding_idx = 2;\r
+               }\r
+               /* primary color */\r
+               else {\r
+                  *binding_idx = 1;\r
+               }\r
+            }\r
+         }\r
+         break;\r
+\r
+      case VERTEX_RESULT_FOGCOORD:\r
+         *binding_idx = 5;\r
+         break;\r
+\r
+      case VERTEX_RESULT_POINTSIZE:\r
+         *binding_idx = 6;\r
+         break;\r
+\r
+      case VERTEX_RESULT_TEXCOORD:\r
+         if (parse_texcoord_num (ctx, inst, Program, &b))\r
+            return 1;\r
+         *binding_idx = 7 + b;\r
+         break;\r
+   }\r
+\r
+   Program->OutputsWritten |= (1 << *binding_idx);\r
+\r
+   return 0;\r
+}\r
+\r
+/**\r
+ * This handles the declaration of ATTRIB variables\r
+ *\r
+ * XXX: Still needs\r
+ *      parse_vert_attrib_binding(), or something like that\r
+ *\r
+ * \return 0 on sucess, 1 on error\r
+ */\r
+static GLint\r
+parse_attrib (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,\r
+              struct arb_program *Program)\r
+{\r
+   GLuint found;\r
+   char *error_msg;\r
+   struct var_cache *attrib_var;\r
+\r
+   attrib_var = parse_string (inst, vc_head, Program, &found);\r
+   Program->Position = parse_position (inst);\r
+   if (found) {\r
+      error_msg = (char *)\r
+         _mesa_malloc (_mesa_strlen ((char *) attrib_var->name) + 40);\r
+      _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",\r
+                     attrib_var->name);\r
+\r
+      _mesa_set_program_error (ctx, Program->Position, error_msg);\r
+      _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);\r
+\r
+      _mesa_free (error_msg);\r
+      return 1;\r
+   }\r
+\r
+   attrib_var->type = vt_attrib;\r
+\r
+   /* I think this is ok now - karl */\r
+   /* XXX: */\r
+   /*if (Program->type == GL_FRAGMENT_PROGRAM_ARB) */\r
+   {\r
+      if (parse_attrib_binding\r
+          (ctx, inst, Program, &attrib_var->attrib_binding,\r
+           &attrib_var->attrib_binding_idx, &attrib_var->attrib_is_generic))\r
+         return 1;\r
+      if (generic_attrib_check(*vc_head)) {\r
+         _mesa_set_program_error (ctx, Program->Position,\r
+   "Cannot use both a generic vertex attribute and a specific attribute of the same type");\r
+         _mesa_error (ctx, GL_INVALID_OPERATION,\r
+   "Cannot use both a generic vertex attribute and a specific attribute of the same type");\r
+         return 1;\r
+      }\r
+\r
+   }\r
+\r
+   Program->Base.NumAttributes++;\r
+   return 0;\r
+}\r
+\r
+/**\r
+ * \param use -- TRUE if we're called when declaring implicit parameters,\r
+ *               FALSE if we're declaraing variables. This has to do with\r
+ *               if we get a signed or unsigned float for scalar constants\r
+ */\r
+static GLuint\r
+parse_param_elements (GLcontext * ctx, GLubyte ** inst,\r
+                      struct var_cache *param_var,\r
+                      struct arb_program *Program, GLboolean use)\r
+{\r
+   GLint idx;\r
+   GLuint err;\r
+   GLint state_tokens[6];\r
+   GLfloat const_values[4];\r
+\r
+   err = 0;\r
+\r
+   switch (*(*inst)++) {\r
+      case PARAM_STATE_ELEMENT:\r
+\r
+         if (parse_state_single_item (ctx, inst, Program, state_tokens))\r
+            return 1;\r
+\r
+         /* If we adding STATE_MATRIX that has multiple rows, we need to\r
+          * unroll it and call _mesa_add_state_reference() for each row\r
+          */\r
+         if ((state_tokens[0] == STATE_MATRIX)\r
+             && (state_tokens[3] != state_tokens[4])) {\r
+            GLint row;\r
+            GLint first_row = state_tokens[3];\r
+            GLint last_row = state_tokens[4];\r
+\r
+            for (row = first_row; row <= last_row; row++) {\r
+               state_tokens[3] = state_tokens[4] = row;\r
+\r
+               idx =\r
+                  _mesa_add_state_reference (Program->Parameters,\r
+                                             state_tokens);\r
+               if (param_var->param_binding_begin == ~0U)\r
+                  param_var->param_binding_begin = idx;\r
+               param_var->param_binding_length++;\r
+               Program->Base.NumParameters++;\r
+            }\r
+         }\r
+         else {\r
+            idx =\r
+               _mesa_add_state_reference (Program->Parameters, state_tokens);\r
+            if (param_var->param_binding_begin == ~0U)\r
+               param_var->param_binding_begin = idx;\r
+            param_var->param_binding_length++;\r
+            Program->Base.NumParameters++;\r
+         }\r
+         break;\r
+\r
+      case PARAM_PROGRAM_ELEMENT:\r
+\r
+         if (parse_program_single_item (ctx, inst, Program, state_tokens))\r
+            return 1;\r
+         idx = _mesa_add_state_reference (Program->Parameters, state_tokens);\r
+         if (param_var->param_binding_begin == ~0U)\r
+            param_var->param_binding_begin = idx;\r
+         param_var->param_binding_length++;\r
+         Program->Base.NumParameters++;\r
+\r
+         /* Check if there is more: 0 -> we're done, else its an integer */\r
+         if (**inst) {\r
+            GLuint out_of_range, new_idx;\r
+            GLuint start_idx = state_tokens[2] + 1;\r
+            GLuint end_idx = parse_integer (inst, Program);\r
+\r
+            out_of_range = 0;\r
+            if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {\r
+               if (((state_tokens[1] == STATE_ENV)\r
+                    && (end_idx >= ctx->Const.MaxFragmentProgramEnvParams))\r
+                   || ((state_tokens[1] == STATE_LOCAL)\r
+                       && (end_idx >=\r
+                           ctx->Const.MaxFragmentProgramLocalParams)))\r
+                  out_of_range = 1;\r
+            }\r
+            else {\r
+               if (((state_tokens[1] == STATE_ENV)\r
+                    && (end_idx >= ctx->Const.MaxVertexProgramEnvParams))\r
+                   || ((state_tokens[1] == STATE_LOCAL)\r
+                       && (end_idx >=\r
+                           ctx->Const.MaxVertexProgramLocalParams)))\r
+                  out_of_range = 1;\r
+            }\r
+            if (out_of_range) {\r
+               _mesa_set_program_error (ctx, Program->Position,\r
+                                        "Invalid Program Parameter");\r
+               _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                            "Invalid Program Parameter: %d", end_idx);\r
+               return 1;\r
+            }\r
+\r
+            for (new_idx = start_idx; new_idx <= end_idx; new_idx++) {\r
+               state_tokens[2] = new_idx;\r
+               idx =\r
+                  _mesa_add_state_reference (Program->Parameters,\r
+                                             state_tokens);\r
+               param_var->param_binding_length++;\r
+               Program->Base.NumParameters++;\r
+            }\r
+         }\r
+                       else\r
+                       {\r
+                               (*inst)++;\r
+                       }\r
+         break;\r
+\r
+      case PARAM_CONSTANT:\r
+         parse_constant (inst, const_values, Program, use);\r
+         idx =\r
+            _mesa_add_named_constant (Program->Parameters,\r
+                                      (char *) param_var->name, const_values);\r
+         if (param_var->param_binding_begin == ~0U)\r
+            param_var->param_binding_begin = idx;\r
+         param_var->param_binding_length++;\r
+         Program->Base.NumParameters++;\r
+         break;\r
+\r
+      default:\r
+         _mesa_set_program_error (ctx, Program->Position,\r
+                                  "Unexpected token in parse_param_elements()");\r
+         _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                      "Unexpected token in parse_param_elements()");\r
+         return 1;\r
+   }\r
+\r
+   /* Make sure we haven't blown past our parameter limits */\r
+   if (((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) &&\r
+        (Program->Base.NumParameters >=\r
+         ctx->Const.MaxVertexProgramLocalParams))\r
+       || ((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB)\r
+           && (Program->Base.NumParameters >=\r
+               ctx->Const.MaxFragmentProgramLocalParams))) {\r
+      _mesa_set_program_error (ctx, Program->Position,\r
+                               "Too many parameter variables");\r
+      _mesa_error (ctx, GL_INVALID_OPERATION, "Too many parameter variables");\r
+      return 1;\r
+   }\r
+\r
+   return err;\r
+}\r
+\r
+/**\r
+ * This picks out PARAM program parameter bindings.\r
+ *\r
+ * XXX: This needs to be stressed & tested\r
+ *\r
+ * \return 0 on sucess, 1 on error\r
+ */\r
+static GLuint\r
+parse_param (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,\r
+             struct arb_program *Program)\r
+{\r
+   GLuint found, specified_length, err;\r
+   char *error_msg;\r
+   struct var_cache *param_var;\r
+\r
+   err = 0;\r
+   param_var = parse_string (inst, vc_head, Program, &found);\r
+   Program->Position = parse_position (inst);\r
+\r
+   if (found) {\r
+      error_msg = (char *) _mesa_malloc (_mesa_strlen ((char *) param_var->name) + 40);\r
+      _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",\r
+                     param_var->name);\r
+\r
+      _mesa_set_program_error (ctx, Program->Position, error_msg);\r
+      _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);\r
+\r
+      _mesa_free (error_msg);\r
+      return 1;\r
+   }\r
+\r
+   specified_length = parse_integer (inst, Program);\r
+\r
+   if (specified_length < 0) {\r
+      _mesa_set_program_error (ctx, Program->Position,\r
+                               "Negative parameter array length");\r
+      _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                   "Negative parameter array length: %d", specified_length);\r
+      return 1;\r
+   }\r
+\r
+   param_var->type = vt_param;\r
+   param_var->param_binding_length = 0;\r
+\r
+   /* Right now, everything is shoved into the main state register file.\r
+    *\r
+    * In the future, it would be nice to leave things ENV/LOCAL params\r
+    * in their respective register files, if possible\r
+    */\r
+   param_var->param_binding_type = PROGRAM_STATE_VAR;\r
+\r
+   /* Remember to:\r
+    * *   - add each guy to the parameter list\r
+    * *   - increment the param_var->param_binding_len\r
+    * *   - store the param_var->param_binding_begin for the first one\r
+    * *   - compare the actual len to the specified len at the end\r
+    */\r
+   while (**inst != PARAM_NULL) {\r
+      if (parse_param_elements (ctx, inst, param_var, Program, GL_FALSE))\r
+         return 1;\r
+   }\r
+\r
+   /* Test array length here! */\r
+   if (specified_length) {\r
+      if (specified_length != param_var->param_binding_length) {\r
+         _mesa_set_program_error (ctx, Program->Position,\r
+                                  "Declared parameter array lenght does not match parameter list");\r
+         _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                      "Declared parameter array lenght does not match parameter list");\r
+      }\r
+   }\r
+\r
+   (*inst)++;\r
+\r
+   return 0;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+static GLuint\r
+parse_param_use (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,\r
+                 struct arb_program *Program, struct var_cache **new_var)\r
+{\r
+   struct var_cache *param_var;\r
+\r
+   /* First, insert a dummy entry into the var_cache */\r
+   var_cache_create (&param_var);\r
+   param_var->name = (GLubyte *) _mesa_strdup (" ");\r
+   param_var->type = vt_param;\r
+\r
+   param_var->param_binding_length = 0;\r
+   /* Don't fill in binding_begin; We use the default value of -1\r
+    * to tell if its already initialized, elsewhere.\r
+    *\r
+    * param_var->param_binding_begin  = 0;\r
+    */\r
+   param_var->param_binding_type = PROGRAM_STATE_VAR;\r
+\r
+   var_cache_append (vc_head, param_var);\r
+\r
+   /* Then fill it with juicy parameter goodness */\r
+   if (parse_param_elements (ctx, inst, param_var, Program, GL_TRUE))\r
+      return 1;\r
+\r
+   *new_var = param_var;\r
+\r
+   return 0;\r
+}\r
+\r
+\r
+/**\r
+ * This handles the declaration of TEMP variables\r
+ *\r
+ * \return 0 on sucess, 1 on error\r
+ */\r
+static GLuint\r
+parse_temp (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,\r
+            struct arb_program *Program)\r
+{\r
+   GLuint found;\r
+   struct var_cache *temp_var;\r
+   char *error_msg;\r
+\r
+   while (**inst != 0) {\r
+      temp_var = parse_string (inst, vc_head, Program, &found);\r
+      Program->Position = parse_position (inst);\r
+      if (found) {\r
+         error_msg = (char *)\r
+            _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);\r
+         _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",\r
+                        temp_var->name);\r
+\r
+         _mesa_set_program_error (ctx, Program->Position, error_msg);\r
+         _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);\r
+\r
+         _mesa_free (error_msg);\r
+         return 1;\r
+      }\r
+\r
+      temp_var->type = vt_temp;\r
+\r
+      if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) &&\r
+           (Program->Base.NumTemporaries >=\r
+            ctx->Const.MaxFragmentProgramTemps))\r
+          || ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB)\r
+              && (Program->Base.NumTemporaries >=\r
+                  ctx->Const.MaxVertexProgramTemps))) {\r
+         _mesa_set_program_error (ctx, Program->Position,\r
+                                  "Too many TEMP variables declared");\r
+         _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                      "Too many TEMP variables declared");\r
+         return 1;\r
+      }\r
+\r
+      temp_var->temp_binding = Program->Base.NumTemporaries;\r
+      Program->Base.NumTemporaries++;\r
+   }\r
+   (*inst)++;\r
+\r
+   return 0;\r
+}\r
+\r
+/**\r
+ * This handles variables of the OUTPUT variety\r
+ *\r
+ * \return 0 on sucess, 1 on error\r
+ */\r
+static GLuint\r
+parse_output (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,\r
+              struct arb_program *Program)\r
+{\r
+   GLuint found;\r
+   struct var_cache *output_var;\r
+\r
+   output_var = parse_string (inst, vc_head, Program, &found);\r
+   Program->Position = parse_position (inst);\r
+   if (found) {\r
+      char *error_msg;\r
+      error_msg = (char *)\r
+         _mesa_malloc (_mesa_strlen ((char *) output_var->name) + 40);\r
+      _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",\r
+                     output_var->name);\r
+\r
+      _mesa_set_program_error (ctx, Program->Position, error_msg);\r
+      _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);\r
+\r
+      _mesa_free (error_msg);\r
+      return 1;\r
+   }\r
+\r
+   output_var->type = vt_output;\r
+   return parse_result_binding (ctx, inst, &output_var->output_binding,\r
+                                &output_var->output_binding_idx, Program);\r
+}\r
+\r
+/**\r
+ * This handles variables of the ALIAS kind\r
+ *\r
+ * \return 0 on sucess, 1 on error\r
+ */\r
+static GLuint\r
+parse_alias (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,\r
+             struct arb_program *Program)\r
+{\r
+   GLuint found;\r
+   struct var_cache *temp_var;\r
+   char *error_msg;\r
+\r
+\r
+   temp_var = parse_string (inst, vc_head, Program, &found);\r
+   Program->Position = parse_position (inst);\r
+\r
+   if (found) {\r
+      error_msg = (char *)\r
+         _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);\r
+      _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",\r
+                     temp_var->name);\r
+\r
+      _mesa_set_program_error (ctx, Program->Position, error_msg);\r
+      _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);\r
+\r
+      _mesa_free (error_msg);\r
+      return 1;\r
+   }\r
+\r
+   temp_var->type = vt_alias;\r
+   temp_var->alias_binding =  parse_string (inst, vc_head, Program, &found);\r
+   Program->Position = parse_position (inst);\r
+\r
+   if (!found)\r
+   {\r
+      error_msg = (char *)\r
+         _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);\r
+      _mesa_sprintf (error_msg, "Alias value %s is not defined",\r
+                     temp_var->alias_binding->name);\r
+\r
+      _mesa_set_program_error (ctx, Program->Position, error_msg);\r
+      _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);\r
+\r
+      _mesa_free (error_msg);\r
+      return 1;\r
+   }\r
+\r
+   return 0;\r
+}\r
+\r
+/**\r
+ * This handles variables of the ADDRESS kind\r
+ *\r
+ * \return 0 on sucess, 1 on error\r
+ */\r
+static GLuint\r
+parse_address (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,\r
+               struct arb_program *Program)\r
+{\r
+   GLuint found;\r
+   struct var_cache *temp_var;\r
+   char *error_msg;\r
+\r
+   while (**inst != 0) {\r
+      temp_var = parse_string (inst, vc_head, Program, &found);\r
+      Program->Position = parse_position (inst);\r
+      if (found) {\r
+         error_msg = (char *)\r
+            _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);\r
+         _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",\r
+                        temp_var->name);\r
+\r
+         _mesa_set_program_error (ctx, Program->Position, error_msg);\r
+         _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);\r
+\r
+         _mesa_free (error_msg);\r
+         return 1;\r
+      }\r
+\r
+      temp_var->type = vt_address;\r
+\r
+      if (Program->Base.NumAddressRegs >=\r
+          ctx->Const.MaxVertexProgramAddressRegs) {\r
+         _mesa_set_program_error (ctx, Program->Position,\r
+                                  "Too many ADDRESS variables declared");\r
+         _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                      "Too many ADDRESS variables declared");\r
+         return 1;\r
+      }\r
+\r
+      temp_var->address_binding = Program->Base.NumAddressRegs;\r
+      Program->Base.NumAddressRegs++;\r
+   }\r
+   (*inst)++;\r
+\r
+   return 0;\r
+}\r
+\r
+/**\r
+ * Parse a program declaration\r
+ *\r
+ * \return 0 on sucess, 1 on error\r
+ */\r
+static GLint\r
+parse_declaration (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,\r
+                   struct arb_program *Program)\r
+{\r
+   GLint err = 0;\r
+\r
+   switch (*(*inst)++) {\r
+      case ADDRESS:\r
+         err = parse_address (ctx, inst, vc_head, Program);\r
+         break;\r
+\r
+      case ALIAS:\r
+         err = parse_alias (ctx, inst, vc_head, Program);\r
+         break;\r
+\r
+      case ATTRIB:\r
+         err = parse_attrib (ctx, inst, vc_head, Program);\r
+         break;\r
+\r
+      case OUTPUT:\r
+         err = parse_output (ctx, inst, vc_head, Program);\r
+         break;\r
+\r
+      case PARAM:\r
+         err = parse_param (ctx, inst, vc_head, Program);\r
+         break;\r
+\r
+      case TEMP:\r
+         err = parse_temp (ctx, inst, vc_head, Program);\r
+         break;\r
+   }\r
+\r
+   return err;\r
+}\r
+\r
+/**\r
+ * Handle the parsing out of a masked destination register\r
+ *\r
+ * If we are a vertex program, make sure we don't write to\r
+ * result.position of we have specified that the program is\r
+ * position invariant\r
+ *\r
+ * \param File      - The register file we write to\r
+ * \param Index     - The register index we write to\r
+ * \param WriteMask - The mask controlling which components we write (1->write)\r
+ *\r
+ * \return 0 on sucess, 1 on error\r
+ */\r
+static GLuint\r
+parse_masked_dst_reg (GLcontext * ctx, GLubyte ** inst,\r
+                      struct var_cache **vc_head, struct arb_program *Program,\r
+                      GLint * File, GLint * Index, GLboolean * WriteMask)\r
+{\r
+   GLuint result;\r
+   GLubyte mask;\r
+   struct var_cache *dst;\r
+\r
+   /* We either have a result register specified, or a\r
+    * variable that may or may not be writable\r
+    */\r
+   switch (*(*inst)++) {\r
+      case REGISTER_RESULT:\r
+         if (parse_result_binding\r
+             (ctx, inst, &result, (GLuint *) Index, Program))\r
+            return 1;\r
+         *File = PROGRAM_OUTPUT;\r
+         break;\r
+\r
+      case REGISTER_ESTABLISHED_NAME:\r
+         dst = parse_string (inst, vc_head, Program, &result);\r
+         Program->Position = parse_position (inst);\r
+\r
+         /* If the name has never been added to our symbol table, we're hosed */\r
+         if (!result) {\r
+            _mesa_set_program_error (ctx, Program->Position,\r
+                                     "0: Undefined variable");\r
+            _mesa_error (ctx, GL_INVALID_OPERATION, "0: Undefined variable: %s",\r
+                         dst->name);\r
+            return 1;\r
+         }\r
+\r
+         switch (dst->type) {\r
+            case vt_output:\r
+               *File = PROGRAM_OUTPUT;\r
+               *Index = dst->output_binding_idx;\r
+               break;\r
+\r
+            case vt_temp:\r
+               *File = PROGRAM_TEMPORARY;\r
+               *Index = dst->temp_binding;\r
+               break;\r
+\r
+               /* If the var type is not vt_output or vt_temp, no go */\r
+            default:\r
+               _mesa_set_program_error (ctx, Program->Position,\r
+                                        "Destination register is read only");\r
+               _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                            "Destination register is read only: %s",\r
+                            dst->name);\r
+               return 1;\r
+         }\r
+         break;\r
+\r
+      default:\r
+         _mesa_set_program_error (ctx, Program->Position,\r
+                                  "Unexpected opcode in parse_masked_dst_reg()");\r
+         _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                      "Unexpected opcode in parse_masked_dst_reg()");\r
+         return 1;\r
+   }\r
+\r
+\r
+   /* Position invariance test */\r
+   /* This test is done now in syntax portion - when position invariance OPTION\r
+      is specified, "result.position" rule is disabled so there is no way\r
+      to write the position\r
+   */\r
+   /*if ((Program->HintPositionInvariant) && (*File == PROGRAM_OUTPUT) &&\r
+      (*Index == 0))   {\r
+      _mesa_set_program_error (ctx, Program->Position,\r
+                  "Vertex program specified position invariance and wrote vertex position");\r
+      _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                  "Vertex program specified position invariance and wrote vertex position");\r
+   }*/\r
+\r
+   /* And then the mask.\r
+    *  w,a -> bit 0\r
+    *  z,b -> bit 1\r
+    *  y,g -> bit 2\r
+    *  x,r -> bit 3\r
+    */\r
+   mask = *(*inst)++;\r
+\r
+   WriteMask[0] = (GLboolean) (mask & (1 << 3)) >> 3;\r
+   WriteMask[1] = (GLboolean) (mask & (1 << 2)) >> 2;\r
+   WriteMask[2] = (GLboolean) (mask & (1 << 1)) >> 1;\r
+   WriteMask[3] = (GLboolean) (mask & (1));\r
+\r
+   return 0;\r
+}\r
+\r
+\r
+/**\r
+ * Handle the parsing of a address register\r
+ *\r
+ * \param Index     - The register index we write to\r
+ *\r
+ * \return 0 on sucess, 1 on error\r
+ */\r
+static GLuint\r
+parse_address_reg (GLcontext * ctx, GLubyte ** inst,\r
+                          struct var_cache **vc_head,\r
+                          struct arb_program *Program, GLint * Index)\r
+{\r
+   struct var_cache *dst;\r
+   GLuint result;\r
+\r
+   dst = parse_string (inst, vc_head, Program, &result);\r
+   Program->Position = parse_position (inst);\r
+\r
+   /* If the name has never been added to our symbol table, we're hosed */\r
+   if (!result) {\r
+      _mesa_set_program_error (ctx, Program->Position, "Undefined variable");\r
+      _mesa_error (ctx, GL_INVALID_OPERATION, "Undefined variable: %s",\r
+                   dst->name);\r
+      return 1;\r
+   }\r
+\r
+   if (dst->type != vt_address) {\r
+      _mesa_set_program_error (ctx, Program->Position,\r
+                               "Variable is not of type ADDRESS");\r
+      _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                   "Variable: %s is not of type ADDRESS", dst->name);\r
+      return 1;\r
+   }\r
+\r
+   return 0;\r
+}\r
+\r
+/**\r
+ * Handle the parsing out of a masked address register\r
+ *\r
+ * \param Index     - The register index we write to\r
+ * \param WriteMask - The mask controlling which components we write (1->write)\r
+ *\r
+ * \return 0 on sucess, 1 on error\r
+ */\r
+static GLuint\r
+parse_masked_address_reg (GLcontext * ctx, GLubyte ** inst,\r
+                          struct var_cache **vc_head,\r
+                          struct arb_program *Program, GLint * Index,\r
+                          GLboolean * WriteMask)\r
+{\r
+   if (parse_address_reg (ctx, inst, vc_head, Program, Index))\r
+      return 1;\r
+\r
+   /* This should be 0x8 */\r
+   (*inst)++;\r
+\r
+   /* Writemask of .x is implied */\r
+   WriteMask[0] = 1;\r
+   WriteMask[1] = WriteMask[2] = WriteMask[3] = 0;\r
+\r
+   return 0;\r
+}\r
+\r
+\r
+/**\r
+ * Parse out a swizzle mask.\r
+ *\r
+ * The values in the input stream are:\r
+ *   COMPONENT_X -> x/r\r
+ *   COMPONENT_Y -> y/g\r
+ *   COMPONENT_Z-> z/b\r
+ *   COMPONENT_W-> w/a\r
+ *\r
+ * The values in the output mask are:\r
+ *   0 -> x/r\r
+ *   1 -> y/g\r
+ *   2 -> z/b\r
+ *   3 -> w/a\r
+ *\r
+ * The len parameter allows us to grab 4 components for a vector\r
+ * swizzle, or just 1 component for a scalar src register selection\r
+ */\r
+static GLuint\r
+parse_swizzle_mask (GLubyte ** inst, GLubyte * mask, GLint len)\r
+{\r
+   GLint a;\r
+\r
+   for (a = 0; a < 4; a++)\r
+      mask[a] = a;\r
+\r
+   for (a = 0; a < len; a++) {\r
+      switch (*(*inst)++) {\r
+         case COMPONENT_X:\r
+            mask[a] = 0;\r
+            break;\r
+\r
+         case COMPONENT_Y:\r
+            mask[a] = 1;\r
+            break;\r
+\r
+         case COMPONENT_Z:\r
+            mask[a] = 2;\r
+            break;\r
+\r
+         case COMPONENT_W:\r
+            mask[a] = 3;\r
+            break;\r
+      }\r
+   }\r
+\r
+   return 0;\r
+}\r
+\r
+/**\r
+ */\r
+static GLuint\r
+parse_extended_swizzle_mask (GLubyte ** inst, GLubyte * mask, GLboolean * Negate)\r
+{\r
+   GLint a;\r
+   GLubyte swz;\r
+\r
+   *Negate = GL_FALSE;\r
+   for (a = 0; a < 4; a++) {\r
+      if (parse_sign (inst))\r
+         *Negate = GL_TRUE;\r
+\r
+      swz = *(*inst)++;\r
+\r
+      switch (swz) {\r
+         case COMPONENT_0:\r
+            mask[a] = SWIZZLE_ZERO;\r
+            break;\r
+         case COMPONENT_1:\r
+            mask[a] = SWIZZLE_ONE;\r
+            break;\r
+         case COMPONENT_X:\r
+            mask[a] = SWIZZLE_X;\r
+            break;\r
+         case COMPONENT_Y:\r
+            mask[a] = SWIZZLE_Y;\r
+            break;\r
+         case COMPONENT_Z:\r
+            mask[a] = SWIZZLE_Z;\r
+            break;\r
+         case COMPONENT_W:\r
+            mask[a] = SWIZZLE_W;\r
+            break;\r
+\r
+      }\r
+#if 0\r
+      if (swz == 0)\r
+         mask[a] = SWIZZLE_ZERO;\r
+      else if (swz == 1)\r
+         mask[a] = SWIZZLE_ONE;\r
+      else\r
+         mask[a] = swz - 2;\r
+#endif\r
+\r
+   }\r
+\r
+   return 0;\r
+}\r
+\r
+\r
+static GLuint\r
+parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,\r
+               struct arb_program *Program, GLint * File, GLint * Index,\r
+               GLboolean *IsRelOffset )\r
+{\r
+   struct var_cache *src;\r
+   GLuint binding_state, binding_idx, is_generic, found, offset;\r
+\r
+   /* And the binding for the src */\r
+   switch (*(*inst)++) {\r
+      case REGISTER_ATTRIB:\r
+         if (parse_attrib_binding\r
+             (ctx, inst, Program, &binding_state, &binding_idx, &is_generic))\r
+            return 1;\r
+         *File = PROGRAM_INPUT;\r
+         *Index = binding_idx;\r
+\r
+         /* We need to insert a dummy variable into the var_cache so we can\r
+          * catch generic vertex attrib aliasing errors\r
+          */\r
+         var_cache_create(&src);\r
+         src->type = vt_attrib;\r
+         src->name = (GLubyte *)_mesa_strdup("Dummy Attrib Variable");\r
+         src->attrib_binding     = binding_state;\r
+         src->attrib_binding_idx = binding_idx;\r
+         src->attrib_is_generic  = is_generic;\r
+         var_cache_append(vc_head, src);\r
+         if (generic_attrib_check(*vc_head)) {\r
+            _mesa_set_program_error (ctx, Program->Position,\r
+   "Cannot use both a generic vertex attribute and a specific attribute of the same type");\r
+            _mesa_error (ctx, GL_INVALID_OPERATION,\r
+   "Cannot use both a generic vertex attribute and a specific attribute of the same type");\r
+            return 1;\r
+         }\r
+         break;\r
+\r
+      case REGISTER_PARAM:\r
+         switch (**inst) {\r
+            case PARAM_ARRAY_ELEMENT:\r
+               (*inst)++;\r
+               src = parse_string (inst, vc_head, Program, &found);\r
+               Program->Position = parse_position (inst);\r
+\r
+               if (!found) {\r
+                  _mesa_set_program_error (ctx, Program->Position,\r
+                                           "2: Undefined variable");\r
+                  _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                               "2: Undefined variable: %s", src->name);\r
+                  return 1;\r
+               }\r
+\r
+               *File = src->param_binding_type;\r
+\r
+               switch (*(*inst)++) {\r
+                  case ARRAY_INDEX_ABSOLUTE:\r
+                     offset = parse_integer (inst, Program);\r
+\r
+                     if ((offset < 0)\r
+                         || (offset >= src->param_binding_length)) {\r
+                        _mesa_set_program_error (ctx, Program->Position,\r
+                                                 "Index out of range");\r
+                        _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                                     "Index %d out of range for %s", offset,\r
+                                     src->name);\r
+                        return 1;\r
+                     }\r
+\r
+                     *Index = src->param_binding_begin + offset;\r
+                     break;\r
+\r
+                  case ARRAY_INDEX_RELATIVE:\r
+                     {\r
+                        GLint addr_reg_idx, rel_off;\r
+\r
+                        /* First, grab the address regiseter */\r
+                        if (parse_address_reg (ctx, inst, vc_head, Program, &addr_reg_idx))\r
+                           return 1;\r
+\r
+                        /* And the .x */\r
+                        ((*inst)++);\r
+                        ((*inst)++);\r
+                        ((*inst)++);\r
+                        ((*inst)++);\r
+\r
+                        /* Then the relative offset */\r
+                        if (parse_relative_offset(ctx, inst, Program, &rel_off)) return 1;\r
+\r
+                        /* And store it properly */\r
+                        *Index = src->param_binding_begin + rel_off;\r
+                        *IsRelOffset = 1;\r
+                     }\r
+                     break;\r
+               }\r
+               break;\r
+\r
+            default:\r
+\r
+               if (parse_param_use (ctx, inst, vc_head, Program, &src))\r
+                  return 1;\r
+\r
+               *File = src->param_binding_type;\r
+               *Index = src->param_binding_begin;\r
+               break;\r
+         }\r
+         break;\r
+\r
+      case REGISTER_ESTABLISHED_NAME:\r
+\r
+         src = parse_string (inst, vc_head, Program, &found);\r
+         Program->Position = parse_position (inst);\r
+\r
+         /* If the name has never been added to our symbol table, we're hosed */\r
+         if (!found) {\r
+            _mesa_set_program_error (ctx, Program->Position,\r
+                                     "3: Undefined variable");\r
+            _mesa_error (ctx, GL_INVALID_OPERATION, "3: Undefined variable: %s",\r
+                         src->name);\r
+            return 1;\r
+         }\r
+\r
+         switch (src->type) {\r
+            case vt_attrib:\r
+               *File = PROGRAM_INPUT;\r
+               *Index = src->attrib_binding_idx;\r
+               break;\r
+\r
+               /* XXX: We have to handle offsets someplace in here!  -- or are those above? */\r
+            case vt_param:\r
+               *File = src->param_binding_type;\r
+               *Index = src->param_binding_begin;\r
+               break;\r
+\r
+            case vt_temp:\r
+               *File = PROGRAM_TEMPORARY;\r
+               *Index = src->temp_binding;\r
+               break;\r
+\r
+               /* If the var type is vt_output no go */\r
+            default:\r
+               _mesa_set_program_error (ctx, Program->Position,\r
+                                        "destination register is read only");\r
+               _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                            "destination register is read only: %s",\r
+                            src->name);\r
+               return 1;\r
+         }\r
+         break;\r
+\r
+      default:\r
+         _mesa_set_program_error (ctx, Program->Position,\r
+                                  "Unknown token in parse_src_reg");\r
+         _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                      "Unknown token in parse_src_reg");\r
+         return 1;\r
+   }\r
+\r
+   return 0;\r
+}\r
+\r
+/**\r
+ */\r
+static GLuint\r
+parse_vector_src_reg (GLcontext * ctx, GLubyte ** inst,\r
+                      struct var_cache **vc_head, struct arb_program *Program,\r
+                      GLint * File, GLint * Index, GLboolean * Negate,\r
+                      GLubyte * Swizzle, GLboolean *IsRelOffset)\r
+{\r
+   /* Grab the sign */\r
+   *Negate = parse_sign (inst);\r
+\r
+   /* And the src reg */\r
+   if (parse_src_reg (ctx, inst, vc_head, Program, File, Index, IsRelOffset))\r
+      return 1;\r
+\r
+   /* finally, the swizzle */\r
+   parse_swizzle_mask (inst, Swizzle, 4);\r
+\r
+   return 0;\r
+}\r
+\r
+/**\r
+ */\r
+static GLuint\r
+parse_scalar_src_reg (GLcontext * ctx, GLubyte ** inst,\r
+                      struct var_cache **vc_head, struct arb_program *Program,\r
+                      GLint * File, GLint * Index, GLboolean * Negate,\r
+                      GLubyte * Swizzle, GLboolean *IsRelOffset)\r
+{\r
+   /* Grab the sign */\r
+   *Negate = parse_sign (inst);\r
+\r
+   /* And the src reg */\r
+   if (parse_src_reg (ctx, inst, vc_head, Program, File, Index, IsRelOffset))\r
+      return 1;\r
+\r
+   /* Now, get the component and shove it into all the swizzle slots  */\r
+   parse_swizzle_mask (inst, Swizzle, 1);\r
+\r
+   return 0;\r
+}\r
+\r
+/**\r
+ * This is a big mother that handles getting opcodes into the instruction\r
+ * and handling the src & dst registers for fragment program instructions\r
+ */\r
+static GLuint\r
+parse_fp_instruction (GLcontext * ctx, GLubyte ** inst,\r
+                      struct var_cache **vc_head, struct arb_program *Program,\r
+                      struct fp_instruction *fp)\r
+{\r
+   GLint a, b;\r
+   GLubyte swz[4]; /* FP's swizzle mask is a GLubyte, while VP's is GLuint */\r
+   GLuint texcoord;\r
+   GLubyte instClass, type, code;\r
+   GLboolean rel;\r
+\r
+   /* No condition codes in ARB_fp */\r
+   fp->UpdateCondRegister = 0;\r
+\r
+   /* Record the position in the program string for debugging */\r
+   fp->StringPos = Program->Position;\r
+\r
+   /* OP_ALU_INST or OP_TEX_INST */\r
+   instClass = *(*inst)++;\r
+\r
+   /* OP_ALU_{VECTOR, SCALAR, BINSC, BIN, TRI, SWZ},\r
+    * OP_TEX_{SAMPLE, KIL}\r
+    */\r
+   type = *(*inst)++;\r
+\r
+   /* The actual opcode name */\r
+   code = *(*inst)++;\r
+\r
+   /* Increment the correct count */\r
+   switch (instClass) {\r
+      case OP_ALU_INST:\r
+         Program->NumAluInstructions++;\r
+         break;\r
+      case OP_TEX_INST:\r
+         Program->NumTexInstructions++;\r
+         break;\r
+   }\r
+\r
+   fp->Saturate = 0;\r
+   fp->Precision = FLOAT32;\r
+\r
+   fp->DstReg.CondMask = COND_TR;\r
+\r
+   switch (type) {\r
+      case OP_ALU_VECTOR:\r
+         switch (code) {\r
+            case OP_ABS_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_ABS:\r
+               fp->Opcode = FP_OPCODE_ABS;\r
+               break;\r
+\r
+            case OP_FLR_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_FLR:\r
+               fp->Opcode = FP_OPCODE_FLR;\r
+               break;\r
+\r
+            case OP_FRC_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_FRC:\r
+               fp->Opcode = FP_OPCODE_FRC;\r
+               break;\r
+\r
+            case OP_LIT_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_LIT:\r
+               fp->Opcode = FP_OPCODE_LIT;\r
+               break;\r
+\r
+            case OP_MOV_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_MOV:\r
+               fp->Opcode = FP_OPCODE_MOV;\r
+               break;\r
+         }\r
+\r
+         if (parse_masked_dst_reg\r
+             (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,\r
+              &fp->DstReg.Index, fp->DstReg.WriteMask))\r
+            return 1;\r
+\r
+         fp->SrcReg[0].Abs = GL_FALSE;\r
+         fp->SrcReg[0].NegateAbs = GL_FALSE;\r
+         if (parse_vector_src_reg\r
+             (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,\r
+              &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,\r
+              swz, &rel))\r
+            return 1;\r
+         for (b=0; b<4; b++)\r
+            fp->SrcReg[0].Swizzle[b] = swz[b];\r
+         break;\r
+\r
+      case OP_ALU_SCALAR:\r
+         switch (code) {\r
+            case OP_COS_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_COS:\r
+               fp->Opcode = FP_OPCODE_COS;\r
+               break;\r
+\r
+            case OP_EX2_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_EX2:\r
+               fp->Opcode = FP_OPCODE_EX2;\r
+               break;\r
+\r
+            case OP_LG2_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_LG2:\r
+               fp->Opcode = FP_OPCODE_LG2;\r
+               break;\r
+\r
+            case OP_RCP_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_RCP:\r
+               fp->Opcode = FP_OPCODE_RCP;\r
+               break;\r
+\r
+            case OP_RSQ_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_RSQ:\r
+               fp->Opcode = FP_OPCODE_RSQ;\r
+               break;\r
+\r
+            case OP_SIN_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_SIN:\r
+               fp->Opcode = FP_OPCODE_SIN;\r
+               break;\r
+\r
+            case OP_SCS_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_SCS:\r
+\r
+               fp->Opcode = FP_OPCODE_SCS;\r
+               break;\r
+         }\r
+\r
+         if (parse_masked_dst_reg\r
+             (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,\r
+              &fp->DstReg.Index, fp->DstReg.WriteMask))\r
+            return 1;\r
+         fp->SrcReg[0].Abs = GL_FALSE;\r
+         fp->SrcReg[0].NegateAbs = GL_FALSE;\r
+         if (parse_scalar_src_reg\r
+             (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,\r
+              &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,\r
+              swz, &rel))\r
+            return 1;\r
+         for (b=0; b<4; b++)\r
+            fp->SrcReg[0].Swizzle[b] = swz[b];\r
+         break;\r
+\r
+      case OP_ALU_BINSC:\r
+         switch (code) {\r
+            case OP_POW_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_POW:\r
+               fp->Opcode = FP_OPCODE_POW;\r
+               break;\r
+         }\r
+\r
+         if (parse_masked_dst_reg\r
+             (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,\r
+              &fp->DstReg.Index, fp->DstReg.WriteMask))\r
+            return 1;\r
+         for (a = 0; a < 2; a++) {\r
+            fp->SrcReg[a].Abs = GL_FALSE;\r
+            fp->SrcReg[a].NegateAbs = GL_FALSE;\r
+            if (parse_scalar_src_reg\r
+                (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File,\r
+                 &fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase,\r
+                 swz, &rel))\r
+               return 1;\r
+            for (b=0; b<4; b++)\r
+               fp->SrcReg[a].Swizzle[b] = swz[b];\r
+         }\r
+         break;\r
+\r
+\r
+      case OP_ALU_BIN:\r
+         switch (code) {\r
+            case OP_ADD_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_ADD:\r
+               fp->Opcode = FP_OPCODE_ADD;\r
+               break;\r
+\r
+            case OP_DP3_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_DP3:\r
+               fp->Opcode = FP_OPCODE_DP3;\r
+               break;\r
+\r
+            case OP_DP4_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_DP4:\r
+               fp->Opcode = FP_OPCODE_DP4;\r
+               break;\r
+\r
+            case OP_DPH_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_DPH:\r
+               fp->Opcode = FP_OPCODE_DPH;\r
+               break;\r
+\r
+            case OP_DST_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_DST:\r
+               fp->Opcode = FP_OPCODE_DST;\r
+               break;\r
+\r
+            case OP_MAX_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_MAX:\r
+               fp->Opcode = FP_OPCODE_MAX;\r
+               break;\r
+\r
+            case OP_MIN_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_MIN:\r
+               fp->Opcode = FP_OPCODE_MIN;\r
+               break;\r
+\r
+            case OP_MUL_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_MUL:\r
+               fp->Opcode = FP_OPCODE_MUL;\r
+               break;\r
+\r
+            case OP_SGE_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_SGE:\r
+               fp->Opcode = FP_OPCODE_SGE;\r
+               break;\r
+\r
+            case OP_SLT_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_SLT:\r
+               fp->Opcode = FP_OPCODE_SLT;\r
+               break;\r
+\r
+            case OP_SUB_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_SUB:\r
+               fp->Opcode = FP_OPCODE_SUB;\r
+               break;\r
+\r
+            case OP_XPD_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_XPD:\r
+               fp->Opcode = FP_OPCODE_XPD;\r
+               break;\r
+         }\r
+\r
+         if (parse_masked_dst_reg\r
+             (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,\r
+              &fp->DstReg.Index, fp->DstReg.WriteMask))\r
+            return 1;\r
+         for (a = 0; a < 2; a++) {\r
+            fp->SrcReg[a].Abs = GL_FALSE;\r
+            fp->SrcReg[a].NegateAbs = GL_FALSE;\r
+            if (parse_vector_src_reg\r
+                (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File,\r
+                 &fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase,\r
+                 swz, &rel))\r
+               return 1;\r
+            for (b=0; b<4; b++)\r
+               fp->SrcReg[a].Swizzle[b] = swz[b];\r
+         }\r
+         break;\r
+\r
+      case OP_ALU_TRI:\r
+         switch (code) {\r
+            case OP_CMP_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_CMP:\r
+               fp->Opcode = FP_OPCODE_CMP;\r
+               break;\r
+\r
+            case OP_LRP_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_LRP:\r
+               fp->Opcode = FP_OPCODE_LRP;\r
+               break;\r
+\r
+            case OP_MAD_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_MAD:\r
+               fp->Opcode = FP_OPCODE_MAD;\r
+               break;\r
+         }\r
+\r
+         if (parse_masked_dst_reg\r
+             (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,\r
+              &fp->DstReg.Index, fp->DstReg.WriteMask))\r
+            return 1;\r
+         for (a = 0; a < 3; a++) {\r
+            fp->SrcReg[a].Abs = GL_FALSE;\r
+            fp->SrcReg[a].NegateAbs = GL_FALSE;\r
+            if (parse_vector_src_reg\r
+                (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File,\r
+                 &fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase,\r
+                 swz, &rel))\r
+               return 1;\r
+            for (b=0; b<4; b++)\r
+               fp->SrcReg[a].Swizzle[b] = swz[b];\r
+         }\r
+         break;\r
+\r
+      case OP_ALU_SWZ:\r
+         switch (code) {\r
+            case OP_SWZ_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_SWZ:\r
+               fp->Opcode = FP_OPCODE_SWZ;\r
+               break;\r
+         }\r
+         if (parse_masked_dst_reg\r
+             (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,\r
+              &fp->DstReg.Index, fp->DstReg.WriteMask))\r
+            return 1;\r
+\r
+         if (parse_src_reg\r
+             (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,\r
+              &fp->SrcReg[0].Index, &rel))\r
+            return 1;\r
+         parse_extended_swizzle_mask (inst, swz,\r
+                                      &fp->SrcReg[0].NegateBase);\r
+         for (b=0; b<4; b++)\r
+            fp->SrcReg[0].Swizzle[b] = swz[b];\r
+         break;\r
+\r
+      case OP_TEX_SAMPLE:\r
+         switch (code) {\r
+            case OP_TEX_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_TEX:\r
+               fp->Opcode = FP_OPCODE_TEX;\r
+               break;\r
+\r
+            case OP_TXP_SAT:\r
+               fp->Saturate = 1;\r
+            case OP_TXP:\r
+               fp->Opcode = FP_OPCODE_TXP;\r
+               break;\r
+\r
+            case OP_TXB_SAT:\r
+\r
+               fp->Saturate = 1;\r
+            case OP_TXB:\r
+               fp->Opcode = FP_OPCODE_TXB;\r
+               break;\r
+         }\r
+\r
+         if (parse_masked_dst_reg\r
+             (ctx, inst, vc_head, Program, (GLint *) & fp->DstReg.File,\r
+              &fp->DstReg.Index, fp->DstReg.WriteMask))\r
+            return 1;\r
+         fp->SrcReg[0].Abs = GL_FALSE;\r
+         fp->SrcReg[0].NegateAbs = GL_FALSE;\r
+         if (parse_vector_src_reg\r
+             (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,\r
+              &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,\r
+              swz, &rel))\r
+            return 1;\r
+         for (b=0; b<4; b++)\r
+            fp->SrcReg[0].Swizzle[b] = swz[b];\r
+\r
+         /* texImageUnit */\r
+         if (parse_texcoord_num (ctx, inst, Program, &texcoord))\r
+            return 1;\r
+         fp->TexSrcUnit = texcoord;\r
+\r
+         /* texTarget */\r
+         switch (*(*inst)++) {\r
+            case TEXTARGET_1D:\r
+               fp->TexSrcBit = TEXTURE_1D_BIT;\r
+               break;\r
+            case TEXTARGET_2D:\r
+               fp->TexSrcBit = TEXTURE_2D_BIT;\r
+               break;\r
+            case TEXTARGET_3D:\r
+               fp->TexSrcBit = TEXTURE_3D_BIT;\r
+               break;\r
+            case TEXTARGET_RECT:\r
+               fp->TexSrcBit = TEXTURE_RECT_BIT;\r
+               break;\r
+            case TEXTARGET_CUBE:\r
+               fp->TexSrcBit = TEXTURE_CUBE_BIT;\r
+               break;\r
+           case TEXTARGET_SHADOW1D:\r
+           case TEXTARGET_SHADOW2D:\r
+           case TEXTARGET_SHADOWRECT:\r
+              /* TODO ARB_fragment_program_shadow code */\r
+              break;\r
+         }\r
+         Program->TexturesUsed[texcoord] |= fp->TexSrcBit;\r
+         break;\r
+\r
+      case OP_TEX_KIL:\r
+         fp->Opcode = FP_OPCODE_KIL;\r
+         fp->SrcReg[0].Abs = GL_FALSE;\r
+         fp->SrcReg[0].NegateAbs = GL_FALSE;\r
+         if (parse_vector_src_reg\r
+             (ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,\r
+              &fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,\r
+              swz, &rel))\r
+            return 1;\r
+         for (b=0; b<4; b++)\r
+            fp->SrcReg[0].Swizzle[b] = swz[b];\r
+         break;\r
+   }\r
+\r
+   return 0;\r
+}\r
+\r
+/**\r
+ * This is a big mother that handles getting opcodes into the instruction\r
+ * and handling the src & dst registers for vertex program instructions\r
+ */\r
+static GLuint\r
+parse_vp_instruction (GLcontext * ctx, GLubyte ** inst,\r
+                      struct var_cache **vc_head, struct arb_program *Program,\r
+                      struct vp_instruction *vp)\r
+{\r
+   GLint a;\r
+   GLubyte type, code;\r
+\r
+   /* OP_ALU_{ARL, VECTOR, SCALAR, BINSC, BIN, TRI, SWZ} */\r
+   type = *(*inst)++;\r
+\r
+   /* The actual opcode name */\r
+   code = *(*inst)++;\r
+\r
+   /* Record the position in the program string for debugging */\r
+   vp->StringPos = Program->Position;\r
+\r
+   vp->SrcReg[0].RelAddr = vp->SrcReg[1].RelAddr = vp->SrcReg[2].RelAddr = 0;\r
+\r
+   for (a = 0; a < 4; a++) {\r
+      vp->SrcReg[0].Swizzle[a] = a;\r
+      vp->SrcReg[1].Swizzle[a] = a;\r
+      vp->SrcReg[2].Swizzle[a] = a;\r
+      vp->DstReg.WriteMask[a] = 1;\r
+   }\r
+\r
+   switch (type) {\r
+         /* XXX: */\r
+      case OP_ALU_ARL:\r
+         vp->Opcode = VP_OPCODE_ARL;\r
+\r
+         /* Remember to set SrcReg.RelAddr; */\r
+\r
+         /* Get the masked address register [dst] */\r
+         if (parse_masked_address_reg\r
+             (ctx, inst, vc_head, Program, &vp->DstReg.Index,\r
+              vp->DstReg.WriteMask))\r
+            return 1;\r
+         vp->DstReg.File = PROGRAM_ADDRESS;\r
+\r
+         /* Get a scalar src register */\r
+         if (parse_scalar_src_reg\r
+             (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,\r
+              &vp->SrcReg[0].Index, &vp->SrcReg[0].Negate,\r
+              vp->SrcReg[0].Swizzle, &vp->SrcReg[0].RelAddr))\r
+            return 1;\r
+\r
+         break;\r
+\r
+      case OP_ALU_VECTOR:\r
+         switch (code) {\r
+            case OP_ABS:\r
+               vp->Opcode = VP_OPCODE_ABS;\r
+               break;\r
+            case OP_FLR:\r
+               vp->Opcode = VP_OPCODE_FLR;\r
+               break;\r
+            case OP_FRC:\r
+               vp->Opcode = VP_OPCODE_FRC;\r
+               break;\r
+            case OP_LIT:\r
+               vp->Opcode = VP_OPCODE_LIT;\r
+               break;\r
+            case OP_MOV:\r
+               vp->Opcode = VP_OPCODE_MOV;\r
+               break;\r
+         }\r
+         if (parse_masked_dst_reg\r
+             (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,\r
+              &vp->DstReg.Index, vp->DstReg.WriteMask))\r
+            return 1;\r
+         if (parse_vector_src_reg\r
+             (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,\r
+              &vp->SrcReg[0].Index, &vp->SrcReg[0].Negate,\r
+              vp->SrcReg[0].Swizzle, &vp->SrcReg[0].RelAddr))\r
+            return 1;\r
+         break;\r
+\r
+      case OP_ALU_SCALAR:\r
+         switch (code) {\r
+            case OP_EX2:\r
+               vp->Opcode = VP_OPCODE_EX2;\r
+               break;\r
+            case OP_EXP:\r
+               vp->Opcode = VP_OPCODE_EXP;\r
+               break;\r
+            case OP_LG2:\r
+               vp->Opcode = VP_OPCODE_LG2;\r
+               break;\r
+            case OP_LOG:\r
+               vp->Opcode = VP_OPCODE_LOG;\r
+               break;\r
+            case OP_RCP:\r
+               vp->Opcode = VP_OPCODE_RCP;\r
+               break;\r
+            case OP_RSQ:\r
+               vp->Opcode = VP_OPCODE_RSQ;\r
+               break;\r
+         }\r
+         if (parse_masked_dst_reg\r
+             (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,\r
+              &vp->DstReg.Index, vp->DstReg.WriteMask))\r
+            return 1;\r
+         if (parse_scalar_src_reg\r
+             (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,\r
+              &vp->SrcReg[0].Index, &vp->SrcReg[0].Negate,\r
+              vp->SrcReg[0].Swizzle, &vp->SrcReg[0].RelAddr))\r
+            return 1;\r
+         break;\r
+\r
+      case OP_ALU_BINSC:\r
+         switch (code) {\r
+            case OP_POW:\r
+               vp->Opcode = VP_OPCODE_POW;\r
+               break;\r
+         }\r
+         if (parse_masked_dst_reg\r
+             (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,\r
+              &vp->DstReg.Index, vp->DstReg.WriteMask))\r
+            return 1;\r
+         for (a = 0; a < 2; a++) {\r
+            if (parse_scalar_src_reg\r
+                (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File,\r
+                 &vp->SrcReg[a].Index, &vp->SrcReg[a].Negate,\r
+                 vp->SrcReg[a].Swizzle, &vp->SrcReg[a].RelAddr))\r
+               return 1;\r
+         }\r
+         break;\r
+\r
+      case OP_ALU_BIN:\r
+         switch (code) {\r
+            case OP_ADD:\r
+               vp->Opcode = VP_OPCODE_ADD;\r
+               break;\r
+            case OP_DP3:\r
+               vp->Opcode = VP_OPCODE_DP3;\r
+               break;\r
+            case OP_DP4:\r
+               vp->Opcode = VP_OPCODE_DP4;\r
+               break;\r
+            case OP_DPH:\r
+               vp->Opcode = VP_OPCODE_DPH;\r
+               break;\r
+            case OP_DST:\r
+               vp->Opcode = VP_OPCODE_DST;\r
+               break;\r
+            case OP_MAX:\r
+               vp->Opcode = VP_OPCODE_MAX;\r
+               break;\r
+            case OP_MIN:\r
+               vp->Opcode = VP_OPCODE_MIN;\r
+               break;\r
+            case OP_MUL:\r
+               vp->Opcode = VP_OPCODE_MUL;\r
+               break;\r
+            case OP_SGE:\r
+               vp->Opcode = VP_OPCODE_SGE;\r
+               break;\r
+            case OP_SLT:\r
+               vp->Opcode = VP_OPCODE_SLT;\r
+               break;\r
+            case OP_SUB:\r
+               vp->Opcode = VP_OPCODE_SUB;\r
+               break;\r
+            case OP_XPD:\r
+               vp->Opcode = VP_OPCODE_XPD;\r
+               break;\r
+         }\r
+         if (parse_masked_dst_reg\r
+             (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,\r
+              &vp->DstReg.Index, vp->DstReg.WriteMask))\r
+            return 1;\r
+         for (a = 0; a < 2; a++) {\r
+            if (parse_vector_src_reg\r
+                (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File,\r
+                 &vp->SrcReg[a].Index, &vp->SrcReg[a].Negate,\r
+                 vp->SrcReg[a].Swizzle, &vp->SrcReg[a].RelAddr))\r
+               return 1;\r
+         }\r
+         break;\r
+\r
+      case OP_ALU_TRI:\r
+         switch (code) {\r
+            case OP_MAD:\r
+               vp->Opcode = VP_OPCODE_MAD;\r
+               break;\r
+         }\r
+\r
+         if (parse_masked_dst_reg\r
+             (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,\r
+              &vp->DstReg.Index, vp->DstReg.WriteMask))\r
+            return 1;\r
+         for (a = 0; a < 3; a++) {\r
+            if (parse_vector_src_reg\r
+                (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File,\r
+                 &vp->SrcReg[a].Index, &vp->SrcReg[a].Negate,\r
+                 vp->SrcReg[a].Swizzle, &vp->SrcReg[a].RelAddr))\r
+               return 1;\r
+         }\r
+         break;\r
+\r
+      case OP_ALU_SWZ:\r
+         switch (code) {\r
+            case OP_SWZ:\r
+               vp->Opcode = VP_OPCODE_SWZ;\r
+               break;\r
+         }\r
+         if (parse_masked_dst_reg\r
+             (ctx, inst, vc_head, Program, (GLint *) & vp->DstReg.File,\r
+              &vp->DstReg.Index, vp->DstReg.WriteMask))\r
+            return 1;\r
+\r
+         if (parse_src_reg\r
+             (ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,\r
+              &vp->SrcReg[0].Index, &vp->SrcReg[0].RelAddr))\r
+            return 1;\r
+         parse_extended_swizzle_mask (inst, vp->SrcReg[0].Swizzle,\r
+                                      &vp->SrcReg[0].Negate);\r
+         break;\r
+   }\r
+   return 0;\r
+}\r
+\r
+#if DEBUG_PARSING\r
+\r
+static GLvoid\r
+print_state_token (GLint token)\r
+{\r
+   switch (token) {\r
+      case STATE_MATERIAL:\r
+         fprintf (stderr, "STATE_MATERIAL ");\r
+         break;\r
+      case STATE_LIGHT:\r
+         fprintf (stderr, "STATE_LIGHT ");\r
+         break;\r
+\r
+      case STATE_LIGHTMODEL_AMBIENT:\r
+         fprintf (stderr, "STATE_AMBIENT ");\r
+         break;\r
+\r
+      case STATE_LIGHTMODEL_SCENECOLOR:\r
+         fprintf (stderr, "STATE_SCENECOLOR ");\r
+         break;\r
+\r
+      case STATE_LIGHTPROD:\r
+         fprintf (stderr, "STATE_LIGHTPROD ");\r
+         break;\r
+\r
+      case STATE_TEXGEN:\r
+         fprintf (stderr, "STATE_TEXGEN ");\r
+         break;\r
+\r
+      case STATE_FOG_COLOR:\r
+         fprintf (stderr, "STATE_FOG_COLOR ");\r
+         break;\r
+\r
+      case STATE_FOG_PARAMS:\r
+         fprintf (stderr, "STATE_FOG_PARAMS ");\r
+         break;\r
+\r
+      case STATE_CLIPPLANE:\r
+         fprintf (stderr, "STATE_CLIPPLANE ");\r
+         break;\r
+\r
+      case STATE_POINT_SIZE:\r
+         fprintf (stderr, "STATE_POINT_SIZE ");\r
+         break;\r
+\r
+      case STATE_POINT_ATTENUATION:\r
+         fprintf (stderr, "STATE_ATTENUATION ");\r
+         break;\r
+\r
+      case STATE_MATRIX:\r
+         fprintf (stderr, "STATE_MATRIX ");\r
+         break;\r
+\r
+      case STATE_MODELVIEW:\r
+         fprintf (stderr, "STATE_MODELVIEW ");\r
+         break;\r
+\r
+      case STATE_PROJECTION:\r
+         fprintf (stderr, "STATE_PROJECTION ");\r
+         break;\r
+\r
+      case STATE_MVP:\r
+         fprintf (stderr, "STATE_MVP ");\r
+         break;\r
+\r
+      case STATE_TEXTURE:\r
+         fprintf (stderr, "STATE_TEXTURE ");\r
+         break;\r
+\r
+      case STATE_PROGRAM:\r
+         fprintf (stderr, "STATE_PROGRAM ");\r
+         break;\r
+\r
+      case STATE_MATRIX_INVERSE:\r
+         fprintf (stderr, "STATE_INVERSE ");\r
+         break;\r
+\r
+      case STATE_MATRIX_TRANSPOSE:\r
+         fprintf (stderr, "STATE_TRANSPOSE ");\r
+         break;\r
+\r
+      case STATE_MATRIX_INVTRANS:\r
+         fprintf (stderr, "STATE_INVTRANS ");\r
+         break;\r
+\r
+      case STATE_AMBIENT:\r
+         fprintf (stderr, "STATE_AMBIENT ");\r
+         break;\r
+\r
+      case STATE_DIFFUSE:\r
+         fprintf (stderr, "STATE_DIFFUSE ");\r
+         break;\r
+\r
+      case STATE_SPECULAR:\r
+         fprintf (stderr, "STATE_SPECULAR ");\r
+         break;\r
+\r
+      case STATE_EMISSION:\r
+         fprintf (stderr, "STATE_EMISSION ");\r
+         break;\r
+\r
+      case STATE_SHININESS:\r
+         fprintf (stderr, "STATE_SHININESS ");\r
+         break;\r
+\r
+      case STATE_HALF:\r
+         fprintf (stderr, "STATE_HALF ");\r
+         break;\r
+\r
+      case STATE_POSITION:\r
+         fprintf (stderr, "STATE_POSITION ");\r
+         break;\r
+\r
+      case STATE_ATTENUATION:\r
+         fprintf (stderr, "STATE_ATTENUATION ");\r
+         break;\r
+\r
+      case STATE_SPOT_DIRECTION:\r
+         fprintf (stderr, "STATE_DIRECTION ");\r
+         break;\r
+\r
+      case STATE_TEXGEN_EYE_S:\r
+         fprintf (stderr, "STATE_TEXGEN_EYE_S ");\r
+         break;\r
+\r
+      case STATE_TEXGEN_EYE_T:\r
+         fprintf (stderr, "STATE_TEXGEN_EYE_T ");\r
+         break;\r
+\r
+      case STATE_TEXGEN_EYE_R:\r
+         fprintf (stderr, "STATE_TEXGEN_EYE_R ");\r
+         break;\r
+\r
+      case STATE_TEXGEN_EYE_Q:\r
+         fprintf (stderr, "STATE_TEXGEN_EYE_Q ");\r
+         break;\r
+\r
+      case STATE_TEXGEN_OBJECT_S:\r
+         fprintf (stderr, "STATE_TEXGEN_EYE_S ");\r
+         break;\r
+\r
+      case STATE_TEXGEN_OBJECT_T:\r
+         fprintf (stderr, "STATE_TEXGEN_OBJECT_T ");\r
+         break;\r
+\r
+      case STATE_TEXGEN_OBJECT_R:\r
+         fprintf (stderr, "STATE_TEXGEN_OBJECT_R ");\r
+         break;\r
+\r
+      case STATE_TEXGEN_OBJECT_Q:\r
+         fprintf (stderr, "STATE_TEXGEN_OBJECT_Q ");\r
+         break;\r
+\r
+      case STATE_TEXENV_COLOR:\r
+         fprintf (stderr, "STATE_TEXENV_COLOR ");\r
+         break;\r
+\r
+      case STATE_DEPTH_RANGE:\r
+         fprintf (stderr, "STATE_DEPTH_RANGE ");\r
+         break;\r
+\r
+      case STATE_VERTEX_PROGRAM:\r
+         fprintf (stderr, "STATE_VERTEX_PROGRAM ");\r
+         break;\r
+\r
+      case STATE_FRAGMENT_PROGRAM:\r
+         fprintf (stderr, "STATE_FRAGMENT_PROGRAM ");\r
+         break;\r
+\r
+      case STATE_ENV:\r
+         fprintf (stderr, "STATE_ENV ");\r
+         break;\r
+\r
+      case STATE_LOCAL:\r
+         fprintf (stderr, "STATE_LOCAL ");\r
+         break;\r
+\r
+   }\r
+   fprintf (stderr, "[%d] ", token);\r
+}\r
+\r
+\r
+static GLvoid\r
+debug_variables (GLcontext * ctx, struct var_cache *vc_head,\r
+                 struct arb_program *Program)\r
+{\r
+   struct var_cache *vc;\r
+   GLint a, b;\r
+\r
+   fprintf (stderr, "debug_variables, vc_head: %x\n", vc_head);\r
+\r
+   /* First of all, print out the contents of the var_cache */\r
+   vc = vc_head;\r
+   while (vc) {\r
+      fprintf (stderr, "[%x]\n", vc);\r
+      switch (vc->type) {\r
+         case vt_none:\r
+            fprintf (stderr, "UNDEFINED %s\n", vc->name);\r
+            break;\r
+         case vt_attrib:\r
+            fprintf (stderr, "ATTRIB    %s\n", vc->name);\r
+            fprintf (stderr, "          binding: 0x%x\n", vc->attrib_binding);\r
+            break;\r
+         case vt_param:\r
+            fprintf (stderr, "PARAM     %s  begin: %d len: %d\n", vc->name,\r
+                     vc->param_binding_begin, vc->param_binding_length);\r
+            b = vc->param_binding_begin;\r
+            for (a = 0; a < vc->param_binding_length; a++) {\r
+               fprintf (stderr, "%s\n",\r
+                        Program->Parameters->Parameters[a + b].Name);\r
+               if (Program->Parameters->Parameters[a + b].Type == STATE) {\r
+                  print_state_token (Program->Parameters->Parameters[a + b].\r
+                                     StateIndexes[0]);\r
+                  print_state_token (Program->Parameters->Parameters[a + b].\r
+                                     StateIndexes[1]);\r
+                  print_state_token (Program->Parameters->Parameters[a + b].\r
+                                     StateIndexes[2]);\r
+                  print_state_token (Program->Parameters->Parameters[a + b].\r
+                                     StateIndexes[3]);\r
+                  print_state_token (Program->Parameters->Parameters[a + b].\r
+                                     StateIndexes[4]);\r
+                  print_state_token (Program->Parameters->Parameters[a + b].\r
+                                     StateIndexes[5]);\r
+               }\r
+               else\r
+                  fprintf (stderr, "%f %f %f %f\n",\r
+                           Program->Parameters->Parameters[a + b].Values[0],\r
+                           Program->Parameters->Parameters[a + b].Values[1],\r
+                           Program->Parameters->Parameters[a + b].Values[2],\r
+                           Program->Parameters->Parameters[a + b].Values[3]);\r
+            }\r
+            break;\r
+         case vt_temp:\r
+            fprintf (stderr, "TEMP      %s\n", vc->name);\r
+            fprintf (stderr, "          binding: 0x%x\n", vc->temp_binding);\r
+            break;\r
+         case vt_output:\r
+            fprintf (stderr, "OUTPUT    %s\n", vc->name);\r
+            fprintf (stderr, "          binding: 0x%x\n", vc->output_binding);\r
+            break;\r
+         case vt_alias:\r
+            fprintf (stderr, "ALIAS     %s\n", vc->name);\r
+            fprintf (stderr, "          binding: 0x%x (%s)\n",\r
+                     vc->alias_binding, vc->alias_binding->name);\r
+            break;\r
+      }\r
+      vc = vc->next;\r
+   }\r
+}\r
+\r
+#endif\r
+\r
+\r
+/**\r
+ * The main loop for parsing a fragment or vertex program\r
+ *\r
+ * \return 0 on sucess, 1 on error\r
+ */\r
+static GLint\r
+parse_arb_program (GLcontext * ctx, GLubyte * inst, struct var_cache **vc_head,\r
+                   struct arb_program *Program)\r
+{\r
+   GLint err = 0;\r
+\r
+   Program->MajorVersion = (GLuint) * inst++;\r
+   Program->MinorVersion = (GLuint) * inst++;\r
+\r
+   while (*inst != END) {\r
+      switch (*inst++) {\r
+\r
+         case OPTION:\r
+            switch (*inst++) {\r
+               case ARB_PRECISION_HINT_FASTEST:\r
+                  Program->PrecisionOption = GL_FASTEST;\r
+                  break;\r
+\r
+               case ARB_PRECISION_HINT_NICEST:\r
+                  Program->PrecisionOption = GL_NICEST;\r
+                  break;\r
+\r
+               case ARB_FOG_EXP:\r
+                  Program->FogOption = GL_EXP;\r
+                  break;\r
+\r
+               case ARB_FOG_EXP2:\r
+                  Program->FogOption = GL_EXP2;\r
+                  break;\r
+\r
+               case ARB_FOG_LINEAR:\r
+                  Program->FogOption = GL_LINEAR;\r
+                  break;\r
+\r
+               case ARB_POSITION_INVARIANT:\r
+                  if (Program->Base.Target == GL_VERTEX_PROGRAM_ARB)\r
+                     Program->HintPositionInvariant = 1;\r
+                  break;\r
+\r
+               case ARB_FRAGMENT_PROGRAM_SHADOW:\r
+                 if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {\r
+                    /* TODO ARB_fragment_program_shadow code */\r
+                 }\r
+                 break;\r
+            }\r
+            break;\r
+\r
+         case INSTRUCTION:\r
+            Program->Position = parse_position (&inst);\r
+\r
+            if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {\r
+\r
+               /* Check the instruction count\r
+                * XXX: Does END count as an instruction?\r
+                */\r
+               if (Program->Base.NumInstructions+1 == MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS) {\r
+                  _mesa_set_program_error (ctx, Program->Position,\r
+                      "Max instruction count exceeded!");\r
+                  _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                      "Max instruction count exceeded!");\r
+               }\r
+\r
+               /* Realloc Program->FPInstructions */\r
+               Program->FPInstructions =\r
+                  (struct fp_instruction *) _mesa_realloc (Program->FPInstructions,\r
+                                                           Program->Base.NumInstructions*sizeof(struct fp_instruction),\r
+                                                           (Program->Base.NumInstructions+1)*sizeof (struct fp_instruction));\r
+\r
+               /* parse the current instruction   */\r
+               err = parse_fp_instruction (ctx, &inst, vc_head, Program,\r
+                                           &Program->FPInstructions[Program->Base.NumInstructions]);\r
+\r
+            }\r
+            else {\r
+               /* Check the instruction count\r
+                * XXX: Does END count as an instruction?\r
+                */\r
+               if (Program->Base.NumInstructions+1 == MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS) {\r
+                  _mesa_set_program_error (ctx, Program->Position,\r
+                      "Max instruction count exceeded!");\r
+                  _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                      "Max instruction count exceeded!");\r
+               }\r
+\r
+               /* Realloc Program->VPInstructions */\r
+               Program->VPInstructions =\r
+                  (struct vp_instruction *) _mesa_realloc (Program->VPInstructions,\r
+                                                           Program->Base.NumInstructions*sizeof(struct vp_instruction),\r
+                                                           (Program->Base.NumInstructions +1)*sizeof(struct vp_instruction));\r
+\r
+               /* parse the current instruction   */\r
+               err = parse_vp_instruction (ctx, &inst, vc_head, Program,\r
+                                           &Program->VPInstructions[Program->Base.NumInstructions]);\r
+            }\r
+\r
+            /* increment Program->Base.NumInstructions */\r
+            Program->Base.NumInstructions++;\r
+            break;\r
+\r
+         case DECLARATION:\r
+            err = parse_declaration (ctx, &inst, vc_head, Program);\r
+            break;\r
+\r
+         default:\r
+            break;\r
+      }\r
+\r
+      if (err)\r
+         break;\r
+   }\r
+\r
+   /* Finally, tag on an OPCODE_END instruction */\r
+   if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {\r
+      Program->FPInstructions =\r
+         (struct fp_instruction *) _mesa_realloc (Program->FPInstructions,\r
+                                                 Program->Base.NumInstructions*sizeof(struct fp_instruction),\r
+                                                  (Program->Base.NumInstructions+1)*sizeof(struct fp_instruction));\r
+\r
+      Program->FPInstructions[Program->Base.NumInstructions].Opcode = FP_OPCODE_END;\r
+      /* YYY Wrong Position in program, whatever, at least not random -> crash\r
+        Program->Position = parse_position (&inst);\r
+      */\r
+      Program->FPInstructions[Program->Base.NumInstructions].StringPos = Program->Position;\r
+   }\r
+   else {\r
+      Program->VPInstructions =\r
+         (struct vp_instruction *) _mesa_realloc (Program->VPInstructions,\r
+                                                  Program->Base.NumInstructions*sizeof(struct vp_instruction),\r
+                                                  (Program->Base.NumInstructions+1)*sizeof(struct vp_instruction));\r
+\r
+      Program->VPInstructions[Program->Base.NumInstructions].Opcode = VP_OPCODE_END;\r
+      /* YYY Wrong Position in program, whatever, at least not random -> crash\r
+        Program->Position = parse_position (&inst);\r
+      */\r
+      Program->VPInstructions[Program->Base.NumInstructions].StringPos = Program->Position;\r
+   }\r
+\r
+   /* increment Program->Base.NumInstructions */\r
+   Program->Base.NumInstructions++;\r
+\r
+   return err;\r
+}\r
+\r
+/* XXX temporary */\r
+static char core_grammar_text[] =\r
+#include "grammar_syn.h"\r
+;\r
+\r
+static int set_reg8 (GLcontext *ctx, grammar id, const byte *name, byte value)\r
+{\r
+   char error_msg[300];\r
+   GLint error_pos;\r
+\r
+   if (grammar_set_reg8 (id, name, value))\r
+      return 0;\r
+\r
+   grammar_get_last_error ((byte *) error_msg, 300, &error_pos);\r
+   _mesa_set_program_error (ctx, error_pos, error_msg);\r
+   _mesa_error (ctx, GL_INVALID_OPERATION, "Grammar Register Error");\r
+   return 1;\r
+}\r
+\r
+static int extension_is_supported (const GLubyte *ext)\r
+{\r
+   const GLubyte *extensions = glGetString (GL_EXTENSIONS);\r
+   const GLubyte *end = extensions + _mesa_strlen ((const char *) extensions);\r
+   const GLint ext_len = _mesa_strlen ((const char *) ext);\r
+\r
    while (extensions < end)\r
    {\r
       const GLubyte *name_end = (const GLubyte *) strchr ((const char *) extensions, ' ');\r
@@ -3732,222 +3732,222 @@ static int extension_is_supported (const GLubyte *ext)
          return 1;\r
       extensions = name_end + 1;\r
    }\r
-
-   return 0;
-}
-
-static int enable_ext (GLcontext *ctx, grammar id, const byte *name, const byte *extname)
-{
-   if (extension_is_supported (extname))
-      if (set_reg8 (ctx, id, name, 0x01))
-         return 1;
-   return 0;
-}
-
-/**
- * This kicks everything off.
- *
- * \param ctx - The GL Context
- * \param str - The program string
- * \param len - The program string length
- * \param Program - The arb_program struct to return all the parsed info in
- * \return 0 on sucess, 1 on error
- */
-GLuint
-_mesa_parse_arb_program (GLcontext * ctx, const GLubyte * str, GLsizei len,
-                         struct arb_program * program)
-{
-   GLint a, err, error_pos;
-   char error_msg[300];
-   GLuint parsed_len;
-   struct var_cache *vc_head;
-   grammar arbprogram_syn_id;
-   GLubyte *parsed, *inst;
-   GLubyte *strz = NULL;
-   static int arbprogram_syn_is_ok = 0;                /* XXX temporary */
-
-#if DEBUG_PARSING
-   fprintf (stderr, "Loading grammar text!\n");
-#endif
-
-   /* check if the arb_grammar_text (arbprogram.syn) is syntactically correct */
-   if (!arbprogram_syn_is_ok) {
-      grammar grammar_syn_id;
-      GLint err;
-      GLuint parsed_len;
-      byte *parsed;
-
-      grammar_syn_id = grammar_load_from_text ((byte *) core_grammar_text);
-      if (grammar_syn_id == 0) {
-         grammar_get_last_error ((byte *) error_msg, 300, &error_pos);
-         _mesa_set_program_error (ctx, error_pos, error_msg);
-         _mesa_error (ctx, GL_INVALID_OPERATION,
-                      "Error loading grammar rule set");
-         return 1;
-      }
-
-      err = grammar_check (grammar_syn_id, (byte *) arb_grammar_text, &parsed, &parsed_len);
-
-      /* NOTE: we cant destroy grammar_syn_id right here because grammar_destroy() can
-         reset the last error
-      */
-
-      if (err == 0) {
-         grammar_get_last_error ((byte *) error_msg, 300, &error_pos);
-         _mesa_set_program_error (ctx, error_pos, error_msg);
-         _mesa_error (ctx, GL_INVALID_OPERATION, "Error loading grammar rule set");
-
-         grammar_destroy (grammar_syn_id);
-         return 1;
-      }
-
-      grammar_destroy (grammar_syn_id);
-
-      arbprogram_syn_is_ok = 1;
-   }
-
-   /* create the grammar object */
-   arbprogram_syn_id = grammar_load_from_text ((byte *) arb_grammar_text);
-   if (arbprogram_syn_id == 0) {
-      grammar_get_last_error ((GLubyte *) error_msg, 300, &error_pos);
-      _mesa_set_program_error (ctx, error_pos, error_msg);
-      _mesa_error (ctx, GL_INVALID_OPERATION,
-                   "Error loading grammer rule set");
-      return 1;
-   }
-
-   /* Set program_target register value */
-   if (set_reg8 (ctx, arbprogram_syn_id, (byte *) "program_target",
-      program->Base.Target == GL_FRAGMENT_PROGRAM_ARB ? 0x10 : 0x20)) {
-      grammar_destroy (arbprogram_syn_id);
-      return 1;
-   }
-
-   /* Enable all active extensions */
-   if (enable_ext (ctx, arbprogram_syn_id,
-          (byte *) "vertex_blend", (byte *) "GL_ARB_vertex_blend") ||
-       enable_ext (ctx, arbprogram_syn_id,
-          (byte *) "vertex_blend", (byte *) "GL_EXT_vertex_weighting") ||
-       enable_ext (ctx, arbprogram_syn_id,
-          (byte *) "matrix_palette", (byte *) "GL_ARB_matrix_palette") ||
-       enable_ext (ctx, arbprogram_syn_id,
-          (byte *) "point_parameters", (byte *) "GL_ARB_point_parameters") ||
-       enable_ext (ctx, arbprogram_syn_id,
-          (byte *) "point_parameters", (byte *) "GL_EXT_point_parameters") ||
-       enable_ext (ctx, arbprogram_syn_id,
-          (byte *) "secondary_color", (byte *) "GL_EXT_secondary_color") ||
-       enable_ext (ctx, arbprogram_syn_id,
-          (byte *) "fog_coord", (byte *) "GL_EXT_fog_coord") ||
-       enable_ext (ctx, arbprogram_syn_id,
-          (byte *) "texture_rectangle", (byte *) "GL_EXT_texture_rectangle") ||
-       enable_ext (ctx, arbprogram_syn_id,
-          (byte *) "texture_rectangle", (byte *) "GL_NV_texture_rectangle") ||
-       enable_ext (ctx, arbprogram_syn_id,
-          (byte *) "fragment_program_shadow", (byte *) "GL_ARB_fragment_program_shadow")) {
-      grammar_destroy (arbprogram_syn_id);
-      return 1;
-   }
-
-   /* check for NULL character occurences */
-   {
-      int i;
-      for (i = 0; i < len; i++)
-         if (str[i] == '\0') {
-            _mesa_set_program_error (ctx, i, "invalid character");
-            _mesa_error (ctx, GL_INVALID_OPERATION, "Lexical Error");
-
-            grammar_destroy (arbprogram_syn_id);
-            return 1;
-         }
-   }
-
-   /* copy the program string to a null-terminated string */
-   /* XXX should I check for NULL from malloc()? */
-   strz = _mesa_malloc (len + 1);
-   _mesa_memcpy (strz, str, len);
-   strz[len] = '\0';
-
-#if DEBUG_PARSING
-   printf ("Checking Grammar!\n");
-#endif
-   err = grammar_check (arbprogram_syn_id, strz, &parsed, &parsed_len);
-
-   /* Syntax parse error */
-   if (err == 0) {
-      _mesa_free (strz);
-      grammar_get_last_error ((GLubyte *) error_msg, 300, &error_pos);
-      _mesa_set_program_error (ctx, error_pos, error_msg);
-      _mesa_error (ctx, GL_INVALID_OPERATION, "Parse Error");
-
-      grammar_destroy (arbprogram_syn_id);
-      return 1;
-   }
-
-#if DEBUG_PARSING
-   printf ("Destroying grammer dict [parse retval: %d]\n", err);
-#endif
-   grammar_destroy (arbprogram_syn_id);
-
-   /* Initialize the arb_program struct */
-   program->Base.String = strz;
-   program->Base.NumInstructions =
-   program->Base.NumTemporaries =
-   program->Base.NumParameters =
-   program->Base.NumAttributes = program->Base.NumAddressRegs = 0;
-   program->Parameters = _mesa_new_parameter_list ();
-   program->InputsRead = 0;
-   program->OutputsWritten = 0;
-   program->Position = 0;
-   program->MajorVersion = program->MinorVersion = 0;
-   program->PrecisionOption = GL_DONT_CARE;
-   program->FogOption = GL_NONE;
-   program->HintPositionInvariant = GL_FALSE;
-   for (a = 0; a < MAX_TEXTURE_IMAGE_UNITS; a++)
-      program->TexturesUsed[a] = 0;
-   program->NumAluInstructions =
-   program->NumTexInstructions =
-   program->NumTexIndirections = 0;
-
-   program->FPInstructions = NULL;
-   program->VPInstructions = NULL;
-
-   vc_head = NULL;
-   err = 0;
-
-   /* Start examining the tokens in the array */
-   inst = parsed;
-
-   /* Check the grammer rev */
-   if (*inst++ != REVISION) {
-      _mesa_set_program_error (ctx, 0, "Grammar version mismatch");
-      _mesa_error (ctx, GL_INVALID_OPERATION, "Grammar verison mismatch");
-      err = 1;
-   }
-   else {
-      switch (*inst++) {
-         case FRAGMENT_PROGRAM:
-            program->Base.Target = GL_FRAGMENT_PROGRAM_ARB;
-            break;
-
-         case VERTEX_PROGRAM:
-            program->Base.Target = GL_VERTEX_PROGRAM_ARB;
-            break;
-      }
-
-      err = parse_arb_program (ctx, inst, &vc_head, program);
-#if DEBUG_PARSING
-      fprintf (stderr, "Symantic analysis returns %d [1 is bad!]\n", err);
-#endif
-   }
-
-   /*debug_variables(ctx, vc_head, program); */
-
-   /* We're done with the parsed binary array */
-   var_cache_destroy (&vc_head);
-
-   _mesa_free (parsed);
-#if DEBUG_PARSING
-   printf ("_mesa_parse_arb_program() done\n");
-#endif
-   return err;
-}
+\r
+   return 0;\r
+}\r
+\r
+static int enable_ext (GLcontext *ctx, grammar id, const byte *name, const byte *extname)\r
+{\r
+   if (extension_is_supported (extname))\r
+      if (set_reg8 (ctx, id, name, 0x01))\r
+         return 1;\r
+   return 0;\r
+}\r
+\r
+/**\r
+ * This kicks everything off.\r
+ *\r
+ * \param ctx - The GL Context\r
+ * \param str - The program string\r
+ * \param len - The program string length\r
+ * \param Program - The arb_program struct to return all the parsed info in\r
+ * \return 0 on sucess, 1 on error\r
+ */\r
+GLuint\r
+_mesa_parse_arb_program (GLcontext * ctx, const GLubyte * str, GLsizei len,\r
+                         struct arb_program * program)\r
+{\r
+   GLint a, err, error_pos;\r
+   char error_msg[300];\r
+   GLuint parsed_len;\r
+   struct var_cache *vc_head;\r
+   grammar arbprogram_syn_id;\r
+   GLubyte *parsed, *inst;\r
+   GLubyte *strz = NULL;\r
+   static int arbprogram_syn_is_ok = 0;                /* XXX temporary */\r
+\r
+#if DEBUG_PARSING\r
+   fprintf (stderr, "Loading grammar text!\n");\r
+#endif\r
+\r
+   /* check if the arb_grammar_text (arbprogram.syn) is syntactically correct */\r
+   if (!arbprogram_syn_is_ok) {\r
+      grammar grammar_syn_id;\r
+      GLint err;\r
+      GLuint parsed_len;\r
+      byte *parsed;\r
+\r
+      grammar_syn_id = grammar_load_from_text ((byte *) core_grammar_text);\r
+      if (grammar_syn_id == 0) {\r
+         grammar_get_last_error ((byte *) error_msg, 300, &error_pos);\r
+         _mesa_set_program_error (ctx, error_pos, error_msg);\r
+         _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                      "Error loading grammar rule set");\r
+         return 1;\r
+      }\r
+\r
+      err = grammar_check (grammar_syn_id, (byte *) arb_grammar_text, &parsed, &parsed_len);\r
+\r
+      /* NOTE: we cant destroy grammar_syn_id right here because grammar_destroy() can\r
+         reset the last error\r
+      */\r
+\r
+      if (err == 0) {\r
+         grammar_get_last_error ((byte *) error_msg, 300, &error_pos);\r
+         _mesa_set_program_error (ctx, error_pos, error_msg);\r
+         _mesa_error (ctx, GL_INVALID_OPERATION, "Error loading grammar rule set");\r
+\r
+         grammar_destroy (grammar_syn_id);\r
+         return 1;\r
+      }\r
+\r
+      grammar_destroy (grammar_syn_id);\r
+\r
+      arbprogram_syn_is_ok = 1;\r
+   }\r
+\r
+   /* create the grammar object */\r
+   arbprogram_syn_id = grammar_load_from_text ((byte *) arb_grammar_text);\r
+   if (arbprogram_syn_id == 0) {\r
+      grammar_get_last_error ((GLubyte *) error_msg, 300, &error_pos);\r
+      _mesa_set_program_error (ctx, error_pos, error_msg);\r
+      _mesa_error (ctx, GL_INVALID_OPERATION,\r
+                   "Error loading grammer rule set");\r
+      return 1;\r
+   }\r
+\r
+   /* Set program_target register value */\r
+   if (set_reg8 (ctx, arbprogram_syn_id, (byte *) "program_target",\r
+      program->Base.Target == GL_FRAGMENT_PROGRAM_ARB ? 0x10 : 0x20)) {\r
+      grammar_destroy (arbprogram_syn_id);\r
+      return 1;\r
+   }\r
+\r
+   /* Enable all active extensions */\r
+   if (enable_ext (ctx, arbprogram_syn_id,\r
+          (byte *) "vertex_blend", (byte *) "GL_ARB_vertex_blend") ||\r
+       enable_ext (ctx, arbprogram_syn_id,\r
+          (byte *) "vertex_blend", (byte *) "GL_EXT_vertex_weighting") ||\r
+       enable_ext (ctx, arbprogram_syn_id,\r
+          (byte *) "matrix_palette", (byte *) "GL_ARB_matrix_palette") ||\r
+       enable_ext (ctx, arbprogram_syn_id,\r
+          (byte *) "point_parameters", (byte *) "GL_ARB_point_parameters") ||\r
+       enable_ext (ctx, arbprogram_syn_id,\r
+          (byte *) "point_parameters", (byte *) "GL_EXT_point_parameters") ||\r
+       enable_ext (ctx, arbprogram_syn_id,\r
+          (byte *) "secondary_color", (byte *) "GL_EXT_secondary_color") ||\r
+       enable_ext (ctx, arbprogram_syn_id,\r
+          (byte *) "fog_coord", (byte *) "GL_EXT_fog_coord") ||\r
+       enable_ext (ctx, arbprogram_syn_id,\r
+          (byte *) "texture_rectangle", (byte *) "GL_EXT_texture_rectangle") ||\r
+       enable_ext (ctx, arbprogram_syn_id,\r
+          (byte *) "texture_rectangle", (byte *) "GL_NV_texture_rectangle") ||\r
+       enable_ext (ctx, arbprogram_syn_id,\r
+          (byte *) "fragment_program_shadow", (byte *) "GL_ARB_fragment_program_shadow")) {\r
+      grammar_destroy (arbprogram_syn_id);\r
+      return 1;\r
+   }\r
+\r
+   /* check for NULL character occurences */\r
+   {\r
+      int i;\r
+      for (i = 0; i < len; i++)\r
+         if (str[i] == '\0') {\r
+            _mesa_set_program_error (ctx, i, "invalid character");\r
+            _mesa_error (ctx, GL_INVALID_OPERATION, "Lexical Error");\r
+\r
+            grammar_destroy (arbprogram_syn_id);\r
+            return 1;\r
+         }\r
+   }\r
+\r
+   /* copy the program string to a null-terminated string */\r
+   /* XXX should I check for NULL from malloc()? */\r
+   strz = _mesa_malloc (len + 1);\r
+   _mesa_memcpy (strz, str, len);\r
+   strz[len] = '\0';\r
+\r
+#if DEBUG_PARSING\r
+   printf ("Checking Grammar!\n");\r
+#endif\r
+   err = grammar_check (arbprogram_syn_id, strz, &parsed, &parsed_len);\r
+\r
+   /* Syntax parse error */\r
+   if (err == 0) {\r
+      _mesa_free (strz);\r
+      grammar_get_last_error ((GLubyte *) error_msg, 300, &error_pos);\r
+      _mesa_set_program_error (ctx, error_pos, error_msg);\r
+      _mesa_error (ctx, GL_INVALID_OPERATION, "Parse Error");\r
+\r
+      grammar_destroy (arbprogram_syn_id);\r
+      return 1;\r
+   }\r
+\r
+#if DEBUG_PARSING\r
+   printf ("Destroying grammer dict [parse retval: %d]\n", err);\r
+#endif\r
+   grammar_destroy (arbprogram_syn_id);\r
+\r
+   /* Initialize the arb_program struct */\r
+   program->Base.String = strz;\r
+   program->Base.NumInstructions =\r
+   program->Base.NumTemporaries =\r
+   program->Base.NumParameters =\r
+   program->Base.NumAttributes = program->Base.NumAddressRegs = 0;\r
+   program->Parameters = _mesa_new_parameter_list ();\r
+   program->InputsRead = 0;\r
+   program->OutputsWritten = 0;\r
+   program->Position = 0;\r
+   program->MajorVersion = program->MinorVersion = 0;\r
+   program->PrecisionOption = GL_DONT_CARE;\r
+   program->FogOption = GL_NONE;\r
+   program->HintPositionInvariant = GL_FALSE;\r
+   for (a = 0; a < MAX_TEXTURE_IMAGE_UNITS; a++)\r
+      program->TexturesUsed[a] = 0;\r
+   program->NumAluInstructions =\r
+   program->NumTexInstructions =\r
+   program->NumTexIndirections = 0;\r
+\r
+   program->FPInstructions = NULL;\r
+   program->VPInstructions = NULL;\r
+\r
+   vc_head = NULL;\r
+   err = 0;\r
+\r
+   /* Start examining the tokens in the array */\r
+   inst = parsed;\r
+\r
+   /* Check the grammer rev */\r
+   if (*inst++ != REVISION) {\r
+      _mesa_set_program_error (ctx, 0, "Grammar version mismatch");\r
+      _mesa_error (ctx, GL_INVALID_OPERATION, "Grammar verison mismatch");\r
+      err = 1;\r
+   }\r
+   else {\r
+      switch (*inst++) {\r
+         case FRAGMENT_PROGRAM:\r
+            program->Base.Target = GL_FRAGMENT_PROGRAM_ARB;\r
+            break;\r
+\r
+         case VERTEX_PROGRAM:\r
+            program->Base.Target = GL_VERTEX_PROGRAM_ARB;\r
+            break;\r
+      }\r
+\r
+      err = parse_arb_program (ctx, inst, &vc_head, program);\r
+#if DEBUG_PARSING\r
+      fprintf (stderr, "Symantic analysis returns %d [1 is bad!]\n", err);\r
+#endif\r
+   }\r
+\r
+   /*debug_variables(ctx, vc_head, program); */\r
+\r
+   /* We're done with the parsed binary array */\r
+   var_cache_destroy (&vc_head);\r
+\r
+   _mesa_free (parsed);\r
+#if DEBUG_PARSING\r
+   printf ("_mesa_parse_arb_program() done\n");\r
+#endif\r
+   return err;\r
+}\r
index 88bdcd130cde74601f4a6ecc963eacad4f4ff90e..887ffea69a1828638f80a33152425224d095d623 100644 (file)
@@ -1,69 +1,69 @@
-# Makefile for core library for VMS
-# contributed by Jouk Jansen  joukj@hrem.stm.tudelft.nl
-# Last revision : 23 March 2004
-
-.first
-       define gl [---.include.gl]
-       define math [-.math]
-       define swrast [-.swrast]
-       define array_cache [-.array_cache]
-
-.include [---]mms-config.
-
-##### MACROS #####
-
-VPATH = RCS
-
-INCDIR = [---.include],[-.main],[-.glapi]
-LIBDIR = [---.lib]
-CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1)/name=(as_is,short)
-
-SOURCES = \
-       arbfragparse.c \
-       arbprogparse.c \
-       arbprogram.c \
-       arbvertparse.c \
-       grammar_mesa.c \
-       nvfragparse.c \
-       nvprogram.c \
-       nvvertexec.c \
-       nvvertparse.c \
-       program.c
-
-OBJECTS = \
-       arbfragparse.obj \
-       arbprogparse.obj \
-       arbprogram.obj \
-       arbvertparse.obj \
-       grammar_mesa.obj \
-       nvfragparse.obj \
-       nvprogram.obj \
-       nvvertexec.obj \
-       nvvertparse.obj \
-       program.obj
-
-
-##### RULES #####
-
-VERSION=Mesa V3.4
-
-##### TARGETS #####
-# Make the library
-$(LIBDIR)$(GL_LIB) : $(OBJECTS)
-  @ library $(LIBDIR)$(GL_LIB) $(OBJECTS)
-
-clean :
-       purge
-       delete *.obj;*
-
-
-arbfragparse.obj : arbfragparse.c
-arbprogparse.obj : arbprogparse.c
-arbprogram.obj : arbprogram.c
-arbvertparse.obj : arbvertparse.c
-grammar_mesa.obj : grammar_mesa.c
-nvfragparse.obj : nvfragparse.c
-nvprogram.obj : nvprogram.c
-nvvertexec.obj : nvvertexec.c
-nvvertparse.obj : nvvertparse.c
-program.obj : program.c
+# Makefile for core library for VMS\r
+# contributed by Jouk Jansen  joukj@hrem.stm.tudelft.nl\r
+# Last revision : 23 March 2004\r
+\r
+.first\r
+       define gl [---.include.gl]\r
+       define math [-.math]\r
+       define swrast [-.swrast]\r
+       define array_cache [-.array_cache]\r
+\r
+.include [---]mms-config.\r
+\r
+##### MACROS #####\r
+\r
+VPATH = RCS\r
+\r
+INCDIR = [---.include],[-.main],[-.glapi]\r
+LIBDIR = [---.lib]\r
+CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1)/name=(as_is,short)\r
+\r
+SOURCES = \\r
+       arbfragparse.c \\r
+       arbprogparse.c \\r
+       arbprogram.c \\r
+       arbvertparse.c \\r
+       grammar_mesa.c \\r
+       nvfragparse.c \\r
+       nvprogram.c \\r
+       nvvertexec.c \\r
+       nvvertparse.c \\r
+       program.c\r
+\r
+OBJECTS = \\r
+       arbfragparse.obj,\\r
+       arbprogparse.obj,\\r
+       arbprogram.obj,\\r
+       arbvertparse.obj,\\r
+       grammar_mesa.obj,\\r
+       nvfragparse.obj,\\r
+       nvprogram.obj,\\r
+       nvvertexec.obj,\\r
+       nvvertparse.obj,\\r
+       program.obj\r
+\r
+\r
+##### RULES #####\r
+\r
+VERSION=Mesa V3.4\r
+\r
+##### TARGETS #####\r
+# Make the library\r
+$(LIBDIR)$(GL_LIB) : $(OBJECTS)\r
+  @ library $(LIBDIR)$(GL_LIB) $(OBJECTS)\r
+\r
+clean :\r
+       purge\r
+       delete *.obj;*\r
+\r
+\r
+arbfragparse.obj : arbfragparse.c\r
+arbprogparse.obj : arbprogparse.c\r
+arbprogram.obj : arbprogram.c\r
+arbvertparse.obj : arbvertparse.c\r
+grammar_mesa.obj : grammar_mesa.c\r
+nvfragparse.obj : nvfragparse.c\r
+nvprogram.obj : nvprogram.c\r
+nvvertexec.obj : nvvertexec.c\r
+nvvertparse.obj : nvvertparse.c\r
+program.obj : program.c\r
index 446942c034fcf0eaecc9300f5b9817325e4cc4e8..c36e60d4fbb36f578ebdcafe8cf33dbc0b79fc02 100644 (file)
@@ -1,79 +1,79 @@
-# Makefile for core library for VMS
-# contributed by Jouk Jansen  joukj@hrem.stm.tudelft.nl
-# Last revision : 23 March 2004
-
-.first
-       define gl [---.include.gl]
-       define math [-.math]
-       define swrast [-.swrast]
-       define array_cache [-.array_cache]
-
-.include [---]mms-config.
-
-##### MACROS #####
-
-VPATH = RCS
-
-INCDIR = [---.include],[-.main],[-.glapi]
-LIBDIR = [---.lib]
-CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1)/name=(as_is,short)
-
-SOURCES = s_aaline.c s_aatriangle.c s_accum.c s_alpha.c s_alphabuf.c \
-       s_auxbuffer.c \
-       s_bitmap.c s_blend.c s_buffers.c s_context.c s_copypix.c s_depth.c \
-        s_drawpix.c s_feedback.c s_fog.c s_imaging.c s_lines.c s_logic.c \
-       s_masking.c s_nvfragprog.c s_pixeltex.c s_points.c s_readpix.c \
-       s_span.c s_stencil.c s_texstore.c s_texture.c s_triangle.c s_zoom.c \
-       s_auxbuffer.c
-OBJECTS = s_aaline.obj,s_aatriangle.obj,s_accum.obj,s_alpha.obj,\
-       s_alphabuf.obj,s_auxbuffer.obj,s_bitmap.obj,s_blend.obj,\
-       s_buffers.obj,s_context.obj,\
-       s_copypix.obj,s_depth.obj,s_drawpix.obj,s_feedback.obj,s_fog.obj,\
-       s_imaging.obj,s_lines.obj,s_logic.obj,s_masking.obj,s_nvfragprog.obj,\
-       s_pixeltex.obj,s_points.obj,s_readpix.obj,s_span.obj,s_stencil.obj,\
-       s_texstore.obj,s_texture.obj,s_triangle.obj,s_zoom.obj,s_auxbuffer.obj
-##### RULES #####
-
-VERSION=Mesa V3.4
-
-##### TARGETS #####
-# Make the library
-$(LIBDIR)$(GL_LIB) : $(OBJECTS)
-  @ library $(LIBDIR)$(GL_LIB) $(OBJECTS)
-
-clean :
-       purge
-       delete *.obj;*
-
-s_aaline.obj : s_aaline.c
-s_aatriangle.obj : s_aatriangle.c
-s_accum.obj : s_accum.c
-s_alpha.obj : s_alpha.c
-s_alphabuf.obj : s_alphabuf.c
-s_auxbuffer.obj : s_auxbuffer.c
-s_bitmap.obj : s_bitmap.c
-s_blend.obj : s_blend.c
-s_buffers.obj : s_buffers.c
-s_context.obj : s_context.c
-s_copypix.obj : s_copypix.c
-s_depth.obj : s_depth.c
-s_drawpix.obj : s_drawpix.c
-s_feedback.obj : s_feedback.c
-s_fog.obj : s_fog.c
-s_imaging.obj : s_imaging.c
-s_lines.obj : s_lines.c
-s_logic.obj : s_logic.c
-s_masking.obj : s_masking.c
-s_nvfragprog.obj : s_nvfragprog.c
-s_pixeltex.obj : s_pixeltex.c
-s_points.obj : s_points.c
-s_readpix.obj : s_readpix.c
-s_span.obj : s_span.c
-s_stencil.obj : s_stencil.c
-s_texstore.obj : s_texstore.c
-s_texture.obj : s_texture.c
-s_triangle.obj : s_triangle.c
-s_zoom.obj : s_zoom.c
-s_auxbuffer.obj : s_auxbuffer.c
+# Makefile for core library for VMS\r
+# contributed by Jouk Jansen  joukj@hrem.stm.tudelft.nl\r
+# Last revision : 23 March 2004\r
+\r
+.first\r
+       define gl [---.include.gl]\r
+       define math [-.math]\r
+       define swrast [-.swrast]\r
+       define array_cache [-.array_cache]\r
+\r
+.include [---]mms-config.\r
+\r
+##### MACROS #####\r
+\r
+VPATH = RCS\r
+\r
+INCDIR = [---.include],[-.main],[-.glapi],[-.shader]\r
+LIBDIR = [---.lib]\r
+CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1)/name=(as_is,short)\r
+\r
+SOURCES = s_aaline.c s_aatriangle.c s_accum.c s_alpha.c s_alphabuf.c \\r
+       s_auxbuffer.c \\r
+       s_bitmap.c s_blend.c s_buffers.c s_context.c s_copypix.c s_depth.c \\r
+        s_drawpix.c s_feedback.c s_fog.c s_imaging.c s_lines.c s_logic.c \\r
+       s_masking.c s_nvfragprog.c s_pixeltex.c s_points.c s_readpix.c \\r
+       s_span.c s_stencil.c s_texstore.c s_texture.c s_triangle.c s_zoom.c \\r
+       s_auxbuffer.c\r
\r
+OBJECTS = s_aaline.obj,s_aatriangle.obj,s_accum.obj,s_alpha.obj,\\r
+       s_alphabuf.obj,s_auxbuffer.obj,s_bitmap.obj,s_blend.obj,\\r
+       s_buffers.obj,s_context.obj,\\r
+       s_copypix.obj,s_depth.obj,s_drawpix.obj,s_feedback.obj,s_fog.obj,\\r
+       s_imaging.obj,s_lines.obj,s_logic.obj,s_masking.obj,s_nvfragprog.obj,\\r
+       s_pixeltex.obj,s_points.obj,s_readpix.obj,s_span.obj,s_stencil.obj,\\r
+       s_texstore.obj,s_texture.obj,s_triangle.obj,s_zoom.obj,s_auxbuffer.obj\r
\r
+##### RULES #####\r
+\r
+VERSION=Mesa V3.4\r
+\r
+##### TARGETS #####\r
+# Make the library\r
+$(LIBDIR)$(GL_LIB) : $(OBJECTS)\r
+  @ library $(LIBDIR)$(GL_LIB) $(OBJECTS)\r
+\r
+clean :\r
+       purge\r
+       delete *.obj;*\r
+\r
+s_aaline.obj : s_aaline.c\r
+s_aatriangle.obj : s_aatriangle.c\r
+s_accum.obj : s_accum.c\r
+s_alpha.obj : s_alpha.c\r
+s_alphabuf.obj : s_alphabuf.c\r
+s_auxbuffer.obj : s_auxbuffer.c\r
+s_bitmap.obj : s_bitmap.c\r
+s_blend.obj : s_blend.c\r
+s_buffers.obj : s_buffers.c\r
+s_context.obj : s_context.c\r
+s_copypix.obj : s_copypix.c\r
+s_depth.obj : s_depth.c\r
+s_drawpix.obj : s_drawpix.c\r
+s_feedback.obj : s_feedback.c\r
+s_fog.obj : s_fog.c\r
+s_imaging.obj : s_imaging.c\r
+s_lines.obj : s_lines.c\r
+s_logic.obj : s_logic.c\r
+s_masking.obj : s_masking.c\r
+s_nvfragprog.obj : s_nvfragprog.c\r
+s_pixeltex.obj : s_pixeltex.c\r
+s_points.obj : s_points.c\r
+s_readpix.obj : s_readpix.c\r
+s_span.obj : s_span.c\r
+s_stencil.obj : s_stencil.c\r
+s_texstore.obj : s_texstore.c\r
+s_texture.obj : s_texture.c\r
+s_triangle.obj : s_triangle.c\r
+s_zoom.obj : s_zoom.c\r
+s_auxbuffer.obj : s_auxbuffer.c\r
index 49f4aa61b8b5cf223129c07b7d3fbebb7f749549..968962287444836ffec5707b61e2532dcd52a3cc 100644 (file)
@@ -1,66 +1,68 @@
-# Makefile for core library for VMS
-# contributed by Jouk Jansen  joukj@hrem.stm.tudelft.nl
-# Last revision : 16 June 2003
-
-.first
-       define gl [---.include.gl]
-       define math [-.math]
-       define array_cache [-.array_cache]
-
-.include [---]mms-config.
-
-##### MACROS #####
-
-VPATH = RCS
-
-INCDIR = [---.include],[-.main],[-.glapi]
-LIBDIR = [---.lib]
-CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1)/name=(as_is,short)
-
-SOURCES = t_array_api.c t_array_import.c t_context.c \
-       t_pipeline.c t_vb_fog.c t_save_api.c t_vtx_api.c \
-       t_vb_light.c t_vb_normals.c t_vb_points.c t_vb_program.c \
-       t_vb_render.c t_vb_texgen.c t_vb_texmat.c t_vb_vertex.c \
-       t_vtx_eval.c t_vtx_exec.c t_save_playback.c t_save_loopback.c \
-       t_vertex.c
-
-OBJECTS = t_array_api.obj,t_array_import.obj,t_context.obj,\
-       t_pipeline.obj,t_vb_fog.obj,t_vb_light.obj,t_vb_normals.obj,\
-       t_vb_points.obj,t_vb_program.obj,t_vb_render.obj,t_vb_texgen.obj,\
-       t_vb_texmat.obj,t_vb_vertex.obj,t_save_api.obj,t_vtx_api.obj,\
-       t_vtx_eval.obj,t_vtx_exec.obj,t_save_playback.obj,t_save_loopback.obj,\
-       t_vertex.obj
-
-##### RULES #####
-
-VERSION=Mesa V3.4
-
-##### TARGETS #####
-# Make the library
-$(LIBDIR)$(GL_LIB) : $(OBJECTS)
-  @ library $(LIBDIR)$(GL_LIB) $(OBJECTS)
-
-clean :
-       purge
-       delete *.obj;*
-
-t_array_api.obj : t_array_api.c
-t_array_import.obj : t_array_import.c
-t_context.obj : t_context.c
-t_pipeline.obj : t_pipeline.c
-t_vb_fog.obj : t_vb_fog.c
-t_vb_light.obj : t_vb_light.c
-t_vb_normals.obj : t_vb_normals.c
-t_vb_points.obj : t_vb_points.c
-t_vb_program.obj : t_vb_program.c
-t_vb_render.obj : t_vb_render.c
-t_vb_texgen.obj : t_vb_texgen.c
-t_vb_texmat.obj : t_vb_texmat.c
-t_vb_vertex.obj : t_vb_vertex.c
-t_save_api.obj : t_save_api.c
-t_vtx_api.obj : t_vtx_api.c
-t_vtx_eval.obj : t_vtx_eval.c
-t_vtx_exec.obj : t_vtx_exec.c
-t_save_playback.obj : t_save_playback.c
-t_save_loopback.obj : t_save_loopback.c
-t_vertex.obj : t_vertex.c
+# Makefile for core library for VMS\r
+# contributed by Jouk Jansen  joukj@hrem.stm.tudelft.nl\r
+# Last revision : 16 June 2003\r
+\r
+.first\r
+       define gl [---.include.gl]\r
+       define math [-.math]\r
+       define array_cache [-.array_cache]\r
+\r
+.include [---]mms-config.\r
+\r
+##### MACROS #####\r
+\r
+VPATH = RCS\r
+\r
+INCDIR = [---.include],[-.main],[-.glapi],[-.shader]\r
+LIBDIR = [---.lib]\r
+CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1)/name=(as_is,short)\r
+\r
+SOURCES = t_array_api.c t_array_import.c t_context.c \\r
+       t_pipeline.c t_vb_fog.c t_save_api.c t_vtx_api.c \\r
+       t_vb_light.c t_vb_normals.c t_vb_points.c t_vb_program.c \\r
+       t_vb_render.c t_vb_texgen.c t_vb_texmat.c t_vb_vertex.c \\r
+       t_vtx_eval.c t_vtx_exec.c t_save_playback.c t_save_loopback.c \\r
+       t_vertex.c t_vtx_generic.c t_vtx_x86.c\r
+\r
+OBJECTS = t_array_api.obj,t_array_import.obj,t_context.obj,\\r
+       t_pipeline.obj,t_vb_fog.obj,t_vb_light.obj,t_vb_normals.obj,\\r
+       t_vb_points.obj,t_vb_program.obj,t_vb_render.obj,t_vb_texgen.obj,\\r
+       t_vb_texmat.obj,t_vb_vertex.obj,t_save_api.obj,t_vtx_api.obj,\\r
+       t_vtx_eval.obj,t_vtx_exec.obj,t_save_playback.obj,t_save_loopback.obj,\\r
+       t_vertex.obj,t_vtx_generic.obj,t_vtx_x86.obj\r
+\r
+##### RULES #####\r
+\r
+VERSION=Mesa V3.4\r
+\r
+##### TARGETS #####\r
+# Make the library\r
+$(LIBDIR)$(GL_LIB) : $(OBJECTS)\r
+  @ library $(LIBDIR)$(GL_LIB) $(OBJECTS)\r
+\r
+clean :\r
+       purge\r
+       delete *.obj;*\r
+\r
+t_array_api.obj : t_array_api.c\r
+t_array_import.obj : t_array_import.c\r
+t_context.obj : t_context.c\r
+t_pipeline.obj : t_pipeline.c\r
+t_vb_fog.obj : t_vb_fog.c\r
+t_vb_light.obj : t_vb_light.c\r
+t_vb_normals.obj : t_vb_normals.c\r
+t_vb_points.obj : t_vb_points.c\r
+t_vb_program.obj : t_vb_program.c\r
+t_vb_render.obj : t_vb_render.c\r
+t_vb_texgen.obj : t_vb_texgen.c\r
+t_vb_texmat.obj : t_vb_texmat.c\r
+t_vb_vertex.obj : t_vb_vertex.c\r
+t_save_api.obj : t_save_api.c\r
+t_vtx_api.obj : t_vtx_api.c\r
+t_vtx_eval.obj : t_vtx_eval.c\r
+t_vtx_exec.obj : t_vtx_exec.c\r
+t_save_playback.obj : t_save_playback.c\r
+t_save_loopback.obj : t_save_loopback.c\r
+t_vertex.obj : t_vertex.c\r
+t_vtx_x86.obj : t_vtx_x86.c\r
+t_vtx_generic.obj : t_vtx_generic.c\r