Home | History | Annotate | Download | only in program
      1 %{
      2 /*
      3  * Copyright  2009 Intel Corporation
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the "Software"),
      7  * to deal in the Software without restriction, including without limitation
      8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      9  * and/or sell copies of the Software, and to permit persons to whom the
     10  * Software is furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice (including the next
     13  * paragraph) shall be included in all copies or substantial portions of the
     14  * Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     22  * DEALINGS IN THE SOFTWARE.
     23  */
     24 #include <stdio.h>
     25 #include <stdlib.h>
     26 #include <string.h>
     27 
     28 #include "main/mtypes.h"
     29 #include "main/imports.h"
     30 #include "program/program.h"
     31 #include "program/prog_parameter.h"
     32 #include "program/prog_parameter_layout.h"
     33 #include "program/prog_statevars.h"
     34 #include "program/prog_instruction.h"
     35 
     36 #include "program/symbol_table.h"
     37 #include "program/program_parser.h"
     38 
     39 extern void *yy_scan_string(char *);
     40 extern void yy_delete_buffer(void *);
     41 
     42 static struct asm_symbol *declare_variable(struct asm_parser_state *state,
     43     char *name, enum asm_type t, struct YYLTYPE *locp);
     44 
     45 static int add_state_reference(struct gl_program_parameter_list *param_list,
     46     const gl_state_index tokens[STATE_LENGTH]);
     47 
     48 static int initialize_symbol_from_state(struct gl_program *prog,
     49     struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
     50 
     51 static int initialize_symbol_from_param(struct gl_program *prog,
     52     struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
     53 
     54 static int initialize_symbol_from_const(struct gl_program *prog,
     55     struct asm_symbol *param_var, const struct asm_vector *vec,
     56     GLboolean allowSwizzle);
     57 
     58 static int yyparse(struct asm_parser_state *state);
     59 
     60 static char *make_error_string(const char *fmt, ...);
     61 
     62 static void yyerror(struct YYLTYPE *locp, struct asm_parser_state *state,
     63     const char *s);
     64 
     65 static int validate_inputs(struct YYLTYPE *locp,
     66     struct asm_parser_state *state);
     67 
     68 static void init_dst_reg(struct prog_dst_register *r);
     69 
     70 static void set_dst_reg(struct prog_dst_register *r,
     71                         gl_register_file file, GLint index);
     72 
     73 static void init_src_reg(struct asm_src_register *r);
     74 
     75 static void set_src_reg(struct asm_src_register *r,
     76                         gl_register_file file, GLint index);
     77 
     78 static void set_src_reg_swz(struct asm_src_register *r,
     79                             gl_register_file file, GLint index, GLuint swizzle);
     80 
     81 static void asm_instruction_set_operands(struct asm_instruction *inst,
     82     const struct prog_dst_register *dst, const struct asm_src_register *src0,
     83     const struct asm_src_register *src1, const struct asm_src_register *src2);
     84 
     85 static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op,
     86     const struct prog_dst_register *dst, const struct asm_src_register *src0,
     87     const struct asm_src_register *src1, const struct asm_src_register *src2);
     88 
     89 static struct asm_instruction *asm_instruction_copy_ctor(
     90     const struct prog_instruction *base, const struct prog_dst_register *dst,
     91     const struct asm_src_register *src0, const struct asm_src_register *src1,
     92     const struct asm_src_register *src2);
     93 
     94 #ifndef FALSE
     95 #define FALSE 0
     96 #define TRUE (!FALSE)
     97 #endif
     98 
     99 #define YYLLOC_DEFAULT(Current, Rhs, N)					\
    100    do {									\
    101       if (YYID(N)) {							\
    102 	 (Current).first_line = YYRHSLOC(Rhs, 1).first_line;		\
    103 	 (Current).first_column = YYRHSLOC(Rhs, 1).first_column;	\
    104 	 (Current).position = YYRHSLOC(Rhs, 1).position;		\
    105 	 (Current).last_line = YYRHSLOC(Rhs, N).last_line;		\
    106 	 (Current).last_column = YYRHSLOC(Rhs, N).last_column;		\
    107       } else {								\
    108 	 (Current).first_line = YYRHSLOC(Rhs, 0).last_line;		\
    109 	 (Current).last_line = (Current).first_line;			\
    110 	 (Current).first_column = YYRHSLOC(Rhs, 0).last_column;		\
    111 	 (Current).last_column = (Current).first_column;		\
    112 	 (Current).position = YYRHSLOC(Rhs, 0).position			\
    113 	    + (Current).first_column;					\
    114       }									\
    115    } while(YYID(0))
    116 
    117 #define YYLEX_PARAM state->scanner
    118 %}
    119 
    120 %pure-parser
    121 %locations
    122 %parse-param { struct asm_parser_state *state }
    123 %error-verbose
    124 %lex-param { void *scanner }
    125 
    126 %union {
    127    struct asm_instruction *inst;
    128    struct asm_symbol *sym;
    129    struct asm_symbol temp_sym;
    130    struct asm_swizzle_mask swiz_mask;
    131    struct asm_src_register src_reg;
    132    struct prog_dst_register dst_reg;
    133    struct prog_instruction temp_inst;
    134    char *string;
    135    unsigned result;
    136    unsigned attrib;
    137    int integer;
    138    float real;
    139    gl_state_index state[STATE_LENGTH];
    140    int negate;
    141    struct asm_vector vector;
    142    gl_inst_opcode opcode;
    143 
    144    struct {
    145       unsigned swz;
    146       unsigned rgba_valid:1;
    147       unsigned xyzw_valid:1;
    148       unsigned negate:1;
    149    } ext_swizzle;
    150 }
    151 
    152 %token ARBvp_10 ARBfp_10
    153 
    154 /* Tokens for assembler pseudo-ops */
    155 %token <integer> ADDRESS
    156 %token ALIAS ATTRIB
    157 %token OPTION OUTPUT
    158 %token PARAM
    159 %token <integer> TEMP
    160 %token END
    161 
    162  /* Tokens for instructions */
    163 %token <temp_inst> BIN_OP BINSC_OP SAMPLE_OP SCALAR_OP TRI_OP VECTOR_OP
    164 %token <temp_inst> ARL KIL SWZ TXD_OP
    165 
    166 %token <integer> INTEGER
    167 %token <real> REAL
    168 
    169 %token AMBIENT ATTENUATION
    170 %token BACK
    171 %token CLIP COLOR
    172 %token DEPTH DIFFUSE DIRECTION
    173 %token EMISSION ENV EYE
    174 %token FOG FOGCOORD FRAGMENT FRONT
    175 %token HALF
    176 %token INVERSE INVTRANS
    177 %token LIGHT LIGHTMODEL LIGHTPROD LOCAL
    178 %token MATERIAL MAT_PROGRAM MATRIX MATRIXINDEX MODELVIEW MVP
    179 %token NORMAL
    180 %token OBJECT
    181 %token PALETTE PARAMS PLANE POINT_TOK POINTSIZE POSITION PRIMARY PROGRAM PROJECTION
    182 %token RANGE RESULT ROW
    183 %token SCENECOLOR SECONDARY SHININESS SIZE_TOK SPECULAR SPOT STATE
    184 %token TEXCOORD TEXENV TEXGEN TEXGEN_Q TEXGEN_R TEXGEN_S TEXGEN_T TEXTURE TRANSPOSE
    185 %token TEXTURE_UNIT TEX_1D TEX_2D TEX_3D TEX_CUBE TEX_RECT
    186 %token TEX_SHADOW1D TEX_SHADOW2D TEX_SHADOWRECT
    187 %token TEX_ARRAY1D TEX_ARRAY2D TEX_ARRAYSHADOW1D TEX_ARRAYSHADOW2D
    188 %token VERTEX VTXATTRIB
    189 %token WEIGHT
    190 
    191 %token <string> IDENTIFIER USED_IDENTIFIER
    192 %type <string> string
    193 %token <swiz_mask> MASK4 MASK3 MASK2 MASK1 SWIZZLE
    194 %token DOT_DOT
    195 %token DOT
    196 
    197 %type <inst> instruction ALU_instruction TexInstruction
    198 %type <inst> ARL_instruction VECTORop_instruction
    199 %type <inst> SCALARop_instruction BINSCop_instruction BINop_instruction
    200 %type <inst> TRIop_instruction TXD_instruction SWZ_instruction SAMPLE_instruction
    201 %type <inst> KIL_instruction
    202 
    203 %type <dst_reg> dstReg maskedDstReg maskedAddrReg
    204 %type <src_reg> srcReg scalarUse scalarSrcReg swizzleSrcReg
    205 %type <swiz_mask> scalarSuffix swizzleSuffix extendedSwizzle
    206 %type <ext_swizzle> extSwizComp extSwizSel
    207 %type <swiz_mask> optionalMask
    208 
    209 %type <sym> progParamArray
    210 %type <integer> addrRegRelOffset addrRegPosOffset addrRegNegOffset
    211 %type <src_reg> progParamArrayMem progParamArrayAbs progParamArrayRel
    212 %type <sym> addrReg
    213 %type <swiz_mask> addrComponent addrWriteMask
    214 
    215 %type <dst_reg> ccMaskRule ccTest ccMaskRule2 ccTest2 optionalCcMask
    216 
    217 %type <result> resultBinding resultColBinding
    218 %type <integer> optFaceType optColorType
    219 %type <integer> optResultFaceType optResultColorType
    220 
    221 %type <integer> optTexImageUnitNum texImageUnitNum
    222 %type <integer> optTexCoordUnitNum texCoordUnitNum
    223 %type <integer> optLegacyTexUnitNum legacyTexUnitNum
    224 %type <integer> texImageUnit texTarget
    225 %type <integer> vtxAttribNum
    226 
    227 %type <attrib> attribBinding vtxAttribItem fragAttribItem
    228 
    229 %type <temp_sym> paramSingleInit paramSingleItemDecl
    230 %type <integer> optArraySize
    231 
    232 %type <state> stateSingleItem stateMultipleItem
    233 %type <state> stateMaterialItem
    234 %type <state> stateLightItem stateLightModelItem stateLightProdItem
    235 %type <state> stateTexGenItem stateFogItem stateClipPlaneItem statePointItem
    236 %type <state> stateMatrixItem stateMatrixRow stateMatrixRows
    237 %type <state> stateTexEnvItem stateDepthItem
    238 
    239 %type <state> stateLModProperty
    240 %type <state> stateMatrixName optMatrixRows
    241 
    242 %type <integer> stateMatProperty
    243 %type <integer> stateLightProperty stateSpotProperty
    244 %type <integer> stateLightNumber stateLProdProperty
    245 %type <integer> stateTexGenType stateTexGenCoord
    246 %type <integer> stateTexEnvProperty
    247 %type <integer> stateFogProperty
    248 %type <integer> stateClipPlaneNum
    249 %type <integer> statePointProperty
    250 
    251 %type <integer> stateOptMatModifier stateMatModifier stateMatrixRowNum
    252 %type <integer> stateOptModMatNum stateModMatNum statePaletteMatNum
    253 %type <integer> stateProgramMatNum
    254 
    255 %type <integer> ambDiffSpecProperty
    256 
    257 %type <state> programSingleItem progEnvParam progLocalParam
    258 %type <state> programMultipleItem progEnvParams progLocalParams
    259 
    260 %type <temp_sym> paramMultipleInit paramMultInitList paramMultipleItem
    261 %type <temp_sym> paramSingleItemUse
    262 
    263 %type <integer> progEnvParamNum progLocalParamNum
    264 %type <state> progEnvParamNums progLocalParamNums
    265 
    266 %type <vector> paramConstDecl paramConstUse
    267 %type <vector> paramConstScalarDecl paramConstScalarUse paramConstVector
    268 %type <real> signedFloatConstant
    269 %type <negate> optionalSign
    270 
    271 %{
    272 extern int yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
    273     void *yyscanner);
    274 %}
    275 
    276 %%
    277 
    278 program: language optionSequence statementSequence END
    279 	;
    280 
    281 language: ARBvp_10
    282 	{
    283 	   if (state->prog->Target != GL_VERTEX_PROGRAM_ARB) {
    284 	      yyerror(& @1, state, "invalid fragment program header");
    285 
    286 	   }
    287 	   state->mode = ARB_vertex;
    288 	}
    289 	| ARBfp_10
    290 	{
    291 	   if (state->prog->Target != GL_FRAGMENT_PROGRAM_ARB) {
    292 	      yyerror(& @1, state, "invalid vertex program header");
    293 	   }
    294 	   state->mode = ARB_fragment;
    295 
    296 	   state->option.TexRect =
    297 	      (state->ctx->Extensions.NV_texture_rectangle != GL_FALSE);
    298 	}
    299 	;
    300 
    301 optionSequence: optionSequence option
    302 	|
    303 	;
    304 
    305 option: OPTION string ';'
    306 	{
    307 	   int valid = 0;
    308 
    309 	   if (state->mode == ARB_vertex) {
    310 	      valid = _mesa_ARBvp_parse_option(state, $2);
    311 	   } else if (state->mode == ARB_fragment) {
    312 	      valid = _mesa_ARBfp_parse_option(state, $2);
    313 	   }
    314 
    315 
    316 	   free($2);
    317 
    318 	   if (!valid) {
    319 	      const char *const err_str = (state->mode == ARB_vertex)
    320 		 ? "invalid ARB vertex program option"
    321 		 : "invalid ARB fragment program option";
    322 
    323 	      yyerror(& @2, state, err_str);
    324 	      YYERROR;
    325 	   }
    326 	}
    327 	;
    328 
    329 statementSequence: statementSequence statement
    330 	|
    331 	;
    332 
    333 statement: instruction ';'
    334 	{
    335 	   if ($1 != NULL) {
    336 	      if (state->inst_tail == NULL) {
    337 		 state->inst_head = $1;
    338 	      } else {
    339 		 state->inst_tail->next = $1;
    340 	      }
    341 
    342 	      state->inst_tail = $1;
    343 	      $1->next = NULL;
    344 
    345 	      state->prog->NumInstructions++;
    346 	   }
    347 	}
    348 	| namingStatement ';'
    349 	;
    350 
    351 instruction: ALU_instruction
    352 	{
    353 	   $$ = $1;
    354 	   state->prog->NumAluInstructions++;
    355 	}
    356 	| TexInstruction
    357 	{
    358 	   $$ = $1;
    359 	   state->prog->NumTexInstructions++;
    360 	}
    361 	;
    362 
    363 ALU_instruction: ARL_instruction
    364 	| VECTORop_instruction
    365 	| SCALARop_instruction
    366 	| BINSCop_instruction
    367 	| BINop_instruction
    368 	| TRIop_instruction
    369 	| SWZ_instruction
    370 	;
    371 
    372 TexInstruction: SAMPLE_instruction
    373 	| KIL_instruction
    374 	| TXD_instruction
    375 	;
    376 
    377 ARL_instruction: ARL maskedAddrReg ',' scalarSrcReg
    378 	{
    379 	   $$ = asm_instruction_ctor(OPCODE_ARL, & $2, & $4, NULL, NULL);
    380 	}
    381 	;
    382 
    383 VECTORop_instruction: VECTOR_OP maskedDstReg ',' swizzleSrcReg
    384 	{
    385 	   if ($1.Opcode == OPCODE_DDY)
    386 	      state->fragment.UsesDFdy = 1;
    387 	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
    388 	}
    389 	;
    390 
    391 SCALARop_instruction: SCALAR_OP maskedDstReg ',' scalarSrcReg
    392 	{
    393 	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
    394 	}
    395 	;
    396 
    397 BINSCop_instruction: BINSC_OP maskedDstReg ',' scalarSrcReg ',' scalarSrcReg
    398 	{
    399 	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL);
    400 	}
    401 	;
    402 
    403 
    404 BINop_instruction: BIN_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg
    405 	{
    406 	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL);
    407 	}
    408 	;
    409 
    410 TRIop_instruction: TRI_OP maskedDstReg ','
    411                    swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg
    412 	{
    413 	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8);
    414 	}
    415 	;
    416 
    417 SAMPLE_instruction: SAMPLE_OP maskedDstReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget
    418 	{
    419 	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
    420 	   if ($$ != NULL) {
    421 	      const GLbitfield tex_mask = (1U << $6);
    422 	      GLbitfield shadow_tex = 0;
    423 	      GLbitfield target_mask = 0;
    424 
    425 
    426 	      $$->Base.TexSrcUnit = $6;
    427 
    428 	      if ($8 < 0) {
    429 		 shadow_tex = tex_mask;
    430 
    431 		 $$->Base.TexSrcTarget = -$8;
    432 		 $$->Base.TexShadow = 1;
    433 	      } else {
    434 		 $$->Base.TexSrcTarget = $8;
    435 	      }
    436 
    437 	      target_mask = (1U << $$->Base.TexSrcTarget);
    438 
    439 	      /* If this texture unit was previously accessed and that access
    440 	       * had a different texture target, generate an error.
    441 	       *
    442 	       * If this texture unit was previously accessed and that access
    443 	       * had a different shadow mode, generate an error.
    444 	       */
    445 	      if ((state->prog->TexturesUsed[$6] != 0)
    446 		  && ((state->prog->TexturesUsed[$6] != target_mask)
    447 		      || ((state->prog->ShadowSamplers & tex_mask)
    448 			  != shadow_tex))) {
    449 		 yyerror(& @8, state,
    450 			 "multiple targets used on one texture image unit");
    451 		 YYERROR;
    452 	      }
    453 
    454 
    455 	      state->prog->TexturesUsed[$6] |= target_mask;
    456 	      state->prog->ShadowSamplers |= shadow_tex;
    457 	   }
    458 	}
    459 	;
    460 
    461 KIL_instruction: KIL swizzleSrcReg
    462 	{
    463 	   $$ = asm_instruction_ctor(OPCODE_KIL, NULL, & $2, NULL, NULL);
    464 	   state->fragment.UsesKill = 1;
    465 	}
    466 	| KIL ccTest
    467 	{
    468 	   $$ = asm_instruction_ctor(OPCODE_KIL_NV, NULL, NULL, NULL, NULL);
    469 	   $$->Base.DstReg.CondMask = $2.CondMask;
    470 	   $$->Base.DstReg.CondSwizzle = $2.CondSwizzle;
    471 	   $$->Base.DstReg.CondSrc = $2.CondSrc;
    472 	   state->fragment.UsesKill = 1;
    473 	}
    474 	;
    475 
    476 TXD_instruction: TXD_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget
    477 	{
    478 	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8);
    479 	   if ($$ != NULL) {
    480 	      const GLbitfield tex_mask = (1U << $10);
    481 	      GLbitfield shadow_tex = 0;
    482 	      GLbitfield target_mask = 0;
    483 
    484 
    485 	      $$->Base.TexSrcUnit = $10;
    486 
    487 	      if ($12 < 0) {
    488 		 shadow_tex = tex_mask;
    489 
    490 		 $$->Base.TexSrcTarget = -$12;
    491 		 $$->Base.TexShadow = 1;
    492 	      } else {
    493 		 $$->Base.TexSrcTarget = $12;
    494 	      }
    495 
    496 	      target_mask = (1U << $$->Base.TexSrcTarget);
    497 
    498 	      /* If this texture unit was previously accessed and that access
    499 	       * had a different texture target, generate an error.
    500 	       *
    501 	       * If this texture unit was previously accessed and that access
    502 	       * had a different shadow mode, generate an error.
    503 	       */
    504 	      if ((state->prog->TexturesUsed[$10] != 0)
    505 		  && ((state->prog->TexturesUsed[$10] != target_mask)
    506 		      || ((state->prog->ShadowSamplers & tex_mask)
    507 			  != shadow_tex))) {
    508 		 yyerror(& @12, state,
    509 			 "multiple targets used on one texture image unit");
    510 		 YYERROR;
    511 	      }
    512 
    513 
    514 	      state->prog->TexturesUsed[$10] |= target_mask;
    515 	      state->prog->ShadowSamplers |= shadow_tex;
    516 	   }
    517 	}
    518 	;
    519 
    520 texImageUnit: TEXTURE_UNIT optTexImageUnitNum
    521 	{
    522 	   $$ = $2;
    523 	}
    524 	;
    525 
    526 texTarget: TEX_1D  { $$ = TEXTURE_1D_INDEX; }
    527 	| TEX_2D   { $$ = TEXTURE_2D_INDEX; }
    528 	| TEX_3D   { $$ = TEXTURE_3D_INDEX; }
    529 	| TEX_CUBE { $$ = TEXTURE_CUBE_INDEX; }
    530 	| TEX_RECT { $$ = TEXTURE_RECT_INDEX; }
    531 	| TEX_SHADOW1D   { $$ = -TEXTURE_1D_INDEX; }
    532 	| TEX_SHADOW2D   { $$ = -TEXTURE_2D_INDEX; }
    533 	| TEX_SHADOWRECT { $$ = -TEXTURE_RECT_INDEX; }
    534 	| TEX_ARRAY1D         { $$ = TEXTURE_1D_ARRAY_INDEX; }
    535 	| TEX_ARRAY2D         { $$ = TEXTURE_2D_ARRAY_INDEX; }
    536 	| TEX_ARRAYSHADOW1D   { $$ = -TEXTURE_1D_ARRAY_INDEX; }
    537 	| TEX_ARRAYSHADOW2D   { $$ = -TEXTURE_2D_ARRAY_INDEX; }
    538 	;
    539 
    540 SWZ_instruction: SWZ maskedDstReg ',' srcReg ',' extendedSwizzle
    541 	{
    542 	   /* FIXME: Is this correct?  Should the extenedSwizzle be applied
    543 	    * FIXME: to the existing swizzle?
    544 	    */
    545 	   $4.Base.Swizzle = $6.swizzle;
    546 	   $4.Base.Negate = $6.mask;
    547 
    548 	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
    549 	}
    550 	;
    551 
    552 scalarSrcReg: optionalSign scalarUse
    553 	{
    554 	   $$ = $2;
    555 
    556 	   if ($1) {
    557 	      $$.Base.Negate = ~$$.Base.Negate;
    558 	   }
    559 	}
    560 	| optionalSign '|' scalarUse '|'
    561 	{
    562 	   $$ = $3;
    563 
    564 	   if (!state->option.NV_fragment) {
    565 	      yyerror(& @2, state, "unexpected character '|'");
    566 	      YYERROR;
    567 	   }
    568 
    569 	   if ($1) {
    570 	      $$.Base.Negate = ~$$.Base.Negate;
    571 	   }
    572 
    573 	   $$.Base.Abs = 1;
    574 	}
    575 	;
    576 
    577 scalarUse:  srcReg scalarSuffix
    578 	{
    579 	   $$ = $1;
    580 
    581 	   $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
    582 						    $2.swizzle);
    583 	}
    584 	| paramConstScalarUse
    585 	{
    586 	   struct asm_symbol temp_sym;
    587 
    588 	   if (!state->option.NV_fragment) {
    589 	      yyerror(& @1, state, "expected scalar suffix");
    590 	      YYERROR;
    591 	   }
    592 
    593 	   memset(& temp_sym, 0, sizeof(temp_sym));
    594 	   temp_sym.param_binding_begin = ~0;
    595 	   initialize_symbol_from_const(state->prog, & temp_sym, & $1, GL_TRUE);
    596 
    597 	   set_src_reg_swz(& $$, PROGRAM_CONSTANT,
    598                            temp_sym.param_binding_begin,
    599                            temp_sym.param_binding_swizzle);
    600 	}
    601 	;
    602 
    603 swizzleSrcReg: optionalSign srcReg swizzleSuffix
    604 	{
    605 	   $$ = $2;
    606 
    607 	   if ($1) {
    608 	      $$.Base.Negate = ~$$.Base.Negate;
    609 	   }
    610 
    611 	   $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
    612 						    $3.swizzle);
    613 	}
    614 	| optionalSign '|' srcReg swizzleSuffix '|'
    615 	{
    616 	   $$ = $3;
    617 
    618 	   if (!state->option.NV_fragment) {
    619 	      yyerror(& @2, state, "unexpected character '|'");
    620 	      YYERROR;
    621 	   }
    622 
    623 	   if ($1) {
    624 	      $$.Base.Negate = ~$$.Base.Negate;
    625 	   }
    626 
    627 	   $$.Base.Abs = 1;
    628 	   $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
    629 						    $4.swizzle);
    630 	}
    631 
    632 	;
    633 
    634 maskedDstReg: dstReg optionalMask optionalCcMask
    635 	{
    636 	   $$ = $1;
    637 	   $$.WriteMask = $2.mask;
    638 	   $$.CondMask = $3.CondMask;
    639 	   $$.CondSwizzle = $3.CondSwizzle;
    640 	   $$.CondSrc = $3.CondSrc;
    641 
    642 	   if ($$.File == PROGRAM_OUTPUT) {
    643 	      /* Technically speaking, this should check that it is in
    644 	       * vertex program mode.  However, PositionInvariant can never be
    645 	       * set in fragment program mode, so it is somewhat irrelevant.
    646 	       */
    647 	      if (state->option.PositionInvariant
    648 	       && ($$.Index == VERT_RESULT_HPOS)) {
    649 		 yyerror(& @1, state, "position-invariant programs cannot "
    650 			 "write position");
    651 		 YYERROR;
    652 	      }
    653 
    654 	      state->prog->OutputsWritten |= BITFIELD64_BIT($$.Index);
    655 	   }
    656 	}
    657 	;
    658 
    659 maskedAddrReg: addrReg addrWriteMask
    660 	{
    661 	   set_dst_reg(& $$, PROGRAM_ADDRESS, 0);
    662 	   $$.WriteMask = $2.mask;
    663 	}
    664 	;
    665 
    666 extendedSwizzle: extSwizComp ',' extSwizComp ',' extSwizComp ',' extSwizComp
    667 	{
    668 	   const unsigned xyzw_valid =
    669 	      ($1.xyzw_valid << 0)
    670 	      | ($3.xyzw_valid << 1)
    671 	      | ($5.xyzw_valid << 2)
    672 	      | ($7.xyzw_valid << 3);
    673 	   const unsigned rgba_valid =
    674 	      ($1.rgba_valid << 0)
    675 	      | ($3.rgba_valid << 1)
    676 	      | ($5.rgba_valid << 2)
    677 	      | ($7.rgba_valid << 3);
    678 
    679 	   /* All of the swizzle components have to be valid in either RGBA
    680 	    * or XYZW.  Note that 0 and 1 are valid in both, so both masks
    681 	    * can have some bits set.
    682 	    *
    683 	    * We somewhat deviate from the spec here.  It would be really hard
    684 	    * to figure out which component is the error, and there probably
    685 	    * isn't a lot of benefit.
    686 	    */
    687 	   if ((rgba_valid != 0x0f) && (xyzw_valid != 0x0f)) {
    688 	      yyerror(& @1, state, "cannot combine RGBA and XYZW swizzle "
    689 		      "components");
    690 	      YYERROR;
    691 	   }
    692 
    693 	   $$.swizzle = MAKE_SWIZZLE4($1.swz, $3.swz, $5.swz, $7.swz);
    694 	   $$.mask = ($1.negate) | ($3.negate << 1) | ($5.negate << 2)
    695 	      | ($7.negate << 3);
    696 	}
    697 	;
    698 
    699 extSwizComp: optionalSign extSwizSel
    700 	{
    701 	   $$ = $2;
    702 	   $$.negate = ($1) ? 1 : 0;
    703 	}
    704 	;
    705 
    706 extSwizSel: INTEGER
    707 	{
    708 	   if (($1 != 0) && ($1 != 1)) {
    709 	      yyerror(& @1, state, "invalid extended swizzle selector");
    710 	      YYERROR;
    711 	   }
    712 
    713 	   $$.swz = ($1 == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE;
    714 
    715 	   /* 0 and 1 are valid for both RGBA swizzle names and XYZW
    716 	    * swizzle names.
    717 	    */
    718 	   $$.xyzw_valid = 1;
    719 	   $$.rgba_valid = 1;
    720 	}
    721 	| string
    722 	{
    723 	   char s;
    724 
    725 	   if (strlen($1) > 1) {
    726 	      yyerror(& @1, state, "invalid extended swizzle selector");
    727 	      YYERROR;
    728 	   }
    729 
    730 	   s = $1[0];
    731 	   free($1);
    732 
    733 	   switch (s) {
    734 	   case 'x':
    735 	      $$.swz = SWIZZLE_X;
    736 	      $$.xyzw_valid = 1;
    737 	      break;
    738 	   case 'y':
    739 	      $$.swz = SWIZZLE_Y;
    740 	      $$.xyzw_valid = 1;
    741 	      break;
    742 	   case 'z':
    743 	      $$.swz = SWIZZLE_Z;
    744 	      $$.xyzw_valid = 1;
    745 	      break;
    746 	   case 'w':
    747 	      $$.swz = SWIZZLE_W;
    748 	      $$.xyzw_valid = 1;
    749 	      break;
    750 
    751 	   case 'r':
    752 	      $$.swz = SWIZZLE_X;
    753 	      $$.rgba_valid = 1;
    754 	      break;
    755 	   case 'g':
    756 	      $$.swz = SWIZZLE_Y;
    757 	      $$.rgba_valid = 1;
    758 	      break;
    759 	   case 'b':
    760 	      $$.swz = SWIZZLE_Z;
    761 	      $$.rgba_valid = 1;
    762 	      break;
    763 	   case 'a':
    764 	      $$.swz = SWIZZLE_W;
    765 	      $$.rgba_valid = 1;
    766 	      break;
    767 
    768 	   default:
    769 	      yyerror(& @1, state, "invalid extended swizzle selector");
    770 	      YYERROR;
    771 	      break;
    772 	   }
    773 	}
    774 	;
    775 
    776 srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */
    777 	{
    778 	   struct asm_symbol *const s = (struct asm_symbol *)
    779 	      _mesa_symbol_table_find_symbol(state->st, 0, $1);
    780 
    781 	   free($1);
    782 
    783 	   if (s == NULL) {
    784 	      yyerror(& @1, state, "invalid operand variable");
    785 	      YYERROR;
    786 	   } else if ((s->type != at_param) && (s->type != at_temp)
    787 		      && (s->type != at_attrib)) {
    788 	      yyerror(& @1, state, "invalid operand variable");
    789 	      YYERROR;
    790 	   } else if ((s->type == at_param) && s->param_is_array) {
    791 	      yyerror(& @1, state, "non-array access to array PARAM");
    792 	      YYERROR;
    793 	   }
    794 
    795 	   init_src_reg(& $$);
    796 	   switch (s->type) {
    797 	   case at_temp:
    798 	      set_src_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding);
    799 	      break;
    800 	   case at_param:
    801               set_src_reg_swz(& $$, s->param_binding_type,
    802                               s->param_binding_begin,
    803                               s->param_binding_swizzle);
    804 	      break;
    805 	   case at_attrib:
    806 	      set_src_reg(& $$, PROGRAM_INPUT, s->attrib_binding);
    807 	      state->prog->InputsRead |= BITFIELD64_BIT($$.Base.Index);
    808 
    809 	      if (!validate_inputs(& @1, state)) {
    810 		 YYERROR;
    811 	      }
    812 	      break;
    813 
    814 	   default:
    815 	      YYERROR;
    816 	      break;
    817 	   }
    818 	}
    819 	| attribBinding
    820 	{
    821 	   set_src_reg(& $$, PROGRAM_INPUT, $1);
    822 	   state->prog->InputsRead |= BITFIELD64_BIT($$.Base.Index);
    823 
    824 	   if (!validate_inputs(& @1, state)) {
    825 	      YYERROR;
    826 	   }
    827 	}
    828 	| progParamArray '[' progParamArrayMem ']'
    829 	{
    830 	   if (! $3.Base.RelAddr
    831 	       && ((unsigned) $3.Base.Index >= $1->param_binding_length)) {
    832 	      yyerror(& @3, state, "out of bounds array access");
    833 	      YYERROR;
    834 	   }
    835 
    836 	   init_src_reg(& $$);
    837 	   $$.Base.File = $1->param_binding_type;
    838 
    839 	   if ($3.Base.RelAddr) {
    840               state->prog->IndirectRegisterFiles |= (1 << $$.Base.File);
    841 	      $1->param_accessed_indirectly = 1;
    842 
    843 	      $$.Base.RelAddr = 1;
    844 	      $$.Base.Index = $3.Base.Index;
    845 	      $$.Symbol = $1;
    846 	   } else {
    847 	      $$.Base.Index = $1->param_binding_begin + $3.Base.Index;
    848 	   }
    849 	}
    850 	| paramSingleItemUse
    851 	{
    852            gl_register_file file = ($1.name != NULL)
    853 	      ? $1.param_binding_type
    854 	      : PROGRAM_CONSTANT;
    855            set_src_reg_swz(& $$, file, $1.param_binding_begin,
    856                            $1.param_binding_swizzle);
    857 	}
    858 	;
    859 
    860 dstReg: resultBinding
    861 	{
    862 	   set_dst_reg(& $$, PROGRAM_OUTPUT, $1);
    863 	}
    864 	| USED_IDENTIFIER /* temporaryReg | vertexResultReg */
    865 	{
    866 	   struct asm_symbol *const s = (struct asm_symbol *)
    867 	      _mesa_symbol_table_find_symbol(state->st, 0, $1);
    868 
    869 	   free($1);
    870 
    871 	   if (s == NULL) {
    872 	      yyerror(& @1, state, "invalid operand variable");
    873 	      YYERROR;
    874 	   } else if ((s->type != at_output) && (s->type != at_temp)) {
    875 	      yyerror(& @1, state, "invalid operand variable");
    876 	      YYERROR;
    877 	   }
    878 
    879 	   switch (s->type) {
    880 	   case at_temp:
    881 	      set_dst_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding);
    882 	      break;
    883 	   case at_output:
    884 	      set_dst_reg(& $$, PROGRAM_OUTPUT, s->output_binding);
    885 	      break;
    886 	   default:
    887 	      set_dst_reg(& $$, s->param_binding_type, s->param_binding_begin);
    888 	      break;
    889 	   }
    890 	}
    891 	;
    892 
    893 progParamArray: USED_IDENTIFIER
    894 	{
    895 	   struct asm_symbol *const s = (struct asm_symbol *)
    896 	      _mesa_symbol_table_find_symbol(state->st, 0, $1);
    897 
    898 	   free($1);
    899 
    900 	   if (s == NULL) {
    901 	      yyerror(& @1, state, "invalid operand variable");
    902 	      YYERROR;
    903 	   } else if ((s->type != at_param) || !s->param_is_array) {
    904 	      yyerror(& @1, state, "array access to non-PARAM variable");
    905 	      YYERROR;
    906 	   } else {
    907 	      $$ = s;
    908 	   }
    909 	}
    910 	;
    911 
    912 progParamArrayMem: progParamArrayAbs | progParamArrayRel;
    913 
    914 progParamArrayAbs: INTEGER
    915 	{
    916 	   init_src_reg(& $$);
    917 	   $$.Base.Index = $1;
    918 	}
    919 	;
    920 
    921 progParamArrayRel: addrReg addrComponent addrRegRelOffset
    922 	{
    923 	   /* FINISHME: Add support for multiple address registers.
    924 	    */
    925 	   /* FINISHME: Add support for 4-component address registers.
    926 	    */
    927 	   init_src_reg(& $$);
    928 	   $$.Base.RelAddr = 1;
    929 	   $$.Base.Index = $3;
    930 	}
    931 	;
    932 
    933 addrRegRelOffset:              { $$ = 0; }
    934 	| '+' addrRegPosOffset { $$ = $2; }
    935 	| '-' addrRegNegOffset { $$ = -$2; }
    936 	;
    937 
    938 addrRegPosOffset: INTEGER
    939 	{
    940 	   if (($1 < 0) || ($1 > (state->limits->MaxAddressOffset - 1))) {
    941               char s[100];
    942               _mesa_snprintf(s, sizeof(s),
    943                              "relative address offset too large (%d)", $1);
    944 	      yyerror(& @1, state, s);
    945 	      YYERROR;
    946 	   } else {
    947 	      $$ = $1;
    948 	   }
    949 	}
    950 	;
    951 
    952 addrRegNegOffset: INTEGER
    953 	{
    954 	   if (($1 < 0) || ($1 > state->limits->MaxAddressOffset)) {
    955               char s[100];
    956               _mesa_snprintf(s, sizeof(s),
    957                              "relative address offset too large (%d)", $1);
    958 	      yyerror(& @1, state, s);
    959 	      YYERROR;
    960 	   } else {
    961 	      $$ = $1;
    962 	   }
    963 	}
    964 	;
    965 
    966 addrReg: USED_IDENTIFIER
    967 	{
    968 	   struct asm_symbol *const s = (struct asm_symbol *)
    969 	      _mesa_symbol_table_find_symbol(state->st, 0, $1);
    970 
    971 	   free($1);
    972 
    973 	   if (s == NULL) {
    974 	      yyerror(& @1, state, "invalid array member");
    975 	      YYERROR;
    976 	   } else if (s->type != at_address) {
    977 	      yyerror(& @1, state,
    978 		      "invalid variable for indexed array access");
    979 	      YYERROR;
    980 	   } else {
    981 	      $$ = s;
    982 	   }
    983 	}
    984 	;
    985 
    986 addrComponent: MASK1
    987 	{
    988 	   if ($1.mask != WRITEMASK_X) {
    989 	      yyerror(& @1, state, "invalid address component selector");
    990 	      YYERROR;
    991 	   } else {
    992 	      $$ = $1;
    993 	   }
    994 	}
    995 	;
    996 
    997 addrWriteMask: MASK1
    998 	{
    999 	   if ($1.mask != WRITEMASK_X) {
   1000 	      yyerror(& @1, state,
   1001 		      "address register write mask must be \".x\"");
   1002 	      YYERROR;
   1003 	   } else {
   1004 	      $$ = $1;
   1005 	   }
   1006 	}
   1007 	;
   1008 
   1009 scalarSuffix: MASK1;
   1010 
   1011 swizzleSuffix: MASK1
   1012 	| MASK4
   1013 	| SWIZZLE
   1014 	|              { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
   1015 	;
   1016 
   1017 optionalMask: MASK4 | MASK3 | MASK2 | MASK1
   1018 	|              { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
   1019 	;
   1020 
   1021 optionalCcMask: '(' ccTest ')'
   1022 	{
   1023 	   $$ = $2;
   1024 	}
   1025 	| '(' ccTest2 ')'
   1026 	{
   1027 	   $$ = $2;
   1028 	}
   1029 	|
   1030 	{
   1031 	   $$.CondMask = COND_TR;
   1032 	   $$.CondSwizzle = SWIZZLE_NOOP;
   1033 	   $$.CondSrc = 0;
   1034 	}
   1035 	;
   1036 
   1037 ccTest: ccMaskRule swizzleSuffix
   1038 	{
   1039 	   $$ = $1;
   1040 	   $$.CondSwizzle = $2.swizzle;
   1041 	}
   1042 	;
   1043 
   1044 ccTest2: ccMaskRule2 swizzleSuffix
   1045 	{
   1046 	   $$ = $1;
   1047 	   $$.CondSwizzle = $2.swizzle;
   1048 	}
   1049 	;
   1050 
   1051 ccMaskRule: IDENTIFIER
   1052 	{
   1053 	   const int cond = _mesa_parse_cc($1);
   1054 	   if ((cond == 0) || ($1[2] != '\0')) {
   1055 	      char *const err_str =
   1056 		 make_error_string("invalid condition code \"%s\"", $1);
   1057 
   1058 	      yyerror(& @1, state, (err_str != NULL)
   1059 		      ? err_str : "invalid condition code");
   1060 
   1061 	      if (err_str != NULL) {
   1062 		 free(err_str);
   1063 	      }
   1064 
   1065 	      YYERROR;
   1066 	   }
   1067 
   1068 	   $$.CondMask = cond;
   1069 	   $$.CondSwizzle = SWIZZLE_NOOP;
   1070 	   $$.CondSrc = 0;
   1071 	}
   1072 	;
   1073 
   1074 ccMaskRule2: USED_IDENTIFIER
   1075 	{
   1076 	   const int cond = _mesa_parse_cc($1);
   1077 	   if ((cond == 0) || ($1[2] != '\0')) {
   1078 	      char *const err_str =
   1079 		 make_error_string("invalid condition code \"%s\"", $1);
   1080 
   1081 	      yyerror(& @1, state, (err_str != NULL)
   1082 		      ? err_str : "invalid condition code");
   1083 
   1084 	      if (err_str != NULL) {
   1085 		 free(err_str);
   1086 	      }
   1087 
   1088 	      YYERROR;
   1089 	   }
   1090 
   1091 	   $$.CondMask = cond;
   1092 	   $$.CondSwizzle = SWIZZLE_NOOP;
   1093 	   $$.CondSrc = 0;
   1094 	}
   1095 	;
   1096 
   1097 namingStatement: ATTRIB_statement
   1098 	| PARAM_statement
   1099 	| TEMP_statement
   1100 	| ADDRESS_statement
   1101 	| OUTPUT_statement
   1102 	| ALIAS_statement
   1103 	;
   1104 
   1105 ATTRIB_statement: ATTRIB IDENTIFIER '=' attribBinding
   1106 	{
   1107 	   struct asm_symbol *const s =
   1108 	      declare_variable(state, $2, at_attrib, & @2);
   1109 
   1110 	   if (s == NULL) {
   1111 	      free($2);
   1112 	      YYERROR;
   1113 	   } else {
   1114 	      s->attrib_binding = $4;
   1115 	      state->InputsBound |= BITFIELD64_BIT(s->attrib_binding);
   1116 
   1117 	      if (!validate_inputs(& @4, state)) {
   1118 		 YYERROR;
   1119 	      }
   1120 	   }
   1121 	}
   1122 	;
   1123 
   1124 attribBinding: VERTEX vtxAttribItem
   1125 	{
   1126 	   $$ = $2;
   1127 	}
   1128 	| FRAGMENT fragAttribItem
   1129 	{
   1130 	   $$ = $2;
   1131 	}
   1132 	;
   1133 
   1134 vtxAttribItem: POSITION
   1135 	{
   1136 	   $$ = VERT_ATTRIB_POS;
   1137 	}
   1138 	| WEIGHT vtxOptWeightNum
   1139 	{
   1140 	   $$ = VERT_ATTRIB_WEIGHT;
   1141 	}
   1142 	| NORMAL
   1143 	{
   1144 	   $$ = VERT_ATTRIB_NORMAL;
   1145 	}
   1146 	| COLOR optColorType
   1147 	{
   1148 	   if (!state->ctx->Extensions.EXT_secondary_color) {
   1149 	      yyerror(& @2, state, "GL_EXT_secondary_color not supported");
   1150 	      YYERROR;
   1151 	   }
   1152 
   1153 	   $$ = VERT_ATTRIB_COLOR0 + $2;
   1154 	}
   1155 	| FOGCOORD
   1156 	{
   1157 	   if (!state->ctx->Extensions.EXT_fog_coord) {
   1158 	      yyerror(& @1, state, "GL_EXT_fog_coord not supported");
   1159 	      YYERROR;
   1160 	   }
   1161 
   1162 	   $$ = VERT_ATTRIB_FOG;
   1163 	}
   1164 	| TEXCOORD optTexCoordUnitNum
   1165 	{
   1166 	   $$ = VERT_ATTRIB_TEX0 + $2;
   1167 	}
   1168 	| MATRIXINDEX '[' vtxWeightNum ']'
   1169 	{
   1170 	   yyerror(& @1, state, "GL_ARB_matrix_palette not supported");
   1171 	   YYERROR;
   1172 	}
   1173 	| VTXATTRIB '[' vtxAttribNum ']'
   1174 	{
   1175 	   $$ = VERT_ATTRIB_GENERIC0 + $3;
   1176 	}
   1177 	;
   1178 
   1179 vtxAttribNum: INTEGER
   1180 	{
   1181 	   if ((unsigned) $1 >= state->limits->MaxAttribs) {
   1182 	      yyerror(& @1, state, "invalid vertex attribute reference");
   1183 	      YYERROR;
   1184 	   }
   1185 
   1186 	   $$ = $1;
   1187 	}
   1188 	;
   1189 
   1190 vtxOptWeightNum:  | '[' vtxWeightNum ']';
   1191 vtxWeightNum: INTEGER;
   1192 
   1193 fragAttribItem: POSITION
   1194 	{
   1195 	   $$ = FRAG_ATTRIB_WPOS;
   1196 	}
   1197 	| COLOR optColorType
   1198 	{
   1199 	   $$ = FRAG_ATTRIB_COL0 + $2;
   1200 	}
   1201 	| FOGCOORD
   1202 	{
   1203 	   $$ = FRAG_ATTRIB_FOGC;
   1204 	}
   1205 	| TEXCOORD optTexCoordUnitNum
   1206 	{
   1207 	   $$ = FRAG_ATTRIB_TEX0 + $2;
   1208 	}
   1209 	;
   1210 
   1211 PARAM_statement: PARAM_singleStmt | PARAM_multipleStmt;
   1212 
   1213 PARAM_singleStmt: PARAM IDENTIFIER paramSingleInit
   1214 	{
   1215 	   struct asm_symbol *const s =
   1216 	      declare_variable(state, $2, at_param, & @2);
   1217 
   1218 	   if (s == NULL) {
   1219 	      free($2);
   1220 	      YYERROR;
   1221 	   } else {
   1222 	      s->param_binding_type = $3.param_binding_type;
   1223 	      s->param_binding_begin = $3.param_binding_begin;
   1224 	      s->param_binding_length = $3.param_binding_length;
   1225               s->param_binding_swizzle = $3.param_binding_swizzle;
   1226 	      s->param_is_array = 0;
   1227 	   }
   1228 	}
   1229 	;
   1230 
   1231 PARAM_multipleStmt: PARAM IDENTIFIER '[' optArraySize ']' paramMultipleInit
   1232 	{
   1233 	   if (($4 != 0) && ((unsigned) $4 != $6.param_binding_length)) {
   1234 	      free($2);
   1235 	      yyerror(& @4, state,
   1236 		      "parameter array size and number of bindings must match");
   1237 	      YYERROR;
   1238 	   } else {
   1239 	      struct asm_symbol *const s =
   1240 		 declare_variable(state, $2, $6.type, & @2);
   1241 
   1242 	      if (s == NULL) {
   1243 		 free($2);
   1244 		 YYERROR;
   1245 	      } else {
   1246 		 s->param_binding_type = $6.param_binding_type;
   1247 		 s->param_binding_begin = $6.param_binding_begin;
   1248 		 s->param_binding_length = $6.param_binding_length;
   1249                  s->param_binding_swizzle = SWIZZLE_XYZW;
   1250 		 s->param_is_array = 1;
   1251 	      }
   1252 	   }
   1253 	}
   1254 	;
   1255 
   1256 optArraySize:
   1257 	{
   1258 	   $$ = 0;
   1259 	}
   1260 	| INTEGER
   1261         {
   1262 	   if (($1 < 1) || ((unsigned) $1 > state->limits->MaxParameters)) {
   1263               char msg[100];
   1264               _mesa_snprintf(msg, sizeof(msg),
   1265                              "invalid parameter array size (size=%d max=%u)",
   1266                              $1, state->limits->MaxParameters);
   1267 	      yyerror(& @1, state, msg);
   1268 	      YYERROR;
   1269 	   } else {
   1270 	      $$ = $1;
   1271 	   }
   1272 	}
   1273 	;
   1274 
   1275 paramSingleInit: '=' paramSingleItemDecl
   1276 	{
   1277 	   $$ = $2;
   1278 	}
   1279 	;
   1280 
   1281 paramMultipleInit: '=' '{' paramMultInitList '}'
   1282 	{
   1283 	   $$ = $3;
   1284 	}
   1285 	;
   1286 
   1287 paramMultInitList: paramMultipleItem
   1288 	| paramMultInitList ',' paramMultipleItem
   1289 	{
   1290 	   $1.param_binding_length += $3.param_binding_length;
   1291 	   $$ = $1;
   1292 	}
   1293 	;
   1294 
   1295 paramSingleItemDecl: stateSingleItem
   1296 	{
   1297 	   memset(& $$, 0, sizeof($$));
   1298 	   $$.param_binding_begin = ~0;
   1299 	   initialize_symbol_from_state(state->prog, & $$, $1);
   1300 	}
   1301 	| programSingleItem
   1302 	{
   1303 	   memset(& $$, 0, sizeof($$));
   1304 	   $$.param_binding_begin = ~0;
   1305 	   initialize_symbol_from_param(state->prog, & $$, $1);
   1306 	}
   1307 	| paramConstDecl
   1308 	{
   1309 	   memset(& $$, 0, sizeof($$));
   1310 	   $$.param_binding_begin = ~0;
   1311 	   initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE);
   1312 	}
   1313 	;
   1314 
   1315 paramSingleItemUse: stateSingleItem
   1316 	{
   1317 	   memset(& $$, 0, sizeof($$));
   1318 	   $$.param_binding_begin = ~0;
   1319 	   initialize_symbol_from_state(state->prog, & $$, $1);
   1320 	}
   1321 	| programSingleItem
   1322 	{
   1323 	   memset(& $$, 0, sizeof($$));
   1324 	   $$.param_binding_begin = ~0;
   1325 	   initialize_symbol_from_param(state->prog, & $$, $1);
   1326 	}
   1327 	| paramConstUse
   1328 	{
   1329 	   memset(& $$, 0, sizeof($$));
   1330 	   $$.param_binding_begin = ~0;
   1331 	   initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE);
   1332 	}
   1333 	;
   1334 
   1335 paramMultipleItem: stateMultipleItem
   1336 	{
   1337 	   memset(& $$, 0, sizeof($$));
   1338 	   $$.param_binding_begin = ~0;
   1339 	   initialize_symbol_from_state(state->prog, & $$, $1);
   1340 	}
   1341 	| programMultipleItem
   1342 	{
   1343 	   memset(& $$, 0, sizeof($$));
   1344 	   $$.param_binding_begin = ~0;
   1345 	   initialize_symbol_from_param(state->prog, & $$, $1);
   1346 	}
   1347 	| paramConstDecl
   1348 	{
   1349 	   memset(& $$, 0, sizeof($$));
   1350 	   $$.param_binding_begin = ~0;
   1351 	   initialize_symbol_from_const(state->prog, & $$, & $1, GL_FALSE);
   1352 	}
   1353 	;
   1354 
   1355 stateMultipleItem: stateSingleItem        { memcpy($$, $1, sizeof($$)); }
   1356 	| STATE stateMatrixRows           { memcpy($$, $2, sizeof($$)); }
   1357 	;
   1358 
   1359 stateSingleItem: STATE stateMaterialItem  { memcpy($$, $2, sizeof($$)); }
   1360 	| STATE stateLightItem            { memcpy($$, $2, sizeof($$)); }
   1361 	| STATE stateLightModelItem       { memcpy($$, $2, sizeof($$)); }
   1362 	| STATE stateLightProdItem        { memcpy($$, $2, sizeof($$)); }
   1363 	| STATE stateTexGenItem           { memcpy($$, $2, sizeof($$)); }
   1364 	| STATE stateTexEnvItem           { memcpy($$, $2, sizeof($$)); }
   1365 	| STATE stateFogItem              { memcpy($$, $2, sizeof($$)); }
   1366 	| STATE stateClipPlaneItem        { memcpy($$, $2, sizeof($$)); }
   1367 	| STATE statePointItem            { memcpy($$, $2, sizeof($$)); }
   1368 	| STATE stateMatrixRow            { memcpy($$, $2, sizeof($$)); }
   1369 	| STATE stateDepthItem            { memcpy($$, $2, sizeof($$)); }
   1370 	;
   1371 
   1372 stateMaterialItem: MATERIAL optFaceType stateMatProperty
   1373 	{
   1374 	   memset($$, 0, sizeof($$));
   1375 	   $$[0] = STATE_MATERIAL;
   1376 	   $$[1] = $2;
   1377 	   $$[2] = $3;
   1378 	}
   1379 	;
   1380 
   1381 stateMatProperty: ambDiffSpecProperty
   1382 	{
   1383 	   $$ = $1;
   1384 	}
   1385 	| EMISSION
   1386 	{
   1387 	   $$ = STATE_EMISSION;
   1388 	}
   1389 	| SHININESS
   1390 	{
   1391 	   $$ = STATE_SHININESS;
   1392 	}
   1393 	;
   1394 
   1395 stateLightItem: LIGHT '[' stateLightNumber ']' stateLightProperty
   1396 	{
   1397 	   memset($$, 0, sizeof($$));
   1398 	   $$[0] = STATE_LIGHT;
   1399 	   $$[1] = $3;
   1400 	   $$[2] = $5;
   1401 	}
   1402 	;
   1403 
   1404 stateLightProperty: ambDiffSpecProperty
   1405 	{
   1406 	   $$ = $1;
   1407 	}
   1408 	| POSITION
   1409 	{
   1410 	   $$ = STATE_POSITION;
   1411 	}
   1412 	| ATTENUATION
   1413 	{
   1414 	   if (!state->ctx->Extensions.EXT_point_parameters) {
   1415 	      yyerror(& @1, state, "GL_ARB_point_parameters not supported");
   1416 	      YYERROR;
   1417 	   }
   1418 
   1419 	   $$ = STATE_ATTENUATION;
   1420 	}
   1421 	| SPOT stateSpotProperty
   1422 	{
   1423 	   $$ = $2;
   1424 	}
   1425 	| HALF
   1426 	{
   1427 	   $$ = STATE_HALF_VECTOR;
   1428 	}
   1429 	;
   1430 
   1431 stateSpotProperty: DIRECTION
   1432 	{
   1433 	   $$ = STATE_SPOT_DIRECTION;
   1434 	}
   1435 	;
   1436 
   1437 stateLightModelItem: LIGHTMODEL stateLModProperty
   1438 	{
   1439 	   $$[0] = $2[0];
   1440 	   $$[1] = $2[1];
   1441 	}
   1442 	;
   1443 
   1444 stateLModProperty: AMBIENT
   1445 	{
   1446 	   memset($$, 0, sizeof($$));
   1447 	   $$[0] = STATE_LIGHTMODEL_AMBIENT;
   1448 	}
   1449 	| optFaceType SCENECOLOR
   1450 	{
   1451 	   memset($$, 0, sizeof($$));
   1452 	   $$[0] = STATE_LIGHTMODEL_SCENECOLOR;
   1453 	   $$[1] = $1;
   1454 	}
   1455 	;
   1456 
   1457 stateLightProdItem: LIGHTPROD '[' stateLightNumber ']' optFaceType stateLProdProperty
   1458 	{
   1459 	   memset($$, 0, sizeof($$));
   1460 	   $$[0] = STATE_LIGHTPROD;
   1461 	   $$[1] = $3;
   1462 	   $$[2] = $5;
   1463 	   $$[3] = $6;
   1464 	}
   1465 	;
   1466 
   1467 stateLProdProperty: ambDiffSpecProperty;
   1468 
   1469 stateTexEnvItem: TEXENV optLegacyTexUnitNum stateTexEnvProperty
   1470 	{
   1471 	   memset($$, 0, sizeof($$));
   1472 	   $$[0] = $3;
   1473 	   $$[1] = $2;
   1474 	}
   1475 	;
   1476 
   1477 stateTexEnvProperty: COLOR
   1478 	{
   1479 	   $$ = STATE_TEXENV_COLOR;
   1480 	}
   1481 	;
   1482 
   1483 ambDiffSpecProperty: AMBIENT
   1484 	{
   1485 	   $$ = STATE_AMBIENT;
   1486 	}
   1487 	| DIFFUSE
   1488 	{
   1489 	   $$ = STATE_DIFFUSE;
   1490 	}
   1491 	| SPECULAR
   1492 	{
   1493 	   $$ = STATE_SPECULAR;
   1494 	}
   1495 	;
   1496 
   1497 stateLightNumber: INTEGER
   1498 	{
   1499 	   if ((unsigned) $1 >= state->MaxLights) {
   1500 	      yyerror(& @1, state, "invalid light selector");
   1501 	      YYERROR;
   1502 	   }
   1503 
   1504 	   $$ = $1;
   1505 	}
   1506 	;
   1507 
   1508 stateTexGenItem: TEXGEN optTexCoordUnitNum stateTexGenType stateTexGenCoord
   1509 	{
   1510 	   memset($$, 0, sizeof($$));
   1511 	   $$[0] = STATE_TEXGEN;
   1512 	   $$[1] = $2;
   1513 	   $$[2] = $3 + $4;
   1514 	}
   1515 	;
   1516 
   1517 stateTexGenType: EYE
   1518 	{
   1519 	   $$ = STATE_TEXGEN_EYE_S;
   1520 	}
   1521 	| OBJECT
   1522 	{
   1523 	   $$ = STATE_TEXGEN_OBJECT_S;
   1524 	}
   1525 	;
   1526 stateTexGenCoord: TEXGEN_S
   1527 	{
   1528 	   $$ = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S;
   1529 	}
   1530 	| TEXGEN_T
   1531 	{
   1532 	   $$ = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S;
   1533 	}
   1534 	| TEXGEN_R
   1535 	{
   1536 	   $$ = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S;
   1537 	}
   1538 	| TEXGEN_Q
   1539 	{
   1540 	   $$ = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S;
   1541 	}
   1542 	;
   1543 
   1544 stateFogItem: FOG stateFogProperty
   1545 	{
   1546 	   memset($$, 0, sizeof($$));
   1547 	   $$[0] = $2;
   1548 	}
   1549 	;
   1550 
   1551 stateFogProperty: COLOR
   1552 	{
   1553 	   $$ = STATE_FOG_COLOR;
   1554 	}
   1555 	| PARAMS
   1556 	{
   1557 	   $$ = STATE_FOG_PARAMS;
   1558 	}
   1559 	;
   1560 
   1561 stateClipPlaneItem: CLIP '[' stateClipPlaneNum ']' PLANE
   1562 	{
   1563 	   memset($$, 0, sizeof($$));
   1564 	   $$[0] = STATE_CLIPPLANE;
   1565 	   $$[1] = $3;
   1566 	}
   1567 	;
   1568 
   1569 stateClipPlaneNum: INTEGER
   1570 	{
   1571 	   if ((unsigned) $1 >= state->MaxClipPlanes) {
   1572 	      yyerror(& @1, state, "invalid clip plane selector");
   1573 	      YYERROR;
   1574 	   }
   1575 
   1576 	   $$ = $1;
   1577 	}
   1578 	;
   1579 
   1580 statePointItem: POINT_TOK statePointProperty
   1581 	{
   1582 	   memset($$, 0, sizeof($$));
   1583 	   $$[0] = $2;
   1584 	}
   1585 	;
   1586 
   1587 statePointProperty: SIZE_TOK
   1588 	{
   1589 	   $$ = STATE_POINT_SIZE;
   1590 	}
   1591 	| ATTENUATION
   1592 	{
   1593 	   $$ = STATE_POINT_ATTENUATION;
   1594 	}
   1595 	;
   1596 
   1597 stateMatrixRow: stateMatrixItem ROW '[' stateMatrixRowNum ']'
   1598 	{
   1599 	   $$[0] = $1[0];
   1600 	   $$[1] = $1[1];
   1601 	   $$[2] = $4;
   1602 	   $$[3] = $4;
   1603 	   $$[4] = $1[2];
   1604 	}
   1605 	;
   1606 
   1607 stateMatrixRows: stateMatrixItem optMatrixRows
   1608 	{
   1609 	   $$[0] = $1[0];
   1610 	   $$[1] = $1[1];
   1611 	   $$[2] = $2[2];
   1612 	   $$[3] = $2[3];
   1613 	   $$[4] = $1[2];
   1614 	}
   1615 	;
   1616 
   1617 optMatrixRows:
   1618 	{
   1619 	   $$[2] = 0;
   1620 	   $$[3] = 3;
   1621 	}
   1622 	| ROW '[' stateMatrixRowNum DOT_DOT stateMatrixRowNum ']'
   1623 	{
   1624 	   /* It seems logical that the matrix row range specifier would have
   1625 	    * to specify a range or more than one row (i.e., $5 > $3).
   1626 	    * However, the ARB_vertex_program spec says "a program will fail
   1627 	    * to load if <a> is greater than <b>."  This means that $3 == $5
   1628 	    * is valid.
   1629 	    */
   1630 	   if ($3 > $5) {
   1631 	      yyerror(& @3, state, "invalid matrix row range");
   1632 	      YYERROR;
   1633 	   }
   1634 
   1635 	   $$[2] = $3;
   1636 	   $$[3] = $5;
   1637 	}
   1638 	;
   1639 
   1640 stateMatrixItem: MATRIX stateMatrixName stateOptMatModifier
   1641 	{
   1642 	   $$[0] = $2[0];
   1643 	   $$[1] = $2[1];
   1644 	   $$[2] = $3;
   1645 	}
   1646 	;
   1647 
   1648 stateOptMatModifier:
   1649 	{
   1650 	   $$ = 0;
   1651 	}
   1652 	| stateMatModifier
   1653 	{
   1654 	   $$ = $1;
   1655 	}
   1656 	;
   1657 
   1658 stateMatModifier: INVERSE
   1659 	{
   1660 	   $$ = STATE_MATRIX_INVERSE;
   1661 	}
   1662 	| TRANSPOSE
   1663 	{
   1664 	   $$ = STATE_MATRIX_TRANSPOSE;
   1665 	}
   1666 	| INVTRANS
   1667 	{
   1668 	   $$ = STATE_MATRIX_INVTRANS;
   1669 	}
   1670 	;
   1671 
   1672 stateMatrixRowNum: INTEGER
   1673 	{
   1674 	   if ($1 > 3) {
   1675 	      yyerror(& @1, state, "invalid matrix row reference");
   1676 	      YYERROR;
   1677 	   }
   1678 
   1679 	   $$ = $1;
   1680 	}
   1681 	;
   1682 
   1683 stateMatrixName: MODELVIEW stateOptModMatNum
   1684 	{
   1685 	   $$[0] = STATE_MODELVIEW_MATRIX;
   1686 	   $$[1] = $2;
   1687 	}
   1688 	| PROJECTION
   1689 	{
   1690 	   $$[0] = STATE_PROJECTION_MATRIX;
   1691 	   $$[1] = 0;
   1692 	}
   1693 	| MVP
   1694 	{
   1695 	   $$[0] = STATE_MVP_MATRIX;
   1696 	   $$[1] = 0;
   1697 	}
   1698 	| TEXTURE optTexCoordUnitNum
   1699 	{
   1700 	   $$[0] = STATE_TEXTURE_MATRIX;
   1701 	   $$[1] = $2;
   1702 	}
   1703 	| PALETTE '[' statePaletteMatNum ']'
   1704 	{
   1705 	   yyerror(& @1, state, "GL_ARB_matrix_palette not supported");
   1706 	   YYERROR;
   1707 	}
   1708 	| MAT_PROGRAM '[' stateProgramMatNum ']'
   1709 	{
   1710 	   $$[0] = STATE_PROGRAM_MATRIX;
   1711 	   $$[1] = $3;
   1712 	}
   1713 	;
   1714 
   1715 stateOptModMatNum:
   1716 	{
   1717 	   $$ = 0;
   1718 	}
   1719 	| '[' stateModMatNum ']'
   1720 	{
   1721 	   $$ = $2;
   1722 	}
   1723 	;
   1724 stateModMatNum: INTEGER
   1725 	{
   1726 	   /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix
   1727 	    * zero is valid.
   1728 	    */
   1729 	   if ($1 != 0) {
   1730 	      yyerror(& @1, state, "invalid modelview matrix index");
   1731 	      YYERROR;
   1732 	   }
   1733 
   1734 	   $$ = $1;
   1735 	}
   1736 	;
   1737 statePaletteMatNum: INTEGER
   1738 	{
   1739 	   /* Since GL_ARB_matrix_palette isn't supported, just let any value
   1740 	    * through here.  The error will be generated later.
   1741 	    */
   1742 	   $$ = $1;
   1743 	}
   1744 	;
   1745 stateProgramMatNum: INTEGER
   1746 	{
   1747 	   if ((unsigned) $1 >= state->MaxProgramMatrices) {
   1748 	      yyerror(& @1, state, "invalid program matrix selector");
   1749 	      YYERROR;
   1750 	   }
   1751 
   1752 	   $$ = $1;
   1753 	}
   1754 	;
   1755 
   1756 stateDepthItem: DEPTH RANGE
   1757 	{
   1758 	   memset($$, 0, sizeof($$));
   1759 	   $$[0] = STATE_DEPTH_RANGE;
   1760 	}
   1761 	;
   1762 
   1763 
   1764 programSingleItem: progEnvParam | progLocalParam;
   1765 
   1766 programMultipleItem: progEnvParams | progLocalParams;
   1767 
   1768 progEnvParams: PROGRAM ENV '[' progEnvParamNums ']'
   1769 	{
   1770 	   memset($$, 0, sizeof($$));
   1771 	   $$[0] = state->state_param_enum;
   1772 	   $$[1] = STATE_ENV;
   1773 	   $$[2] = $4[0];
   1774 	   $$[3] = $4[1];
   1775 	}
   1776 	;
   1777 
   1778 progEnvParamNums: progEnvParamNum
   1779 	{
   1780 	   $$[0] = $1;
   1781 	   $$[1] = $1;
   1782 	}
   1783 	| progEnvParamNum DOT_DOT progEnvParamNum
   1784 	{
   1785 	   $$[0] = $1;
   1786 	   $$[1] = $3;
   1787 	}
   1788 	;
   1789 
   1790 progEnvParam: PROGRAM ENV '[' progEnvParamNum ']'
   1791 	{
   1792 	   memset($$, 0, sizeof($$));
   1793 	   $$[0] = state->state_param_enum;
   1794 	   $$[1] = STATE_ENV;
   1795 	   $$[2] = $4;
   1796 	   $$[3] = $4;
   1797 	}
   1798 	;
   1799 
   1800 progLocalParams: PROGRAM LOCAL '[' progLocalParamNums ']'
   1801 	{
   1802 	   memset($$, 0, sizeof($$));
   1803 	   $$[0] = state->state_param_enum;
   1804 	   $$[1] = STATE_LOCAL;
   1805 	   $$[2] = $4[0];
   1806 	   $$[3] = $4[1];
   1807 	}
   1808 
   1809 progLocalParamNums: progLocalParamNum
   1810 	{
   1811 	   $$[0] = $1;
   1812 	   $$[1] = $1;
   1813 	}
   1814 	| progLocalParamNum DOT_DOT progLocalParamNum
   1815 	{
   1816 	   $$[0] = $1;
   1817 	   $$[1] = $3;
   1818 	}
   1819 	;
   1820 
   1821 progLocalParam: PROGRAM LOCAL '[' progLocalParamNum ']'
   1822 	{
   1823 	   memset($$, 0, sizeof($$));
   1824 	   $$[0] = state->state_param_enum;
   1825 	   $$[1] = STATE_LOCAL;
   1826 	   $$[2] = $4;
   1827 	   $$[3] = $4;
   1828 	}
   1829 	;
   1830 
   1831 progEnvParamNum: INTEGER
   1832 	{
   1833 	   if ((unsigned) $1 >= state->limits->MaxEnvParams) {
   1834 	      yyerror(& @1, state, "invalid environment parameter reference");
   1835 	      YYERROR;
   1836 	   }
   1837 	   $$ = $1;
   1838 	}
   1839 	;
   1840 
   1841 progLocalParamNum: INTEGER
   1842 	{
   1843 	   if ((unsigned) $1 >= state->limits->MaxLocalParams) {
   1844 	      yyerror(& @1, state, "invalid local parameter reference");
   1845 	      YYERROR;
   1846 	   }
   1847 	   $$ = $1;
   1848 	}
   1849 	;
   1850 
   1851 
   1852 
   1853 paramConstDecl: paramConstScalarDecl | paramConstVector;
   1854 paramConstUse: paramConstScalarUse | paramConstVector;
   1855 
   1856 paramConstScalarDecl: signedFloatConstant
   1857 	{
   1858 	   $$.count = 4;
   1859 	   $$.data[0].f = $1;
   1860 	   $$.data[1].f = $1;
   1861 	   $$.data[2].f = $1;
   1862 	   $$.data[3].f = $1;
   1863 	}
   1864 	;
   1865 
   1866 paramConstScalarUse: REAL
   1867 	{
   1868 	   $$.count = 1;
   1869 	   $$.data[0].f = $1;
   1870 	   $$.data[1].f = $1;
   1871 	   $$.data[2].f = $1;
   1872 	   $$.data[3].f = $1;
   1873 	}
   1874 	| INTEGER
   1875 	{
   1876 	   $$.count = 1;
   1877 	   $$.data[0].f = (float) $1;
   1878 	   $$.data[1].f = (float) $1;
   1879 	   $$.data[2].f = (float) $1;
   1880 	   $$.data[3].f = (float) $1;
   1881 	}
   1882 	;
   1883 
   1884 paramConstVector: '{' signedFloatConstant '}'
   1885 	{
   1886 	   $$.count = 4;
   1887 	   $$.data[0].f = $2;
   1888 	   $$.data[1].f = 0.0f;
   1889 	   $$.data[2].f = 0.0f;
   1890 	   $$.data[3].f = 1.0f;
   1891 	}
   1892 	| '{' signedFloatConstant ',' signedFloatConstant '}'
   1893 	{
   1894 	   $$.count = 4;
   1895 	   $$.data[0].f = $2;
   1896 	   $$.data[1].f = $4;
   1897 	   $$.data[2].f = 0.0f;
   1898 	   $$.data[3].f = 1.0f;
   1899 	}
   1900 	| '{' signedFloatConstant ',' signedFloatConstant ','
   1901               signedFloatConstant '}'
   1902 	{
   1903 	   $$.count = 4;
   1904 	   $$.data[0].f = $2;
   1905 	   $$.data[1].f = $4;
   1906 	   $$.data[2].f = $6;
   1907 	   $$.data[3].f = 1.0f;
   1908 	}
   1909 	| '{' signedFloatConstant ',' signedFloatConstant ','
   1910               signedFloatConstant ',' signedFloatConstant '}'
   1911 	{
   1912 	   $$.count = 4;
   1913 	   $$.data[0].f = $2;
   1914 	   $$.data[1].f = $4;
   1915 	   $$.data[2].f = $6;
   1916 	   $$.data[3].f = $8;
   1917 	}
   1918 	;
   1919 
   1920 signedFloatConstant: optionalSign REAL
   1921 	{
   1922 	   $$ = ($1) ? -$2 : $2;
   1923 	}
   1924 	| optionalSign INTEGER
   1925 	{
   1926 	   $$ = (float)(($1) ? -$2 : $2);
   1927 	}
   1928 	;
   1929 
   1930 optionalSign: '+'        { $$ = FALSE; }
   1931 	| '-'            { $$ = TRUE;  }
   1932 	|                { $$ = FALSE; }
   1933 	;
   1934 
   1935 TEMP_statement: optVarSize TEMP { $<integer>$ = $2; } varNameList
   1936 	;
   1937 
   1938 optVarSize: string
   1939 	{
   1940 	   /* NV_fragment_program_option defines the size qualifiers in a
   1941 	    * fairly broken way.  "SHORT" or "LONG" can optionally be used
   1942 	    * before TEMP or OUTPUT.  However, neither is a reserved word!
   1943 	    * This means that we have to parse it as an identifier, then check
   1944 	    * to make sure it's one of the valid values.  *sigh*
   1945 	    *
   1946 	    * In addition, the grammar in the extension spec does *not* allow
   1947 	    * the size specifier to be optional, but all known implementations
   1948 	    * do.
   1949 	    */
   1950 	   if (!state->option.NV_fragment) {
   1951 	      yyerror(& @1, state, "unexpected IDENTIFIER");
   1952 	      YYERROR;
   1953 	   }
   1954 
   1955 	   if (strcmp("SHORT", $1) == 0) {
   1956 	   } else if (strcmp("LONG", $1) == 0) {
   1957 	   } else {
   1958 	      char *const err_str =
   1959 		 make_error_string("invalid storage size specifier \"%s\"",
   1960 				   $1);
   1961 
   1962 	      yyerror(& @1, state, (err_str != NULL)
   1963 		      ? err_str : "invalid storage size specifier");
   1964 
   1965 	      if (err_str != NULL) {
   1966 		 free(err_str);
   1967 	      }
   1968 
   1969 	      YYERROR;
   1970 	   }
   1971 	}
   1972 	|
   1973 	{
   1974 	}
   1975 	;
   1976 
   1977 ADDRESS_statement: ADDRESS { $<integer>$ = $1; } varNameList
   1978 	;
   1979 
   1980 varNameList: varNameList ',' IDENTIFIER
   1981 	{
   1982 	   if (!declare_variable(state, $3, $<integer>0, & @3)) {
   1983 	      free($3);
   1984 	      YYERROR;
   1985 	   }
   1986 	}
   1987 	| IDENTIFIER
   1988 	{
   1989 	   if (!declare_variable(state, $1, $<integer>0, & @1)) {
   1990 	      free($1);
   1991 	      YYERROR;
   1992 	   }
   1993 	}
   1994 	;
   1995 
   1996 OUTPUT_statement: optVarSize OUTPUT IDENTIFIER '=' resultBinding
   1997 	{
   1998 	   struct asm_symbol *const s =
   1999 	      declare_variable(state, $3, at_output, & @3);
   2000 
   2001 	   if (s == NULL) {
   2002 	      free($3);
   2003 	      YYERROR;
   2004 	   } else {
   2005 	      s->output_binding = $5;
   2006 	   }
   2007 	}
   2008 	;
   2009 
   2010 resultBinding: RESULT POSITION
   2011 	{
   2012 	   if (state->mode == ARB_vertex) {
   2013 	      $$ = VERT_RESULT_HPOS;
   2014 	   } else {
   2015 	      yyerror(& @2, state, "invalid program result name");
   2016 	      YYERROR;
   2017 	   }
   2018 	}
   2019 	| RESULT FOGCOORD
   2020 	{
   2021 	   if (state->mode == ARB_vertex) {
   2022 	      $$ = VERT_RESULT_FOGC;
   2023 	   } else {
   2024 	      yyerror(& @2, state, "invalid program result name");
   2025 	      YYERROR;
   2026 	   }
   2027 	}
   2028 	| RESULT resultColBinding
   2029 	{
   2030 	   $$ = $2;
   2031 	}
   2032 	| RESULT POINTSIZE
   2033 	{
   2034 	   if (state->mode == ARB_vertex) {
   2035 	      $$ = VERT_RESULT_PSIZ;
   2036 	   } else {
   2037 	      yyerror(& @2, state, "invalid program result name");
   2038 	      YYERROR;
   2039 	   }
   2040 	}
   2041 	| RESULT TEXCOORD optTexCoordUnitNum
   2042 	{
   2043 	   if (state->mode == ARB_vertex) {
   2044 	      $$ = VERT_RESULT_TEX0 + $3;
   2045 	   } else {
   2046 	      yyerror(& @2, state, "invalid program result name");
   2047 	      YYERROR;
   2048 	   }
   2049 	}
   2050 	| RESULT DEPTH
   2051 	{
   2052 	   if (state->mode == ARB_fragment) {
   2053 	      $$ = FRAG_RESULT_DEPTH;
   2054 	   } else {
   2055 	      yyerror(& @2, state, "invalid program result name");
   2056 	      YYERROR;
   2057 	   }
   2058 	}
   2059 	;
   2060 
   2061 resultColBinding: COLOR optResultFaceType optResultColorType
   2062 	{
   2063 	   $$ = $2 + $3;
   2064 	}
   2065 	;
   2066 
   2067 optResultFaceType:
   2068 	{
   2069 	   if (state->mode == ARB_vertex) {
   2070 	      $$ = VERT_RESULT_COL0;
   2071 	   } else {
   2072 	      if (state->option.DrawBuffers)
   2073 		 $$ = FRAG_RESULT_DATA0;
   2074 	      else
   2075 		 $$ = FRAG_RESULT_COLOR;
   2076 	   }
   2077 	}
   2078 	| '[' INTEGER ']'
   2079 	{
   2080 	   if (state->mode == ARB_vertex) {
   2081 	      yyerror(& @1, state, "invalid program result name");
   2082 	      YYERROR;
   2083 	   } else {
   2084 	      if (!state->option.DrawBuffers) {
   2085 		 /* From the ARB_draw_buffers spec (same text exists
   2086 		  * for ATI_draw_buffers):
   2087 		  *
   2088 		  *     If this option is not specified, a fragment
   2089 		  *     program that attempts to bind
   2090 		  *     "result.color[n]" will fail to load, and only
   2091 		  *     "result.color" will be allowed.
   2092 		  */
   2093 		 yyerror(& @1, state,
   2094 			 "result.color[] used without "
   2095 			 "`OPTION ARB_draw_buffers' or "
   2096 			 "`OPTION ATI_draw_buffers'");
   2097 		 YYERROR;
   2098 	      } else if ($2 >= state->MaxDrawBuffers) {
   2099 		 yyerror(& @1, state,
   2100 			 "result.color[] exceeds MAX_DRAW_BUFFERS_ARB");
   2101 		 YYERROR;
   2102 	      }
   2103 	      $$ = FRAG_RESULT_DATA0 + $2;
   2104 	   }
   2105 	}
   2106 	| FRONT
   2107 	{
   2108 	   if (state->mode == ARB_vertex) {
   2109 	      $$ = VERT_RESULT_COL0;
   2110 	   } else {
   2111 	      yyerror(& @1, state, "invalid program result name");
   2112 	      YYERROR;
   2113 	   }
   2114 	}
   2115 	| BACK
   2116 	{
   2117 	   if (state->mode == ARB_vertex) {
   2118 	      $$ = VERT_RESULT_BFC0;
   2119 	   } else {
   2120 	      yyerror(& @1, state, "invalid program result name");
   2121 	      YYERROR;
   2122 	   }
   2123 	}
   2124 	;
   2125 
   2126 optResultColorType:
   2127 	{
   2128 	   $$ = 0;
   2129 	}
   2130 	| PRIMARY
   2131 	{
   2132 	   if (state->mode == ARB_vertex) {
   2133 	      $$ = 0;
   2134 	   } else {
   2135 	      yyerror(& @1, state, "invalid program result name");
   2136 	      YYERROR;
   2137 	   }
   2138 	}
   2139 	| SECONDARY
   2140 	{
   2141 	   if (state->mode == ARB_vertex) {
   2142 	      $$ = 1;
   2143 	   } else {
   2144 	      yyerror(& @1, state, "invalid program result name");
   2145 	      YYERROR;
   2146 	   }
   2147 	}
   2148 	;
   2149 
   2150 optFaceType:    { $$ = 0; }
   2151 	| FRONT	{ $$ = 0; }
   2152 	| BACK  { $$ = 1; }
   2153 	;
   2154 
   2155 optColorType:       { $$ = 0; }
   2156 	| PRIMARY   { $$ = 0; }
   2157 	| SECONDARY { $$ = 1; }
   2158 	;
   2159 
   2160 optTexCoordUnitNum:                { $$ = 0; }
   2161 	| '[' texCoordUnitNum ']'  { $$ = $2; }
   2162 	;
   2163 
   2164 optTexImageUnitNum:                { $$ = 0; }
   2165 	| '[' texImageUnitNum ']'  { $$ = $2; }
   2166 	;
   2167 
   2168 optLegacyTexUnitNum:               { $$ = 0; }
   2169 	| '[' legacyTexUnitNum ']' { $$ = $2; }
   2170 	;
   2171 
   2172 texCoordUnitNum: INTEGER
   2173 	{
   2174 	   if ((unsigned) $1 >= state->MaxTextureCoordUnits) {
   2175 	      yyerror(& @1, state, "invalid texture coordinate unit selector");
   2176 	      YYERROR;
   2177 	   }
   2178 
   2179 	   $$ = $1;
   2180 	}
   2181 	;
   2182 
   2183 texImageUnitNum: INTEGER
   2184 	{
   2185 	   if ((unsigned) $1 >= state->MaxTextureImageUnits) {
   2186 	      yyerror(& @1, state, "invalid texture image unit selector");
   2187 	      YYERROR;
   2188 	   }
   2189 
   2190 	   $$ = $1;
   2191 	}
   2192 	;
   2193 
   2194 legacyTexUnitNum: INTEGER
   2195 	{
   2196 	   if ((unsigned) $1 >= state->MaxTextureUnits) {
   2197 	      yyerror(& @1, state, "invalid texture unit selector");
   2198 	      YYERROR;
   2199 	   }
   2200 
   2201 	   $$ = $1;
   2202 	}
   2203 	;
   2204 
   2205 ALIAS_statement: ALIAS IDENTIFIER '=' USED_IDENTIFIER
   2206 	{
   2207 	   struct asm_symbol *exist = (struct asm_symbol *)
   2208 	      _mesa_symbol_table_find_symbol(state->st, 0, $2);
   2209 	   struct asm_symbol *target = (struct asm_symbol *)
   2210 	      _mesa_symbol_table_find_symbol(state->st, 0, $4);
   2211 
   2212 	   free($4);
   2213 
   2214 	   if (exist != NULL) {
   2215 	      char m[1000];
   2216 	      _mesa_snprintf(m, sizeof(m), "redeclared identifier: %s", $2);
   2217 	      free($2);
   2218 	      yyerror(& @2, state, m);
   2219 	      YYERROR;
   2220 	   } else if (target == NULL) {
   2221 	      free($2);
   2222 	      yyerror(& @4, state,
   2223 		      "undefined variable binding in ALIAS statement");
   2224 	      YYERROR;
   2225 	   } else {
   2226 	      _mesa_symbol_table_add_symbol(state->st, 0, $2, target);
   2227 	   }
   2228 	}
   2229 	;
   2230 
   2231 string: IDENTIFIER
   2232 	| USED_IDENTIFIER
   2233 	;
   2234 
   2235 %%
   2236 
   2237 void
   2238 asm_instruction_set_operands(struct asm_instruction *inst,
   2239 			     const struct prog_dst_register *dst,
   2240 			     const struct asm_src_register *src0,
   2241 			     const struct asm_src_register *src1,
   2242 			     const struct asm_src_register *src2)
   2243 {
   2244    /* In the core ARB extensions only the KIL instruction doesn't have a
   2245     * destination register.
   2246     */
   2247    if (dst == NULL) {
   2248       init_dst_reg(& inst->Base.DstReg);
   2249    } else {
   2250       inst->Base.DstReg = *dst;
   2251    }
   2252 
   2253    /* The only instruction that doesn't have any source registers is the
   2254     * condition-code based KIL instruction added by NV_fragment_program_option.
   2255     */
   2256    if (src0 != NULL) {
   2257       inst->Base.SrcReg[0] = src0->Base;
   2258       inst->SrcReg[0] = *src0;
   2259    } else {
   2260       init_src_reg(& inst->SrcReg[0]);
   2261    }
   2262 
   2263    if (src1 != NULL) {
   2264       inst->Base.SrcReg[1] = src1->Base;
   2265       inst->SrcReg[1] = *src1;
   2266    } else {
   2267       init_src_reg(& inst->SrcReg[1]);
   2268    }
   2269 
   2270    if (src2 != NULL) {
   2271       inst->Base.SrcReg[2] = src2->Base;
   2272       inst->SrcReg[2] = *src2;
   2273    } else {
   2274       init_src_reg(& inst->SrcReg[2]);
   2275    }
   2276 }
   2277 
   2278 
   2279 struct asm_instruction *
   2280 asm_instruction_ctor(gl_inst_opcode op,
   2281 		     const struct prog_dst_register *dst,
   2282 		     const struct asm_src_register *src0,
   2283 		     const struct asm_src_register *src1,
   2284 		     const struct asm_src_register *src2)
   2285 {
   2286    struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
   2287 
   2288    if (inst) {
   2289       _mesa_init_instructions(& inst->Base, 1);
   2290       inst->Base.Opcode = op;
   2291 
   2292       asm_instruction_set_operands(inst, dst, src0, src1, src2);
   2293    }
   2294 
   2295    return inst;
   2296 }
   2297 
   2298 
   2299 struct asm_instruction *
   2300 asm_instruction_copy_ctor(const struct prog_instruction *base,
   2301 			  const struct prog_dst_register *dst,
   2302 			  const struct asm_src_register *src0,
   2303 			  const struct asm_src_register *src1,
   2304 			  const struct asm_src_register *src2)
   2305 {
   2306    struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
   2307 
   2308    if (inst) {
   2309       _mesa_init_instructions(& inst->Base, 1);
   2310       inst->Base.Opcode = base->Opcode;
   2311       inst->Base.CondUpdate = base->CondUpdate;
   2312       inst->Base.CondDst = base->CondDst;
   2313       inst->Base.SaturateMode = base->SaturateMode;
   2314       inst->Base.Precision = base->Precision;
   2315 
   2316       asm_instruction_set_operands(inst, dst, src0, src1, src2);
   2317    }
   2318 
   2319    return inst;
   2320 }
   2321 
   2322 
   2323 void
   2324 init_dst_reg(struct prog_dst_register *r)
   2325 {
   2326    memset(r, 0, sizeof(*r));
   2327    r->File = PROGRAM_UNDEFINED;
   2328    r->WriteMask = WRITEMASK_XYZW;
   2329    r->CondMask = COND_TR;
   2330    r->CondSwizzle = SWIZZLE_NOOP;
   2331 }
   2332 
   2333 
   2334 /** Like init_dst_reg() but set the File and Index fields. */
   2335 void
   2336 set_dst_reg(struct prog_dst_register *r, gl_register_file file, GLint index)
   2337 {
   2338    const GLint maxIndex = 1 << INST_INDEX_BITS;
   2339    const GLint minIndex = 0;
   2340    ASSERT(index >= minIndex);
   2341    (void) minIndex;
   2342    ASSERT(index <= maxIndex);
   2343    (void) maxIndex;
   2344    ASSERT(file == PROGRAM_TEMPORARY ||
   2345 	  file == PROGRAM_ADDRESS ||
   2346 	  file == PROGRAM_OUTPUT);
   2347    memset(r, 0, sizeof(*r));
   2348    r->File = file;
   2349    r->Index = index;
   2350    r->WriteMask = WRITEMASK_XYZW;
   2351    r->CondMask = COND_TR;
   2352    r->CondSwizzle = SWIZZLE_NOOP;
   2353 }
   2354 
   2355 
   2356 void
   2357 init_src_reg(struct asm_src_register *r)
   2358 {
   2359    memset(r, 0, sizeof(*r));
   2360    r->Base.File = PROGRAM_UNDEFINED;
   2361    r->Base.Swizzle = SWIZZLE_NOOP;
   2362    r->Symbol = NULL;
   2363 }
   2364 
   2365 
   2366 /** Like init_src_reg() but set the File and Index fields.
   2367  * \return GL_TRUE if a valid src register, GL_FALSE otherwise
   2368  */
   2369 void
   2370 set_src_reg(struct asm_src_register *r, gl_register_file file, GLint index)
   2371 {
   2372    set_src_reg_swz(r, file, index, SWIZZLE_XYZW);
   2373 }
   2374 
   2375 
   2376 void
   2377 set_src_reg_swz(struct asm_src_register *r, gl_register_file file, GLint index,
   2378                 GLuint swizzle)
   2379 {
   2380    const GLint maxIndex = (1 << INST_INDEX_BITS) - 1;
   2381    const GLint minIndex = -(1 << INST_INDEX_BITS);
   2382    ASSERT(file < PROGRAM_FILE_MAX);
   2383    ASSERT(index >= minIndex);
   2384    (void) minIndex;
   2385    ASSERT(index <= maxIndex);
   2386    (void) maxIndex;
   2387    memset(r, 0, sizeof(*r));
   2388    r->Base.File = file;
   2389    r->Base.Index = index;
   2390    r->Base.Swizzle = swizzle;
   2391    r->Symbol = NULL;
   2392 }
   2393 
   2394 
   2395 /**
   2396  * Validate the set of inputs used by a program
   2397  *
   2398  * Validates that legal sets of inputs are used by the program.  In this case
   2399  * "used" included both reading the input or binding the input to a name using
   2400  * the \c ATTRIB command.
   2401  *
   2402  * \return
   2403  * \c TRUE if the combination of inputs used is valid, \c FALSE otherwise.
   2404  */
   2405 int
   2406 validate_inputs(struct YYLTYPE *locp, struct asm_parser_state *state)
   2407 {
   2408    const GLbitfield64 inputs = state->prog->InputsRead | state->InputsBound;
   2409 
   2410    if (((inputs & VERT_BIT_FF_ALL) & (inputs >> VERT_ATTRIB_GENERIC0)) != 0) {
   2411       yyerror(locp, state, "illegal use of generic attribute and name attribute");
   2412       return 0;
   2413    }
   2414 
   2415    return 1;
   2416 }
   2417 
   2418 
   2419 struct asm_symbol *
   2420 declare_variable(struct asm_parser_state *state, char *name, enum asm_type t,
   2421 		 struct YYLTYPE *locp)
   2422 {
   2423    struct asm_symbol *s = NULL;
   2424    struct asm_symbol *exist = (struct asm_symbol *)
   2425       _mesa_symbol_table_find_symbol(state->st, 0, name);
   2426 
   2427 
   2428    if (exist != NULL) {
   2429       yyerror(locp, state, "redeclared identifier");
   2430    } else {
   2431       s = calloc(1, sizeof(struct asm_symbol));
   2432       s->name = name;
   2433       s->type = t;
   2434 
   2435       switch (t) {
   2436       case at_temp:
   2437 	 if (state->prog->NumTemporaries >= state->limits->MaxTemps) {
   2438 	    yyerror(locp, state, "too many temporaries declared");
   2439 	    free(s);
   2440 	    return NULL;
   2441 	 }
   2442 
   2443 	 s->temp_binding = state->prog->NumTemporaries;
   2444 	 state->prog->NumTemporaries++;
   2445 	 break;
   2446 
   2447       case at_address:
   2448 	 if (state->prog->NumAddressRegs >= state->limits->MaxAddressRegs) {
   2449 	    yyerror(locp, state, "too many address registers declared");
   2450 	    free(s);
   2451 	    return NULL;
   2452 	 }
   2453 
   2454 	 /* FINISHME: Add support for multiple address registers.
   2455 	  */
   2456 	 state->prog->NumAddressRegs++;
   2457 	 break;
   2458 
   2459       default:
   2460 	 break;
   2461       }
   2462 
   2463       _mesa_symbol_table_add_symbol(state->st, 0, s->name, s);
   2464       s->next = state->sym;
   2465       state->sym = s;
   2466    }
   2467 
   2468    return s;
   2469 }
   2470 
   2471 
   2472 int add_state_reference(struct gl_program_parameter_list *param_list,
   2473 			const gl_state_index tokens[STATE_LENGTH])
   2474 {
   2475    const GLuint size = 4; /* XXX fix */
   2476    char *name;
   2477    GLint index;
   2478 
   2479    name = _mesa_program_state_string(tokens);
   2480    index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name,
   2481                                size, GL_NONE, NULL, tokens, 0x0);
   2482    param_list->StateFlags |= _mesa_program_state_flags(tokens);
   2483 
   2484    /* free name string here since we duplicated it in add_parameter() */
   2485    free(name);
   2486 
   2487    return index;
   2488 }
   2489 
   2490 
   2491 int
   2492 initialize_symbol_from_state(struct gl_program *prog,
   2493 			     struct asm_symbol *param_var,
   2494 			     const gl_state_index tokens[STATE_LENGTH])
   2495 {
   2496    int idx = -1;
   2497    gl_state_index state_tokens[STATE_LENGTH];
   2498 
   2499 
   2500    memcpy(state_tokens, tokens, sizeof(state_tokens));
   2501 
   2502    param_var->type = at_param;
   2503    param_var->param_binding_type = PROGRAM_STATE_VAR;
   2504 
   2505    /* If we are adding a STATE_MATRIX that has multiple rows, we need to
   2506     * unroll it and call add_state_reference() for each row
   2507     */
   2508    if ((state_tokens[0] == STATE_MODELVIEW_MATRIX ||
   2509 	state_tokens[0] == STATE_PROJECTION_MATRIX ||
   2510 	state_tokens[0] == STATE_MVP_MATRIX ||
   2511 	state_tokens[0] == STATE_TEXTURE_MATRIX ||
   2512 	state_tokens[0] == STATE_PROGRAM_MATRIX)
   2513        && (state_tokens[2] != state_tokens[3])) {
   2514       int row;
   2515       const int first_row = state_tokens[2];
   2516       const int last_row = state_tokens[3];
   2517 
   2518       for (row = first_row; row <= last_row; row++) {
   2519 	 state_tokens[2] = state_tokens[3] = row;
   2520 
   2521 	 idx = add_state_reference(prog->Parameters, state_tokens);
   2522 	 if (param_var->param_binding_begin == ~0U) {
   2523 	    param_var->param_binding_begin = idx;
   2524             param_var->param_binding_swizzle = SWIZZLE_XYZW;
   2525          }
   2526 
   2527 	 param_var->param_binding_length++;
   2528       }
   2529    }
   2530    else {
   2531       idx = add_state_reference(prog->Parameters, state_tokens);
   2532       if (param_var->param_binding_begin == ~0U) {
   2533 	 param_var->param_binding_begin = idx;
   2534          param_var->param_binding_swizzle = SWIZZLE_XYZW;
   2535       }
   2536       param_var->param_binding_length++;
   2537    }
   2538 
   2539    return idx;
   2540 }
   2541 
   2542 
   2543 int
   2544 initialize_symbol_from_param(struct gl_program *prog,
   2545 			     struct asm_symbol *param_var,
   2546 			     const gl_state_index tokens[STATE_LENGTH])
   2547 {
   2548    int idx = -1;
   2549    gl_state_index state_tokens[STATE_LENGTH];
   2550 
   2551 
   2552    memcpy(state_tokens, tokens, sizeof(state_tokens));
   2553 
   2554    assert((state_tokens[0] == STATE_VERTEX_PROGRAM)
   2555 	  || (state_tokens[0] == STATE_FRAGMENT_PROGRAM));
   2556    assert((state_tokens[1] == STATE_ENV)
   2557 	  || (state_tokens[1] == STATE_LOCAL));
   2558 
   2559    /*
   2560     * The param type is STATE_VAR.  The program parameter entry will
   2561     * effectively be a pointer into the LOCAL or ENV parameter array.
   2562     */
   2563    param_var->type = at_param;
   2564    param_var->param_binding_type = PROGRAM_STATE_VAR;
   2565 
   2566    /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements,
   2567     * we need to unroll it and call add_state_reference() for each row
   2568     */
   2569    if (state_tokens[2] != state_tokens[3]) {
   2570       int row;
   2571       const int first_row = state_tokens[2];
   2572       const int last_row = state_tokens[3];
   2573 
   2574       for (row = first_row; row <= last_row; row++) {
   2575 	 state_tokens[2] = state_tokens[3] = row;
   2576 
   2577 	 idx = add_state_reference(prog->Parameters, state_tokens);
   2578 	 if (param_var->param_binding_begin == ~0U) {
   2579 	    param_var->param_binding_begin = idx;
   2580             param_var->param_binding_swizzle = SWIZZLE_XYZW;
   2581          }
   2582 	 param_var->param_binding_length++;
   2583       }
   2584    }
   2585    else {
   2586       idx = add_state_reference(prog->Parameters, state_tokens);
   2587       if (param_var->param_binding_begin == ~0U) {
   2588 	 param_var->param_binding_begin = idx;
   2589          param_var->param_binding_swizzle = SWIZZLE_XYZW;
   2590       }
   2591       param_var->param_binding_length++;
   2592    }
   2593 
   2594    return idx;
   2595 }
   2596 
   2597 
   2598 /**
   2599  * Put a float/vector constant/literal into the parameter list.
   2600  * \param param_var  returns info about the parameter/constant's location,
   2601  *                   binding, type, etc.
   2602  * \param vec  the vector/constant to add
   2603  * \param allowSwizzle  if true, try to consolidate constants which only differ
   2604  *                      by a swizzle.  We don't want to do this when building
   2605  *                      arrays of constants that may be indexed indirectly.
   2606  * \return index of the constant in the parameter list.
   2607  */
   2608 int
   2609 initialize_symbol_from_const(struct gl_program *prog,
   2610 			     struct asm_symbol *param_var,
   2611 			     const struct asm_vector *vec,
   2612                              GLboolean allowSwizzle)
   2613 {
   2614    unsigned swizzle;
   2615    const int idx = _mesa_add_unnamed_constant(prog->Parameters,
   2616                                               vec->data, vec->count,
   2617                                               allowSwizzle ? &swizzle : NULL);
   2618 
   2619    param_var->type = at_param;
   2620    param_var->param_binding_type = PROGRAM_CONSTANT;
   2621 
   2622    if (param_var->param_binding_begin == ~0U) {
   2623       param_var->param_binding_begin = idx;
   2624       param_var->param_binding_swizzle = allowSwizzle ? swizzle : SWIZZLE_XYZW;
   2625    }
   2626    param_var->param_binding_length++;
   2627 
   2628    return idx;
   2629 }
   2630 
   2631 
   2632 char *
   2633 make_error_string(const char *fmt, ...)
   2634 {
   2635    int length;
   2636    char *str;
   2637    va_list args;
   2638 
   2639 
   2640    /* Call vsnprintf once to determine how large the final string is.  Call it
   2641     * again to do the actual formatting.  from the vsnprintf manual page:
   2642     *
   2643     *    Upon successful return, these functions return the number of
   2644     *    characters printed  (not including the trailing '\0' used to end
   2645     *    output to strings).
   2646     */
   2647    va_start(args, fmt);
   2648    length = 1 + vsnprintf(NULL, 0, fmt, args);
   2649    va_end(args);
   2650 
   2651    str = malloc(length);
   2652    if (str) {
   2653       va_start(args, fmt);
   2654       vsnprintf(str, length, fmt, args);
   2655       va_end(args);
   2656    }
   2657 
   2658    return str;
   2659 }
   2660 
   2661 
   2662 void
   2663 yyerror(YYLTYPE *locp, struct asm_parser_state *state, const char *s)
   2664 {
   2665    char *err_str;
   2666 
   2667 
   2668    err_str = make_error_string("glProgramStringARB(%s)\n", s);
   2669    if (err_str) {
   2670       _mesa_error(state->ctx, GL_INVALID_OPERATION, "%s", err_str);
   2671       free(err_str);
   2672    }
   2673 
   2674    err_str = make_error_string("line %u, char %u: error: %s\n",
   2675 			       locp->first_line, locp->first_column, s);
   2676    _mesa_set_program_error(state->ctx, locp->position, err_str);
   2677 
   2678    if (err_str) {
   2679       free(err_str);
   2680    }
   2681 }
   2682 
   2683 
   2684 GLboolean
   2685 _mesa_parse_arb_program(struct gl_context *ctx, GLenum target, const GLubyte *str,
   2686 			GLsizei len, struct asm_parser_state *state)
   2687 {
   2688    struct asm_instruction *inst;
   2689    unsigned i;
   2690    GLubyte *strz;
   2691    GLboolean result = GL_FALSE;
   2692    void *temp;
   2693    struct asm_symbol *sym;
   2694 
   2695    state->ctx = ctx;
   2696    state->prog->Target = target;
   2697    state->prog->Parameters = _mesa_new_parameter_list();
   2698 
   2699    /* Make a copy of the program string and force it to be NUL-terminated.
   2700     */
   2701    strz = (GLubyte *) malloc(len + 1);
   2702    if (strz == NULL) {
   2703       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
   2704       return GL_FALSE;
   2705    }
   2706    memcpy (strz, str, len);
   2707    strz[len] = '\0';
   2708 
   2709    state->prog->String = strz;
   2710 
   2711    state->st = _mesa_symbol_table_ctor();
   2712 
   2713    state->limits = (target == GL_VERTEX_PROGRAM_ARB)
   2714       ? & ctx->Const.VertexProgram
   2715       : & ctx->Const.FragmentProgram;
   2716 
   2717    state->MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits;
   2718    state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits;
   2719    state->MaxTextureUnits = ctx->Const.MaxTextureUnits;
   2720    state->MaxClipPlanes = ctx->Const.MaxClipPlanes;
   2721    state->MaxLights = ctx->Const.MaxLights;
   2722    state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices;
   2723    state->MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
   2724 
   2725    state->state_param_enum = (target == GL_VERTEX_PROGRAM_ARB)
   2726       ? STATE_VERTEX_PROGRAM : STATE_FRAGMENT_PROGRAM;
   2727 
   2728    _mesa_set_program_error(ctx, -1, NULL);
   2729 
   2730    _mesa_program_lexer_ctor(& state->scanner, state, (const char *) str, len);
   2731    yyparse(state);
   2732    _mesa_program_lexer_dtor(state->scanner);
   2733 
   2734 
   2735    if (ctx->Program.ErrorPos != -1) {
   2736       goto error;
   2737    }
   2738 
   2739    if (! _mesa_layout_parameters(state)) {
   2740       struct YYLTYPE loc;
   2741 
   2742       loc.first_line = 0;
   2743       loc.first_column = 0;
   2744       loc.position = len;
   2745 
   2746       yyerror(& loc, state, "invalid PARAM usage");
   2747       goto error;
   2748    }
   2749 
   2750 
   2751 
   2752    /* Add one instruction to store the "END" instruction.
   2753     */
   2754    state->prog->Instructions =
   2755       _mesa_alloc_instructions(state->prog->NumInstructions + 1);
   2756    inst = state->inst_head;
   2757    for (i = 0; i < state->prog->NumInstructions; i++) {
   2758       struct asm_instruction *const temp = inst->next;
   2759 
   2760       state->prog->Instructions[i] = inst->Base;
   2761       inst = temp;
   2762    }
   2763 
   2764    /* Finally, tag on an OPCODE_END instruction */
   2765    {
   2766       const GLuint numInst = state->prog->NumInstructions;
   2767       _mesa_init_instructions(state->prog->Instructions + numInst, 1);
   2768       state->prog->Instructions[numInst].Opcode = OPCODE_END;
   2769    }
   2770    state->prog->NumInstructions++;
   2771 
   2772    state->prog->NumParameters = state->prog->Parameters->NumParameters;
   2773    state->prog->NumAttributes = _mesa_bitcount_64(state->prog->InputsRead);
   2774 
   2775    /*
   2776     * Initialize native counts to logical counts.  The device driver may
   2777     * change them if program is translated into a hardware program.
   2778     */
   2779    state->prog->NumNativeInstructions = state->prog->NumInstructions;
   2780    state->prog->NumNativeTemporaries = state->prog->NumTemporaries;
   2781    state->prog->NumNativeParameters = state->prog->NumParameters;
   2782    state->prog->NumNativeAttributes = state->prog->NumAttributes;
   2783    state->prog->NumNativeAddressRegs = state->prog->NumAddressRegs;
   2784 
   2785    result = GL_TRUE;
   2786 
   2787 error:
   2788    for (inst = state->inst_head; inst != NULL; inst = temp) {
   2789       temp = inst->next;
   2790       free(inst);
   2791    }
   2792 
   2793    state->inst_head = NULL;
   2794    state->inst_tail = NULL;
   2795 
   2796    for (sym = state->sym; sym != NULL; sym = temp) {
   2797       temp = sym->next;
   2798 
   2799       free((void *) sym->name);
   2800       free(sym);
   2801    }
   2802    state->sym = NULL;
   2803 
   2804    _mesa_symbol_table_dtor(state->st);
   2805    state->st = NULL;
   2806 
   2807    return result;
   2808 }
   2809