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