nvfragparse.c revision 2861e737e84e4884109b9526ac645194ba892a74
12861e737e84e4884109b9526ac645194ba892a74Michal Krol/*
22861e737e84e4884109b9526ac645194ba892a74Michal Krol * Mesa 3-D graphics library
32861e737e84e4884109b9526ac645194ba892a74Michal Krol * Version:  6.0
42861e737e84e4884109b9526ac645194ba892a74Michal Krol *
52861e737e84e4884109b9526ac645194ba892a74Michal Krol * Copyright (C) 1999-2004  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 "hash.h"
432861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "imports.h"
442861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "macros.h"
452861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "mtypes.h"
462861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "nvfragprog.h"
472861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "nvfragparse.h"
482861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "nvprogram.h"
492861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "program.h"
502861e737e84e4884109b9526ac645194ba892a74Michal Krol
512861e737e84e4884109b9526ac645194ba892a74Michal Krol
522861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_1V     1
532861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_2V     2
542861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_3V     3
552861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_1S     4
562861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_2S     5
572861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_CC     6
582861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_1V_T   7  /* one source vector, plus textureId */
592861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_3V_T   8  /* one source vector, plus textureId */
602861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_NONE   9
612861e737e84e4884109b9526ac645194ba892a74Michal Krol#define OUTPUT_V    20
622861e737e84e4884109b9526ac645194ba892a74Michal Krol#define OUTPUT_S    21
632861e737e84e4884109b9526ac645194ba892a74Michal Krol#define OUTPUT_NONE 22
642861e737e84e4884109b9526ac645194ba892a74Michal Krol
652861e737e84e4884109b9526ac645194ba892a74Michal Krol/* IRIX defines some of these */
662861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _R
672861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _H
682861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _X
692861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _C
702861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _S
712861e737e84e4884109b9526ac645194ba892a74Michal Krol
722861e737e84e4884109b9526ac645194ba892a74Michal Krol/* Optional suffixes */
732861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _R  FLOAT32  /* float */
742861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _H  FLOAT16  /* half-float */
752861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _X  FIXED12  /* fixed */
762861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _C  0x08     /* set cond codes */
772861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _S  0x10     /* saturate, clamp result to [0,1] */
782861e737e84e4884109b9526ac645194ba892a74Michal Krol
792861e737e84e4884109b9526ac645194ba892a74Michal Krolstruct instruction_pattern {
802861e737e84e4884109b9526ac645194ba892a74Michal Krol   const char *name;
812861e737e84e4884109b9526ac645194ba892a74Michal Krol   enum fp_opcode opcode;
822861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLuint inputs;
832861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLuint outputs;
842861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLuint suffixes;
852861e737e84e4884109b9526ac645194ba892a74Michal Krol};
862861e737e84e4884109b9526ac645194ba892a74Michal Krol
872861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic const struct instruction_pattern Instructions[] = {
882861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "ADD", FP_OPCODE_ADD, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
892861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "COS", FP_OPCODE_COS, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
902861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "DDX", FP_OPCODE_DDX, INPUT_1V, OUTPUT_V, _R | _H |      _C | _S },
912861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "DDY", FP_OPCODE_DDY, INPUT_1V, OUTPUT_V, _R | _H |      _C | _S },
922861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "DP3", FP_OPCODE_DP3, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S },
932861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "DP4", FP_OPCODE_DP4, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S },
942861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "DST", FP_OPCODE_DP4, INPUT_2V, OUTPUT_V, _R | _H |      _C | _S },
952861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "EX2", FP_OPCODE_DP4, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
962861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "FLR", FP_OPCODE_FLR, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
972861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "FRC", FP_OPCODE_FRC, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
982861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "KIL", FP_OPCODE_KIL, INPUT_CC, OUTPUT_NONE, 0                   },
992861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "LG2", FP_OPCODE_LG2, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
1002861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "LIT", FP_OPCODE_LIT, INPUT_1V, OUTPUT_V, _R | _H |      _C | _S },
1012861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "LRP", FP_OPCODE_LRP, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S },
1022861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "MAD", FP_OPCODE_MAD, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S },
1032861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "MAX", FP_OPCODE_MAX, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1042861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "MIN", FP_OPCODE_MIN, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1052861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "MOV", FP_OPCODE_MOV, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
1062861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "MUL", FP_OPCODE_MUL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1072861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "PK2H",  FP_OPCODE_PK2H,  INPUT_1V, OUTPUT_S, 0                  },
1082861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "PK2US", FP_OPCODE_PK2US, INPUT_1V, OUTPUT_S, 0                  },
1092861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "PK4B",  FP_OPCODE_PK4B,  INPUT_1V, OUTPUT_S, 0                  },
1102861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "PK4UB", FP_OPCODE_PK4UB, INPUT_1V, OUTPUT_S, 0                  },
1112861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "POW", FP_OPCODE_POW, INPUT_2S, OUTPUT_S, _R | _H |      _C | _S },
1122861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "RCP", FP_OPCODE_RCP, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
1132861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "RFL", FP_OPCODE_RFL, INPUT_2V, OUTPUT_V, _R | _H |      _C | _S },
1142861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "RSQ", FP_OPCODE_RSQ, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
1152861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "SEQ", FP_OPCODE_SEQ, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1162861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "SFL", FP_OPCODE_SFL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1172861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "SGE", FP_OPCODE_SGE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1182861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "SGT", FP_OPCODE_SGT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1192861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "SIN", FP_OPCODE_SIN, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
1202861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "SLE", FP_OPCODE_SLE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1212861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "SLT", FP_OPCODE_SLT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1222861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "SNE", FP_OPCODE_SNE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1232861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "STR", FP_OPCODE_STR, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1242861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "SUB", FP_OPCODE_SUB, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
1252861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "TEX", FP_OPCODE_TEX, INPUT_1V_T, OUTPUT_V,              _C | _S },
1262861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "TXD", FP_OPCODE_TXD, INPUT_3V_T, OUTPUT_V,              _C | _S },
1272861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "TXP", FP_OPCODE_TXP, INPUT_1V_T, OUTPUT_V,              _C | _S },
1282861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "UP2H",  FP_OPCODE_UP2H,  INPUT_1S, OUTPUT_V,            _C | _S },
1292861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "UP2US", FP_OPCODE_UP2US, INPUT_1S, OUTPUT_V,            _C | _S },
1302861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "UP4B",  FP_OPCODE_UP4B,  INPUT_1S, OUTPUT_V,            _C | _S },
1312861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "UP4UB", FP_OPCODE_UP4UB, INPUT_1S, OUTPUT_V,            _C | _S },
1322861e737e84e4884109b9526ac645194ba892a74Michal Krol   { "X2D", FP_OPCODE_X2D, INPUT_3V, OUTPUT_V, _R | _H |      _C | _S },
1332861e737e84e4884109b9526ac645194ba892a74Michal Krol   { NULL, (enum fp_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;
1472861e737e84e4884109b9526ac645194ba892a74Michal Krol   struct fragment_program *program;  /* current program */
1482861e737e84e4884109b9526ac645194ba892a74Michal Krol
1492861e737e84e4884109b9526ac645194ba892a74Michal Krol   struct 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   }
2492861e737e84e4884109b9526ac645194ba892a74Michal Krol   result.opcode = (enum fp_opcode) -1;
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   }
3742861e737e84e4884109b9526ac645194ba892a74Michal Krol   len = _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,
6692861e737e84e4884109b9526ac645194ba892a74Michal Krol                   struct fp_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];
6932861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_Token(parseState, token))  /* get xyzw suffix */
6942861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
6952861e737e84e4884109b9526ac645194ba892a74Michal Krol
6962861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_SwizzleSuffix(token, dstReg->CondSwizzle))
6972861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid swizzle suffix");
6982861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6992861e737e84e4884109b9526ac645194ba892a74Michal Krol
7002861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
7012861e737e84e4884109b9526ac645194ba892a74Michal Krol}
7022861e737e84e4884109b9526ac645194ba892a74Michal Krol
7032861e737e84e4884109b9526ac645194ba892a74Michal Krol
7042861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
7052861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a temporary register: Rnn or Hnn
7062861e737e84e4884109b9526ac645194ba892a74Michal Krol */
7072861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
7082861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_TempReg(struct parse_state *parseState, GLint *tempRegNum)
7092861e737e84e4884109b9526ac645194ba892a74Michal Krol{
7102861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
7112861e737e84e4884109b9526ac645194ba892a74Michal Krol
7122861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Should be 'R##' or 'H##' */
7132861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_Token(parseState, token))
7142861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
7152861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (token[0] != 'R' && token[0] != 'H')
7162861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected R## or H##");
7172861e737e84e4884109b9526ac645194ba892a74Michal Krol
7182861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (IsDigit(token[1])) {
7192861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLint reg = _mesa_atoi((const char *) (token + 1));
7202861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[0] == 'H')
7212861e737e84e4884109b9526ac645194ba892a74Michal Krol         reg += 32;
7222861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (reg >= MAX_NV_FRAGMENT_PROGRAM_TEMPS)
7232861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid temporary register name");
7242861e737e84e4884109b9526ac645194ba892a74Michal Krol      *tempRegNum = reg;
7252861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7262861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
7272861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalid temporary register name");
7282861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7292861e737e84e4884109b9526ac645194ba892a74Michal Krol
7302861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
7312861e737e84e4884109b9526ac645194ba892a74Michal Krol}
7322861e737e84e4884109b9526ac645194ba892a74Michal Krol
7332861e737e84e4884109b9526ac645194ba892a74Michal Krol
7342861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
7352861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a write-only dummy register: RC or HC.
7362861e737e84e4884109b9526ac645194ba892a74Michal Krol */
7372861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
7382861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_DummyReg(struct parse_state *parseState, GLint *regNum)
7392861e737e84e4884109b9526ac645194ba892a74Michal Krol{
7402861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "RC")) {
7412861e737e84e4884109b9526ac645194ba892a74Michal Krol       *regNum = 0;
7422861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7432861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "HC")) {
7442861e737e84e4884109b9526ac645194ba892a74Michal Krol       *regNum = 1;
7452861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7462861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
7472861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalid write-only register name");
7482861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7492861e737e84e4884109b9526ac645194ba892a74Michal Krol
7502861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
7512861e737e84e4884109b9526ac645194ba892a74Michal Krol}
7522861e737e84e4884109b9526ac645194ba892a74Michal Krol
7532861e737e84e4884109b9526ac645194ba892a74Michal Krol
7542861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
7552861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a program local parameter register "p[##]"
7562861e737e84e4884109b9526ac645194ba892a74Michal Krol */
7572861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
7582861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_ProgramParamReg(struct parse_state *parseState, GLint *regNum)
7592861e737e84e4884109b9526ac645194ba892a74Michal Krol{
7602861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
7612861e737e84e4884109b9526ac645194ba892a74Michal Krol
7622861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "p["))
7632861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected p[");
7642861e737e84e4884109b9526ac645194ba892a74Michal Krol
7652861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_Token(parseState, token))
7662861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
7672861e737e84e4884109b9526ac645194ba892a74Michal Krol
7682861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (IsDigit(token[0])) {
7692861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* a numbered program parameter register */
7702861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLint reg = _mesa_atoi((const char *) token);
7712861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (reg >= MAX_NV_FRAGMENT_PROGRAM_PARAMS)
7722861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid constant program number");
7732861e737e84e4884109b9526ac645194ba892a74Michal Krol      *regNum = reg;
7742861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7752861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
7762861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
7772861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7782861e737e84e4884109b9526ac645194ba892a74Michal Krol
7792861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "]"))
7802861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected ]");
7812861e737e84e4884109b9526ac645194ba892a74Michal Krol
7822861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
7832861e737e84e4884109b9526ac645194ba892a74Michal Krol}
7842861e737e84e4884109b9526ac645194ba892a74Michal Krol
7852861e737e84e4884109b9526ac645194ba892a74Michal Krol
7862861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
7872861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse f[name]  - fragment input register
7882861e737e84e4884109b9526ac645194ba892a74Michal Krol */
7892861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
7902861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_FragReg(struct parse_state *parseState, GLint *tempRegNum)
7912861e737e84e4884109b9526ac645194ba892a74Michal Krol{
7922861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
7932861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLint j;
7942861e737e84e4884109b9526ac645194ba892a74Michal Krol
7952861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Match 'f[' */
7962861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "f["))
7972861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected f[");
7982861e737e84e4884109b9526ac645194ba892a74Michal Krol
7992861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* get <name> and look for match */
8002861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_Token(parseState, token)) {
8012861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
8022861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8032861e737e84e4884109b9526ac645194ba892a74Michal Krol   for (j = 0; InputRegisters[j]; j++) {
8042861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (_mesa_strcmp((const char *) token, InputRegisters[j]) == 0) {
8052861e737e84e4884109b9526ac645194ba892a74Michal Krol         *tempRegNum = j;
8062861e737e84e4884109b9526ac645194ba892a74Michal Krol         parseState->inputsRead |= (1 << j);
8072861e737e84e4884109b9526ac645194ba892a74Michal Krol         break;
8082861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
8092861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8102861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!InputRegisters[j]) {
8112861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* unknown input register label */
8122861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR2("Invalid register name", token);
8132861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8142861e737e84e4884109b9526ac645194ba892a74Michal Krol
8152861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Match '[' */
8162861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "]"))
8172861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected ]");
8182861e737e84e4884109b9526ac645194ba892a74Michal Krol
8192861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
8202861e737e84e4884109b9526ac645194ba892a74Michal Krol}
8212861e737e84e4884109b9526ac645194ba892a74Michal Krol
8222861e737e84e4884109b9526ac645194ba892a74Michal Krol
8232861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
8242861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_OutputReg(struct parse_state *parseState, GLint *outputRegNum)
8252861e737e84e4884109b9526ac645194ba892a74Michal Krol{
8262861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
8272861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLint j;
8282861e737e84e4884109b9526ac645194ba892a74Michal Krol
8292861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Match "o[" */
8302861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "o["))
8312861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected o[");
8322861e737e84e4884109b9526ac645194ba892a74Michal Krol
8332861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Get output reg name */
8342861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_Token(parseState, token))
8352861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
8362861e737e84e4884109b9526ac645194ba892a74Michal Krol
8372861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* try to match an output register name */
8382861e737e84e4884109b9526ac645194ba892a74Michal Krol   for (j = 0; OutputRegisters[j]; j++) {
8392861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (_mesa_strcmp((const char *) token, OutputRegisters[j]) == 0) {
8402861e737e84e4884109b9526ac645194ba892a74Michal Krol         static GLuint bothColors = (1 << FRAG_OUTPUT_COLR) | (1 << FRAG_OUTPUT_COLH);
8412861e737e84e4884109b9526ac645194ba892a74Michal Krol         *outputRegNum = j;
8422861e737e84e4884109b9526ac645194ba892a74Michal Krol         parseState->outputsWritten |= (1 << j);
8432861e737e84e4884109b9526ac645194ba892a74Michal Krol         if ((parseState->outputsWritten & bothColors) == bothColors) {
8442861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Illegal to write to both o[COLR] and o[COLH]");
8452861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
8462861e737e84e4884109b9526ac645194ba892a74Michal Krol         break;
8472861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
8482861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8492861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!OutputRegisters[j])
8502861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalid output register name");
8512861e737e84e4884109b9526ac645194ba892a74Michal Krol
8522861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Match ']' */
8532861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Parse_String(parseState, "]"))
8542861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected ]");
8552861e737e84e4884109b9526ac645194ba892a74Michal Krol
8562861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
8572861e737e84e4884109b9526ac645194ba892a74Michal Krol}
8582861e737e84e4884109b9526ac645194ba892a74Michal Krol
8592861e737e84e4884109b9526ac645194ba892a74Michal Krol
8602861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
8612861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_MaskedDstReg(struct parse_state *parseState,
8622861e737e84e4884109b9526ac645194ba892a74Michal Krol                   struct fp_dst_register *dstReg)
8632861e737e84e4884109b9526ac645194ba892a74Michal Krol{
8642861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
8652861e737e84e4884109b9526ac645194ba892a74Michal Krol
8662861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Dst reg can be R<n>, H<n>, o[n], RC or HC */
8672861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Peek_Token(parseState, token))
8682861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
8692861e737e84e4884109b9526ac645194ba892a74Michal Krol
8702861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (_mesa_strcmp((const char *) token, "RC") == 0 ||
8712861e737e84e4884109b9526ac645194ba892a74Michal Krol       _mesa_strcmp((const char *) token, "HC") == 0) {
8722861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* a write-only register */
8732861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->File = PROGRAM_WRITE_ONLY;
8742861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_DummyReg(parseState, &dstReg->Index))
8752861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
8762861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8772861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == 'R' || token[0] == 'H') {
8782861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* a temporary register */
8792861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->File = PROGRAM_TEMPORARY;
8802861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_TempReg(parseState, &dstReg->Index))
8812861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
8822861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8832861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == 'o') {
8842861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* an output register */
8852861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->File = PROGRAM_OUTPUT;
8862861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_OutputReg(parseState, &dstReg->Index))
8872861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
8882861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8892861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
8902861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Invalid destination register name");
8912861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8922861e737e84e4884109b9526ac645194ba892a74Michal Krol
8932861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Parse optional write mask */
8942861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, ".")) {
8952861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* got a mask */
8962861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLint k = 0;
8972861e737e84e4884109b9526ac645194ba892a74Michal Krol
8982861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_Token(parseState, token))  /* get xyzw writemask */
8992861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
9002861e737e84e4884109b9526ac645194ba892a74Michal Krol
9012861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->WriteMask[0] = GL_FALSE;
9022861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->WriteMask[1] = GL_FALSE;
9032861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->WriteMask[2] = GL_FALSE;
9042861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->WriteMask[3] = GL_FALSE;
9052861e737e84e4884109b9526ac645194ba892a74Michal Krol
9062861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[k] == 'x') {
9072861e737e84e4884109b9526ac645194ba892a74Michal Krol         dstReg->WriteMask[0] = GL_TRUE;
9082861e737e84e4884109b9526ac645194ba892a74Michal Krol         k++;
9092861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
9102861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[k] == 'y') {
9112861e737e84e4884109b9526ac645194ba892a74Michal Krol         dstReg->WriteMask[1] = GL_TRUE;
9122861e737e84e4884109b9526ac645194ba892a74Michal Krol         k++;
9132861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
9142861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[k] == 'z') {
9152861e737e84e4884109b9526ac645194ba892a74Michal Krol         dstReg->WriteMask[2] = GL_TRUE;
9162861e737e84e4884109b9526ac645194ba892a74Michal Krol         k++;
9172861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
9182861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[k] == 'w') {
9192861e737e84e4884109b9526ac645194ba892a74Michal Krol         dstReg->WriteMask[3] = GL_TRUE;
9202861e737e84e4884109b9526ac645194ba892a74Michal Krol         k++;
9212861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
9222861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (k == 0) {
9232861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid writemask character");
9242861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
9252861e737e84e4884109b9526ac645194ba892a74Michal Krol
9262861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9272861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
9282861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->WriteMask[0] = GL_TRUE;
9292861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->WriteMask[1] = GL_TRUE;
9302861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->WriteMask[2] = GL_TRUE;
9312861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->WriteMask[3] = GL_TRUE;
9322861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9332861e737e84e4884109b9526ac645194ba892a74Michal Krol
9342861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* optional condition code mask */
9352861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "(")) {
9362861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".x|y|z|w) */
9372861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".[xyzw]) */
9382861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_CondCodeMask(parseState, dstReg))
9392861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
9402861e737e84e4884109b9526ac645194ba892a74Michal Krol
9412861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_String(parseState, ")"))  /* consume ")" */
9422861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Expected )");
9432861e737e84e4884109b9526ac645194ba892a74Michal Krol
9442861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_TRUE;
9452861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9462861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
9472861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* no cond code mask */
9482861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondMask = COND_TR;
9492861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondSwizzle[0] = 0;
9502861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondSwizzle[1] = 1;
9512861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondSwizzle[2] = 2;
9522861e737e84e4884109b9526ac645194ba892a74Michal Krol      dstReg->CondSwizzle[3] = 3;
9532861e737e84e4884109b9526ac645194ba892a74Michal Krol      return GL_TRUE;
9542861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9552861e737e84e4884109b9526ac645194ba892a74Michal Krol}
9562861e737e84e4884109b9526ac645194ba892a74Michal Krol
9572861e737e84e4884109b9526ac645194ba892a74Michal Krol
9582861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
9592861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a vector source (register, constant, etc):
9602861e737e84e4884109b9526ac645194ba892a74Michal Krol *   <vectorSrc>    ::= <absVectorSrc>
9612861e737e84e4884109b9526ac645194ba892a74Michal Krol *                    | <baseVectorSrc>
9622861e737e84e4884109b9526ac645194ba892a74Michal Krol *   <absVectorSrc> ::= <negate> "|" <baseVectorSrc> "|"
9632861e737e84e4884109b9526ac645194ba892a74Michal Krol */
9642861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
9652861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_VectorSrc(struct parse_state *parseState,
9662861e737e84e4884109b9526ac645194ba892a74Michal Krol                struct fp_src_register *srcReg)
9672861e737e84e4884109b9526ac645194ba892a74Michal Krol{
9682861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLfloat sign = 1.0F;
9692861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
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, "-"))
9842861e737e84e4884109b9526ac645194ba892a74Michal Krol         srcReg->NegateBase = GL_TRUE;
9852861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (Parse_String(parseState, "+"))
9862861e737e84e4884109b9526ac645194ba892a74Michal Krol         srcReg->NegateBase = GL_FALSE;
9872861e737e84e4884109b9526ac645194ba892a74Michal Krol      else
9882861e737e84e4884109b9526ac645194ba892a74Michal Krol         srcReg->NegateBase = GL_FALSE;
9892861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
9902861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
9912861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Abs = GL_FALSE;
9922861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->NegateAbs = GL_FALSE;
9932861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->NegateBase = (sign < 0.0F) ? GL_TRUE : GL_FALSE;
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;
10052861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_TempReg(parseState, &srcReg->Index))
10062861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
10072861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10082861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == 'f') {
10092861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* XXX this might be an identier! */
10102861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_INPUT;
10112861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_FragReg(parseState, &srcReg->Index))
10122861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
10132861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10142861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == 'p') {
10152861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* XXX this might be an identier! */
10162861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_LOCAL_PARAM;
10172861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_ProgramParamReg(parseState, &srcReg->Index))
10182861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
10192861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10202861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (IsLetter(token[0])){
10212861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLubyte ident[100];
10222861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLint paramIndex;
10232861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_Identifier(parseState, ident))
10242861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
10252861e737e84e4884109b9526ac645194ba892a74Michal Krol      paramIndex = _mesa_lookup_parameter_index(parseState->parameters,
10262861e737e84e4884109b9526ac645194ba892a74Michal Krol                                                -1, (const char *) ident);
10272861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (paramIndex < 0) {
10282861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR2("Undefined constant or parameter: ", ident);
10292861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
10302861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_NAMED_PARAM;
10312861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Index = paramIndex;
10322861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10332861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (IsDigit(token[0]) || token[0] == '-' || token[0] == '+' || token[0] == '.'){
10342861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* literal scalar constant */
10352861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLfloat values[4];
10362861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLuint paramIndex;
10372861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_ScalarConstant(parseState, values))
10382861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
10392861e737e84e4884109b9526ac645194ba892a74Michal Krol      paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values);
10402861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_NAMED_PARAM;
10412861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Index = paramIndex;
10422861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10432861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == '{'){
10442861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* literal vector constant */
10452861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLfloat values[4];
10462861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLuint paramIndex;
10472861e737e84e4884109b9526ac645194ba892a74Michal Krol      (void) Parse_String(parseState, "{");
10482861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_VectorConstant(parseState, values))
10492861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
10502861e737e84e4884109b9526ac645194ba892a74Michal Krol      paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values);
10512861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_NAMED_PARAM;
10522861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Index = paramIndex;
10532861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10542861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
10552861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR2("Invalid source register name", token);
10562861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10572861e737e84e4884109b9526ac645194ba892a74Michal Krol
10582861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* init swizzle fields */
10592861e737e84e4884109b9526ac645194ba892a74Michal Krol   srcReg->Swizzle[0] = 0;
10602861e737e84e4884109b9526ac645194ba892a74Michal Krol   srcReg->Swizzle[1] = 1;
10612861e737e84e4884109b9526ac645194ba892a74Michal Krol   srcReg->Swizzle[2] = 2;
10622861e737e84e4884109b9526ac645194ba892a74Michal Krol   srcReg->Swizzle[3] = 3;
10632861e737e84e4884109b9526ac645194ba892a74Michal Krol
10642861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Look for optional swizzle suffix */
10652861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, ".")) {
10662861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_Token(parseState, token))
10672861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
10682861e737e84e4884109b9526ac645194ba892a74Michal Krol
10692861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_SwizzleSuffix(token, srcReg->Swizzle))
10702861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid swizzle suffix");
10712861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10722861e737e84e4884109b9526ac645194ba892a74Michal Krol
10732861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Finish absolute value */
10742861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (srcReg->Abs && !Parse_String(parseState, "|")) {
10752861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected |");
10762861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
10772861e737e84e4884109b9526ac645194ba892a74Michal Krol
10782861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
10792861e737e84e4884109b9526ac645194ba892a74Michal Krol}
10802861e737e84e4884109b9526ac645194ba892a74Michal Krol
10812861e737e84e4884109b9526ac645194ba892a74Michal Krol
10822861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
10832861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_ScalarSrcReg(struct parse_state *parseState,
10842861e737e84e4884109b9526ac645194ba892a74Michal Krol                   struct fp_src_register *srcReg)
10852861e737e84e4884109b9526ac645194ba892a74Michal Krol{
10862861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte token[100];
10872861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLfloat sign = 1.0F;
10882861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLboolean needSuffix = GL_TRUE;
10892861e737e84e4884109b9526ac645194ba892a74Michal Krol
10902861e737e84e4884109b9526ac645194ba892a74Michal Krol   /*
10912861e737e84e4884109b9526ac645194ba892a74Michal Krol    * First, take care of +/- and absolute value stuff.
10922861e737e84e4884109b9526ac645194ba892a74Michal Krol    */
10932861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "-"))
10942861e737e84e4884109b9526ac645194ba892a74Michal Krol      sign = -1.0F;
10952861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (Parse_String(parseState, "+"))
10962861e737e84e4884109b9526ac645194ba892a74Michal Krol      sign = +1.0F;
10972861e737e84e4884109b9526ac645194ba892a74Michal Krol
10982861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_String(parseState, "|")) {
10992861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Abs = GL_TRUE;
11002861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->NegateAbs = (sign < 0.0F) ? GL_TRUE : GL_FALSE;
11012861e737e84e4884109b9526ac645194ba892a74Michal Krol
11022861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (Parse_String(parseState, "-"))
11032861e737e84e4884109b9526ac645194ba892a74Michal Krol         srcReg->NegateBase = GL_TRUE;
11042861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (Parse_String(parseState, "+"))
11052861e737e84e4884109b9526ac645194ba892a74Michal Krol         srcReg->NegateBase = GL_FALSE;
11062861e737e84e4884109b9526ac645194ba892a74Michal Krol      else
11072861e737e84e4884109b9526ac645194ba892a74Michal Krol         srcReg->NegateBase = GL_FALSE;
11082861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11092861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
11102861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Abs = GL_FALSE;
11112861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->NegateAbs = GL_FALSE;
11122861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->NegateBase = (sign < 0.0F) ? GL_TRUE : GL_FALSE;
11132861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11142861e737e84e4884109b9526ac645194ba892a74Michal Krol
11152861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!Peek_Token(parseState, token))
11162861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR;
11172861e737e84e4884109b9526ac645194ba892a74Michal Krol
11182861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Src reg can be R<n>, H<n> or a named fragment attrib */
11192861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (token[0] == 'R' || token[0] == 'H') {
11202861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_TEMPORARY;
11212861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_TempReg(parseState, &srcReg->Index))
11222861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
11232861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11242861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == 'f') {
11252861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_INPUT;
11262861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_FragReg(parseState, &srcReg->Index))
11272861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
11282861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11292861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (token[0] == '{') {
11302861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* vector literal */
11312861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLfloat values[4];
11322861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLuint paramIndex;
11332861e737e84e4884109b9526ac645194ba892a74Michal Krol      (void) Parse_String(parseState, "{");
11342861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_VectorConstant(parseState, values))
11352861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
11362861e737e84e4884109b9526ac645194ba892a74Michal Krol      paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values);
11372861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_NAMED_PARAM;
11382861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Index = paramIndex;
11392861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11402861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (IsDigit(token[0])) {
11412861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* scalar literal */
11422861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLfloat values[4];
11432861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLuint paramIndex;
11442861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_ScalarConstant(parseState, values))
11452861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
11462861e737e84e4884109b9526ac645194ba892a74Michal Krol      paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values);
11472861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Index = paramIndex;
11482861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->File = PROGRAM_NAMED_PARAM;
11492861e737e84e4884109b9526ac645194ba892a74Michal Krol      needSuffix = GL_FALSE;
11502861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11512861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
11522861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR2("Invalid scalar source argument", token);
11532861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11542861e737e84e4884109b9526ac645194ba892a74Michal Krol
11552861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (needSuffix) {
11562861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* parse .[xyzw] suffix */
11572861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_String(parseState, "."))
11582861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Expected .");
11592861e737e84e4884109b9526ac645194ba892a74Michal Krol
11602861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Parse_Token(parseState, token))
11612861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR;
11622861e737e84e4884109b9526ac645194ba892a74Michal Krol
11632861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (token[0] == 'x' && token[1] == 0) {
11642861e737e84e4884109b9526ac645194ba892a74Michal Krol         srcReg->Swizzle[0] = 0;
11652861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
11662861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (token[0] == 'y' && token[1] == 0) {
11672861e737e84e4884109b9526ac645194ba892a74Michal Krol         srcReg->Swizzle[0] = 1;
11682861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
11692861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (token[0] == 'z' && token[1] == 0) {
11702861e737e84e4884109b9526ac645194ba892a74Michal Krol         srcReg->Swizzle[0] = 2;
11712861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
11722861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (token[0] == 'w' && token[1] == 0) {
11732861e737e84e4884109b9526ac645194ba892a74Michal Krol         srcReg->Swizzle[0] = 3;
11742861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
11752861e737e84e4884109b9526ac645194ba892a74Michal Krol      else {
11762861e737e84e4884109b9526ac645194ba892a74Michal Krol         RETURN_ERROR1("Invalid scalar source suffix");
11772861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
11782861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11792861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
11802861e737e84e4884109b9526ac645194ba892a74Michal Krol      srcReg->Swizzle[0] = 0;
11812861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11822861e737e84e4884109b9526ac645194ba892a74Michal Krol   srcReg->Swizzle[1] = srcReg->Swizzle[2] = srcReg->Swizzle[3] = 0;
11832861e737e84e4884109b9526ac645194ba892a74Michal Krol
11842861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Finish absolute value */
11852861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (srcReg->Abs && !Parse_String(parseState, "|")) {
11862861e737e84e4884109b9526ac645194ba892a74Michal Krol      RETURN_ERROR1("Expected |");
11872861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
11882861e737e84e4884109b9526ac645194ba892a74Michal Krol
11892861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
11902861e737e84e4884109b9526ac645194ba892a74Michal Krol}
11912861e737e84e4884109b9526ac645194ba892a74Michal Krol
11922861e737e84e4884109b9526ac645194ba892a74Michal Krol
11932861e737e84e4884109b9526ac645194ba892a74Michal Krol
11942861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean
11952861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_InstructionSequence(struct parse_state *parseState,
11962861e737e84e4884109b9526ac645194ba892a74Michal Krol                          struct fp_instruction program[])
11972861e737e84e4884109b9526ac645194ba892a74Michal Krol{
11982861e737e84e4884109b9526ac645194ba892a74Michal Krol   while (1) {
11992861e737e84e4884109b9526ac645194ba892a74Michal Krol      struct fp_instruction *inst = program + parseState->numInst;
12002861e737e84e4884109b9526ac645194ba892a74Michal Krol      struct instruction_pattern instMatch;
12012861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLubyte token[100];
12022861e737e84e4884109b9526ac645194ba892a74Michal Krol
12032861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* Initialize the instruction */
12042861e737e84e4884109b9526ac645194ba892a74Michal Krol      inst->SrcReg[0].File = (enum register_file) -1;
12052861e737e84e4884109b9526ac645194ba892a74Michal Krol      inst->SrcReg[1].File = (enum register_file) -1;
12062861e737e84e4884109b9526ac645194ba892a74Michal Krol      inst->SrcReg[2].File = (enum register_file) -1;
12072861e737e84e4884109b9526ac645194ba892a74Michal Krol      inst->DstReg.File = (enum register_file) -1;
12082861e737e84e4884109b9526ac645194ba892a74Michal Krol      inst->DstReg.CondSwizzle[0] = 0;
12092861e737e84e4884109b9526ac645194ba892a74Michal Krol      inst->DstReg.CondSwizzle[1] = 1;
12102861e737e84e4884109b9526ac645194ba892a74Michal Krol      inst->DstReg.CondSwizzle[2] = 2;
12112861e737e84e4884109b9526ac645194ba892a74Michal Krol      inst->DstReg.CondSwizzle[3] = 3;
12122861e737e84e4884109b9526ac645194ba892a74Michal Krol
12132861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* special instructions */
12142861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (Parse_String(parseState, "DEFINE")) {
12152861e737e84e4884109b9526ac645194ba892a74Michal Krol         GLubyte id[100];
12162861e737e84e4884109b9526ac645194ba892a74Michal Krol         GLfloat value[7];  /* yes, 7 to be safe */
12172861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_Identifier(parseState, id))
12182861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR;
12192861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* XXX make sure id is not a reserved identifer, like R9 */
12202861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_String(parseState, "="))
12212861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Expected =");
12222861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_VectorOrScalarConstant(parseState, value))
12232861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR;
12242861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_String(parseState, ";"))
12252861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Expected ;");
12262861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (_mesa_lookup_parameter_index(parseState->parameters,
12272861e737e84e4884109b9526ac645194ba892a74Michal Krol                                          -1, (const char *) id) >= 0) {
12282861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR2(id, "already defined");
12292861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
12302861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_add_named_parameter(parseState->parameters,
12312861e737e84e4884109b9526ac645194ba892a74Michal Krol                                   (const char *) id, value);
12322861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
12332861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (Parse_String(parseState, "DECLARE")) {
12342861e737e84e4884109b9526ac645194ba892a74Michal Krol         GLubyte id[100];
12352861e737e84e4884109b9526ac645194ba892a74Michal Krol         GLfloat value[7] = {0, 0, 0, 0, 0, 0, 0};  /* yes, to be safe */
12362861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_Identifier(parseState, id))
12372861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR;
12382861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* XXX make sure id is not a reserved identifer, like R9 */
12392861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (Parse_String(parseState, "=")) {
12402861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorOrScalarConstant(parseState, value))
12412861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
12422861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
12432861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_String(parseState, ";"))
12442861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Expected ;");
12452861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (_mesa_lookup_parameter_index(parseState->parameters,
12462861e737e84e4884109b9526ac645194ba892a74Michal Krol                                          -1, (const char *) id) >= 0) {
12472861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR2(id, "already declared");
12482861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
12492861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_add_named_parameter(parseState->parameters,
12502861e737e84e4884109b9526ac645194ba892a74Michal Krol                                   (const char *) id, value);
12512861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
12522861e737e84e4884109b9526ac645194ba892a74Michal Krol      else if (Parse_String(parseState, "END")) {
12532861e737e84e4884109b9526ac645194ba892a74Michal Krol         inst->Opcode = FP_OPCODE_END;
12542861e737e84e4884109b9526ac645194ba892a74Michal Krol         inst->StringPos = parseState->curLine - parseState->start;
12552861e737e84e4884109b9526ac645194ba892a74Michal Krol         assert(inst->StringPos >= 0);
12562861e737e84e4884109b9526ac645194ba892a74Michal Krol         parseState->numInst++;
12572861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (Parse_Token(parseState, token)) {
12582861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Code after END opcode.");
12592861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
12602861e737e84e4884109b9526ac645194ba892a74Michal Krol         break;
12612861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
12622861e737e84e4884109b9526ac645194ba892a74Michal Krol      else {
12632861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* general/arithmetic instruction */
12642861e737e84e4884109b9526ac645194ba892a74Michal Krol
12652861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* get token */
12662861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_Token(parseState, token)) {
12672861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Missing END instruction.");
12682861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
12692861e737e84e4884109b9526ac645194ba892a74Michal Krol
12702861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* try to find matching instuction */
12712861e737e84e4884109b9526ac645194ba892a74Michal Krol         instMatch = MatchInstruction(token);
12722861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (instMatch.opcode < 0) {
12732861e737e84e4884109b9526ac645194ba892a74Michal Krol            /* bad instruction name */
12742861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR2("Unexpected token: ", token);
12752861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
12762861e737e84e4884109b9526ac645194ba892a74Michal Krol
12772861e737e84e4884109b9526ac645194ba892a74Michal Krol         inst->Opcode = instMatch.opcode;
12782861e737e84e4884109b9526ac645194ba892a74Michal Krol         inst->Precision = instMatch.suffixes & (_R | _H | _X);
12792861e737e84e4884109b9526ac645194ba892a74Michal Krol         inst->Saturate = (instMatch.suffixes & (_S)) ? GL_TRUE : GL_FALSE;
12802861e737e84e4884109b9526ac645194ba892a74Michal Krol         inst->UpdateCondRegister = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE;
12812861e737e84e4884109b9526ac645194ba892a74Michal Krol         inst->StringPos = parseState->curLine - parseState->start;
12822861e737e84e4884109b9526ac645194ba892a74Michal Krol         assert(inst->StringPos >= 0);
12832861e737e84e4884109b9526ac645194ba892a74Michal Krol
12842861e737e84e4884109b9526ac645194ba892a74Michal Krol         /*
12852861e737e84e4884109b9526ac645194ba892a74Michal Krol          * parse the input and output operands
12862861e737e84e4884109b9526ac645194ba892a74Michal Krol          */
12872861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (instMatch.outputs == OUTPUT_S || instMatch.outputs == OUTPUT_V) {
12882861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
12892861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
12902861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
12912861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
12922861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
12932861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.outputs == OUTPUT_NONE) {
12942861e737e84e4884109b9526ac645194ba892a74Michal Krol            ASSERT(instMatch.opcode == FP_OPCODE_KIL);
12952861e737e84e4884109b9526ac645194ba892a74Michal Krol            /* This is a little weird, the cond code info is in the dest register */
12962861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_CondCodeMask(parseState, &inst->DstReg))
12972861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
12982861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
12992861e737e84e4884109b9526ac645194ba892a74Michal Krol
13002861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (instMatch.inputs == INPUT_1V) {
13012861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
13022861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13032861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13042861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_2V) {
13052861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
13062861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13072861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
13082861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
13092861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
13102861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13112861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13122861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_3V) {
13132861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
13142861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13152861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
13162861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
13172861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
13182861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13192861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
13202861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
13212861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[2]))
13222861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13232861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13242861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_1S) {
13252861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
13262861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13272861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13282861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_2S) {
13292861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
13302861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13312861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
13322861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
13332861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[1]))
13342861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13352861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13362861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_CC) {
13372861e737e84e4884109b9526ac645194ba892a74Michal Krol            /* XXX to-do */
13382861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13392861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_1V_T) {
13402861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
13412861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13422861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
13432861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
13442861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_TextureImageId(parseState, &inst->TexSrcUnit,
13452861e737e84e4884109b9526ac645194ba892a74Michal Krol                                      &inst->TexSrcBit))
13462861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13472861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13482861e737e84e4884109b9526ac645194ba892a74Michal Krol         else if (instMatch.inputs == INPUT_3V_T) {
13492861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
13502861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13512861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
13522861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
13532861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
13542861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13552861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
13562861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
13572861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_VectorSrc(parseState, &inst->SrcReg[2]))
13582861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13592861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_String(parseState, ","))
13602861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR1("Expected ,");
13612861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (!Parse_TextureImageId(parseState, &inst->TexSrcUnit,
13622861e737e84e4884109b9526ac645194ba892a74Michal Krol                                      &inst->TexSrcBit))
13632861e737e84e4884109b9526ac645194ba892a74Michal Krol               RETURN_ERROR;
13642861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
13652861e737e84e4884109b9526ac645194ba892a74Michal Krol
13662861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* end of statement semicolon */
13672861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (!Parse_String(parseState, ";"))
13682861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Expected ;");
13692861e737e84e4884109b9526ac645194ba892a74Michal Krol
13702861e737e84e4884109b9526ac645194ba892a74Michal Krol         parseState->numInst++;
13712861e737e84e4884109b9526ac645194ba892a74Michal Krol
13722861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (parseState->numInst >= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS)
13732861e737e84e4884109b9526ac645194ba892a74Michal Krol            RETURN_ERROR1("Program too long");
13742861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
13752861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
13762861e737e84e4884109b9526ac645194ba892a74Michal Krol   return GL_TRUE;
13772861e737e84e4884109b9526ac645194ba892a74Michal Krol}
13782861e737e84e4884109b9526ac645194ba892a74Michal Krol
13792861e737e84e4884109b9526ac645194ba892a74Michal Krol
13802861e737e84e4884109b9526ac645194ba892a74Michal Krol
13812861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
13822861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse/compile the 'str' returning the compiled 'program'.
13832861e737e84e4884109b9526ac645194ba892a74Michal Krol * ctx->Program.ErrorPos will be -1 if successful.  Otherwise, ErrorPos
13842861e737e84e4884109b9526ac645194ba892a74Michal Krol * indicates the position of the error in 'str'.
13852861e737e84e4884109b9526ac645194ba892a74Michal Krol */
13862861e737e84e4884109b9526ac645194ba892a74Michal Krolvoid
13872861e737e84e4884109b9526ac645194ba892a74Michal Krol_mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,
13882861e737e84e4884109b9526ac645194ba892a74Michal Krol                                const GLubyte *str, GLsizei len,
13892861e737e84e4884109b9526ac645194ba892a74Michal Krol                                struct fragment_program *program)
13902861e737e84e4884109b9526ac645194ba892a74Michal Krol{
13912861e737e84e4884109b9526ac645194ba892a74Michal Krol   struct parse_state parseState;
13922861e737e84e4884109b9526ac645194ba892a74Michal Krol   struct fp_instruction instBuffer[MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS];
13932861e737e84e4884109b9526ac645194ba892a74Michal Krol   struct fp_instruction *newInst;
13942861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLenum target;
13952861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte *programString;
13962861e737e84e4884109b9526ac645194ba892a74Michal Krol
13972861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Make a null-terminated copy of the program string */
13982861e737e84e4884109b9526ac645194ba892a74Michal Krol   programString = (GLubyte *) MALLOC(len + 1);
13992861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!programString) {
14002861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
14012861e737e84e4884109b9526ac645194ba892a74Michal Krol      return;
14022861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
14032861e737e84e4884109b9526ac645194ba892a74Michal Krol   MEMCPY(programString, str, len);
14042861e737e84e4884109b9526ac645194ba892a74Michal Krol   programString[len] = 0;
14052861e737e84e4884109b9526ac645194ba892a74Michal Krol
14062861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Get ready to parse */
14072861e737e84e4884109b9526ac645194ba892a74Michal Krol   _mesa_bzero(&parseState, sizeof(struct parse_state));
14082861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.ctx = ctx;
14092861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.start = programString;
14102861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.program = program;
14112861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.numInst = 0;
14122861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.curLine = programString;
14132861e737e84e4884109b9526ac645194ba892a74Michal Krol   parseState.parameters = _mesa_new_parameter_list();
14142861e737e84e4884109b9526ac645194ba892a74Michal Krol
14152861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Reset error state */
14162861e737e84e4884109b9526ac645194ba892a74Michal Krol   _mesa_set_program_error(ctx, -1, NULL);
14172861e737e84e4884109b9526ac645194ba892a74Michal Krol
14182861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* check the program header */
14192861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (_mesa_strncmp((const char *) programString, "!!FP1.0", 7) == 0) {
14202861e737e84e4884109b9526ac645194ba892a74Michal Krol      target = GL_FRAGMENT_PROGRAM_NV;
14212861e737e84e4884109b9526ac645194ba892a74Michal Krol      parseState.pos = programString + 7;
14222861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
14232861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (_mesa_strncmp((const char *) programString, "!!FCP1.0", 8) == 0) {
14242861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* fragment / register combiner program - not supported */
14252861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_set_program_error(ctx, 0, "Invalid fragment program header");
14262861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
14272861e737e84e4884109b9526ac645194ba892a74Michal Krol      return;
14282861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
14292861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
14302861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* invalid header */
14312861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_set_program_error(ctx, 0, "Invalid fragment program header");
14322861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
14332861e737e84e4884109b9526ac645194ba892a74Michal Krol      return;
14342861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
14352861e737e84e4884109b9526ac645194ba892a74Michal Krol
14362861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* make sure target and header match */
14372861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (target != dstTarget) {
14382861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_error(ctx, GL_INVALID_OPERATION,
14392861e737e84e4884109b9526ac645194ba892a74Michal Krol                  "glLoadProgramNV(target mismatch 0x%x != 0x%x)",
14402861e737e84e4884109b9526ac645194ba892a74Michal Krol                  target, dstTarget);
14412861e737e84e4884109b9526ac645194ba892a74Michal Krol      return;
14422861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
14432861e737e84e4884109b9526ac645194ba892a74Michal Krol
14442861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (Parse_InstructionSequence(&parseState, instBuffer)) {
14452861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLuint u;
14462861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* successful parse! */
14472861e737e84e4884109b9526ac645194ba892a74Michal Krol
14482861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (parseState.outputsWritten == 0) {
14492861e737e84e4884109b9526ac645194ba892a74Michal Krol         /* must write at least one output! */
14502861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_error(ctx, GL_INVALID_OPERATION,
14512861e737e84e4884109b9526ac645194ba892a74Michal Krol                     "Invalid fragment program - no outputs written.");
14522861e737e84e4884109b9526ac645194ba892a74Michal Krol         return;
14532861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
14542861e737e84e4884109b9526ac645194ba892a74Michal Krol
14552861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* copy the compiled instructions */
14562861e737e84e4884109b9526ac645194ba892a74Michal Krol      assert(parseState.numInst <= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS);
14572861e737e84e4884109b9526ac645194ba892a74Michal Krol      newInst = (struct fp_instruction *)
14582861e737e84e4884109b9526ac645194ba892a74Michal Krol         MALLOC(parseState.numInst * sizeof(struct fp_instruction));
14592861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!newInst) {
14602861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
14612861e737e84e4884109b9526ac645194ba892a74Michal Krol         return;  /* out of memory */
14622861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
14632861e737e84e4884109b9526ac645194ba892a74Michal Krol      MEMCPY(newInst, instBuffer,
14642861e737e84e4884109b9526ac645194ba892a74Michal Krol             parseState.numInst * sizeof(struct fp_instruction));
14652861e737e84e4884109b9526ac645194ba892a74Michal Krol
14662861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* install the program */
14672861e737e84e4884109b9526ac645194ba892a74Michal Krol      program->Base.Target = target;
14682861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (program->Base.String) {
14692861e737e84e4884109b9526ac645194ba892a74Michal Krol         FREE(program->Base.String);
14702861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
14712861e737e84e4884109b9526ac645194ba892a74Michal Krol      program->Base.String = programString;
14722861e737e84e4884109b9526ac645194ba892a74Michal Krol      program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB;
14732861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (program->Instructions) {
14742861e737e84e4884109b9526ac645194ba892a74Michal Krol         FREE(program->Instructions);
14752861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
14762861e737e84e4884109b9526ac645194ba892a74Michal Krol      program->Instructions = newInst;
14772861e737e84e4884109b9526ac645194ba892a74Michal Krol      program->InputsRead = parseState.inputsRead;
14782861e737e84e4884109b9526ac645194ba892a74Michal Krol      program->OutputsWritten = parseState.outputsWritten;
14792861e737e84e4884109b9526ac645194ba892a74Michal Krol      for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++)
14802861e737e84e4884109b9526ac645194ba892a74Michal Krol         program->TexturesUsed[u] = parseState.texturesUsed[u];
14812861e737e84e4884109b9526ac645194ba892a74Michal Krol
14822861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* save program parameters */
14832861e737e84e4884109b9526ac645194ba892a74Michal Krol      program->Parameters = parseState.parameters;
14842861e737e84e4884109b9526ac645194ba892a74Michal Krol
14852861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* allocate registers for declared program parameters */
14862861e737e84e4884109b9526ac645194ba892a74Michal Krol#if 00
14872861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_assign_program_registers(&(program->SymbolTable));
14882861e737e84e4884109b9526ac645194ba892a74Michal Krol#endif
14892861e737e84e4884109b9526ac645194ba892a74Michal Krol
14902861e737e84e4884109b9526ac645194ba892a74Michal Krol#ifdef DEBUG
14912861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("--- glLoadProgramNV(%d) result ---\n", program->Base.Id);
14922861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_print_nv_fragment_program(program);
14932861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("----------------------------------\n");
14942861e737e84e4884109b9526ac645194ba892a74Michal Krol#endif
14952861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
14962861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
14972861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* Error! */
14982861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV");
14992861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* NOTE: _mesa_set_program_error would have been called already */
15002861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15012861e737e84e4884109b9526ac645194ba892a74Michal Krol}
15022861e737e84e4884109b9526ac645194ba892a74Michal Krol
15032861e737e84e4884109b9526ac645194ba892a74Michal Krol
15042861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void
15052861e737e84e4884109b9526ac645194ba892a74Michal KrolPrintSrcReg(const struct fragment_program *program,
15062861e737e84e4884109b9526ac645194ba892a74Michal Krol            const struct fp_src_register *src)
15072861e737e84e4884109b9526ac645194ba892a74Michal Krol{
15082861e737e84e4884109b9526ac645194ba892a74Michal Krol   static const char comps[5] = "xyzw";
15092861e737e84e4884109b9526ac645194ba892a74Michal Krol
15102861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (src->NegateAbs) {
15112861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("-");
15122861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15132861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (src->Abs) {
15142861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("|");
15152861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15162861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (src->NegateBase) {
15172861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("-");
15182861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15192861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (src->File == PROGRAM_NAMED_PARAM) {
15202861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (program->Parameters->Parameters[src->Index].Type == CONSTANT) {
15212861e737e84e4884109b9526ac645194ba892a74Michal Krol         printf("{%g, %g, %g, %g}",
15222861e737e84e4884109b9526ac645194ba892a74Michal Krol                program->Parameters->Parameters[src->Index].Values[0],
15232861e737e84e4884109b9526ac645194ba892a74Michal Krol                program->Parameters->Parameters[src->Index].Values[1],
15242861e737e84e4884109b9526ac645194ba892a74Michal Krol                program->Parameters->Parameters[src->Index].Values[2],
15252861e737e84e4884109b9526ac645194ba892a74Michal Krol                program->Parameters->Parameters[src->Index].Values[3]);
15262861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
15272861e737e84e4884109b9526ac645194ba892a74Michal Krol      else {
15282861e737e84e4884109b9526ac645194ba892a74Michal Krol         ASSERT(program->Parameters->Parameters[src->Index].Type
15292861e737e84e4884109b9526ac645194ba892a74Michal Krol                == NAMED_PARAMETER);
15302861e737e84e4884109b9526ac645194ba892a74Michal Krol         printf("%s", program->Parameters->Parameters[src->Index].Name);
15312861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
15322861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15332861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (src->File == PROGRAM_OUTPUT) {
15342861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("o[%s]", OutputRegisters[src->Index]);
15352861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15362861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (src->File == PROGRAM_INPUT) {
15372861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("f[%s]", InputRegisters[src->Index]);
15382861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15392861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (src->File == PROGRAM_LOCAL_PARAM) {
15402861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("p[%d]", src->Index);
15412861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15422861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (src->File == PROGRAM_TEMPORARY) {
15432861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (src->Index >= 32)
15442861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_printf("H%d", src->Index);
15452861e737e84e4884109b9526ac645194ba892a74Michal Krol      else
15462861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_printf("R%d", src->Index);
15472861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15482861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (src->File == PROGRAM_WRITE_ONLY) {
15492861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("%cC", "HR"[src->Index]);
15502861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15512861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
15522861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_problem(NULL, "Invalid fragment register %d", src->Index);
15532861e737e84e4884109b9526ac645194ba892a74Michal Krol      return;
15542861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15552861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (src->Swizzle[0] == src->Swizzle[1] &&
15562861e737e84e4884109b9526ac645194ba892a74Michal Krol       src->Swizzle[0] == src->Swizzle[2] &&
15572861e737e84e4884109b9526ac645194ba892a74Michal Krol       src->Swizzle[0] == src->Swizzle[3]) {
15582861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf(".%c", comps[src->Swizzle[0]]);
15592861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15602861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (src->Swizzle[0] != 0 ||
15612861e737e84e4884109b9526ac645194ba892a74Michal Krol            src->Swizzle[1] != 1 ||
15622861e737e84e4884109b9526ac645194ba892a74Michal Krol            src->Swizzle[2] != 2 ||
15632861e737e84e4884109b9526ac645194ba892a74Michal Krol            src->Swizzle[3] != 3) {
15642861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf(".%c%c%c%c",
15652861e737e84e4884109b9526ac645194ba892a74Michal Krol                   comps[src->Swizzle[0]],
15662861e737e84e4884109b9526ac645194ba892a74Michal Krol                   comps[src->Swizzle[1]],
15672861e737e84e4884109b9526ac645194ba892a74Michal Krol                   comps[src->Swizzle[2]],
15682861e737e84e4884109b9526ac645194ba892a74Michal Krol                   comps[src->Swizzle[3]]);
15692861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15702861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (src->Abs) {
15712861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("|");
15722861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15732861e737e84e4884109b9526ac645194ba892a74Michal Krol}
15742861e737e84e4884109b9526ac645194ba892a74Michal Krol
15752861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void
15762861e737e84e4884109b9526ac645194ba892a74Michal KrolPrintTextureSrc(const struct fp_instruction *inst)
15772861e737e84e4884109b9526ac645194ba892a74Michal Krol{
15782861e737e84e4884109b9526ac645194ba892a74Michal Krol   _mesa_printf("TEX%d, ", inst->TexSrcUnit);
15792861e737e84e4884109b9526ac645194ba892a74Michal Krol   switch (inst->TexSrcBit) {
15802861e737e84e4884109b9526ac645194ba892a74Michal Krol   case TEXTURE_1D_BIT:
15812861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("1D");
15822861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
15832861e737e84e4884109b9526ac645194ba892a74Michal Krol   case TEXTURE_2D_BIT:
15842861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("2D");
15852861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
15862861e737e84e4884109b9526ac645194ba892a74Michal Krol   case TEXTURE_3D_BIT:
15872861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("3D");
15882861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
15892861e737e84e4884109b9526ac645194ba892a74Michal Krol   case TEXTURE_RECT_BIT:
15902861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("RECT");
15912861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
15922861e737e84e4884109b9526ac645194ba892a74Michal Krol   case TEXTURE_CUBE_BIT:
15932861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("CUBE");
15942861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
15952861e737e84e4884109b9526ac645194ba892a74Michal Krol   default:
15962861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_problem(NULL, "Invalid textue target in PrintTextureSrc");
15972861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
15982861e737e84e4884109b9526ac645194ba892a74Michal Krol}
15992861e737e84e4884109b9526ac645194ba892a74Michal Krol
16002861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void
16012861e737e84e4884109b9526ac645194ba892a74Michal KrolPrintCondCode(const struct fp_dst_register *dst)
16022861e737e84e4884109b9526ac645194ba892a74Michal Krol{
16032861e737e84e4884109b9526ac645194ba892a74Michal Krol   static const char *comps = "xyzw";
16042861e737e84e4884109b9526ac645194ba892a74Michal Krol   static const char *ccString[] = {
16052861e737e84e4884109b9526ac645194ba892a74Michal Krol      "??", "GT", "EQ", "LT", "UN", "GE", "LE", "NE", "TR", "FL", "??"
16062861e737e84e4884109b9526ac645194ba892a74Michal Krol   };
16072861e737e84e4884109b9526ac645194ba892a74Michal Krol
16082861e737e84e4884109b9526ac645194ba892a74Michal Krol   _mesa_printf("%s", ccString[dst->CondMask]);
16092861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (dst->CondSwizzle[0] == dst->CondSwizzle[1] &&
16102861e737e84e4884109b9526ac645194ba892a74Michal Krol       dst->CondSwizzle[0] == dst->CondSwizzle[2] &&
16112861e737e84e4884109b9526ac645194ba892a74Michal Krol       dst->CondSwizzle[0] == dst->CondSwizzle[3]) {
16122861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf(".%c", comps[dst->CondSwizzle[0]]);
16132861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
16142861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (dst->CondSwizzle[0] != 0 ||
16152861e737e84e4884109b9526ac645194ba892a74Michal Krol            dst->CondSwizzle[1] != 1 ||
16162861e737e84e4884109b9526ac645194ba892a74Michal Krol            dst->CondSwizzle[2] != 2 ||
16172861e737e84e4884109b9526ac645194ba892a74Michal Krol            dst->CondSwizzle[3] != 3) {
16182861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf(".%c%c%c%c",
16192861e737e84e4884109b9526ac645194ba892a74Michal Krol                   comps[dst->CondSwizzle[0]],
16202861e737e84e4884109b9526ac645194ba892a74Michal Krol                   comps[dst->CondSwizzle[1]],
16212861e737e84e4884109b9526ac645194ba892a74Michal Krol                   comps[dst->CondSwizzle[2]],
16222861e737e84e4884109b9526ac645194ba892a74Michal Krol                   comps[dst->CondSwizzle[3]]);
16232861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
16242861e737e84e4884109b9526ac645194ba892a74Michal Krol}
16252861e737e84e4884109b9526ac645194ba892a74Michal Krol
16262861e737e84e4884109b9526ac645194ba892a74Michal Krol
16272861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void
16282861e737e84e4884109b9526ac645194ba892a74Michal KrolPrintDstReg(const struct fp_dst_register *dst)
16292861e737e84e4884109b9526ac645194ba892a74Michal Krol{
16302861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLint w = dst->WriteMask[0] + dst->WriteMask[1]
16312861e737e84e4884109b9526ac645194ba892a74Michal Krol           + dst->WriteMask[2] + dst->WriteMask[3];
16322861e737e84e4884109b9526ac645194ba892a74Michal Krol
16332861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (dst->File == PROGRAM_OUTPUT) {
16342861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("o[%s]", OutputRegisters[dst->Index]);
16352861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
16362861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (dst->File == PROGRAM_TEMPORARY) {
16372861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (dst->Index >= 32)
16382861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_printf("H%d", dst->Index);
16392861e737e84e4884109b9526ac645194ba892a74Michal Krol      else
16402861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_printf("R%d", dst->Index);
16412861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
16422861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (dst->File == PROGRAM_LOCAL_PARAM) {
16432861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("p[%d]", dst->Index);
16442861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
16452861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (dst->File == PROGRAM_WRITE_ONLY) {
16462861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("%cC", "HR"[dst->Index]);
16472861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
16482861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
16492861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf("???");
16502861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
16512861e737e84e4884109b9526ac645194ba892a74Michal Krol
16522861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (w != 0 && w != 4) {
16532861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf(".");
16542861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (dst->WriteMask[0])
16552861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_printf("x");
16562861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (dst->WriteMask[1])
16572861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_printf("y");
16582861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (dst->WriteMask[2])
16592861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_printf("z");
16602861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (dst->WriteMask[3])
16612861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_printf("w");
16622861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
16632861e737e84e4884109b9526ac645194ba892a74Michal Krol
16642861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (dst->CondMask != COND_TR ||
16652861e737e84e4884109b9526ac645194ba892a74Michal Krol       dst->CondSwizzle[0] != 0 ||
16662861e737e84e4884109b9526ac645194ba892a74Michal Krol       dst->CondSwizzle[1] != 1 ||
16672861e737e84e4884109b9526ac645194ba892a74Michal Krol       dst->CondSwizzle[2] != 2 ||
16682861e737e84e4884109b9526ac645194ba892a74Michal Krol       dst->CondSwizzle[3] != 3) {
16692861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf(" (");
16702861e737e84e4884109b9526ac645194ba892a74Michal Krol      PrintCondCode(dst);
16712861e737e84e4884109b9526ac645194ba892a74Michal Krol      _mesa_printf(")");
16722861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
16732861e737e84e4884109b9526ac645194ba892a74Michal Krol}
16742861e737e84e4884109b9526ac645194ba892a74Michal Krol
16752861e737e84e4884109b9526ac645194ba892a74Michal Krol
16762861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
16772861e737e84e4884109b9526ac645194ba892a74Michal Krol * Print (unparse) the given vertex program.  Just for debugging.
16782861e737e84e4884109b9526ac645194ba892a74Michal Krol */
16792861e737e84e4884109b9526ac645194ba892a74Michal Krolvoid
16802861e737e84e4884109b9526ac645194ba892a74Michal Krol_mesa_print_nv_fragment_program(const struct fragment_program *program)
16812861e737e84e4884109b9526ac645194ba892a74Michal Krol{
16822861e737e84e4884109b9526ac645194ba892a74Michal Krol   const struct fp_instruction *inst;
16832861e737e84e4884109b9526ac645194ba892a74Michal Krol
16842861e737e84e4884109b9526ac645194ba892a74Michal Krol   for (inst = program->Instructions; inst->Opcode != FP_OPCODE_END; inst++) {
16852861e737e84e4884109b9526ac645194ba892a74Michal Krol      int i;
16862861e737e84e4884109b9526ac645194ba892a74Michal Krol      for (i = 0; Instructions[i].name; i++) {
16872861e737e84e4884109b9526ac645194ba892a74Michal Krol         if (inst->Opcode == Instructions[i].opcode) {
16882861e737e84e4884109b9526ac645194ba892a74Michal Krol            /* print instruction name */
16892861e737e84e4884109b9526ac645194ba892a74Michal Krol            _mesa_printf("%s", Instructions[i].name);
16902861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (inst->Precision == FLOAT16)
16912861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf("H");
16922861e737e84e4884109b9526ac645194ba892a74Michal Krol            else if (inst->Precision == FIXED12)
16932861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf("X");
16942861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (inst->UpdateCondRegister)
16952861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf("C");
16962861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (inst->Saturate)
16972861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf("_SAT");
16982861e737e84e4884109b9526ac645194ba892a74Michal Krol            _mesa_printf(" ");
16992861e737e84e4884109b9526ac645194ba892a74Michal Krol
17002861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (Instructions[i].inputs == INPUT_CC) {
17012861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintCondCode(&inst->DstReg);
17022861e737e84e4884109b9526ac645194ba892a74Michal Krol            }
17032861e737e84e4884109b9526ac645194ba892a74Michal Krol            else if (Instructions[i].outputs == OUTPUT_V ||
17042861e737e84e4884109b9526ac645194ba892a74Michal Krol                     Instructions[i].outputs == OUTPUT_S) {
17052861e737e84e4884109b9526ac645194ba892a74Michal Krol               /* print dest register */
17062861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintDstReg(&inst->DstReg);
17072861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf(", ");
17082861e737e84e4884109b9526ac645194ba892a74Michal Krol            }
17092861e737e84e4884109b9526ac645194ba892a74Michal Krol
17102861e737e84e4884109b9526ac645194ba892a74Michal Krol            /* print source register(s) */
17112861e737e84e4884109b9526ac645194ba892a74Michal Krol            if (Instructions[i].inputs == INPUT_1V ||
17122861e737e84e4884109b9526ac645194ba892a74Michal Krol                Instructions[i].inputs == INPUT_1S) {
17132861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintSrcReg(program, &inst->SrcReg[0]);
17142861e737e84e4884109b9526ac645194ba892a74Michal Krol            }
17152861e737e84e4884109b9526ac645194ba892a74Michal Krol            else if (Instructions[i].inputs == INPUT_2V ||
17162861e737e84e4884109b9526ac645194ba892a74Michal Krol                     Instructions[i].inputs == INPUT_2S) {
17172861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintSrcReg(program, &inst->SrcReg[0]);
17182861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf(", ");
17192861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintSrcReg(program, &inst->SrcReg[1]);
17202861e737e84e4884109b9526ac645194ba892a74Michal Krol            }
17212861e737e84e4884109b9526ac645194ba892a74Michal Krol            else if (Instructions[i].inputs == INPUT_3V) {
17222861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintSrcReg(program, &inst->SrcReg[0]);
17232861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf(", ");
17242861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintSrcReg(program, &inst->SrcReg[1]);
17252861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf(", ");
17262861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintSrcReg(program, &inst->SrcReg[2]);
17272861e737e84e4884109b9526ac645194ba892a74Michal Krol            }
17282861e737e84e4884109b9526ac645194ba892a74Michal Krol            else if (Instructions[i].inputs == INPUT_1V_T) {
17292861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintSrcReg(program, &inst->SrcReg[0]);
17302861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf(", ");
17312861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintTextureSrc(inst);
17322861e737e84e4884109b9526ac645194ba892a74Michal Krol            }
17332861e737e84e4884109b9526ac645194ba892a74Michal Krol            else if (Instructions[i].inputs == INPUT_3V_T) {
17342861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintSrcReg(program, &inst->SrcReg[0]);
17352861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf(", ");
17362861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintSrcReg(program, &inst->SrcReg[1]);
17372861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf(", ");
17382861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintSrcReg(program, &inst->SrcReg[2]);
17392861e737e84e4884109b9526ac645194ba892a74Michal Krol               _mesa_printf(", ");
17402861e737e84e4884109b9526ac645194ba892a74Michal Krol               PrintTextureSrc(inst);
17412861e737e84e4884109b9526ac645194ba892a74Michal Krol            }
17422861e737e84e4884109b9526ac645194ba892a74Michal Krol            _mesa_printf(";\n");
17432861e737e84e4884109b9526ac645194ba892a74Michal Krol            break;
17442861e737e84e4884109b9526ac645194ba892a74Michal Krol         }
17452861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
17462861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (!Instructions[i].name) {
17472861e737e84e4884109b9526ac645194ba892a74Michal Krol         _mesa_printf("Invalid opcode %d\n", inst->Opcode);
17482861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
17492861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
17502861e737e84e4884109b9526ac645194ba892a74Michal Krol   _mesa_printf("END\n");
17512861e737e84e4884109b9526ac645194ba892a74Michal Krol}
17522861e737e84e4884109b9526ac645194ba892a74Michal Krol
17532861e737e84e4884109b9526ac645194ba892a74Michal Krol
17542861e737e84e4884109b9526ac645194ba892a74Michal Krolconst char *
17552861e737e84e4884109b9526ac645194ba892a74Michal Krol_mesa_nv_fragment_input_register_name(GLuint i)
17562861e737e84e4884109b9526ac645194ba892a74Michal Krol{
17572861e737e84e4884109b9526ac645194ba892a74Michal Krol   ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_INPUTS);
17582861e737e84e4884109b9526ac645194ba892a74Michal Krol   return InputRegisters[i];
17592861e737e84e4884109b9526ac645194ba892a74Michal Krol}
17602861e737e84e4884109b9526ac645194ba892a74Michal Krol
17612861e737e84e4884109b9526ac645194ba892a74Michal Krol
17622861e737e84e4884109b9526ac645194ba892a74Michal Krolconst char *
17632861e737e84e4884109b9526ac645194ba892a74Michal Krol_mesa_nv_fragment_output_register_name(GLuint i)
17642861e737e84e4884109b9526ac645194ba892a74Michal Krol{
17652861e737e84e4884109b9526ac645194ba892a74Michal Krol   ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_OUTPUTS);
17662861e737e84e4884109b9526ac645194ba892a74Michal Krol   return OutputRegisters[i];
17672861e737e84e4884109b9526ac645194ba892a74Michal Krol}
1768