1848b8605Smrg%{
2848b8605Smrg/*
3848b8605Smrg * Copyright © 2009 Intel Corporation
4848b8605Smrg *
5848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
6848b8605Smrg * copy of this software and associated documentation files (the "Software"),
7848b8605Smrg * to deal in the Software without restriction, including without limitation
8848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the
10848b8605Smrg * Software is furnished to do so, subject to the following conditions:
11848b8605Smrg *
12848b8605Smrg * The above copyright notice and this permission notice (including the next
13848b8605Smrg * paragraph) shall be included in all copies or substantial portions of the
14848b8605Smrg * Software.
15848b8605Smrg *
16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20848b8605Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21848b8605Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22848b8605Smrg * DEALINGS IN THE SOFTWARE.
23848b8605Smrg */
24b8e80941Smrg
25b8e80941Smrg#include <stdarg.h>
26848b8605Smrg#include <stdio.h>
27848b8605Smrg#include <stdlib.h>
28848b8605Smrg#include <string.h>
29848b8605Smrg
30b8e80941Smrg#include "main/errors.h"
31848b8605Smrg#include "main/mtypes.h"
32848b8605Smrg#include "main/imports.h"
33848b8605Smrg#include "program/program.h"
34848b8605Smrg#include "program/prog_parameter.h"
35848b8605Smrg#include "program/prog_parameter_layout.h"
36848b8605Smrg#include "program/prog_statevars.h"
37848b8605Smrg#include "program/prog_instruction.h"
38848b8605Smrg
39848b8605Smrg#include "program/symbol_table.h"
40848b8605Smrg#include "program/program_parser.h"
41848b8605Smrg
42b8e80941Smrg#include "util/u_math.h"
43b8e80941Smrg
44848b8605Smrgextern void *yy_scan_string(char *);
45848b8605Smrgextern void yy_delete_buffer(void *);
46848b8605Smrg
47848b8605Smrgstatic struct asm_symbol *declare_variable(struct asm_parser_state *state,
48848b8605Smrg    char *name, enum asm_type t, struct YYLTYPE *locp);
49848b8605Smrg
50848b8605Smrgstatic int add_state_reference(struct gl_program_parameter_list *param_list,
51b8e80941Smrg    const gl_state_index16 tokens[STATE_LENGTH]);
52848b8605Smrg
53848b8605Smrgstatic int initialize_symbol_from_state(struct gl_program *prog,
54b8e80941Smrg    struct asm_symbol *param_var, const gl_state_index16 tokens[STATE_LENGTH]);
55848b8605Smrg
56848b8605Smrgstatic int initialize_symbol_from_param(struct gl_program *prog,
57b8e80941Smrg    struct asm_symbol *param_var, const gl_state_index16 tokens[STATE_LENGTH]);
58848b8605Smrg
59848b8605Smrgstatic int initialize_symbol_from_const(struct gl_program *prog,
60848b8605Smrg    struct asm_symbol *param_var, const struct asm_vector *vec,
61848b8605Smrg    GLboolean allowSwizzle);
62848b8605Smrg
63848b8605Smrgstatic int yyparse(struct asm_parser_state *state);
64848b8605Smrg
65848b8605Smrgstatic char *make_error_string(const char *fmt, ...);
66848b8605Smrg
67848b8605Smrgstatic void yyerror(struct YYLTYPE *locp, struct asm_parser_state *state,
68848b8605Smrg    const char *s);
69848b8605Smrg
70848b8605Smrgstatic int validate_inputs(struct YYLTYPE *locp,
71848b8605Smrg    struct asm_parser_state *state);
72848b8605Smrg
73848b8605Smrgstatic void init_dst_reg(struct prog_dst_register *r);
74848b8605Smrg
75848b8605Smrgstatic void set_dst_reg(struct prog_dst_register *r,
76848b8605Smrg                        gl_register_file file, GLint index);
77848b8605Smrg
78848b8605Smrgstatic void init_src_reg(struct asm_src_register *r);
79848b8605Smrg
80848b8605Smrgstatic void set_src_reg(struct asm_src_register *r,
81848b8605Smrg                        gl_register_file file, GLint index);
82848b8605Smrg
83848b8605Smrgstatic void set_src_reg_swz(struct asm_src_register *r,
84848b8605Smrg                            gl_register_file file, GLint index, GLuint swizzle);
85848b8605Smrg
86848b8605Smrgstatic void asm_instruction_set_operands(struct asm_instruction *inst,
87848b8605Smrg    const struct prog_dst_register *dst, const struct asm_src_register *src0,
88848b8605Smrg    const struct asm_src_register *src1, const struct asm_src_register *src2);
89848b8605Smrg
90b8e80941Smrgstatic struct asm_instruction *asm_instruction_ctor(enum prog_opcode op,
91848b8605Smrg    const struct prog_dst_register *dst, const struct asm_src_register *src0,
92848b8605Smrg    const struct asm_src_register *src1, const struct asm_src_register *src2);
93848b8605Smrg
94848b8605Smrgstatic struct asm_instruction *asm_instruction_copy_ctor(
95848b8605Smrg    const struct prog_instruction *base, const struct prog_dst_register *dst,
96848b8605Smrg    const struct asm_src_register *src0, const struct asm_src_register *src1,
97848b8605Smrg    const struct asm_src_register *src2);
98848b8605Smrg
99848b8605Smrg#ifndef FALSE
100848b8605Smrg#define FALSE 0
101848b8605Smrg#define TRUE (!FALSE)
102848b8605Smrg#endif
103848b8605Smrg
104848b8605Smrg#define YYLLOC_DEFAULT(Current, Rhs, N)					\
105848b8605Smrg   do {									\
106848b8605Smrg      if (N) {							\
107848b8605Smrg	 (Current).first_line = YYRHSLOC(Rhs, 1).first_line;		\
108848b8605Smrg	 (Current).first_column = YYRHSLOC(Rhs, 1).first_column;	\
109848b8605Smrg	 (Current).position = YYRHSLOC(Rhs, 1).position;		\
110848b8605Smrg	 (Current).last_line = YYRHSLOC(Rhs, N).last_line;		\
111848b8605Smrg	 (Current).last_column = YYRHSLOC(Rhs, N).last_column;		\
112848b8605Smrg      } else {								\
113848b8605Smrg	 (Current).first_line = YYRHSLOC(Rhs, 0).last_line;		\
114848b8605Smrg	 (Current).last_line = (Current).first_line;			\
115848b8605Smrg	 (Current).first_column = YYRHSLOC(Rhs, 0).last_column;		\
116848b8605Smrg	 (Current).last_column = (Current).first_column;		\
117848b8605Smrg	 (Current).position = YYRHSLOC(Rhs, 0).position			\
118848b8605Smrg	    + (Current).first_column;					\
119848b8605Smrg      }									\
120848b8605Smrg   } while(0)
121848b8605Smrg%}
122848b8605Smrg
123848b8605Smrg%pure-parser
124848b8605Smrg%locations
125848b8605Smrg%lex-param   { struct asm_parser_state *state }
126848b8605Smrg%parse-param { struct asm_parser_state *state }
127848b8605Smrg%error-verbose
128848b8605Smrg
129848b8605Smrg%union {
130848b8605Smrg   struct asm_instruction *inst;
131848b8605Smrg   struct asm_symbol *sym;
132848b8605Smrg   struct asm_symbol temp_sym;
133848b8605Smrg   struct asm_swizzle_mask swiz_mask;
134848b8605Smrg   struct asm_src_register src_reg;
135848b8605Smrg   struct prog_dst_register dst_reg;
136848b8605Smrg   struct prog_instruction temp_inst;
137848b8605Smrg   char *string;
138848b8605Smrg   unsigned result;
139848b8605Smrg   unsigned attrib;
140848b8605Smrg   int integer;
141848b8605Smrg   float real;
142b8e80941Smrg   gl_state_index16 state[STATE_LENGTH];
143848b8605Smrg   int negate;
144848b8605Smrg   struct asm_vector vector;
145b8e80941Smrg   enum prog_opcode opcode;
146848b8605Smrg
147848b8605Smrg   struct {
148848b8605Smrg      unsigned swz;
149848b8605Smrg      unsigned rgba_valid:1;
150848b8605Smrg      unsigned xyzw_valid:1;
151848b8605Smrg      unsigned negate:1;
152848b8605Smrg   } ext_swizzle;
153848b8605Smrg}
154848b8605Smrg
155848b8605Smrg%token ARBvp_10 ARBfp_10
156848b8605Smrg
157848b8605Smrg/* Tokens for assembler pseudo-ops */
158848b8605Smrg%token <integer> ADDRESS
159848b8605Smrg%token ALIAS ATTRIB
160848b8605Smrg%token OPTION OUTPUT
161848b8605Smrg%token PARAM
162848b8605Smrg%token <integer> TEMP
163848b8605Smrg%token END
164848b8605Smrg
165848b8605Smrg /* Tokens for instructions */
166848b8605Smrg%token <temp_inst> BIN_OP BINSC_OP SAMPLE_OP SCALAR_OP TRI_OP VECTOR_OP
167848b8605Smrg%token <temp_inst> ARL KIL SWZ TXD_OP
168848b8605Smrg
169848b8605Smrg%token <integer> INTEGER
170848b8605Smrg%token <real> REAL
171848b8605Smrg
172848b8605Smrg%token AMBIENT ATTENUATION
173848b8605Smrg%token BACK
174848b8605Smrg%token CLIP COLOR
175848b8605Smrg%token DEPTH DIFFUSE DIRECTION
176848b8605Smrg%token EMISSION ENV EYE
177848b8605Smrg%token FOG FOGCOORD FRAGMENT FRONT
178848b8605Smrg%token HALF
179848b8605Smrg%token INVERSE INVTRANS
180848b8605Smrg%token LIGHT LIGHTMODEL LIGHTPROD LOCAL
181848b8605Smrg%token MATERIAL MAT_PROGRAM MATRIX MATRIXINDEX MODELVIEW MVP
182848b8605Smrg%token NORMAL
183848b8605Smrg%token OBJECT
184848b8605Smrg%token PALETTE PARAMS PLANE POINT_TOK POINTSIZE POSITION PRIMARY PROGRAM PROJECTION
185848b8605Smrg%token RANGE RESULT ROW
186848b8605Smrg%token SCENECOLOR SECONDARY SHININESS SIZE_TOK SPECULAR SPOT STATE
187848b8605Smrg%token TEXCOORD TEXENV TEXGEN TEXGEN_Q TEXGEN_R TEXGEN_S TEXGEN_T TEXTURE TRANSPOSE
188848b8605Smrg%token TEXTURE_UNIT TEX_1D TEX_2D TEX_3D TEX_CUBE TEX_RECT
189848b8605Smrg%token TEX_SHADOW1D TEX_SHADOW2D TEX_SHADOWRECT
190848b8605Smrg%token TEX_ARRAY1D TEX_ARRAY2D TEX_ARRAYSHADOW1D TEX_ARRAYSHADOW2D
191848b8605Smrg%token VERTEX VTXATTRIB
192848b8605Smrg
193848b8605Smrg%token <string> IDENTIFIER USED_IDENTIFIER
194848b8605Smrg%type <string> string
195848b8605Smrg%token <swiz_mask> MASK4 MASK3 MASK2 MASK1 SWIZZLE
196848b8605Smrg%token DOT_DOT
197848b8605Smrg%token DOT
198848b8605Smrg
199848b8605Smrg%type <inst> instruction ALU_instruction TexInstruction
200848b8605Smrg%type <inst> ARL_instruction VECTORop_instruction
201848b8605Smrg%type <inst> SCALARop_instruction BINSCop_instruction BINop_instruction
202848b8605Smrg%type <inst> TRIop_instruction TXD_instruction SWZ_instruction SAMPLE_instruction
203848b8605Smrg%type <inst> KIL_instruction
204848b8605Smrg
205848b8605Smrg%type <dst_reg> dstReg maskedDstReg maskedAddrReg
206848b8605Smrg%type <src_reg> srcReg scalarUse scalarSrcReg swizzleSrcReg
207848b8605Smrg%type <swiz_mask> scalarSuffix swizzleSuffix extendedSwizzle
208848b8605Smrg%type <ext_swizzle> extSwizComp extSwizSel
209848b8605Smrg%type <swiz_mask> optionalMask
210848b8605Smrg
211848b8605Smrg%type <sym> progParamArray
212848b8605Smrg%type <integer> addrRegRelOffset addrRegPosOffset addrRegNegOffset
213848b8605Smrg%type <src_reg> progParamArrayMem progParamArrayAbs progParamArrayRel
214848b8605Smrg%type <sym> addrReg
215848b8605Smrg%type <swiz_mask> addrComponent addrWriteMask
216848b8605Smrg
217848b8605Smrg%type <result> resultBinding resultColBinding
218848b8605Smrg%type <integer> optFaceType optColorType
219848b8605Smrg%type <integer> optResultFaceType optResultColorType
220848b8605Smrg
221848b8605Smrg%type <integer> optTexImageUnitNum texImageUnitNum
222848b8605Smrg%type <integer> optTexCoordUnitNum texCoordUnitNum
223848b8605Smrg%type <integer> optLegacyTexUnitNum legacyTexUnitNum
224848b8605Smrg%type <integer> texImageUnit texTarget
225848b8605Smrg%type <integer> vtxAttribNum
226848b8605Smrg
227848b8605Smrg%type <attrib> attribBinding vtxAttribItem fragAttribItem
228848b8605Smrg
229848b8605Smrg%type <temp_sym> paramSingleInit paramSingleItemDecl
230848b8605Smrg%type <integer> optArraySize
231848b8605Smrg
232848b8605Smrg%type <state> stateSingleItem stateMultipleItem
233848b8605Smrg%type <state> stateMaterialItem
234848b8605Smrg%type <state> stateLightItem stateLightModelItem stateLightProdItem
235848b8605Smrg%type <state> stateTexGenItem stateFogItem stateClipPlaneItem statePointItem
236848b8605Smrg%type <state> stateMatrixItem stateMatrixRow stateMatrixRows
237848b8605Smrg%type <state> stateTexEnvItem stateDepthItem
238848b8605Smrg
239848b8605Smrg%type <state> stateLModProperty
240848b8605Smrg%type <state> stateMatrixName optMatrixRows
241848b8605Smrg
242848b8605Smrg%type <integer> stateMatProperty
243848b8605Smrg%type <integer> stateLightProperty stateSpotProperty
244848b8605Smrg%type <integer> stateLightNumber stateLProdProperty
245848b8605Smrg%type <integer> stateTexGenType stateTexGenCoord
246848b8605Smrg%type <integer> stateTexEnvProperty
247848b8605Smrg%type <integer> stateFogProperty
248848b8605Smrg%type <integer> stateClipPlaneNum
249848b8605Smrg%type <integer> statePointProperty
250848b8605Smrg
251848b8605Smrg%type <integer> stateOptMatModifier stateMatModifier stateMatrixRowNum
252848b8605Smrg%type <integer> stateOptModMatNum stateModMatNum statePaletteMatNum
253848b8605Smrg%type <integer> stateProgramMatNum
254848b8605Smrg
255848b8605Smrg%type <integer> ambDiffSpecProperty
256848b8605Smrg
257848b8605Smrg%type <state> programSingleItem progEnvParam progLocalParam
258848b8605Smrg%type <state> programMultipleItem progEnvParams progLocalParams
259848b8605Smrg
260848b8605Smrg%type <temp_sym> paramMultipleInit paramMultInitList paramMultipleItem
261848b8605Smrg%type <temp_sym> paramSingleItemUse
262848b8605Smrg
263848b8605Smrg%type <integer> progEnvParamNum progLocalParamNum
264848b8605Smrg%type <state> progEnvParamNums progLocalParamNums
265848b8605Smrg
266848b8605Smrg%type <vector> paramConstDecl paramConstUse
267848b8605Smrg%type <vector> paramConstScalarDecl paramConstScalarUse paramConstVector
268848b8605Smrg%type <real> signedFloatConstant
269848b8605Smrg%type <negate> optionalSign
270848b8605Smrg
271848b8605Smrg%{
272848b8605Smrgextern int
273848b8605Smrg_mesa_program_lexer_lex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
274848b8605Smrg                        void *yyscanner);
275848b8605Smrg
276848b8605Smrgstatic int
277848b8605Smrgyylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
278848b8605Smrg      struct asm_parser_state *state)
279848b8605Smrg{
280848b8605Smrg   return _mesa_program_lexer_lex(yylval_param, yylloc_param, state->scanner);
281848b8605Smrg}
282848b8605Smrg%}
283848b8605Smrg
284848b8605Smrg%%
285848b8605Smrg
286848b8605Smrgprogram: language optionSequence statementSequence END
287848b8605Smrg	;
288848b8605Smrg
289848b8605Smrglanguage: ARBvp_10
290848b8605Smrg	{
291848b8605Smrg	   if (state->prog->Target != GL_VERTEX_PROGRAM_ARB) {
292848b8605Smrg	      yyerror(& @1, state, "invalid fragment program header");
293848b8605Smrg
294848b8605Smrg	   }
295848b8605Smrg	   state->mode = ARB_vertex;
296848b8605Smrg	}
297848b8605Smrg	| ARBfp_10
298848b8605Smrg	{
299848b8605Smrg	   if (state->prog->Target != GL_FRAGMENT_PROGRAM_ARB) {
300848b8605Smrg	      yyerror(& @1, state, "invalid vertex program header");
301848b8605Smrg	   }
302848b8605Smrg	   state->mode = ARB_fragment;
303848b8605Smrg
304848b8605Smrg	   state->option.TexRect =
305848b8605Smrg	      (state->ctx->Extensions.NV_texture_rectangle != GL_FALSE);
306848b8605Smrg	}
307848b8605Smrg	;
308848b8605Smrg
309848b8605SmrgoptionSequence: optionSequence option
310848b8605Smrg	|
311848b8605Smrg	;
312848b8605Smrg
313848b8605Smrgoption: OPTION string ';'
314848b8605Smrg	{
315848b8605Smrg	   int valid = 0;
316848b8605Smrg
317848b8605Smrg	   if (state->mode == ARB_vertex) {
318848b8605Smrg	      valid = _mesa_ARBvp_parse_option(state, $2);
319848b8605Smrg	   } else if (state->mode == ARB_fragment) {
320848b8605Smrg	      valid = _mesa_ARBfp_parse_option(state, $2);
321848b8605Smrg	   }
322848b8605Smrg
323848b8605Smrg
324848b8605Smrg	   free($2);
325848b8605Smrg
326848b8605Smrg	   if (!valid) {
327848b8605Smrg	      const char *const err_str = (state->mode == ARB_vertex)
328848b8605Smrg		 ? "invalid ARB vertex program option"
329848b8605Smrg		 : "invalid ARB fragment program option";
330848b8605Smrg
331848b8605Smrg	      yyerror(& @2, state, err_str);
332848b8605Smrg	      YYERROR;
333848b8605Smrg	   }
334848b8605Smrg	}
335848b8605Smrg	;
336848b8605Smrg
337848b8605SmrgstatementSequence: statementSequence statement
338848b8605Smrg	|
339848b8605Smrg	;
340848b8605Smrg
341848b8605Smrgstatement: instruction ';'
342848b8605Smrg	{
343848b8605Smrg	   if ($1 != NULL) {
344848b8605Smrg	      if (state->inst_tail == NULL) {
345848b8605Smrg		 state->inst_head = $1;
346848b8605Smrg	      } else {
347848b8605Smrg		 state->inst_tail->next = $1;
348848b8605Smrg	      }
349848b8605Smrg
350848b8605Smrg	      state->inst_tail = $1;
351848b8605Smrg	      $1->next = NULL;
352848b8605Smrg
353b8e80941Smrg              state->prog->arb.NumInstructions++;
354848b8605Smrg	   }
355848b8605Smrg	}
356848b8605Smrg	| namingStatement ';'
357848b8605Smrg	;
358848b8605Smrg
359848b8605Smrginstruction: ALU_instruction
360848b8605Smrg	{
361848b8605Smrg	   $$ = $1;
362b8e80941Smrg           state->prog->arb.NumAluInstructions++;
363848b8605Smrg	}
364848b8605Smrg	| TexInstruction
365848b8605Smrg	{
366848b8605Smrg	   $$ = $1;
367b8e80941Smrg           state->prog->arb.NumTexInstructions++;
368848b8605Smrg	}
369848b8605Smrg	;
370848b8605Smrg
371848b8605SmrgALU_instruction: ARL_instruction
372848b8605Smrg	| VECTORop_instruction
373848b8605Smrg	| SCALARop_instruction
374848b8605Smrg	| BINSCop_instruction
375848b8605Smrg	| BINop_instruction
376848b8605Smrg	| TRIop_instruction
377848b8605Smrg	| SWZ_instruction
378848b8605Smrg	;
379848b8605Smrg
380848b8605SmrgTexInstruction: SAMPLE_instruction
381848b8605Smrg	| KIL_instruction
382848b8605Smrg	| TXD_instruction
383848b8605Smrg	;
384848b8605Smrg
385848b8605SmrgARL_instruction: ARL maskedAddrReg ',' scalarSrcReg
386848b8605Smrg	{
387848b8605Smrg	   $$ = asm_instruction_ctor(OPCODE_ARL, & $2, & $4, NULL, NULL);
388848b8605Smrg	}
389848b8605Smrg	;
390848b8605Smrg
391848b8605SmrgVECTORop_instruction: VECTOR_OP maskedDstReg ',' swizzleSrcReg
392848b8605Smrg	{
393848b8605Smrg	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
394848b8605Smrg	}
395848b8605Smrg	;
396848b8605Smrg
397848b8605SmrgSCALARop_instruction: SCALAR_OP maskedDstReg ',' scalarSrcReg
398848b8605Smrg	{
399848b8605Smrg	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
400848b8605Smrg	}
401848b8605Smrg	;
402848b8605Smrg
403848b8605SmrgBINSCop_instruction: BINSC_OP maskedDstReg ',' scalarSrcReg ',' scalarSrcReg
404848b8605Smrg	{
405848b8605Smrg	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL);
406848b8605Smrg	}
407848b8605Smrg	;
408848b8605Smrg
409848b8605Smrg
410848b8605SmrgBINop_instruction: BIN_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg
411848b8605Smrg	{
412848b8605Smrg	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL);
413848b8605Smrg	}
414848b8605Smrg	;
415848b8605Smrg
416848b8605SmrgTRIop_instruction: TRI_OP maskedDstReg ','
417848b8605Smrg                   swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg
418848b8605Smrg	{
419848b8605Smrg	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8);
420848b8605Smrg	}
421848b8605Smrg	;
422848b8605Smrg
423848b8605SmrgSAMPLE_instruction: SAMPLE_OP maskedDstReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget
424848b8605Smrg	{
425848b8605Smrg	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
426848b8605Smrg	   if ($$ != NULL) {
427848b8605Smrg	      const GLbitfield tex_mask = (1U << $6);
428848b8605Smrg	      GLbitfield shadow_tex = 0;
429848b8605Smrg	      GLbitfield target_mask = 0;
430848b8605Smrg
431848b8605Smrg
432848b8605Smrg	      $$->Base.TexSrcUnit = $6;
433848b8605Smrg
434848b8605Smrg	      if ($8 < 0) {
435848b8605Smrg		 shadow_tex = tex_mask;
436848b8605Smrg
437848b8605Smrg		 $$->Base.TexSrcTarget = -$8;
438848b8605Smrg		 $$->Base.TexShadow = 1;
439848b8605Smrg	      } else {
440848b8605Smrg		 $$->Base.TexSrcTarget = $8;
441848b8605Smrg	      }
442848b8605Smrg
443848b8605Smrg	      target_mask = (1U << $$->Base.TexSrcTarget);
444848b8605Smrg
445848b8605Smrg	      /* If this texture unit was previously accessed and that access
446848b8605Smrg	       * had a different texture target, generate an error.
447848b8605Smrg	       *
448848b8605Smrg	       * If this texture unit was previously accessed and that access
449848b8605Smrg	       * had a different shadow mode, generate an error.
450848b8605Smrg	       */
451848b8605Smrg	      if ((state->prog->TexturesUsed[$6] != 0)
452848b8605Smrg		  && ((state->prog->TexturesUsed[$6] != target_mask)
453848b8605Smrg		      || ((state->prog->ShadowSamplers & tex_mask)
454848b8605Smrg			  != shadow_tex))) {
455848b8605Smrg		 yyerror(& @8, state,
456848b8605Smrg			 "multiple targets used on one texture image unit");
457848b8605Smrg		 YYERROR;
458848b8605Smrg	      }
459848b8605Smrg
460848b8605Smrg
461848b8605Smrg	      state->prog->TexturesUsed[$6] |= target_mask;
462848b8605Smrg	      state->prog->ShadowSamplers |= shadow_tex;
463848b8605Smrg	   }
464848b8605Smrg	}
465848b8605Smrg	;
466848b8605Smrg
467848b8605SmrgKIL_instruction: KIL swizzleSrcReg
468848b8605Smrg	{
469848b8605Smrg	   $$ = asm_instruction_ctor(OPCODE_KIL, NULL, & $2, NULL, NULL);
470848b8605Smrg	   state->fragment.UsesKill = 1;
471848b8605Smrg	}
472848b8605Smrg	;
473848b8605Smrg
474848b8605SmrgTXD_instruction: TXD_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget
475848b8605Smrg	{
476848b8605Smrg	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8);
477848b8605Smrg	   if ($$ != NULL) {
478848b8605Smrg	      const GLbitfield tex_mask = (1U << $10);
479848b8605Smrg	      GLbitfield shadow_tex = 0;
480848b8605Smrg	      GLbitfield target_mask = 0;
481848b8605Smrg
482848b8605Smrg
483848b8605Smrg	      $$->Base.TexSrcUnit = $10;
484848b8605Smrg
485848b8605Smrg	      if ($12 < 0) {
486848b8605Smrg		 shadow_tex = tex_mask;
487848b8605Smrg
488848b8605Smrg		 $$->Base.TexSrcTarget = -$12;
489848b8605Smrg		 $$->Base.TexShadow = 1;
490848b8605Smrg	      } else {
491848b8605Smrg		 $$->Base.TexSrcTarget = $12;
492848b8605Smrg	      }
493848b8605Smrg
494848b8605Smrg	      target_mask = (1U << $$->Base.TexSrcTarget);
495848b8605Smrg
496848b8605Smrg	      /* If this texture unit was previously accessed and that access
497848b8605Smrg	       * had a different texture target, generate an error.
498848b8605Smrg	       *
499848b8605Smrg	       * If this texture unit was previously accessed and that access
500848b8605Smrg	       * had a different shadow mode, generate an error.
501848b8605Smrg	       */
502848b8605Smrg	      if ((state->prog->TexturesUsed[$10] != 0)
503848b8605Smrg		  && ((state->prog->TexturesUsed[$10] != target_mask)
504848b8605Smrg		      || ((state->prog->ShadowSamplers & tex_mask)
505848b8605Smrg			  != shadow_tex))) {
506848b8605Smrg		 yyerror(& @12, state,
507848b8605Smrg			 "multiple targets used on one texture image unit");
508848b8605Smrg		 YYERROR;
509848b8605Smrg	      }
510848b8605Smrg
511848b8605Smrg
512848b8605Smrg	      state->prog->TexturesUsed[$10] |= target_mask;
513848b8605Smrg	      state->prog->ShadowSamplers |= shadow_tex;
514848b8605Smrg	   }
515848b8605Smrg	}
516848b8605Smrg	;
517848b8605Smrg
518848b8605SmrgtexImageUnit: TEXTURE_UNIT optTexImageUnitNum
519848b8605Smrg	{
520848b8605Smrg	   $$ = $2;
521848b8605Smrg	}
522848b8605Smrg	;
523848b8605Smrg
524848b8605SmrgtexTarget: TEX_1D  { $$ = TEXTURE_1D_INDEX; }
525848b8605Smrg	| TEX_2D   { $$ = TEXTURE_2D_INDEX; }
526848b8605Smrg	| TEX_3D   { $$ = TEXTURE_3D_INDEX; }
527848b8605Smrg	| TEX_CUBE { $$ = TEXTURE_CUBE_INDEX; }
528848b8605Smrg	| TEX_RECT { $$ = TEXTURE_RECT_INDEX; }
529848b8605Smrg	| TEX_SHADOW1D   { $$ = -TEXTURE_1D_INDEX; }
530848b8605Smrg	| TEX_SHADOW2D   { $$ = -TEXTURE_2D_INDEX; }
531848b8605Smrg	| TEX_SHADOWRECT { $$ = -TEXTURE_RECT_INDEX; }
532848b8605Smrg	| TEX_ARRAY1D         { $$ = TEXTURE_1D_ARRAY_INDEX; }
533848b8605Smrg	| TEX_ARRAY2D         { $$ = TEXTURE_2D_ARRAY_INDEX; }
534848b8605Smrg	| TEX_ARRAYSHADOW1D   { $$ = -TEXTURE_1D_ARRAY_INDEX; }
535848b8605Smrg	| TEX_ARRAYSHADOW2D   { $$ = -TEXTURE_2D_ARRAY_INDEX; }
536848b8605Smrg	;
537848b8605Smrg
538848b8605SmrgSWZ_instruction: SWZ maskedDstReg ',' srcReg ',' extendedSwizzle
539848b8605Smrg	{
540848b8605Smrg	   /* FIXME: Is this correct?  Should the extenedSwizzle be applied
541848b8605Smrg	    * FIXME: to the existing swizzle?
542848b8605Smrg	    */
543848b8605Smrg	   $4.Base.Swizzle = $6.swizzle;
544848b8605Smrg	   $4.Base.Negate = $6.mask;
545848b8605Smrg
546848b8605Smrg	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
547848b8605Smrg	}
548848b8605Smrg	;
549848b8605Smrg
550848b8605SmrgscalarSrcReg: optionalSign scalarUse
551848b8605Smrg	{
552848b8605Smrg	   $$ = $2;
553848b8605Smrg
554848b8605Smrg	   if ($1) {
555848b8605Smrg	      $$.Base.Negate = ~$$.Base.Negate;
556848b8605Smrg	   }
557848b8605Smrg	}
558848b8605Smrg	;
559848b8605Smrg
560848b8605SmrgscalarUse:  srcReg scalarSuffix
561848b8605Smrg	{
562848b8605Smrg	   $$ = $1;
563848b8605Smrg
564848b8605Smrg	   $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
565848b8605Smrg						    $2.swizzle);
566848b8605Smrg	}
567848b8605Smrg	;
568848b8605Smrg
569848b8605SmrgswizzleSrcReg: optionalSign srcReg swizzleSuffix
570848b8605Smrg	{
571848b8605Smrg	   $$ = $2;
572848b8605Smrg
573848b8605Smrg	   if ($1) {
574848b8605Smrg	      $$.Base.Negate = ~$$.Base.Negate;
575848b8605Smrg	   }
576848b8605Smrg
577848b8605Smrg	   $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
578848b8605Smrg						    $3.swizzle);
579848b8605Smrg	}
580848b8605Smrg	;
581848b8605Smrg
582b8e80941SmrgmaskedDstReg: dstReg optionalMask
583848b8605Smrg	{
584848b8605Smrg	   $$ = $1;
585848b8605Smrg	   $$.WriteMask = $2.mask;
586848b8605Smrg
587848b8605Smrg	   if ($$.File == PROGRAM_OUTPUT) {
588848b8605Smrg	      /* Technically speaking, this should check that it is in
589848b8605Smrg	       * vertex program mode.  However, PositionInvariant can never be
590848b8605Smrg	       * set in fragment program mode, so it is somewhat irrelevant.
591848b8605Smrg	       */
592848b8605Smrg	      if (state->option.PositionInvariant
593848b8605Smrg	       && ($$.Index == VARYING_SLOT_POS)) {
594848b8605Smrg		 yyerror(& @1, state, "position-invariant programs cannot "
595848b8605Smrg			 "write position");
596848b8605Smrg		 YYERROR;
597848b8605Smrg	      }
598848b8605Smrg
599b8e80941Smrg              state->prog->info.outputs_written |= BITFIELD64_BIT($$.Index);
600848b8605Smrg	   }
601848b8605Smrg	}
602848b8605Smrg	;
603848b8605Smrg
604848b8605SmrgmaskedAddrReg: addrReg addrWriteMask
605848b8605Smrg	{
606848b8605Smrg	   set_dst_reg(& $$, PROGRAM_ADDRESS, 0);
607848b8605Smrg	   $$.WriteMask = $2.mask;
608848b8605Smrg	}
609848b8605Smrg	;
610848b8605Smrg
611848b8605SmrgextendedSwizzle: extSwizComp ',' extSwizComp ',' extSwizComp ',' extSwizComp
612848b8605Smrg	{
613848b8605Smrg	   const unsigned xyzw_valid =
614848b8605Smrg	      ($1.xyzw_valid << 0)
615848b8605Smrg	      | ($3.xyzw_valid << 1)
616848b8605Smrg	      | ($5.xyzw_valid << 2)
617848b8605Smrg	      | ($7.xyzw_valid << 3);
618848b8605Smrg	   const unsigned rgba_valid =
619848b8605Smrg	      ($1.rgba_valid << 0)
620848b8605Smrg	      | ($3.rgba_valid << 1)
621848b8605Smrg	      | ($5.rgba_valid << 2)
622848b8605Smrg	      | ($7.rgba_valid << 3);
623848b8605Smrg
624848b8605Smrg	   /* All of the swizzle components have to be valid in either RGBA
625848b8605Smrg	    * or XYZW.  Note that 0 and 1 are valid in both, so both masks
626848b8605Smrg	    * can have some bits set.
627848b8605Smrg	    *
628848b8605Smrg	    * We somewhat deviate from the spec here.  It would be really hard
629848b8605Smrg	    * to figure out which component is the error, and there probably
630848b8605Smrg	    * isn't a lot of benefit.
631848b8605Smrg	    */
632848b8605Smrg	   if ((rgba_valid != 0x0f) && (xyzw_valid != 0x0f)) {
633848b8605Smrg	      yyerror(& @1, state, "cannot combine RGBA and XYZW swizzle "
634848b8605Smrg		      "components");
635848b8605Smrg	      YYERROR;
636848b8605Smrg	   }
637848b8605Smrg
638848b8605Smrg	   $$.swizzle = MAKE_SWIZZLE4($1.swz, $3.swz, $5.swz, $7.swz);
639848b8605Smrg	   $$.mask = ($1.negate) | ($3.negate << 1) | ($5.negate << 2)
640848b8605Smrg	      | ($7.negate << 3);
641848b8605Smrg	}
642848b8605Smrg	;
643848b8605Smrg
644848b8605SmrgextSwizComp: optionalSign extSwizSel
645848b8605Smrg	{
646848b8605Smrg	   $$ = $2;
647848b8605Smrg	   $$.negate = ($1) ? 1 : 0;
648848b8605Smrg	}
649848b8605Smrg	;
650848b8605Smrg
651848b8605SmrgextSwizSel: INTEGER
652848b8605Smrg	{
653848b8605Smrg	   if (($1 != 0) && ($1 != 1)) {
654848b8605Smrg	      yyerror(& @1, state, "invalid extended swizzle selector");
655848b8605Smrg	      YYERROR;
656848b8605Smrg	   }
657848b8605Smrg
658848b8605Smrg	   $$.swz = ($1 == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE;
659848b8605Smrg           $$.negate = 0;
660848b8605Smrg
661848b8605Smrg	   /* 0 and 1 are valid for both RGBA swizzle names and XYZW
662848b8605Smrg	    * swizzle names.
663848b8605Smrg	    */
664848b8605Smrg	   $$.xyzw_valid = 1;
665848b8605Smrg	   $$.rgba_valid = 1;
666848b8605Smrg	}
667848b8605Smrg	| string
668848b8605Smrg	{
669848b8605Smrg	   char s;
670848b8605Smrg
671848b8605Smrg	   if (strlen($1) > 1) {
672848b8605Smrg	      yyerror(& @1, state, "invalid extended swizzle selector");
673848b8605Smrg	      YYERROR;
674848b8605Smrg	   }
675848b8605Smrg
676848b8605Smrg	   s = $1[0];
677848b8605Smrg	   free($1);
678848b8605Smrg
679848b8605Smrg           $$.rgba_valid = 0;
680848b8605Smrg           $$.xyzw_valid = 0;
681848b8605Smrg           $$.negate = 0;
682848b8605Smrg
683848b8605Smrg	   switch (s) {
684848b8605Smrg	   case 'x':
685848b8605Smrg	      $$.swz = SWIZZLE_X;
686848b8605Smrg	      $$.xyzw_valid = 1;
687848b8605Smrg	      break;
688848b8605Smrg	   case 'y':
689848b8605Smrg	      $$.swz = SWIZZLE_Y;
690848b8605Smrg	      $$.xyzw_valid = 1;
691848b8605Smrg	      break;
692848b8605Smrg	   case 'z':
693848b8605Smrg	      $$.swz = SWIZZLE_Z;
694848b8605Smrg	      $$.xyzw_valid = 1;
695848b8605Smrg	      break;
696848b8605Smrg	   case 'w':
697848b8605Smrg	      $$.swz = SWIZZLE_W;
698848b8605Smrg	      $$.xyzw_valid = 1;
699848b8605Smrg	      break;
700848b8605Smrg
701848b8605Smrg	   case 'r':
702848b8605Smrg	      $$.swz = SWIZZLE_X;
703848b8605Smrg	      $$.rgba_valid = 1;
704848b8605Smrg	      break;
705848b8605Smrg	   case 'g':
706848b8605Smrg	      $$.swz = SWIZZLE_Y;
707848b8605Smrg	      $$.rgba_valid = 1;
708848b8605Smrg	      break;
709848b8605Smrg	   case 'b':
710848b8605Smrg	      $$.swz = SWIZZLE_Z;
711848b8605Smrg	      $$.rgba_valid = 1;
712848b8605Smrg	      break;
713848b8605Smrg	   case 'a':
714848b8605Smrg	      $$.swz = SWIZZLE_W;
715848b8605Smrg	      $$.rgba_valid = 1;
716848b8605Smrg	      break;
717848b8605Smrg
718848b8605Smrg	   default:
719848b8605Smrg	      yyerror(& @1, state, "invalid extended swizzle selector");
720848b8605Smrg	      YYERROR;
721848b8605Smrg	      break;
722848b8605Smrg	   }
723848b8605Smrg	}
724848b8605Smrg	;
725848b8605Smrg
726848b8605SmrgsrcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */
727848b8605Smrg	{
728848b8605Smrg	   struct asm_symbol *const s = (struct asm_symbol *)
729b8e80941Smrg              _mesa_symbol_table_find_symbol(state->st, $1);
730848b8605Smrg
731848b8605Smrg	   free($1);
732848b8605Smrg
733848b8605Smrg	   if (s == NULL) {
734848b8605Smrg	      yyerror(& @1, state, "invalid operand variable");
735848b8605Smrg	      YYERROR;
736848b8605Smrg	   } else if ((s->type != at_param) && (s->type != at_temp)
737848b8605Smrg		      && (s->type != at_attrib)) {
738848b8605Smrg	      yyerror(& @1, state, "invalid operand variable");
739848b8605Smrg	      YYERROR;
740848b8605Smrg	   } else if ((s->type == at_param) && s->param_is_array) {
741848b8605Smrg	      yyerror(& @1, state, "non-array access to array PARAM");
742848b8605Smrg	      YYERROR;
743848b8605Smrg	   }
744848b8605Smrg
745848b8605Smrg	   init_src_reg(& $$);
746848b8605Smrg	   switch (s->type) {
747848b8605Smrg	   case at_temp:
748848b8605Smrg	      set_src_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding);
749848b8605Smrg	      break;
750848b8605Smrg	   case at_param:
751848b8605Smrg              set_src_reg_swz(& $$, s->param_binding_type,
752848b8605Smrg                              s->param_binding_begin,
753848b8605Smrg                              s->param_binding_swizzle);
754848b8605Smrg	      break;
755848b8605Smrg	   case at_attrib:
756848b8605Smrg	      set_src_reg(& $$, PROGRAM_INPUT, s->attrib_binding);
757b8e80941Smrg              state->prog->info.inputs_read |= BITFIELD64_BIT($$.Base.Index);
758848b8605Smrg
759848b8605Smrg	      if (!validate_inputs(& @1, state)) {
760848b8605Smrg		 YYERROR;
761848b8605Smrg	      }
762848b8605Smrg	      break;
763848b8605Smrg
764848b8605Smrg	   default:
765848b8605Smrg	      YYERROR;
766848b8605Smrg	      break;
767848b8605Smrg	   }
768848b8605Smrg	}
769848b8605Smrg	| attribBinding
770848b8605Smrg	{
771848b8605Smrg	   set_src_reg(& $$, PROGRAM_INPUT, $1);
772b8e80941Smrg           state->prog->info.inputs_read |= BITFIELD64_BIT($$.Base.Index);
773848b8605Smrg
774848b8605Smrg	   if (!validate_inputs(& @1, state)) {
775848b8605Smrg	      YYERROR;
776848b8605Smrg	   }
777848b8605Smrg	}
778848b8605Smrg	| progParamArray '[' progParamArrayMem ']'
779848b8605Smrg	{
780848b8605Smrg	   if (! $3.Base.RelAddr
781848b8605Smrg	       && ((unsigned) $3.Base.Index >= $1->param_binding_length)) {
782848b8605Smrg	      yyerror(& @3, state, "out of bounds array access");
783848b8605Smrg	      YYERROR;
784848b8605Smrg	   }
785848b8605Smrg
786848b8605Smrg	   init_src_reg(& $$);
787848b8605Smrg	   $$.Base.File = $1->param_binding_type;
788848b8605Smrg
789848b8605Smrg	   if ($3.Base.RelAddr) {
790b8e80941Smrg              state->prog->arb.IndirectRegisterFiles |= (1 << $$.Base.File);
791848b8605Smrg	      $1->param_accessed_indirectly = 1;
792848b8605Smrg
793848b8605Smrg	      $$.Base.RelAddr = 1;
794848b8605Smrg	      $$.Base.Index = $3.Base.Index;
795848b8605Smrg	      $$.Symbol = $1;
796848b8605Smrg	   } else {
797848b8605Smrg	      $$.Base.Index = $1->param_binding_begin + $3.Base.Index;
798848b8605Smrg	   }
799848b8605Smrg	}
800848b8605Smrg	| paramSingleItemUse
801848b8605Smrg	{
802848b8605Smrg           gl_register_file file = ($1.name != NULL)
803848b8605Smrg	      ? $1.param_binding_type
804848b8605Smrg	      : PROGRAM_CONSTANT;
805848b8605Smrg           set_src_reg_swz(& $$, file, $1.param_binding_begin,
806848b8605Smrg                           $1.param_binding_swizzle);
807848b8605Smrg	}
808848b8605Smrg	;
809848b8605Smrg
810848b8605SmrgdstReg: resultBinding
811848b8605Smrg	{
812848b8605Smrg	   set_dst_reg(& $$, PROGRAM_OUTPUT, $1);
813848b8605Smrg	}
814848b8605Smrg	| USED_IDENTIFIER /* temporaryReg | vertexResultReg */
815848b8605Smrg	{
816848b8605Smrg	   struct asm_symbol *const s = (struct asm_symbol *)
817b8e80941Smrg              _mesa_symbol_table_find_symbol(state->st, $1);
818848b8605Smrg
819848b8605Smrg	   free($1);
820848b8605Smrg
821848b8605Smrg	   if (s == NULL) {
822848b8605Smrg	      yyerror(& @1, state, "invalid operand variable");
823848b8605Smrg	      YYERROR;
824848b8605Smrg	   } else if ((s->type != at_output) && (s->type != at_temp)) {
825848b8605Smrg	      yyerror(& @1, state, "invalid operand variable");
826848b8605Smrg	      YYERROR;
827848b8605Smrg	   }
828848b8605Smrg
829848b8605Smrg	   switch (s->type) {
830848b8605Smrg	   case at_temp:
831848b8605Smrg	      set_dst_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding);
832848b8605Smrg	      break;
833848b8605Smrg	   case at_output:
834848b8605Smrg	      set_dst_reg(& $$, PROGRAM_OUTPUT, s->output_binding);
835848b8605Smrg	      break;
836848b8605Smrg	   default:
837848b8605Smrg	      set_dst_reg(& $$, s->param_binding_type, s->param_binding_begin);
838848b8605Smrg	      break;
839848b8605Smrg	   }
840848b8605Smrg	}
841848b8605Smrg	;
842848b8605Smrg
843848b8605SmrgprogParamArray: USED_IDENTIFIER
844848b8605Smrg	{
845848b8605Smrg	   struct asm_symbol *const s = (struct asm_symbol *)
846b8e80941Smrg              _mesa_symbol_table_find_symbol(state->st, $1);
847848b8605Smrg
848848b8605Smrg	   free($1);
849848b8605Smrg
850848b8605Smrg	   if (s == NULL) {
851848b8605Smrg	      yyerror(& @1, state, "invalid operand variable");
852848b8605Smrg	      YYERROR;
853848b8605Smrg	   } else if ((s->type != at_param) || !s->param_is_array) {
854848b8605Smrg	      yyerror(& @1, state, "array access to non-PARAM variable");
855848b8605Smrg	      YYERROR;
856848b8605Smrg	   } else {
857848b8605Smrg	      $$ = s;
858848b8605Smrg	   }
859848b8605Smrg	}
860848b8605Smrg	;
861848b8605Smrg
862848b8605SmrgprogParamArrayMem: progParamArrayAbs | progParamArrayRel;
863848b8605Smrg
864848b8605SmrgprogParamArrayAbs: INTEGER
865848b8605Smrg	{
866848b8605Smrg	   init_src_reg(& $$);
867848b8605Smrg	   $$.Base.Index = $1;
868848b8605Smrg	}
869848b8605Smrg	;
870848b8605Smrg
871848b8605SmrgprogParamArrayRel: addrReg addrComponent addrRegRelOffset
872848b8605Smrg	{
873848b8605Smrg	   /* FINISHME: Add support for multiple address registers.
874848b8605Smrg	    */
875848b8605Smrg	   /* FINISHME: Add support for 4-component address registers.
876848b8605Smrg	    */
877848b8605Smrg	   init_src_reg(& $$);
878848b8605Smrg	   $$.Base.RelAddr = 1;
879848b8605Smrg	   $$.Base.Index = $3;
880848b8605Smrg	}
881848b8605Smrg	;
882848b8605Smrg
883848b8605SmrgaddrRegRelOffset:              { $$ = 0; }
884848b8605Smrg	| '+' addrRegPosOffset { $$ = $2; }
885848b8605Smrg	| '-' addrRegNegOffset { $$ = -$2; }
886848b8605Smrg	;
887848b8605Smrg
888848b8605SmrgaddrRegPosOffset: INTEGER
889848b8605Smrg	{
890848b8605Smrg	   if (($1 < 0) || ($1 > (state->limits->MaxAddressOffset - 1))) {
891848b8605Smrg              char s[100];
892848b8605Smrg              _mesa_snprintf(s, sizeof(s),
893848b8605Smrg                             "relative address offset too large (%d)", $1);
894848b8605Smrg	      yyerror(& @1, state, s);
895848b8605Smrg	      YYERROR;
896848b8605Smrg	   } else {
897848b8605Smrg	      $$ = $1;
898848b8605Smrg	   }
899848b8605Smrg	}
900848b8605Smrg	;
901848b8605Smrg
902848b8605SmrgaddrRegNegOffset: INTEGER
903848b8605Smrg	{
904848b8605Smrg	   if (($1 < 0) || ($1 > state->limits->MaxAddressOffset)) {
905848b8605Smrg              char s[100];
906848b8605Smrg              _mesa_snprintf(s, sizeof(s),
907848b8605Smrg                             "relative address offset too large (%d)", $1);
908848b8605Smrg	      yyerror(& @1, state, s);
909848b8605Smrg	      YYERROR;
910848b8605Smrg	   } else {
911848b8605Smrg	      $$ = $1;
912848b8605Smrg	   }
913848b8605Smrg	}
914848b8605Smrg	;
915848b8605Smrg
916848b8605SmrgaddrReg: USED_IDENTIFIER
917848b8605Smrg	{
918848b8605Smrg	   struct asm_symbol *const s = (struct asm_symbol *)
919b8e80941Smrg              _mesa_symbol_table_find_symbol(state->st, $1);
920848b8605Smrg
921848b8605Smrg	   free($1);
922848b8605Smrg
923848b8605Smrg	   if (s == NULL) {
924848b8605Smrg	      yyerror(& @1, state, "invalid array member");
925848b8605Smrg	      YYERROR;
926848b8605Smrg	   } else if (s->type != at_address) {
927848b8605Smrg	      yyerror(& @1, state,
928848b8605Smrg		      "invalid variable for indexed array access");
929848b8605Smrg	      YYERROR;
930848b8605Smrg	   } else {
931848b8605Smrg	      $$ = s;
932848b8605Smrg	   }
933848b8605Smrg	}
934848b8605Smrg	;
935848b8605Smrg
936848b8605SmrgaddrComponent: MASK1
937848b8605Smrg	{
938848b8605Smrg	   if ($1.mask != WRITEMASK_X) {
939848b8605Smrg	      yyerror(& @1, state, "invalid address component selector");
940848b8605Smrg	      YYERROR;
941848b8605Smrg	   } else {
942848b8605Smrg	      $$ = $1;
943848b8605Smrg	   }
944848b8605Smrg	}
945848b8605Smrg	;
946848b8605Smrg
947848b8605SmrgaddrWriteMask: MASK1
948848b8605Smrg	{
949848b8605Smrg	   if ($1.mask != WRITEMASK_X) {
950848b8605Smrg	      yyerror(& @1, state,
951848b8605Smrg		      "address register write mask must be \".x\"");
952848b8605Smrg	      YYERROR;
953848b8605Smrg	   } else {
954848b8605Smrg	      $$ = $1;
955848b8605Smrg	   }
956848b8605Smrg	}
957848b8605Smrg	;
958848b8605Smrg
959848b8605SmrgscalarSuffix: MASK1;
960848b8605Smrg
961848b8605SmrgswizzleSuffix: MASK1
962848b8605Smrg	| MASK4
963848b8605Smrg	| SWIZZLE
964848b8605Smrg	|              { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
965848b8605Smrg	;
966848b8605Smrg
967848b8605SmrgoptionalMask: MASK4 | MASK3 | MASK2 | MASK1
968848b8605Smrg	|              { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
969848b8605Smrg	;
970848b8605Smrg
971848b8605SmrgnamingStatement: ATTRIB_statement
972848b8605Smrg	| PARAM_statement
973848b8605Smrg	| TEMP_statement
974848b8605Smrg	| ADDRESS_statement
975848b8605Smrg	| OUTPUT_statement
976848b8605Smrg	| ALIAS_statement
977848b8605Smrg	;
978848b8605Smrg
979848b8605SmrgATTRIB_statement: ATTRIB IDENTIFIER '=' attribBinding
980848b8605Smrg	{
981848b8605Smrg	   struct asm_symbol *const s =
982848b8605Smrg	      declare_variable(state, $2, at_attrib, & @2);
983848b8605Smrg
984848b8605Smrg	   if (s == NULL) {
985848b8605Smrg	      free($2);
986848b8605Smrg	      YYERROR;
987848b8605Smrg	   } else {
988848b8605Smrg	      s->attrib_binding = $4;
989848b8605Smrg	      state->InputsBound |= BITFIELD64_BIT(s->attrib_binding);
990848b8605Smrg
991848b8605Smrg	      if (!validate_inputs(& @4, state)) {
992848b8605Smrg		 YYERROR;
993848b8605Smrg	      }
994848b8605Smrg	   }
995848b8605Smrg	}
996848b8605Smrg	;
997848b8605Smrg
998848b8605SmrgattribBinding: VERTEX vtxAttribItem
999848b8605Smrg	{
1000848b8605Smrg	   $$ = $2;
1001848b8605Smrg	}
1002848b8605Smrg	| FRAGMENT fragAttribItem
1003848b8605Smrg	{
1004848b8605Smrg	   $$ = $2;
1005848b8605Smrg	}
1006848b8605Smrg	;
1007848b8605Smrg
1008848b8605SmrgvtxAttribItem: POSITION
1009848b8605Smrg	{
1010848b8605Smrg	   $$ = VERT_ATTRIB_POS;
1011848b8605Smrg	}
1012848b8605Smrg	| NORMAL
1013848b8605Smrg	{
1014848b8605Smrg	   $$ = VERT_ATTRIB_NORMAL;
1015848b8605Smrg	}
1016848b8605Smrg	| COLOR optColorType
1017848b8605Smrg	{
1018848b8605Smrg	   $$ = VERT_ATTRIB_COLOR0 + $2;
1019848b8605Smrg	}
1020848b8605Smrg	| FOGCOORD
1021848b8605Smrg	{
1022848b8605Smrg	   $$ = VERT_ATTRIB_FOG;
1023848b8605Smrg	}
1024848b8605Smrg	| TEXCOORD optTexCoordUnitNum
1025848b8605Smrg	{
1026848b8605Smrg	   $$ = VERT_ATTRIB_TEX0 + $2;
1027848b8605Smrg	}
1028848b8605Smrg	| MATRIXINDEX '[' vtxWeightNum ']'
1029848b8605Smrg	{
1030848b8605Smrg	   yyerror(& @1, state, "GL_ARB_matrix_palette not supported");
1031848b8605Smrg	   YYERROR;
1032848b8605Smrg	}
1033848b8605Smrg	| VTXATTRIB '[' vtxAttribNum ']'
1034848b8605Smrg	{
1035848b8605Smrg	   $$ = VERT_ATTRIB_GENERIC0 + $3;
1036848b8605Smrg	}
1037848b8605Smrg	;
1038848b8605Smrg
1039848b8605SmrgvtxAttribNum: INTEGER
1040848b8605Smrg	{
1041848b8605Smrg	   if ((unsigned) $1 >= state->limits->MaxAttribs) {
1042848b8605Smrg	      yyerror(& @1, state, "invalid vertex attribute reference");
1043848b8605Smrg	      YYERROR;
1044848b8605Smrg	   }
1045848b8605Smrg
1046848b8605Smrg	   $$ = $1;
1047848b8605Smrg	}
1048848b8605Smrg	;
1049848b8605Smrg
1050848b8605SmrgvtxWeightNum: INTEGER;
1051848b8605Smrg
1052848b8605SmrgfragAttribItem: POSITION
1053848b8605Smrg	{
1054848b8605Smrg	   $$ = VARYING_SLOT_POS;
1055848b8605Smrg	}
1056848b8605Smrg	| COLOR optColorType
1057848b8605Smrg	{
1058848b8605Smrg	   $$ = VARYING_SLOT_COL0 + $2;
1059848b8605Smrg	}
1060848b8605Smrg	| FOGCOORD
1061848b8605Smrg	{
1062848b8605Smrg	   $$ = VARYING_SLOT_FOGC;
1063848b8605Smrg	}
1064848b8605Smrg	| TEXCOORD optTexCoordUnitNum
1065848b8605Smrg	{
1066848b8605Smrg	   $$ = VARYING_SLOT_TEX0 + $2;
1067848b8605Smrg	}
1068848b8605Smrg	;
1069848b8605Smrg
1070848b8605SmrgPARAM_statement: PARAM_singleStmt | PARAM_multipleStmt;
1071848b8605Smrg
1072848b8605SmrgPARAM_singleStmt: PARAM IDENTIFIER paramSingleInit
1073848b8605Smrg	{
1074848b8605Smrg	   struct asm_symbol *const s =
1075848b8605Smrg	      declare_variable(state, $2, at_param, & @2);
1076848b8605Smrg
1077848b8605Smrg	   if (s == NULL) {
1078848b8605Smrg	      free($2);
1079848b8605Smrg	      YYERROR;
1080848b8605Smrg	   } else {
1081848b8605Smrg	      s->param_binding_type = $3.param_binding_type;
1082848b8605Smrg	      s->param_binding_begin = $3.param_binding_begin;
1083848b8605Smrg	      s->param_binding_length = $3.param_binding_length;
1084848b8605Smrg              s->param_binding_swizzle = $3.param_binding_swizzle;
1085848b8605Smrg	      s->param_is_array = 0;
1086848b8605Smrg	   }
1087848b8605Smrg	}
1088848b8605Smrg	;
1089848b8605Smrg
1090848b8605SmrgPARAM_multipleStmt: PARAM IDENTIFIER '[' optArraySize ']' paramMultipleInit
1091848b8605Smrg	{
1092848b8605Smrg	   if (($4 != 0) && ((unsigned) $4 != $6.param_binding_length)) {
1093848b8605Smrg	      free($2);
1094848b8605Smrg	      yyerror(& @4, state,
1095848b8605Smrg		      "parameter array size and number of bindings must match");
1096848b8605Smrg	      YYERROR;
1097848b8605Smrg	   } else {
1098848b8605Smrg	      struct asm_symbol *const s =
1099848b8605Smrg		 declare_variable(state, $2, $6.type, & @2);
1100848b8605Smrg
1101848b8605Smrg	      if (s == NULL) {
1102848b8605Smrg		 free($2);
1103848b8605Smrg		 YYERROR;
1104848b8605Smrg	      } else {
1105848b8605Smrg		 s->param_binding_type = $6.param_binding_type;
1106848b8605Smrg		 s->param_binding_begin = $6.param_binding_begin;
1107848b8605Smrg		 s->param_binding_length = $6.param_binding_length;
1108848b8605Smrg                 s->param_binding_swizzle = SWIZZLE_XYZW;
1109848b8605Smrg		 s->param_is_array = 1;
1110848b8605Smrg	      }
1111848b8605Smrg	   }
1112848b8605Smrg	}
1113848b8605Smrg	;
1114848b8605Smrg
1115848b8605SmrgoptArraySize:
1116848b8605Smrg	{
1117848b8605Smrg	   $$ = 0;
1118848b8605Smrg	}
1119848b8605Smrg	| INTEGER
1120848b8605Smrg        {
1121848b8605Smrg	   if (($1 < 1) || ((unsigned) $1 > state->limits->MaxParameters)) {
1122848b8605Smrg              char msg[100];
1123848b8605Smrg              _mesa_snprintf(msg, sizeof(msg),
1124848b8605Smrg                             "invalid parameter array size (size=%d max=%u)",
1125848b8605Smrg                             $1, state->limits->MaxParameters);
1126848b8605Smrg	      yyerror(& @1, state, msg);
1127848b8605Smrg	      YYERROR;
1128848b8605Smrg	   } else {
1129848b8605Smrg	      $$ = $1;
1130848b8605Smrg	   }
1131848b8605Smrg	}
1132848b8605Smrg	;
1133848b8605Smrg
1134848b8605SmrgparamSingleInit: '=' paramSingleItemDecl
1135848b8605Smrg	{
1136848b8605Smrg	   $$ = $2;
1137848b8605Smrg	}
1138848b8605Smrg	;
1139848b8605Smrg
1140848b8605SmrgparamMultipleInit: '=' '{' paramMultInitList '}'
1141848b8605Smrg	{
1142848b8605Smrg	   $$ = $3;
1143848b8605Smrg	}
1144848b8605Smrg	;
1145848b8605Smrg
1146848b8605SmrgparamMultInitList: paramMultipleItem
1147848b8605Smrg	| paramMultInitList ',' paramMultipleItem
1148848b8605Smrg	{
1149848b8605Smrg	   $1.param_binding_length += $3.param_binding_length;
1150848b8605Smrg	   $$ = $1;
1151848b8605Smrg	}
1152848b8605Smrg	;
1153848b8605Smrg
1154848b8605SmrgparamSingleItemDecl: stateSingleItem
1155848b8605Smrg	{
1156848b8605Smrg	   memset(& $$, 0, sizeof($$));
1157848b8605Smrg	   $$.param_binding_begin = ~0;
1158848b8605Smrg	   initialize_symbol_from_state(state->prog, & $$, $1);
1159848b8605Smrg	}
1160848b8605Smrg	| programSingleItem
1161848b8605Smrg	{
1162848b8605Smrg	   memset(& $$, 0, sizeof($$));
1163848b8605Smrg	   $$.param_binding_begin = ~0;
1164848b8605Smrg	   initialize_symbol_from_param(state->prog, & $$, $1);
1165848b8605Smrg	}
1166848b8605Smrg	| paramConstDecl
1167848b8605Smrg	{
1168848b8605Smrg	   memset(& $$, 0, sizeof($$));
1169848b8605Smrg	   $$.param_binding_begin = ~0;
1170848b8605Smrg	   initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE);
1171848b8605Smrg	}
1172848b8605Smrg	;
1173848b8605Smrg
1174848b8605SmrgparamSingleItemUse: stateSingleItem
1175848b8605Smrg	{
1176848b8605Smrg	   memset(& $$, 0, sizeof($$));
1177848b8605Smrg	   $$.param_binding_begin = ~0;
1178848b8605Smrg	   initialize_symbol_from_state(state->prog, & $$, $1);
1179848b8605Smrg	}
1180848b8605Smrg	| programSingleItem
1181848b8605Smrg	{
1182848b8605Smrg	   memset(& $$, 0, sizeof($$));
1183848b8605Smrg	   $$.param_binding_begin = ~0;
1184848b8605Smrg	   initialize_symbol_from_param(state->prog, & $$, $1);
1185848b8605Smrg	}
1186848b8605Smrg	| paramConstUse
1187848b8605Smrg	{
1188848b8605Smrg	   memset(& $$, 0, sizeof($$));
1189848b8605Smrg	   $$.param_binding_begin = ~0;
1190848b8605Smrg	   initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE);
1191848b8605Smrg	}
1192848b8605Smrg	;
1193848b8605Smrg
1194848b8605SmrgparamMultipleItem: stateMultipleItem
1195848b8605Smrg	{
1196848b8605Smrg	   memset(& $$, 0, sizeof($$));
1197848b8605Smrg	   $$.param_binding_begin = ~0;
1198848b8605Smrg	   initialize_symbol_from_state(state->prog, & $$, $1);
1199848b8605Smrg	}
1200848b8605Smrg	| programMultipleItem
1201848b8605Smrg	{
1202848b8605Smrg	   memset(& $$, 0, sizeof($$));
1203848b8605Smrg	   $$.param_binding_begin = ~0;
1204848b8605Smrg	   initialize_symbol_from_param(state->prog, & $$, $1);
1205848b8605Smrg	}
1206848b8605Smrg	| paramConstDecl
1207848b8605Smrg	{
1208848b8605Smrg	   memset(& $$, 0, sizeof($$));
1209848b8605Smrg	   $$.param_binding_begin = ~0;
1210848b8605Smrg	   initialize_symbol_from_const(state->prog, & $$, & $1, GL_FALSE);
1211848b8605Smrg	}
1212848b8605Smrg	;
1213848b8605Smrg
1214848b8605SmrgstateMultipleItem: stateSingleItem        { memcpy($$, $1, sizeof($$)); }
1215848b8605Smrg	| STATE stateMatrixRows           { memcpy($$, $2, sizeof($$)); }
1216848b8605Smrg	;
1217848b8605Smrg
1218848b8605SmrgstateSingleItem: STATE stateMaterialItem  { memcpy($$, $2, sizeof($$)); }
1219848b8605Smrg	| STATE stateLightItem            { memcpy($$, $2, sizeof($$)); }
1220848b8605Smrg	| STATE stateLightModelItem       { memcpy($$, $2, sizeof($$)); }
1221848b8605Smrg	| STATE stateLightProdItem        { memcpy($$, $2, sizeof($$)); }
1222848b8605Smrg	| STATE stateTexGenItem           { memcpy($$, $2, sizeof($$)); }
1223848b8605Smrg	| STATE stateTexEnvItem           { memcpy($$, $2, sizeof($$)); }
1224848b8605Smrg	| STATE stateFogItem              { memcpy($$, $2, sizeof($$)); }
1225848b8605Smrg	| STATE stateClipPlaneItem        { memcpy($$, $2, sizeof($$)); }
1226848b8605Smrg	| STATE statePointItem            { memcpy($$, $2, sizeof($$)); }
1227848b8605Smrg	| STATE stateMatrixRow            { memcpy($$, $2, sizeof($$)); }
1228848b8605Smrg	| STATE stateDepthItem            { memcpy($$, $2, sizeof($$)); }
1229848b8605Smrg	;
1230848b8605Smrg
1231848b8605SmrgstateMaterialItem: MATERIAL optFaceType stateMatProperty
1232848b8605Smrg	{
1233848b8605Smrg	   memset($$, 0, sizeof($$));
1234848b8605Smrg	   $$[0] = STATE_MATERIAL;
1235848b8605Smrg	   $$[1] = $2;
1236848b8605Smrg	   $$[2] = $3;
1237848b8605Smrg	}
1238848b8605Smrg	;
1239848b8605Smrg
1240848b8605SmrgstateMatProperty: ambDiffSpecProperty
1241848b8605Smrg	{
1242848b8605Smrg	   $$ = $1;
1243848b8605Smrg	}
1244848b8605Smrg	| EMISSION
1245848b8605Smrg	{
1246848b8605Smrg	   $$ = STATE_EMISSION;
1247848b8605Smrg	}
1248848b8605Smrg	| SHININESS
1249848b8605Smrg	{
1250848b8605Smrg	   $$ = STATE_SHININESS;
1251848b8605Smrg	}
1252848b8605Smrg	;
1253848b8605Smrg
1254848b8605SmrgstateLightItem: LIGHT '[' stateLightNumber ']' stateLightProperty
1255848b8605Smrg	{
1256848b8605Smrg	   memset($$, 0, sizeof($$));
1257848b8605Smrg	   $$[0] = STATE_LIGHT;
1258848b8605Smrg	   $$[1] = $3;
1259848b8605Smrg	   $$[2] = $5;
1260848b8605Smrg	}
1261848b8605Smrg	;
1262848b8605Smrg
1263848b8605SmrgstateLightProperty: ambDiffSpecProperty
1264848b8605Smrg	{
1265848b8605Smrg	   $$ = $1;
1266848b8605Smrg	}
1267848b8605Smrg	| POSITION
1268848b8605Smrg	{
1269848b8605Smrg	   $$ = STATE_POSITION;
1270848b8605Smrg	}
1271848b8605Smrg	| ATTENUATION
1272848b8605Smrg	{
1273848b8605Smrg	   if (!state->ctx->Extensions.EXT_point_parameters) {
1274848b8605Smrg	      yyerror(& @1, state, "GL_ARB_point_parameters not supported");
1275848b8605Smrg	      YYERROR;
1276848b8605Smrg	   }
1277848b8605Smrg
1278848b8605Smrg	   $$ = STATE_ATTENUATION;
1279848b8605Smrg	}
1280848b8605Smrg	| SPOT stateSpotProperty
1281848b8605Smrg	{
1282848b8605Smrg	   $$ = $2;
1283848b8605Smrg	}
1284848b8605Smrg	| HALF
1285848b8605Smrg	{
1286848b8605Smrg	   $$ = STATE_HALF_VECTOR;
1287848b8605Smrg	}
1288848b8605Smrg	;
1289848b8605Smrg
1290848b8605SmrgstateSpotProperty: DIRECTION
1291848b8605Smrg	{
1292848b8605Smrg	   $$ = STATE_SPOT_DIRECTION;
1293848b8605Smrg	}
1294848b8605Smrg	;
1295848b8605Smrg
1296848b8605SmrgstateLightModelItem: LIGHTMODEL stateLModProperty
1297848b8605Smrg	{
1298848b8605Smrg	   $$[0] = $2[0];
1299848b8605Smrg	   $$[1] = $2[1];
1300848b8605Smrg	}
1301848b8605Smrg	;
1302848b8605Smrg
1303848b8605SmrgstateLModProperty: AMBIENT
1304848b8605Smrg	{
1305848b8605Smrg	   memset($$, 0, sizeof($$));
1306848b8605Smrg	   $$[0] = STATE_LIGHTMODEL_AMBIENT;
1307848b8605Smrg	}
1308848b8605Smrg	| optFaceType SCENECOLOR
1309848b8605Smrg	{
1310848b8605Smrg	   memset($$, 0, sizeof($$));
1311848b8605Smrg	   $$[0] = STATE_LIGHTMODEL_SCENECOLOR;
1312848b8605Smrg	   $$[1] = $1;
1313848b8605Smrg	}
1314848b8605Smrg	;
1315848b8605Smrg
1316848b8605SmrgstateLightProdItem: LIGHTPROD '[' stateLightNumber ']' optFaceType stateLProdProperty
1317848b8605Smrg	{
1318848b8605Smrg	   memset($$, 0, sizeof($$));
1319848b8605Smrg	   $$[0] = STATE_LIGHTPROD;
1320848b8605Smrg	   $$[1] = $3;
1321848b8605Smrg	   $$[2] = $5;
1322848b8605Smrg	   $$[3] = $6;
1323848b8605Smrg	}
1324848b8605Smrg	;
1325848b8605Smrg
1326848b8605SmrgstateLProdProperty: ambDiffSpecProperty;
1327848b8605Smrg
1328848b8605SmrgstateTexEnvItem: TEXENV optLegacyTexUnitNum stateTexEnvProperty
1329848b8605Smrg	{
1330848b8605Smrg	   memset($$, 0, sizeof($$));
1331848b8605Smrg	   $$[0] = $3;
1332848b8605Smrg	   $$[1] = $2;
1333848b8605Smrg	}
1334848b8605Smrg	;
1335848b8605Smrg
1336848b8605SmrgstateTexEnvProperty: COLOR
1337848b8605Smrg	{
1338848b8605Smrg	   $$ = STATE_TEXENV_COLOR;
1339848b8605Smrg	}
1340848b8605Smrg	;
1341848b8605Smrg
1342848b8605SmrgambDiffSpecProperty: AMBIENT
1343848b8605Smrg	{
1344848b8605Smrg	   $$ = STATE_AMBIENT;
1345848b8605Smrg	}
1346848b8605Smrg	| DIFFUSE
1347848b8605Smrg	{
1348848b8605Smrg	   $$ = STATE_DIFFUSE;
1349848b8605Smrg	}
1350848b8605Smrg	| SPECULAR
1351848b8605Smrg	{
1352848b8605Smrg	   $$ = STATE_SPECULAR;
1353848b8605Smrg	}
1354848b8605Smrg	;
1355848b8605Smrg
1356848b8605SmrgstateLightNumber: INTEGER
1357848b8605Smrg	{
1358848b8605Smrg	   if ((unsigned) $1 >= state->MaxLights) {
1359848b8605Smrg	      yyerror(& @1, state, "invalid light selector");
1360848b8605Smrg	      YYERROR;
1361848b8605Smrg	   }
1362848b8605Smrg
1363848b8605Smrg	   $$ = $1;
1364848b8605Smrg	}
1365848b8605Smrg	;
1366848b8605Smrg
1367848b8605SmrgstateTexGenItem: TEXGEN optTexCoordUnitNum stateTexGenType stateTexGenCoord
1368848b8605Smrg	{
1369848b8605Smrg	   memset($$, 0, sizeof($$));
1370848b8605Smrg	   $$[0] = STATE_TEXGEN;
1371848b8605Smrg	   $$[1] = $2;
1372848b8605Smrg	   $$[2] = $3 + $4;
1373848b8605Smrg	}
1374848b8605Smrg	;
1375848b8605Smrg
1376848b8605SmrgstateTexGenType: EYE
1377848b8605Smrg	{
1378848b8605Smrg	   $$ = STATE_TEXGEN_EYE_S;
1379848b8605Smrg	}
1380848b8605Smrg	| OBJECT
1381848b8605Smrg	{
1382848b8605Smrg	   $$ = STATE_TEXGEN_OBJECT_S;
1383848b8605Smrg	}
1384848b8605Smrg	;
1385848b8605SmrgstateTexGenCoord: TEXGEN_S
1386848b8605Smrg	{
1387848b8605Smrg	   $$ = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S;
1388848b8605Smrg	}
1389848b8605Smrg	| TEXGEN_T
1390848b8605Smrg	{
1391848b8605Smrg	   $$ = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S;
1392848b8605Smrg	}
1393848b8605Smrg	| TEXGEN_R
1394848b8605Smrg	{
1395848b8605Smrg	   $$ = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S;
1396848b8605Smrg	}
1397848b8605Smrg	| TEXGEN_Q
1398848b8605Smrg	{
1399848b8605Smrg	   $$ = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S;
1400848b8605Smrg	}
1401848b8605Smrg	;
1402848b8605Smrg
1403848b8605SmrgstateFogItem: FOG stateFogProperty
1404848b8605Smrg	{
1405848b8605Smrg	   memset($$, 0, sizeof($$));
1406848b8605Smrg	   $$[0] = $2;
1407848b8605Smrg	}
1408848b8605Smrg	;
1409848b8605Smrg
1410848b8605SmrgstateFogProperty: COLOR
1411848b8605Smrg	{
1412848b8605Smrg	   $$ = STATE_FOG_COLOR;
1413848b8605Smrg	}
1414848b8605Smrg	| PARAMS
1415848b8605Smrg	{
1416848b8605Smrg	   $$ = STATE_FOG_PARAMS;
1417848b8605Smrg	}
1418848b8605Smrg	;
1419848b8605Smrg
1420848b8605SmrgstateClipPlaneItem: CLIP '[' stateClipPlaneNum ']' PLANE
1421848b8605Smrg	{
1422848b8605Smrg	   memset($$, 0, sizeof($$));
1423848b8605Smrg	   $$[0] = STATE_CLIPPLANE;
1424848b8605Smrg	   $$[1] = $3;
1425848b8605Smrg	}
1426848b8605Smrg	;
1427848b8605Smrg
1428848b8605SmrgstateClipPlaneNum: INTEGER
1429848b8605Smrg	{
1430848b8605Smrg	   if ((unsigned) $1 >= state->MaxClipPlanes) {
1431848b8605Smrg	      yyerror(& @1, state, "invalid clip plane selector");
1432848b8605Smrg	      YYERROR;
1433848b8605Smrg	   }
1434848b8605Smrg
1435848b8605Smrg	   $$ = $1;
1436848b8605Smrg	}
1437848b8605Smrg	;
1438848b8605Smrg
1439848b8605SmrgstatePointItem: POINT_TOK statePointProperty
1440848b8605Smrg	{
1441848b8605Smrg	   memset($$, 0, sizeof($$));
1442848b8605Smrg	   $$[0] = $2;
1443848b8605Smrg	}
1444848b8605Smrg	;
1445848b8605Smrg
1446848b8605SmrgstatePointProperty: SIZE_TOK
1447848b8605Smrg	{
1448848b8605Smrg	   $$ = STATE_POINT_SIZE;
1449848b8605Smrg	}
1450848b8605Smrg	| ATTENUATION
1451848b8605Smrg	{
1452848b8605Smrg	   $$ = STATE_POINT_ATTENUATION;
1453848b8605Smrg	}
1454848b8605Smrg	;
1455848b8605Smrg
1456848b8605SmrgstateMatrixRow: stateMatrixItem ROW '[' stateMatrixRowNum ']'
1457848b8605Smrg	{
1458848b8605Smrg	   $$[0] = $1[0];
1459848b8605Smrg	   $$[1] = $1[1];
1460848b8605Smrg	   $$[2] = $4;
1461848b8605Smrg	   $$[3] = $4;
1462848b8605Smrg	   $$[4] = $1[2];
1463848b8605Smrg	}
1464848b8605Smrg	;
1465848b8605Smrg
1466848b8605SmrgstateMatrixRows: stateMatrixItem optMatrixRows
1467848b8605Smrg	{
1468848b8605Smrg	   $$[0] = $1[0];
1469848b8605Smrg	   $$[1] = $1[1];
1470848b8605Smrg	   $$[2] = $2[2];
1471848b8605Smrg	   $$[3] = $2[3];
1472848b8605Smrg	   $$[4] = $1[2];
1473848b8605Smrg	}
1474848b8605Smrg	;
1475848b8605Smrg
1476848b8605SmrgoptMatrixRows:
1477848b8605Smrg	{
1478848b8605Smrg	   $$[2] = 0;
1479848b8605Smrg	   $$[3] = 3;
1480848b8605Smrg	}
1481848b8605Smrg	| ROW '[' stateMatrixRowNum DOT_DOT stateMatrixRowNum ']'
1482848b8605Smrg	{
1483848b8605Smrg	   /* It seems logical that the matrix row range specifier would have
1484848b8605Smrg	    * to specify a range or more than one row (i.e., $5 > $3).
1485848b8605Smrg	    * However, the ARB_vertex_program spec says "a program will fail
1486848b8605Smrg	    * to load if <a> is greater than <b>."  This means that $3 == $5
1487848b8605Smrg	    * is valid.
1488848b8605Smrg	    */
1489848b8605Smrg	   if ($3 > $5) {
1490848b8605Smrg	      yyerror(& @3, state, "invalid matrix row range");
1491848b8605Smrg	      YYERROR;
1492848b8605Smrg	   }
1493848b8605Smrg
1494848b8605Smrg	   $$[2] = $3;
1495848b8605Smrg	   $$[3] = $5;
1496848b8605Smrg	}
1497848b8605Smrg	;
1498848b8605Smrg
1499848b8605SmrgstateMatrixItem: MATRIX stateMatrixName stateOptMatModifier
1500848b8605Smrg	{
1501848b8605Smrg	   $$[0] = $2[0];
1502848b8605Smrg	   $$[1] = $2[1];
1503848b8605Smrg	   $$[2] = $3;
1504848b8605Smrg	}
1505848b8605Smrg	;
1506848b8605Smrg
1507848b8605SmrgstateOptMatModifier:
1508848b8605Smrg	{
1509848b8605Smrg	   $$ = 0;
1510848b8605Smrg	}
1511848b8605Smrg	| stateMatModifier
1512848b8605Smrg	{
1513848b8605Smrg	   $$ = $1;
1514848b8605Smrg	}
1515848b8605Smrg	;
1516848b8605Smrg
1517848b8605SmrgstateMatModifier: INVERSE
1518848b8605Smrg	{
1519848b8605Smrg	   $$ = STATE_MATRIX_INVERSE;
1520848b8605Smrg	}
1521848b8605Smrg	| TRANSPOSE
1522848b8605Smrg	{
1523848b8605Smrg	   $$ = STATE_MATRIX_TRANSPOSE;
1524848b8605Smrg	}
1525848b8605Smrg	| INVTRANS
1526848b8605Smrg	{
1527848b8605Smrg	   $$ = STATE_MATRIX_INVTRANS;
1528848b8605Smrg	}
1529848b8605Smrg	;
1530848b8605Smrg
1531848b8605SmrgstateMatrixRowNum: INTEGER
1532848b8605Smrg	{
1533848b8605Smrg	   if ($1 > 3) {
1534848b8605Smrg	      yyerror(& @1, state, "invalid matrix row reference");
1535848b8605Smrg	      YYERROR;
1536848b8605Smrg	   }
1537848b8605Smrg
1538848b8605Smrg	   $$ = $1;
1539848b8605Smrg	}
1540848b8605Smrg	;
1541848b8605Smrg
1542848b8605SmrgstateMatrixName: MODELVIEW stateOptModMatNum
1543848b8605Smrg	{
1544848b8605Smrg	   $$[0] = STATE_MODELVIEW_MATRIX;
1545848b8605Smrg	   $$[1] = $2;
1546848b8605Smrg	}
1547848b8605Smrg	| PROJECTION
1548848b8605Smrg	{
1549848b8605Smrg	   $$[0] = STATE_PROJECTION_MATRIX;
1550848b8605Smrg	   $$[1] = 0;
1551848b8605Smrg	}
1552848b8605Smrg	| MVP
1553848b8605Smrg	{
1554848b8605Smrg	   $$[0] = STATE_MVP_MATRIX;
1555848b8605Smrg	   $$[1] = 0;
1556848b8605Smrg	}
1557848b8605Smrg	| TEXTURE optTexCoordUnitNum
1558848b8605Smrg	{
1559848b8605Smrg	   $$[0] = STATE_TEXTURE_MATRIX;
1560848b8605Smrg	   $$[1] = $2;
1561848b8605Smrg	}
1562848b8605Smrg	| PALETTE '[' statePaletteMatNum ']'
1563848b8605Smrg	{
1564848b8605Smrg	   yyerror(& @1, state, "GL_ARB_matrix_palette not supported");
1565848b8605Smrg	   YYERROR;
1566848b8605Smrg	}
1567848b8605Smrg	| MAT_PROGRAM '[' stateProgramMatNum ']'
1568848b8605Smrg	{
1569848b8605Smrg	   $$[0] = STATE_PROGRAM_MATRIX;
1570848b8605Smrg	   $$[1] = $3;
1571848b8605Smrg	}
1572848b8605Smrg	;
1573848b8605Smrg
1574848b8605SmrgstateOptModMatNum:
1575848b8605Smrg	{
1576848b8605Smrg	   $$ = 0;
1577848b8605Smrg	}
1578848b8605Smrg	| '[' stateModMatNum ']'
1579848b8605Smrg	{
1580848b8605Smrg	   $$ = $2;
1581848b8605Smrg	}
1582848b8605Smrg	;
1583848b8605SmrgstateModMatNum: INTEGER
1584848b8605Smrg	{
1585848b8605Smrg	   /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix
1586848b8605Smrg	    * zero is valid.
1587848b8605Smrg	    */
1588848b8605Smrg	   if ($1 != 0) {
1589848b8605Smrg	      yyerror(& @1, state, "invalid modelview matrix index");
1590848b8605Smrg	      YYERROR;
1591848b8605Smrg	   }
1592848b8605Smrg
1593848b8605Smrg	   $$ = $1;
1594848b8605Smrg	}
1595848b8605Smrg	;
1596848b8605SmrgstatePaletteMatNum: INTEGER
1597848b8605Smrg	{
1598848b8605Smrg	   /* Since GL_ARB_matrix_palette isn't supported, just let any value
1599848b8605Smrg	    * through here.  The error will be generated later.
1600848b8605Smrg	    */
1601848b8605Smrg	   $$ = $1;
1602848b8605Smrg	}
1603848b8605Smrg	;
1604848b8605SmrgstateProgramMatNum: INTEGER
1605848b8605Smrg	{
1606848b8605Smrg	   if ((unsigned) $1 >= state->MaxProgramMatrices) {
1607848b8605Smrg	      yyerror(& @1, state, "invalid program matrix selector");
1608848b8605Smrg	      YYERROR;
1609848b8605Smrg	   }
1610848b8605Smrg
1611848b8605Smrg	   $$ = $1;
1612848b8605Smrg	}
1613848b8605Smrg	;
1614848b8605Smrg
1615848b8605SmrgstateDepthItem: DEPTH RANGE
1616848b8605Smrg	{
1617848b8605Smrg	   memset($$, 0, sizeof($$));
1618848b8605Smrg	   $$[0] = STATE_DEPTH_RANGE;
1619848b8605Smrg	}
1620848b8605Smrg	;
1621848b8605Smrg
1622848b8605Smrg
1623848b8605SmrgprogramSingleItem: progEnvParam | progLocalParam;
1624848b8605Smrg
1625848b8605SmrgprogramMultipleItem: progEnvParams | progLocalParams;
1626848b8605Smrg
1627848b8605SmrgprogEnvParams: PROGRAM ENV '[' progEnvParamNums ']'
1628848b8605Smrg	{
1629848b8605Smrg	   memset($$, 0, sizeof($$));
1630848b8605Smrg	   $$[0] = state->state_param_enum;
1631848b8605Smrg	   $$[1] = STATE_ENV;
1632848b8605Smrg	   $$[2] = $4[0];
1633848b8605Smrg	   $$[3] = $4[1];
1634848b8605Smrg	}
1635848b8605Smrg	;
1636848b8605Smrg
1637848b8605SmrgprogEnvParamNums: progEnvParamNum
1638848b8605Smrg	{
1639848b8605Smrg	   $$[0] = $1;
1640848b8605Smrg	   $$[1] = $1;
1641848b8605Smrg	}
1642848b8605Smrg	| progEnvParamNum DOT_DOT progEnvParamNum
1643848b8605Smrg	{
1644848b8605Smrg	   $$[0] = $1;
1645848b8605Smrg	   $$[1] = $3;
1646848b8605Smrg	}
1647848b8605Smrg	;
1648848b8605Smrg
1649848b8605SmrgprogEnvParam: PROGRAM ENV '[' progEnvParamNum ']'
1650848b8605Smrg	{
1651848b8605Smrg	   memset($$, 0, sizeof($$));
1652848b8605Smrg	   $$[0] = state->state_param_enum;
1653848b8605Smrg	   $$[1] = STATE_ENV;
1654848b8605Smrg	   $$[2] = $4;
1655848b8605Smrg	   $$[3] = $4;
1656848b8605Smrg	}
1657848b8605Smrg	;
1658848b8605Smrg
1659848b8605SmrgprogLocalParams: PROGRAM LOCAL '[' progLocalParamNums ']'
1660848b8605Smrg	{
1661848b8605Smrg	   memset($$, 0, sizeof($$));
1662848b8605Smrg	   $$[0] = state->state_param_enum;
1663848b8605Smrg	   $$[1] = STATE_LOCAL;
1664848b8605Smrg	   $$[2] = $4[0];
1665848b8605Smrg	   $$[3] = $4[1];
1666848b8605Smrg	}
1667848b8605Smrg
1668848b8605SmrgprogLocalParamNums: progLocalParamNum
1669848b8605Smrg	{
1670848b8605Smrg	   $$[0] = $1;
1671848b8605Smrg	   $$[1] = $1;
1672848b8605Smrg	}
1673848b8605Smrg	| progLocalParamNum DOT_DOT progLocalParamNum
1674848b8605Smrg	{
1675848b8605Smrg	   $$[0] = $1;
1676848b8605Smrg	   $$[1] = $3;
1677848b8605Smrg	}
1678848b8605Smrg	;
1679848b8605Smrg
1680848b8605SmrgprogLocalParam: PROGRAM LOCAL '[' progLocalParamNum ']'
1681848b8605Smrg	{
1682848b8605Smrg	   memset($$, 0, sizeof($$));
1683848b8605Smrg	   $$[0] = state->state_param_enum;
1684848b8605Smrg	   $$[1] = STATE_LOCAL;
1685848b8605Smrg	   $$[2] = $4;
1686848b8605Smrg	   $$[3] = $4;
1687848b8605Smrg	}
1688848b8605Smrg	;
1689848b8605Smrg
1690848b8605SmrgprogEnvParamNum: INTEGER
1691848b8605Smrg	{
1692848b8605Smrg	   if ((unsigned) $1 >= state->limits->MaxEnvParams) {
1693848b8605Smrg	      yyerror(& @1, state, "invalid environment parameter reference");
1694848b8605Smrg	      YYERROR;
1695848b8605Smrg	   }
1696848b8605Smrg	   $$ = $1;
1697848b8605Smrg	}
1698848b8605Smrg	;
1699848b8605Smrg
1700848b8605SmrgprogLocalParamNum: INTEGER
1701848b8605Smrg	{
1702848b8605Smrg	   if ((unsigned) $1 >= state->limits->MaxLocalParams) {
1703848b8605Smrg	      yyerror(& @1, state, "invalid local parameter reference");
1704848b8605Smrg	      YYERROR;
1705848b8605Smrg	   }
1706848b8605Smrg	   $$ = $1;
1707848b8605Smrg	}
1708848b8605Smrg	;
1709848b8605Smrg
1710848b8605Smrg
1711848b8605Smrg
1712848b8605SmrgparamConstDecl: paramConstScalarDecl | paramConstVector;
1713848b8605SmrgparamConstUse: paramConstScalarUse | paramConstVector;
1714848b8605Smrg
1715848b8605SmrgparamConstScalarDecl: signedFloatConstant
1716848b8605Smrg	{
1717848b8605Smrg	   $$.count = 4;
1718848b8605Smrg	   $$.data[0].f = $1;
1719848b8605Smrg	   $$.data[1].f = $1;
1720848b8605Smrg	   $$.data[2].f = $1;
1721848b8605Smrg	   $$.data[3].f = $1;
1722848b8605Smrg	}
1723848b8605Smrg	;
1724848b8605Smrg
1725848b8605SmrgparamConstScalarUse: REAL
1726848b8605Smrg	{
1727848b8605Smrg	   $$.count = 1;
1728848b8605Smrg	   $$.data[0].f = $1;
1729848b8605Smrg	   $$.data[1].f = $1;
1730848b8605Smrg	   $$.data[2].f = $1;
1731848b8605Smrg	   $$.data[3].f = $1;
1732848b8605Smrg	}
1733848b8605Smrg	| INTEGER
1734848b8605Smrg	{
1735848b8605Smrg	   $$.count = 1;
1736848b8605Smrg	   $$.data[0].f = (float) $1;
1737848b8605Smrg	   $$.data[1].f = (float) $1;
1738848b8605Smrg	   $$.data[2].f = (float) $1;
1739848b8605Smrg	   $$.data[3].f = (float) $1;
1740848b8605Smrg	}
1741848b8605Smrg	;
1742848b8605Smrg
1743848b8605SmrgparamConstVector: '{' signedFloatConstant '}'
1744848b8605Smrg	{
1745848b8605Smrg	   $$.count = 4;
1746848b8605Smrg	   $$.data[0].f = $2;
1747848b8605Smrg	   $$.data[1].f = 0.0f;
1748848b8605Smrg	   $$.data[2].f = 0.0f;
1749848b8605Smrg	   $$.data[3].f = 1.0f;
1750848b8605Smrg	}
1751848b8605Smrg	| '{' signedFloatConstant ',' signedFloatConstant '}'
1752848b8605Smrg	{
1753848b8605Smrg	   $$.count = 4;
1754848b8605Smrg	   $$.data[0].f = $2;
1755848b8605Smrg	   $$.data[1].f = $4;
1756848b8605Smrg	   $$.data[2].f = 0.0f;
1757848b8605Smrg	   $$.data[3].f = 1.0f;
1758848b8605Smrg	}
1759848b8605Smrg	| '{' signedFloatConstant ',' signedFloatConstant ','
1760848b8605Smrg              signedFloatConstant '}'
1761848b8605Smrg	{
1762848b8605Smrg	   $$.count = 4;
1763848b8605Smrg	   $$.data[0].f = $2;
1764848b8605Smrg	   $$.data[1].f = $4;
1765848b8605Smrg	   $$.data[2].f = $6;
1766848b8605Smrg	   $$.data[3].f = 1.0f;
1767848b8605Smrg	}
1768848b8605Smrg	| '{' signedFloatConstant ',' signedFloatConstant ','
1769848b8605Smrg              signedFloatConstant ',' signedFloatConstant '}'
1770848b8605Smrg	{
1771848b8605Smrg	   $$.count = 4;
1772848b8605Smrg	   $$.data[0].f = $2;
1773848b8605Smrg	   $$.data[1].f = $4;
1774848b8605Smrg	   $$.data[2].f = $6;
1775848b8605Smrg	   $$.data[3].f = $8;
1776848b8605Smrg	}
1777848b8605Smrg	;
1778848b8605Smrg
1779848b8605SmrgsignedFloatConstant: optionalSign REAL
1780848b8605Smrg	{
1781848b8605Smrg	   $$ = ($1) ? -$2 : $2;
1782848b8605Smrg	}
1783848b8605Smrg	| optionalSign INTEGER
1784848b8605Smrg	{
1785848b8605Smrg	   $$ = (float)(($1) ? -$2 : $2);
1786848b8605Smrg	}
1787848b8605Smrg	;
1788848b8605Smrg
1789848b8605SmrgoptionalSign: '+'        { $$ = FALSE; }
1790848b8605Smrg	| '-'            { $$ = TRUE;  }
1791848b8605Smrg	|                { $$ = FALSE; }
1792848b8605Smrg	;
1793848b8605Smrg
1794b8e80941SmrgTEMP_statement: TEMP { $<integer>$ = $1; } varNameList
1795848b8605Smrg	;
1796848b8605Smrg
1797848b8605SmrgADDRESS_statement: ADDRESS { $<integer>$ = $1; } varNameList
1798848b8605Smrg	;
1799848b8605Smrg
1800848b8605SmrgvarNameList: varNameList ',' IDENTIFIER
1801848b8605Smrg	{
1802848b8605Smrg	   if (!declare_variable(state, $3, $<integer>0, & @3)) {
1803848b8605Smrg	      free($3);
1804848b8605Smrg	      YYERROR;
1805848b8605Smrg	   }
1806848b8605Smrg	}
1807848b8605Smrg	| IDENTIFIER
1808848b8605Smrg	{
1809848b8605Smrg	   if (!declare_variable(state, $1, $<integer>0, & @1)) {
1810848b8605Smrg	      free($1);
1811848b8605Smrg	      YYERROR;
1812848b8605Smrg	   }
1813848b8605Smrg	}
1814848b8605Smrg	;
1815848b8605Smrg
1816b8e80941SmrgOUTPUT_statement: OUTPUT IDENTIFIER '=' resultBinding
1817848b8605Smrg	{
1818848b8605Smrg	   struct asm_symbol *const s =
1819b8e80941Smrg	      declare_variable(state, $2, at_output, & @2);
1820848b8605Smrg
1821848b8605Smrg	   if (s == NULL) {
1822b8e80941Smrg	      free($2);
1823848b8605Smrg	      YYERROR;
1824848b8605Smrg	   } else {
1825b8e80941Smrg	      s->output_binding = $4;
1826848b8605Smrg	   }
1827848b8605Smrg	}
1828848b8605Smrg	;
1829848b8605Smrg
1830848b8605SmrgresultBinding: RESULT POSITION
1831848b8605Smrg	{
1832848b8605Smrg	   if (state->mode == ARB_vertex) {
1833848b8605Smrg	      $$ = VARYING_SLOT_POS;
1834848b8605Smrg	   } else {
1835848b8605Smrg	      yyerror(& @2, state, "invalid program result name");
1836848b8605Smrg	      YYERROR;
1837848b8605Smrg	   }
1838848b8605Smrg	}
1839848b8605Smrg	| RESULT FOGCOORD
1840848b8605Smrg	{
1841848b8605Smrg	   if (state->mode == ARB_vertex) {
1842848b8605Smrg	      $$ = VARYING_SLOT_FOGC;
1843848b8605Smrg	   } else {
1844848b8605Smrg	      yyerror(& @2, state, "invalid program result name");
1845848b8605Smrg	      YYERROR;
1846848b8605Smrg	   }
1847848b8605Smrg	}
1848848b8605Smrg	| RESULT resultColBinding
1849848b8605Smrg	{
1850848b8605Smrg	   $$ = $2;
1851848b8605Smrg	}
1852848b8605Smrg	| RESULT POINTSIZE
1853848b8605Smrg	{
1854848b8605Smrg	   if (state->mode == ARB_vertex) {
1855848b8605Smrg	      $$ = VARYING_SLOT_PSIZ;
1856848b8605Smrg	   } else {
1857848b8605Smrg	      yyerror(& @2, state, "invalid program result name");
1858848b8605Smrg	      YYERROR;
1859848b8605Smrg	   }
1860848b8605Smrg	}
1861848b8605Smrg	| RESULT TEXCOORD optTexCoordUnitNum
1862848b8605Smrg	{
1863848b8605Smrg	   if (state->mode == ARB_vertex) {
1864848b8605Smrg	      $$ = VARYING_SLOT_TEX0 + $3;
1865848b8605Smrg	   } else {
1866848b8605Smrg	      yyerror(& @2, state, "invalid program result name");
1867848b8605Smrg	      YYERROR;
1868848b8605Smrg	   }
1869848b8605Smrg	}
1870848b8605Smrg	| RESULT DEPTH
1871848b8605Smrg	{
1872848b8605Smrg	   if (state->mode == ARB_fragment) {
1873848b8605Smrg	      $$ = FRAG_RESULT_DEPTH;
1874848b8605Smrg	   } else {
1875848b8605Smrg	      yyerror(& @2, state, "invalid program result name");
1876848b8605Smrg	      YYERROR;
1877848b8605Smrg	   }
1878848b8605Smrg	}
1879848b8605Smrg	;
1880848b8605Smrg
1881848b8605SmrgresultColBinding: COLOR optResultFaceType optResultColorType
1882848b8605Smrg	{
1883848b8605Smrg	   $$ = $2 + $3;
1884848b8605Smrg	}
1885848b8605Smrg	;
1886848b8605Smrg
1887848b8605SmrgoptResultFaceType:
1888848b8605Smrg	{
1889848b8605Smrg	   if (state->mode == ARB_vertex) {
1890848b8605Smrg	      $$ = VARYING_SLOT_COL0;
1891848b8605Smrg	   } else {
1892848b8605Smrg	      if (state->option.DrawBuffers)
1893848b8605Smrg		 $$ = FRAG_RESULT_DATA0;
1894848b8605Smrg	      else
1895848b8605Smrg		 $$ = FRAG_RESULT_COLOR;
1896848b8605Smrg	   }
1897848b8605Smrg	}
1898848b8605Smrg	| '[' INTEGER ']'
1899848b8605Smrg	{
1900848b8605Smrg	   if (state->mode == ARB_vertex) {
1901848b8605Smrg	      yyerror(& @1, state, "invalid program result name");
1902848b8605Smrg	      YYERROR;
1903848b8605Smrg	   } else {
1904848b8605Smrg	      if (!state->option.DrawBuffers) {
1905848b8605Smrg		 /* From the ARB_draw_buffers spec (same text exists
1906848b8605Smrg		  * for ATI_draw_buffers):
1907848b8605Smrg		  *
1908848b8605Smrg		  *     If this option is not specified, a fragment
1909848b8605Smrg		  *     program that attempts to bind
1910848b8605Smrg		  *     "result.color[n]" will fail to load, and only
1911848b8605Smrg		  *     "result.color" will be allowed.
1912848b8605Smrg		  */
1913848b8605Smrg		 yyerror(& @1, state,
1914848b8605Smrg			 "result.color[] used without "
1915848b8605Smrg			 "`OPTION ARB_draw_buffers' or "
1916848b8605Smrg			 "`OPTION ATI_draw_buffers'");
1917848b8605Smrg		 YYERROR;
1918848b8605Smrg	      } else if ($2 >= state->MaxDrawBuffers) {
1919848b8605Smrg		 yyerror(& @1, state,
1920848b8605Smrg			 "result.color[] exceeds MAX_DRAW_BUFFERS_ARB");
1921848b8605Smrg		 YYERROR;
1922848b8605Smrg	      }
1923848b8605Smrg	      $$ = FRAG_RESULT_DATA0 + $2;
1924848b8605Smrg	   }
1925848b8605Smrg	}
1926848b8605Smrg	| FRONT
1927848b8605Smrg	{
1928848b8605Smrg	   if (state->mode == ARB_vertex) {
1929848b8605Smrg	      $$ = VARYING_SLOT_COL0;
1930848b8605Smrg	   } else {
1931848b8605Smrg	      yyerror(& @1, state, "invalid program result name");
1932848b8605Smrg	      YYERROR;
1933848b8605Smrg	   }
1934848b8605Smrg	}
1935848b8605Smrg	| BACK
1936848b8605Smrg	{
1937848b8605Smrg	   if (state->mode == ARB_vertex) {
1938848b8605Smrg	      $$ = VARYING_SLOT_BFC0;
1939848b8605Smrg	   } else {
1940848b8605Smrg	      yyerror(& @1, state, "invalid program result name");
1941848b8605Smrg	      YYERROR;
1942848b8605Smrg	   }
1943848b8605Smrg	}
1944848b8605Smrg	;
1945848b8605Smrg
1946848b8605SmrgoptResultColorType:
1947848b8605Smrg	{
1948848b8605Smrg	   $$ = 0;
1949848b8605Smrg	}
1950848b8605Smrg	| PRIMARY
1951848b8605Smrg	{
1952848b8605Smrg	   if (state->mode == ARB_vertex) {
1953848b8605Smrg	      $$ = 0;
1954848b8605Smrg	   } else {
1955848b8605Smrg	      yyerror(& @1, state, "invalid program result name");
1956848b8605Smrg	      YYERROR;
1957848b8605Smrg	   }
1958848b8605Smrg	}
1959848b8605Smrg	| SECONDARY
1960848b8605Smrg	{
1961848b8605Smrg	   if (state->mode == ARB_vertex) {
1962848b8605Smrg	      $$ = 1;
1963848b8605Smrg	   } else {
1964848b8605Smrg	      yyerror(& @1, state, "invalid program result name");
1965848b8605Smrg	      YYERROR;
1966848b8605Smrg	   }
1967848b8605Smrg	}
1968848b8605Smrg	;
1969848b8605Smrg
1970848b8605SmrgoptFaceType:    { $$ = 0; }
1971848b8605Smrg	| FRONT	{ $$ = 0; }
1972848b8605Smrg	| BACK  { $$ = 1; }
1973848b8605Smrg	;
1974848b8605Smrg
1975848b8605SmrgoptColorType:       { $$ = 0; }
1976848b8605Smrg	| PRIMARY   { $$ = 0; }
1977848b8605Smrg	| SECONDARY { $$ = 1; }
1978848b8605Smrg	;
1979848b8605Smrg
1980848b8605SmrgoptTexCoordUnitNum:                { $$ = 0; }
1981848b8605Smrg	| '[' texCoordUnitNum ']'  { $$ = $2; }
1982848b8605Smrg	;
1983848b8605Smrg
1984848b8605SmrgoptTexImageUnitNum:                { $$ = 0; }
1985848b8605Smrg	| '[' texImageUnitNum ']'  { $$ = $2; }
1986848b8605Smrg	;
1987848b8605Smrg
1988848b8605SmrgoptLegacyTexUnitNum:               { $$ = 0; }
1989848b8605Smrg	| '[' legacyTexUnitNum ']' { $$ = $2; }
1990848b8605Smrg	;
1991848b8605Smrg
1992848b8605SmrgtexCoordUnitNum: INTEGER
1993848b8605Smrg	{
1994848b8605Smrg	   if ((unsigned) $1 >= state->MaxTextureCoordUnits) {
1995848b8605Smrg	      yyerror(& @1, state, "invalid texture coordinate unit selector");
1996848b8605Smrg	      YYERROR;
1997848b8605Smrg	   }
1998848b8605Smrg
1999848b8605Smrg	   $$ = $1;
2000848b8605Smrg	}
2001848b8605Smrg	;
2002848b8605Smrg
2003848b8605SmrgtexImageUnitNum: INTEGER
2004848b8605Smrg	{
2005848b8605Smrg	   if ((unsigned) $1 >= state->MaxTextureImageUnits) {
2006848b8605Smrg	      yyerror(& @1, state, "invalid texture image unit selector");
2007848b8605Smrg	      YYERROR;
2008848b8605Smrg	   }
2009848b8605Smrg
2010848b8605Smrg	   $$ = $1;
2011848b8605Smrg	}
2012848b8605Smrg	;
2013848b8605Smrg
2014848b8605SmrglegacyTexUnitNum: INTEGER
2015848b8605Smrg	{
2016848b8605Smrg	   if ((unsigned) $1 >= state->MaxTextureUnits) {
2017848b8605Smrg	      yyerror(& @1, state, "invalid texture unit selector");
2018848b8605Smrg	      YYERROR;
2019848b8605Smrg	   }
2020848b8605Smrg
2021848b8605Smrg	   $$ = $1;
2022848b8605Smrg	}
2023848b8605Smrg	;
2024848b8605Smrg
2025848b8605SmrgALIAS_statement: ALIAS IDENTIFIER '=' USED_IDENTIFIER
2026848b8605Smrg	{
2027848b8605Smrg	   struct asm_symbol *exist = (struct asm_symbol *)
2028b8e80941Smrg              _mesa_symbol_table_find_symbol(state->st, $2);
2029848b8605Smrg	   struct asm_symbol *target = (struct asm_symbol *)
2030b8e80941Smrg              _mesa_symbol_table_find_symbol(state->st, $4);
2031848b8605Smrg
2032848b8605Smrg	   free($4);
2033848b8605Smrg
2034848b8605Smrg	   if (exist != NULL) {
2035848b8605Smrg	      char m[1000];
2036848b8605Smrg	      _mesa_snprintf(m, sizeof(m), "redeclared identifier: %s", $2);
2037848b8605Smrg	      free($2);
2038848b8605Smrg	      yyerror(& @2, state, m);
2039848b8605Smrg	      YYERROR;
2040848b8605Smrg	   } else if (target == NULL) {
2041848b8605Smrg	      free($2);
2042848b8605Smrg	      yyerror(& @4, state,
2043848b8605Smrg		      "undefined variable binding in ALIAS statement");
2044848b8605Smrg	      YYERROR;
2045848b8605Smrg	   } else {
2046b8e80941Smrg              _mesa_symbol_table_add_symbol(state->st, $2, target);
2047848b8605Smrg	   }
2048848b8605Smrg	}
2049848b8605Smrg	;
2050848b8605Smrg
2051848b8605Smrgstring: IDENTIFIER
2052848b8605Smrg	| USED_IDENTIFIER
2053848b8605Smrg	;
2054848b8605Smrg
2055848b8605Smrg%%
2056848b8605Smrg
2057848b8605Smrgvoid
2058848b8605Smrgasm_instruction_set_operands(struct asm_instruction *inst,
2059848b8605Smrg			     const struct prog_dst_register *dst,
2060848b8605Smrg			     const struct asm_src_register *src0,
2061848b8605Smrg			     const struct asm_src_register *src1,
2062848b8605Smrg			     const struct asm_src_register *src2)
2063848b8605Smrg{
2064848b8605Smrg   /* In the core ARB extensions only the KIL instruction doesn't have a
2065848b8605Smrg    * destination register.
2066848b8605Smrg    */
2067848b8605Smrg   if (dst == NULL) {
2068848b8605Smrg      init_dst_reg(& inst->Base.DstReg);
2069848b8605Smrg   } else {
2070848b8605Smrg      inst->Base.DstReg = *dst;
2071848b8605Smrg   }
2072848b8605Smrg
2073848b8605Smrg   if (src0 != NULL) {
2074848b8605Smrg      inst->Base.SrcReg[0] = src0->Base;
2075848b8605Smrg      inst->SrcReg[0] = *src0;
2076848b8605Smrg   } else {
2077848b8605Smrg      init_src_reg(& inst->SrcReg[0]);
2078848b8605Smrg   }
2079848b8605Smrg
2080848b8605Smrg   if (src1 != NULL) {
2081848b8605Smrg      inst->Base.SrcReg[1] = src1->Base;
2082848b8605Smrg      inst->SrcReg[1] = *src1;
2083848b8605Smrg   } else {
2084848b8605Smrg      init_src_reg(& inst->SrcReg[1]);
2085848b8605Smrg   }
2086848b8605Smrg
2087848b8605Smrg   if (src2 != NULL) {
2088848b8605Smrg      inst->Base.SrcReg[2] = src2->Base;
2089848b8605Smrg      inst->SrcReg[2] = *src2;
2090848b8605Smrg   } else {
2091848b8605Smrg      init_src_reg(& inst->SrcReg[2]);
2092848b8605Smrg   }
2093848b8605Smrg}
2094848b8605Smrg
2095848b8605Smrg
2096848b8605Smrgstruct asm_instruction *
2097b8e80941Smrgasm_instruction_ctor(enum prog_opcode op,
2098848b8605Smrg		     const struct prog_dst_register *dst,
2099848b8605Smrg		     const struct asm_src_register *src0,
2100848b8605Smrg		     const struct asm_src_register *src1,
2101848b8605Smrg		     const struct asm_src_register *src2)
2102848b8605Smrg{
2103848b8605Smrg   struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
2104848b8605Smrg
2105848b8605Smrg   if (inst) {
2106848b8605Smrg      _mesa_init_instructions(& inst->Base, 1);
2107848b8605Smrg      inst->Base.Opcode = op;
2108848b8605Smrg
2109848b8605Smrg      asm_instruction_set_operands(inst, dst, src0, src1, src2);
2110848b8605Smrg   }
2111848b8605Smrg
2112848b8605Smrg   return inst;
2113848b8605Smrg}
2114848b8605Smrg
2115848b8605Smrg
2116848b8605Smrgstruct asm_instruction *
2117848b8605Smrgasm_instruction_copy_ctor(const struct prog_instruction *base,
2118848b8605Smrg			  const struct prog_dst_register *dst,
2119848b8605Smrg			  const struct asm_src_register *src0,
2120848b8605Smrg			  const struct asm_src_register *src1,
2121848b8605Smrg			  const struct asm_src_register *src2)
2122848b8605Smrg{
2123848b8605Smrg   struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
2124848b8605Smrg
2125848b8605Smrg   if (inst) {
2126848b8605Smrg      _mesa_init_instructions(& inst->Base, 1);
2127848b8605Smrg      inst->Base.Opcode = base->Opcode;
2128b8e80941Smrg      inst->Base.Saturate = base->Saturate;
2129848b8605Smrg
2130848b8605Smrg      asm_instruction_set_operands(inst, dst, src0, src1, src2);
2131848b8605Smrg   }
2132848b8605Smrg
2133848b8605Smrg   return inst;
2134848b8605Smrg}
2135848b8605Smrg
2136848b8605Smrg
2137848b8605Smrgvoid
2138848b8605Smrginit_dst_reg(struct prog_dst_register *r)
2139848b8605Smrg{
2140848b8605Smrg   memset(r, 0, sizeof(*r));
2141848b8605Smrg   r->File = PROGRAM_UNDEFINED;
2142848b8605Smrg   r->WriteMask = WRITEMASK_XYZW;
2143848b8605Smrg}
2144848b8605Smrg
2145848b8605Smrg
2146848b8605Smrg/** Like init_dst_reg() but set the File and Index fields. */
2147848b8605Smrgvoid
2148848b8605Smrgset_dst_reg(struct prog_dst_register *r, gl_register_file file, GLint index)
2149848b8605Smrg{
2150848b8605Smrg   const GLint maxIndex = 1 << INST_INDEX_BITS;
2151848b8605Smrg   const GLint minIndex = 0;
2152b8e80941Smrg   assert(index >= minIndex);
2153848b8605Smrg   (void) minIndex;
2154b8e80941Smrg   assert(index <= maxIndex);
2155848b8605Smrg   (void) maxIndex;
2156b8e80941Smrg   assert(file == PROGRAM_TEMPORARY ||
2157848b8605Smrg	  file == PROGRAM_ADDRESS ||
2158848b8605Smrg	  file == PROGRAM_OUTPUT);
2159848b8605Smrg   memset(r, 0, sizeof(*r));
2160848b8605Smrg   r->File = file;
2161848b8605Smrg   r->Index = index;
2162848b8605Smrg   r->WriteMask = WRITEMASK_XYZW;
2163848b8605Smrg}
2164848b8605Smrg
2165848b8605Smrg
2166848b8605Smrgvoid
2167848b8605Smrginit_src_reg(struct asm_src_register *r)
2168848b8605Smrg{
2169848b8605Smrg   memset(r, 0, sizeof(*r));
2170848b8605Smrg   r->Base.File = PROGRAM_UNDEFINED;
2171848b8605Smrg   r->Base.Swizzle = SWIZZLE_NOOP;
2172848b8605Smrg   r->Symbol = NULL;
2173848b8605Smrg}
2174848b8605Smrg
2175848b8605Smrg
2176848b8605Smrg/** Like init_src_reg() but set the File and Index fields.
2177848b8605Smrg * \return GL_TRUE if a valid src register, GL_FALSE otherwise
2178848b8605Smrg */
2179848b8605Smrgvoid
2180848b8605Smrgset_src_reg(struct asm_src_register *r, gl_register_file file, GLint index)
2181848b8605Smrg{
2182848b8605Smrg   set_src_reg_swz(r, file, index, SWIZZLE_XYZW);
2183848b8605Smrg}
2184848b8605Smrg
2185848b8605Smrg
2186848b8605Smrgvoid
2187848b8605Smrgset_src_reg_swz(struct asm_src_register *r, gl_register_file file, GLint index,
2188848b8605Smrg                GLuint swizzle)
2189848b8605Smrg{
2190848b8605Smrg   const GLint maxIndex = (1 << INST_INDEX_BITS) - 1;
2191848b8605Smrg   const GLint minIndex = -(1 << INST_INDEX_BITS);
2192b8e80941Smrg   assert(file < PROGRAM_FILE_MAX);
2193b8e80941Smrg   assert(index >= minIndex);
2194848b8605Smrg   (void) minIndex;
2195b8e80941Smrg   assert(index <= maxIndex);
2196848b8605Smrg   (void) maxIndex;
2197848b8605Smrg   memset(r, 0, sizeof(*r));
2198848b8605Smrg   r->Base.File = file;
2199848b8605Smrg   r->Base.Index = index;
2200848b8605Smrg   r->Base.Swizzle = swizzle;
2201848b8605Smrg   r->Symbol = NULL;
2202848b8605Smrg}
2203848b8605Smrg
2204848b8605Smrg
2205848b8605Smrg/**
2206848b8605Smrg * Validate the set of inputs used by a program
2207848b8605Smrg *
2208848b8605Smrg * Validates that legal sets of inputs are used by the program.  In this case
2209848b8605Smrg * "used" included both reading the input or binding the input to a name using
2210848b8605Smrg * the \c ATTRIB command.
2211848b8605Smrg *
2212848b8605Smrg * \return
2213848b8605Smrg * \c TRUE if the combination of inputs used is valid, \c FALSE otherwise.
2214848b8605Smrg */
2215848b8605Smrgint
2216848b8605Smrgvalidate_inputs(struct YYLTYPE *locp, struct asm_parser_state *state)
2217848b8605Smrg{
2218b8e80941Smrg   const GLbitfield64 inputs = state->prog->info.inputs_read | state->InputsBound;
2219b8e80941Smrg   GLbitfield ff_inputs = 0;
2220848b8605Smrg
2221b8e80941Smrg   /* Since Mesa internal attribute indices are different from
2222b8e80941Smrg    * how NV_vertex_program defines attribute aliasing, we have to construct
2223b8e80941Smrg    * a separate usage mask based on how the aliasing is defined.
2224b8e80941Smrg    *
2225b8e80941Smrg    * Note that attribute aliasing is optional if NV_vertex_program is
2226b8e80941Smrg    * unsupported.
2227b8e80941Smrg    */
2228b8e80941Smrg   if (inputs & VERT_BIT_POS)
2229b8e80941Smrg      ff_inputs |= 1 << 0;
2230b8e80941Smrg   if (inputs & VERT_BIT_NORMAL)
2231b8e80941Smrg      ff_inputs |= 1 << 2;
2232b8e80941Smrg   if (inputs & VERT_BIT_COLOR0)
2233b8e80941Smrg      ff_inputs |= 1 << 3;
2234b8e80941Smrg   if (inputs & VERT_BIT_COLOR1)
2235b8e80941Smrg      ff_inputs |= 1 << 4;
2236b8e80941Smrg   if (inputs & VERT_BIT_FOG)
2237b8e80941Smrg      ff_inputs |= 1 << 5;
2238b8e80941Smrg
2239b8e80941Smrg   ff_inputs |= ((inputs & VERT_BIT_TEX_ALL) >> VERT_ATTRIB_TEX0) << 8;
2240b8e80941Smrg
2241b8e80941Smrg   if ((ff_inputs & (inputs >> VERT_ATTRIB_GENERIC0)) != 0) {
2242848b8605Smrg      yyerror(locp, state, "illegal use of generic attribute and name attribute");
2243848b8605Smrg      return 0;
2244848b8605Smrg   }
2245848b8605Smrg
2246848b8605Smrg   return 1;
2247848b8605Smrg}
2248848b8605Smrg
2249848b8605Smrg
2250848b8605Smrgstruct asm_symbol *
2251848b8605Smrgdeclare_variable(struct asm_parser_state *state, char *name, enum asm_type t,
2252848b8605Smrg		 struct YYLTYPE *locp)
2253848b8605Smrg{
2254848b8605Smrg   struct asm_symbol *s = NULL;
2255848b8605Smrg   struct asm_symbol *exist = (struct asm_symbol *)
2256b8e80941Smrg      _mesa_symbol_table_find_symbol(state->st, name);
2257848b8605Smrg
2258848b8605Smrg
2259848b8605Smrg   if (exist != NULL) {
2260848b8605Smrg      yyerror(locp, state, "redeclared identifier");
2261848b8605Smrg   } else {
2262848b8605Smrg      s = calloc(1, sizeof(struct asm_symbol));
2263848b8605Smrg      s->name = name;
2264848b8605Smrg      s->type = t;
2265848b8605Smrg
2266848b8605Smrg      switch (t) {
2267848b8605Smrg      case at_temp:
2268b8e80941Smrg         if (state->prog->arb.NumTemporaries >= state->limits->MaxTemps) {
2269848b8605Smrg	    yyerror(locp, state, "too many temporaries declared");
2270848b8605Smrg	    free(s);
2271848b8605Smrg	    return NULL;
2272848b8605Smrg	 }
2273848b8605Smrg
2274b8e80941Smrg         s->temp_binding = state->prog->arb.NumTemporaries;
2275b8e80941Smrg         state->prog->arb.NumTemporaries++;
2276848b8605Smrg	 break;
2277848b8605Smrg
2278848b8605Smrg      case at_address:
2279b8e80941Smrg         if (state->prog->arb.NumAddressRegs >=
2280b8e80941Smrg             state->limits->MaxAddressRegs) {
2281848b8605Smrg	    yyerror(locp, state, "too many address registers declared");
2282848b8605Smrg	    free(s);
2283848b8605Smrg	    return NULL;
2284848b8605Smrg	 }
2285848b8605Smrg
2286848b8605Smrg	 /* FINISHME: Add support for multiple address registers.
2287848b8605Smrg	  */
2288b8e80941Smrg         state->prog->arb.NumAddressRegs++;
2289848b8605Smrg	 break;
2290848b8605Smrg
2291848b8605Smrg      default:
2292848b8605Smrg	 break;
2293848b8605Smrg      }
2294848b8605Smrg
2295b8e80941Smrg      _mesa_symbol_table_add_symbol(state->st, s->name, s);
2296848b8605Smrg      s->next = state->sym;
2297848b8605Smrg      state->sym = s;
2298848b8605Smrg   }
2299848b8605Smrg
2300848b8605Smrg   return s;
2301848b8605Smrg}
2302848b8605Smrg
2303848b8605Smrg
2304848b8605Smrgint add_state_reference(struct gl_program_parameter_list *param_list,
2305b8e80941Smrg			const gl_state_index16 tokens[STATE_LENGTH])
2306848b8605Smrg{
2307848b8605Smrg   const GLuint size = 4; /* XXX fix */
2308848b8605Smrg   char *name;
2309848b8605Smrg   GLint index;
2310848b8605Smrg
2311848b8605Smrg   name = _mesa_program_state_string(tokens);
2312848b8605Smrg   index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name,
2313b8e80941Smrg                               size, GL_NONE, NULL, tokens, true);
2314848b8605Smrg   param_list->StateFlags |= _mesa_program_state_flags(tokens);
2315848b8605Smrg
2316848b8605Smrg   /* free name string here since we duplicated it in add_parameter() */
2317848b8605Smrg   free(name);
2318848b8605Smrg
2319848b8605Smrg   return index;
2320848b8605Smrg}
2321848b8605Smrg
2322848b8605Smrg
2323848b8605Smrgint
2324848b8605Smrginitialize_symbol_from_state(struct gl_program *prog,
2325848b8605Smrg			     struct asm_symbol *param_var,
2326b8e80941Smrg			     const gl_state_index16 tokens[STATE_LENGTH])
2327848b8605Smrg{
2328848b8605Smrg   int idx = -1;
2329b8e80941Smrg   gl_state_index16 state_tokens[STATE_LENGTH];
2330848b8605Smrg
2331848b8605Smrg
2332848b8605Smrg   memcpy(state_tokens, tokens, sizeof(state_tokens));
2333848b8605Smrg
2334848b8605Smrg   param_var->type = at_param;
2335848b8605Smrg   param_var->param_binding_type = PROGRAM_STATE_VAR;
2336848b8605Smrg
2337848b8605Smrg   /* If we are adding a STATE_MATRIX that has multiple rows, we need to
2338848b8605Smrg    * unroll it and call add_state_reference() for each row
2339848b8605Smrg    */
2340848b8605Smrg   if ((state_tokens[0] == STATE_MODELVIEW_MATRIX ||
2341848b8605Smrg	state_tokens[0] == STATE_PROJECTION_MATRIX ||
2342848b8605Smrg	state_tokens[0] == STATE_MVP_MATRIX ||
2343848b8605Smrg	state_tokens[0] == STATE_TEXTURE_MATRIX ||
2344848b8605Smrg	state_tokens[0] == STATE_PROGRAM_MATRIX)
2345848b8605Smrg       && (state_tokens[2] != state_tokens[3])) {
2346848b8605Smrg      int row;
2347848b8605Smrg      const int first_row = state_tokens[2];
2348848b8605Smrg      const int last_row = state_tokens[3];
2349848b8605Smrg
2350848b8605Smrg      for (row = first_row; row <= last_row; row++) {
2351848b8605Smrg	 state_tokens[2] = state_tokens[3] = row;
2352848b8605Smrg
2353848b8605Smrg	 idx = add_state_reference(prog->Parameters, state_tokens);
2354848b8605Smrg	 if (param_var->param_binding_begin == ~0U) {
2355848b8605Smrg	    param_var->param_binding_begin = idx;
2356848b8605Smrg            param_var->param_binding_swizzle = SWIZZLE_XYZW;
2357848b8605Smrg         }
2358848b8605Smrg
2359848b8605Smrg	 param_var->param_binding_length++;
2360848b8605Smrg      }
2361848b8605Smrg   }
2362848b8605Smrg   else {
2363848b8605Smrg      idx = add_state_reference(prog->Parameters, state_tokens);
2364848b8605Smrg      if (param_var->param_binding_begin == ~0U) {
2365848b8605Smrg	 param_var->param_binding_begin = idx;
2366848b8605Smrg         param_var->param_binding_swizzle = SWIZZLE_XYZW;
2367848b8605Smrg      }
2368848b8605Smrg      param_var->param_binding_length++;
2369848b8605Smrg   }
2370848b8605Smrg
2371848b8605Smrg   return idx;
2372848b8605Smrg}
2373848b8605Smrg
2374848b8605Smrg
2375848b8605Smrgint
2376848b8605Smrginitialize_symbol_from_param(struct gl_program *prog,
2377848b8605Smrg			     struct asm_symbol *param_var,
2378b8e80941Smrg			     const gl_state_index16 tokens[STATE_LENGTH])
2379848b8605Smrg{
2380848b8605Smrg   int idx = -1;
2381b8e80941Smrg   gl_state_index16 state_tokens[STATE_LENGTH];
2382848b8605Smrg
2383848b8605Smrg
2384848b8605Smrg   memcpy(state_tokens, tokens, sizeof(state_tokens));
2385848b8605Smrg
2386848b8605Smrg   assert((state_tokens[0] == STATE_VERTEX_PROGRAM)
2387848b8605Smrg	  || (state_tokens[0] == STATE_FRAGMENT_PROGRAM));
2388848b8605Smrg   assert((state_tokens[1] == STATE_ENV)
2389848b8605Smrg	  || (state_tokens[1] == STATE_LOCAL));
2390848b8605Smrg
2391848b8605Smrg   /*
2392848b8605Smrg    * The param type is STATE_VAR.  The program parameter entry will
2393848b8605Smrg    * effectively be a pointer into the LOCAL or ENV parameter array.
2394848b8605Smrg    */
2395848b8605Smrg   param_var->type = at_param;
2396848b8605Smrg   param_var->param_binding_type = PROGRAM_STATE_VAR;
2397848b8605Smrg
2398848b8605Smrg   /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements,
2399848b8605Smrg    * we need to unroll it and call add_state_reference() for each row
2400848b8605Smrg    */
2401848b8605Smrg   if (state_tokens[2] != state_tokens[3]) {
2402848b8605Smrg      int row;
2403848b8605Smrg      const int first_row = state_tokens[2];
2404848b8605Smrg      const int last_row = state_tokens[3];
2405848b8605Smrg
2406848b8605Smrg      for (row = first_row; row <= last_row; row++) {
2407848b8605Smrg	 state_tokens[2] = state_tokens[3] = row;
2408848b8605Smrg
2409848b8605Smrg	 idx = add_state_reference(prog->Parameters, state_tokens);
2410848b8605Smrg	 if (param_var->param_binding_begin == ~0U) {
2411848b8605Smrg	    param_var->param_binding_begin = idx;
2412848b8605Smrg            param_var->param_binding_swizzle = SWIZZLE_XYZW;
2413848b8605Smrg         }
2414848b8605Smrg	 param_var->param_binding_length++;
2415848b8605Smrg      }
2416848b8605Smrg   }
2417848b8605Smrg   else {
2418848b8605Smrg      idx = add_state_reference(prog->Parameters, state_tokens);
2419848b8605Smrg      if (param_var->param_binding_begin == ~0U) {
2420848b8605Smrg	 param_var->param_binding_begin = idx;
2421848b8605Smrg         param_var->param_binding_swizzle = SWIZZLE_XYZW;
2422848b8605Smrg      }
2423848b8605Smrg      param_var->param_binding_length++;
2424848b8605Smrg   }
2425848b8605Smrg
2426848b8605Smrg   return idx;
2427848b8605Smrg}
2428848b8605Smrg
2429848b8605Smrg
2430848b8605Smrg/**
2431848b8605Smrg * Put a float/vector constant/literal into the parameter list.
2432848b8605Smrg * \param param_var  returns info about the parameter/constant's location,
2433848b8605Smrg *                   binding, type, etc.
2434848b8605Smrg * \param vec  the vector/constant to add
2435848b8605Smrg * \param allowSwizzle  if true, try to consolidate constants which only differ
2436848b8605Smrg *                      by a swizzle.  We don't want to do this when building
2437848b8605Smrg *                      arrays of constants that may be indexed indirectly.
2438848b8605Smrg * \return index of the constant in the parameter list.
2439848b8605Smrg */
2440848b8605Smrgint
2441848b8605Smrginitialize_symbol_from_const(struct gl_program *prog,
2442848b8605Smrg			     struct asm_symbol *param_var,
2443848b8605Smrg			     const struct asm_vector *vec,
2444848b8605Smrg                             GLboolean allowSwizzle)
2445848b8605Smrg{
2446848b8605Smrg   unsigned swizzle;
2447848b8605Smrg   const int idx = _mesa_add_unnamed_constant(prog->Parameters,
2448848b8605Smrg                                              vec->data, vec->count,
2449848b8605Smrg                                              allowSwizzle ? &swizzle : NULL);
2450848b8605Smrg
2451848b8605Smrg   param_var->type = at_param;
2452848b8605Smrg   param_var->param_binding_type = PROGRAM_CONSTANT;
2453848b8605Smrg
2454848b8605Smrg   if (param_var->param_binding_begin == ~0U) {
2455848b8605Smrg      param_var->param_binding_begin = idx;
2456848b8605Smrg      param_var->param_binding_swizzle = allowSwizzle ? swizzle : SWIZZLE_XYZW;
2457848b8605Smrg   }
2458848b8605Smrg   param_var->param_binding_length++;
2459848b8605Smrg
2460848b8605Smrg   return idx;
2461848b8605Smrg}
2462848b8605Smrg
2463848b8605Smrg
2464848b8605Smrgchar *
2465848b8605Smrgmake_error_string(const char *fmt, ...)
2466848b8605Smrg{
2467848b8605Smrg   int length;
2468848b8605Smrg   char *str;
2469848b8605Smrg   va_list args;
2470848b8605Smrg
2471848b8605Smrg
2472848b8605Smrg   /* Call vsnprintf once to determine how large the final string is.  Call it
2473848b8605Smrg    * again to do the actual formatting.  from the vsnprintf manual page:
2474848b8605Smrg    *
2475848b8605Smrg    *    Upon successful return, these functions return the number of
2476848b8605Smrg    *    characters printed  (not including the trailing '\0' used to end
2477848b8605Smrg    *    output to strings).
2478848b8605Smrg    */
2479848b8605Smrg   va_start(args, fmt);
2480848b8605Smrg   length = 1 + vsnprintf(NULL, 0, fmt, args);
2481848b8605Smrg   va_end(args);
2482848b8605Smrg
2483848b8605Smrg   str = malloc(length);
2484848b8605Smrg   if (str) {
2485848b8605Smrg      va_start(args, fmt);
2486848b8605Smrg      vsnprintf(str, length, fmt, args);
2487848b8605Smrg      va_end(args);
2488848b8605Smrg   }
2489848b8605Smrg
2490848b8605Smrg   return str;
2491848b8605Smrg}
2492848b8605Smrg
2493848b8605Smrg
2494848b8605Smrgvoid
2495848b8605Smrgyyerror(YYLTYPE *locp, struct asm_parser_state *state, const char *s)
2496848b8605Smrg{
2497848b8605Smrg   char *err_str;
2498848b8605Smrg
2499848b8605Smrg
2500848b8605Smrg   err_str = make_error_string("glProgramStringARB(%s)\n", s);
2501848b8605Smrg   if (err_str) {
2502848b8605Smrg      _mesa_error(state->ctx, GL_INVALID_OPERATION, "%s", err_str);
2503848b8605Smrg      free(err_str);
2504848b8605Smrg   }
2505848b8605Smrg
2506848b8605Smrg   err_str = make_error_string("line %u, char %u: error: %s\n",
2507848b8605Smrg			       locp->first_line, locp->first_column, s);
2508848b8605Smrg   _mesa_set_program_error(state->ctx, locp->position, err_str);
2509848b8605Smrg
2510848b8605Smrg   if (err_str) {
2511848b8605Smrg      free(err_str);
2512848b8605Smrg   }
2513848b8605Smrg}
2514848b8605Smrg
2515848b8605Smrg
2516848b8605SmrgGLboolean
2517848b8605Smrg_mesa_parse_arb_program(struct gl_context *ctx, GLenum target, const GLubyte *str,
2518848b8605Smrg			GLsizei len, struct asm_parser_state *state)
2519848b8605Smrg{
2520848b8605Smrg   struct asm_instruction *inst;
2521848b8605Smrg   unsigned i;
2522848b8605Smrg   GLubyte *strz;
2523848b8605Smrg   GLboolean result = GL_FALSE;
2524848b8605Smrg   void *temp;
2525848b8605Smrg   struct asm_symbol *sym;
2526848b8605Smrg
2527848b8605Smrg   state->ctx = ctx;
2528848b8605Smrg   state->prog->Target = target;
2529848b8605Smrg   state->prog->Parameters = _mesa_new_parameter_list();
2530848b8605Smrg
2531848b8605Smrg   /* Make a copy of the program string and force it to be NUL-terminated.
2532848b8605Smrg    */
2533b8e80941Smrg   strz = (GLubyte *) ralloc_size(state->mem_ctx, len + 1);
2534848b8605Smrg   if (strz == NULL) {
2535848b8605Smrg      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
2536848b8605Smrg      return GL_FALSE;
2537848b8605Smrg   }
2538848b8605Smrg   memcpy (strz, str, len);
2539848b8605Smrg   strz[len] = '\0';
2540848b8605Smrg
2541848b8605Smrg   state->prog->String = strz;
2542848b8605Smrg
2543848b8605Smrg   state->st = _mesa_symbol_table_ctor();
2544848b8605Smrg
2545848b8605Smrg   state->limits = (target == GL_VERTEX_PROGRAM_ARB)
2546848b8605Smrg      ? & ctx->Const.Program[MESA_SHADER_VERTEX]
2547848b8605Smrg      : & ctx->Const.Program[MESA_SHADER_FRAGMENT];
2548848b8605Smrg
2549848b8605Smrg   state->MaxTextureImageUnits = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits;
2550848b8605Smrg   state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits;
2551848b8605Smrg   state->MaxTextureUnits = ctx->Const.MaxTextureUnits;
2552848b8605Smrg   state->MaxClipPlanes = ctx->Const.MaxClipPlanes;
2553848b8605Smrg   state->MaxLights = ctx->Const.MaxLights;
2554848b8605Smrg   state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices;
2555848b8605Smrg   state->MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
2556848b8605Smrg
2557848b8605Smrg   state->state_param_enum = (target == GL_VERTEX_PROGRAM_ARB)
2558848b8605Smrg      ? STATE_VERTEX_PROGRAM : STATE_FRAGMENT_PROGRAM;
2559848b8605Smrg
2560848b8605Smrg   _mesa_set_program_error(ctx, -1, NULL);
2561848b8605Smrg
2562848b8605Smrg   _mesa_program_lexer_ctor(& state->scanner, state, (const char *) str, len);
2563848b8605Smrg   yyparse(state);
2564848b8605Smrg   _mesa_program_lexer_dtor(state->scanner);
2565848b8605Smrg
2566848b8605Smrg
2567848b8605Smrg   if (ctx->Program.ErrorPos != -1) {
2568848b8605Smrg      goto error;
2569848b8605Smrg   }
2570848b8605Smrg
2571848b8605Smrg   if (! _mesa_layout_parameters(state)) {
2572848b8605Smrg      struct YYLTYPE loc;
2573848b8605Smrg
2574848b8605Smrg      loc.first_line = 0;
2575848b8605Smrg      loc.first_column = 0;
2576848b8605Smrg      loc.position = len;
2577848b8605Smrg
2578848b8605Smrg      yyerror(& loc, state, "invalid PARAM usage");
2579848b8605Smrg      goto error;
2580848b8605Smrg   }
2581848b8605Smrg
2582848b8605Smrg
2583848b8605Smrg
2584848b8605Smrg   /* Add one instruction to store the "END" instruction.
2585848b8605Smrg    */
2586b8e80941Smrg   state->prog->arb.Instructions =
2587b8e80941Smrg      rzalloc_array(state->mem_ctx, struct prog_instruction,
2588b8e80941Smrg                    state->prog->arb.NumInstructions + 1);
2589848b8605Smrg
2590b8e80941Smrg   if (state->prog->arb.Instructions == NULL) {
2591848b8605Smrg      goto error;
2592848b8605Smrg   }
2593848b8605Smrg
2594848b8605Smrg   inst = state->inst_head;
2595b8e80941Smrg   for (i = 0; i < state->prog->arb.NumInstructions; i++) {
2596848b8605Smrg      struct asm_instruction *const temp = inst->next;
2597848b8605Smrg
2598b8e80941Smrg      state->prog->arb.Instructions[i] = inst->Base;
2599848b8605Smrg      inst = temp;
2600848b8605Smrg   }
2601848b8605Smrg
2602848b8605Smrg   /* Finally, tag on an OPCODE_END instruction */
2603848b8605Smrg   {
2604b8e80941Smrg      const GLuint numInst = state->prog->arb.NumInstructions;
2605b8e80941Smrg      _mesa_init_instructions(state->prog->arb.Instructions + numInst, 1);
2606b8e80941Smrg      state->prog->arb.Instructions[numInst].Opcode = OPCODE_END;
2607848b8605Smrg   }
2608b8e80941Smrg   state->prog->arb.NumInstructions++;
2609848b8605Smrg
2610b8e80941Smrg   state->prog->arb.NumParameters = state->prog->Parameters->NumParameters;
2611b8e80941Smrg   state->prog->arb.NumAttributes =
2612b8e80941Smrg      util_bitcount64(state->prog->info.inputs_read);
2613848b8605Smrg
2614848b8605Smrg   /*
2615848b8605Smrg    * Initialize native counts to logical counts.  The device driver may
2616848b8605Smrg    * change them if program is translated into a hardware program.
2617848b8605Smrg    */
2618b8e80941Smrg   state->prog->arb.NumNativeInstructions = state->prog->arb.NumInstructions;
2619b8e80941Smrg   state->prog->arb.NumNativeTemporaries = state->prog->arb.NumTemporaries;
2620b8e80941Smrg   state->prog->arb.NumNativeParameters = state->prog->arb.NumParameters;
2621b8e80941Smrg   state->prog->arb.NumNativeAttributes = state->prog->arb.NumAttributes;
2622b8e80941Smrg   state->prog->arb.NumNativeAddressRegs = state->prog->arb.NumAddressRegs;
2623848b8605Smrg
2624848b8605Smrg   result = GL_TRUE;
2625848b8605Smrg
2626848b8605Smrgerror:
2627848b8605Smrg   for (inst = state->inst_head; inst != NULL; inst = temp) {
2628848b8605Smrg      temp = inst->next;
2629848b8605Smrg      free(inst);
2630848b8605Smrg   }
2631848b8605Smrg
2632848b8605Smrg   state->inst_head = NULL;
2633848b8605Smrg   state->inst_tail = NULL;
2634848b8605Smrg
2635848b8605Smrg   for (sym = state->sym; sym != NULL; sym = temp) {
2636848b8605Smrg      temp = sym->next;
2637848b8605Smrg
2638848b8605Smrg      free((void *) sym->name);
2639848b8605Smrg      free(sym);
2640848b8605Smrg   }
2641848b8605Smrg   state->sym = NULL;
2642848b8605Smrg
2643848b8605Smrg   _mesa_symbol_table_dtor(state->st);
2644848b8605Smrg   state->st = NULL;
2645848b8605Smrg
2646848b8605Smrg   return result;
2647848b8605Smrg}
2648