12861e737e84e4884109b9526ac645194ba892a74Michal Krol/*
22861e737e84e4884109b9526ac645194ba892a74Michal Krol * Mesa 3-D graphics library
37e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul * Version:  6.5
42861e737e84e4884109b9526ac645194ba892a74Michal Krol *
57e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
62861e737e84e4884109b9526ac645194ba892a74Michal Krol *
72861e737e84e4884109b9526ac645194ba892a74Michal Krol * Permission is hereby granted, free of charge, to any person obtaining a
82861e737e84e4884109b9526ac645194ba892a74Michal Krol * copy of this software and associated documentation files (the "Software"),
92861e737e84e4884109b9526ac645194ba892a74Michal Krol * to deal in the Software without restriction, including without limitation
102861e737e84e4884109b9526ac645194ba892a74Michal Krol * the rights to use, copy, modify, merge, publish, distribute, sublicense,
112861e737e84e4884109b9526ac645194ba892a74Michal Krol * and/or sell copies of the Software, and to permit persons to whom the
122861e737e84e4884109b9526ac645194ba892a74Michal Krol * Software is furnished to do so, subject to the following conditions:
132861e737e84e4884109b9526ac645194ba892a74Michal Krol *
142861e737e84e4884109b9526ac645194ba892a74Michal Krol * The above copyright notice and this permission notice shall be included
152861e737e84e4884109b9526ac645194ba892a74Michal Krol * in all copies or substantial portions of the Software.
162861e737e84e4884109b9526ac645194ba892a74Michal Krol *
172861e737e84e4884109b9526ac645194ba892a74Michal Krol * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
182861e737e84e4884109b9526ac645194ba892a74Michal Krol * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
192861e737e84e4884109b9526ac645194ba892a74Michal Krol * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
202861e737e84e4884109b9526ac645194ba892a74Michal Krol * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
212861e737e84e4884109b9526ac645194ba892a74Michal Krol * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
222861e737e84e4884109b9526ac645194ba892a74Michal Krol * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
232861e737e84e4884109b9526ac645194ba892a74Michal Krol */
242861e737e84e4884109b9526ac645194ba892a74Michal Krol
252861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
262861e737e84e4884109b9526ac645194ba892a74Michal Krol * \file nvfragparse.c
272861e737e84e4884109b9526ac645194ba892a74Michal Krol * NVIDIA fragment program parser.
282861e737e84e4884109b9526ac645194ba892a74Michal Krol * \author Brian Paul
292861e737e84e4884109b9526ac645194ba892a74Michal Krol */
302861e737e84e4884109b9526ac645194ba892a74Michal Krol
312861e737e84e4884109b9526ac645194ba892a74Michal Krol/*
322861e737e84e4884109b9526ac645194ba892a74Michal Krol * Regarding GL_NV_fragment_program:
332861e737e84e4884109b9526ac645194ba892a74Michal Krol *
342861e737e84e4884109b9526ac645194ba892a74Michal Krol * Portions of this software may use or implement intellectual
352861e737e84e4884109b9526ac645194ba892a74Michal Krol * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims
362861e737e84e4884109b9526ac645194ba892a74Michal Krol * any and all warranties with respect to such intellectual property,
372861e737e84e4884109b9526ac645194ba892a74Michal Krol * including any use thereof or modifications thereto.
382861e737e84e4884109b9526ac645194ba892a74Michal Krol */
392861e737e84e4884109b9526ac645194ba892a74Michal Krol
40bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h"
41bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/context.h"
42bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/imports.h"
43bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/macros.h"
44bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "program.h"
45c0551f0a465b577a17698ede46370a17e29b3df7Brian#include "prog_parameter.h"
46fe278f1e600058af18c6ba5fe77bfc5a772bf9f5Brian Paul#include "prog_print.h"
47c0551f0a465b577a17698ede46370a17e29b3df7Brian#include "prog_instruction.h"
482861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "nvfragparse.h"
492861e737e84e4884109b9526ac645194ba892a74Michal Krol
502861e737e84e4884109b9526ac645194ba892a74Michal Krol
512861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_1V     1
522861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_2V     2
532861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_3V     3
542861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_1S     4
552861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_2S     5
562861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_CC     6
572861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_1V_T   7  /* one source vector, plus textureId */
582861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_3V_T   8  /* one source vector, plus textureId */
592861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_NONE   9
602a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul#define INPUT_1V_S  10  /* a string and a vector register */
612861e737e84e4884109b9526ac645194ba892a74Michal Krol#define OUTPUT_V    20
622861e737e84e4884109b9526ac645194ba892a74Michal Krol#define OUTPUT_S    21
632861e737e84e4884109b9526ac645194ba892a74Michal Krol#define OUTPUT_NONE 22
642861e737e84e4884109b9526ac645194ba892a74Michal Krol
652861e737e84e4884109b9526ac645194ba892a74Michal Krol/* IRIX defines some of these */
662861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _R
672861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _H
682861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _X
692861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _C
702861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _S
712861e737e84e4884109b9526ac645194ba892a74Michal Krol
722861e737e84e4884109b9526ac645194ba892a74Michal Krol/* Optional suffixes */
732861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _R  FLOAT32  /* float */
742861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _H  FLOAT16  /* half-float */
752861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _X  FIXED12  /* fixed */
762861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _C  0x08     /* set cond codes */
772861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _S  0x10     /* saturate, clamp result to [0,1] */
782861e737e84e4884109b9526ac645194ba892a74Michal Krol
792861e737e84e4884109b9526ac645194ba892a74Michal Krolstruct instruction_pattern {
802861e737e84e4884109b9526ac645194ba892a74Michal Krol   const char *name;
817e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   enum prog_opcode opcode;
822861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLuint inputs;
832861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLuint outputs;
842861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLuint suffixes;
852861e737e84e4884109b9526ac645194ba892a74Michal Krol};
862861e737e84e4884109b9526ac645194ba892a74Michal Krol
872861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic const struct instruction_pattern Instructions[] = {
887e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "ADD", OPCODE_ADD, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
897e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "COS", OPCODE_COS, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
907e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "DDX", OPCODE_DDX, INPUT_1V, OUTPUT_V, _R | _H |      _C | _S },
917e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "DDY", OPCODE_DDY, INPUT_1V, OUTPUT_V, _R | _H |      _C | _S },
927e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "DP3", OPCODE_DP3, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S },
937e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "DP4", OPCODE_DP4, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S },
947e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "DST", OPCODE_DP4, INPUT_2V, OUTPUT_V, _R | _H |      _C | _S },
957e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "EX2", OPCODE_DP4, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
967e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "FLR", OPCODE_FLR, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
977e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "FRC", OPCODE_FRC, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
987e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "KIL", OPCODE_KIL_NV, INPUT_CC, OUTPUT_NONE, 0                },
997e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "LG2", OPCODE_LG2, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
1007e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "LIT", OPCODE_LIT, INPUT_1V, OUTPUT_V, _R | _H |      _C | _S },
1017e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "LRP", OPCODE_LRP, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S },
1027e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "MAD", OPCODE_MAD, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S },
1037e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "MAX", OPCODE_MAX, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1047e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "MIN", OPCODE_MIN, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1057e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "MOV", OPCODE_MOV, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
1067e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "MUL", OPCODE_MUL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1077e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "PK2H",  OPCODE_PK2H,  INPUT_1V, OUTPUT_S, 0                  },
1087e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "PK2US", OPCODE_PK2US, INPUT_1V, OUTPUT_S, 0                  },
1097e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "PK4B",  OPCODE_PK4B,  INPUT_1V, OUTPUT_S, 0                  },
1107e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "PK4UB", OPCODE_PK4UB, INPUT_1V, OUTPUT_S, 0                  },
1117e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "POW", OPCODE_POW, INPUT_2S, OUTPUT_S, _R | _H |      _C | _S },
1127e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "RCP", OPCODE_RCP, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
1137e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "RFL", OPCODE_RFL, INPUT_2V, OUTPUT_V, _R | _H |      _C | _S },
1147e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "RSQ", OPCODE_RSQ, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
1157e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "SEQ", OPCODE_SEQ, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1167e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "SFL", OPCODE_SFL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1177e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "SGE", OPCODE_SGE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1187e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "SGT", OPCODE_SGT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1197e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "SIN", OPCODE_SIN, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
1207e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "SLE", OPCODE_SLE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1217e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "SLT", OPCODE_SLT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1227e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "SNE", OPCODE_SNE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1237e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "STR", OPCODE_STR, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1247e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "SUB", OPCODE_SUB, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1257e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "TEX", OPCODE_TEX, INPUT_1V_T, OUTPUT_V,              _C | _S },
1267e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "TXD", OPCODE_TXD, INPUT_3V_T, OUTPUT_V,              _C | _S },
1277e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "TXP", OPCODE_TXP_NV, INPUT_1V_T, OUTPUT_V,           _C | _S },
1287e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "UP2H",  OPCODE_UP2H,  INPUT_1S, OUTPUT_V,            _C | _S },
1297e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "UP2US", OPCODE_UP2US, INPUT_1S, OUTPUT_V,            _C | _S },
1307e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "UP4B",  OPCODE_UP4B,  INPUT_1S, OUTPUT_V,            _C | _S },
1317e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "UP4UB", OPCODE_UP4UB, INPUT_1S, OUTPUT_V,            _C | _S },
1327e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "X2D", OPCODE_X2D, INPUT_3V, OUTPUT_V, _R | _H |      _C | _S },
1337e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "PRINT", OPCODE_PRINT, INPUT_1V_S, OUTPUT_NONE, 0               },
1347e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { NULL, (enum prog_opcode) -1, 0, 0, 0 }
1352861e737e84e4884109b9526ac645194ba892a74Michal Krol};
1362861e737e84e4884109b9526ac645194ba892a74Michal Krol
1372861e737e84e4884109b9526ac645194ba892a74Michal Krol
1382861e737e84e4884109b9526ac645194ba892a74Michal Krol/*
1392861e737e84e4884109b9526ac645194ba892a74Michal Krol * Information needed or computed during parsing.
1402861e737e84e4884109b9526ac645194ba892a74Michal Krol * Remember, we can't modify the target program object until we've
1412861e737e84e4884109b9526ac645194ba892a74Michal Krol * _successfully_ parsed the program text.
1422861e737e84e4884109b9526ac645194ba892a74Michal Krol */
1432861e737e84e4884109b9526ac645194ba892a74Michal Krolstruct parse_state {
144f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg   struct gl_context *ctx;
1452861e737e84e4884109b9526ac645194ba892a74Michal Krol   const GLubyte *start;              /* start of program string */
1462861e737e84e4884109b9526ac645194ba892a74Michal Krol   const GLubyte *pos;                /* current position */
1472861e737e84e4884109b9526ac645194ba892a74Michal Krol   const GLubyte *curLine;
148122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul   struct gl_fragment_program *program;  /* current program */
1492861e737e84e4884109b9526ac645194ba892a74Michal Krol
150122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul   struct gl_program_parameter_list *parameters;
1512861e737e84e4884109b9526ac645194ba892a74Michal Krol
1522861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLuint numInst;                    /* number of instructions parsed */
1532861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLuint inputsRead;                 /* bitmask of input registers used */
1542861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLuint outputsWritten;             /* bitmask of 1 << FRAG_OUTPUT_* bits */
1552861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLuint texturesUsed[MAX_TEXTURE_IMAGE_UNITS];
1562861e737e84e4884109b9526ac645194ba892a74Michal Krol};
1572861e737e84e4884109b9526ac645194ba892a74Michal Krol
1582861e737e84e4884109b9526ac645194ba892a74Michal Krol
1592861e737e84e4884109b9526ac645194ba892a74Michal Krol
1602861e737e84e4884109b9526ac645194ba892a74Michal Krol/*
1612861e737e84e4884109b9526ac645194ba892a74Michal Krol * Called whenever we find an error during parsing.
1622861e737e84e4884109b9526ac645194ba892a74Michal Krol */
1632861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void
1642861e737e84e4884109b9526ac645194ba892a74Michal Krolrecord_error(struct parse_state *parseState, const char *msg, int lineNo)
1652861e737e84e4884109b9526ac645194ba892a74Michal Krol{
1662861e737e84e4884109b9526ac645194ba892a74Michal Krol#ifdef DEBUG
1672861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLint line, column;
1682861e737e84e4884109b9526ac645194ba892a74Michal Krol   const GLubyte *lineStr;
1692861e737e84e4884109b9526ac645194ba892a74Michal Krol   lineStr = _mesa_find_line_column(parseState->start,
1702861e737e84e4884109b9526ac645194ba892a74Michal Krol                                    parseState->pos, &line, &column);
1712861e737e84e4884109b9526ac645194ba892a74Michal Krol   _mesa_debug(parseState->ctx,
1722861e737e84e4884109b9526ac645194ba892a74Michal Krol               "nvfragparse.c(%d): line %d, column %d:%s (%s)\n",
1732861e737e84e4884109b9526ac645194ba892a74Michal Krol               lineNo, line, column, (char *) lineStr, msg);
17432f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg   free((void *) lineStr);
1752861e737e84e4884109b9526ac645194ba892a74Michal Krol#else
1762861e737e84e4884109b9526ac645194ba892a74Michal Krol   (void) lineNo;
1772861e737e84e4884109b9526ac645194ba892a74Michal Krol#endif
1782861e737e84e4884109b9526ac645194ba892a74Michal Krol
1792861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Check that no error was already recorded.  Only record the first one. */
1802861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (parseState->ctx->Program.ErrorString[0] == 0) {
1812861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_set_program_error(parseState->ctx,
1822861e737e84e4884109b9526ac645194ba892a74Michal Krol                              parseState->pos - parseState->start,
1832861e737e84e4884109b9526ac645194ba892a74Michal Krol                              msg);
1842861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
1852861e737e84e4884109b9526ac645194ba892a74Michal Krol}
1862861e737e84e4884109b9526ac645194ba892a74Michal Krol
1872861e737e84e4884109b9526ac645194ba892a74Michal Krol
1882861e737e84e4884109b9526ac645194ba892a74Michal Krol#define RETURN_ERROR							\
1892861e737e84e4884109b9526ac645194ba892a74Michal Kroldo {									\
1902861e737e84e4884109b9526ac645194ba892a74Michal Krol   record_error(parseState, "Unexpected end of input.", __LINE__);	\
1912861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_FALSE;							\
1922861e737e84e4884109b9526ac645194ba892a74Michal Krol} while(0)
1932861e737e84e4884109b9526ac645194ba892a74Michal Krol
1942861e737e84e4884109b9526ac645194ba892a74Michal Krol#define RETURN_ERROR1(msg)						\
1952861e737e84e4884109b9526ac645194ba892a74Michal Kroldo {									\
1962861e737e84e4884109b9526ac645194ba892a74Michal Krol   record_error(parseState, msg, __LINE__);				\
1972861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_FALSE;							\
1982861e737e84e4884109b9526ac645194ba892a74Michal Krol} while(0)
1992861e737e84e4884109b9526ac645194ba892a74Michal Krol
2002861e737e84e4884109b9526ac645194ba892a74Michal Krol#define RETURN_ERROR2(msg1, msg2)					\
2012861e737e84e4884109b9526ac645194ba892a74Michal Kroldo {									\
2022861e737e84e4884109b9526ac645194ba892a74Michal Krol   char err[1000];							\
203298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg   sprintf(err, "%s %s", msg1, msg2);				\
2042861e737e84e4884109b9526ac645194ba892a74Michal Krol   record_error(parseState, err, __LINE__);				\
2052861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_FALSE;							\
2062861e737e84e4884109b9526ac645194ba892a74Michal Krol} while(0)
2072861e737e84e4884109b9526ac645194ba892a74Michal Krol
2082861e737e84e4884109b9526ac645194ba892a74Michal Krol
2092861e737e84e4884109b9526ac645194ba892a74Michal Krol
2102861e737e84e4884109b9526ac645194ba892a74Michal Krol
2112861e737e84e4884109b9526ac645194ba892a74Michal Krol/*
2122861e737e84e4884109b9526ac645194ba892a74Michal Krol * Search a list of instruction structures for a match.
2132861e737e84e4884109b9526ac645194ba892a74Michal Krol */
2142861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic struct instruction_pattern
2152861e737e84e4884109b9526ac645194ba892a74Michal KrolMatchInstruction(const GLubyte *token)
2162861e737e84e4884109b9526ac645194ba892a74Michal Krol{
2172861e737e84e4884109b9526ac645194ba892a74Michal Krol   const struct instruction_pattern *inst;
2182861e737e84e4884109b9526ac645194ba892a74Michal Krol   struct instruction_pattern result;
2192861e737e84e4884109b9526ac645194ba892a74Michal Krol
22094fba49be97008565c0225bc46894bfd9453bb5eVinson Lee   result.name = NULL;
22194fba49be97008565c0225bc46894bfd9453bb5eVinson Lee   result.opcode = MAX_OPCODE; /* i.e. invalid instruction */
22294fba49be97008565c0225bc46894bfd9453bb5eVinson Lee   result.inputs = 0;
22394fba49be97008565c0225bc46894bfd9453bb5eVinson Lee   result.outputs = 0;
22494fba49be97008565c0225bc46894bfd9453bb5eVinson Lee   result.suffixes = 0;
22594fba49be97008565c0225bc46894bfd9453bb5eVinson Lee
2262861e737e84e4884109b9526ac645194ba892a74Michal Krol   for (inst = Instructions; inst->name; inst++) {
2279d9afe9393fde99858ddf40e478bc16cf44e60dcKenneth Graunke      if (strncmp((const char *) token, inst->name, 3) == 0) {
2282861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* matched! */
2292861e737e84e4884109b9526ac645194ba892a74Michal Krol         int i = 3;
2302861e737e84e4884109b9526ac645194ba892a74Michal Krol         result = *inst;
2312861e737e84e4884109b9526ac645194ba892a74Michal Krol         result.suffixes = 0;
2322861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* look at suffix */
2332861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (token[i] == 'R') {
2342861e737e84e4884109b9526ac645194ba892a74Michal Krol            result.suffixes |= _R;
2352861e737e84e4884109b9526ac645194ba892a74Michal Krol            i++;
2362861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
2372861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (token[i] == 'H') {
2382861e737e84e4884109b9526ac645194ba892a74Michal Krol            result.suffixes |= _H;
2392861e737e84e4884109b9526ac645194ba892a74Michal Krol            i++;
2402861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
2412861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (token[i] == 'X') {
2422861e737e84e4884109b9526ac645194ba892a74Michal Krol            result.suffixes |= _X;
2432861e737e84e4884109b9526ac645194ba892a74Michal Krol            i++;
2442861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
2452861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (token[i] == 'C') {
2462861e737e84e4884109b9526ac645194ba892a74Michal Krol            result.suffixes |= _C;
2472861e737e84e4884109b9526ac645194ba892a74Michal Krol            i++;
2482861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
2492861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (token[i] == '_' && token[i+1] == 'S' &&
2502861e737e84e4884109b9526ac645194ba892a74Michal Krol             token[i+2] == 'A' && token[i+3] == 'T') {
2512861e737e84e4884109b9526ac645194ba892a74Michal Krol            result.suffixes |= _S;
2522861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
2532861e737e84e4884109b9526ac645194ba892a74Michal Krol         return result;
2542861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
2552861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
25694fba49be97008565c0225bc46894bfd9453bb5eVinson Lee
2572861e737e84e4884109b9526ac645194ba892a74Michal Krol   return result;
2582861e737e84e4884109b9526ac645194ba892a74Michal Krol}
2592861e737e84e4884109b9526ac645194ba892a74Michal Krol
2602861e737e84e4884109b9526ac645194ba892a74Michal Krol
2612861e737e84e4884109b9526ac645194ba892a74Michal Krol
2622861e737e84e4884109b9526ac645194ba892a74Michal Krol
2632861e737e84e4884109b9526ac645194ba892a74Michal Krol/**********************************************************************/
2642861e737e84e4884109b9526ac645194ba892a74Michal Krol
2652861e737e84e4884109b9526ac645194ba892a74Michal Krol
2662861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean IsLetter(GLubyte b)
2672861e737e84e4884109b9526ac645194ba892a74Michal Krol{
2682861e737e84e4884109b9526ac645194ba892a74Michal Krol   return (b >= 'a' && b <= 'z') ||
2692861e737e84e4884109b9526ac645194ba892a74Michal Krol          (b >= 'A' && b <= 'Z') ||
2702861e737e84e4884109b9526ac645194ba892a74Michal Krol          (b == '_') ||
2712861e737e84e4884109b9526ac645194ba892a74Michal Krol          (b == '$');
2722861e737e84e4884109b9526ac645194ba892a74Michal Krol}
2732861e737e84e4884109b9526ac645194ba892a74Michal Krol
2742861e737e84e4884109b9526ac645194ba892a74Michal Krol
2752861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean IsDigit(GLubyte b)
2762861e737e84e4884109b9526ac645194ba892a74Michal Krol{
2772861e737e84e4884109b9526ac645194ba892a74Michal Krol   return b >= '0' && b <= '9';
2782861e737e84e4884109b9526ac645194ba892a74Michal Krol}
2792861e737e84e4884109b9526ac645194ba892a74Michal Krol
2802861e737e84e4884109b9526ac645194ba892a74Michal Krol
2812861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean IsWhitespace(GLubyte b)
2822861e737e84e4884109b9526ac645194ba892a74Michal Krol{
2832861e737e84e4884109b9526ac645194ba892a74Michal Krol   return b == ' ' || b == '\t' || b == '\n' || b == '\r';
2842861e737e84e4884109b9526ac645194ba892a74Michal Krol}
2852861e737e84e4884109b9526ac645194ba892a74Michal Krol
2862861e737e84e4884109b9526ac645194ba892a74Michal Krol
2872861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
2882861e737e84e4884109b9526ac645194ba892a74Michal Krol * Starting at 'str' find the next token.  A token can be an integer,
2892861e737e84e4884109b9526ac645194ba892a74Michal Krol * an identifier or punctuation symbol.
2902861e737e84e4884109b9526ac645194ba892a74Michal Krol * \return <= 0 we found an error, else, return number of characters parsed.
2912861e737e84e4884109b9526ac645194ba892a74Michal Krol */
2922861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLint
2932861e737e84e4884109b9526ac645194ba892a74Michal KrolGetToken(struct parse_state *parseState, GLubyte *token)
2942861e737e84e4884109b9526ac645194ba892a74Michal Krol{
2952861e737e84e4884109b9526ac645194ba892a74Michal Krol   const GLubyte *str = parseState->pos;
2962861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLint i = 0, j = 0;
2972861e737e84e4884109b9526ac645194ba892a74Michal Krol
2982861e737e84e4884109b9526ac645194ba892a74Michal Krol   token[0] = 0;
2992861e737e84e4884109b9526ac645194ba892a74Michal Krol
3002861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* skip whitespace and comments */
3012861e737e84e4884109b9526ac645194ba892a74Michal Krol   while (str[i] && (IsWhitespace(str[i]) || str[i] == '#')) {
3022861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (str[i] == '#') {
3032861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* skip comment */
3042861e737e84e4884109b9526ac645194ba892a74Michal Krol         while (str[i] && (str[i] != '\n' && str[i] != '\r')) {
3052861e737e84e4884109b9526ac645194ba892a74Michal Krol            i++;
3062861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
3072861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (str[i] == '\n' || str[i] == '\r')
3082861e737e84e4884109b9526ac645194ba892a74Michal Krol            parseState->curLine = str + i + 1;
3092861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
3102861e737e84e4884109b9526ac645194ba892a74Michal Krol      else {
3112861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* skip whitespace */
3122861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (str[i] == '\n' || str[i] == '\r')
3132861e737e84e4884109b9526ac645194ba892a74Michal Krol            parseState->curLine = str + i + 1;
3142861e737e84e4884109b9526ac645194ba892a74Michal Krol         i++;
3152861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
3162861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
3172861e737e84e4884109b9526ac645194ba892a74Michal Krol
3182861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (str[i] == 0)
3192861e737e84e4884109b9526ac645194ba892a74Michal Krol      return -i;
3202861e737e84e4884109b9526ac645194ba892a74Michal Krol
3212861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* try matching an integer */
3222861e737e84e4884109b9526ac645194ba892a74Michal Krol   while (str[i] && IsDigit(str[i])) {
3232861e737e84e4884109b9526ac645194ba892a74Michal Krol      token[j++] = str[i++];
3242861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
3252861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (j > 0 || !str[i]) {
3262861e737e84e4884109b9526ac645194ba892a74Michal Krol      token[j] = 0;
3272861e737e84e4884109b9526ac645194ba892a74Michal Krol      return i;
3282861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
3292861e737e84e4884109b9526ac645194ba892a74Michal Krol
3302861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* try matching an identifier */
3312861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (IsLetter(str[i])) {
3322861e737e84e4884109b9526ac645194ba892a74Michal Krol      while (str[i] && (IsLetter(str[i]) || IsDigit(str[i]))) {
3332861e737e84e4884109b9526ac645194ba892a74Michal Krol         token[j++] = str[i++];
3342861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
3352861e737e84e4884109b9526ac645194ba892a74Michal Krol      token[j] = 0;
3362861e737e84e4884109b9526ac645194ba892a74Michal Krol      return i;
3372861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
3382861e737e84e4884109b9526ac645194ba892a74Michal Krol
3392861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* punctuation character */
3402861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (str[i]) {
3412861e737e84e4884109b9526ac645194ba892a74Michal Krol      token[0] = str[i++];
3422861e737e84e4884109b9526ac645194ba892a74Michal Krol      token[1] = 0;
3432861e737e84e4884109b9526ac645194ba892a74Michal Krol      return i;
3442861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
3452861e737e84e4884109b9526ac645194ba892a74Michal Krol
3462861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* end of input */
3472861e737e84e4884109b9526ac645194ba892a74Michal Krol   token[0] = 0;
3482861e737e84e4884109b9526ac645194ba892a74Michal Krol   return i;
3492861e737e84e4884109b9526ac645194ba892a74Michal Krol}
3502861e737e84e4884109b9526ac645194ba892a74Michal Krol
3512861e737e84e4884109b9526ac645194ba892a74Michal Krol
3522861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
3532861e737e84e4884109b9526ac645194ba892a74Michal Krol * Get next token from input stream and increment stream pointer past token.
3542861e737e84e4884109b9526ac645194ba892a74Michal Krol */
3552861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
3562861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_Token(struct parse_state *parseState, GLubyte *token)
3572861e737e84e4884109b9526ac645194ba892a74Michal Krol{
3582861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLint i;
3592861e737e84e4884109b9526ac645194ba892a74Michal Krol   i = GetToken(parseState, token);
3602861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (i <= 0) {
3612861e737e84e4884109b9526ac645194ba892a74Michal Krol      parseState->pos += (-i);
3622861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_FALSE;
3632861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
3642861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState->pos += i;
3652861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
3662861e737e84e4884109b9526ac645194ba892a74Michal Krol}
3672861e737e84e4884109b9526ac645194ba892a74Michal Krol
3682861e737e84e4884109b9526ac645194ba892a74Michal Krol
3692861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
3702861e737e84e4884109b9526ac645194ba892a74Michal Krol * Get next token from input stream but don't increment stream pointer.
3712861e737e84e4884109b9526ac645194ba892a74Michal Krol */
3722861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
3732861e737e84e4884109b9526ac645194ba892a74Michal KrolPeek_Token(struct parse_state *parseState, GLubyte *token)
3742861e737e84e4884109b9526ac645194ba892a74Michal Krol{
3752861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLint i, len;
3762861e737e84e4884109b9526ac645194ba892a74Michal Krol   i = GetToken(parseState, token);
3772861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (i <= 0) {
3782861e737e84e4884109b9526ac645194ba892a74Michal Krol      parseState->pos += (-i);
3792861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_FALSE;
3802861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
38121d0c70b4b1c18dc1c3ac7d0fbd8a903d60f8be7Kenneth Graunke   len = (GLint) strlen((const char *) token);
3822861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState->pos += (i - len);
3832861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
3842861e737e84e4884109b9526ac645194ba892a74Michal Krol}
3852861e737e84e4884109b9526ac645194ba892a74Michal Krol
3862861e737e84e4884109b9526ac645194ba892a74Michal Krol
3872861e737e84e4884109b9526ac645194ba892a74Michal Krol/**********************************************************************/
3882861e737e84e4884109b9526ac645194ba892a74Michal Krol
3892861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic const char *InputRegisters[MAX_NV_FRAGMENT_PROGRAM_INPUTS + 1] = {
3902861e737e84e4884109b9526ac645194ba892a74Michal Krol   "WPOS", "COL0", "COL1", "FOGC",
3912861e737e84e4884109b9526ac645194ba892a74Michal Krol   "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL
3922861e737e84e4884109b9526ac645194ba892a74Michal Krol};
3932861e737e84e4884109b9526ac645194ba892a74Michal Krol
3948d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul
3952861e737e84e4884109b9526ac645194ba892a74Michal Krol
3962861e737e84e4884109b9526ac645194ba892a74Michal Krol/**********************************************************************/
3972861e737e84e4884109b9526ac645194ba892a74Michal Krol
3982861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
3992861e737e84e4884109b9526ac645194ba892a74Michal Krol * Try to match 'pattern' as the next token after any whitespace/comments.
4002861e737e84e4884109b9526ac645194ba892a74Michal Krol */
4012861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
4022861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_String(struct parse_state *parseState, const char *pattern)
4032861e737e84e4884109b9526ac645194ba892a74Michal Krol{
4042861e737e84e4884109b9526ac645194ba892a74Michal Krol   const GLubyte *m;
4052861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLint i;
4062861e737e84e4884109b9526ac645194ba892a74Michal Krol
4072861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* skip whitespace and comments */
4082861e737e84e4884109b9526ac645194ba892a74Michal Krol   while (IsWhitespace(*parseState->pos) || *parseState->pos == '#') {
4092861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (*parseState->pos == '#') {
4102861e737e84e4884109b9526ac645194ba892a74Michal Krol         while (*parseState->pos && (*parseState->pos != '\n' && *parseState->pos != '\r')) {
4112861e737e84e4884109b9526ac645194ba892a74Michal Krol            parseState->pos += 1;
4122861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
4132861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (*parseState->pos == '\n' || *parseState->pos == '\r')
4142861e737e84e4884109b9526ac645194ba892a74Michal Krol            parseState->curLine = parseState->pos + 1;
4152861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
4162861e737e84e4884109b9526ac645194ba892a74Michal Krol      else {
4172861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* skip whitespace */
4182861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (*parseState->pos == '\n' || *parseState->pos == '\r')
4192861e737e84e4884109b9526ac645194ba892a74Michal Krol            parseState->curLine = parseState->pos + 1;
4202861e737e84e4884109b9526ac645194ba892a74Michal Krol         parseState->pos += 1;
4212861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
4222861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
4232861e737e84e4884109b9526ac645194ba892a74Michal Krol
4242861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Try to match the pattern */
4252861e737e84e4884109b9526ac645194ba892a74Michal Krol   m = parseState->pos;
4262861e737e84e4884109b9526ac645194ba892a74Michal Krol   for (i = 0; pattern[i]; i++) {
4272861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (*m != (GLubyte) pattern[i])
4282861e737e84e4884109b9526ac645194ba892a74Michal Krol         return GL_FALSE;
4292861e737e84e4884109b9526ac645194ba892a74Michal Krol      m += 1;
4302861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
4312861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState->pos = m;
4322861e737e84e4884109b9526ac645194ba892a74Michal Krol
4332861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE; /* success */
4342861e737e84e4884109b9526ac645194ba892a74Michal Krol}
4352861e737e84e4884109b9526ac645194ba892a74Michal Krol
4362861e737e84e4884109b9526ac645194ba892a74Michal Krol
4372861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
4382861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_Identifier(struct parse_state *parseState, GLubyte *ident)
4392861e737e84e4884109b9526ac645194ba892a74Michal Krol{
4402861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_Token(parseState, ident))
4412861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
4422861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (IsLetter(ident[0]))
4432861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_TRUE;
4442861e737e84e4884109b9526ac645194ba892a74Michal Krol   else
4452861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected an identfier");
4462861e737e84e4884109b9526ac645194ba892a74Michal Krol}
4472861e737e84e4884109b9526ac645194ba892a74Michal Krol
4482861e737e84e4884109b9526ac645194ba892a74Michal Krol
4492861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
4502861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a floating point constant, or a defined symbol name.
4512861e737e84e4884109b9526ac645194ba892a74Michal Krol * [+/-]N[.N[eN]]
4522861e737e84e4884109b9526ac645194ba892a74Michal Krol * Output:  number[0 .. 3] will get the value.
4532861e737e84e4884109b9526ac645194ba892a74Michal Krol */
4542861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
4552861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_ScalarConstant(struct parse_state *parseState, GLfloat *number)
4562861e737e84e4884109b9526ac645194ba892a74Michal Krol{
4572861e737e84e4884109b9526ac645194ba892a74Michal Krol   char *end = NULL;
4582861e737e84e4884109b9526ac645194ba892a74Michal Krol
459346298c7658f2ec8b105e5e53101637af232724fMarcin Baczyński   *number = (GLfloat) _mesa_strtof((const char *) parseState->pos, &end);
4602861e737e84e4884109b9526ac645194ba892a74Michal Krol
4612861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (end && end > (char *) parseState->pos) {
4622861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* got a number */
4632861e737e84e4884109b9526ac645194ba892a74Michal Krol      parseState->pos = (GLubyte *) end;
4642861e737e84e4884109b9526ac645194ba892a74Michal Krol      number[1] = *number;
4652861e737e84e4884109b9526ac645194ba892a74Michal Krol      number[2] = *number;
4662861e737e84e4884109b9526ac645194ba892a74Michal Krol      number[3] = *number;
4672861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_TRUE;
4682861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
4692861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
4702861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* should be an identifier */
4712861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLubyte ident[100];
4722861e737e84e4884109b9526ac645194ba892a74Michal Krol      const GLfloat *constant;
4732861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_Identifier(parseState, ident))
4742861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Expected an identifier");
4756d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain      constant = (GLfloat *)_mesa_lookup_parameter_value(parseState->parameters,
4766d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain                                                         -1,
4776d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain                                                         (const char *) ident);
4782861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* XXX Check that it's a constant and not a parameter */
4792861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!constant) {
4802861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Undefined symbol");
4812861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
4822861e737e84e4884109b9526ac645194ba892a74Michal Krol      else {
4832861e737e84e4884109b9526ac645194ba892a74Michal Krol         COPY_4V(number, constant);
4842861e737e84e4884109b9526ac645194ba892a74Michal Krol         return GL_TRUE;
4852861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
4862861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
4872861e737e84e4884109b9526ac645194ba892a74Michal Krol}
4882861e737e84e4884109b9526ac645194ba892a74Michal Krol
4892861e737e84e4884109b9526ac645194ba892a74Michal Krol
4902861e737e84e4884109b9526ac645194ba892a74Michal Krol
4912861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
4922861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a vector constant, one of:
4932861e737e84e4884109b9526ac645194ba892a74Michal Krol *   { float }
4942861e737e84e4884109b9526ac645194ba892a74Michal Krol *   { float, float }
4952861e737e84e4884109b9526ac645194ba892a74Michal Krol *   { float, float, float }
4962861e737e84e4884109b9526ac645194ba892a74Michal Krol *   { float, float, float, float }
4972861e737e84e4884109b9526ac645194ba892a74Michal Krol */
4982861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
4992861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_VectorConstant(struct parse_state *parseState, GLfloat *vec)
5002861e737e84e4884109b9526ac645194ba892a74Michal Krol{
5012861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* "{" was already consumed */
5022861e737e84e4884109b9526ac645194ba892a74Michal Krol
5032861e737e84e4884109b9526ac645194ba892a74Michal Krol   ASSIGN_4V(vec, 0.0, 0.0, 0.0, 1.0);
5042861e737e84e4884109b9526ac645194ba892a74Michal Krol
5052861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_ScalarConstant(parseState, vec+0))  /* X */
5062861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_FALSE;
5072861e737e84e4884109b9526ac645194ba892a74Michal Krol
5082861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "}")) {
5092861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_TRUE;
5102861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5112861e737e84e4884109b9526ac645194ba892a74Michal Krol
5122861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, ","))
5132861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected comma in vector constant");
5142861e737e84e4884109b9526ac645194ba892a74Michal Krol
5152861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_ScalarConstant(parseState, vec+1))  /* Y */
5162861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_FALSE;
5172861e737e84e4884109b9526ac645194ba892a74Michal Krol
5182861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "}")) {
5192861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_TRUE;
5202861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5212861e737e84e4884109b9526ac645194ba892a74Michal Krol
5222861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, ","))
5232861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected comma in vector constant");
5242861e737e84e4884109b9526ac645194ba892a74Michal Krol
5252861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_ScalarConstant(parseState, vec+2))  /* Z */
5262861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_FALSE;
5272861e737e84e4884109b9526ac645194ba892a74Michal Krol
5282861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "}")) {
5292861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_TRUE;
5302861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5312861e737e84e4884109b9526ac645194ba892a74Michal Krol
5322861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, ","))
5332861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected comma in vector constant");
5342861e737e84e4884109b9526ac645194ba892a74Michal Krol
5352861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_ScalarConstant(parseState, vec+3))  /* W */
5362861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_FALSE;
5372861e737e84e4884109b9526ac645194ba892a74Michal Krol
5382861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "}"))
5392861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected closing brace in vector constant");
5402861e737e84e4884109b9526ac645194ba892a74Michal Krol
5412861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
5422861e737e84e4884109b9526ac645194ba892a74Michal Krol}
5432861e737e84e4884109b9526ac645194ba892a74Michal Krol
5442861e737e84e4884109b9526ac645194ba892a74Michal Krol
5452861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
5462861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse <number>, <varname> or {a, b, c, d}.
5472861e737e84e4884109b9526ac645194ba892a74Michal Krol * Return number of values in the vector or scalar, or zero if parse error.
5482861e737e84e4884109b9526ac645194ba892a74Michal Krol */
5492861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLuint
5502861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_VectorOrScalarConstant(struct parse_state *parseState, GLfloat *vec)
5512861e737e84e4884109b9526ac645194ba892a74Michal Krol{
5522861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "{")) {
5532861e737e84e4884109b9526ac645194ba892a74Michal Krol      return Parse_VectorConstant(parseState, vec);
5542861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5552861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
5562861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLboolean b = Parse_ScalarConstant(parseState, vec);
5572861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (b) {
5582861e737e84e4884109b9526ac645194ba892a74Michal Krol         vec[1] = vec[2] = vec[3] = vec[0];
5592861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
5602861e737e84e4884109b9526ac645194ba892a74Michal Krol      return b;
5612861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5622861e737e84e4884109b9526ac645194ba892a74Michal Krol}
5632861e737e84e4884109b9526ac645194ba892a74Michal Krol
5642861e737e84e4884109b9526ac645194ba892a74Michal Krol
5652861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
5662861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a texture image source:
5672861e737e84e4884109b9526ac645194ba892a74Michal Krol *    [TEX0 | TEX1 | .. | TEX15] , [1D | 2D | 3D | CUBE | RECT]
5682861e737e84e4884109b9526ac645194ba892a74Michal Krol */
5692861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
5702861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_TextureImageId(struct parse_state *parseState,
571bf5255fb30d9d9832f93616016c94782469d43adBrian Paul                     GLubyte *texUnit, GLubyte *texTarget)
5722861e737e84e4884109b9526ac645194ba892a74Michal Krol{
5732861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte imageSrc[100];
5742861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLint unit;
5752861e737e84e4884109b9526ac645194ba892a74Michal Krol
5762861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_Token(parseState, imageSrc))
5772861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
5782861e737e84e4884109b9526ac645194ba892a74Michal Krol
5792861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (imageSrc[0] != 'T' ||
5802861e737e84e4884109b9526ac645194ba892a74Michal Krol       imageSrc[1] != 'E' ||
5812861e737e84e4884109b9526ac645194ba892a74Michal Krol       imageSrc[2] != 'X') {
5822861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected TEX# source");
5832861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
58460b0cae412029e53654f38d0de151908f1feb310Kenneth Graunke   unit = atoi((const char *) imageSrc + 3);
58561b62c007a7941e9b45e83440e932160a597e0e1Vinson Lee   if ((unit < 0 || unit >= MAX_TEXTURE_IMAGE_UNITS) ||
5862861e737e84e4884109b9526ac645194ba892a74Michal Krol       (unit == 0 && (imageSrc[3] != '0' || imageSrc[4] != 0))) {
5872861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalied TEX# source index");
5882861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5892861e737e84e4884109b9526ac645194ba892a74Michal Krol   *texUnit = unit;
5902861e737e84e4884109b9526ac645194ba892a74Michal Krol
5912861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, ","))
5922861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected ,");
5932861e737e84e4884109b9526ac645194ba892a74Michal Krol
5942861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "1D")) {
595bf5255fb30d9d9832f93616016c94782469d43adBrian Paul      *texTarget = TEXTURE_1D_INDEX;
5962861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5972861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "2D")) {
598bf5255fb30d9d9832f93616016c94782469d43adBrian Paul      *texTarget = TEXTURE_2D_INDEX;
5992861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6002861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "3D")) {
601bf5255fb30d9d9832f93616016c94782469d43adBrian Paul      *texTarget = TEXTURE_3D_INDEX;
6022861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6032861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "CUBE")) {
604bf5255fb30d9d9832f93616016c94782469d43adBrian Paul      *texTarget = TEXTURE_CUBE_INDEX;
6052861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6062861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "RECT")) {
607bf5255fb30d9d9832f93616016c94782469d43adBrian Paul      *texTarget = TEXTURE_RECT_INDEX;
6082861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6092861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
6102861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalid texture target token");
6112861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6122861e737e84e4884109b9526ac645194ba892a74Michal Krol
6132861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* update record of referenced texture units */
614bf5255fb30d9d9832f93616016c94782469d43adBrian Paul   parseState->texturesUsed[*texUnit] |= (1 << *texTarget);
6152861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (_mesa_bitcount(parseState->texturesUsed[*texUnit]) > 1) {
6162861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Only one texture target can be used per texture unit.");
6172861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6182861e737e84e4884109b9526ac645194ba892a74Michal Krol
6192861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
6202861e737e84e4884109b9526ac645194ba892a74Michal Krol}
6212861e737e84e4884109b9526ac645194ba892a74Michal Krol
6222861e737e84e4884109b9526ac645194ba892a74Michal Krol
6232861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
6242861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a scalar suffix like .x, .y, .z or .w or parse a swizzle suffix
6252861e737e84e4884109b9526ac645194ba892a74Michal Krol * like .wxyz, .xxyy, etc and return the swizzle indexes.
6262861e737e84e4884109b9526ac645194ba892a74Michal Krol */
6272861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
6282861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_SwizzleSuffix(const GLubyte *token, GLuint swizzle[4])
6292861e737e84e4884109b9526ac645194ba892a74Michal Krol{
6302861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (token[1] == 0) {
6312861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* single letter swizzle (scalar) */
6322861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[0] == 'x')
6332861e737e84e4884109b9526ac645194ba892a74Michal Krol         ASSIGN_4V(swizzle, 0, 0, 0, 0);
6342861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (token[0] == 'y')
6352861e737e84e4884109b9526ac645194ba892a74Michal Krol         ASSIGN_4V(swizzle, 1, 1, 1, 1);
6362861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (token[0] == 'z')
6372861e737e84e4884109b9526ac645194ba892a74Michal Krol         ASSIGN_4V(swizzle, 2, 2, 2, 2);
6382861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (token[0] == 'w')
6392861e737e84e4884109b9526ac645194ba892a74Michal Krol         ASSIGN_4V(swizzle, 3, 3, 3, 3);
6402861e737e84e4884109b9526ac645194ba892a74Michal Krol      else
6412861e737e84e4884109b9526ac645194ba892a74Michal Krol         return GL_FALSE;
6422861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6432861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
6442861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* 4-component swizzle (vector) */
6452861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLint k;
646324568f79d6e014900c981bd9a0e1dffedc326c8Roel Kluin      for (k = 0; k < 4 && token[k]; k++) {
6472861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (token[k] == 'x')
6482861e737e84e4884109b9526ac645194ba892a74Michal Krol            swizzle[k] = 0;
6492861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (token[k] == 'y')
6502861e737e84e4884109b9526ac645194ba892a74Michal Krol            swizzle[k] = 1;
6512861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (token[k] == 'z')
6522861e737e84e4884109b9526ac645194ba892a74Michal Krol            swizzle[k] = 2;
6532861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (token[k] == 'w')
6542861e737e84e4884109b9526ac645194ba892a74Michal Krol            swizzle[k] = 3;
6552861e737e84e4884109b9526ac645194ba892a74Michal Krol         else
6562861e737e84e4884109b9526ac645194ba892a74Michal Krol            return GL_FALSE;
6572861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
6582861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (k != 4)
6592861e737e84e4884109b9526ac645194ba892a74Michal Krol         return GL_FALSE;
6602861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6612861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
6622861e737e84e4884109b9526ac645194ba892a74Michal Krol}
6632861e737e84e4884109b9526ac645194ba892a74Michal Krol
6642861e737e84e4884109b9526ac645194ba892a74Michal Krol
6652861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
6662861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_CondCodeMask(struct parse_state *parseState,
6677e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul                   struct prog_dst_register *dstReg)
6682861e737e84e4884109b9526ac645194ba892a74Michal Krol{
6692861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "EQ"))
6702861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_EQ;
6712861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "GE"))
6722861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_GE;
6732861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "GT"))
6742861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_GT;
6752861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "LE"))
6762861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_LE;
6772861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "LT"))
6782861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_LT;
6792861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "NE"))
6802861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_NE;
6812861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "TR"))
6822861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_TR;
6832861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "FL"))
6842861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_FL;
6852861e737e84e4884109b9526ac645194ba892a74Michal Krol   else
6862861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalid condition code mask");
6872861e737e84e4884109b9526ac645194ba892a74Michal Krol
6882861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* look for optional .xyzw swizzle */
6892861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, ".")) {
6902861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLubyte token[100];
6917c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      GLuint swz[4];
6927c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell
6932861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_Token(parseState, token))  /* get xyzw suffix */
6942861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
6952861e737e84e4884109b9526ac645194ba892a74Michal Krol
6967c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_SwizzleSuffix(token, swz))
6972861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid swizzle suffix");
6987c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell
699fd4395b8d1d6f8f018e7e7c3dd0c52fe52ab2794Brian Paul      dstReg->CondSwizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
7002861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7012861e737e84e4884109b9526ac645194ba892a74Michal Krol
7022861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
7032861e737e84e4884109b9526ac645194ba892a74Michal Krol}
7042861e737e84e4884109b9526ac645194ba892a74Michal Krol
7052861e737e84e4884109b9526ac645194ba892a74Michal Krol
7062861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
7072861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a temporary register: Rnn or Hnn
7082861e737e84e4884109b9526ac645194ba892a74Michal Krol */
7092861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
7102861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_TempReg(struct parse_state *parseState, GLint *tempRegNum)
7112861e737e84e4884109b9526ac645194ba892a74Michal Krol{
7122861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
7132861e737e84e4884109b9526ac645194ba892a74Michal Krol
7142861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Should be 'R##' or 'H##' */
7152861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_Token(parseState, token))
7162861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
7172861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (token[0] != 'R' && token[0] != 'H')
7182861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected R## or H##");
7192861e737e84e4884109b9526ac645194ba892a74Michal Krol
7202861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (IsDigit(token[1])) {
72160b0cae412029e53654f38d0de151908f1feb310Kenneth Graunke      GLint reg = atoi((const char *) (token + 1));
7222861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[0] == 'H')
7232861e737e84e4884109b9526ac645194ba892a74Michal Krol         reg += 32;
7242861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (reg >= MAX_NV_FRAGMENT_PROGRAM_TEMPS)
7252861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid temporary register name");
7262861e737e84e4884109b9526ac645194ba892a74Michal Krol      *tempRegNum = reg;
7272861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7282861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
7292861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalid temporary register name");
7302861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7312861e737e84e4884109b9526ac645194ba892a74Michal Krol
7322861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
7332861e737e84e4884109b9526ac645194ba892a74Michal Krol}
7342861e737e84e4884109b9526ac645194ba892a74Michal Krol
7352861e737e84e4884109b9526ac645194ba892a74Michal Krol
7362861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
7372861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a write-only dummy register: RC or HC.
7382861e737e84e4884109b9526ac645194ba892a74Michal Krol */
7392861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
7402861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_DummyReg(struct parse_state *parseState, GLint *regNum)
7412861e737e84e4884109b9526ac645194ba892a74Michal Krol{
7422861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "RC")) {
7432861e737e84e4884109b9526ac645194ba892a74Michal Krol       *regNum = 0;
7442861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7452861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "HC")) {
7462861e737e84e4884109b9526ac645194ba892a74Michal Krol       *regNum = 1;
7472861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7482861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
7492861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalid write-only register name");
7502861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7512861e737e84e4884109b9526ac645194ba892a74Michal Krol
7522861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
7532861e737e84e4884109b9526ac645194ba892a74Michal Krol}
7542861e737e84e4884109b9526ac645194ba892a74Michal Krol
7552861e737e84e4884109b9526ac645194ba892a74Michal Krol
7562861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
7572861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a program local parameter register "p[##]"
7582861e737e84e4884109b9526ac645194ba892a74Michal Krol */
7592861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
7602861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_ProgramParamReg(struct parse_state *parseState, GLint *regNum)
7612861e737e84e4884109b9526ac645194ba892a74Michal Krol{
7622861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
7632861e737e84e4884109b9526ac645194ba892a74Michal Krol
7642861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "p["))
7652861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected p[");
7662861e737e84e4884109b9526ac645194ba892a74Michal Krol
7672861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_Token(parseState, token))
7682861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
7692861e737e84e4884109b9526ac645194ba892a74Michal Krol
7702861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (IsDigit(token[0])) {
7712861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* a numbered program parameter register */
77260b0cae412029e53654f38d0de151908f1feb310Kenneth Graunke      GLint reg = atoi((const char *) token);
7732861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (reg >= MAX_NV_FRAGMENT_PROGRAM_PARAMS)
7742861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid constant program number");
7752861e737e84e4884109b9526ac645194ba892a74Michal Krol      *regNum = reg;
7762861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7772861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
7782861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
7792861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7802861e737e84e4884109b9526ac645194ba892a74Michal Krol
7812861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "]"))
7822861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected ]");
7832861e737e84e4884109b9526ac645194ba892a74Michal Krol
7842861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
7852861e737e84e4884109b9526ac645194ba892a74Michal Krol}
7862861e737e84e4884109b9526ac645194ba892a74Michal Krol
7872861e737e84e4884109b9526ac645194ba892a74Michal Krol
7882861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
7892861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse f[name]  - fragment input register
7902861e737e84e4884109b9526ac645194ba892a74Michal Krol */
7912861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
7922861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_FragReg(struct parse_state *parseState, GLint *tempRegNum)
7932861e737e84e4884109b9526ac645194ba892a74Michal Krol{
7942861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
7952861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLint j;
7962861e737e84e4884109b9526ac645194ba892a74Michal Krol
7972861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Match 'f[' */
7982861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "f["))
7992861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected f[");
8002861e737e84e4884109b9526ac645194ba892a74Michal Krol
8012861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* get <name> and look for match */
8022861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_Token(parseState, token)) {
8032861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
8042861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8052861e737e84e4884109b9526ac645194ba892a74Michal Krol   for (j = 0; InputRegisters[j]; j++) {
8068d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke      if (strcmp((const char *) token, InputRegisters[j]) == 0) {
8072861e737e84e4884109b9526ac645194ba892a74Michal Krol         *tempRegNum = j;
8082861e737e84e4884109b9526ac645194ba892a74Michal Krol         parseState->inputsRead |= (1 << j);
8092861e737e84e4884109b9526ac645194ba892a74Michal Krol         break;
8102861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
8112861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8122861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!InputRegisters[j]) {
8132861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* unknown input register label */
8142861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR2("Invalid register name", token);
8152861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8162861e737e84e4884109b9526ac645194ba892a74Michal Krol
8172861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Match '[' */
8182861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "]"))
8192861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected ]");
8202861e737e84e4884109b9526ac645194ba892a74Michal Krol
8212861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
8222861e737e84e4884109b9526ac645194ba892a74Michal Krol}
8232861e737e84e4884109b9526ac645194ba892a74Michal Krol
8242861e737e84e4884109b9526ac645194ba892a74Michal Krol
8252861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
8262861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_OutputReg(struct parse_state *parseState, GLint *outputRegNum)
8272861e737e84e4884109b9526ac645194ba892a74Michal Krol{
8282861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
8292861e737e84e4884109b9526ac645194ba892a74Michal Krol
8302861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Match "o[" */
8312861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "o["))
8322861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected o[");
8332861e737e84e4884109b9526ac645194ba892a74Michal Krol
8342861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Get output reg name */
8352861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_Token(parseState, token))
8362861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
8372861e737e84e4884109b9526ac645194ba892a74Michal Krol
8382861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* try to match an output register name */
8398d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke   if (strcmp((char *) token, "COLR") == 0 ||
8408d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke       strcmp((char *) token, "COLH") == 0) {
8418d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul      /* note that we don't distinguish between COLR and COLH */
8428d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul      *outputRegNum = FRAG_RESULT_COLOR;
8438d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul      parseState->outputsWritten |= (1 << FRAG_RESULT_COLOR);
8442861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8458d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke   else if (strcmp((char *) token, "DEPR") == 0) {
8468d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul      *outputRegNum = FRAG_RESULT_DEPTH;
8478d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul      parseState->outputsWritten |= (1 << FRAG_RESULT_DEPTH);
8488d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul   }
8498d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul   else {
8502861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalid output register name");
8518d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul   }
8522861e737e84e4884109b9526ac645194ba892a74Michal Krol
8532861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Match ']' */
8542861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "]"))
8552861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected ]");
8562861e737e84e4884109b9526ac645194ba892a74Michal Krol
8572861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
8582861e737e84e4884109b9526ac645194ba892a74Michal Krol}
8592861e737e84e4884109b9526ac645194ba892a74Michal Krol
8602861e737e84e4884109b9526ac645194ba892a74Michal Krol
8612861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
8622861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_MaskedDstReg(struct parse_state *parseState,
8637e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul                   struct prog_dst_register *dstReg)
8642861e737e84e4884109b9526ac645194ba892a74Michal Krol{
8652861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
8667c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   GLint idx;
8672861e737e84e4884109b9526ac645194ba892a74Michal Krol
8682861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Dst reg can be R<n>, H<n>, o[n], RC or HC */
8692861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Peek_Token(parseState, token))
8702861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
8712861e737e84e4884109b9526ac645194ba892a74Michal Krol
8728d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke   if (strcmp((const char *) token, "RC") == 0 ||
8738d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke       strcmp((const char *) token, "HC") == 0) {
8742861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* a write-only register */
8752861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->File = PROGRAM_WRITE_ONLY;
8767c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_DummyReg(parseState, &idx))
8772861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
8787c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      dstReg->Index = idx;
8792861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8802861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == 'R' || token[0] == 'H') {
8812861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* a temporary register */
8822861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->File = PROGRAM_TEMPORARY;
8837c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_TempReg(parseState, &idx))
8842861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
8857c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      dstReg->Index = idx;
8862861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8872861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == 'o') {
8882861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* an output register */
8892861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->File = PROGRAM_OUTPUT;
8907c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_OutputReg(parseState, &idx))
8912861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
8927c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      dstReg->Index = idx;
8932861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8942861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
8952861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalid destination register name");
8962861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8972861e737e84e4884109b9526ac645194ba892a74Michal Krol
8982861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Parse optional write mask */
8992861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, ".")) {
9002861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* got a mask */
9012861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLint k = 0;
9022861e737e84e4884109b9526ac645194ba892a74Michal Krol
9032861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_Token(parseState, token))  /* get xyzw writemask */
9042861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
9052861e737e84e4884109b9526ac645194ba892a74Michal Krol
9067c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      dstReg->WriteMask = 0;
9072861e737e84e4884109b9526ac645194ba892a74Michal Krol
9082861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[k] == 'x') {
9097c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         dstReg->WriteMask |= WRITEMASK_X;
9102861e737e84e4884109b9526ac645194ba892a74Michal Krol         k++;
9112861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
9122861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[k] == 'y') {
9137c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         dstReg->WriteMask |= WRITEMASK_Y;
9142861e737e84e4884109b9526ac645194ba892a74Michal Krol         k++;
9152861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
9162861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[k] == 'z') {
9177c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         dstReg->WriteMask |= WRITEMASK_Z;
9182861e737e84e4884109b9526ac645194ba892a74Michal Krol         k++;
9192861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
9202861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[k] == 'w') {
9217c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         dstReg->WriteMask |= WRITEMASK_W;
9222861e737e84e4884109b9526ac645194ba892a74Michal Krol         k++;
9232861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
9242861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (k == 0) {
9252861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid writemask character");
9262861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
9272861e737e84e4884109b9526ac645194ba892a74Michal Krol
9282861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9292861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
9307c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      dstReg->WriteMask = WRITEMASK_XYZW;
9312861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9322861e737e84e4884109b9526ac645194ba892a74Michal Krol
9332861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* optional condition code mask */
9342861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "(")) {
9352861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".x|y|z|w) */
9362861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".[xyzw]) */
9372861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_CondCodeMask(parseState, dstReg))
9382861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
9392861e737e84e4884109b9526ac645194ba892a74Michal Krol
9402861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_String(parseState, ")"))  /* consume ")" */
9412861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Expected )");
9422861e737e84e4884109b9526ac645194ba892a74Michal Krol
9432861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_TRUE;
9442861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9452861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
9462861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* no cond code mask */
9472861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_TR;
9487c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      dstReg->CondSwizzle = SWIZZLE_NOOP;
9492861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_TRUE;
9502861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9512861e737e84e4884109b9526ac645194ba892a74Michal Krol}
9522861e737e84e4884109b9526ac645194ba892a74Michal Krol
9532861e737e84e4884109b9526ac645194ba892a74Michal Krol
9542861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
9552861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a vector source (register, constant, etc):
9562861e737e84e4884109b9526ac645194ba892a74Michal Krol *   <vectorSrc>    ::= <absVectorSrc>
9572861e737e84e4884109b9526ac645194ba892a74Michal Krol *                    | <baseVectorSrc>
9582861e737e84e4884109b9526ac645194ba892a74Michal Krol *   <absVectorSrc> ::= <negate> "|" <baseVectorSrc> "|"
9592861e737e84e4884109b9526ac645194ba892a74Michal Krol */
9602861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
9612861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_VectorSrc(struct parse_state *parseState,
9627e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul                struct prog_src_register *srcReg)
9632861e737e84e4884109b9526ac645194ba892a74Michal Krol{
9642861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLfloat sign = 1.0F;
9652861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
9667c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   GLint idx;
9677db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul   GLuint negateBase, negateAbs;
9682861e737e84e4884109b9526ac645194ba892a74Michal Krol
9692861e737e84e4884109b9526ac645194ba892a74Michal Krol   /*
9702861e737e84e4884109b9526ac645194ba892a74Michal Krol    * First, take care of +/- and absolute value stuff.
9712861e737e84e4884109b9526ac645194ba892a74Michal Krol    */
9722861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "-"))
9732861e737e84e4884109b9526ac645194ba892a74Michal Krol      sign = -1.0F;
9742861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "+"))
9752861e737e84e4884109b9526ac645194ba892a74Michal Krol      sign = +1.0F;
9762861e737e84e4884109b9526ac645194ba892a74Michal Krol
9772861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "|")) {
9782861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Abs = GL_TRUE;
9797db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul      negateAbs = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
9802861e737e84e4884109b9526ac645194ba892a74Michal Krol
9812861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (Parse_String(parseState, "-"))
9827db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul         negateBase = NEGATE_XYZW;
9832861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (Parse_String(parseState, "+"))
9847db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul         negateBase = NEGATE_NONE;
9852861e737e84e4884109b9526ac645194ba892a74Michal Krol      else
9867db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul         negateBase = NEGATE_NONE;
9872861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9882861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
9892861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Abs = GL_FALSE;
9907db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul      negateAbs = NEGATE_NONE;
9917db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul      negateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
9922861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9932861e737e84e4884109b9526ac645194ba892a74Michal Krol
9947db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul   srcReg->Negate = srcReg->Abs ? negateAbs : negateBase;
9957db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul
9962861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* This should be the real src vector/register name */
9972861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Peek_Token(parseState, token))
9982861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
9992861e737e84e4884109b9526ac645194ba892a74Michal Krol
10002861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Src reg can be Rn, Hn, f[n], p[n], a named parameter, a scalar
10012861e737e84e4884109b9526ac645194ba892a74Michal Krol    * literal or vector literal.
10022861e737e84e4884109b9526ac645194ba892a74Michal Krol    */
10032861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (token[0] == 'R' || token[0] == 'H') {
10042861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_TEMPORARY;
10057c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_TempReg(parseState, &idx))
10062861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
10077c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      srcReg->Index = idx;
10082861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10092861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == 'f') {
1010e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      /* XXX this might be an identifier! */
10112861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_INPUT;
10127c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_FragReg(parseState, &idx))
10132861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
10147c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      srcReg->Index = idx;
10152861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10162861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == 'p') {
1017e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      /* XXX this might be an identifier! */
10182861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_LOCAL_PARAM;
10197c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_ProgramParamReg(parseState, &idx))
10202861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
10217c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      srcReg->Index = idx;
10222861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10232861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (IsLetter(token[0])){
10242861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLubyte ident[100];
10252861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLint paramIndex;
10262861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_Identifier(parseState, ident))
10272861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
10282861e737e84e4884109b9526ac645194ba892a74Michal Krol      paramIndex = _mesa_lookup_parameter_index(parseState->parameters,
10292861e737e84e4884109b9526ac645194ba892a74Michal Krol                                                -1, (const char *) ident);
10302861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (paramIndex < 0) {
10312861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR2("Undefined constant or parameter: ", ident);
10322861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
10332861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_NAMED_PARAM;
10342861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Index = paramIndex;
10352861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10362861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (IsDigit(token[0]) || token[0] == '-' || token[0] == '+' || token[0] == '.'){
10372861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* literal scalar constant */
10382861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLfloat values[4];
1039257f799849a1eb3e81851b92a8fd27efa8f93d47Brian      GLuint paramIndex;
10402861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_ScalarConstant(parseState, values))
10412861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
1042fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
10436d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain                                              (gl_constant_value *) values,
10446d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain                                              4, NULL);
10452861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_NAMED_PARAM;
10462861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Index = paramIndex;
10472861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10482861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == '{'){
10492861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* literal vector constant */
10502861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLfloat values[4];
1051257f799849a1eb3e81851b92a8fd27efa8f93d47Brian      GLuint paramIndex;
10522861e737e84e4884109b9526ac645194ba892a74Michal Krol      (void) Parse_String(parseState, "{");
10532861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_VectorConstant(parseState, values))
10542861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
1055fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
10566d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain                                              (gl_constant_value *) values,
10576d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain                                              4, NULL);
10582861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_NAMED_PARAM;
10592861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Index = paramIndex;
10602861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10612861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
10622861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR2("Invalid source register name", token);
10632861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10642861e737e84e4884109b9526ac645194ba892a74Michal Krol
10652861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* init swizzle fields */
10667c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   srcReg->Swizzle = SWIZZLE_NOOP;
10672861e737e84e4884109b9526ac645194ba892a74Michal Krol
10682861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Look for optional swizzle suffix */
10692861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, ".")) {
10707c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      GLuint swz[4];
10717c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell
10722861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_Token(parseState, token))
10732861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
10742861e737e84e4884109b9526ac645194ba892a74Michal Krol
10757c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_SwizzleSuffix(token, swz))
10762861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid swizzle suffix");
10777c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell
1078fd4395b8d1d6f8f018e7e7c3dd0c52fe52ab2794Brian Paul      srcReg->Swizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
10792861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10802861e737e84e4884109b9526ac645194ba892a74Michal Krol
10812861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Finish absolute value */
10822861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (srcReg->Abs && !Parse_String(parseState, "|")) {
10832861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected |");
10842861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10852861e737e84e4884109b9526ac645194ba892a74Michal Krol
10862861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
10872861e737e84e4884109b9526ac645194ba892a74Michal Krol}
10882861e737e84e4884109b9526ac645194ba892a74Michal Krol
10892861e737e84e4884109b9526ac645194ba892a74Michal Krol
10902861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
10912861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_ScalarSrcReg(struct parse_state *parseState,
10927e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul                   struct prog_src_register *srcReg)
10932861e737e84e4884109b9526ac645194ba892a74Michal Krol{
10942861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
10952861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLfloat sign = 1.0F;
10962861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLboolean needSuffix = GL_TRUE;
10977c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   GLint idx;
10987db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul   GLuint negateBase, negateAbs;
10992861e737e84e4884109b9526ac645194ba892a74Michal Krol
11002861e737e84e4884109b9526ac645194ba892a74Michal Krol   /*
11012861e737e84e4884109b9526ac645194ba892a74Michal Krol    * First, take care of +/- and absolute value stuff.
11022861e737e84e4884109b9526ac645194ba892a74Michal Krol    */
11032861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "-"))
11042861e737e84e4884109b9526ac645194ba892a74Michal Krol      sign = -1.0F;
11052861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "+"))
11062861e737e84e4884109b9526ac645194ba892a74Michal Krol      sign = +1.0F;
11072861e737e84e4884109b9526ac645194ba892a74Michal Krol
11082861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "|")) {
11092861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Abs = GL_TRUE;
11107db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul      negateAbs = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
11112861e737e84e4884109b9526ac645194ba892a74Michal Krol
11122861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (Parse_String(parseState, "-"))
11137db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul         negateBase = NEGATE_XYZW;
11142861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (Parse_String(parseState, "+"))
11157db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul         negateBase = NEGATE_NONE;
11162861e737e84e4884109b9526ac645194ba892a74Michal Krol      else
11177db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul         negateBase = NEGATE_NONE;
11182861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11192861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
11202861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Abs = GL_FALSE;
11217db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul      negateAbs = NEGATE_NONE;
11227db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul      negateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
11232861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11242861e737e84e4884109b9526ac645194ba892a74Michal Krol
11257db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul   srcReg->Negate = srcReg->Abs ? negateAbs : negateBase;
11267db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul
11272861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Peek_Token(parseState, token))
11282861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
11292861e737e84e4884109b9526ac645194ba892a74Michal Krol
11302861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Src reg can be R<n>, H<n> or a named fragment attrib */
11312861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (token[0] == 'R' || token[0] == 'H') {
11322861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_TEMPORARY;
11337c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_TempReg(parseState, &idx))
11342861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
11357c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      srcReg->Index = idx;
11362861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11372861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == 'f') {
11382861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_INPUT;
11397c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_FragReg(parseState, &idx))
11402861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
11417c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      srcReg->Index = idx;
11422861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11432861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == '{') {
11442861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* vector literal */
11452861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLfloat values[4];
114681c4fee160cd2840caf77bbdbf462e783911141aBrian      GLuint paramIndex;
11472861e737e84e4884109b9526ac645194ba892a74Michal Krol      (void) Parse_String(parseState, "{");
11482861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_VectorConstant(parseState, values))
11492861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
1150fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
11516d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain                                              (gl_constant_value *) values,
11526d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain                                              4, NULL);
11532861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_NAMED_PARAM;
11542861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Index = paramIndex;
11552861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
1156e6940f0a33a571b199bab60b680c30b718c47445Brian Paul   else if (IsLetter(token[0])){
1157e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      /* named param/constant */
1158e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      GLubyte ident[100];
1159e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      GLint paramIndex;
1160e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      if (!Parse_Identifier(parseState, ident))
1161e6940f0a33a571b199bab60b680c30b718c47445Brian Paul         RETURN_ERROR;
1162e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      paramIndex = _mesa_lookup_parameter_index(parseState->parameters,
1163e6940f0a33a571b199bab60b680c30b718c47445Brian Paul                                                -1, (const char *) ident);
1164e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      if (paramIndex < 0) {
1165e6940f0a33a571b199bab60b680c30b718c47445Brian Paul         RETURN_ERROR2("Undefined constant or parameter: ", ident);
1166e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      }
1167e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      srcReg->File = PROGRAM_NAMED_PARAM;
1168e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      srcReg->Index = paramIndex;
1169e6940f0a33a571b199bab60b680c30b718c47445Brian Paul   }
11702861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (IsDigit(token[0])) {
11712861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* scalar literal */
11722861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLfloat values[4];
117381c4fee160cd2840caf77bbdbf462e783911141aBrian      GLuint paramIndex;
11742861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_ScalarConstant(parseState, values))
11752861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
1176fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
11776d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain                                              (gl_constant_value *) values,
11786d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain                                              4, NULL);
11792861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Index = paramIndex;
11802861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_NAMED_PARAM;
11812861e737e84e4884109b9526ac645194ba892a74Michal Krol      needSuffix = GL_FALSE;
11822861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11832861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
11842861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR2("Invalid scalar source argument", token);
11852861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11862861e737e84e4884109b9526ac645194ba892a74Michal Krol
11877c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   srcReg->Swizzle = 0;
11882861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (needSuffix) {
11892861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* parse .[xyzw] suffix */
11902861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_String(parseState, "."))
11912861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Expected .");
11922861e737e84e4884109b9526ac645194ba892a74Michal Krol
11932861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_Token(parseState, token))
11942861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
11952861e737e84e4884109b9526ac645194ba892a74Michal Krol
11962861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[0] == 'x' && token[1] == 0) {
11977c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         srcReg->Swizzle = 0;
11982861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
11992861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (token[0] == 'y' && token[1] == 0) {
12007c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         srcReg->Swizzle = 1;
12012861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
12022861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (token[0] == 'z' && token[1] == 0) {
12037c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         srcReg->Swizzle = 2;
12042861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
12052861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (token[0] == 'w' && token[1] == 0) {
12067c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         srcReg->Swizzle = 3;
12072861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
12082861e737e84e4884109b9526ac645194ba892a74Michal Krol      else {
12092861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid scalar source suffix");
12102861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
12112861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
12122861e737e84e4884109b9526ac645194ba892a74Michal Krol
12132861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Finish absolute value */
12142861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (srcReg->Abs && !Parse_String(parseState, "|")) {
12152861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected |");
12162861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
12172861e737e84e4884109b9526ac645194ba892a74Michal Krol
12182861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
12192861e737e84e4884109b9526ac645194ba892a74Michal Krol}
12202861e737e84e4884109b9526ac645194ba892a74Michal Krol
12212861e737e84e4884109b9526ac645194ba892a74Michal Krol
12222a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paulstatic GLboolean
12232a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian PaulParse_PrintInstruction(struct parse_state *parseState,
12247e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul                       struct prog_instruction *inst)
12252a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul{
12262a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   const GLubyte *str;
12272a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   GLubyte *msg;
12282a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   GLuint len;
12297c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   GLint idx;
12302a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul
12312a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   /* The first argument is a literal string 'just like this' */
12322a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   if (!Parse_String(parseState, "'"))
12332a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      RETURN_ERROR1("Expected '");
12342a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul
12352a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   str = parseState->pos;
12362a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   for (len = 0; str[len] != '\''; len++) /* find closing quote */
12372a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      ;
12382a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   parseState->pos += len + 1;
123932f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg   msg = (GLubyte*) malloc(len + 1);
12402a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul
1241c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke   memcpy(msg, str, len);
12422a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   msg[len] = 0;
12432a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   inst->Data = msg;
12442a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul
12452a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   if (Parse_String(parseState, ",")) {
12462a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      /* got an optional register to print */
12472a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      GLubyte token[100];
12482a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      GetToken(parseState, token);
12492a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      if (token[0] == 'o') {
12502a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul         /* dst reg */
12517c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         if (!Parse_OutputReg(parseState, &idx))
12522a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul            RETURN_ERROR;
12537c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell	 inst->SrcReg[0].Index = idx;
12542a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul         inst->SrcReg[0].File = PROGRAM_OUTPUT;
12552a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      }
12562a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      else {
12572a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul         /* src reg */
12582a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul         if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
12592a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul            RETURN_ERROR;
12602a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      }
12612a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   }
12622a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   else {
12638cdf3729468aefb7c67c8ecd32fd850adbf6d351Brian Paul      inst->SrcReg[0].File = PROGRAM_UNDEFINED;
12642a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   }
12652a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul
12667c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   inst->SrcReg[0].Swizzle = SWIZZLE_NOOP;
12672a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   inst->SrcReg[0].Abs = GL_FALSE;
12687db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul   inst->SrcReg[0].Negate = NEGATE_NONE;
12692a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul
12702a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   return GL_TRUE;
12712a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul}
12722a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul
12732861e737e84e4884109b9526ac645194ba892a74Michal Krol
12742861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
12752861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_InstructionSequence(struct parse_state *parseState,
12767e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul                          struct prog_instruction program[])
12772861e737e84e4884109b9526ac645194ba892a74Michal Krol{
12782861e737e84e4884109b9526ac645194ba892a74Michal Krol   while (1) {
12797e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul      struct prog_instruction *inst = program + parseState->numInst;
12802861e737e84e4884109b9526ac645194ba892a74Michal Krol      struct instruction_pattern instMatch;
12812861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLubyte token[100];
12822861e737e84e4884109b9526ac645194ba892a74Michal Krol
12832861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* Initialize the instruction */
1284d6272e06172f7ac7a0d6e8062e8ffba33e1ab3baBrian Paul      _mesa_init_instructions(inst, 1);
12852861e737e84e4884109b9526ac645194ba892a74Michal Krol
12862861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* special instructions */
12872861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (Parse_String(parseState, "DEFINE")) {
12882861e737e84e4884109b9526ac645194ba892a74Michal Krol         GLubyte id[100];
12892861e737e84e4884109b9526ac645194ba892a74Michal Krol         GLfloat value[7];  /* yes, 7 to be safe */
12902861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_Identifier(parseState, id))
12912861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR;
12922861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* XXX make sure id is not a reserved identifer, like R9 */
12932861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_String(parseState, "="))
12942861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Expected =");
12952861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_VectorOrScalarConstant(parseState, value))
12962861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR;
12972861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_String(parseState, ";"))
12982861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Expected ;");
12992861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (_mesa_lookup_parameter_index(parseState->parameters,
13002861e737e84e4884109b9526ac645194ba892a74Michal Krol                                          -1, (const char *) id) >= 0) {
13012861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR2(id, "already defined");
13022861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13032861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_add_named_parameter(parseState->parameters,
13046d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain                                   (const char *) id,
13056d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain                                   (gl_constant_value *) value);
13062861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
13072861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (Parse_String(parseState, "DECLARE")) {
13082861e737e84e4884109b9526ac645194ba892a74Michal Krol         GLubyte id[100];
13092861e737e84e4884109b9526ac645194ba892a74Michal Krol         GLfloat value[7] = {0, 0, 0, 0, 0, 0, 0};  /* yes, to be safe */
13102861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_Identifier(parseState, id))
13112861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR;
13122861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* XXX make sure id is not a reserved identifer, like R9 */
13132861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (Parse_String(parseState, "=")) {
13142861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorOrScalarConstant(parseState, value))
13152861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13162861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13172861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_String(parseState, ";"))
13182861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Expected ;");
13192861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (_mesa_lookup_parameter_index(parseState->parameters,
13202861e737e84e4884109b9526ac645194ba892a74Michal Krol                                          -1, (const char *) id) >= 0) {
13212861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR2(id, "already declared");
13222861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13232861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_add_named_parameter(parseState->parameters,
13246d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain                                   (const char *) id,
13256d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain                                   (gl_constant_value *) value);
13262861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
13272861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (Parse_String(parseState, "END")) {
13287e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul         inst->Opcode = OPCODE_END;
13292861e737e84e4884109b9526ac645194ba892a74Michal Krol         parseState->numInst++;
13302861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (Parse_Token(parseState, token)) {
13312861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Code after END opcode.");
13322861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13332861e737e84e4884109b9526ac645194ba892a74Michal Krol         break;
13342861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
13352861e737e84e4884109b9526ac645194ba892a74Michal Krol      else {
13362861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* general/arithmetic instruction */
13372861e737e84e4884109b9526ac645194ba892a74Michal Krol
13382861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* get token */
13392861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_Token(parseState, token)) {
13402861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Missing END instruction.");
13412861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13422861e737e84e4884109b9526ac645194ba892a74Michal Krol
13432861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* try to find matching instuction */
13442861e737e84e4884109b9526ac645194ba892a74Michal Krol         instMatch = MatchInstruction(token);
134528b014ee256290eb0494b967e40c475c0c895f57Brian Paul         if (instMatch.opcode >= MAX_OPCODE) {
13462861e737e84e4884109b9526ac645194ba892a74Michal Krol            /* bad instruction name */
13472861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR2("Unexpected token: ", token);
13482861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13492861e737e84e4884109b9526ac645194ba892a74Michal Krol
13502861e737e84e4884109b9526ac645194ba892a74Michal Krol         inst->Opcode = instMatch.opcode;
13512861e737e84e4884109b9526ac645194ba892a74Michal Krol         inst->Precision = instMatch.suffixes & (_R | _H | _X);
1352e31ac052236ea615b4995f9ec301d8af4b864531Brian Paul         inst->SaturateMode = (instMatch.suffixes & (_S))
1353e31ac052236ea615b4995f9ec301d8af4b864531Brian Paul            ? SATURATE_ZERO_ONE : SATURATE_OFF;
13547e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul         inst->CondUpdate = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE;
13552861e737e84e4884109b9526ac645194ba892a74Michal Krol
13562861e737e84e4884109b9526ac645194ba892a74Michal Krol         /*
13572861e737e84e4884109b9526ac645194ba892a74Michal Krol          * parse the input and output operands
13582861e737e84e4884109b9526ac645194ba892a74Michal Krol          */
13592861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (instMatch.outputs == OUTPUT_S || instMatch.outputs == OUTPUT_V) {
13602861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
13612861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13622861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
13632861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
13642861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13652861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.outputs == OUTPUT_NONE) {
13667e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul            if (instMatch.opcode == OPCODE_KIL_NV) {
13672a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul               /* This is a little weird, the cond code info is in
13682a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul                * the dest register.
13692a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul                */
13702a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul               if (!Parse_CondCodeMask(parseState, &inst->DstReg))
13712a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul                  RETURN_ERROR;
13722a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul            }
13732a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul            else {
13747e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul               ASSERT(instMatch.opcode == OPCODE_PRINT);
13752a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul            }
13762861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13772861e737e84e4884109b9526ac645194ba892a74Michal Krol
13782861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (instMatch.inputs == INPUT_1V) {
13792861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
13802861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13812861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13822861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_2V) {
13832861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
13842861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13852861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
13862861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
13872861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
13882861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13892861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13902861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_3V) {
13912861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
13922861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13932861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
13942861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
13952861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
13962861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13972861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
13982861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
13992861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[2]))
14002861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14012861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
14022861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_1S) {
14032861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
14042861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14052861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
14062861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_2S) {
14072861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
14082861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14092861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
14102861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
14112861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[1]))
14122861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14132861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
14142861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_CC) {
14152861e737e84e4884109b9526ac645194ba892a74Michal Krol            /* XXX to-do */
14162861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
14172861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_1V_T) {
14187c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell	    GLubyte unit, idx;
14192861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
14202861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14212861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
14222861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
14237c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell            if (!Parse_TextureImageId(parseState, &unit, &idx))
14242861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14257c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell	    inst->TexSrcUnit = unit;
14267e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul	    inst->TexSrcTarget = idx;
14272861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
14282861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_3V_T) {
14297c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell	    GLubyte unit, idx;
14302861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
14312861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14322861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
14332861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
14342861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
14352861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14362861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
14372861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
14382861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[2]))
14392861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14402861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
14412861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
14427c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell            if (!Parse_TextureImageId(parseState, &unit, &idx))
14432861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14447c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell	    inst->TexSrcUnit = unit;
14457e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul	    inst->TexSrcTarget = idx;
14462861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
14472a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul         else if (instMatch.inputs == INPUT_1V_S) {
14482a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul            if (!Parse_PrintInstruction(parseState, inst))
14492a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul               RETURN_ERROR;
14502a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul         }
14512861e737e84e4884109b9526ac645194ba892a74Michal Krol
14522861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* end of statement semicolon */
14532861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_String(parseState, ";"))
14542861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Expected ;");
14552861e737e84e4884109b9526ac645194ba892a74Michal Krol
14562861e737e84e4884109b9526ac645194ba892a74Michal Krol         parseState->numInst++;
14572861e737e84e4884109b9526ac645194ba892a74Michal Krol
14582861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (parseState->numInst >= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS)
14592861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Program too long");
14602861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
14612861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
14622861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
14632861e737e84e4884109b9526ac645194ba892a74Michal Krol}
14642861e737e84e4884109b9526ac645194ba892a74Michal Krol
14652861e737e84e4884109b9526ac645194ba892a74Michal Krol
14662861e737e84e4884109b9526ac645194ba892a74Michal Krol
14672861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
14682861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse/compile the 'str' returning the compiled 'program'.
14692861e737e84e4884109b9526ac645194ba892a74Michal Krol * ctx->Program.ErrorPos will be -1 if successful.  Otherwise, ErrorPos
14702861e737e84e4884109b9526ac645194ba892a74Michal Krol * indicates the position of the error in 'str'.
14712861e737e84e4884109b9526ac645194ba892a74Michal Krol */
14722861e737e84e4884109b9526ac645194ba892a74Michal Krolvoid
1473f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_parse_nv_fragment_program(struct gl_context *ctx, GLenum dstTarget,
14742861e737e84e4884109b9526ac645194ba892a74Michal Krol                                const GLubyte *str, GLsizei len,
1475122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul                                struct gl_fragment_program *program)
14762861e737e84e4884109b9526ac645194ba892a74Michal Krol{
14772861e737e84e4884109b9526ac645194ba892a74Michal Krol   struct parse_state parseState;
14787e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   struct prog_instruction instBuffer[MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS];
14797e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   struct prog_instruction *newInst;
14802861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLenum target;
14812861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte *programString;
14822861e737e84e4884109b9526ac645194ba892a74Michal Krol
14832861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Make a null-terminated copy of the program string */
14842861e737e84e4884109b9526ac645194ba892a74Michal Krol   programString = (GLubyte *) MALLOC(len + 1);
14852861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!programString) {
14862861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
14872861e737e84e4884109b9526ac645194ba892a74Michal Krol      return;
14882861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
1489e197de56cdb86835f1437688a9161cd909792d80Brian Paul   memcpy(programString, str, len);
14902861e737e84e4884109b9526ac645194ba892a74Michal Krol   programString[len] = 0;
14912861e737e84e4884109b9526ac645194ba892a74Michal Krol
14922861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Get ready to parse */
14936bf1ea897fa470af58fe8916dff45e2da79634a3Brian Paul   memset(&parseState, 0, sizeof(struct parse_state));
14942861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.ctx = ctx;
14952861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.start = programString;
14962861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.program = program;
14972861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.numInst = 0;
14982861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.curLine = programString;
14992861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.parameters = _mesa_new_parameter_list();
15002861e737e84e4884109b9526ac645194ba892a74Michal Krol
15012861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Reset error state */
15022861e737e84e4884109b9526ac645194ba892a74Michal Krol   _mesa_set_program_error(ctx, -1, NULL);
15032861e737e84e4884109b9526ac645194ba892a74Michal Krol
15042861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* check the program header */
15059d9afe9393fde99858ddf40e478bc16cf44e60dcKenneth Graunke   if (strncmp((const char *) programString, "!!FP1.0", 7) == 0) {
15062861e737e84e4884109b9526ac645194ba892a74Michal Krol      target = GL_FRAGMENT_PROGRAM_NV;
15072861e737e84e4884109b9526ac645194ba892a74Michal Krol      parseState.pos = programString + 7;
15082861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15099d9afe9393fde99858ddf40e478bc16cf44e60dcKenneth Graunke   else if (strncmp((const char *) programString, "!!FCP1.0", 8) == 0) {
15102861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* fragment / register combiner program - not supported */
15112861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_set_program_error(ctx, 0, "Invalid fragment program header");
15122861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
15132861e737e84e4884109b9526ac645194ba892a74Michal Krol      return;
15142861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15152861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
15162861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* invalid header */
15172861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_set_program_error(ctx, 0, "Invalid fragment program header");
15182861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
15192861e737e84e4884109b9526ac645194ba892a74Michal Krol      return;
15202861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15212861e737e84e4884109b9526ac645194ba892a74Michal Krol
15222861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* make sure target and header match */
15232861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (target != dstTarget) {
15242861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_error(ctx, GL_INVALID_OPERATION,
15252861e737e84e4884109b9526ac645194ba892a74Michal Krol                  "glLoadProgramNV(target mismatch 0x%x != 0x%x)",
15262861e737e84e4884109b9526ac645194ba892a74Michal Krol                  target, dstTarget);
15272861e737e84e4884109b9526ac645194ba892a74Michal Krol      return;
15282861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15292861e737e84e4884109b9526ac645194ba892a74Michal Krol
15302861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_InstructionSequence(&parseState, instBuffer)) {
15312861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLuint u;
15322861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* successful parse! */
15332861e737e84e4884109b9526ac645194ba892a74Michal Krol
15342861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (parseState.outputsWritten == 0) {
15352861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* must write at least one output! */
15362861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_error(ctx, GL_INVALID_OPERATION,
15372861e737e84e4884109b9526ac645194ba892a74Michal Krol                     "Invalid fragment program - no outputs written.");
15382861e737e84e4884109b9526ac645194ba892a74Michal Krol         return;
15392861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
15402861e737e84e4884109b9526ac645194ba892a74Michal Krol
15412861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* copy the compiled instructions */
15422861e737e84e4884109b9526ac645194ba892a74Michal Krol      assert(parseState.numInst <= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS);
1543383c39e58e0ab888afac473526109b62ec0f8f6fBrian Paul      newInst = _mesa_alloc_instructions(parseState.numInst);
15442861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!newInst) {
15452861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
15462861e737e84e4884109b9526ac645194ba892a74Michal Krol         return;  /* out of memory */
15472861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
154812229f119d754715e0315846fdd8d6e9213e8edfBrian      _mesa_copy_instructions(newInst, instBuffer, parseState.numInst);
15492861e737e84e4884109b9526ac645194ba892a74Michal Krol
15502861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* install the program */
15512861e737e84e4884109b9526ac645194ba892a74Michal Krol      program->Base.Target = target;
15522861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (program->Base.String) {
15532861e737e84e4884109b9526ac645194ba892a74Michal Krol         FREE(program->Base.String);
15542861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
15552861e737e84e4884109b9526ac645194ba892a74Michal Krol      program->Base.String = programString;
15562861e737e84e4884109b9526ac645194ba892a74Michal Krol      program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB;
1557de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul      if (program->Base.Instructions) {
155832f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg         free(program->Base.Instructions);
15592861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
1560de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul      program->Base.Instructions = newInst;
1561ee40c4fb34bd06ecc6dd6f2e658ca2c2c20af952Brian Paul      program->Base.NumInstructions = parseState.numInst;
1562de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul      program->Base.InputsRead = parseState.inputsRead;
1563de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul      program->Base.OutputsWritten = parseState.outputsWritten;
15642861e737e84e4884109b9526ac645194ba892a74Michal Krol      for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++)
1565c9db223f902ce9d7e9f3038e6baac6da7f231b34Brian         program->Base.TexturesUsed[u] = parseState.texturesUsed[u];
15662861e737e84e4884109b9526ac645194ba892a74Michal Krol
15672861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* save program parameters */
1568de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul      program->Base.Parameters = parseState.parameters;
15692861e737e84e4884109b9526ac645194ba892a74Michal Krol
15702861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* allocate registers for declared program parameters */
15712861e737e84e4884109b9526ac645194ba892a74Michal Krol#if 00
15722861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_assign_program_registers(&(program->SymbolTable));
15732861e737e84e4884109b9526ac645194ba892a74Michal Krol#endif
15742861e737e84e4884109b9526ac645194ba892a74Michal Krol
1575ac33dd1312530e0bab0c7e5d25c9d70f4e884753Brian Paul#ifdef DEBUG_foo
1576298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf("--- glLoadProgramNV(%d) result ---\n", program->Base.Id);
1577fe278f1e600058af18c6ba5fe77bfc5a772bf9f5Brian Paul      _mesa_fprint_program_opt(stdout, &program->Base, PROG_PRINT_NV, 0);
1578298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf("----------------------------------\n");
15792861e737e84e4884109b9526ac645194ba892a74Michal Krol#endif
15802861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15812861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
15822861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* Error! */
15832861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV");
15842861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* NOTE: _mesa_set_program_error would have been called already */
15852861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15862861e737e84e4884109b9526ac645194ba892a74Michal Krol}
15872861e737e84e4884109b9526ac645194ba892a74Michal Krol
15882861e737e84e4884109b9526ac645194ba892a74Michal Krol
15892861e737e84e4884109b9526ac645194ba892a74Michal Krolconst char *
15902861e737e84e4884109b9526ac645194ba892a74Michal Krol_mesa_nv_fragment_input_register_name(GLuint i)
15912861e737e84e4884109b9526ac645194ba892a74Michal Krol{
15922861e737e84e4884109b9526ac645194ba892a74Michal Krol   ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_INPUTS);
15932861e737e84e4884109b9526ac645194ba892a74Michal Krol   return InputRegisters[i];
15942861e737e84e4884109b9526ac645194ba892a74Michal Krol}
15952861e737e84e4884109b9526ac645194ba892a74Michal Krol
1596