nvfragparse.c revision e197de56cdb86835f1437688a9161cd909792d80
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 {
1442861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLcontext *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);
1742861e737e84e4884109b9526ac645194ba892a74Michal Krol   _mesa_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];							\
2032861e737e84e4884109b9526ac645194ba892a74Michal Krol   _mesa_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
4592861e737e84e4884109b9526ac645194ba892a74Michal Krol   *number = (GLfloat) _mesa_strtod((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");
4752861e737e84e4884109b9526ac645194ba892a74Michal Krol      constant = _mesa_lookup_parameter_value(parseState->parameters,
4762861e737e84e4884109b9526ac645194ba892a74Michal Krol                                              -1, (const char *) ident);
4772861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* XXX Check that it's a constant and not a parameter */
4782861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!constant) {
4792861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Undefined symbol");
4802861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
4812861e737e84e4884109b9526ac645194ba892a74Michal Krol      else {
4822861e737e84e4884109b9526ac645194ba892a74Michal Krol         COPY_4V(number, constant);
4832861e737e84e4884109b9526ac645194ba892a74Michal Krol         return GL_TRUE;
4842861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
4852861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
4862861e737e84e4884109b9526ac645194ba892a74Michal Krol}
4872861e737e84e4884109b9526ac645194ba892a74Michal Krol
4882861e737e84e4884109b9526ac645194ba892a74Michal Krol
4892861e737e84e4884109b9526ac645194ba892a74Michal Krol
4902861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
4912861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a vector constant, one of:
4922861e737e84e4884109b9526ac645194ba892a74Michal Krol *   { float }
4932861e737e84e4884109b9526ac645194ba892a74Michal Krol *   { float, float }
4942861e737e84e4884109b9526ac645194ba892a74Michal Krol *   { float, float, float }
4952861e737e84e4884109b9526ac645194ba892a74Michal Krol *   { float, float, float, float }
4962861e737e84e4884109b9526ac645194ba892a74Michal Krol */
4972861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
4982861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_VectorConstant(struct parse_state *parseState, GLfloat *vec)
4992861e737e84e4884109b9526ac645194ba892a74Michal Krol{
5002861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* "{" was already consumed */
5012861e737e84e4884109b9526ac645194ba892a74Michal Krol
5022861e737e84e4884109b9526ac645194ba892a74Michal Krol   ASSIGN_4V(vec, 0.0, 0.0, 0.0, 1.0);
5032861e737e84e4884109b9526ac645194ba892a74Michal Krol
5042861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_ScalarConstant(parseState, vec+0))  /* X */
5052861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_FALSE;
5062861e737e84e4884109b9526ac645194ba892a74Michal Krol
5072861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "}")) {
5082861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_TRUE;
5092861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5102861e737e84e4884109b9526ac645194ba892a74Michal Krol
5112861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, ","))
5122861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected comma in vector constant");
5132861e737e84e4884109b9526ac645194ba892a74Michal Krol
5142861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_ScalarConstant(parseState, vec+1))  /* Y */
5152861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_FALSE;
5162861e737e84e4884109b9526ac645194ba892a74Michal Krol
5172861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "}")) {
5182861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_TRUE;
5192861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5202861e737e84e4884109b9526ac645194ba892a74Michal Krol
5212861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, ","))
5222861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected comma in vector constant");
5232861e737e84e4884109b9526ac645194ba892a74Michal Krol
5242861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_ScalarConstant(parseState, vec+2))  /* Z */
5252861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_FALSE;
5262861e737e84e4884109b9526ac645194ba892a74Michal Krol
5272861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "}")) {
5282861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_TRUE;
5292861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5302861e737e84e4884109b9526ac645194ba892a74Michal Krol
5312861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, ","))
5322861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected comma in vector constant");
5332861e737e84e4884109b9526ac645194ba892a74Michal Krol
5342861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_ScalarConstant(parseState, vec+3))  /* W */
5352861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_FALSE;
5362861e737e84e4884109b9526ac645194ba892a74Michal Krol
5372861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "}"))
5382861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected closing brace in vector constant");
5392861e737e84e4884109b9526ac645194ba892a74Michal Krol
5402861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
5412861e737e84e4884109b9526ac645194ba892a74Michal Krol}
5422861e737e84e4884109b9526ac645194ba892a74Michal Krol
5432861e737e84e4884109b9526ac645194ba892a74Michal Krol
5442861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
5452861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse <number>, <varname> or {a, b, c, d}.
5462861e737e84e4884109b9526ac645194ba892a74Michal Krol * Return number of values in the vector or scalar, or zero if parse error.
5472861e737e84e4884109b9526ac645194ba892a74Michal Krol */
5482861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLuint
5492861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_VectorOrScalarConstant(struct parse_state *parseState, GLfloat *vec)
5502861e737e84e4884109b9526ac645194ba892a74Michal Krol{
5512861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "{")) {
5522861e737e84e4884109b9526ac645194ba892a74Michal Krol      return Parse_VectorConstant(parseState, vec);
5532861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5542861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
5552861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLboolean b = Parse_ScalarConstant(parseState, vec);
5562861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (b) {
5572861e737e84e4884109b9526ac645194ba892a74Michal Krol         vec[1] = vec[2] = vec[3] = vec[0];
5582861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
5592861e737e84e4884109b9526ac645194ba892a74Michal Krol      return b;
5602861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5612861e737e84e4884109b9526ac645194ba892a74Michal Krol}
5622861e737e84e4884109b9526ac645194ba892a74Michal Krol
5632861e737e84e4884109b9526ac645194ba892a74Michal Krol
5642861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
5652861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a texture image source:
5662861e737e84e4884109b9526ac645194ba892a74Michal Krol *    [TEX0 | TEX1 | .. | TEX15] , [1D | 2D | 3D | CUBE | RECT]
5672861e737e84e4884109b9526ac645194ba892a74Michal Krol */
5682861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
5692861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_TextureImageId(struct parse_state *parseState,
5702861e737e84e4884109b9526ac645194ba892a74Michal Krol                     GLubyte *texUnit, GLubyte *texTargetBit)
5712861e737e84e4884109b9526ac645194ba892a74Michal Krol{
5722861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte imageSrc[100];
5732861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLint unit;
5742861e737e84e4884109b9526ac645194ba892a74Michal Krol
5752861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_Token(parseState, imageSrc))
5762861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
5772861e737e84e4884109b9526ac645194ba892a74Michal Krol
5782861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (imageSrc[0] != 'T' ||
5792861e737e84e4884109b9526ac645194ba892a74Michal Krol       imageSrc[1] != 'E' ||
5802861e737e84e4884109b9526ac645194ba892a74Michal Krol       imageSrc[2] != 'X') {
5812861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected TEX# source");
5822861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
58360b0cae412029e53654f38d0de151908f1feb310Kenneth Graunke   unit = atoi((const char *) imageSrc + 3);
5842861e737e84e4884109b9526ac645194ba892a74Michal Krol   if ((unit < 0 || unit > MAX_TEXTURE_IMAGE_UNITS) ||
5852861e737e84e4884109b9526ac645194ba892a74Michal Krol       (unit == 0 && (imageSrc[3] != '0' || imageSrc[4] != 0))) {
5862861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalied TEX# source index");
5872861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5882861e737e84e4884109b9526ac645194ba892a74Michal Krol   *texUnit = unit;
5892861e737e84e4884109b9526ac645194ba892a74Michal Krol
5902861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, ","))
5912861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected ,");
5922861e737e84e4884109b9526ac645194ba892a74Michal Krol
5932861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "1D")) {
5942861e737e84e4884109b9526ac645194ba892a74Michal Krol      *texTargetBit = TEXTURE_1D_BIT;
5952861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5962861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "2D")) {
5972861e737e84e4884109b9526ac645194ba892a74Michal Krol      *texTargetBit = TEXTURE_2D_BIT;
5982861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5992861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "3D")) {
6002861e737e84e4884109b9526ac645194ba892a74Michal Krol      *texTargetBit = TEXTURE_3D_BIT;
6012861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6022861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "CUBE")) {
6032861e737e84e4884109b9526ac645194ba892a74Michal Krol      *texTargetBit = TEXTURE_CUBE_BIT;
6042861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6052861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "RECT")) {
6062861e737e84e4884109b9526ac645194ba892a74Michal Krol      *texTargetBit = TEXTURE_RECT_BIT;
6072861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6082861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
6092861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalid texture target token");
6102861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6112861e737e84e4884109b9526ac645194ba892a74Michal Krol
6122861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* update record of referenced texture units */
6132861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState->texturesUsed[*texUnit] |= *texTargetBit;
6142861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (_mesa_bitcount(parseState->texturesUsed[*texUnit]) > 1) {
6152861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Only one texture target can be used per texture unit.");
6162861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6172861e737e84e4884109b9526ac645194ba892a74Michal Krol
6182861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
6192861e737e84e4884109b9526ac645194ba892a74Michal Krol}
6202861e737e84e4884109b9526ac645194ba892a74Michal Krol
6212861e737e84e4884109b9526ac645194ba892a74Michal Krol
6222861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
6232861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a scalar suffix like .x, .y, .z or .w or parse a swizzle suffix
6242861e737e84e4884109b9526ac645194ba892a74Michal Krol * like .wxyz, .xxyy, etc and return the swizzle indexes.
6252861e737e84e4884109b9526ac645194ba892a74Michal Krol */
6262861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
6272861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_SwizzleSuffix(const GLubyte *token, GLuint swizzle[4])
6282861e737e84e4884109b9526ac645194ba892a74Michal Krol{
6292861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (token[1] == 0) {
6302861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* single letter swizzle (scalar) */
6312861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[0] == 'x')
6322861e737e84e4884109b9526ac645194ba892a74Michal Krol         ASSIGN_4V(swizzle, 0, 0, 0, 0);
6332861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (token[0] == 'y')
6342861e737e84e4884109b9526ac645194ba892a74Michal Krol         ASSIGN_4V(swizzle, 1, 1, 1, 1);
6352861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (token[0] == 'z')
6362861e737e84e4884109b9526ac645194ba892a74Michal Krol         ASSIGN_4V(swizzle, 2, 2, 2, 2);
6372861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (token[0] == 'w')
6382861e737e84e4884109b9526ac645194ba892a74Michal Krol         ASSIGN_4V(swizzle, 3, 3, 3, 3);
6392861e737e84e4884109b9526ac645194ba892a74Michal Krol      else
6402861e737e84e4884109b9526ac645194ba892a74Michal Krol         return GL_FALSE;
6412861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6422861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
6432861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* 4-component swizzle (vector) */
6442861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLint k;
645324568f79d6e014900c981bd9a0e1dffedc326c8Roel Kluin      for (k = 0; k < 4 && token[k]; k++) {
6462861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (token[k] == 'x')
6472861e737e84e4884109b9526ac645194ba892a74Michal Krol            swizzle[k] = 0;
6482861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (token[k] == 'y')
6492861e737e84e4884109b9526ac645194ba892a74Michal Krol            swizzle[k] = 1;
6502861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (token[k] == 'z')
6512861e737e84e4884109b9526ac645194ba892a74Michal Krol            swizzle[k] = 2;
6522861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (token[k] == 'w')
6532861e737e84e4884109b9526ac645194ba892a74Michal Krol            swizzle[k] = 3;
6542861e737e84e4884109b9526ac645194ba892a74Michal Krol         else
6552861e737e84e4884109b9526ac645194ba892a74Michal Krol            return GL_FALSE;
6562861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
6572861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (k != 4)
6582861e737e84e4884109b9526ac645194ba892a74Michal Krol         return GL_FALSE;
6592861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6602861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
6612861e737e84e4884109b9526ac645194ba892a74Michal Krol}
6622861e737e84e4884109b9526ac645194ba892a74Michal Krol
6632861e737e84e4884109b9526ac645194ba892a74Michal Krol
6642861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
6652861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_CondCodeMask(struct parse_state *parseState,
6667e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul                   struct prog_dst_register *dstReg)
6672861e737e84e4884109b9526ac645194ba892a74Michal Krol{
6682861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "EQ"))
6692861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_EQ;
6702861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "GE"))
6712861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_GE;
6722861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "GT"))
6732861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_GT;
6742861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "LE"))
6752861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_LE;
6762861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "LT"))
6772861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_LT;
6782861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "NE"))
6792861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_NE;
6802861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "TR"))
6812861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_TR;
6822861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "FL"))
6832861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_FL;
6842861e737e84e4884109b9526ac645194ba892a74Michal Krol   else
6852861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalid condition code mask");
6862861e737e84e4884109b9526ac645194ba892a74Michal Krol
6872861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* look for optional .xyzw swizzle */
6882861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, ".")) {
6892861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLubyte token[100];
6907c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      GLuint swz[4];
6917c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell
6922861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_Token(parseState, token))  /* get xyzw suffix */
6932861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
6942861e737e84e4884109b9526ac645194ba892a74Michal Krol
6957c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_SwizzleSuffix(token, swz))
6962861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid swizzle suffix");
6977c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell
698fd4395b8d1d6f8f018e7e7c3dd0c52fe52ab2794Brian Paul      dstReg->CondSwizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
6992861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7002861e737e84e4884109b9526ac645194ba892a74Michal Krol
7012861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
7022861e737e84e4884109b9526ac645194ba892a74Michal Krol}
7032861e737e84e4884109b9526ac645194ba892a74Michal Krol
7042861e737e84e4884109b9526ac645194ba892a74Michal Krol
7052861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
7062861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a temporary register: Rnn or Hnn
7072861e737e84e4884109b9526ac645194ba892a74Michal Krol */
7082861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
7092861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_TempReg(struct parse_state *parseState, GLint *tempRegNum)
7102861e737e84e4884109b9526ac645194ba892a74Michal Krol{
7112861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
7122861e737e84e4884109b9526ac645194ba892a74Michal Krol
7132861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Should be 'R##' or 'H##' */
7142861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_Token(parseState, token))
7152861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
7162861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (token[0] != 'R' && token[0] != 'H')
7172861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected R## or H##");
7182861e737e84e4884109b9526ac645194ba892a74Michal Krol
7192861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (IsDigit(token[1])) {
72060b0cae412029e53654f38d0de151908f1feb310Kenneth Graunke      GLint reg = atoi((const char *) (token + 1));
7212861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[0] == 'H')
7222861e737e84e4884109b9526ac645194ba892a74Michal Krol         reg += 32;
7232861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (reg >= MAX_NV_FRAGMENT_PROGRAM_TEMPS)
7242861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid temporary register name");
7252861e737e84e4884109b9526ac645194ba892a74Michal Krol      *tempRegNum = reg;
7262861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7272861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
7282861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalid temporary register name");
7292861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7302861e737e84e4884109b9526ac645194ba892a74Michal Krol
7312861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
7322861e737e84e4884109b9526ac645194ba892a74Michal Krol}
7332861e737e84e4884109b9526ac645194ba892a74Michal Krol
7342861e737e84e4884109b9526ac645194ba892a74Michal Krol
7352861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
7362861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a write-only dummy register: RC or HC.
7372861e737e84e4884109b9526ac645194ba892a74Michal Krol */
7382861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
7392861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_DummyReg(struct parse_state *parseState, GLint *regNum)
7402861e737e84e4884109b9526ac645194ba892a74Michal Krol{
7412861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "RC")) {
7422861e737e84e4884109b9526ac645194ba892a74Michal Krol       *regNum = 0;
7432861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7442861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "HC")) {
7452861e737e84e4884109b9526ac645194ba892a74Michal Krol       *regNum = 1;
7462861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7472861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
7482861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalid write-only register name");
7492861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7502861e737e84e4884109b9526ac645194ba892a74Michal Krol
7512861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
7522861e737e84e4884109b9526ac645194ba892a74Michal Krol}
7532861e737e84e4884109b9526ac645194ba892a74Michal Krol
7542861e737e84e4884109b9526ac645194ba892a74Michal Krol
7552861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
7562861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a program local parameter register "p[##]"
7572861e737e84e4884109b9526ac645194ba892a74Michal Krol */
7582861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
7592861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_ProgramParamReg(struct parse_state *parseState, GLint *regNum)
7602861e737e84e4884109b9526ac645194ba892a74Michal Krol{
7612861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
7622861e737e84e4884109b9526ac645194ba892a74Michal Krol
7632861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "p["))
7642861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected p[");
7652861e737e84e4884109b9526ac645194ba892a74Michal Krol
7662861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_Token(parseState, token))
7672861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
7682861e737e84e4884109b9526ac645194ba892a74Michal Krol
7692861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (IsDigit(token[0])) {
7702861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* a numbered program parameter register */
77160b0cae412029e53654f38d0de151908f1feb310Kenneth Graunke      GLint reg = atoi((const char *) token);
7722861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (reg >= MAX_NV_FRAGMENT_PROGRAM_PARAMS)
7732861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid constant program number");
7742861e737e84e4884109b9526ac645194ba892a74Michal Krol      *regNum = reg;
7752861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7762861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
7772861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
7782861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7792861e737e84e4884109b9526ac645194ba892a74Michal Krol
7802861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "]"))
7812861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected ]");
7822861e737e84e4884109b9526ac645194ba892a74Michal Krol
7832861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
7842861e737e84e4884109b9526ac645194ba892a74Michal Krol}
7852861e737e84e4884109b9526ac645194ba892a74Michal Krol
7862861e737e84e4884109b9526ac645194ba892a74Michal Krol
7872861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
7882861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse f[name]  - fragment input register
7892861e737e84e4884109b9526ac645194ba892a74Michal Krol */
7902861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
7912861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_FragReg(struct parse_state *parseState, GLint *tempRegNum)
7922861e737e84e4884109b9526ac645194ba892a74Michal Krol{
7932861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
7942861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLint j;
7952861e737e84e4884109b9526ac645194ba892a74Michal Krol
7962861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Match 'f[' */
7972861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "f["))
7982861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected f[");
7992861e737e84e4884109b9526ac645194ba892a74Michal Krol
8002861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* get <name> and look for match */
8012861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_Token(parseState, token)) {
8022861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
8032861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8042861e737e84e4884109b9526ac645194ba892a74Michal Krol   for (j = 0; InputRegisters[j]; j++) {
8058d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke      if (strcmp((const char *) token, InputRegisters[j]) == 0) {
8062861e737e84e4884109b9526ac645194ba892a74Michal Krol         *tempRegNum = j;
8072861e737e84e4884109b9526ac645194ba892a74Michal Krol         parseState->inputsRead |= (1 << j);
8082861e737e84e4884109b9526ac645194ba892a74Michal Krol         break;
8092861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
8102861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8112861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!InputRegisters[j]) {
8122861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* unknown input register label */
8132861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR2("Invalid register name", token);
8142861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8152861e737e84e4884109b9526ac645194ba892a74Michal Krol
8162861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Match '[' */
8172861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "]"))
8182861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected ]");
8192861e737e84e4884109b9526ac645194ba892a74Michal Krol
8202861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
8212861e737e84e4884109b9526ac645194ba892a74Michal Krol}
8222861e737e84e4884109b9526ac645194ba892a74Michal Krol
8232861e737e84e4884109b9526ac645194ba892a74Michal Krol
8242861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
8252861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_OutputReg(struct parse_state *parseState, GLint *outputRegNum)
8262861e737e84e4884109b9526ac645194ba892a74Michal Krol{
8272861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
8282861e737e84e4884109b9526ac645194ba892a74Michal Krol
8292861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Match "o[" */
8302861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "o["))
8312861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected o[");
8322861e737e84e4884109b9526ac645194ba892a74Michal Krol
8332861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Get output reg name */
8342861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_Token(parseState, token))
8352861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
8362861e737e84e4884109b9526ac645194ba892a74Michal Krol
8372861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* try to match an output register name */
8388d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke   if (strcmp((char *) token, "COLR") == 0 ||
8398d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke       strcmp((char *) token, "COLH") == 0) {
8408d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul      /* note that we don't distinguish between COLR and COLH */
8418d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul      *outputRegNum = FRAG_RESULT_COLOR;
8428d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul      parseState->outputsWritten |= (1 << FRAG_RESULT_COLOR);
8432861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8448d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke   else if (strcmp((char *) token, "DEPR") == 0) {
8458d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul      *outputRegNum = FRAG_RESULT_DEPTH;
8468d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul      parseState->outputsWritten |= (1 << FRAG_RESULT_DEPTH);
8478d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul   }
8488d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul   else {
8492861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalid output register name");
8508d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul   }
8512861e737e84e4884109b9526ac645194ba892a74Michal Krol
8522861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Match ']' */
8532861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "]"))
8542861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected ]");
8552861e737e84e4884109b9526ac645194ba892a74Michal Krol
8562861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
8572861e737e84e4884109b9526ac645194ba892a74Michal Krol}
8582861e737e84e4884109b9526ac645194ba892a74Michal Krol
8592861e737e84e4884109b9526ac645194ba892a74Michal Krol
8602861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
8612861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_MaskedDstReg(struct parse_state *parseState,
8627e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul                   struct prog_dst_register *dstReg)
8632861e737e84e4884109b9526ac645194ba892a74Michal Krol{
8642861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
8657c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   GLint idx;
8662861e737e84e4884109b9526ac645194ba892a74Michal Krol
8672861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Dst reg can be R<n>, H<n>, o[n], RC or HC */
8682861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Peek_Token(parseState, token))
8692861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
8702861e737e84e4884109b9526ac645194ba892a74Michal Krol
8718d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke   if (strcmp((const char *) token, "RC") == 0 ||
8728d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke       strcmp((const char *) token, "HC") == 0) {
8732861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* a write-only register */
8742861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->File = PROGRAM_WRITE_ONLY;
8757c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_DummyReg(parseState, &idx))
8762861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
8777c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      dstReg->Index = idx;
8782861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8792861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == 'R' || token[0] == 'H') {
8802861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* a temporary register */
8812861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->File = PROGRAM_TEMPORARY;
8827c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_TempReg(parseState, &idx))
8832861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
8847c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      dstReg->Index = idx;
8852861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8862861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == 'o') {
8872861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* an output register */
8882861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->File = PROGRAM_OUTPUT;
8897c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_OutputReg(parseState, &idx))
8902861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
8917c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      dstReg->Index = idx;
8922861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8932861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
8942861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalid destination register name");
8952861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8962861e737e84e4884109b9526ac645194ba892a74Michal Krol
8972861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Parse optional write mask */
8982861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, ".")) {
8992861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* got a mask */
9002861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLint k = 0;
9012861e737e84e4884109b9526ac645194ba892a74Michal Krol
9022861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_Token(parseState, token))  /* get xyzw writemask */
9032861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
9042861e737e84e4884109b9526ac645194ba892a74Michal Krol
9057c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      dstReg->WriteMask = 0;
9062861e737e84e4884109b9526ac645194ba892a74Michal Krol
9072861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[k] == 'x') {
9087c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         dstReg->WriteMask |= WRITEMASK_X;
9092861e737e84e4884109b9526ac645194ba892a74Michal Krol         k++;
9102861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
9112861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[k] == 'y') {
9127c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         dstReg->WriteMask |= WRITEMASK_Y;
9132861e737e84e4884109b9526ac645194ba892a74Michal Krol         k++;
9142861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
9152861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[k] == 'z') {
9167c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         dstReg->WriteMask |= WRITEMASK_Z;
9172861e737e84e4884109b9526ac645194ba892a74Michal Krol         k++;
9182861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
9192861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[k] == 'w') {
9207c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         dstReg->WriteMask |= WRITEMASK_W;
9212861e737e84e4884109b9526ac645194ba892a74Michal Krol         k++;
9222861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
9232861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (k == 0) {
9242861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid writemask character");
9252861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
9262861e737e84e4884109b9526ac645194ba892a74Michal Krol
9272861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9282861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
9297c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      dstReg->WriteMask = WRITEMASK_XYZW;
9302861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9312861e737e84e4884109b9526ac645194ba892a74Michal Krol
9322861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* optional condition code mask */
9332861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "(")) {
9342861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".x|y|z|w) */
9352861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".[xyzw]) */
9362861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_CondCodeMask(parseState, dstReg))
9372861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
9382861e737e84e4884109b9526ac645194ba892a74Michal Krol
9392861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_String(parseState, ")"))  /* consume ")" */
9402861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Expected )");
9412861e737e84e4884109b9526ac645194ba892a74Michal Krol
9422861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_TRUE;
9432861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9442861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
9452861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* no cond code mask */
9462861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_TR;
9477c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      dstReg->CondSwizzle = SWIZZLE_NOOP;
9482861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_TRUE;
9492861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9502861e737e84e4884109b9526ac645194ba892a74Michal Krol}
9512861e737e84e4884109b9526ac645194ba892a74Michal Krol
9522861e737e84e4884109b9526ac645194ba892a74Michal Krol
9532861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
9542861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a vector source (register, constant, etc):
9552861e737e84e4884109b9526ac645194ba892a74Michal Krol *   <vectorSrc>    ::= <absVectorSrc>
9562861e737e84e4884109b9526ac645194ba892a74Michal Krol *                    | <baseVectorSrc>
9572861e737e84e4884109b9526ac645194ba892a74Michal Krol *   <absVectorSrc> ::= <negate> "|" <baseVectorSrc> "|"
9582861e737e84e4884109b9526ac645194ba892a74Michal Krol */
9592861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
9602861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_VectorSrc(struct parse_state *parseState,
9617e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul                struct prog_src_register *srcReg)
9622861e737e84e4884109b9526ac645194ba892a74Michal Krol{
9632861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLfloat sign = 1.0F;
9642861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
9657c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   GLint idx;
9667db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul   GLuint negateBase, negateAbs;
9672861e737e84e4884109b9526ac645194ba892a74Michal Krol
9682861e737e84e4884109b9526ac645194ba892a74Michal Krol   /*
9692861e737e84e4884109b9526ac645194ba892a74Michal Krol    * First, take care of +/- and absolute value stuff.
9702861e737e84e4884109b9526ac645194ba892a74Michal Krol    */
9712861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "-"))
9722861e737e84e4884109b9526ac645194ba892a74Michal Krol      sign = -1.0F;
9732861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "+"))
9742861e737e84e4884109b9526ac645194ba892a74Michal Krol      sign = +1.0F;
9752861e737e84e4884109b9526ac645194ba892a74Michal Krol
9762861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "|")) {
9772861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Abs = GL_TRUE;
9787db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul      negateAbs = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
9792861e737e84e4884109b9526ac645194ba892a74Michal Krol
9802861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (Parse_String(parseState, "-"))
9817db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul         negateBase = NEGATE_XYZW;
9822861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (Parse_String(parseState, "+"))
9837db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul         negateBase = NEGATE_NONE;
9842861e737e84e4884109b9526ac645194ba892a74Michal Krol      else
9857db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul         negateBase = NEGATE_NONE;
9862861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9872861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
9882861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Abs = GL_FALSE;
9897db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul      negateAbs = NEGATE_NONE;
9907db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul      negateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
9912861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9922861e737e84e4884109b9526ac645194ba892a74Michal Krol
9937db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul   srcReg->Negate = srcReg->Abs ? negateAbs : negateBase;
9947db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul
9952861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* This should be the real src vector/register name */
9962861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Peek_Token(parseState, token))
9972861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
9982861e737e84e4884109b9526ac645194ba892a74Michal Krol
9992861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Src reg can be Rn, Hn, f[n], p[n], a named parameter, a scalar
10002861e737e84e4884109b9526ac645194ba892a74Michal Krol    * literal or vector literal.
10012861e737e84e4884109b9526ac645194ba892a74Michal Krol    */
10022861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (token[0] == 'R' || token[0] == 'H') {
10032861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_TEMPORARY;
10047c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_TempReg(parseState, &idx))
10052861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
10067c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      srcReg->Index = idx;
10072861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10082861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == 'f') {
1009e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      /* XXX this might be an identifier! */
10102861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_INPUT;
10117c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_FragReg(parseState, &idx))
10122861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
10137c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      srcReg->Index = idx;
10142861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10152861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == 'p') {
1016e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      /* XXX this might be an identifier! */
10172861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_LOCAL_PARAM;
10187c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_ProgramParamReg(parseState, &idx))
10192861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
10207c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      srcReg->Index = idx;
10212861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10222861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (IsLetter(token[0])){
10232861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLubyte ident[100];
10242861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLint paramIndex;
10252861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_Identifier(parseState, ident))
10262861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
10272861e737e84e4884109b9526ac645194ba892a74Michal Krol      paramIndex = _mesa_lookup_parameter_index(parseState->parameters,
10282861e737e84e4884109b9526ac645194ba892a74Michal Krol                                                -1, (const char *) ident);
10292861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (paramIndex < 0) {
10302861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR2("Undefined constant or parameter: ", ident);
10312861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
10322861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_NAMED_PARAM;
10332861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Index = paramIndex;
10342861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10352861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (IsDigit(token[0]) || token[0] == '-' || token[0] == '+' || token[0] == '.'){
10362861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* literal scalar constant */
10372861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLfloat values[4];
1038257f799849a1eb3e81851b92a8fd27efa8f93d47Brian      GLuint paramIndex;
10392861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_ScalarConstant(parseState, values))
10402861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
1041fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
10421bf81e3c5d65b636658d11072f4f027f5c499396Brian                                              values, 4, NULL);
10432861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_NAMED_PARAM;
10442861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Index = paramIndex;
10452861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10462861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == '{'){
10472861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* literal vector constant */
10482861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLfloat values[4];
1049257f799849a1eb3e81851b92a8fd27efa8f93d47Brian      GLuint paramIndex;
10502861e737e84e4884109b9526ac645194ba892a74Michal Krol      (void) Parse_String(parseState, "{");
10512861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_VectorConstant(parseState, values))
10522861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
1053fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
10541bf81e3c5d65b636658d11072f4f027f5c499396Brian                                              values, 4, NULL);
10552861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_NAMED_PARAM;
10562861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Index = paramIndex;
10572861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10582861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
10592861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR2("Invalid source register name", token);
10602861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10612861e737e84e4884109b9526ac645194ba892a74Michal Krol
10622861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* init swizzle fields */
10637c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   srcReg->Swizzle = SWIZZLE_NOOP;
10642861e737e84e4884109b9526ac645194ba892a74Michal Krol
10652861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Look for optional swizzle suffix */
10662861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, ".")) {
10677c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      GLuint swz[4];
10687c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell
10692861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_Token(parseState, token))
10702861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
10712861e737e84e4884109b9526ac645194ba892a74Michal Krol
10727c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_SwizzleSuffix(token, swz))
10732861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid swizzle suffix");
10747c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell
1075fd4395b8d1d6f8f018e7e7c3dd0c52fe52ab2794Brian Paul      srcReg->Swizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
10762861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10772861e737e84e4884109b9526ac645194ba892a74Michal Krol
10782861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Finish absolute value */
10792861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (srcReg->Abs && !Parse_String(parseState, "|")) {
10802861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected |");
10812861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10822861e737e84e4884109b9526ac645194ba892a74Michal Krol
10832861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
10842861e737e84e4884109b9526ac645194ba892a74Michal Krol}
10852861e737e84e4884109b9526ac645194ba892a74Michal Krol
10862861e737e84e4884109b9526ac645194ba892a74Michal Krol
10872861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
10882861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_ScalarSrcReg(struct parse_state *parseState,
10897e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul                   struct prog_src_register *srcReg)
10902861e737e84e4884109b9526ac645194ba892a74Michal Krol{
10912861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
10922861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLfloat sign = 1.0F;
10932861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLboolean needSuffix = GL_TRUE;
10947c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   GLint idx;
10957db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul   GLuint negateBase, negateAbs;
10962861e737e84e4884109b9526ac645194ba892a74Michal Krol
10972861e737e84e4884109b9526ac645194ba892a74Michal Krol   /*
10982861e737e84e4884109b9526ac645194ba892a74Michal Krol    * First, take care of +/- and absolute value stuff.
10992861e737e84e4884109b9526ac645194ba892a74Michal Krol    */
11002861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "-"))
11012861e737e84e4884109b9526ac645194ba892a74Michal Krol      sign = -1.0F;
11022861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "+"))
11032861e737e84e4884109b9526ac645194ba892a74Michal Krol      sign = +1.0F;
11042861e737e84e4884109b9526ac645194ba892a74Michal Krol
11052861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "|")) {
11062861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Abs = GL_TRUE;
11077db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul      negateAbs = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
11082861e737e84e4884109b9526ac645194ba892a74Michal Krol
11092861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (Parse_String(parseState, "-"))
11107db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul         negateBase = NEGATE_XYZW;
11112861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (Parse_String(parseState, "+"))
11127db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul         negateBase = NEGATE_NONE;
11132861e737e84e4884109b9526ac645194ba892a74Michal Krol      else
11147db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul         negateBase = NEGATE_NONE;
11152861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11162861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
11172861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Abs = GL_FALSE;
11187db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul      negateAbs = NEGATE_NONE;
11197db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul      negateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
11202861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11212861e737e84e4884109b9526ac645194ba892a74Michal Krol
11227db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul   srcReg->Negate = srcReg->Abs ? negateAbs : negateBase;
11237db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul
11242861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Peek_Token(parseState, token))
11252861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
11262861e737e84e4884109b9526ac645194ba892a74Michal Krol
11272861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Src reg can be R<n>, H<n> or a named fragment attrib */
11282861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (token[0] == 'R' || token[0] == 'H') {
11292861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_TEMPORARY;
11307c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_TempReg(parseState, &idx))
11312861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
11327c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      srcReg->Index = idx;
11332861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11342861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == 'f') {
11352861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_INPUT;
11367c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_FragReg(parseState, &idx))
11372861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
11387c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      srcReg->Index = idx;
11392861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11402861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == '{') {
11412861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* vector literal */
11422861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLfloat values[4];
114381c4fee160cd2840caf77bbdbf462e783911141aBrian      GLuint paramIndex;
11442861e737e84e4884109b9526ac645194ba892a74Michal Krol      (void) Parse_String(parseState, "{");
11452861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_VectorConstant(parseState, values))
11462861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
1147fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
11481bf81e3c5d65b636658d11072f4f027f5c499396Brian                                              values, 4, NULL);
11492861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_NAMED_PARAM;
11502861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Index = paramIndex;
11512861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
1152e6940f0a33a571b199bab60b680c30b718c47445Brian Paul   else if (IsLetter(token[0])){
1153e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      /* named param/constant */
1154e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      GLubyte ident[100];
1155e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      GLint paramIndex;
1156e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      if (!Parse_Identifier(parseState, ident))
1157e6940f0a33a571b199bab60b680c30b718c47445Brian Paul         RETURN_ERROR;
1158e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      paramIndex = _mesa_lookup_parameter_index(parseState->parameters,
1159e6940f0a33a571b199bab60b680c30b718c47445Brian Paul                                                -1, (const char *) ident);
1160e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      if (paramIndex < 0) {
1161e6940f0a33a571b199bab60b680c30b718c47445Brian Paul         RETURN_ERROR2("Undefined constant or parameter: ", ident);
1162e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      }
1163e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      srcReg->File = PROGRAM_NAMED_PARAM;
1164e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      srcReg->Index = paramIndex;
1165e6940f0a33a571b199bab60b680c30b718c47445Brian Paul   }
11662861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (IsDigit(token[0])) {
11672861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* scalar literal */
11682861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLfloat values[4];
116981c4fee160cd2840caf77bbdbf462e783911141aBrian      GLuint paramIndex;
11702861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_ScalarConstant(parseState, values))
11712861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
1172fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
11731bf81e3c5d65b636658d11072f4f027f5c499396Brian                                              values, 4, NULL);
11742861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Index = paramIndex;
11752861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_NAMED_PARAM;
11762861e737e84e4884109b9526ac645194ba892a74Michal Krol      needSuffix = GL_FALSE;
11772861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11782861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
11792861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR2("Invalid scalar source argument", token);
11802861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11812861e737e84e4884109b9526ac645194ba892a74Michal Krol
11827c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   srcReg->Swizzle = 0;
11832861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (needSuffix) {
11842861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* parse .[xyzw] suffix */
11852861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_String(parseState, "."))
11862861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Expected .");
11872861e737e84e4884109b9526ac645194ba892a74Michal Krol
11882861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_Token(parseState, token))
11892861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
11902861e737e84e4884109b9526ac645194ba892a74Michal Krol
11912861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[0] == 'x' && token[1] == 0) {
11927c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         srcReg->Swizzle = 0;
11932861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
11942861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (token[0] == 'y' && token[1] == 0) {
11957c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         srcReg->Swizzle = 1;
11962861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
11972861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (token[0] == 'z' && token[1] == 0) {
11987c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         srcReg->Swizzle = 2;
11992861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
12002861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (token[0] == 'w' && token[1] == 0) {
12017c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         srcReg->Swizzle = 3;
12022861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
12032861e737e84e4884109b9526ac645194ba892a74Michal Krol      else {
12042861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid scalar source suffix");
12052861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
12062861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
12072861e737e84e4884109b9526ac645194ba892a74Michal Krol
12082861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Finish absolute value */
12092861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (srcReg->Abs && !Parse_String(parseState, "|")) {
12102861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected |");
12112861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
12122861e737e84e4884109b9526ac645194ba892a74Michal Krol
12132861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
12142861e737e84e4884109b9526ac645194ba892a74Michal Krol}
12152861e737e84e4884109b9526ac645194ba892a74Michal Krol
12162861e737e84e4884109b9526ac645194ba892a74Michal Krol
12172a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paulstatic GLboolean
12182a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian PaulParse_PrintInstruction(struct parse_state *parseState,
12197e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul                       struct prog_instruction *inst)
12202a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul{
12212a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   const GLubyte *str;
12222a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   GLubyte *msg;
12232a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   GLuint len;
12247c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   GLint idx;
12252a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul
12262a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   /* The first argument is a literal string 'just like this' */
12272a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   if (!Parse_String(parseState, "'"))
12282a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      RETURN_ERROR1("Expected '");
12292a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul
12302a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   str = parseState->pos;
12312a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   for (len = 0; str[len] != '\''; len++) /* find closing quote */
12322a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      ;
12332a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   parseState->pos += len + 1;
12349580179dfb42d5b81ff6ec9704b82a556c7f1229Brian Paul   msg = (GLubyte*) _mesa_malloc(len + 1);
12352a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul
1236c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke   memcpy(msg, str, len);
12372a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   msg[len] = 0;
12382a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   inst->Data = msg;
12392a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul
12402a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   if (Parse_String(parseState, ",")) {
12412a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      /* got an optional register to print */
12422a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      GLubyte token[100];
12432a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      GetToken(parseState, token);
12442a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      if (token[0] == 'o') {
12452a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul         /* dst reg */
12467c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         if (!Parse_OutputReg(parseState, &idx))
12472a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul            RETURN_ERROR;
12487c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell	 inst->SrcReg[0].Index = idx;
12492a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul         inst->SrcReg[0].File = PROGRAM_OUTPUT;
12502a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      }
12512a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      else {
12522a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul         /* src reg */
12532a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul         if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
12542a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul            RETURN_ERROR;
12552a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      }
12562a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   }
12572a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   else {
12588cdf3729468aefb7c67c8ecd32fd850adbf6d351Brian Paul      inst->SrcReg[0].File = PROGRAM_UNDEFINED;
12592a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   }
12602a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul
12617c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   inst->SrcReg[0].Swizzle = SWIZZLE_NOOP;
12622a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   inst->SrcReg[0].Abs = GL_FALSE;
12637db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul   inst->SrcReg[0].Negate = NEGATE_NONE;
12642a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul
12652a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   return GL_TRUE;
12662a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul}
12672a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul
12682861e737e84e4884109b9526ac645194ba892a74Michal Krol
12692861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
12702861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_InstructionSequence(struct parse_state *parseState,
12717e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul                          struct prog_instruction program[])
12722861e737e84e4884109b9526ac645194ba892a74Michal Krol{
12732861e737e84e4884109b9526ac645194ba892a74Michal Krol   while (1) {
12747e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul      struct prog_instruction *inst = program + parseState->numInst;
12752861e737e84e4884109b9526ac645194ba892a74Michal Krol      struct instruction_pattern instMatch;
12762861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLubyte token[100];
12772861e737e84e4884109b9526ac645194ba892a74Michal Krol
12782861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* Initialize the instruction */
1279d6272e06172f7ac7a0d6e8062e8ffba33e1ab3baBrian Paul      _mesa_init_instructions(inst, 1);
12802861e737e84e4884109b9526ac645194ba892a74Michal Krol
12812861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* special instructions */
12822861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (Parse_String(parseState, "DEFINE")) {
12832861e737e84e4884109b9526ac645194ba892a74Michal Krol         GLubyte id[100];
12842861e737e84e4884109b9526ac645194ba892a74Michal Krol         GLfloat value[7];  /* yes, 7 to be safe */
12852861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_Identifier(parseState, id))
12862861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR;
12872861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* XXX make sure id is not a reserved identifer, like R9 */
12882861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_String(parseState, "="))
12892861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Expected =");
12902861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_VectorOrScalarConstant(parseState, value))
12912861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR;
12922861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_String(parseState, ";"))
12932861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Expected ;");
12942861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (_mesa_lookup_parameter_index(parseState->parameters,
12952861e737e84e4884109b9526ac645194ba892a74Michal Krol                                          -1, (const char *) id) >= 0) {
12962861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR2(id, "already defined");
12972861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
12982861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_add_named_parameter(parseState->parameters,
12992861e737e84e4884109b9526ac645194ba892a74Michal Krol                                   (const char *) id, value);
13002861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
13012861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (Parse_String(parseState, "DECLARE")) {
13022861e737e84e4884109b9526ac645194ba892a74Michal Krol         GLubyte id[100];
13032861e737e84e4884109b9526ac645194ba892a74Michal Krol         GLfloat value[7] = {0, 0, 0, 0, 0, 0, 0};  /* yes, to be safe */
13042861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_Identifier(parseState, id))
13052861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR;
13062861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* XXX make sure id is not a reserved identifer, like R9 */
13072861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (Parse_String(parseState, "=")) {
13082861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorOrScalarConstant(parseState, value))
13092861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13102861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13112861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_String(parseState, ";"))
13122861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Expected ;");
13132861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (_mesa_lookup_parameter_index(parseState->parameters,
13142861e737e84e4884109b9526ac645194ba892a74Michal Krol                                          -1, (const char *) id) >= 0) {
13152861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR2(id, "already declared");
13162861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13172861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_add_named_parameter(parseState->parameters,
13182861e737e84e4884109b9526ac645194ba892a74Michal Krol                                   (const char *) id, value);
13192861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
13202861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (Parse_String(parseState, "END")) {
13217e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul         inst->Opcode = OPCODE_END;
13222861e737e84e4884109b9526ac645194ba892a74Michal Krol         parseState->numInst++;
13232861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (Parse_Token(parseState, token)) {
13242861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Code after END opcode.");
13252861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13262861e737e84e4884109b9526ac645194ba892a74Michal Krol         break;
13272861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
13282861e737e84e4884109b9526ac645194ba892a74Michal Krol      else {
13292861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* general/arithmetic instruction */
13302861e737e84e4884109b9526ac645194ba892a74Michal Krol
13312861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* get token */
13322861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_Token(parseState, token)) {
13332861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Missing END instruction.");
13342861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13352861e737e84e4884109b9526ac645194ba892a74Michal Krol
13362861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* try to find matching instuction */
13372861e737e84e4884109b9526ac645194ba892a74Michal Krol         instMatch = MatchInstruction(token);
133828b014ee256290eb0494b967e40c475c0c895f57Brian Paul         if (instMatch.opcode >= MAX_OPCODE) {
13392861e737e84e4884109b9526ac645194ba892a74Michal Krol            /* bad instruction name */
13402861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR2("Unexpected token: ", token);
13412861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13422861e737e84e4884109b9526ac645194ba892a74Michal Krol
13432861e737e84e4884109b9526ac645194ba892a74Michal Krol         inst->Opcode = instMatch.opcode;
13442861e737e84e4884109b9526ac645194ba892a74Michal Krol         inst->Precision = instMatch.suffixes & (_R | _H | _X);
1345e31ac052236ea615b4995f9ec301d8af4b864531Brian Paul         inst->SaturateMode = (instMatch.suffixes & (_S))
1346e31ac052236ea615b4995f9ec301d8af4b864531Brian Paul            ? SATURATE_ZERO_ONE : SATURATE_OFF;
13477e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul         inst->CondUpdate = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE;
13482861e737e84e4884109b9526ac645194ba892a74Michal Krol
13492861e737e84e4884109b9526ac645194ba892a74Michal Krol         /*
13502861e737e84e4884109b9526ac645194ba892a74Michal Krol          * parse the input and output operands
13512861e737e84e4884109b9526ac645194ba892a74Michal Krol          */
13522861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (instMatch.outputs == OUTPUT_S || instMatch.outputs == OUTPUT_V) {
13532861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
13542861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13552861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
13562861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
13572861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13582861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.outputs == OUTPUT_NONE) {
13597e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul            if (instMatch.opcode == OPCODE_KIL_NV) {
13602a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul               /* This is a little weird, the cond code info is in
13612a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul                * the dest register.
13622a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul                */
13632a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul               if (!Parse_CondCodeMask(parseState, &inst->DstReg))
13642a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul                  RETURN_ERROR;
13652a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul            }
13662a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul            else {
13677e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul               ASSERT(instMatch.opcode == OPCODE_PRINT);
13682a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul            }
13692861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13702861e737e84e4884109b9526ac645194ba892a74Michal Krol
13712861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (instMatch.inputs == INPUT_1V) {
13722861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
13732861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13742861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13752861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_2V) {
13762861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
13772861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13782861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
13792861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
13802861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
13812861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13822861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13832861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_3V) {
13842861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
13852861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13862861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
13872861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
13882861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
13892861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13902861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
13912861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
13922861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[2]))
13932861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13942861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13952861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_1S) {
13962861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
13972861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13982861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13992861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_2S) {
14002861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
14012861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14022861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
14032861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
14042861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[1]))
14052861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14062861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
14072861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_CC) {
14082861e737e84e4884109b9526ac645194ba892a74Michal Krol            /* XXX to-do */
14092861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
14102861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_1V_T) {
14117c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell	    GLubyte unit, idx;
14122861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
14132861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14142861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
14152861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
14167c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell            if (!Parse_TextureImageId(parseState, &unit, &idx))
14172861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14187c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell	    inst->TexSrcUnit = unit;
14197e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul	    inst->TexSrcTarget = idx;
14202861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
14212861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_3V_T) {
14227c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell	    GLubyte unit, idx;
14232861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
14242861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14252861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
14262861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
14272861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
14282861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14292861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
14302861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
14312861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[2]))
14322861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14332861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
14342861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
14357c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell            if (!Parse_TextureImageId(parseState, &unit, &idx))
14362861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14377c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell	    inst->TexSrcUnit = unit;
14387e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul	    inst->TexSrcTarget = idx;
14392861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
14402a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul         else if (instMatch.inputs == INPUT_1V_S) {
14412a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul            if (!Parse_PrintInstruction(parseState, inst))
14422a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul               RETURN_ERROR;
14432a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul         }
14442861e737e84e4884109b9526ac645194ba892a74Michal Krol
14452861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* end of statement semicolon */
14462861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_String(parseState, ";"))
14472861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Expected ;");
14482861e737e84e4884109b9526ac645194ba892a74Michal Krol
14492861e737e84e4884109b9526ac645194ba892a74Michal Krol         parseState->numInst++;
14502861e737e84e4884109b9526ac645194ba892a74Michal Krol
14512861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (parseState->numInst >= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS)
14522861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Program too long");
14532861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
14542861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
14552861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
14562861e737e84e4884109b9526ac645194ba892a74Michal Krol}
14572861e737e84e4884109b9526ac645194ba892a74Michal Krol
14582861e737e84e4884109b9526ac645194ba892a74Michal Krol
14592861e737e84e4884109b9526ac645194ba892a74Michal Krol
14602861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
14612861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse/compile the 'str' returning the compiled 'program'.
14622861e737e84e4884109b9526ac645194ba892a74Michal Krol * ctx->Program.ErrorPos will be -1 if successful.  Otherwise, ErrorPos
14632861e737e84e4884109b9526ac645194ba892a74Michal Krol * indicates the position of the error in 'str'.
14642861e737e84e4884109b9526ac645194ba892a74Michal Krol */
14652861e737e84e4884109b9526ac645194ba892a74Michal Krolvoid
14662861e737e84e4884109b9526ac645194ba892a74Michal Krol_mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,
14672861e737e84e4884109b9526ac645194ba892a74Michal Krol                                const GLubyte *str, GLsizei len,
1468122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul                                struct gl_fragment_program *program)
14692861e737e84e4884109b9526ac645194ba892a74Michal Krol{
14702861e737e84e4884109b9526ac645194ba892a74Michal Krol   struct parse_state parseState;
14717e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   struct prog_instruction instBuffer[MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS];
14727e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   struct prog_instruction *newInst;
14732861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLenum target;
14742861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte *programString;
14752861e737e84e4884109b9526ac645194ba892a74Michal Krol
14762861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Make a null-terminated copy of the program string */
14772861e737e84e4884109b9526ac645194ba892a74Michal Krol   programString = (GLubyte *) MALLOC(len + 1);
14782861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!programString) {
14792861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
14802861e737e84e4884109b9526ac645194ba892a74Michal Krol      return;
14812861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
1482e197de56cdb86835f1437688a9161cd909792d80Brian Paul   memcpy(programString, str, len);
14832861e737e84e4884109b9526ac645194ba892a74Michal Krol   programString[len] = 0;
14842861e737e84e4884109b9526ac645194ba892a74Michal Krol
14852861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Get ready to parse */
14862861e737e84e4884109b9526ac645194ba892a74Michal Krol   _mesa_bzero(&parseState, sizeof(struct parse_state));
14872861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.ctx = ctx;
14882861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.start = programString;
14892861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.program = program;
14902861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.numInst = 0;
14912861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.curLine = programString;
14922861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.parameters = _mesa_new_parameter_list();
14932861e737e84e4884109b9526ac645194ba892a74Michal Krol
14942861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Reset error state */
14952861e737e84e4884109b9526ac645194ba892a74Michal Krol   _mesa_set_program_error(ctx, -1, NULL);
14962861e737e84e4884109b9526ac645194ba892a74Michal Krol
14972861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* check the program header */
14989d9afe9393fde99858ddf40e478bc16cf44e60dcKenneth Graunke   if (strncmp((const char *) programString, "!!FP1.0", 7) == 0) {
14992861e737e84e4884109b9526ac645194ba892a74Michal Krol      target = GL_FRAGMENT_PROGRAM_NV;
15002861e737e84e4884109b9526ac645194ba892a74Michal Krol      parseState.pos = programString + 7;
15012861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15029d9afe9393fde99858ddf40e478bc16cf44e60dcKenneth Graunke   else if (strncmp((const char *) programString, "!!FCP1.0", 8) == 0) {
15032861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* fragment / register combiner program - not supported */
15042861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_set_program_error(ctx, 0, "Invalid fragment program header");
15052861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
15062861e737e84e4884109b9526ac645194ba892a74Michal Krol      return;
15072861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15082861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
15092861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* invalid header */
15102861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_set_program_error(ctx, 0, "Invalid fragment program header");
15112861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
15122861e737e84e4884109b9526ac645194ba892a74Michal Krol      return;
15132861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15142861e737e84e4884109b9526ac645194ba892a74Michal Krol
15152861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* make sure target and header match */
15162861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (target != dstTarget) {
15172861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_error(ctx, GL_INVALID_OPERATION,
15182861e737e84e4884109b9526ac645194ba892a74Michal Krol                  "glLoadProgramNV(target mismatch 0x%x != 0x%x)",
15192861e737e84e4884109b9526ac645194ba892a74Michal Krol                  target, dstTarget);
15202861e737e84e4884109b9526ac645194ba892a74Michal Krol      return;
15212861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15222861e737e84e4884109b9526ac645194ba892a74Michal Krol
15232861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_InstructionSequence(&parseState, instBuffer)) {
15242861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLuint u;
15252861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* successful parse! */
15262861e737e84e4884109b9526ac645194ba892a74Michal Krol
15272861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (parseState.outputsWritten == 0) {
15282861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* must write at least one output! */
15292861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_error(ctx, GL_INVALID_OPERATION,
15302861e737e84e4884109b9526ac645194ba892a74Michal Krol                     "Invalid fragment program - no outputs written.");
15312861e737e84e4884109b9526ac645194ba892a74Michal Krol         return;
15322861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
15332861e737e84e4884109b9526ac645194ba892a74Michal Krol
15342861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* copy the compiled instructions */
15352861e737e84e4884109b9526ac645194ba892a74Michal Krol      assert(parseState.numInst <= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS);
1536383c39e58e0ab888afac473526109b62ec0f8f6fBrian Paul      newInst = _mesa_alloc_instructions(parseState.numInst);
15372861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!newInst) {
15382861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
15392861e737e84e4884109b9526ac645194ba892a74Michal Krol         return;  /* out of memory */
15402861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
154112229f119d754715e0315846fdd8d6e9213e8edfBrian      _mesa_copy_instructions(newInst, instBuffer, parseState.numInst);
15422861e737e84e4884109b9526ac645194ba892a74Michal Krol
15432861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* install the program */
15442861e737e84e4884109b9526ac645194ba892a74Michal Krol      program->Base.Target = target;
15452861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (program->Base.String) {
15462861e737e84e4884109b9526ac645194ba892a74Michal Krol         FREE(program->Base.String);
15472861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
15482861e737e84e4884109b9526ac645194ba892a74Michal Krol      program->Base.String = programString;
15492861e737e84e4884109b9526ac645194ba892a74Michal Krol      program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB;
1550de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul      if (program->Base.Instructions) {
1551de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul         _mesa_free(program->Base.Instructions);
15522861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
1553de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul      program->Base.Instructions = newInst;
1554ee40c4fb34bd06ecc6dd6f2e658ca2c2c20af952Brian Paul      program->Base.NumInstructions = parseState.numInst;
1555de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul      program->Base.InputsRead = parseState.inputsRead;
1556de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul      program->Base.OutputsWritten = parseState.outputsWritten;
15572861e737e84e4884109b9526ac645194ba892a74Michal Krol      for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++)
1558c9db223f902ce9d7e9f3038e6baac6da7f231b34Brian         program->Base.TexturesUsed[u] = parseState.texturesUsed[u];
15592861e737e84e4884109b9526ac645194ba892a74Michal Krol
15602861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* save program parameters */
1561de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul      program->Base.Parameters = parseState.parameters;
15622861e737e84e4884109b9526ac645194ba892a74Michal Krol
15632861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* allocate registers for declared program parameters */
15642861e737e84e4884109b9526ac645194ba892a74Michal Krol#if 00
15652861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_assign_program_registers(&(program->SymbolTable));
15662861e737e84e4884109b9526ac645194ba892a74Michal Krol#endif
15672861e737e84e4884109b9526ac645194ba892a74Michal Krol
1568ac33dd1312530e0bab0c7e5d25c9d70f4e884753Brian Paul#ifdef DEBUG_foo
15692861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("--- glLoadProgramNV(%d) result ---\n", program->Base.Id);
1570fe278f1e600058af18c6ba5fe77bfc5a772bf9f5Brian Paul      _mesa_fprint_program_opt(stdout, &program->Base, PROG_PRINT_NV, 0);
15712861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("----------------------------------\n");
15722861e737e84e4884109b9526ac645194ba892a74Michal Krol#endif
15732861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15742861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
15752861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* Error! */
15762861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV");
15772861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* NOTE: _mesa_set_program_error would have been called already */
15782861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15792861e737e84e4884109b9526ac645194ba892a74Michal Krol}
15802861e737e84e4884109b9526ac645194ba892a74Michal Krol
15812861e737e84e4884109b9526ac645194ba892a74Michal Krol
15822861e737e84e4884109b9526ac645194ba892a74Michal Krolconst char *
15832861e737e84e4884109b9526ac645194ba892a74Michal Krol_mesa_nv_fragment_input_register_name(GLuint i)
15842861e737e84e4884109b9526ac645194ba892a74Michal Krol{
15852861e737e84e4884109b9526ac645194ba892a74Michal Krol   ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_INPUTS);
15862861e737e84e4884109b9526ac645194ba892a74Michal Krol   return InputRegisters[i];
15872861e737e84e4884109b9526ac645194ba892a74Michal Krol}
15882861e737e84e4884109b9526ac645194ba892a74Michal Krol
1589