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