mesa: rename src/mesa/shader/ to src/mesa/program/
[mesa.git] / src / mesa / shader / nvfragparse.c
diff --git a/src/mesa/shader/nvfragparse.c b/src/mesa/shader/nvfragparse.c
deleted file mode 100644 (file)
index 0de3c58..0000000
+++ /dev/null
@@ -1,1588 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5
- *
- * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file nvfragparse.c
- * NVIDIA fragment program parser.
- * \author Brian Paul
- */
-
-/*
- * Regarding GL_NV_fragment_program:
- *
- * Portions of this software may use or implement intellectual
- * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims
- * any and all warranties with respect to such intellectual property,
- * including any use thereof or modifications thereto.
- */
-
-#include "main/glheader.h"
-#include "main/context.h"
-#include "main/imports.h"
-#include "main/macros.h"
-#include "program.h"
-#include "prog_parameter.h"
-#include "prog_print.h"
-#include "prog_instruction.h"
-#include "nvfragparse.h"
-
-
-#define INPUT_1V     1
-#define INPUT_2V     2
-#define INPUT_3V     3
-#define INPUT_1S     4
-#define INPUT_2S     5
-#define INPUT_CC     6
-#define INPUT_1V_T   7  /* one source vector, plus textureId */
-#define INPUT_3V_T   8  /* one source vector, plus textureId */
-#define INPUT_NONE   9
-#define INPUT_1V_S  10  /* a string and a vector register */
-#define OUTPUT_V    20
-#define OUTPUT_S    21
-#define OUTPUT_NONE 22
-
-/* IRIX defines some of these */
-#undef _R
-#undef _H
-#undef _X
-#undef _C
-#undef _S
-
-/* Optional suffixes */
-#define _R  FLOAT32  /* float */
-#define _H  FLOAT16  /* half-float */
-#define _X  FIXED12  /* fixed */
-#define _C  0x08     /* set cond codes */
-#define _S  0x10     /* saturate, clamp result to [0,1] */
-
-struct instruction_pattern {
-   const char *name;
-   enum prog_opcode opcode;
-   GLuint inputs;
-   GLuint outputs;
-   GLuint suffixes;
-};
-
-static const struct instruction_pattern Instructions[] = {
-   { "ADD", OPCODE_ADD, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "COS", OPCODE_COS, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
-   { "DDX", OPCODE_DDX, INPUT_1V, OUTPUT_V, _R | _H |      _C | _S },
-   { "DDY", OPCODE_DDY, INPUT_1V, OUTPUT_V, _R | _H |      _C | _S },
-   { "DP3", OPCODE_DP3, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S },
-   { "DP4", OPCODE_DP4, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S },
-   { "DST", OPCODE_DP4, INPUT_2V, OUTPUT_V, _R | _H |      _C | _S },
-   { "EX2", OPCODE_DP4, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
-   { "FLR", OPCODE_FLR, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "FRC", OPCODE_FRC, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "KIL", OPCODE_KIL_NV, INPUT_CC, OUTPUT_NONE, 0                },
-   { "LG2", OPCODE_LG2, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
-   { "LIT", OPCODE_LIT, INPUT_1V, OUTPUT_V, _R | _H |      _C | _S },
-   { "LRP", OPCODE_LRP, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "MAD", OPCODE_MAD, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "MAX", OPCODE_MAX, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "MIN", OPCODE_MIN, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "MOV", OPCODE_MOV, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "MUL", OPCODE_MUL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "PK2H",  OPCODE_PK2H,  INPUT_1V, OUTPUT_S, 0                  },
-   { "PK2US", OPCODE_PK2US, INPUT_1V, OUTPUT_S, 0                  },
-   { "PK4B",  OPCODE_PK4B,  INPUT_1V, OUTPUT_S, 0                  },
-   { "PK4UB", OPCODE_PK4UB, INPUT_1V, OUTPUT_S, 0                  },
-   { "POW", OPCODE_POW, INPUT_2S, OUTPUT_S, _R | _H |      _C | _S },
-   { "RCP", OPCODE_RCP, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
-   { "RFL", OPCODE_RFL, INPUT_2V, OUTPUT_V, _R | _H |      _C | _S },
-   { "RSQ", OPCODE_RSQ, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
-   { "SEQ", OPCODE_SEQ, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "SFL", OPCODE_SFL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "SGE", OPCODE_SGE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "SGT", OPCODE_SGT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "SIN", OPCODE_SIN, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
-   { "SLE", OPCODE_SLE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "SLT", OPCODE_SLT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "SNE", OPCODE_SNE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "STR", OPCODE_STR, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "SUB", OPCODE_SUB, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "TEX", OPCODE_TEX, INPUT_1V_T, OUTPUT_V,              _C | _S },
-   { "TXD", OPCODE_TXD, INPUT_3V_T, OUTPUT_V,              _C | _S },
-   { "TXP", OPCODE_TXP_NV, INPUT_1V_T, OUTPUT_V,           _C | _S },
-   { "UP2H",  OPCODE_UP2H,  INPUT_1S, OUTPUT_V,            _C | _S },
-   { "UP2US", OPCODE_UP2US, INPUT_1S, OUTPUT_V,            _C | _S },
-   { "UP4B",  OPCODE_UP4B,  INPUT_1S, OUTPUT_V,            _C | _S },
-   { "UP4UB", OPCODE_UP4UB, INPUT_1S, OUTPUT_V,            _C | _S },
-   { "X2D", OPCODE_X2D, INPUT_3V, OUTPUT_V, _R | _H |      _C | _S },
-   { "PRINT", OPCODE_PRINT, INPUT_1V_S, OUTPUT_NONE, 0               },
-   { NULL, (enum prog_opcode) -1, 0, 0, 0 }
-};
-
-
-/*
- * Information needed or computed during parsing.
- * Remember, we can't modify the target program object until we've
- * _successfully_ parsed the program text.
- */
-struct parse_state {
-   GLcontext *ctx;
-   const GLubyte *start;              /* start of program string */
-   const GLubyte *pos;                /* current position */
-   const GLubyte *curLine;
-   struct gl_fragment_program *program;  /* current program */
-
-   struct gl_program_parameter_list *parameters;
-
-   GLuint numInst;                    /* number of instructions parsed */
-   GLuint inputsRead;                 /* bitmask of input registers used */
-   GLuint outputsWritten;             /* bitmask of 1 << FRAG_OUTPUT_* bits */
-   GLuint texturesUsed[MAX_TEXTURE_IMAGE_UNITS];
-};
-
-
-
-/*
- * Called whenever we find an error during parsing.
- */
-static void
-record_error(struct parse_state *parseState, const char *msg, int lineNo)
-{
-#ifdef DEBUG
-   GLint line, column;
-   const GLubyte *lineStr;
-   lineStr = _mesa_find_line_column(parseState->start,
-                                    parseState->pos, &line, &column);
-   _mesa_debug(parseState->ctx,
-               "nvfragparse.c(%d): line %d, column %d:%s (%s)\n",
-               lineNo, line, column, (char *) lineStr, msg);
-   free((void *) lineStr);
-#else
-   (void) lineNo;
-#endif
-
-   /* Check that no error was already recorded.  Only record the first one. */
-   if (parseState->ctx->Program.ErrorString[0] == 0) {
-      _mesa_set_program_error(parseState->ctx,
-                              parseState->pos - parseState->start,
-                              msg);
-   }
-}
-
-
-#define RETURN_ERROR                                                   \
-do {                                                                   \
-   record_error(parseState, "Unexpected end of input.", __LINE__);     \
-   return GL_FALSE;                                                    \
-} while(0)
-
-#define RETURN_ERROR1(msg)                                             \
-do {                                                                   \
-   record_error(parseState, msg, __LINE__);                            \
-   return GL_FALSE;                                                    \
-} while(0)
-
-#define RETURN_ERROR2(msg1, msg2)                                      \
-do {                                                                   \
-   char err[1000];                                                     \
-   sprintf(err, "%s %s", msg1, msg2);                          \
-   record_error(parseState, err, __LINE__);                            \
-   return GL_FALSE;                                                    \
-} while(0)
-
-
-
-
-/*
- * Search a list of instruction structures for a match.
- */
-static struct instruction_pattern
-MatchInstruction(const GLubyte *token)
-{
-   const struct instruction_pattern *inst;
-   struct instruction_pattern result;
-
-   result.name = NULL;
-   result.opcode = MAX_OPCODE; /* i.e. invalid instruction */
-   result.inputs = 0;
-   result.outputs = 0;
-   result.suffixes = 0;
-
-   for (inst = Instructions; inst->name; inst++) {
-      if (strncmp((const char *) token, inst->name, 3) == 0) {
-         /* matched! */
-         int i = 3;
-         result = *inst;
-         result.suffixes = 0;
-         /* look at suffix */
-         if (token[i] == 'R') {
-            result.suffixes |= _R;
-            i++;
-         }
-         else if (token[i] == 'H') {
-            result.suffixes |= _H;
-            i++;
-         }
-         else if (token[i] == 'X') {
-            result.suffixes |= _X;
-            i++;
-         }
-         if (token[i] == 'C') {
-            result.suffixes |= _C;
-            i++;
-         }
-         if (token[i] == '_' && token[i+1] == 'S' &&
-             token[i+2] == 'A' && token[i+3] == 'T') {
-            result.suffixes |= _S;
-         }
-         return result;
-      }
-   }
-
-   return result;
-}
-
-
-
-
-/**********************************************************************/
-
-
-static GLboolean IsLetter(GLubyte b)
-{
-   return (b >= 'a' && b <= 'z') ||
-          (b >= 'A' && b <= 'Z') ||
-          (b == '_') ||
-          (b == '$');
-}
-
-
-static GLboolean IsDigit(GLubyte b)
-{
-   return b >= '0' && b <= '9';
-}
-
-
-static GLboolean IsWhitespace(GLubyte b)
-{
-   return b == ' ' || b == '\t' || b == '\n' || b == '\r';
-}
-
-
-/**
- * Starting at 'str' find the next token.  A token can be an integer,
- * an identifier or punctuation symbol.
- * \return <= 0 we found an error, else, return number of characters parsed.
- */
-static GLint
-GetToken(struct parse_state *parseState, GLubyte *token)
-{
-   const GLubyte *str = parseState->pos;
-   GLint i = 0, j = 0;
-
-   token[0] = 0;
-
-   /* skip whitespace and comments */
-   while (str[i] && (IsWhitespace(str[i]) || str[i] == '#')) {
-      if (str[i] == '#') {
-         /* skip comment */
-         while (str[i] && (str[i] != '\n' && str[i] != '\r')) {
-            i++;
-         }
-         if (str[i] == '\n' || str[i] == '\r')
-            parseState->curLine = str + i + 1;
-      }
-      else {
-         /* skip whitespace */
-         if (str[i] == '\n' || str[i] == '\r')
-            parseState->curLine = str + i + 1;
-         i++;
-      }
-   }
-
-   if (str[i] == 0)
-      return -i;
-
-   /* try matching an integer */
-   while (str[i] && IsDigit(str[i])) {
-      token[j++] = str[i++];
-   }
-   if (j > 0 || !str[i]) {
-      token[j] = 0;
-      return i;
-   }
-
-   /* try matching an identifier */
-   if (IsLetter(str[i])) {
-      while (str[i] && (IsLetter(str[i]) || IsDigit(str[i]))) {
-         token[j++] = str[i++];
-      }
-      token[j] = 0;
-      return i;
-   }
-
-   /* punctuation character */
-   if (str[i]) {
-      token[0] = str[i++];
-      token[1] = 0;
-      return i;
-   }
-
-   /* end of input */
-   token[0] = 0;
-   return i;
-}
-
-
-/**
- * Get next token from input stream and increment stream pointer past token.
- */
-static GLboolean
-Parse_Token(struct parse_state *parseState, GLubyte *token)
-{
-   GLint i;
-   i = GetToken(parseState, token);
-   if (i <= 0) {
-      parseState->pos += (-i);
-      return GL_FALSE;
-   }
-   parseState->pos += i;
-   return GL_TRUE;
-}
-
-
-/**
- * Get next token from input stream but don't increment stream pointer.
- */
-static GLboolean
-Peek_Token(struct parse_state *parseState, GLubyte *token)
-{
-   GLint i, len;
-   i = GetToken(parseState, token);
-   if (i <= 0) {
-      parseState->pos += (-i);
-      return GL_FALSE;
-   }
-   len = (GLint) strlen((const char *) token);
-   parseState->pos += (i - len);
-   return GL_TRUE;
-}
-
-
-/**********************************************************************/
-
-static const char *InputRegisters[MAX_NV_FRAGMENT_PROGRAM_INPUTS + 1] = {
-   "WPOS", "COL0", "COL1", "FOGC",
-   "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL
-};
-
-
-
-/**********************************************************************/
-
-/**
- * Try to match 'pattern' as the next token after any whitespace/comments.
- */
-static GLboolean
-Parse_String(struct parse_state *parseState, const char *pattern)
-{
-   const GLubyte *m;
-   GLint i;
-
-   /* skip whitespace and comments */
-   while (IsWhitespace(*parseState->pos) || *parseState->pos == '#') {
-      if (*parseState->pos == '#') {
-         while (*parseState->pos && (*parseState->pos != '\n' && *parseState->pos != '\r')) {
-            parseState->pos += 1;
-         }
-         if (*parseState->pos == '\n' || *parseState->pos == '\r')
-            parseState->curLine = parseState->pos + 1;
-      }
-      else {
-         /* skip whitespace */
-         if (*parseState->pos == '\n' || *parseState->pos == '\r')
-            parseState->curLine = parseState->pos + 1;
-         parseState->pos += 1;
-      }
-   }
-
-   /* Try to match the pattern */
-   m = parseState->pos;
-   for (i = 0; pattern[i]; i++) {
-      if (*m != (GLubyte) pattern[i])
-         return GL_FALSE;
-      m += 1;
-   }
-   parseState->pos = m;
-
-   return GL_TRUE; /* success */
-}
-
-
-static GLboolean
-Parse_Identifier(struct parse_state *parseState, GLubyte *ident)
-{
-   if (!Parse_Token(parseState, ident))
-      RETURN_ERROR;
-   if (IsLetter(ident[0]))
-      return GL_TRUE;
-   else
-      RETURN_ERROR1("Expected an identfier");
-}
-
-
-/**
- * Parse a floating point constant, or a defined symbol name.
- * [+/-]N[.N[eN]]
- * Output:  number[0 .. 3] will get the value.
- */
-static GLboolean
-Parse_ScalarConstant(struct parse_state *parseState, GLfloat *number)
-{
-   char *end = NULL;
-
-   *number = (GLfloat) _mesa_strtof((const char *) parseState->pos, &end);
-
-   if (end && end > (char *) parseState->pos) {
-      /* got a number */
-      parseState->pos = (GLubyte *) end;
-      number[1] = *number;
-      number[2] = *number;
-      number[3] = *number;
-      return GL_TRUE;
-   }
-   else {
-      /* should be an identifier */
-      GLubyte ident[100];
-      const GLfloat *constant;
-      if (!Parse_Identifier(parseState, ident))
-         RETURN_ERROR1("Expected an identifier");
-      constant = _mesa_lookup_parameter_value(parseState->parameters,
-                                              -1, (const char *) ident);
-      /* XXX Check that it's a constant and not a parameter */
-      if (!constant) {
-         RETURN_ERROR1("Undefined symbol");
-      }
-      else {
-         COPY_4V(number, constant);
-         return GL_TRUE;
-      }
-   }
-}
-
-
-
-/**
- * Parse a vector constant, one of:
- *   { float }
- *   { float, float }
- *   { float, float, float }
- *   { float, float, float, float }
- */
-static GLboolean
-Parse_VectorConstant(struct parse_state *parseState, GLfloat *vec)
-{
-   /* "{" was already consumed */
-
-   ASSIGN_4V(vec, 0.0, 0.0, 0.0, 1.0);
-
-   if (!Parse_ScalarConstant(parseState, vec+0))  /* X */
-      return GL_FALSE;
-
-   if (Parse_String(parseState, "}")) {
-      return GL_TRUE;
-   }
-
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR1("Expected comma in vector constant");
-
-   if (!Parse_ScalarConstant(parseState, vec+1))  /* Y */
-      return GL_FALSE;
-
-   if (Parse_String(parseState, "}")) {
-      return GL_TRUE;
-   }
-
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR1("Expected comma in vector constant");
-
-   if (!Parse_ScalarConstant(parseState, vec+2))  /* Z */
-      return GL_FALSE;
-
-   if (Parse_String(parseState, "}")) {
-      return GL_TRUE;
-   }
-
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR1("Expected comma in vector constant");
-
-   if (!Parse_ScalarConstant(parseState, vec+3))  /* W */
-      return GL_FALSE;
-
-   if (!Parse_String(parseState, "}"))
-      RETURN_ERROR1("Expected closing brace in vector constant");
-
-   return GL_TRUE;
-}
-
-
-/**
- * Parse <number>, <varname> or {a, b, c, d}.
- * Return number of values in the vector or scalar, or zero if parse error.
- */
-static GLuint
-Parse_VectorOrScalarConstant(struct parse_state *parseState, GLfloat *vec)
-{
-   if (Parse_String(parseState, "{")) {
-      return Parse_VectorConstant(parseState, vec);
-   }
-   else {
-      GLboolean b = Parse_ScalarConstant(parseState, vec);
-      if (b) {
-         vec[1] = vec[2] = vec[3] = vec[0];
-      }
-      return b;
-   }
-}
-
-
-/**
- * Parse a texture image source:
- *    [TEX0 | TEX1 | .. | TEX15] , [1D | 2D | 3D | CUBE | RECT]
- */
-static GLboolean
-Parse_TextureImageId(struct parse_state *parseState,
-                     GLubyte *texUnit, GLubyte *texTargetBit)
-{
-   GLubyte imageSrc[100];
-   GLint unit;
-
-   if (!Parse_Token(parseState, imageSrc))
-      RETURN_ERROR;
-   
-   if (imageSrc[0] != 'T' ||
-       imageSrc[1] != 'E' ||
-       imageSrc[2] != 'X') {
-      RETURN_ERROR1("Expected TEX# source");
-   }
-   unit = atoi((const char *) imageSrc + 3);
-   if ((unit < 0 || unit > MAX_TEXTURE_IMAGE_UNITS) ||
-       (unit == 0 && (imageSrc[3] != '0' || imageSrc[4] != 0))) {
-      RETURN_ERROR1("Invalied TEX# source index");
-   }
-   *texUnit = unit;
-
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR1("Expected ,");
-
-   if (Parse_String(parseState, "1D")) {
-      *texTargetBit = TEXTURE_1D_BIT;
-   }
-   else if (Parse_String(parseState, "2D")) {
-      *texTargetBit = TEXTURE_2D_BIT;
-   }
-   else if (Parse_String(parseState, "3D")) {
-      *texTargetBit = TEXTURE_3D_BIT;
-   }
-   else if (Parse_String(parseState, "CUBE")) {
-      *texTargetBit = TEXTURE_CUBE_BIT;
-   }
-   else if (Parse_String(parseState, "RECT")) {
-      *texTargetBit = TEXTURE_RECT_BIT;
-   }
-   else {
-      RETURN_ERROR1("Invalid texture target token");
-   }
-
-   /* update record of referenced texture units */
-   parseState->texturesUsed[*texUnit] |= *texTargetBit;
-   if (_mesa_bitcount(parseState->texturesUsed[*texUnit]) > 1) {
-      RETURN_ERROR1("Only one texture target can be used per texture unit.");
-   }
-
-   return GL_TRUE;
-}
-
-
-/**
- * Parse a scalar suffix like .x, .y, .z or .w or parse a swizzle suffix
- * like .wxyz, .xxyy, etc and return the swizzle indexes.
- */
-static GLboolean
-Parse_SwizzleSuffix(const GLubyte *token, GLuint swizzle[4])
-{
-   if (token[1] == 0) {
-      /* single letter swizzle (scalar) */
-      if (token[0] == 'x')
-         ASSIGN_4V(swizzle, 0, 0, 0, 0);
-      else if (token[0] == 'y')
-         ASSIGN_4V(swizzle, 1, 1, 1, 1);
-      else if (token[0] == 'z')
-         ASSIGN_4V(swizzle, 2, 2, 2, 2);
-      else if (token[0] == 'w')
-         ASSIGN_4V(swizzle, 3, 3, 3, 3);
-      else
-         return GL_FALSE;
-   }
-   else {
-      /* 4-component swizzle (vector) */
-      GLint k;
-      for (k = 0; k < 4 && token[k]; k++) {
-         if (token[k] == 'x')
-            swizzle[k] = 0;
-         else if (token[k] == 'y')
-            swizzle[k] = 1;
-         else if (token[k] == 'z')
-            swizzle[k] = 2;
-         else if (token[k] == 'w')
-            swizzle[k] = 3;
-         else
-            return GL_FALSE;
-      }
-      if (k != 4)
-         return GL_FALSE;
-   }
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_CondCodeMask(struct parse_state *parseState,
-                   struct prog_dst_register *dstReg)
-{
-   if (Parse_String(parseState, "EQ"))
-      dstReg->CondMask = COND_EQ;
-   else if (Parse_String(parseState, "GE"))
-      dstReg->CondMask = COND_GE;
-   else if (Parse_String(parseState, "GT"))
-      dstReg->CondMask = COND_GT;
-   else if (Parse_String(parseState, "LE"))
-      dstReg->CondMask = COND_LE;
-   else if (Parse_String(parseState, "LT"))
-      dstReg->CondMask = COND_LT;
-   else if (Parse_String(parseState, "NE"))
-      dstReg->CondMask = COND_NE;
-   else if (Parse_String(parseState, "TR"))
-      dstReg->CondMask = COND_TR;
-   else if (Parse_String(parseState, "FL"))
-      dstReg->CondMask = COND_FL;
-   else
-      RETURN_ERROR1("Invalid condition code mask");
-
-   /* look for optional .xyzw swizzle */
-   if (Parse_String(parseState, ".")) {
-      GLubyte token[100];
-      GLuint swz[4];
-
-      if (!Parse_Token(parseState, token))  /* get xyzw suffix */
-         RETURN_ERROR;
-
-      if (!Parse_SwizzleSuffix(token, swz))
-         RETURN_ERROR1("Invalid swizzle suffix");
-
-      dstReg->CondSwizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
-   }
-
-   return GL_TRUE;
-}
-
-
-/**
- * Parse a temporary register: Rnn or Hnn
- */
-static GLboolean
-Parse_TempReg(struct parse_state *parseState, GLint *tempRegNum)
-{
-   GLubyte token[100];
-
-   /* Should be 'R##' or 'H##' */
-   if (!Parse_Token(parseState, token))
-      RETURN_ERROR;
-   if (token[0] != 'R' && token[0] != 'H')
-      RETURN_ERROR1("Expected R## or H##");
-
-   if (IsDigit(token[1])) {
-      GLint reg = atoi((const char *) (token + 1));
-      if (token[0] == 'H')
-         reg += 32;
-      if (reg >= MAX_NV_FRAGMENT_PROGRAM_TEMPS)
-         RETURN_ERROR1("Invalid temporary register name");
-      *tempRegNum = reg;
-   }
-   else {
-      RETURN_ERROR1("Invalid temporary register name");
-   }
-
-   return GL_TRUE;
-}
-
-
-/**
- * Parse a write-only dummy register: RC or HC.
- */
-static GLboolean
-Parse_DummyReg(struct parse_state *parseState, GLint *regNum)
-{
-   if (Parse_String(parseState, "RC")) {
-       *regNum = 0;
-   }
-   else if (Parse_String(parseState, "HC")) {
-       *regNum = 1;
-   }
-   else {
-      RETURN_ERROR1("Invalid write-only register name");
-   }
-
-   return GL_TRUE;
-}
-
-
-/**
- * Parse a program local parameter register "p[##]"
- */
-static GLboolean
-Parse_ProgramParamReg(struct parse_state *parseState, GLint *regNum)
-{
-   GLubyte token[100];
-
-   if (!Parse_String(parseState, "p["))
-      RETURN_ERROR1("Expected p[");
-
-   if (!Parse_Token(parseState, token))
-      RETURN_ERROR;
-
-   if (IsDigit(token[0])) {
-      /* a numbered program parameter register */
-      GLint reg = atoi((const char *) token);
-      if (reg >= MAX_NV_FRAGMENT_PROGRAM_PARAMS)
-         RETURN_ERROR1("Invalid constant program number");
-      *regNum = reg;
-   }
-   else {
-      RETURN_ERROR;
-   }
-
-   if (!Parse_String(parseState, "]"))
-      RETURN_ERROR1("Expected ]");
-
-   return GL_TRUE;
-}
-
-
-/**
- * Parse f[name]  - fragment input register
- */
-static GLboolean
-Parse_FragReg(struct parse_state *parseState, GLint *tempRegNum)
-{
-   GLubyte token[100];
-   GLint j;
-
-   /* Match 'f[' */
-   if (!Parse_String(parseState, "f["))
-      RETURN_ERROR1("Expected f[");
-
-   /* get <name> and look for match */
-   if (!Parse_Token(parseState, token)) {
-      RETURN_ERROR;
-   }
-   for (j = 0; InputRegisters[j]; j++) {
-      if (strcmp((const char *) token, InputRegisters[j]) == 0) {
-         *tempRegNum = j;
-         parseState->inputsRead |= (1 << j);
-         break;
-      }
-   }
-   if (!InputRegisters[j]) {
-      /* unknown input register label */
-      RETURN_ERROR2("Invalid register name", token);
-   }
-
-   /* Match '[' */
-   if (!Parse_String(parseState, "]"))
-      RETURN_ERROR1("Expected ]");
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum)
-{
-   GLubyte token[100];
-
-   /* Match "o[" */
-   if (!Parse_String(parseState, "o["))
-      RETURN_ERROR1("Expected o[");
-
-   /* Get output reg name */
-   if (!Parse_Token(parseState, token))
-      RETURN_ERROR;
-
-   /* try to match an output register name */
-   if (strcmp((char *) token, "COLR") == 0 ||
-       strcmp((char *) token, "COLH") == 0) {
-      /* note that we don't distinguish between COLR and COLH */
-      *outputRegNum = FRAG_RESULT_COLOR;
-      parseState->outputsWritten |= (1 << FRAG_RESULT_COLOR);
-   }
-   else if (strcmp((char *) token, "DEPR") == 0) {
-      *outputRegNum = FRAG_RESULT_DEPTH;
-      parseState->outputsWritten |= (1 << FRAG_RESULT_DEPTH);
-   }
-   else {
-      RETURN_ERROR1("Invalid output register name");
-   }
-
-   /* Match ']' */
-   if (!Parse_String(parseState, "]"))
-      RETURN_ERROR1("Expected ]");
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_MaskedDstReg(struct parse_state *parseState,
-                   struct prog_dst_register *dstReg)
-{
-   GLubyte token[100];
-   GLint idx;
-
-   /* Dst reg can be R<n>, H<n>, o[n], RC or HC */
-   if (!Peek_Token(parseState, token))
-      RETURN_ERROR;
-
-   if (strcmp((const char *) token, "RC") == 0 ||
-       strcmp((const char *) token, "HC") == 0) {
-      /* a write-only register */
-      dstReg->File = PROGRAM_WRITE_ONLY;
-      if (!Parse_DummyReg(parseState, &idx))
-         RETURN_ERROR;
-      dstReg->Index = idx;
-   }
-   else if (token[0] == 'R' || token[0] == 'H') {
-      /* a temporary register */
-      dstReg->File = PROGRAM_TEMPORARY;
-      if (!Parse_TempReg(parseState, &idx))
-         RETURN_ERROR;
-      dstReg->Index = idx;
-   }
-   else if (token[0] == 'o') {
-      /* an output register */
-      dstReg->File = PROGRAM_OUTPUT;
-      if (!Parse_OutputReg(parseState, &idx))
-         RETURN_ERROR;
-      dstReg->Index = idx;
-   }
-   else {
-      RETURN_ERROR1("Invalid destination register name");
-   }
-
-   /* Parse optional write mask */
-   if (Parse_String(parseState, ".")) {
-      /* got a mask */
-      GLint k = 0;
-
-      if (!Parse_Token(parseState, token))  /* get xyzw writemask */
-         RETURN_ERROR;
-
-      dstReg->WriteMask = 0;
-
-      if (token[k] == 'x') {
-         dstReg->WriteMask |= WRITEMASK_X;
-         k++;
-      }
-      if (token[k] == 'y') {
-         dstReg->WriteMask |= WRITEMASK_Y;
-         k++;
-      }
-      if (token[k] == 'z') {
-         dstReg->WriteMask |= WRITEMASK_Z;
-         k++;
-      }
-      if (token[k] == 'w') {
-         dstReg->WriteMask |= WRITEMASK_W;
-         k++;
-      }
-      if (k == 0) {
-         RETURN_ERROR1("Invalid writemask character");
-      }
-
-   }
-   else {
-      dstReg->WriteMask = WRITEMASK_XYZW;
-   }
-
-   /* optional condition code mask */
-   if (Parse_String(parseState, "(")) {
-      /* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".x|y|z|w) */
-      /* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".[xyzw]) */
-      if (!Parse_CondCodeMask(parseState, dstReg))
-         RETURN_ERROR;
-
-      if (!Parse_String(parseState, ")"))  /* consume ")" */
-         RETURN_ERROR1("Expected )");
-
-      return GL_TRUE;
-   }
-   else {
-      /* no cond code mask */
-      dstReg->CondMask = COND_TR;
-      dstReg->CondSwizzle = SWIZZLE_NOOP;
-      return GL_TRUE;
-   }
-}
-
-
-/**
- * Parse a vector source (register, constant, etc):
- *   <vectorSrc>    ::= <absVectorSrc>
- *                    | <baseVectorSrc>
- *   <absVectorSrc> ::= <negate> "|" <baseVectorSrc> "|"
- */
-static GLboolean
-Parse_VectorSrc(struct parse_state *parseState,
-                struct prog_src_register *srcReg)
-{
-   GLfloat sign = 1.0F;
-   GLubyte token[100];
-   GLint idx;
-   GLuint negateBase, negateAbs;
-
-   /*
-    * First, take care of +/- and absolute value stuff.
-    */
-   if (Parse_String(parseState, "-"))
-      sign = -1.0F;
-   else if (Parse_String(parseState, "+"))
-      sign = +1.0F;
-
-   if (Parse_String(parseState, "|")) {
-      srcReg->Abs = GL_TRUE;
-      negateAbs = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
-
-      if (Parse_String(parseState, "-"))
-         negateBase = NEGATE_XYZW;
-      else if (Parse_String(parseState, "+"))
-         negateBase = NEGATE_NONE;
-      else
-         negateBase = NEGATE_NONE;
-   }
-   else {
-      srcReg->Abs = GL_FALSE;
-      negateAbs = NEGATE_NONE;
-      negateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
-   }
-
-   srcReg->Negate = srcReg->Abs ? negateAbs : negateBase;
-
-   /* This should be the real src vector/register name */
-   if (!Peek_Token(parseState, token))
-      RETURN_ERROR;
-
-   /* Src reg can be Rn, Hn, f[n], p[n], a named parameter, a scalar
-    * literal or vector literal.
-    */
-   if (token[0] == 'R' || token[0] == 'H') {
-      srcReg->File = PROGRAM_TEMPORARY;
-      if (!Parse_TempReg(parseState, &idx))
-         RETURN_ERROR;
-      srcReg->Index = idx;
-   }
-   else if (token[0] == 'f') {
-      /* XXX this might be an identifier! */
-      srcReg->File = PROGRAM_INPUT;
-      if (!Parse_FragReg(parseState, &idx))
-         RETURN_ERROR;
-      srcReg->Index = idx;
-   }
-   else if (token[0] == 'p') {
-      /* XXX this might be an identifier! */
-      srcReg->File = PROGRAM_LOCAL_PARAM;
-      if (!Parse_ProgramParamReg(parseState, &idx))
-         RETURN_ERROR;
-      srcReg->Index = idx;
-   }
-   else if (IsLetter(token[0])){
-      GLubyte ident[100];
-      GLint paramIndex;
-      if (!Parse_Identifier(parseState, ident))
-         RETURN_ERROR;
-      paramIndex = _mesa_lookup_parameter_index(parseState->parameters,
-                                                -1, (const char *) ident);
-      if (paramIndex < 0) {
-         RETURN_ERROR2("Undefined constant or parameter: ", ident);
-      }
-      srcReg->File = PROGRAM_NAMED_PARAM;
-      srcReg->Index = paramIndex;      
-   }
-   else if (IsDigit(token[0]) || token[0] == '-' || token[0] == '+' || token[0] == '.'){
-      /* literal scalar constant */
-      GLfloat values[4];
-      GLuint paramIndex;
-      if (!Parse_ScalarConstant(parseState, values))
-         RETURN_ERROR;
-      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
-                                              values, 4, NULL);
-      srcReg->File = PROGRAM_NAMED_PARAM;
-      srcReg->Index = paramIndex;
-   }
-   else if (token[0] == '{'){
-      /* literal vector constant */
-      GLfloat values[4];
-      GLuint paramIndex;
-      (void) Parse_String(parseState, "{");
-      if (!Parse_VectorConstant(parseState, values))
-         RETURN_ERROR;
-      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
-                                              values, 4, NULL);
-      srcReg->File = PROGRAM_NAMED_PARAM;
-      srcReg->Index = paramIndex;      
-   }
-   else {
-      RETURN_ERROR2("Invalid source register name", token);
-   }
-
-   /* init swizzle fields */
-   srcReg->Swizzle = SWIZZLE_NOOP;
-
-   /* Look for optional swizzle suffix */
-   if (Parse_String(parseState, ".")) {
-      GLuint swz[4];
-
-      if (!Parse_Token(parseState, token))
-         RETURN_ERROR;
-
-      if (!Parse_SwizzleSuffix(token, swz))
-         RETURN_ERROR1("Invalid swizzle suffix");
-
-      srcReg->Swizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
-   }
-
-   /* Finish absolute value */
-   if (srcReg->Abs && !Parse_String(parseState, "|")) {
-      RETURN_ERROR1("Expected |");
-   }
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_ScalarSrcReg(struct parse_state *parseState,
-                   struct prog_src_register *srcReg)
-{
-   GLubyte token[100];
-   GLfloat sign = 1.0F;
-   GLboolean needSuffix = GL_TRUE;
-   GLint idx;
-   GLuint negateBase, negateAbs;
-
-   /*
-    * First, take care of +/- and absolute value stuff.
-    */
-   if (Parse_String(parseState, "-"))
-      sign = -1.0F;
-   else if (Parse_String(parseState, "+"))
-      sign = +1.0F;
-
-   if (Parse_String(parseState, "|")) {
-      srcReg->Abs = GL_TRUE;
-      negateAbs = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
-
-      if (Parse_String(parseState, "-"))
-         negateBase = NEGATE_XYZW;
-      else if (Parse_String(parseState, "+"))
-         negateBase = NEGATE_NONE;
-      else
-         negateBase = NEGATE_NONE;
-   }
-   else {
-      srcReg->Abs = GL_FALSE;
-      negateAbs = NEGATE_NONE;
-      negateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
-   }
-
-   srcReg->Negate = srcReg->Abs ? negateAbs : negateBase;
-
-   if (!Peek_Token(parseState, token))
-      RETURN_ERROR;
-
-   /* Src reg can be R<n>, H<n> or a named fragment attrib */
-   if (token[0] == 'R' || token[0] == 'H') {
-      srcReg->File = PROGRAM_TEMPORARY;
-      if (!Parse_TempReg(parseState, &idx))
-         RETURN_ERROR;
-      srcReg->Index = idx;
-   }
-   else if (token[0] == 'f') {
-      srcReg->File = PROGRAM_INPUT;
-      if (!Parse_FragReg(parseState, &idx))
-         RETURN_ERROR;
-      srcReg->Index = idx;
-   }
-   else if (token[0] == '{') {
-      /* vector literal */
-      GLfloat values[4];
-      GLuint paramIndex;
-      (void) Parse_String(parseState, "{");
-      if (!Parse_VectorConstant(parseState, values))
-         RETURN_ERROR;
-      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
-                                              values, 4, NULL);
-      srcReg->File = PROGRAM_NAMED_PARAM;
-      srcReg->Index = paramIndex;      
-   }
-   else if (IsLetter(token[0])){
-      /* named param/constant */
-      GLubyte ident[100];
-      GLint paramIndex;
-      if (!Parse_Identifier(parseState, ident))
-         RETURN_ERROR;
-      paramIndex = _mesa_lookup_parameter_index(parseState->parameters,
-                                                -1, (const char *) ident);
-      if (paramIndex < 0) {
-         RETURN_ERROR2("Undefined constant or parameter: ", ident);
-      }
-      srcReg->File = PROGRAM_NAMED_PARAM;
-      srcReg->Index = paramIndex;      
-   }
-   else if (IsDigit(token[0])) {
-      /* scalar literal */
-      GLfloat values[4];
-      GLuint paramIndex;
-      if (!Parse_ScalarConstant(parseState, values))
-         RETURN_ERROR;
-      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
-                                              values, 4, NULL);
-      srcReg->Index = paramIndex;      
-      srcReg->File = PROGRAM_NAMED_PARAM;
-      needSuffix = GL_FALSE;
-   }
-   else {
-      RETURN_ERROR2("Invalid scalar source argument", token);
-   }
-
-   srcReg->Swizzle = 0;
-   if (needSuffix) {
-      /* parse .[xyzw] suffix */
-      if (!Parse_String(parseState, "."))
-         RETURN_ERROR1("Expected .");
-
-      if (!Parse_Token(parseState, token))
-         RETURN_ERROR;
-
-      if (token[0] == 'x' && token[1] == 0) {
-         srcReg->Swizzle = 0;
-      }
-      else if (token[0] == 'y' && token[1] == 0) {
-         srcReg->Swizzle = 1;
-      }
-      else if (token[0] == 'z' && token[1] == 0) {
-         srcReg->Swizzle = 2;
-      }
-      else if (token[0] == 'w' && token[1] == 0) {
-         srcReg->Swizzle = 3;
-      }
-      else {
-         RETURN_ERROR1("Invalid scalar source suffix");
-      }
-   }
-
-   /* Finish absolute value */
-   if (srcReg->Abs && !Parse_String(parseState, "|")) {
-      RETURN_ERROR1("Expected |");
-   }
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_PrintInstruction(struct parse_state *parseState,
-                       struct prog_instruction *inst)
-{
-   const GLubyte *str;
-   GLubyte *msg;
-   GLuint len;
-   GLint idx;
-
-   /* The first argument is a literal string 'just like this' */
-   if (!Parse_String(parseState, "'"))
-      RETURN_ERROR1("Expected '");
-
-   str = parseState->pos;
-   for (len = 0; str[len] != '\''; len++) /* find closing quote */
-      ;
-   parseState->pos += len + 1;
-   msg = (GLubyte*) malloc(len + 1);
-
-   memcpy(msg, str, len);
-   msg[len] = 0;
-   inst->Data = msg;
-
-   if (Parse_String(parseState, ",")) {
-      /* got an optional register to print */
-      GLubyte token[100];
-      GetToken(parseState, token);
-      if (token[0] == 'o') {
-         /* dst reg */
-         if (!Parse_OutputReg(parseState, &idx))
-            RETURN_ERROR;
-        inst->SrcReg[0].Index = idx;
-         inst->SrcReg[0].File = PROGRAM_OUTPUT;
-      }
-      else {
-         /* src reg */
-         if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
-            RETURN_ERROR;
-      }
-   }
-   else {
-      inst->SrcReg[0].File = PROGRAM_UNDEFINED;
-   }
-
-   inst->SrcReg[0].Swizzle = SWIZZLE_NOOP;
-   inst->SrcReg[0].Abs = GL_FALSE;
-   inst->SrcReg[0].Negate = NEGATE_NONE;
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_InstructionSequence(struct parse_state *parseState,
-                          struct prog_instruction program[])
-{
-   while (1) {
-      struct prog_instruction *inst = program + parseState->numInst;
-      struct instruction_pattern instMatch;
-      GLubyte token[100];
-
-      /* Initialize the instruction */
-      _mesa_init_instructions(inst, 1);
-
-      /* special instructions */
-      if (Parse_String(parseState, "DEFINE")) {
-         GLubyte id[100];
-         GLfloat value[7];  /* yes, 7 to be safe */
-         if (!Parse_Identifier(parseState, id))
-            RETURN_ERROR;
-         /* XXX make sure id is not a reserved identifer, like R9 */
-         if (!Parse_String(parseState, "="))
-            RETURN_ERROR1("Expected =");
-         if (!Parse_VectorOrScalarConstant(parseState, value))
-            RETURN_ERROR;
-         if (!Parse_String(parseState, ";"))
-            RETURN_ERROR1("Expected ;");
-         if (_mesa_lookup_parameter_index(parseState->parameters,
-                                          -1, (const char *) id) >= 0) {
-            RETURN_ERROR2(id, "already defined");
-         }
-         _mesa_add_named_parameter(parseState->parameters,
-                                   (const char *) id, value);
-      }
-      else if (Parse_String(parseState, "DECLARE")) {
-         GLubyte id[100];
-         GLfloat value[7] = {0, 0, 0, 0, 0, 0, 0};  /* yes, to be safe */
-         if (!Parse_Identifier(parseState, id))
-            RETURN_ERROR;
-         /* XXX make sure id is not a reserved identifer, like R9 */
-         if (Parse_String(parseState, "=")) {
-            if (!Parse_VectorOrScalarConstant(parseState, value))
-               RETURN_ERROR;
-         }
-         if (!Parse_String(parseState, ";"))
-            RETURN_ERROR1("Expected ;");
-         if (_mesa_lookup_parameter_index(parseState->parameters,
-                                          -1, (const char *) id) >= 0) {
-            RETURN_ERROR2(id, "already declared");
-         }
-         _mesa_add_named_parameter(parseState->parameters,
-                                   (const char *) id, value);
-      }
-      else if (Parse_String(parseState, "END")) {
-         inst->Opcode = OPCODE_END;
-         parseState->numInst++;
-         if (Parse_Token(parseState, token)) {
-            RETURN_ERROR1("Code after END opcode.");
-         }
-         break;
-      }
-      else {
-         /* general/arithmetic instruction */
-
-         /* get token */
-         if (!Parse_Token(parseState, token)) {
-            RETURN_ERROR1("Missing END instruction.");
-         }
-
-         /* try to find matching instuction */
-         instMatch = MatchInstruction(token);
-         if (instMatch.opcode >= MAX_OPCODE) {
-            /* bad instruction name */
-            RETURN_ERROR2("Unexpected token: ", token);
-         }
-
-         inst->Opcode = instMatch.opcode;
-         inst->Precision = instMatch.suffixes & (_R | _H | _X);
-         inst->SaturateMode = (instMatch.suffixes & (_S))
-            ? SATURATE_ZERO_ONE : SATURATE_OFF;
-         inst->CondUpdate = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE;
-
-         /*
-          * parse the input and output operands
-          */
-         if (instMatch.outputs == OUTPUT_S || instMatch.outputs == OUTPUT_V) {
-            if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
-               RETURN_ERROR;
-            if (!Parse_String(parseState, ","))
-               RETURN_ERROR1("Expected ,");
-         }
-         else if (instMatch.outputs == OUTPUT_NONE) {
-            if (instMatch.opcode == OPCODE_KIL_NV) {
-               /* This is a little weird, the cond code info is in
-                * the dest register.
-                */
-               if (!Parse_CondCodeMask(parseState, &inst->DstReg))
-                  RETURN_ERROR;
-            }
-            else {
-               ASSERT(instMatch.opcode == OPCODE_PRINT);
-            }
-         }
-
-         if (instMatch.inputs == INPUT_1V) {
-            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
-               RETURN_ERROR;
-         }
-         else if (instMatch.inputs == INPUT_2V) {
-            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
-               RETURN_ERROR;
-            if (!Parse_String(parseState, ","))
-               RETURN_ERROR1("Expected ,");
-            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
-               RETURN_ERROR;
-         }
-         else if (instMatch.inputs == INPUT_3V) {
-            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
-               RETURN_ERROR;
-            if (!Parse_String(parseState, ","))
-               RETURN_ERROR1("Expected ,");
-            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
-               RETURN_ERROR;
-            if (!Parse_String(parseState, ","))
-               RETURN_ERROR1("Expected ,");
-            if (!Parse_VectorSrc(parseState, &inst->SrcReg[2]))
-               RETURN_ERROR;
-         }
-         else if (instMatch.inputs == INPUT_1S) {
-            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
-               RETURN_ERROR;
-         }
-         else if (instMatch.inputs == INPUT_2S) {
-            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
-               RETURN_ERROR;
-            if (!Parse_String(parseState, ","))
-               RETURN_ERROR1("Expected ,");
-            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[1]))
-               RETURN_ERROR;
-         }
-         else if (instMatch.inputs == INPUT_CC) {
-            /* XXX to-do */
-         }
-         else if (instMatch.inputs == INPUT_1V_T) {
-           GLubyte unit, idx;
-            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
-               RETURN_ERROR;
-            if (!Parse_String(parseState, ","))
-               RETURN_ERROR1("Expected ,");
-            if (!Parse_TextureImageId(parseState, &unit, &idx))
-               RETURN_ERROR;
-           inst->TexSrcUnit = unit;
-           inst->TexSrcTarget = idx;
-         }
-         else if (instMatch.inputs == INPUT_3V_T) {
-           GLubyte unit, idx;
-            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
-               RETURN_ERROR;
-            if (!Parse_String(parseState, ","))
-               RETURN_ERROR1("Expected ,");
-            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
-               RETURN_ERROR;
-            if (!Parse_String(parseState, ","))
-               RETURN_ERROR1("Expected ,");
-            if (!Parse_VectorSrc(parseState, &inst->SrcReg[2]))
-               RETURN_ERROR;
-            if (!Parse_String(parseState, ","))
-               RETURN_ERROR1("Expected ,");
-            if (!Parse_TextureImageId(parseState, &unit, &idx))
-               RETURN_ERROR;
-           inst->TexSrcUnit = unit;
-           inst->TexSrcTarget = idx;
-         }
-         else if (instMatch.inputs == INPUT_1V_S) {
-            if (!Parse_PrintInstruction(parseState, inst))
-               RETURN_ERROR;
-         }
-
-         /* end of statement semicolon */
-         if (!Parse_String(parseState, ";"))
-            RETURN_ERROR1("Expected ;");
-
-         parseState->numInst++;
-
-         if (parseState->numInst >= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS)
-            RETURN_ERROR1("Program too long");
-      }
-   }
-   return GL_TRUE;
-}
-
-
-
-/**
- * Parse/compile the 'str' returning the compiled 'program'.
- * ctx->Program.ErrorPos will be -1 if successful.  Otherwise, ErrorPos
- * indicates the position of the error in 'str'.
- */
-void
-_mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,
-                                const GLubyte *str, GLsizei len,
-                                struct gl_fragment_program *program)
-{
-   struct parse_state parseState;
-   struct prog_instruction instBuffer[MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS];
-   struct prog_instruction *newInst;
-   GLenum target;
-   GLubyte *programString;
-
-   /* Make a null-terminated copy of the program string */
-   programString = (GLubyte *) MALLOC(len + 1);
-   if (!programString) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
-      return;
-   }
-   memcpy(programString, str, len);
-   programString[len] = 0;
-
-   /* Get ready to parse */
-   memset(&parseState, 0, sizeof(struct parse_state));
-   parseState.ctx = ctx;
-   parseState.start = programString;
-   parseState.program = program;
-   parseState.numInst = 0;
-   parseState.curLine = programString;
-   parseState.parameters = _mesa_new_parameter_list();
-
-   /* Reset error state */
-   _mesa_set_program_error(ctx, -1, NULL);
-
-   /* check the program header */
-   if (strncmp((const char *) programString, "!!FP1.0", 7) == 0) {
-      target = GL_FRAGMENT_PROGRAM_NV;
-      parseState.pos = programString + 7;
-   }
-   else if (strncmp((const char *) programString, "!!FCP1.0", 8) == 0) {
-      /* fragment / register combiner program - not supported */
-      _mesa_set_program_error(ctx, 0, "Invalid fragment program header");
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
-      return;
-   }
-   else {
-      /* invalid header */
-      _mesa_set_program_error(ctx, 0, "Invalid fragment program header");
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
-      return;
-   }
-
-   /* make sure target and header match */
-   if (target != dstTarget) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glLoadProgramNV(target mismatch 0x%x != 0x%x)",
-                  target, dstTarget);
-      return;
-   }
-
-   if (Parse_InstructionSequence(&parseState, instBuffer)) {
-      GLuint u;
-      /* successful parse! */
-
-      if (parseState.outputsWritten == 0) {
-         /* must write at least one output! */
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "Invalid fragment program - no outputs written.");
-         return;
-      }
-
-      /* copy the compiled instructions */
-      assert(parseState.numInst <= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS);
-      newInst = _mesa_alloc_instructions(parseState.numInst);
-      if (!newInst) {
-         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
-         return;  /* out of memory */
-      }
-      _mesa_copy_instructions(newInst, instBuffer, parseState.numInst);
-
-      /* install the program */
-      program->Base.Target = target;
-      if (program->Base.String) {
-         FREE(program->Base.String);
-      }
-      program->Base.String = programString;
-      program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB;
-      if (program->Base.Instructions) {
-         free(program->Base.Instructions);
-      }
-      program->Base.Instructions = newInst;
-      program->Base.NumInstructions = parseState.numInst;
-      program->Base.InputsRead = parseState.inputsRead;
-      program->Base.OutputsWritten = parseState.outputsWritten;
-      for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++)
-         program->Base.TexturesUsed[u] = parseState.texturesUsed[u];
-
-      /* save program parameters */
-      program->Base.Parameters = parseState.parameters;
-
-      /* allocate registers for declared program parameters */
-#if 00
-      _mesa_assign_program_registers(&(program->SymbolTable));
-#endif
-
-#ifdef DEBUG_foo
-      printf("--- glLoadProgramNV(%d) result ---\n", program->Base.Id);
-      _mesa_fprint_program_opt(stdout, &program->Base, PROG_PRINT_NV, 0);
-      printf("----------------------------------\n");
-#endif
-   }
-   else {
-      /* Error! */
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV");
-      /* NOTE: _mesa_set_program_error would have been called already */
-   }
-}
-
-
-const char *
-_mesa_nv_fragment_input_register_name(GLuint i)
-{
-   ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_INPUTS);
-   return InputRegisters[i];
-}
-