nvfragparse.c revision c9db223f902ce9d7e9f3038e6baac6da7f231b34
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
402861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "glheader.h"
412861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "context.h"
422861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "imports.h"
432861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "macros.h"
44c0551f0a465b577a17698ede46370a17e29b3df7Brian#include "prog_parameter.h"
45c0551f0a465b577a17698ede46370a17e29b3df7Brian#include "prog_instruction.h"
462861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "nvfragparse.h"
472861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "program.h"
482861e737e84e4884109b9526ac645194ba892a74Michal Krol
492861e737e84e4884109b9526ac645194ba892a74Michal Krol
502861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_1V     1
512861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_2V     2
522861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_3V     3
532861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_1S     4
542861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_2S     5
552861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_CC     6
562861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_1V_T   7  /* one source vector, plus textureId */
572861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_3V_T   8  /* one source vector, plus textureId */
582861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_NONE   9
592a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul#define INPUT_1V_S  10  /* a string and a vector register */
602861e737e84e4884109b9526ac645194ba892a74Michal Krol#define OUTPUT_V    20
612861e737e84e4884109b9526ac645194ba892a74Michal Krol#define OUTPUT_S    21
622861e737e84e4884109b9526ac645194ba892a74Michal Krol#define OUTPUT_NONE 22
632861e737e84e4884109b9526ac645194ba892a74Michal Krol
642861e737e84e4884109b9526ac645194ba892a74Michal Krol/* IRIX defines some of these */
652861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _R
662861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _H
672861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _X
682861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _C
692861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _S
702861e737e84e4884109b9526ac645194ba892a74Michal Krol
712861e737e84e4884109b9526ac645194ba892a74Michal Krol/* Optional suffixes */
722861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _R  FLOAT32  /* float */
732861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _H  FLOAT16  /* half-float */
742861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _X  FIXED12  /* fixed */
752861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _C  0x08     /* set cond codes */
762861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _S  0x10     /* saturate, clamp result to [0,1] */
772861e737e84e4884109b9526ac645194ba892a74Michal Krol
782861e737e84e4884109b9526ac645194ba892a74Michal Krolstruct instruction_pattern {
792861e737e84e4884109b9526ac645194ba892a74Michal Krol   const char *name;
807e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   enum prog_opcode opcode;
812861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLuint inputs;
822861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLuint outputs;
832861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLuint suffixes;
842861e737e84e4884109b9526ac645194ba892a74Michal Krol};
852861e737e84e4884109b9526ac645194ba892a74Michal Krol
862861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic const struct instruction_pattern Instructions[] = {
877e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "ADD", OPCODE_ADD, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
887e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "COS", OPCODE_COS, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
897e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "DDX", OPCODE_DDX, INPUT_1V, OUTPUT_V, _R | _H |      _C | _S },
907e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "DDY", OPCODE_DDY, INPUT_1V, OUTPUT_V, _R | _H |      _C | _S },
917e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "DP3", OPCODE_DP3, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S },
927e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "DP4", OPCODE_DP4, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S },
937e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "DST", OPCODE_DP4, INPUT_2V, OUTPUT_V, _R | _H |      _C | _S },
947e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "EX2", OPCODE_DP4, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
957e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "FLR", OPCODE_FLR, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
967e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "FRC", OPCODE_FRC, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
977e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "KIL", OPCODE_KIL_NV, INPUT_CC, OUTPUT_NONE, 0                },
987e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "LG2", OPCODE_LG2, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
997e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "LIT", OPCODE_LIT, INPUT_1V, OUTPUT_V, _R | _H |      _C | _S },
1007e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "LRP", OPCODE_LRP, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S },
1017e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "MAD", OPCODE_MAD, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S },
1027e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "MAX", OPCODE_MAX, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1037e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "MIN", OPCODE_MIN, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1047e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "MOV", OPCODE_MOV, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
1057e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "MUL", OPCODE_MUL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1067e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "PK2H",  OPCODE_PK2H,  INPUT_1V, OUTPUT_S, 0                  },
1077e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "PK2US", OPCODE_PK2US, INPUT_1V, OUTPUT_S, 0                  },
1087e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "PK4B",  OPCODE_PK4B,  INPUT_1V, OUTPUT_S, 0                  },
1097e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "PK4UB", OPCODE_PK4UB, INPUT_1V, OUTPUT_S, 0                  },
1107e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "POW", OPCODE_POW, INPUT_2S, OUTPUT_S, _R | _H |      _C | _S },
1117e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "RCP", OPCODE_RCP, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
1127e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "RFL", OPCODE_RFL, INPUT_2V, OUTPUT_V, _R | _H |      _C | _S },
1137e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "RSQ", OPCODE_RSQ, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
1147e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "SEQ", OPCODE_SEQ, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1157e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "SFL", OPCODE_SFL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1167e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "SGE", OPCODE_SGE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1177e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "SGT", OPCODE_SGT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1187e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "SIN", OPCODE_SIN, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
1197e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "SLE", OPCODE_SLE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1207e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "SLT", OPCODE_SLT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1217e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "SNE", OPCODE_SNE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1227e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "STR", OPCODE_STR, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1237e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "SUB", OPCODE_SUB, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1247e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "TEX", OPCODE_TEX, INPUT_1V_T, OUTPUT_V,              _C | _S },
1257e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "TXD", OPCODE_TXD, INPUT_3V_T, OUTPUT_V,              _C | _S },
1267e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "TXP", OPCODE_TXP_NV, INPUT_1V_T, OUTPUT_V,           _C | _S },
1277e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "UP2H",  OPCODE_UP2H,  INPUT_1S, OUTPUT_V,            _C | _S },
1287e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "UP2US", OPCODE_UP2US, INPUT_1S, OUTPUT_V,            _C | _S },
1297e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "UP4B",  OPCODE_UP4B,  INPUT_1S, OUTPUT_V,            _C | _S },
1307e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "UP4UB", OPCODE_UP4UB, INPUT_1S, OUTPUT_V,            _C | _S },
1317e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "X2D", OPCODE_X2D, INPUT_3V, OUTPUT_V, _R | _H |      _C | _S },
1327e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { "PRINT", OPCODE_PRINT, INPUT_1V_S, OUTPUT_NONE, 0               },
1337e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   { NULL, (enum prog_opcode) -1, 0, 0, 0 }
1342861e737e84e4884109b9526ac645194ba892a74Michal Krol};
1352861e737e84e4884109b9526ac645194ba892a74Michal Krol
1362861e737e84e4884109b9526ac645194ba892a74Michal Krol
1372861e737e84e4884109b9526ac645194ba892a74Michal Krol/*
1382861e737e84e4884109b9526ac645194ba892a74Michal Krol * Information needed or computed during parsing.
1392861e737e84e4884109b9526ac645194ba892a74Michal Krol * Remember, we can't modify the target program object until we've
1402861e737e84e4884109b9526ac645194ba892a74Michal Krol * _successfully_ parsed the program text.
1412861e737e84e4884109b9526ac645194ba892a74Michal Krol */
1422861e737e84e4884109b9526ac645194ba892a74Michal Krolstruct parse_state {
1432861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLcontext *ctx;
1442861e737e84e4884109b9526ac645194ba892a74Michal Krol   const GLubyte *start;              /* start of program string */
1452861e737e84e4884109b9526ac645194ba892a74Michal Krol   const GLubyte *pos;                /* current position */
1462861e737e84e4884109b9526ac645194ba892a74Michal Krol   const GLubyte *curLine;
147122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul   struct gl_fragment_program *program;  /* current program */
1482861e737e84e4884109b9526ac645194ba892a74Michal Krol
149122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul   struct gl_program_parameter_list *parameters;
1502861e737e84e4884109b9526ac645194ba892a74Michal Krol
1512861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLuint numInst;                    /* number of instructions parsed */
1522861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLuint inputsRead;                 /* bitmask of input registers used */
1532861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLuint outputsWritten;             /* bitmask of 1 << FRAG_OUTPUT_* bits */
1542861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLuint texturesUsed[MAX_TEXTURE_IMAGE_UNITS];
1552861e737e84e4884109b9526ac645194ba892a74Michal Krol};
1562861e737e84e4884109b9526ac645194ba892a74Michal Krol
1572861e737e84e4884109b9526ac645194ba892a74Michal Krol
1582861e737e84e4884109b9526ac645194ba892a74Michal Krol
1592861e737e84e4884109b9526ac645194ba892a74Michal Krol/*
1602861e737e84e4884109b9526ac645194ba892a74Michal Krol * Called whenever we find an error during parsing.
1612861e737e84e4884109b9526ac645194ba892a74Michal Krol */
1622861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void
1632861e737e84e4884109b9526ac645194ba892a74Michal Krolrecord_error(struct parse_state *parseState, const char *msg, int lineNo)
1642861e737e84e4884109b9526ac645194ba892a74Michal Krol{
1652861e737e84e4884109b9526ac645194ba892a74Michal Krol#ifdef DEBUG
1662861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLint line, column;
1672861e737e84e4884109b9526ac645194ba892a74Michal Krol   const GLubyte *lineStr;
1682861e737e84e4884109b9526ac645194ba892a74Michal Krol   lineStr = _mesa_find_line_column(parseState->start,
1692861e737e84e4884109b9526ac645194ba892a74Michal Krol                                    parseState->pos, &line, &column);
1702861e737e84e4884109b9526ac645194ba892a74Michal Krol   _mesa_debug(parseState->ctx,
1712861e737e84e4884109b9526ac645194ba892a74Michal Krol               "nvfragparse.c(%d): line %d, column %d:%s (%s)\n",
1722861e737e84e4884109b9526ac645194ba892a74Michal Krol               lineNo, line, column, (char *) lineStr, msg);
1732861e737e84e4884109b9526ac645194ba892a74Michal Krol   _mesa_free((void *) lineStr);
1742861e737e84e4884109b9526ac645194ba892a74Michal Krol#else
1752861e737e84e4884109b9526ac645194ba892a74Michal Krol   (void) lineNo;
1762861e737e84e4884109b9526ac645194ba892a74Michal Krol#endif
1772861e737e84e4884109b9526ac645194ba892a74Michal Krol
1782861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Check that no error was already recorded.  Only record the first one. */
1792861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (parseState->ctx->Program.ErrorString[0] == 0) {
1802861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_set_program_error(parseState->ctx,
1812861e737e84e4884109b9526ac645194ba892a74Michal Krol                              parseState->pos - parseState->start,
1822861e737e84e4884109b9526ac645194ba892a74Michal Krol                              msg);
1832861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
1842861e737e84e4884109b9526ac645194ba892a74Michal Krol}
1852861e737e84e4884109b9526ac645194ba892a74Michal Krol
1862861e737e84e4884109b9526ac645194ba892a74Michal Krol
1872861e737e84e4884109b9526ac645194ba892a74Michal Krol#define RETURN_ERROR							\
1882861e737e84e4884109b9526ac645194ba892a74Michal Kroldo {									\
1892861e737e84e4884109b9526ac645194ba892a74Michal Krol   record_error(parseState, "Unexpected end of input.", __LINE__);	\
1902861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_FALSE;							\
1912861e737e84e4884109b9526ac645194ba892a74Michal Krol} while(0)
1922861e737e84e4884109b9526ac645194ba892a74Michal Krol
1932861e737e84e4884109b9526ac645194ba892a74Michal Krol#define RETURN_ERROR1(msg)						\
1942861e737e84e4884109b9526ac645194ba892a74Michal Kroldo {									\
1952861e737e84e4884109b9526ac645194ba892a74Michal Krol   record_error(parseState, msg, __LINE__);				\
1962861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_FALSE;							\
1972861e737e84e4884109b9526ac645194ba892a74Michal Krol} while(0)
1982861e737e84e4884109b9526ac645194ba892a74Michal Krol
1992861e737e84e4884109b9526ac645194ba892a74Michal Krol#define RETURN_ERROR2(msg1, msg2)					\
2002861e737e84e4884109b9526ac645194ba892a74Michal Kroldo {									\
2012861e737e84e4884109b9526ac645194ba892a74Michal Krol   char err[1000];							\
2022861e737e84e4884109b9526ac645194ba892a74Michal Krol   _mesa_sprintf(err, "%s %s", msg1, msg2);				\
2032861e737e84e4884109b9526ac645194ba892a74Michal Krol   record_error(parseState, err, __LINE__);				\
2042861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_FALSE;							\
2052861e737e84e4884109b9526ac645194ba892a74Michal Krol} while(0)
2062861e737e84e4884109b9526ac645194ba892a74Michal Krol
2072861e737e84e4884109b9526ac645194ba892a74Michal Krol
2082861e737e84e4884109b9526ac645194ba892a74Michal Krol
2092861e737e84e4884109b9526ac645194ba892a74Michal Krol
2102861e737e84e4884109b9526ac645194ba892a74Michal Krol/*
2112861e737e84e4884109b9526ac645194ba892a74Michal Krol * Search a list of instruction structures for a match.
2122861e737e84e4884109b9526ac645194ba892a74Michal Krol */
2132861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic struct instruction_pattern
2142861e737e84e4884109b9526ac645194ba892a74Michal KrolMatchInstruction(const GLubyte *token)
2152861e737e84e4884109b9526ac645194ba892a74Michal Krol{
2162861e737e84e4884109b9526ac645194ba892a74Michal Krol   const struct instruction_pattern *inst;
2172861e737e84e4884109b9526ac645194ba892a74Michal Krol   struct instruction_pattern result;
2182861e737e84e4884109b9526ac645194ba892a74Michal Krol
2192861e737e84e4884109b9526ac645194ba892a74Michal Krol   for (inst = Instructions; inst->name; inst++) {
2202861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (_mesa_strncmp((const char *) token, inst->name, 3) == 0) {
2212861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* matched! */
2222861e737e84e4884109b9526ac645194ba892a74Michal Krol         int i = 3;
2232861e737e84e4884109b9526ac645194ba892a74Michal Krol         result = *inst;
2242861e737e84e4884109b9526ac645194ba892a74Michal Krol         result.suffixes = 0;
2252861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* look at suffix */
2262861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (token[i] == 'R') {
2272861e737e84e4884109b9526ac645194ba892a74Michal Krol            result.suffixes |= _R;
2282861e737e84e4884109b9526ac645194ba892a74Michal Krol            i++;
2292861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
2302861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (token[i] == 'H') {
2312861e737e84e4884109b9526ac645194ba892a74Michal Krol            result.suffixes |= _H;
2322861e737e84e4884109b9526ac645194ba892a74Michal Krol            i++;
2332861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
2342861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (token[i] == 'X') {
2352861e737e84e4884109b9526ac645194ba892a74Michal Krol            result.suffixes |= _X;
2362861e737e84e4884109b9526ac645194ba892a74Michal Krol            i++;
2372861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
2382861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (token[i] == 'C') {
2392861e737e84e4884109b9526ac645194ba892a74Michal Krol            result.suffixes |= _C;
2402861e737e84e4884109b9526ac645194ba892a74Michal Krol            i++;
2412861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
2422861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (token[i] == '_' && token[i+1] == 'S' &&
2432861e737e84e4884109b9526ac645194ba892a74Michal Krol             token[i+2] == 'A' && token[i+3] == 'T') {
2442861e737e84e4884109b9526ac645194ba892a74Michal Krol            result.suffixes |= _S;
2452861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
2462861e737e84e4884109b9526ac645194ba892a74Michal Krol         return result;
2472861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
2482861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
24928b014ee256290eb0494b967e40c475c0c895f57Brian Paul   result.opcode = MAX_OPCODE; /* i.e. invalid instruction */
2502861e737e84e4884109b9526ac645194ba892a74Michal Krol   return result;
2512861e737e84e4884109b9526ac645194ba892a74Michal Krol}
2522861e737e84e4884109b9526ac645194ba892a74Michal Krol
2532861e737e84e4884109b9526ac645194ba892a74Michal Krol
2542861e737e84e4884109b9526ac645194ba892a74Michal Krol
2552861e737e84e4884109b9526ac645194ba892a74Michal Krol
2562861e737e84e4884109b9526ac645194ba892a74Michal Krol/**********************************************************************/
2572861e737e84e4884109b9526ac645194ba892a74Michal Krol
2582861e737e84e4884109b9526ac645194ba892a74Michal Krol
2592861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean IsLetter(GLubyte b)
2602861e737e84e4884109b9526ac645194ba892a74Michal Krol{
2612861e737e84e4884109b9526ac645194ba892a74Michal Krol   return (b >= 'a' && b <= 'z') ||
2622861e737e84e4884109b9526ac645194ba892a74Michal Krol          (b >= 'A' && b <= 'Z') ||
2632861e737e84e4884109b9526ac645194ba892a74Michal Krol          (b == '_') ||
2642861e737e84e4884109b9526ac645194ba892a74Michal Krol          (b == '$');
2652861e737e84e4884109b9526ac645194ba892a74Michal Krol}
2662861e737e84e4884109b9526ac645194ba892a74Michal Krol
2672861e737e84e4884109b9526ac645194ba892a74Michal Krol
2682861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean IsDigit(GLubyte b)
2692861e737e84e4884109b9526ac645194ba892a74Michal Krol{
2702861e737e84e4884109b9526ac645194ba892a74Michal Krol   return b >= '0' && b <= '9';
2712861e737e84e4884109b9526ac645194ba892a74Michal Krol}
2722861e737e84e4884109b9526ac645194ba892a74Michal Krol
2732861e737e84e4884109b9526ac645194ba892a74Michal Krol
2742861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean IsWhitespace(GLubyte b)
2752861e737e84e4884109b9526ac645194ba892a74Michal Krol{
2762861e737e84e4884109b9526ac645194ba892a74Michal Krol   return b == ' ' || b == '\t' || b == '\n' || b == '\r';
2772861e737e84e4884109b9526ac645194ba892a74Michal Krol}
2782861e737e84e4884109b9526ac645194ba892a74Michal Krol
2792861e737e84e4884109b9526ac645194ba892a74Michal Krol
2802861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
2812861e737e84e4884109b9526ac645194ba892a74Michal Krol * Starting at 'str' find the next token.  A token can be an integer,
2822861e737e84e4884109b9526ac645194ba892a74Michal Krol * an identifier or punctuation symbol.
2832861e737e84e4884109b9526ac645194ba892a74Michal Krol * \return <= 0 we found an error, else, return number of characters parsed.
2842861e737e84e4884109b9526ac645194ba892a74Michal Krol */
2852861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLint
2862861e737e84e4884109b9526ac645194ba892a74Michal KrolGetToken(struct parse_state *parseState, GLubyte *token)
2872861e737e84e4884109b9526ac645194ba892a74Michal Krol{
2882861e737e84e4884109b9526ac645194ba892a74Michal Krol   const GLubyte *str = parseState->pos;
2892861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLint i = 0, j = 0;
2902861e737e84e4884109b9526ac645194ba892a74Michal Krol
2912861e737e84e4884109b9526ac645194ba892a74Michal Krol   token[0] = 0;
2922861e737e84e4884109b9526ac645194ba892a74Michal Krol
2932861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* skip whitespace and comments */
2942861e737e84e4884109b9526ac645194ba892a74Michal Krol   while (str[i] && (IsWhitespace(str[i]) || str[i] == '#')) {
2952861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (str[i] == '#') {
2962861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* skip comment */
2972861e737e84e4884109b9526ac645194ba892a74Michal Krol         while (str[i] && (str[i] != '\n' && str[i] != '\r')) {
2982861e737e84e4884109b9526ac645194ba892a74Michal Krol            i++;
2992861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
3002861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (str[i] == '\n' || str[i] == '\r')
3012861e737e84e4884109b9526ac645194ba892a74Michal Krol            parseState->curLine = str + i + 1;
3022861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
3032861e737e84e4884109b9526ac645194ba892a74Michal Krol      else {
3042861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* skip whitespace */
3052861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (str[i] == '\n' || str[i] == '\r')
3062861e737e84e4884109b9526ac645194ba892a74Michal Krol            parseState->curLine = str + i + 1;
3072861e737e84e4884109b9526ac645194ba892a74Michal Krol         i++;
3082861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
3092861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
3102861e737e84e4884109b9526ac645194ba892a74Michal Krol
3112861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (str[i] == 0)
3122861e737e84e4884109b9526ac645194ba892a74Michal Krol      return -i;
3132861e737e84e4884109b9526ac645194ba892a74Michal Krol
3142861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* try matching an integer */
3152861e737e84e4884109b9526ac645194ba892a74Michal Krol   while (str[i] && IsDigit(str[i])) {
3162861e737e84e4884109b9526ac645194ba892a74Michal Krol      token[j++] = str[i++];
3172861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
3182861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (j > 0 || !str[i]) {
3192861e737e84e4884109b9526ac645194ba892a74Michal Krol      token[j] = 0;
3202861e737e84e4884109b9526ac645194ba892a74Michal Krol      return i;
3212861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
3222861e737e84e4884109b9526ac645194ba892a74Michal Krol
3232861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* try matching an identifier */
3242861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (IsLetter(str[i])) {
3252861e737e84e4884109b9526ac645194ba892a74Michal Krol      while (str[i] && (IsLetter(str[i]) || IsDigit(str[i]))) {
3262861e737e84e4884109b9526ac645194ba892a74Michal Krol         token[j++] = str[i++];
3272861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
3282861e737e84e4884109b9526ac645194ba892a74Michal Krol      token[j] = 0;
3292861e737e84e4884109b9526ac645194ba892a74Michal Krol      return i;
3302861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
3312861e737e84e4884109b9526ac645194ba892a74Michal Krol
3322861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* punctuation character */
3332861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (str[i]) {
3342861e737e84e4884109b9526ac645194ba892a74Michal Krol      token[0] = str[i++];
3352861e737e84e4884109b9526ac645194ba892a74Michal Krol      token[1] = 0;
3362861e737e84e4884109b9526ac645194ba892a74Michal Krol      return i;
3372861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
3382861e737e84e4884109b9526ac645194ba892a74Michal Krol
3392861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* end of input */
3402861e737e84e4884109b9526ac645194ba892a74Michal Krol   token[0] = 0;
3412861e737e84e4884109b9526ac645194ba892a74Michal Krol   return i;
3422861e737e84e4884109b9526ac645194ba892a74Michal Krol}
3432861e737e84e4884109b9526ac645194ba892a74Michal Krol
3442861e737e84e4884109b9526ac645194ba892a74Michal Krol
3452861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
3462861e737e84e4884109b9526ac645194ba892a74Michal Krol * Get next token from input stream and increment stream pointer past token.
3472861e737e84e4884109b9526ac645194ba892a74Michal Krol */
3482861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
3492861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_Token(struct parse_state *parseState, GLubyte *token)
3502861e737e84e4884109b9526ac645194ba892a74Michal Krol{
3512861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLint i;
3522861e737e84e4884109b9526ac645194ba892a74Michal Krol   i = GetToken(parseState, token);
3532861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (i <= 0) {
3542861e737e84e4884109b9526ac645194ba892a74Michal Krol      parseState->pos += (-i);
3552861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_FALSE;
3562861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
3572861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState->pos += i;
3582861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
3592861e737e84e4884109b9526ac645194ba892a74Michal Krol}
3602861e737e84e4884109b9526ac645194ba892a74Michal Krol
3612861e737e84e4884109b9526ac645194ba892a74Michal Krol
3622861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
3632861e737e84e4884109b9526ac645194ba892a74Michal Krol * Get next token from input stream but don't increment stream pointer.
3642861e737e84e4884109b9526ac645194ba892a74Michal Krol */
3652861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
3662861e737e84e4884109b9526ac645194ba892a74Michal KrolPeek_Token(struct parse_state *parseState, GLubyte *token)
3672861e737e84e4884109b9526ac645194ba892a74Michal Krol{
3682861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLint i, len;
3692861e737e84e4884109b9526ac645194ba892a74Michal Krol   i = GetToken(parseState, token);
3702861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (i <= 0) {
3712861e737e84e4884109b9526ac645194ba892a74Michal Krol      parseState->pos += (-i);
3722861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_FALSE;
3732861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
3746258b76c49f49a56a7c713914b798e80c6553b06Karl Schultz   len = (GLint)_mesa_strlen((const char *) token);
3752861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState->pos += (i - len);
3762861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
3772861e737e84e4884109b9526ac645194ba892a74Michal Krol}
3782861e737e84e4884109b9526ac645194ba892a74Michal Krol
3792861e737e84e4884109b9526ac645194ba892a74Michal Krol
3802861e737e84e4884109b9526ac645194ba892a74Michal Krol/**********************************************************************/
3812861e737e84e4884109b9526ac645194ba892a74Michal Krol
3822861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic const char *InputRegisters[MAX_NV_FRAGMENT_PROGRAM_INPUTS + 1] = {
3832861e737e84e4884109b9526ac645194ba892a74Michal Krol   "WPOS", "COL0", "COL1", "FOGC",
3842861e737e84e4884109b9526ac645194ba892a74Michal Krol   "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL
3852861e737e84e4884109b9526ac645194ba892a74Michal Krol};
3862861e737e84e4884109b9526ac645194ba892a74Michal Krol
3872861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic const char *OutputRegisters[MAX_NV_FRAGMENT_PROGRAM_OUTPUTS + 1] = {
3882861e737e84e4884109b9526ac645194ba892a74Michal Krol   "COLR", "COLH",
3892861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* These are only allows for register combiners */
3902861e737e84e4884109b9526ac645194ba892a74Michal Krol   /*
3912861e737e84e4884109b9526ac645194ba892a74Michal Krol   "TEX0", "TEX1", "TEX2", "TEX3",
3922861e737e84e4884109b9526ac645194ba892a74Michal Krol   */
3932861e737e84e4884109b9526ac645194ba892a74Michal Krol   "DEPR", NULL
3942861e737e84e4884109b9526ac645194ba892a74Michal Krol};
3952861e737e84e4884109b9526ac645194ba892a74Michal Krol
3962861e737e84e4884109b9526ac645194ba892a74Michal Krol
3972861e737e84e4884109b9526ac645194ba892a74Michal Krol
3982861e737e84e4884109b9526ac645194ba892a74Michal Krol
3992861e737e84e4884109b9526ac645194ba892a74Michal Krol/**********************************************************************/
4002861e737e84e4884109b9526ac645194ba892a74Michal Krol
4012861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
4022861e737e84e4884109b9526ac645194ba892a74Michal Krol * Try to match 'pattern' as the next token after any whitespace/comments.
4032861e737e84e4884109b9526ac645194ba892a74Michal Krol */
4042861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
4052861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_String(struct parse_state *parseState, const char *pattern)
4062861e737e84e4884109b9526ac645194ba892a74Michal Krol{
4072861e737e84e4884109b9526ac645194ba892a74Michal Krol   const GLubyte *m;
4082861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLint i;
4092861e737e84e4884109b9526ac645194ba892a74Michal Krol
4102861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* skip whitespace and comments */
4112861e737e84e4884109b9526ac645194ba892a74Michal Krol   while (IsWhitespace(*parseState->pos) || *parseState->pos == '#') {
4122861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (*parseState->pos == '#') {
4132861e737e84e4884109b9526ac645194ba892a74Michal Krol         while (*parseState->pos && (*parseState->pos != '\n' && *parseState->pos != '\r')) {
4142861e737e84e4884109b9526ac645194ba892a74Michal Krol            parseState->pos += 1;
4152861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
4162861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (*parseState->pos == '\n' || *parseState->pos == '\r')
4172861e737e84e4884109b9526ac645194ba892a74Michal Krol            parseState->curLine = parseState->pos + 1;
4182861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
4192861e737e84e4884109b9526ac645194ba892a74Michal Krol      else {
4202861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* skip whitespace */
4212861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (*parseState->pos == '\n' || *parseState->pos == '\r')
4222861e737e84e4884109b9526ac645194ba892a74Michal Krol            parseState->curLine = parseState->pos + 1;
4232861e737e84e4884109b9526ac645194ba892a74Michal Krol         parseState->pos += 1;
4242861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
4252861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
4262861e737e84e4884109b9526ac645194ba892a74Michal Krol
4272861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Try to match the pattern */
4282861e737e84e4884109b9526ac645194ba892a74Michal Krol   m = parseState->pos;
4292861e737e84e4884109b9526ac645194ba892a74Michal Krol   for (i = 0; pattern[i]; i++) {
4302861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (*m != (GLubyte) pattern[i])
4312861e737e84e4884109b9526ac645194ba892a74Michal Krol         return GL_FALSE;
4322861e737e84e4884109b9526ac645194ba892a74Michal Krol      m += 1;
4332861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
4342861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState->pos = m;
4352861e737e84e4884109b9526ac645194ba892a74Michal Krol
4362861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE; /* success */
4372861e737e84e4884109b9526ac645194ba892a74Michal Krol}
4382861e737e84e4884109b9526ac645194ba892a74Michal Krol
4392861e737e84e4884109b9526ac645194ba892a74Michal Krol
4402861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
4412861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_Identifier(struct parse_state *parseState, GLubyte *ident)
4422861e737e84e4884109b9526ac645194ba892a74Michal Krol{
4432861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_Token(parseState, ident))
4442861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
4452861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (IsLetter(ident[0]))
4462861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_TRUE;
4472861e737e84e4884109b9526ac645194ba892a74Michal Krol   else
4482861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected an identfier");
4492861e737e84e4884109b9526ac645194ba892a74Michal Krol}
4502861e737e84e4884109b9526ac645194ba892a74Michal Krol
4512861e737e84e4884109b9526ac645194ba892a74Michal Krol
4522861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
4532861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a floating point constant, or a defined symbol name.
4542861e737e84e4884109b9526ac645194ba892a74Michal Krol * [+/-]N[.N[eN]]
4552861e737e84e4884109b9526ac645194ba892a74Michal Krol * Output:  number[0 .. 3] will get the value.
4562861e737e84e4884109b9526ac645194ba892a74Michal Krol */
4572861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
4582861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_ScalarConstant(struct parse_state *parseState, GLfloat *number)
4592861e737e84e4884109b9526ac645194ba892a74Michal Krol{
4602861e737e84e4884109b9526ac645194ba892a74Michal Krol   char *end = NULL;
4612861e737e84e4884109b9526ac645194ba892a74Michal Krol
4622861e737e84e4884109b9526ac645194ba892a74Michal Krol   *number = (GLfloat) _mesa_strtod((const char *) parseState->pos, &end);
4632861e737e84e4884109b9526ac645194ba892a74Michal Krol
4642861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (end && end > (char *) parseState->pos) {
4652861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* got a number */
4662861e737e84e4884109b9526ac645194ba892a74Michal Krol      parseState->pos = (GLubyte *) end;
4672861e737e84e4884109b9526ac645194ba892a74Michal Krol      number[1] = *number;
4682861e737e84e4884109b9526ac645194ba892a74Michal Krol      number[2] = *number;
4692861e737e84e4884109b9526ac645194ba892a74Michal Krol      number[3] = *number;
4702861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_TRUE;
4712861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
4722861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
4732861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* should be an identifier */
4742861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLubyte ident[100];
4752861e737e84e4884109b9526ac645194ba892a74Michal Krol      const GLfloat *constant;
4762861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_Identifier(parseState, ident))
4772861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Expected an identifier");
4782861e737e84e4884109b9526ac645194ba892a74Michal Krol      constant = _mesa_lookup_parameter_value(parseState->parameters,
4792861e737e84e4884109b9526ac645194ba892a74Michal Krol                                              -1, (const char *) ident);
4802861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* XXX Check that it's a constant and not a parameter */
4812861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!constant) {
4822861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Undefined symbol");
4832861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
4842861e737e84e4884109b9526ac645194ba892a74Michal Krol      else {
4852861e737e84e4884109b9526ac645194ba892a74Michal Krol         COPY_4V(number, constant);
4862861e737e84e4884109b9526ac645194ba892a74Michal Krol         return GL_TRUE;
4872861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
4882861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
4892861e737e84e4884109b9526ac645194ba892a74Michal Krol}
4902861e737e84e4884109b9526ac645194ba892a74Michal Krol
4912861e737e84e4884109b9526ac645194ba892a74Michal Krol
4922861e737e84e4884109b9526ac645194ba892a74Michal Krol
4932861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
4942861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a vector constant, one of:
4952861e737e84e4884109b9526ac645194ba892a74Michal Krol *   { float }
4962861e737e84e4884109b9526ac645194ba892a74Michal Krol *   { float, float }
4972861e737e84e4884109b9526ac645194ba892a74Michal Krol *   { float, float, float }
4982861e737e84e4884109b9526ac645194ba892a74Michal Krol *   { float, float, float, float }
4992861e737e84e4884109b9526ac645194ba892a74Michal Krol */
5002861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
5012861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_VectorConstant(struct parse_state *parseState, GLfloat *vec)
5022861e737e84e4884109b9526ac645194ba892a74Michal Krol{
5032861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* "{" was already consumed */
5042861e737e84e4884109b9526ac645194ba892a74Michal Krol
5052861e737e84e4884109b9526ac645194ba892a74Michal Krol   ASSIGN_4V(vec, 0.0, 0.0, 0.0, 1.0);
5062861e737e84e4884109b9526ac645194ba892a74Michal Krol
5072861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_ScalarConstant(parseState, vec+0))  /* X */
5082861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_FALSE;
5092861e737e84e4884109b9526ac645194ba892a74Michal Krol
5102861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "}")) {
5112861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_TRUE;
5122861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5132861e737e84e4884109b9526ac645194ba892a74Michal Krol
5142861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, ","))
5152861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected comma in vector constant");
5162861e737e84e4884109b9526ac645194ba892a74Michal Krol
5172861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_ScalarConstant(parseState, vec+1))  /* Y */
5182861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_FALSE;
5192861e737e84e4884109b9526ac645194ba892a74Michal Krol
5202861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "}")) {
5212861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_TRUE;
5222861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5232861e737e84e4884109b9526ac645194ba892a74Michal Krol
5242861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, ","))
5252861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected comma in vector constant");
5262861e737e84e4884109b9526ac645194ba892a74Michal Krol
5272861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_ScalarConstant(parseState, vec+2))  /* Z */
5282861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_FALSE;
5292861e737e84e4884109b9526ac645194ba892a74Michal Krol
5302861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "}")) {
5312861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_TRUE;
5322861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5332861e737e84e4884109b9526ac645194ba892a74Michal Krol
5342861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, ","))
5352861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected comma in vector constant");
5362861e737e84e4884109b9526ac645194ba892a74Michal Krol
5372861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_ScalarConstant(parseState, vec+3))  /* W */
5382861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_FALSE;
5392861e737e84e4884109b9526ac645194ba892a74Michal Krol
5402861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "}"))
5412861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected closing brace in vector constant");
5422861e737e84e4884109b9526ac645194ba892a74Michal Krol
5432861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
5442861e737e84e4884109b9526ac645194ba892a74Michal Krol}
5452861e737e84e4884109b9526ac645194ba892a74Michal Krol
5462861e737e84e4884109b9526ac645194ba892a74Michal Krol
5472861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
5482861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse <number>, <varname> or {a, b, c, d}.
5492861e737e84e4884109b9526ac645194ba892a74Michal Krol * Return number of values in the vector or scalar, or zero if parse error.
5502861e737e84e4884109b9526ac645194ba892a74Michal Krol */
5512861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLuint
5522861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_VectorOrScalarConstant(struct parse_state *parseState, GLfloat *vec)
5532861e737e84e4884109b9526ac645194ba892a74Michal Krol{
5542861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "{")) {
5552861e737e84e4884109b9526ac645194ba892a74Michal Krol      return Parse_VectorConstant(parseState, vec);
5562861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5572861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
5582861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLboolean b = Parse_ScalarConstant(parseState, vec);
5592861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (b) {
5602861e737e84e4884109b9526ac645194ba892a74Michal Krol         vec[1] = vec[2] = vec[3] = vec[0];
5612861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
5622861e737e84e4884109b9526ac645194ba892a74Michal Krol      return b;
5632861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5642861e737e84e4884109b9526ac645194ba892a74Michal Krol}
5652861e737e84e4884109b9526ac645194ba892a74Michal Krol
5662861e737e84e4884109b9526ac645194ba892a74Michal Krol
5672861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
5682861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a texture image source:
5692861e737e84e4884109b9526ac645194ba892a74Michal Krol *    [TEX0 | TEX1 | .. | TEX15] , [1D | 2D | 3D | CUBE | RECT]
5702861e737e84e4884109b9526ac645194ba892a74Michal Krol */
5712861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
5722861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_TextureImageId(struct parse_state *parseState,
5732861e737e84e4884109b9526ac645194ba892a74Michal Krol                     GLubyte *texUnit, GLubyte *texTargetBit)
5742861e737e84e4884109b9526ac645194ba892a74Michal Krol{
5752861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte imageSrc[100];
5762861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLint unit;
5772861e737e84e4884109b9526ac645194ba892a74Michal Krol
5782861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_Token(parseState, imageSrc))
5792861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
5802861e737e84e4884109b9526ac645194ba892a74Michal Krol
5812861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (imageSrc[0] != 'T' ||
5822861e737e84e4884109b9526ac645194ba892a74Michal Krol       imageSrc[1] != 'E' ||
5832861e737e84e4884109b9526ac645194ba892a74Michal Krol       imageSrc[2] != 'X') {
5842861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected TEX# source");
5852861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5862861e737e84e4884109b9526ac645194ba892a74Michal Krol   unit = _mesa_atoi((const char *) imageSrc + 3);
5872861e737e84e4884109b9526ac645194ba892a74Michal Krol   if ((unit < 0 || unit > MAX_TEXTURE_IMAGE_UNITS) ||
5882861e737e84e4884109b9526ac645194ba892a74Michal Krol       (unit == 0 && (imageSrc[3] != '0' || imageSrc[4] != 0))) {
5892861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalied TEX# source index");
5902861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5912861e737e84e4884109b9526ac645194ba892a74Michal Krol   *texUnit = unit;
5922861e737e84e4884109b9526ac645194ba892a74Michal Krol
5932861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, ","))
5942861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected ,");
5952861e737e84e4884109b9526ac645194ba892a74Michal Krol
5962861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "1D")) {
5972861e737e84e4884109b9526ac645194ba892a74Michal Krol      *texTargetBit = TEXTURE_1D_BIT;
5982861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5992861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "2D")) {
6002861e737e84e4884109b9526ac645194ba892a74Michal Krol      *texTargetBit = TEXTURE_2D_BIT;
6012861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6022861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "3D")) {
6032861e737e84e4884109b9526ac645194ba892a74Michal Krol      *texTargetBit = TEXTURE_3D_BIT;
6042861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6052861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "CUBE")) {
6062861e737e84e4884109b9526ac645194ba892a74Michal Krol      *texTargetBit = TEXTURE_CUBE_BIT;
6072861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6082861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "RECT")) {
6092861e737e84e4884109b9526ac645194ba892a74Michal Krol      *texTargetBit = TEXTURE_RECT_BIT;
6102861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6112861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
6122861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalid texture target token");
6132861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6142861e737e84e4884109b9526ac645194ba892a74Michal Krol
6152861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* update record of referenced texture units */
6162861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState->texturesUsed[*texUnit] |= *texTargetBit;
6172861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (_mesa_bitcount(parseState->texturesUsed[*texUnit]) > 1) {
6182861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Only one texture target can be used per texture unit.");
6192861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6202861e737e84e4884109b9526ac645194ba892a74Michal Krol
6212861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
6222861e737e84e4884109b9526ac645194ba892a74Michal Krol}
6232861e737e84e4884109b9526ac645194ba892a74Michal Krol
6242861e737e84e4884109b9526ac645194ba892a74Michal Krol
6252861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
6262861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a scalar suffix like .x, .y, .z or .w or parse a swizzle suffix
6272861e737e84e4884109b9526ac645194ba892a74Michal Krol * like .wxyz, .xxyy, etc and return the swizzle indexes.
6282861e737e84e4884109b9526ac645194ba892a74Michal Krol */
6292861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
6302861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_SwizzleSuffix(const GLubyte *token, GLuint swizzle[4])
6312861e737e84e4884109b9526ac645194ba892a74Michal Krol{
6322861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (token[1] == 0) {
6332861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* single letter swizzle (scalar) */
6342861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[0] == 'x')
6352861e737e84e4884109b9526ac645194ba892a74Michal Krol         ASSIGN_4V(swizzle, 0, 0, 0, 0);
6362861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (token[0] == 'y')
6372861e737e84e4884109b9526ac645194ba892a74Michal Krol         ASSIGN_4V(swizzle, 1, 1, 1, 1);
6382861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (token[0] == 'z')
6392861e737e84e4884109b9526ac645194ba892a74Michal Krol         ASSIGN_4V(swizzle, 2, 2, 2, 2);
6402861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (token[0] == 'w')
6412861e737e84e4884109b9526ac645194ba892a74Michal Krol         ASSIGN_4V(swizzle, 3, 3, 3, 3);
6422861e737e84e4884109b9526ac645194ba892a74Michal Krol      else
6432861e737e84e4884109b9526ac645194ba892a74Michal Krol         return GL_FALSE;
6442861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6452861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
6462861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* 4-component swizzle (vector) */
6472861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLint k;
6482861e737e84e4884109b9526ac645194ba892a74Michal Krol      for (k = 0; token[k] && k < 4; k++) {
6492861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (token[k] == 'x')
6502861e737e84e4884109b9526ac645194ba892a74Michal Krol            swizzle[k] = 0;
6512861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (token[k] == 'y')
6522861e737e84e4884109b9526ac645194ba892a74Michal Krol            swizzle[k] = 1;
6532861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (token[k] == 'z')
6542861e737e84e4884109b9526ac645194ba892a74Michal Krol            swizzle[k] = 2;
6552861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (token[k] == 'w')
6562861e737e84e4884109b9526ac645194ba892a74Michal Krol            swizzle[k] = 3;
6572861e737e84e4884109b9526ac645194ba892a74Michal Krol         else
6582861e737e84e4884109b9526ac645194ba892a74Michal Krol            return GL_FALSE;
6592861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
6602861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (k != 4)
6612861e737e84e4884109b9526ac645194ba892a74Michal Krol         return GL_FALSE;
6622861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6632861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
6642861e737e84e4884109b9526ac645194ba892a74Michal Krol}
6652861e737e84e4884109b9526ac645194ba892a74Michal Krol
6662861e737e84e4884109b9526ac645194ba892a74Michal Krol
6672861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
6682861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_CondCodeMask(struct parse_state *parseState,
6697e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul                   struct prog_dst_register *dstReg)
6702861e737e84e4884109b9526ac645194ba892a74Michal Krol{
6712861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "EQ"))
6722861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_EQ;
6732861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "GE"))
6742861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_GE;
6752861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "GT"))
6762861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_GT;
6772861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "LE"))
6782861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_LE;
6792861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "LT"))
6802861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_LT;
6812861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "NE"))
6822861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_NE;
6832861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "TR"))
6842861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_TR;
6852861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "FL"))
6862861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_FL;
6872861e737e84e4884109b9526ac645194ba892a74Michal Krol   else
6882861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalid condition code mask");
6892861e737e84e4884109b9526ac645194ba892a74Michal Krol
6902861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* look for optional .xyzw swizzle */
6912861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, ".")) {
6922861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLubyte token[100];
6937c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      GLuint swz[4];
6947c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell
6952861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_Token(parseState, token))  /* get xyzw suffix */
6962861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
6972861e737e84e4884109b9526ac645194ba892a74Michal Krol
6987c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_SwizzleSuffix(token, swz))
6992861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid swizzle suffix");
7007c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell
701fd4395b8d1d6f8f018e7e7c3dd0c52fe52ab2794Brian Paul      dstReg->CondSwizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
7022861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7032861e737e84e4884109b9526ac645194ba892a74Michal Krol
7042861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
7052861e737e84e4884109b9526ac645194ba892a74Michal Krol}
7062861e737e84e4884109b9526ac645194ba892a74Michal Krol
7072861e737e84e4884109b9526ac645194ba892a74Michal Krol
7082861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
7092861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a temporary register: Rnn or Hnn
7102861e737e84e4884109b9526ac645194ba892a74Michal Krol */
7112861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
7122861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_TempReg(struct parse_state *parseState, GLint *tempRegNum)
7132861e737e84e4884109b9526ac645194ba892a74Michal Krol{
7142861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
7152861e737e84e4884109b9526ac645194ba892a74Michal Krol
7162861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Should be 'R##' or 'H##' */
7172861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_Token(parseState, token))
7182861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
7192861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (token[0] != 'R' && token[0] != 'H')
7202861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected R## or H##");
7212861e737e84e4884109b9526ac645194ba892a74Michal Krol
7222861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (IsDigit(token[1])) {
7232861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLint reg = _mesa_atoi((const char *) (token + 1));
7242861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[0] == 'H')
7252861e737e84e4884109b9526ac645194ba892a74Michal Krol         reg += 32;
7262861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (reg >= MAX_NV_FRAGMENT_PROGRAM_TEMPS)
7272861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid temporary register name");
7282861e737e84e4884109b9526ac645194ba892a74Michal Krol      *tempRegNum = reg;
7292861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7302861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
7312861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalid temporary register name");
7322861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7332861e737e84e4884109b9526ac645194ba892a74Michal Krol
7342861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
7352861e737e84e4884109b9526ac645194ba892a74Michal Krol}
7362861e737e84e4884109b9526ac645194ba892a74Michal Krol
7372861e737e84e4884109b9526ac645194ba892a74Michal Krol
7382861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
7392861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a write-only dummy register: RC or HC.
7402861e737e84e4884109b9526ac645194ba892a74Michal Krol */
7412861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
7422861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_DummyReg(struct parse_state *parseState, GLint *regNum)
7432861e737e84e4884109b9526ac645194ba892a74Michal Krol{
7442861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "RC")) {
7452861e737e84e4884109b9526ac645194ba892a74Michal Krol       *regNum = 0;
7462861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7472861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "HC")) {
7482861e737e84e4884109b9526ac645194ba892a74Michal Krol       *regNum = 1;
7492861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7502861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
7512861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalid write-only register name");
7522861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7532861e737e84e4884109b9526ac645194ba892a74Michal Krol
7542861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
7552861e737e84e4884109b9526ac645194ba892a74Michal Krol}
7562861e737e84e4884109b9526ac645194ba892a74Michal Krol
7572861e737e84e4884109b9526ac645194ba892a74Michal Krol
7582861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
7592861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a program local parameter register "p[##]"
7602861e737e84e4884109b9526ac645194ba892a74Michal Krol */
7612861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
7622861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_ProgramParamReg(struct parse_state *parseState, GLint *regNum)
7632861e737e84e4884109b9526ac645194ba892a74Michal Krol{
7642861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
7652861e737e84e4884109b9526ac645194ba892a74Michal Krol
7662861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "p["))
7672861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected p[");
7682861e737e84e4884109b9526ac645194ba892a74Michal Krol
7692861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_Token(parseState, token))
7702861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
7712861e737e84e4884109b9526ac645194ba892a74Michal Krol
7722861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (IsDigit(token[0])) {
7732861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* a numbered program parameter register */
7742861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLint reg = _mesa_atoi((const char *) token);
7752861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (reg >= MAX_NV_FRAGMENT_PROGRAM_PARAMS)
7762861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid constant program number");
7772861e737e84e4884109b9526ac645194ba892a74Michal Krol      *regNum = reg;
7782861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7792861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
7802861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
7812861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7822861e737e84e4884109b9526ac645194ba892a74Michal Krol
7832861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "]"))
7842861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected ]");
7852861e737e84e4884109b9526ac645194ba892a74Michal Krol
7862861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
7872861e737e84e4884109b9526ac645194ba892a74Michal Krol}
7882861e737e84e4884109b9526ac645194ba892a74Michal Krol
7892861e737e84e4884109b9526ac645194ba892a74Michal Krol
7902861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
7912861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse f[name]  - fragment input register
7922861e737e84e4884109b9526ac645194ba892a74Michal Krol */
7932861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
7942861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_FragReg(struct parse_state *parseState, GLint *tempRegNum)
7952861e737e84e4884109b9526ac645194ba892a74Michal Krol{
7962861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
7972861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLint j;
7982861e737e84e4884109b9526ac645194ba892a74Michal Krol
7992861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Match 'f[' */
8002861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "f["))
8012861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected f[");
8022861e737e84e4884109b9526ac645194ba892a74Michal Krol
8032861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* get <name> and look for match */
8042861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_Token(parseState, token)) {
8052861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
8062861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8072861e737e84e4884109b9526ac645194ba892a74Michal Krol   for (j = 0; InputRegisters[j]; j++) {
8082861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (_mesa_strcmp((const char *) token, InputRegisters[j]) == 0) {
8092861e737e84e4884109b9526ac645194ba892a74Michal Krol         *tempRegNum = j;
8102861e737e84e4884109b9526ac645194ba892a74Michal Krol         parseState->inputsRead |= (1 << j);
8112861e737e84e4884109b9526ac645194ba892a74Michal Krol         break;
8122861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
8132861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8142861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!InputRegisters[j]) {
8152861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* unknown input register label */
8162861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR2("Invalid register name", token);
8172861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8182861e737e84e4884109b9526ac645194ba892a74Michal Krol
8192861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Match '[' */
8202861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "]"))
8212861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected ]");
8222861e737e84e4884109b9526ac645194ba892a74Michal Krol
8232861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
8242861e737e84e4884109b9526ac645194ba892a74Michal Krol}
8252861e737e84e4884109b9526ac645194ba892a74Michal Krol
8262861e737e84e4884109b9526ac645194ba892a74Michal Krol
8272861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
8282861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_OutputReg(struct parse_state *parseState, GLint *outputRegNum)
8292861e737e84e4884109b9526ac645194ba892a74Michal Krol{
8302861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
8312861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLint j;
8322861e737e84e4884109b9526ac645194ba892a74Michal Krol
8332861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Match "o[" */
8342861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "o["))
8352861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected o[");
8362861e737e84e4884109b9526ac645194ba892a74Michal Krol
8372861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Get output reg name */
8382861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_Token(parseState, token))
8392861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
8402861e737e84e4884109b9526ac645194ba892a74Michal Krol
8412861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* try to match an output register name */
8422861e737e84e4884109b9526ac645194ba892a74Michal Krol   for (j = 0; OutputRegisters[j]; j++) {
8432861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (_mesa_strcmp((const char *) token, OutputRegisters[j]) == 0) {
84490ebb581e60d29bd565ad4d8a49e642de7b0ce5dBrian Paul         static GLuint bothColors = (1 << FRAG_RESULT_COLR) | (1 << FRAG_RESULT_COLH);
8452861e737e84e4884109b9526ac645194ba892a74Michal Krol         *outputRegNum = j;
8462861e737e84e4884109b9526ac645194ba892a74Michal Krol         parseState->outputsWritten |= (1 << j);
8472861e737e84e4884109b9526ac645194ba892a74Michal Krol         if ((parseState->outputsWritten & bothColors) == bothColors) {
8482861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Illegal to write to both o[COLR] and o[COLH]");
8492861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
8502861e737e84e4884109b9526ac645194ba892a74Michal Krol         break;
8512861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
8522861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8532861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!OutputRegisters[j])
8542861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalid output register name");
8552861e737e84e4884109b9526ac645194ba892a74Michal Krol
8562861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Match ']' */
8572861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "]"))
8582861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected ]");
8592861e737e84e4884109b9526ac645194ba892a74Michal Krol
8602861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
8612861e737e84e4884109b9526ac645194ba892a74Michal Krol}
8622861e737e84e4884109b9526ac645194ba892a74Michal Krol
8632861e737e84e4884109b9526ac645194ba892a74Michal Krol
8642861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
8652861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_MaskedDstReg(struct parse_state *parseState,
8667e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul                   struct prog_dst_register *dstReg)
8672861e737e84e4884109b9526ac645194ba892a74Michal Krol{
8682861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
8697c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   GLint idx;
8702861e737e84e4884109b9526ac645194ba892a74Michal Krol
8712861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Dst reg can be R<n>, H<n>, o[n], RC or HC */
8722861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Peek_Token(parseState, token))
8732861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
8742861e737e84e4884109b9526ac645194ba892a74Michal Krol
8752861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (_mesa_strcmp((const char *) token, "RC") == 0 ||
8762861e737e84e4884109b9526ac645194ba892a74Michal Krol       _mesa_strcmp((const char *) token, "HC") == 0) {
8772861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* a write-only register */
8782861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->File = PROGRAM_WRITE_ONLY;
8797c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_DummyReg(parseState, &idx))
8802861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
8817c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      dstReg->Index = idx;
8822861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8832861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == 'R' || token[0] == 'H') {
8842861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* a temporary register */
8852861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->File = PROGRAM_TEMPORARY;
8867c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_TempReg(parseState, &idx))
8872861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
8887c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      dstReg->Index = idx;
8892861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8902861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == 'o') {
8912861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* an output register */
8922861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->File = PROGRAM_OUTPUT;
8937c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_OutputReg(parseState, &idx))
8942861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
8957c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      dstReg->Index = idx;
8962861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8972861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
8982861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalid destination register name");
8992861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9002861e737e84e4884109b9526ac645194ba892a74Michal Krol
9012861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Parse optional write mask */
9022861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, ".")) {
9032861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* got a mask */
9042861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLint k = 0;
9052861e737e84e4884109b9526ac645194ba892a74Michal Krol
9062861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_Token(parseState, token))  /* get xyzw writemask */
9072861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
9082861e737e84e4884109b9526ac645194ba892a74Michal Krol
9097c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      dstReg->WriteMask = 0;
9102861e737e84e4884109b9526ac645194ba892a74Michal Krol
9112861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[k] == 'x') {
9127c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         dstReg->WriteMask |= WRITEMASK_X;
9132861e737e84e4884109b9526ac645194ba892a74Michal Krol         k++;
9142861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
9152861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[k] == 'y') {
9167c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         dstReg->WriteMask |= WRITEMASK_Y;
9172861e737e84e4884109b9526ac645194ba892a74Michal Krol         k++;
9182861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
9192861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[k] == 'z') {
9207c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         dstReg->WriteMask |= WRITEMASK_Z;
9212861e737e84e4884109b9526ac645194ba892a74Michal Krol         k++;
9222861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
9232861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[k] == 'w') {
9247c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         dstReg->WriteMask |= WRITEMASK_W;
9252861e737e84e4884109b9526ac645194ba892a74Michal Krol         k++;
9262861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
9272861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (k == 0) {
9282861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid writemask character");
9292861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
9302861e737e84e4884109b9526ac645194ba892a74Michal Krol
9312861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9322861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
9337c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      dstReg->WriteMask = WRITEMASK_XYZW;
9342861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9352861e737e84e4884109b9526ac645194ba892a74Michal Krol
9362861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* optional condition code mask */
9372861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "(")) {
9382861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".x|y|z|w) */
9392861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".[xyzw]) */
9402861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_CondCodeMask(parseState, dstReg))
9412861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
9422861e737e84e4884109b9526ac645194ba892a74Michal Krol
9432861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_String(parseState, ")"))  /* consume ")" */
9442861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Expected )");
9452861e737e84e4884109b9526ac645194ba892a74Michal Krol
9462861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_TRUE;
9472861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9482861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
9492861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* no cond code mask */
9502861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_TR;
9517c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      dstReg->CondSwizzle = SWIZZLE_NOOP;
9522861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_TRUE;
9532861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9542861e737e84e4884109b9526ac645194ba892a74Michal Krol}
9552861e737e84e4884109b9526ac645194ba892a74Michal Krol
9562861e737e84e4884109b9526ac645194ba892a74Michal Krol
9572861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
9582861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a vector source (register, constant, etc):
9592861e737e84e4884109b9526ac645194ba892a74Michal Krol *   <vectorSrc>    ::= <absVectorSrc>
9602861e737e84e4884109b9526ac645194ba892a74Michal Krol *                    | <baseVectorSrc>
9612861e737e84e4884109b9526ac645194ba892a74Michal Krol *   <absVectorSrc> ::= <negate> "|" <baseVectorSrc> "|"
9622861e737e84e4884109b9526ac645194ba892a74Michal Krol */
9632861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
9642861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_VectorSrc(struct parse_state *parseState,
9657e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul                struct prog_src_register *srcReg)
9662861e737e84e4884109b9526ac645194ba892a74Michal Krol{
9672861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLfloat sign = 1.0F;
9682861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
9697c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   GLint idx;
9702861e737e84e4884109b9526ac645194ba892a74Michal Krol
9712861e737e84e4884109b9526ac645194ba892a74Michal Krol   /*
9722861e737e84e4884109b9526ac645194ba892a74Michal Krol    * First, take care of +/- and absolute value stuff.
9732861e737e84e4884109b9526ac645194ba892a74Michal Krol    */
9742861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "-"))
9752861e737e84e4884109b9526ac645194ba892a74Michal Krol      sign = -1.0F;
9762861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "+"))
9772861e737e84e4884109b9526ac645194ba892a74Michal Krol      sign = +1.0F;
9782861e737e84e4884109b9526ac645194ba892a74Michal Krol
9792861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "|")) {
9802861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Abs = GL_TRUE;
9812861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->NegateAbs = (sign < 0.0F) ? GL_TRUE : GL_FALSE;
9822861e737e84e4884109b9526ac645194ba892a74Michal Krol
9832861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (Parse_String(parseState, "-"))
984a8c4242395b1bce0eac2a20243e5289414a9f511Brian Paul         srcReg->NegateBase = NEGATE_XYZW;
9852861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (Parse_String(parseState, "+"))
986a8c4242395b1bce0eac2a20243e5289414a9f511Brian Paul         srcReg->NegateBase = NEGATE_NONE;
9872861e737e84e4884109b9526ac645194ba892a74Michal Krol      else
988a8c4242395b1bce0eac2a20243e5289414a9f511Brian Paul         srcReg->NegateBase = NEGATE_NONE;
9892861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9902861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
9912861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Abs = GL_FALSE;
9922861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->NegateAbs = GL_FALSE;
993a8c4242395b1bce0eac2a20243e5289414a9f511Brian Paul      srcReg->NegateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
9942861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9952861e737e84e4884109b9526ac645194ba892a74Michal Krol
9962861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* This should be the real src vector/register name */
9972861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Peek_Token(parseState, token))
9982861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
9992861e737e84e4884109b9526ac645194ba892a74Michal Krol
10002861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Src reg can be Rn, Hn, f[n], p[n], a named parameter, a scalar
10012861e737e84e4884109b9526ac645194ba892a74Michal Krol    * literal or vector literal.
10022861e737e84e4884109b9526ac645194ba892a74Michal Krol    */
10032861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (token[0] == 'R' || token[0] == 'H') {
10042861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_TEMPORARY;
10057c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_TempReg(parseState, &idx))
10062861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
10077c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      srcReg->Index = idx;
10082861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10092861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == 'f') {
1010e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      /* XXX this might be an identifier! */
10112861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_INPUT;
10127c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_FragReg(parseState, &idx))
10132861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
10147c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      srcReg->Index = idx;
10152861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10162861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == 'p') {
1017e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      /* XXX this might be an identifier! */
10182861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_LOCAL_PARAM;
10197c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_ProgramParamReg(parseState, &idx))
10202861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
10217c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      srcReg->Index = idx;
10222861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10232861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (IsLetter(token[0])){
10242861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLubyte ident[100];
10252861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLint paramIndex;
10262861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_Identifier(parseState, ident))
10272861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
10282861e737e84e4884109b9526ac645194ba892a74Michal Krol      paramIndex = _mesa_lookup_parameter_index(parseState->parameters,
10292861e737e84e4884109b9526ac645194ba892a74Michal Krol                                                -1, (const char *) ident);
10302861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (paramIndex < 0) {
10312861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR2("Undefined constant or parameter: ", ident);
10322861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
10332861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_NAMED_PARAM;
10342861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Index = paramIndex;
10352861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10362861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (IsDigit(token[0]) || token[0] == '-' || token[0] == '+' || token[0] == '.'){
10372861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* literal scalar constant */
10382861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLfloat values[4];
1039fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian      GLuint paramIndex, swizzle;
10402861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_ScalarConstant(parseState, values))
10412861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
1042fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
1043fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian                                              values, 4, &swizzle);
1044fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian      ASSERT(swizzle == SWIZZLE_NOOP);
10452861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_NAMED_PARAM;
10462861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Index = paramIndex;
10472861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10482861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == '{'){
10492861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* literal vector constant */
10502861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLfloat values[4];
1051fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian      GLuint paramIndex, swizzle;
10522861e737e84e4884109b9526ac645194ba892a74Michal Krol      (void) Parse_String(parseState, "{");
10532861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_VectorConstant(parseState, values))
10542861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
1055fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
1056fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian                                              values, 4, &swizzle);
1057fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian      ASSERT(swizzle == SWIZZLE_NOOP);
10582861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_NAMED_PARAM;
10592861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Index = paramIndex;
10602861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10612861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
10622861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR2("Invalid source register name", token);
10632861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10642861e737e84e4884109b9526ac645194ba892a74Michal Krol
10652861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* init swizzle fields */
10667c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   srcReg->Swizzle = SWIZZLE_NOOP;
10672861e737e84e4884109b9526ac645194ba892a74Michal Krol
10682861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Look for optional swizzle suffix */
10692861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, ".")) {
10707c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      GLuint swz[4];
10717c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell
10722861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_Token(parseState, token))
10732861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
10742861e737e84e4884109b9526ac645194ba892a74Michal Krol
10757c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      if (!Parse_SwizzleSuffix(token, swz))
10762861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid swizzle suffix");
10777c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell
1078fd4395b8d1d6f8f018e7e7c3dd0c52fe52ab2794Brian Paul      srcReg->Swizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
10792861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10802861e737e84e4884109b9526ac645194ba892a74Michal Krol
10812861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Finish absolute value */
10822861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (srcReg->Abs && !Parse_String(parseState, "|")) {
10832861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected |");
10842861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10852861e737e84e4884109b9526ac645194ba892a74Michal Krol
10862861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
10872861e737e84e4884109b9526ac645194ba892a74Michal Krol}
10882861e737e84e4884109b9526ac645194ba892a74Michal Krol
10892861e737e84e4884109b9526ac645194ba892a74Michal Krol
10902861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
10912861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_ScalarSrcReg(struct parse_state *parseState,
10927e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul                   struct prog_src_register *srcReg)
10932861e737e84e4884109b9526ac645194ba892a74Michal Krol{
10942861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
10952861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLfloat sign = 1.0F;
10962861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLboolean needSuffix = GL_TRUE;
10977c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   GLint idx;
10982861e737e84e4884109b9526ac645194ba892a74Michal Krol
10992861e737e84e4884109b9526ac645194ba892a74Michal Krol   /*
11002861e737e84e4884109b9526ac645194ba892a74Michal Krol    * First, take care of +/- and absolute value stuff.
11012861e737e84e4884109b9526ac645194ba892a74Michal Krol    */
11022861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "-"))
11032861e737e84e4884109b9526ac645194ba892a74Michal Krol      sign = -1.0F;
11042861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "+"))
11052861e737e84e4884109b9526ac645194ba892a74Michal Krol      sign = +1.0F;
11062861e737e84e4884109b9526ac645194ba892a74Michal Krol
11072861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "|")) {
11082861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Abs = GL_TRUE;
11092861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->NegateAbs = (sign < 0.0F) ? GL_TRUE : GL_FALSE;
11102861e737e84e4884109b9526ac645194ba892a74Michal Krol
11112861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (Parse_String(parseState, "-"))
1112a8c4242395b1bce0eac2a20243e5289414a9f511Brian Paul         srcReg->NegateBase = NEGATE_XYZW;
11132861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (Parse_String(parseState, "+"))
1114a8c4242395b1bce0eac2a20243e5289414a9f511Brian Paul         srcReg->NegateBase = NEGATE_NONE;
11152861e737e84e4884109b9526ac645194ba892a74Michal Krol      else
1116a8c4242395b1bce0eac2a20243e5289414a9f511Brian Paul         srcReg->NegateBase = NEGATE_NONE;
11172861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11182861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
11192861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Abs = GL_FALSE;
11202861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->NegateAbs = GL_FALSE;
1121a8c4242395b1bce0eac2a20243e5289414a9f511Brian Paul      srcReg->NegateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
11222861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11232861e737e84e4884109b9526ac645194ba892a74Michal Krol
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];
1143fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian      GLuint paramIndex, swizzle;
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,
1148fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian                                              values, 4, &swizzle);
1149fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian      ASSERT(swizzle == SWIZZLE_NOOP);
11502861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_NAMED_PARAM;
11512861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Index = paramIndex;
11522861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
1153e6940f0a33a571b199bab60b680c30b718c47445Brian Paul   else if (IsLetter(token[0])){
1154e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      /* named param/constant */
1155e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      GLubyte ident[100];
1156e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      GLint paramIndex;
1157e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      if (!Parse_Identifier(parseState, ident))
1158e6940f0a33a571b199bab60b680c30b718c47445Brian Paul         RETURN_ERROR;
1159e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      paramIndex = _mesa_lookup_parameter_index(parseState->parameters,
1160e6940f0a33a571b199bab60b680c30b718c47445Brian Paul                                                -1, (const char *) ident);
1161e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      if (paramIndex < 0) {
1162e6940f0a33a571b199bab60b680c30b718c47445Brian Paul         RETURN_ERROR2("Undefined constant or parameter: ", ident);
1163e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      }
1164e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      srcReg->File = PROGRAM_NAMED_PARAM;
1165e6940f0a33a571b199bab60b680c30b718c47445Brian Paul      srcReg->Index = paramIndex;
1166e6940f0a33a571b199bab60b680c30b718c47445Brian Paul   }
11672861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (IsDigit(token[0])) {
11682861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* scalar literal */
11692861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLfloat values[4];
1170fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian      GLuint paramIndex, swizzle;
11712861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_ScalarConstant(parseState, values))
11722861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
1173fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
1174fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian                                              values, 4, &swizzle);
1175fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian      ASSERT(swizzle == SWIZZLE_NOOP);
11762861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Index = paramIndex;
11772861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_NAMED_PARAM;
11782861e737e84e4884109b9526ac645194ba892a74Michal Krol      needSuffix = GL_FALSE;
11792861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11802861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
11812861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR2("Invalid scalar source argument", token);
11822861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11832861e737e84e4884109b9526ac645194ba892a74Michal Krol
11847c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   srcReg->Swizzle = 0;
11852861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (needSuffix) {
11862861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* parse .[xyzw] suffix */
11872861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_String(parseState, "."))
11882861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Expected .");
11892861e737e84e4884109b9526ac645194ba892a74Michal Krol
11902861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_Token(parseState, token))
11912861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
11922861e737e84e4884109b9526ac645194ba892a74Michal Krol
11932861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[0] == 'x' && token[1] == 0) {
11947c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         srcReg->Swizzle = 0;
11952861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
11962861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (token[0] == 'y' && token[1] == 0) {
11977c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         srcReg->Swizzle = 1;
11982861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
11992861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (token[0] == 'z' && token[1] == 0) {
12007c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         srcReg->Swizzle = 2;
12012861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
12022861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (token[0] == 'w' && token[1] == 0) {
12037c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         srcReg->Swizzle = 3;
12042861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
12052861e737e84e4884109b9526ac645194ba892a74Michal Krol      else {
12062861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid scalar source suffix");
12072861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
12082861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
12092861e737e84e4884109b9526ac645194ba892a74Michal Krol
12102861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Finish absolute value */
12112861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (srcReg->Abs && !Parse_String(parseState, "|")) {
12122861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected |");
12132861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
12142861e737e84e4884109b9526ac645194ba892a74Michal Krol
12152861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
12162861e737e84e4884109b9526ac645194ba892a74Michal Krol}
12172861e737e84e4884109b9526ac645194ba892a74Michal Krol
12182861e737e84e4884109b9526ac645194ba892a74Michal Krol
12192a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paulstatic GLboolean
12202a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian PaulParse_PrintInstruction(struct parse_state *parseState,
12217e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul                       struct prog_instruction *inst)
12222a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul{
12232a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   const GLubyte *str;
12242a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   GLubyte *msg;
12252a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   GLuint len;
12267c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   GLint idx;
12272a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul
12282a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   /* The first argument is a literal string 'just like this' */
12292a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   if (!Parse_String(parseState, "'"))
12302a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      RETURN_ERROR1("Expected '");
12312a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul
12322a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   str = parseState->pos;
12332a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   for (len = 0; str[len] != '\''; len++) /* find closing quote */
12342a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      ;
12352a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   parseState->pos += len + 1;
12369580179dfb42d5b81ff6ec9704b82a556c7f1229Brian Paul   msg = (GLubyte*) _mesa_malloc(len + 1);
12372a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul
12382a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   _mesa_memcpy(msg, str, len);
12392a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   msg[len] = 0;
12402a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   inst->Data = msg;
12412a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul
12422a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   if (Parse_String(parseState, ",")) {
12432a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      /* got an optional register to print */
12442a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      GLubyte token[100];
12452a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      GetToken(parseState, token);
12462a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      if (token[0] == 'o') {
12472a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul         /* dst reg */
12487c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell         if (!Parse_OutputReg(parseState, &idx))
12492a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul            RETURN_ERROR;
12507c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell	 inst->SrcReg[0].Index = idx;
12512a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul         inst->SrcReg[0].File = PROGRAM_OUTPUT;
12522a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      }
12532a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      else {
12542a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul         /* src reg */
12552a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul         if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
12562a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul            RETURN_ERROR;
12572a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul      }
12582a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   }
12592a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   else {
12608cdf3729468aefb7c67c8ecd32fd850adbf6d351Brian Paul      inst->SrcReg[0].File = PROGRAM_UNDEFINED;
12612a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   }
12622a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul
12637c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   inst->SrcReg[0].Swizzle = SWIZZLE_NOOP;
1264a8c4242395b1bce0eac2a20243e5289414a9f511Brian Paul   inst->SrcReg[0].NegateBase = NEGATE_NONE;
12652a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   inst->SrcReg[0].Abs = GL_FALSE;
12662a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   inst->SrcReg[0].NegateAbs = GL_FALSE;
12672a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul
12682a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul   return GL_TRUE;
12692a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul}
12702a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul
12712861e737e84e4884109b9526ac645194ba892a74Michal Krol
12722861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
12732861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_InstructionSequence(struct parse_state *parseState,
12747e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul                          struct prog_instruction program[])
12752861e737e84e4884109b9526ac645194ba892a74Michal Krol{
12762861e737e84e4884109b9526ac645194ba892a74Michal Krol   while (1) {
12777e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul      struct prog_instruction *inst = program + parseState->numInst;
12782861e737e84e4884109b9526ac645194ba892a74Michal Krol      struct instruction_pattern instMatch;
12792861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLubyte token[100];
12802861e737e84e4884109b9526ac645194ba892a74Michal Krol
12812861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* Initialize the instruction */
1282d6272e06172f7ac7a0d6e8062e8ffba33e1ab3baBrian Paul      _mesa_init_instructions(inst, 1);
12832861e737e84e4884109b9526ac645194ba892a74Michal Krol
12842861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* special instructions */
12852861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (Parse_String(parseState, "DEFINE")) {
12862861e737e84e4884109b9526ac645194ba892a74Michal Krol         GLubyte id[100];
12872861e737e84e4884109b9526ac645194ba892a74Michal Krol         GLfloat value[7];  /* yes, 7 to be safe */
12882861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_Identifier(parseState, id))
12892861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR;
12902861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* XXX make sure id is not a reserved identifer, like R9 */
12912861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_String(parseState, "="))
12922861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Expected =");
12932861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_VectorOrScalarConstant(parseState, value))
12942861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR;
12952861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_String(parseState, ";"))
12962861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Expected ;");
12972861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (_mesa_lookup_parameter_index(parseState->parameters,
12982861e737e84e4884109b9526ac645194ba892a74Michal Krol                                          -1, (const char *) id) >= 0) {
12992861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR2(id, "already defined");
13002861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13012861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_add_named_parameter(parseState->parameters,
13022861e737e84e4884109b9526ac645194ba892a74Michal Krol                                   (const char *) id, value);
13032861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
13042861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (Parse_String(parseState, "DECLARE")) {
13052861e737e84e4884109b9526ac645194ba892a74Michal Krol         GLubyte id[100];
13062861e737e84e4884109b9526ac645194ba892a74Michal Krol         GLfloat value[7] = {0, 0, 0, 0, 0, 0, 0};  /* yes, to be safe */
13072861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_Identifier(parseState, id))
13082861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR;
13092861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* XXX make sure id is not a reserved identifer, like R9 */
13102861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (Parse_String(parseState, "=")) {
13112861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorOrScalarConstant(parseState, value))
13122861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13132861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13142861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_String(parseState, ";"))
13152861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Expected ;");
13162861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (_mesa_lookup_parameter_index(parseState->parameters,
13172861e737e84e4884109b9526ac645194ba892a74Michal Krol                                          -1, (const char *) id) >= 0) {
13182861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR2(id, "already declared");
13192861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13202861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_add_named_parameter(parseState->parameters,
13212861e737e84e4884109b9526ac645194ba892a74Michal Krol                                   (const char *) id, value);
13222861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
13232861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (Parse_String(parseState, "END")) {
13247e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul         inst->Opcode = OPCODE_END;
13252861e737e84e4884109b9526ac645194ba892a74Michal Krol         inst->StringPos = parseState->curLine - parseState->start;
13262861e737e84e4884109b9526ac645194ba892a74Michal Krol         assert(inst->StringPos >= 0);
13272861e737e84e4884109b9526ac645194ba892a74Michal Krol         parseState->numInst++;
13282861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (Parse_Token(parseState, token)) {
13292861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Code after END opcode.");
13302861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13312861e737e84e4884109b9526ac645194ba892a74Michal Krol         break;
13322861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
13332861e737e84e4884109b9526ac645194ba892a74Michal Krol      else {
13342861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* general/arithmetic instruction */
13352861e737e84e4884109b9526ac645194ba892a74Michal Krol
13362861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* get token */
13372861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_Token(parseState, token)) {
13382861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Missing END instruction.");
13392861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13402861e737e84e4884109b9526ac645194ba892a74Michal Krol
13412861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* try to find matching instuction */
13422861e737e84e4884109b9526ac645194ba892a74Michal Krol         instMatch = MatchInstruction(token);
134328b014ee256290eb0494b967e40c475c0c895f57Brian Paul         if (instMatch.opcode >= MAX_OPCODE) {
13442861e737e84e4884109b9526ac645194ba892a74Michal Krol            /* bad instruction name */
13452861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR2("Unexpected token: ", token);
13462861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13472861e737e84e4884109b9526ac645194ba892a74Michal Krol
13482861e737e84e4884109b9526ac645194ba892a74Michal Krol         inst->Opcode = instMatch.opcode;
13492861e737e84e4884109b9526ac645194ba892a74Michal Krol         inst->Precision = instMatch.suffixes & (_R | _H | _X);
1350e31ac052236ea615b4995f9ec301d8af4b864531Brian Paul         inst->SaturateMode = (instMatch.suffixes & (_S))
1351e31ac052236ea615b4995f9ec301d8af4b864531Brian Paul            ? SATURATE_ZERO_ONE : SATURATE_OFF;
13527e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul         inst->CondUpdate = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE;
13532861e737e84e4884109b9526ac645194ba892a74Michal Krol         inst->StringPos = parseState->curLine - parseState->start;
13542861e737e84e4884109b9526ac645194ba892a74Michal Krol         assert(inst->StringPos >= 0);
13552861e737e84e4884109b9526ac645194ba892a74Michal Krol
13562861e737e84e4884109b9526ac645194ba892a74Michal Krol         /*
13572861e737e84e4884109b9526ac645194ba892a74Michal Krol          * parse the input and output operands
13582861e737e84e4884109b9526ac645194ba892a74Michal Krol          */
13592861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (instMatch.outputs == OUTPUT_S || instMatch.outputs == OUTPUT_V) {
13602861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
13612861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13622861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
13632861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
13642861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13652861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.outputs == OUTPUT_NONE) {
13667e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul            if (instMatch.opcode == OPCODE_KIL_NV) {
13672a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul               /* This is a little weird, the cond code info is in
13682a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul                * the dest register.
13692a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul                */
13702a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul               if (!Parse_CondCodeMask(parseState, &inst->DstReg))
13712a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul                  RETURN_ERROR;
13722a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul            }
13732a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul            else {
13747e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul               ASSERT(instMatch.opcode == OPCODE_PRINT);
13752a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul            }
13762861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13772861e737e84e4884109b9526ac645194ba892a74Michal Krol
13782861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (instMatch.inputs == INPUT_1V) {
13792861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
13802861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13812861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13822861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_2V) {
13832861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
13842861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13852861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
13862861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
13872861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
13882861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13892861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13902861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_3V) {
13912861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
13922861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13932861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
13942861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
13952861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
13962861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13972861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
13982861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
13992861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[2]))
14002861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14012861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
14022861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_1S) {
14032861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
14042861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14052861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
14062861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_2S) {
14072861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
14082861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14092861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
14102861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
14112861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[1]))
14122861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14132861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
14142861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_CC) {
14152861e737e84e4884109b9526ac645194ba892a74Michal Krol            /* XXX to-do */
14162861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
14172861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_1V_T) {
14187c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell	    GLubyte unit, idx;
14192861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
14202861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14212861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
14222861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
14237c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell            if (!Parse_TextureImageId(parseState, &unit, &idx))
14242861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14257c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell	    inst->TexSrcUnit = unit;
14267e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul	    inst->TexSrcTarget = idx;
14272861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
14282861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_3V_T) {
14297c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell	    GLubyte unit, idx;
14302861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
14312861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14322861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
14332861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
14342861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
14352861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14362861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
14372861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
14382861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[2]))
14392861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14402861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
14412861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
14427c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell            if (!Parse_TextureImageId(parseState, &unit, &idx))
14432861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
14447c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell	    inst->TexSrcUnit = unit;
14457e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul	    inst->TexSrcTarget = idx;
14462861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
14472a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul         else if (instMatch.inputs == INPUT_1V_S) {
14482a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul            if (!Parse_PrintInstruction(parseState, inst))
14492a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul               RETURN_ERROR;
14502a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul         }
14512861e737e84e4884109b9526ac645194ba892a74Michal Krol
14522861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* end of statement semicolon */
14532861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_String(parseState, ";"))
14542861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Expected ;");
14552861e737e84e4884109b9526ac645194ba892a74Michal Krol
14562861e737e84e4884109b9526ac645194ba892a74Michal Krol         parseState->numInst++;
14572861e737e84e4884109b9526ac645194ba892a74Michal Krol
14582861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (parseState->numInst >= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS)
14592861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Program too long");
14602861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
14612861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
14622861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
14632861e737e84e4884109b9526ac645194ba892a74Michal Krol}
14642861e737e84e4884109b9526ac645194ba892a74Michal Krol
14652861e737e84e4884109b9526ac645194ba892a74Michal Krol
14662861e737e84e4884109b9526ac645194ba892a74Michal Krol
14672861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
14682861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse/compile the 'str' returning the compiled 'program'.
14692861e737e84e4884109b9526ac645194ba892a74Michal Krol * ctx->Program.ErrorPos will be -1 if successful.  Otherwise, ErrorPos
14702861e737e84e4884109b9526ac645194ba892a74Michal Krol * indicates the position of the error in 'str'.
14712861e737e84e4884109b9526ac645194ba892a74Michal Krol */
14722861e737e84e4884109b9526ac645194ba892a74Michal Krolvoid
14732861e737e84e4884109b9526ac645194ba892a74Michal Krol_mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,
14742861e737e84e4884109b9526ac645194ba892a74Michal Krol                                const GLubyte *str, GLsizei len,
1475122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul                                struct gl_fragment_program *program)
14762861e737e84e4884109b9526ac645194ba892a74Michal Krol{
14772861e737e84e4884109b9526ac645194ba892a74Michal Krol   struct parse_state parseState;
14787e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   struct prog_instruction instBuffer[MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS];
14797e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   struct prog_instruction *newInst;
14802861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLenum target;
14812861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte *programString;
14822861e737e84e4884109b9526ac645194ba892a74Michal Krol
14832861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Make a null-terminated copy of the program string */
14842861e737e84e4884109b9526ac645194ba892a74Michal Krol   programString = (GLubyte *) MALLOC(len + 1);
14852861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!programString) {
14862861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
14872861e737e84e4884109b9526ac645194ba892a74Michal Krol      return;
14882861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
14892861e737e84e4884109b9526ac645194ba892a74Michal Krol   MEMCPY(programString, str, len);
14902861e737e84e4884109b9526ac645194ba892a74Michal Krol   programString[len] = 0;
14912861e737e84e4884109b9526ac645194ba892a74Michal Krol
14922861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Get ready to parse */
14932861e737e84e4884109b9526ac645194ba892a74Michal Krol   _mesa_bzero(&parseState, sizeof(struct parse_state));
14942861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.ctx = ctx;
14952861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.start = programString;
14962861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.program = program;
14972861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.numInst = 0;
14982861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.curLine = programString;
14992861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.parameters = _mesa_new_parameter_list();
15002861e737e84e4884109b9526ac645194ba892a74Michal Krol
15012861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Reset error state */
15022861e737e84e4884109b9526ac645194ba892a74Michal Krol   _mesa_set_program_error(ctx, -1, NULL);
15032861e737e84e4884109b9526ac645194ba892a74Michal Krol
15042861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* check the program header */
15052861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (_mesa_strncmp((const char *) programString, "!!FP1.0", 7) == 0) {
15062861e737e84e4884109b9526ac645194ba892a74Michal Krol      target = GL_FRAGMENT_PROGRAM_NV;
15072861e737e84e4884109b9526ac645194ba892a74Michal Krol      parseState.pos = programString + 7;
15082861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15092861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (_mesa_strncmp((const char *) programString, "!!FCP1.0", 8) == 0) {
15102861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* fragment / register combiner program - not supported */
15112861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_set_program_error(ctx, 0, "Invalid fragment program header");
15122861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
15132861e737e84e4884109b9526ac645194ba892a74Michal Krol      return;
15142861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15152861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
15162861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* invalid header */
15172861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_set_program_error(ctx, 0, "Invalid fragment program header");
15182861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
15192861e737e84e4884109b9526ac645194ba892a74Michal Krol      return;
15202861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15212861e737e84e4884109b9526ac645194ba892a74Michal Krol
15222861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* make sure target and header match */
15232861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (target != dstTarget) {
15242861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_error(ctx, GL_INVALID_OPERATION,
15252861e737e84e4884109b9526ac645194ba892a74Michal Krol                  "glLoadProgramNV(target mismatch 0x%x != 0x%x)",
15262861e737e84e4884109b9526ac645194ba892a74Michal Krol                  target, dstTarget);
15272861e737e84e4884109b9526ac645194ba892a74Michal Krol      return;
15282861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15292861e737e84e4884109b9526ac645194ba892a74Michal Krol
15302861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_InstructionSequence(&parseState, instBuffer)) {
15312861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLuint u;
15322861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* successful parse! */
15332861e737e84e4884109b9526ac645194ba892a74Michal Krol
15342861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (parseState.outputsWritten == 0) {
15352861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* must write at least one output! */
15362861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_error(ctx, GL_INVALID_OPERATION,
15372861e737e84e4884109b9526ac645194ba892a74Michal Krol                     "Invalid fragment program - no outputs written.");
15382861e737e84e4884109b9526ac645194ba892a74Michal Krol         return;
15392861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
15402861e737e84e4884109b9526ac645194ba892a74Michal Krol
15412861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* copy the compiled instructions */
15422861e737e84e4884109b9526ac645194ba892a74Michal Krol      assert(parseState.numInst <= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS);
1543383c39e58e0ab888afac473526109b62ec0f8f6fBrian Paul      newInst = _mesa_alloc_instructions(parseState.numInst);
15442861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!newInst) {
15452861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
15462861e737e84e4884109b9526ac645194ba892a74Michal Krol         return;  /* out of memory */
15472861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
1548383c39e58e0ab888afac473526109b62ec0f8f6fBrian Paul      _mesa_memcpy(newInst, instBuffer,
1549383c39e58e0ab888afac473526109b62ec0f8f6fBrian Paul                   parseState.numInst * sizeof(struct prog_instruction));
15502861e737e84e4884109b9526ac645194ba892a74Michal Krol
15512861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* install the program */
15522861e737e84e4884109b9526ac645194ba892a74Michal Krol      program->Base.Target = target;
15532861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (program->Base.String) {
15542861e737e84e4884109b9526ac645194ba892a74Michal Krol         FREE(program->Base.String);
15552861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
15562861e737e84e4884109b9526ac645194ba892a74Michal Krol      program->Base.String = programString;
15572861e737e84e4884109b9526ac645194ba892a74Michal Krol      program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB;
1558de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul      if (program->Base.Instructions) {
1559de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul         _mesa_free(program->Base.Instructions);
15602861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
1561de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul      program->Base.Instructions = newInst;
1562ee40c4fb34bd06ecc6dd6f2e658ca2c2c20af952Brian Paul      program->Base.NumInstructions = parseState.numInst;
1563de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul      program->Base.InputsRead = parseState.inputsRead;
1564de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul      program->Base.OutputsWritten = parseState.outputsWritten;
15652861e737e84e4884109b9526ac645194ba892a74Michal Krol      for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++)
1566c9db223f902ce9d7e9f3038e6baac6da7f231b34Brian         program->Base.TexturesUsed[u] = parseState.texturesUsed[u];
15672861e737e84e4884109b9526ac645194ba892a74Michal Krol
15682861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* save program parameters */
1569de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul      program->Base.Parameters = parseState.parameters;
15702861e737e84e4884109b9526ac645194ba892a74Michal Krol
15712861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* allocate registers for declared program parameters */
15722861e737e84e4884109b9526ac645194ba892a74Michal Krol#if 00
15732861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_assign_program_registers(&(program->SymbolTable));
15742861e737e84e4884109b9526ac645194ba892a74Michal Krol#endif
15752861e737e84e4884109b9526ac645194ba892a74Michal Krol
1576ac33dd1312530e0bab0c7e5d25c9d70f4e884753Brian Paul#ifdef DEBUG_foo
15772861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("--- glLoadProgramNV(%d) result ---\n", program->Base.Id);
15782861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_print_nv_fragment_program(program);
15792861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("----------------------------------\n");
15802861e737e84e4884109b9526ac645194ba892a74Michal Krol#endif
15812861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15822861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
15832861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* Error! */
15842861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV");
15852861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* NOTE: _mesa_set_program_error would have been called already */
15862861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15872861e737e84e4884109b9526ac645194ba892a74Michal Krol}
15882861e737e84e4884109b9526ac645194ba892a74Michal Krol
15892861e737e84e4884109b9526ac645194ba892a74Michal Krol
15902861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void
1591122629f27925a9dc50029bebc5079f87f416a7e1Brian PaulPrintSrcReg(const struct gl_fragment_program *program,
15927e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul            const struct prog_src_register *src)
15932861e737e84e4884109b9526ac645194ba892a74Michal Krol{
15942861e737e84e4884109b9526ac645194ba892a74Michal Krol   static const char comps[5] = "xyzw";
15952861e737e84e4884109b9526ac645194ba892a74Michal Krol
15962861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (src->NegateAbs) {
15972861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("-");
15982861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15992861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (src->Abs) {
16002861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("|");
16012861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
16022861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (src->NegateBase) {
16032861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("-");
16042861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
16052861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (src->File == PROGRAM_NAMED_PARAM) {
1606de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul      if (program->Base.Parameters->Parameters[src->Index].Type
1607de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul          == PROGRAM_CONSTANT) {
1608de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul         const GLfloat *v;
1609de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul         v = program->Base.Parameters->ParameterValues[src->Index];
1610de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul         _mesa_printf("{%g, %g, %g, %g}", v[0], v[1], v[2], v[3]);
16112861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
16122861e737e84e4884109b9526ac645194ba892a74Michal Krol      else {
1613bed8363aa6ab9f3dbd8052acc8c12d3de14f1399Brian Paul         ASSERT(program->Base.Parameters->Parameters[src->Index].Type
1614613e1ad5d517d9964bd9cf94daa931dda33113feBrian Paul                == PROGRAM_NAMED_PARAM);
1615de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul         _mesa_printf("%s", program->Base.Parameters->Parameters[src->Index].Name);
16162861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
16172861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
16182861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (src->File == PROGRAM_OUTPUT) {
16192861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("o[%s]", OutputRegisters[src->Index]);
16202861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
16212861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (src->File == PROGRAM_INPUT) {
16222861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("f[%s]", InputRegisters[src->Index]);
16232861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
16242861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (src->File == PROGRAM_LOCAL_PARAM) {
16252861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("p[%d]", src->Index);
16262861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
16272861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (src->File == PROGRAM_TEMPORARY) {
16282861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (src->Index >= 32)
16292861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_printf("H%d", src->Index);
16302861e737e84e4884109b9526ac645194ba892a74Michal Krol      else
16312861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_printf("R%d", src->Index);
16322861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
16332861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (src->File == PROGRAM_WRITE_ONLY) {
16342861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("%cC", "HR"[src->Index]);
16352861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
16362861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
16372861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_problem(NULL, "Invalid fragment register %d", src->Index);
16382861e737e84e4884109b9526ac645194ba892a74Michal Krol      return;
16392861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
16407c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   if (GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 1) &&
16417c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell       GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 2) &&
16427c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell       GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 3)) {
16437c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      _mesa_printf(".%c", comps[GET_SWZ(src->Swizzle, 0)]);
16442861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
16457c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   else if (src->Swizzle != SWIZZLE_NOOP) {
16462861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf(".%c%c%c%c",
16477c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell                   comps[GET_SWZ(src->Swizzle, 0)],
16487c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell                   comps[GET_SWZ(src->Swizzle, 1)],
16497c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell                   comps[GET_SWZ(src->Swizzle, 2)],
16507c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell                   comps[GET_SWZ(src->Swizzle, 3)]);
16512861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
16522861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (src->Abs) {
16532861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("|");
16542861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
16552861e737e84e4884109b9526ac645194ba892a74Michal Krol}
16562861e737e84e4884109b9526ac645194ba892a74Michal Krol
16572861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void
16587e807510d8c3e88ee7ae6c697393201cf08f992fBrian PaulPrintTextureSrc(const struct prog_instruction *inst)
16592861e737e84e4884109b9526ac645194ba892a74Michal Krol{
16602861e737e84e4884109b9526ac645194ba892a74Michal Krol   _mesa_printf("TEX%d, ", inst->TexSrcUnit);
16617e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   switch (inst->TexSrcTarget) {
16627c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   case TEXTURE_1D_INDEX:
16632861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("1D");
16642861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
16657c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   case TEXTURE_2D_INDEX:
16662861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("2D");
16672861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
16687c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   case TEXTURE_3D_INDEX:
16692861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("3D");
16702861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
16717c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   case TEXTURE_RECT_INDEX:
16722861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("RECT");
16732861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
16747c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   case TEXTURE_CUBE_INDEX:
16752861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("CUBE");
16762861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
16772861e737e84e4884109b9526ac645194ba892a74Michal Krol   default:
16782861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_problem(NULL, "Invalid textue target in PrintTextureSrc");
16792861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
16802861e737e84e4884109b9526ac645194ba892a74Michal Krol}
16812861e737e84e4884109b9526ac645194ba892a74Michal Krol
16822861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void
16837e807510d8c3e88ee7ae6c697393201cf08f992fBrian PaulPrintCondCode(const struct prog_dst_register *dst)
16842861e737e84e4884109b9526ac645194ba892a74Michal Krol{
16852861e737e84e4884109b9526ac645194ba892a74Michal Krol   static const char *comps = "xyzw";
16862861e737e84e4884109b9526ac645194ba892a74Michal Krol   static const char *ccString[] = {
16872861e737e84e4884109b9526ac645194ba892a74Michal Krol      "??", "GT", "EQ", "LT", "UN", "GE", "LE", "NE", "TR", "FL", "??"
16882861e737e84e4884109b9526ac645194ba892a74Michal Krol   };
16892861e737e84e4884109b9526ac645194ba892a74Michal Krol
16902861e737e84e4884109b9526ac645194ba892a74Michal Krol   _mesa_printf("%s", ccString[dst->CondMask]);
16917c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   if (GET_SWZ(dst->CondSwizzle, 0) == GET_SWZ(dst->CondSwizzle, 1) &&
16927c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell       GET_SWZ(dst->CondSwizzle, 0) == GET_SWZ(dst->CondSwizzle, 2) &&
16937c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell       GET_SWZ(dst->CondSwizzle, 0) == GET_SWZ(dst->CondSwizzle, 3)) {
16947c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell      _mesa_printf(".%c", comps[GET_SWZ(dst->CondSwizzle, 0)]);
16957c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   }
16967c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell   else if (dst->CondSwizzle != SWIZZLE_NOOP) {
16972861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf(".%c%c%c%c",
16987c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell                   comps[GET_SWZ(dst->CondSwizzle, 0)],
16997c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell                   comps[GET_SWZ(dst->CondSwizzle, 1)],
17007c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell                   comps[GET_SWZ(dst->CondSwizzle, 2)],
17017c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell                   comps[GET_SWZ(dst->CondSwizzle, 3)]);
17022861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
17032861e737e84e4884109b9526ac645194ba892a74Michal Krol}
17042861e737e84e4884109b9526ac645194ba892a74Michal Krol
17052861e737e84e4884109b9526ac645194ba892a74Michal Krol
17062861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void
17077e807510d8c3e88ee7ae6c697393201cf08f992fBrian PaulPrintDstReg(const struct prog_dst_register *dst)
17082861e737e84e4884109b9526ac645194ba892a74Michal Krol{
17092861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (dst->File == PROGRAM_OUTPUT) {
17102861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("o[%s]", OutputRegisters[dst->Index]);
17112861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
17122861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (dst->File == PROGRAM_TEMPORARY) {
17132861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (dst->Index >= 32)
17142861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_printf("H%d", dst->Index);
17152861e737e84e4884109b9526ac645194ba892a74Michal Krol      else
17162861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_printf("R%d", dst->Index);
17172861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
17182861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (dst->File == PROGRAM_LOCAL_PARAM) {
17192861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("p[%d]", dst->Index);
17202861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
17212861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (dst->File == PROGRAM_WRITE_ONLY) {
17222861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("%cC", "HR"[dst->Index]);
17232861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
17242861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
17252861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("???");
17262861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
17272861e737e84e4884109b9526ac645194ba892a74Michal Krol
1728ccfe3d4683bb6c97ffacd67267aa002dcb060433Brian Paul   if (dst->WriteMask != 0 && dst->WriteMask != WRITEMASK_XYZW) {
17292861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf(".");
1730ccfe3d4683bb6c97ffacd67267aa002dcb060433Brian Paul      if (dst->WriteMask & WRITEMASK_X)
17312861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_printf("x");
1732ccfe3d4683bb6c97ffacd67267aa002dcb060433Brian Paul      if (dst->WriteMask & WRITEMASK_Y)
17332861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_printf("y");
1734ccfe3d4683bb6c97ffacd67267aa002dcb060433Brian Paul      if (dst->WriteMask & WRITEMASK_Z)
17352861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_printf("z");
1736ccfe3d4683bb6c97ffacd67267aa002dcb060433Brian Paul      if (dst->WriteMask & WRITEMASK_W)
17372861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_printf("w");
17382861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
17392861e737e84e4884109b9526ac645194ba892a74Michal Krol
17402861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (dst->CondMask != COND_TR ||
17417c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell       dst->CondSwizzle != SWIZZLE_NOOP) {
17422861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf(" (");
17432861e737e84e4884109b9526ac645194ba892a74Michal Krol      PrintCondCode(dst);
17442861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf(")");
17452861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
17462861e737e84e4884109b9526ac645194ba892a74Michal Krol}
17472861e737e84e4884109b9526ac645194ba892a74Michal Krol
17482861e737e84e4884109b9526ac645194ba892a74Michal Krol
17492861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
17502861e737e84e4884109b9526ac645194ba892a74Michal Krol * Print (unparse) the given vertex program.  Just for debugging.
17512861e737e84e4884109b9526ac645194ba892a74Michal Krol */
17522861e737e84e4884109b9526ac645194ba892a74Michal Krolvoid
1753122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul_mesa_print_nv_fragment_program(const struct gl_fragment_program *program)
17542861e737e84e4884109b9526ac645194ba892a74Michal Krol{
17557e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul   const struct prog_instruction *inst;
17562861e737e84e4884109b9526ac645194ba892a74Michal Krol
1757de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul   for (inst = program->Base.Instructions; inst->Opcode != OPCODE_END; inst++) {
17582861e737e84e4884109b9526ac645194ba892a74Michal Krol      int i;
17592861e737e84e4884109b9526ac645194ba892a74Michal Krol      for (i = 0; Instructions[i].name; i++) {
17602861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (inst->Opcode == Instructions[i].opcode) {
17612861e737e84e4884109b9526ac645194ba892a74Michal Krol            /* print instruction name */
17622861e737e84e4884109b9526ac645194ba892a74Michal Krol            _mesa_printf("%s", Instructions[i].name);
17632861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (inst->Precision == FLOAT16)
17642861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf("H");
17652861e737e84e4884109b9526ac645194ba892a74Michal Krol            else if (inst->Precision == FIXED12)
17662861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf("X");
17677e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul            if (inst->CondUpdate)
17682861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf("C");
1769e31ac052236ea615b4995f9ec301d8af4b864531Brian Paul            if (inst->SaturateMode == SATURATE_ZERO_ONE)
17702861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf("_SAT");
17712861e737e84e4884109b9526ac645194ba892a74Michal Krol            _mesa_printf(" ");
17722861e737e84e4884109b9526ac645194ba892a74Michal Krol
17732861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (Instructions[i].inputs == INPUT_CC) {
17742861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintCondCode(&inst->DstReg);
17752861e737e84e4884109b9526ac645194ba892a74Michal Krol            }
17762861e737e84e4884109b9526ac645194ba892a74Michal Krol            else if (Instructions[i].outputs == OUTPUT_V ||
17772861e737e84e4884109b9526ac645194ba892a74Michal Krol                     Instructions[i].outputs == OUTPUT_S) {
17782861e737e84e4884109b9526ac645194ba892a74Michal Krol               /* print dest register */
17792861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintDstReg(&inst->DstReg);
17802861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf(", ");
17812861e737e84e4884109b9526ac645194ba892a74Michal Krol            }
17822861e737e84e4884109b9526ac645194ba892a74Michal Krol
17832861e737e84e4884109b9526ac645194ba892a74Michal Krol            /* print source register(s) */
17842861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (Instructions[i].inputs == INPUT_1V ||
17852861e737e84e4884109b9526ac645194ba892a74Michal Krol                Instructions[i].inputs == INPUT_1S) {
17862861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintSrcReg(program, &inst->SrcReg[0]);
17872861e737e84e4884109b9526ac645194ba892a74Michal Krol            }
17882861e737e84e4884109b9526ac645194ba892a74Michal Krol            else if (Instructions[i].inputs == INPUT_2V ||
17892861e737e84e4884109b9526ac645194ba892a74Michal Krol                     Instructions[i].inputs == INPUT_2S) {
17902861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintSrcReg(program, &inst->SrcReg[0]);
17912861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf(", ");
17922861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintSrcReg(program, &inst->SrcReg[1]);
17932861e737e84e4884109b9526ac645194ba892a74Michal Krol            }
17942861e737e84e4884109b9526ac645194ba892a74Michal Krol            else if (Instructions[i].inputs == INPUT_3V) {
17952861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintSrcReg(program, &inst->SrcReg[0]);
17962861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf(", ");
17972861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintSrcReg(program, &inst->SrcReg[1]);
17982861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf(", ");
17992861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintSrcReg(program, &inst->SrcReg[2]);
18002861e737e84e4884109b9526ac645194ba892a74Michal Krol            }
18012861e737e84e4884109b9526ac645194ba892a74Michal Krol            else if (Instructions[i].inputs == INPUT_1V_T) {
18022861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintSrcReg(program, &inst->SrcReg[0]);
18032861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf(", ");
18042861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintTextureSrc(inst);
18052861e737e84e4884109b9526ac645194ba892a74Michal Krol            }
18062861e737e84e4884109b9526ac645194ba892a74Michal Krol            else if (Instructions[i].inputs == INPUT_3V_T) {
18072861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintSrcReg(program, &inst->SrcReg[0]);
18082861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf(", ");
18092861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintSrcReg(program, &inst->SrcReg[1]);
18102861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf(", ");
18112861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintSrcReg(program, &inst->SrcReg[2]);
18122861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf(", ");
18132861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintTextureSrc(inst);
18142861e737e84e4884109b9526ac645194ba892a74Michal Krol            }
18152861e737e84e4884109b9526ac645194ba892a74Michal Krol            _mesa_printf(";\n");
18162861e737e84e4884109b9526ac645194ba892a74Michal Krol            break;
18172861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
18182861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
18192861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Instructions[i].name) {
18202861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_printf("Invalid opcode %d\n", inst->Opcode);
18212861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
18222861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
18232861e737e84e4884109b9526ac645194ba892a74Michal Krol   _mesa_printf("END\n");
18242861e737e84e4884109b9526ac645194ba892a74Michal Krol}
18252861e737e84e4884109b9526ac645194ba892a74Michal Krol
18262861e737e84e4884109b9526ac645194ba892a74Michal Krol
18272861e737e84e4884109b9526ac645194ba892a74Michal Krolconst char *
18282861e737e84e4884109b9526ac645194ba892a74Michal Krol_mesa_nv_fragment_input_register_name(GLuint i)
18292861e737e84e4884109b9526ac645194ba892a74Michal Krol{
18302861e737e84e4884109b9526ac645194ba892a74Michal Krol   ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_INPUTS);
18312861e737e84e4884109b9526ac645194ba892a74Michal Krol   return InputRegisters[i];
18322861e737e84e4884109b9526ac645194ba892a74Michal Krol}
18332861e737e84e4884109b9526ac645194ba892a74Michal Krol
18342861e737e84e4884109b9526ac645194ba892a74Michal Krol
18352861e737e84e4884109b9526ac645194ba892a74Michal Krolconst char *
18362861e737e84e4884109b9526ac645194ba892a74Michal Krol_mesa_nv_fragment_output_register_name(GLuint i)
18372861e737e84e4884109b9526ac645194ba892a74Michal Krol{
18382861e737e84e4884109b9526ac645194ba892a74Michal Krol   ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_OUTPUTS);
18392861e737e84e4884109b9526ac645194ba892a74Michal Krol   return OutputRegisters[i];
18402861e737e84e4884109b9526ac645194ba892a74Michal Krol}
1841