13464ebd5Sriastradh%{
23464ebd5Sriastradh/*
33464ebd5Sriastradh * Copyright © 2009 Intel Corporation
43464ebd5Sriastradh *
53464ebd5Sriastradh * Permission is hereby granted, free of charge, to any person obtaining a
63464ebd5Sriastradh * copy of this software and associated documentation files (the "Software"),
73464ebd5Sriastradh * to deal in the Software without restriction, including without limitation
83464ebd5Sriastradh * the rights to use, copy, modify, merge, publish, distribute, sublicense,
93464ebd5Sriastradh * and/or sell copies of the Software, and to permit persons to whom the
103464ebd5Sriastradh * Software is furnished to do so, subject to the following conditions:
113464ebd5Sriastradh *
123464ebd5Sriastradh * The above copyright notice and this permission notice (including the next
133464ebd5Sriastradh * paragraph) shall be included in all copies or substantial portions of the
143464ebd5Sriastradh * Software.
153464ebd5Sriastradh *
163464ebd5Sriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
173464ebd5Sriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
183464ebd5Sriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
193464ebd5Sriastradh * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
203464ebd5Sriastradh * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
213464ebd5Sriastradh * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
223464ebd5Sriastradh * DEALINGS IN THE SOFTWARE.
233464ebd5Sriastradh */
2401e04c3fSmrg
2501e04c3fSmrg#include <stdarg.h>
263464ebd5Sriastradh#include <stdio.h>
273464ebd5Sriastradh#include <stdlib.h>
283464ebd5Sriastradh#include <string.h>
293464ebd5Sriastradh
3001e04c3fSmrg#include "main/errors.h"
313464ebd5Sriastradh#include "main/mtypes.h"
327ec681f3Smrg
333464ebd5Sriastradh#include "program/program.h"
343464ebd5Sriastradh#include "program/prog_parameter.h"
353464ebd5Sriastradh#include "program/prog_parameter_layout.h"
363464ebd5Sriastradh#include "program/prog_statevars.h"
373464ebd5Sriastradh#include "program/prog_instruction.h"
383464ebd5Sriastradh
393464ebd5Sriastradh#include "program/symbol_table.h"
403464ebd5Sriastradh#include "program/program_parser.h"
413464ebd5Sriastradh
4201e04c3fSmrg#include "util/u_math.h"
437ec681f3Smrg#include "util/u_memory.h"
447ec681f3Smrg
457ec681f3Smrgenum {
467ec681f3Smrg   STATE_MATRIX_NO_MODIFIER,
477ec681f3Smrg   STATE_MATRIX_INVERSE,
487ec681f3Smrg   STATE_MATRIX_TRANSPOSE,
497ec681f3Smrg   STATE_MATRIX_INVTRANS,
507ec681f3Smrg};
5101e04c3fSmrg
523464ebd5Sriastradhextern void *yy_scan_string(char *);
533464ebd5Sriastradhextern void yy_delete_buffer(void *);
543464ebd5Sriastradh
553464ebd5Sriastradhstatic struct asm_symbol *declare_variable(struct asm_parser_state *state,
563464ebd5Sriastradh    char *name, enum asm_type t, struct YYLTYPE *locp);
573464ebd5Sriastradh
583464ebd5Sriastradhstatic int add_state_reference(struct gl_program_parameter_list *param_list,
5901e04c3fSmrg    const gl_state_index16 tokens[STATE_LENGTH]);
603464ebd5Sriastradh
613464ebd5Sriastradhstatic int initialize_symbol_from_state(struct gl_program *prog,
6201e04c3fSmrg    struct asm_symbol *param_var, const gl_state_index16 tokens[STATE_LENGTH]);
633464ebd5Sriastradh
643464ebd5Sriastradhstatic int initialize_symbol_from_param(struct gl_program *prog,
6501e04c3fSmrg    struct asm_symbol *param_var, const gl_state_index16 tokens[STATE_LENGTH]);
663464ebd5Sriastradh
673464ebd5Sriastradhstatic int initialize_symbol_from_const(struct gl_program *prog,
683464ebd5Sriastradh    struct asm_symbol *param_var, const struct asm_vector *vec,
693464ebd5Sriastradh    GLboolean allowSwizzle);
703464ebd5Sriastradh
713464ebd5Sriastradhstatic int yyparse(struct asm_parser_state *state);
723464ebd5Sriastradh
733464ebd5Sriastradhstatic char *make_error_string(const char *fmt, ...);
743464ebd5Sriastradh
753464ebd5Sriastradhstatic void yyerror(struct YYLTYPE *locp, struct asm_parser_state *state,
763464ebd5Sriastradh    const char *s);
773464ebd5Sriastradh
783464ebd5Sriastradhstatic int validate_inputs(struct YYLTYPE *locp,
793464ebd5Sriastradh    struct asm_parser_state *state);
803464ebd5Sriastradh
813464ebd5Sriastradhstatic void init_dst_reg(struct prog_dst_register *r);
823464ebd5Sriastradh
833464ebd5Sriastradhstatic void set_dst_reg(struct prog_dst_register *r,
843464ebd5Sriastradh                        gl_register_file file, GLint index);
853464ebd5Sriastradh
863464ebd5Sriastradhstatic void init_src_reg(struct asm_src_register *r);
873464ebd5Sriastradh
883464ebd5Sriastradhstatic void set_src_reg(struct asm_src_register *r,
893464ebd5Sriastradh                        gl_register_file file, GLint index);
903464ebd5Sriastradh
913464ebd5Sriastradhstatic void set_src_reg_swz(struct asm_src_register *r,
923464ebd5Sriastradh                            gl_register_file file, GLint index, GLuint swizzle);
933464ebd5Sriastradh
943464ebd5Sriastradhstatic void asm_instruction_set_operands(struct asm_instruction *inst,
953464ebd5Sriastradh    const struct prog_dst_register *dst, const struct asm_src_register *src0,
963464ebd5Sriastradh    const struct asm_src_register *src1, const struct asm_src_register *src2);
973464ebd5Sriastradh
9801e04c3fSmrgstatic struct asm_instruction *asm_instruction_ctor(enum prog_opcode op,
993464ebd5Sriastradh    const struct prog_dst_register *dst, const struct asm_src_register *src0,
1003464ebd5Sriastradh    const struct asm_src_register *src1, const struct asm_src_register *src2);
1013464ebd5Sriastradh
1023464ebd5Sriastradhstatic struct asm_instruction *asm_instruction_copy_ctor(
1033464ebd5Sriastradh    const struct prog_instruction *base, const struct prog_dst_register *dst,
1043464ebd5Sriastradh    const struct asm_src_register *src0, const struct asm_src_register *src1,
1053464ebd5Sriastradh    const struct asm_src_register *src2);
1063464ebd5Sriastradh
1073464ebd5Sriastradh#ifndef FALSE
1083464ebd5Sriastradh#define FALSE 0
1093464ebd5Sriastradh#define TRUE (!FALSE)
1103464ebd5Sriastradh#endif
1113464ebd5Sriastradh
1123464ebd5Sriastradh#define YYLLOC_DEFAULT(Current, Rhs, N)					\
1133464ebd5Sriastradh   do {									\
114af69d88dSmrg      if (N) {							\
1153464ebd5Sriastradh	 (Current).first_line = YYRHSLOC(Rhs, 1).first_line;		\
1163464ebd5Sriastradh	 (Current).first_column = YYRHSLOC(Rhs, 1).first_column;	\
1173464ebd5Sriastradh	 (Current).position = YYRHSLOC(Rhs, 1).position;		\
1183464ebd5Sriastradh	 (Current).last_line = YYRHSLOC(Rhs, N).last_line;		\
1193464ebd5Sriastradh	 (Current).last_column = YYRHSLOC(Rhs, N).last_column;		\
1203464ebd5Sriastradh      } else {								\
1213464ebd5Sriastradh	 (Current).first_line = YYRHSLOC(Rhs, 0).last_line;		\
1223464ebd5Sriastradh	 (Current).last_line = (Current).first_line;			\
1233464ebd5Sriastradh	 (Current).first_column = YYRHSLOC(Rhs, 0).last_column;		\
1243464ebd5Sriastradh	 (Current).last_column = (Current).first_column;		\
1253464ebd5Sriastradh	 (Current).position = YYRHSLOC(Rhs, 0).position			\
1263464ebd5Sriastradh	    + (Current).first_column;					\
1273464ebd5Sriastradh      }									\
128af69d88dSmrg   } while(0)
1293464ebd5Sriastradh%}
1303464ebd5Sriastradh
1313464ebd5Sriastradh%pure-parser
1323464ebd5Sriastradh%locations
133af69d88dSmrg%lex-param   { struct asm_parser_state *state }
1343464ebd5Sriastradh%parse-param { struct asm_parser_state *state }
1353464ebd5Sriastradh%error-verbose
1363464ebd5Sriastradh
1373464ebd5Sriastradh%union {
1383464ebd5Sriastradh   struct asm_instruction *inst;
1393464ebd5Sriastradh   struct asm_symbol *sym;
1403464ebd5Sriastradh   struct asm_symbol temp_sym;
1413464ebd5Sriastradh   struct asm_swizzle_mask swiz_mask;
1423464ebd5Sriastradh   struct asm_src_register src_reg;
1433464ebd5Sriastradh   struct prog_dst_register dst_reg;
1443464ebd5Sriastradh   struct prog_instruction temp_inst;
1453464ebd5Sriastradh   char *string;
1463464ebd5Sriastradh   unsigned result;
1473464ebd5Sriastradh   unsigned attrib;
1483464ebd5Sriastradh   int integer;
1493464ebd5Sriastradh   float real;
15001e04c3fSmrg   gl_state_index16 state[STATE_LENGTH];
1513464ebd5Sriastradh   int negate;
1523464ebd5Sriastradh   struct asm_vector vector;
15301e04c3fSmrg   enum prog_opcode opcode;
1543464ebd5Sriastradh
1553464ebd5Sriastradh   struct {
1563464ebd5Sriastradh      unsigned swz;
1573464ebd5Sriastradh      unsigned rgba_valid:1;
1583464ebd5Sriastradh      unsigned xyzw_valid:1;
1593464ebd5Sriastradh      unsigned negate:1;
1603464ebd5Sriastradh   } ext_swizzle;
1613464ebd5Sriastradh}
1623464ebd5Sriastradh
1633464ebd5Sriastradh%token ARBvp_10 ARBfp_10
1643464ebd5Sriastradh
1653464ebd5Sriastradh/* Tokens for assembler pseudo-ops */
1663464ebd5Sriastradh%token <integer> ADDRESS
1673464ebd5Sriastradh%token ALIAS ATTRIB
1683464ebd5Sriastradh%token OPTION OUTPUT
1693464ebd5Sriastradh%token PARAM
1703464ebd5Sriastradh%token <integer> TEMP
1713464ebd5Sriastradh%token END
1723464ebd5Sriastradh
1733464ebd5Sriastradh /* Tokens for instructions */
1743464ebd5Sriastradh%token <temp_inst> BIN_OP BINSC_OP SAMPLE_OP SCALAR_OP TRI_OP VECTOR_OP
1753464ebd5Sriastradh%token <temp_inst> ARL KIL SWZ TXD_OP
1763464ebd5Sriastradh
1773464ebd5Sriastradh%token <integer> INTEGER
1783464ebd5Sriastradh%token <real> REAL
1793464ebd5Sriastradh
1803464ebd5Sriastradh%token AMBIENT ATTENUATION
1813464ebd5Sriastradh%token BACK
1823464ebd5Sriastradh%token CLIP COLOR
1833464ebd5Sriastradh%token DEPTH DIFFUSE DIRECTION
1843464ebd5Sriastradh%token EMISSION ENV EYE
1853464ebd5Sriastradh%token FOG FOGCOORD FRAGMENT FRONT
1863464ebd5Sriastradh%token HALF
1873464ebd5Sriastradh%token INVERSE INVTRANS
1883464ebd5Sriastradh%token LIGHT LIGHTMODEL LIGHTPROD LOCAL
1893464ebd5Sriastradh%token MATERIAL MAT_PROGRAM MATRIX MATRIXINDEX MODELVIEW MVP
1903464ebd5Sriastradh%token NORMAL
1913464ebd5Sriastradh%token OBJECT
1923464ebd5Sriastradh%token PALETTE PARAMS PLANE POINT_TOK POINTSIZE POSITION PRIMARY PROGRAM PROJECTION
1933464ebd5Sriastradh%token RANGE RESULT ROW
1943464ebd5Sriastradh%token SCENECOLOR SECONDARY SHININESS SIZE_TOK SPECULAR SPOT STATE
1953464ebd5Sriastradh%token TEXCOORD TEXENV TEXGEN TEXGEN_Q TEXGEN_R TEXGEN_S TEXGEN_T TEXTURE TRANSPOSE
1963464ebd5Sriastradh%token TEXTURE_UNIT TEX_1D TEX_2D TEX_3D TEX_CUBE TEX_RECT
1973464ebd5Sriastradh%token TEX_SHADOW1D TEX_SHADOW2D TEX_SHADOWRECT
1987ec681f3Smrg%token TEX_ARRAY1D TEX_ARRAY2D TEX_ARRAYSHADOW1D TEX_ARRAYSHADOW2D
1993464ebd5Sriastradh%token VERTEX VTXATTRIB
2003464ebd5Sriastradh
2013464ebd5Sriastradh%token <string> IDENTIFIER USED_IDENTIFIER
2023464ebd5Sriastradh%type <string> string
2033464ebd5Sriastradh%token <swiz_mask> MASK4 MASK3 MASK2 MASK1 SWIZZLE
2043464ebd5Sriastradh%token DOT_DOT
2053464ebd5Sriastradh%token DOT
2063464ebd5Sriastradh
2073464ebd5Sriastradh%type <inst> instruction ALU_instruction TexInstruction
2083464ebd5Sriastradh%type <inst> ARL_instruction VECTORop_instruction
2093464ebd5Sriastradh%type <inst> SCALARop_instruction BINSCop_instruction BINop_instruction
2103464ebd5Sriastradh%type <inst> TRIop_instruction TXD_instruction SWZ_instruction SAMPLE_instruction
2113464ebd5Sriastradh%type <inst> KIL_instruction
2123464ebd5Sriastradh
2133464ebd5Sriastradh%type <dst_reg> dstReg maskedDstReg maskedAddrReg
2143464ebd5Sriastradh%type <src_reg> srcReg scalarUse scalarSrcReg swizzleSrcReg
2153464ebd5Sriastradh%type <swiz_mask> scalarSuffix swizzleSuffix extendedSwizzle
2163464ebd5Sriastradh%type <ext_swizzle> extSwizComp extSwizSel
2173464ebd5Sriastradh%type <swiz_mask> optionalMask
2183464ebd5Sriastradh
2193464ebd5Sriastradh%type <sym> progParamArray
2203464ebd5Sriastradh%type <integer> addrRegRelOffset addrRegPosOffset addrRegNegOffset
2213464ebd5Sriastradh%type <src_reg> progParamArrayMem progParamArrayAbs progParamArrayRel
2223464ebd5Sriastradh%type <sym> addrReg
2233464ebd5Sriastradh%type <swiz_mask> addrComponent addrWriteMask
2243464ebd5Sriastradh
2253464ebd5Sriastradh%type <result> resultBinding resultColBinding
2263464ebd5Sriastradh%type <integer> optFaceType optColorType
2273464ebd5Sriastradh%type <integer> optResultFaceType optResultColorType
2283464ebd5Sriastradh
2293464ebd5Sriastradh%type <integer> optTexImageUnitNum texImageUnitNum
2303464ebd5Sriastradh%type <integer> optTexCoordUnitNum texCoordUnitNum
2313464ebd5Sriastradh%type <integer> optLegacyTexUnitNum legacyTexUnitNum
2323464ebd5Sriastradh%type <integer> texImageUnit texTarget
2333464ebd5Sriastradh%type <integer> vtxAttribNum
2343464ebd5Sriastradh
2353464ebd5Sriastradh%type <attrib> attribBinding vtxAttribItem fragAttribItem
2363464ebd5Sriastradh
2373464ebd5Sriastradh%type <temp_sym> paramSingleInit paramSingleItemDecl
2383464ebd5Sriastradh%type <integer> optArraySize
2393464ebd5Sriastradh
2403464ebd5Sriastradh%type <state> stateSingleItem stateMultipleItem
2413464ebd5Sriastradh%type <state> stateMaterialItem
2423464ebd5Sriastradh%type <state> stateLightItem stateLightModelItem stateLightProdItem
2433464ebd5Sriastradh%type <state> stateTexGenItem stateFogItem stateClipPlaneItem statePointItem
2443464ebd5Sriastradh%type <state> stateMatrixItem stateMatrixRow stateMatrixRows
2453464ebd5Sriastradh%type <state> stateTexEnvItem stateDepthItem
2463464ebd5Sriastradh
2473464ebd5Sriastradh%type <state> stateLModProperty
2483464ebd5Sriastradh%type <state> stateMatrixName optMatrixRows
2493464ebd5Sriastradh
2503464ebd5Sriastradh%type <integer> stateMatProperty
2513464ebd5Sriastradh%type <integer> stateLightProperty stateSpotProperty
2523464ebd5Sriastradh%type <integer> stateLightNumber stateLProdProperty
2533464ebd5Sriastradh%type <integer> stateTexGenType stateTexGenCoord
2543464ebd5Sriastradh%type <integer> stateTexEnvProperty
2553464ebd5Sriastradh%type <integer> stateFogProperty
2563464ebd5Sriastradh%type <integer> stateClipPlaneNum
2573464ebd5Sriastradh%type <integer> statePointProperty
2583464ebd5Sriastradh
2593464ebd5Sriastradh%type <integer> stateOptMatModifier stateMatModifier stateMatrixRowNum
2607ec681f3Smrg%type <integer> stateOptModMatNum stateModMatNum statePaletteMatNum
2613464ebd5Sriastradh%type <integer> stateProgramMatNum
2623464ebd5Sriastradh
2637ec681f3Smrg%type <integer> ambDiffSpecPropertyMaterial
2647ec681f3Smrg%type <integer> ambDiffSpecPropertyLight
2653464ebd5Sriastradh
2663464ebd5Sriastradh%type <state> programSingleItem progEnvParam progLocalParam
2673464ebd5Sriastradh%type <state> programMultipleItem progEnvParams progLocalParams
2683464ebd5Sriastradh
2693464ebd5Sriastradh%type <temp_sym> paramMultipleInit paramMultInitList paramMultipleItem
2703464ebd5Sriastradh%type <temp_sym> paramSingleItemUse
2713464ebd5Sriastradh
2723464ebd5Sriastradh%type <integer> progEnvParamNum progLocalParamNum
2733464ebd5Sriastradh%type <state> progEnvParamNums progLocalParamNums
2743464ebd5Sriastradh
2753464ebd5Sriastradh%type <vector> paramConstDecl paramConstUse
2763464ebd5Sriastradh%type <vector> paramConstScalarDecl paramConstScalarUse paramConstVector
2773464ebd5Sriastradh%type <real> signedFloatConstant
2783464ebd5Sriastradh%type <negate> optionalSign
2793464ebd5Sriastradh
2803464ebd5Sriastradh%{
281af69d88dSmrgextern int
282af69d88dSmrg_mesa_program_lexer_lex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
283af69d88dSmrg                        void *yyscanner);
284af69d88dSmrg
285af69d88dSmrgstatic int
286af69d88dSmrgyylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
287af69d88dSmrg      struct asm_parser_state *state)
288af69d88dSmrg{
289af69d88dSmrg   return _mesa_program_lexer_lex(yylval_param, yylloc_param, state->scanner);
290af69d88dSmrg}
2913464ebd5Sriastradh%}
2923464ebd5Sriastradh
2933464ebd5Sriastradh%%
2943464ebd5Sriastradh
2953464ebd5Sriastradhprogram: language optionSequence statementSequence END
2963464ebd5Sriastradh	;
2973464ebd5Sriastradh
2983464ebd5Sriastradhlanguage: ARBvp_10
2993464ebd5Sriastradh	{
3003464ebd5Sriastradh	   if (state->prog->Target != GL_VERTEX_PROGRAM_ARB) {
3013464ebd5Sriastradh	      yyerror(& @1, state, "invalid fragment program header");
3023464ebd5Sriastradh
3033464ebd5Sriastradh	   }
3043464ebd5Sriastradh	   state->mode = ARB_vertex;
3053464ebd5Sriastradh	}
3063464ebd5Sriastradh	| ARBfp_10
3073464ebd5Sriastradh	{
3083464ebd5Sriastradh	   if (state->prog->Target != GL_FRAGMENT_PROGRAM_ARB) {
3093464ebd5Sriastradh	      yyerror(& @1, state, "invalid vertex program header");
3103464ebd5Sriastradh	   }
3113464ebd5Sriastradh	   state->mode = ARB_fragment;
3123464ebd5Sriastradh
3133464ebd5Sriastradh	   state->option.TexRect =
3143464ebd5Sriastradh	      (state->ctx->Extensions.NV_texture_rectangle != GL_FALSE);
3153464ebd5Sriastradh	}
3163464ebd5Sriastradh	;
3173464ebd5Sriastradh
3183464ebd5SriastradhoptionSequence: optionSequence option
3193464ebd5Sriastradh	|
3203464ebd5Sriastradh	;
3213464ebd5Sriastradh
3223464ebd5Sriastradhoption: OPTION string ';'
3233464ebd5Sriastradh	{
3243464ebd5Sriastradh	   int valid = 0;
3253464ebd5Sriastradh
3263464ebd5Sriastradh	   if (state->mode == ARB_vertex) {
3273464ebd5Sriastradh	      valid = _mesa_ARBvp_parse_option(state, $2);
3283464ebd5Sriastradh	   } else if (state->mode == ARB_fragment) {
3293464ebd5Sriastradh	      valid = _mesa_ARBfp_parse_option(state, $2);
3303464ebd5Sriastradh	   }
3313464ebd5Sriastradh
3323464ebd5Sriastradh
3333464ebd5Sriastradh	   free($2);
3343464ebd5Sriastradh
3353464ebd5Sriastradh	   if (!valid) {
3363464ebd5Sriastradh	      const char *const err_str = (state->mode == ARB_vertex)
3373464ebd5Sriastradh		 ? "invalid ARB vertex program option"
3383464ebd5Sriastradh		 : "invalid ARB fragment program option";
3393464ebd5Sriastradh
3403464ebd5Sriastradh	      yyerror(& @2, state, err_str);
3413464ebd5Sriastradh	      YYERROR;
3423464ebd5Sriastradh	   }
3433464ebd5Sriastradh	}
3443464ebd5Sriastradh	;
3453464ebd5Sriastradh
3463464ebd5SriastradhstatementSequence: statementSequence statement
3473464ebd5Sriastradh	|
3483464ebd5Sriastradh	;
3493464ebd5Sriastradh
3503464ebd5Sriastradhstatement: instruction ';'
3513464ebd5Sriastradh	{
3523464ebd5Sriastradh	   if ($1 != NULL) {
3533464ebd5Sriastradh	      if (state->inst_tail == NULL) {
3543464ebd5Sriastradh		 state->inst_head = $1;
3553464ebd5Sriastradh	      } else {
3563464ebd5Sriastradh		 state->inst_tail->next = $1;
3573464ebd5Sriastradh	      }
3583464ebd5Sriastradh
3593464ebd5Sriastradh	      state->inst_tail = $1;
3603464ebd5Sriastradh	      $1->next = NULL;
3613464ebd5Sriastradh
36201e04c3fSmrg              state->prog->arb.NumInstructions++;
3633464ebd5Sriastradh	   }
3643464ebd5Sriastradh	}
3653464ebd5Sriastradh	| namingStatement ';'
3663464ebd5Sriastradh	;
3673464ebd5Sriastradh
3683464ebd5Sriastradhinstruction: ALU_instruction
3693464ebd5Sriastradh	{
3703464ebd5Sriastradh	   $$ = $1;
37101e04c3fSmrg           state->prog->arb.NumAluInstructions++;
3723464ebd5Sriastradh	}
3733464ebd5Sriastradh	| TexInstruction
3743464ebd5Sriastradh	{
3753464ebd5Sriastradh	   $$ = $1;
37601e04c3fSmrg           state->prog->arb.NumTexInstructions++;
3773464ebd5Sriastradh	}
3783464ebd5Sriastradh	;
3793464ebd5Sriastradh
3803464ebd5SriastradhALU_instruction: ARL_instruction
3813464ebd5Sriastradh	| VECTORop_instruction
3823464ebd5Sriastradh	| SCALARop_instruction
3833464ebd5Sriastradh	| BINSCop_instruction
3843464ebd5Sriastradh	| BINop_instruction
3853464ebd5Sriastradh	| TRIop_instruction
3863464ebd5Sriastradh	| SWZ_instruction
3873464ebd5Sriastradh	;
3883464ebd5Sriastradh
3893464ebd5SriastradhTexInstruction: SAMPLE_instruction
3903464ebd5Sriastradh	| KIL_instruction
3913464ebd5Sriastradh	| TXD_instruction
3923464ebd5Sriastradh	;
3933464ebd5Sriastradh
3943464ebd5SriastradhARL_instruction: ARL maskedAddrReg ',' scalarSrcReg
3953464ebd5Sriastradh	{
3963464ebd5Sriastradh	   $$ = asm_instruction_ctor(OPCODE_ARL, & $2, & $4, NULL, NULL);
3973464ebd5Sriastradh	}
3983464ebd5Sriastradh	;
3993464ebd5Sriastradh
4003464ebd5SriastradhVECTORop_instruction: VECTOR_OP maskedDstReg ',' swizzleSrcReg
4013464ebd5Sriastradh	{
4023464ebd5Sriastradh	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
4033464ebd5Sriastradh	}
4043464ebd5Sriastradh	;
4053464ebd5Sriastradh
4063464ebd5SriastradhSCALARop_instruction: SCALAR_OP maskedDstReg ',' scalarSrcReg
4073464ebd5Sriastradh	{
4083464ebd5Sriastradh	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
4093464ebd5Sriastradh	}
4103464ebd5Sriastradh	;
4113464ebd5Sriastradh
4123464ebd5SriastradhBINSCop_instruction: BINSC_OP maskedDstReg ',' scalarSrcReg ',' scalarSrcReg
4133464ebd5Sriastradh	{
4143464ebd5Sriastradh	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL);
4153464ebd5Sriastradh	}
4163464ebd5Sriastradh	;
4173464ebd5Sriastradh
4183464ebd5Sriastradh
4193464ebd5SriastradhBINop_instruction: BIN_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg
4203464ebd5Sriastradh	{
4213464ebd5Sriastradh	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL);
4223464ebd5Sriastradh	}
4233464ebd5Sriastradh	;
4243464ebd5Sriastradh
4253464ebd5SriastradhTRIop_instruction: TRI_OP maskedDstReg ','
4263464ebd5Sriastradh                   swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg
4273464ebd5Sriastradh	{
4283464ebd5Sriastradh	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8);
4293464ebd5Sriastradh	}
4303464ebd5Sriastradh	;
4313464ebd5Sriastradh
4323464ebd5SriastradhSAMPLE_instruction: SAMPLE_OP maskedDstReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget
4333464ebd5Sriastradh	{
4343464ebd5Sriastradh	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
4353464ebd5Sriastradh	   if ($$ != NULL) {
4363464ebd5Sriastradh	      const GLbitfield tex_mask = (1U << $6);
4373464ebd5Sriastradh	      GLbitfield shadow_tex = 0;
4383464ebd5Sriastradh	      GLbitfield target_mask = 0;
4393464ebd5Sriastradh
4403464ebd5Sriastradh
4413464ebd5Sriastradh	      $$->Base.TexSrcUnit = $6;
4423464ebd5Sriastradh
4433464ebd5Sriastradh	      if ($8 < 0) {
4443464ebd5Sriastradh		 shadow_tex = tex_mask;
4453464ebd5Sriastradh
4463464ebd5Sriastradh		 $$->Base.TexSrcTarget = -$8;
4473464ebd5Sriastradh		 $$->Base.TexShadow = 1;
4483464ebd5Sriastradh	      } else {
4493464ebd5Sriastradh		 $$->Base.TexSrcTarget = $8;
4503464ebd5Sriastradh	      }
4513464ebd5Sriastradh
4523464ebd5Sriastradh	      target_mask = (1U << $$->Base.TexSrcTarget);
4533464ebd5Sriastradh
4543464ebd5Sriastradh	      /* If this texture unit was previously accessed and that access
4553464ebd5Sriastradh	       * had a different texture target, generate an error.
4563464ebd5Sriastradh	       *
4573464ebd5Sriastradh	       * If this texture unit was previously accessed and that access
4583464ebd5Sriastradh	       * had a different shadow mode, generate an error.
4593464ebd5Sriastradh	       */
4603464ebd5Sriastradh	      if ((state->prog->TexturesUsed[$6] != 0)
4613464ebd5Sriastradh		  && ((state->prog->TexturesUsed[$6] != target_mask)
4623464ebd5Sriastradh		      || ((state->prog->ShadowSamplers & tex_mask)
4633464ebd5Sriastradh			  != shadow_tex))) {
4643464ebd5Sriastradh		 yyerror(& @8, state,
4653464ebd5Sriastradh			 "multiple targets used on one texture image unit");
4663464ebd5Sriastradh		 YYERROR;
4673464ebd5Sriastradh	      }
4683464ebd5Sriastradh
4693464ebd5Sriastradh
4703464ebd5Sriastradh	      state->prog->TexturesUsed[$6] |= target_mask;
4713464ebd5Sriastradh	      state->prog->ShadowSamplers |= shadow_tex;
4723464ebd5Sriastradh	   }
4733464ebd5Sriastradh	}
4743464ebd5Sriastradh	;
4753464ebd5Sriastradh
4763464ebd5SriastradhKIL_instruction: KIL swizzleSrcReg
4773464ebd5Sriastradh	{
4783464ebd5Sriastradh	   $$ = asm_instruction_ctor(OPCODE_KIL, NULL, & $2, NULL, NULL);
4793464ebd5Sriastradh	   state->fragment.UsesKill = 1;
4803464ebd5Sriastradh	}
4813464ebd5Sriastradh	;
4823464ebd5Sriastradh
4833464ebd5SriastradhTXD_instruction: TXD_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget
4843464ebd5Sriastradh	{
4853464ebd5Sriastradh	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8);
4863464ebd5Sriastradh	   if ($$ != NULL) {
4873464ebd5Sriastradh	      const GLbitfield tex_mask = (1U << $10);
4883464ebd5Sriastradh	      GLbitfield shadow_tex = 0;
4893464ebd5Sriastradh	      GLbitfield target_mask = 0;
4903464ebd5Sriastradh
4913464ebd5Sriastradh
4923464ebd5Sriastradh	      $$->Base.TexSrcUnit = $10;
4933464ebd5Sriastradh
4943464ebd5Sriastradh	      if ($12 < 0) {
4953464ebd5Sriastradh		 shadow_tex = tex_mask;
4963464ebd5Sriastradh
4973464ebd5Sriastradh		 $$->Base.TexSrcTarget = -$12;
4983464ebd5Sriastradh		 $$->Base.TexShadow = 1;
4993464ebd5Sriastradh	      } else {
5003464ebd5Sriastradh		 $$->Base.TexSrcTarget = $12;
5013464ebd5Sriastradh	      }
5023464ebd5Sriastradh
5033464ebd5Sriastradh	      target_mask = (1U << $$->Base.TexSrcTarget);
5043464ebd5Sriastradh
5053464ebd5Sriastradh	      /* If this texture unit was previously accessed and that access
5063464ebd5Sriastradh	       * had a different texture target, generate an error.
5073464ebd5Sriastradh	       *
5083464ebd5Sriastradh	       * If this texture unit was previously accessed and that access
5093464ebd5Sriastradh	       * had a different shadow mode, generate an error.
5103464ebd5Sriastradh	       */
5113464ebd5Sriastradh	      if ((state->prog->TexturesUsed[$10] != 0)
5123464ebd5Sriastradh		  && ((state->prog->TexturesUsed[$10] != target_mask)
5133464ebd5Sriastradh		      || ((state->prog->ShadowSamplers & tex_mask)
5143464ebd5Sriastradh			  != shadow_tex))) {
5153464ebd5Sriastradh		 yyerror(& @12, state,
5163464ebd5Sriastradh			 "multiple targets used on one texture image unit");
5173464ebd5Sriastradh		 YYERROR;
5183464ebd5Sriastradh	      }
5193464ebd5Sriastradh
5203464ebd5Sriastradh
5213464ebd5Sriastradh	      state->prog->TexturesUsed[$10] |= target_mask;
5223464ebd5Sriastradh	      state->prog->ShadowSamplers |= shadow_tex;
5233464ebd5Sriastradh	   }
5243464ebd5Sriastradh	}
5253464ebd5Sriastradh	;
5263464ebd5Sriastradh
5273464ebd5SriastradhtexImageUnit: TEXTURE_UNIT optTexImageUnitNum
5283464ebd5Sriastradh	{
5293464ebd5Sriastradh	   $$ = $2;
5303464ebd5Sriastradh	}
5313464ebd5Sriastradh	;
5323464ebd5Sriastradh
5333464ebd5SriastradhtexTarget: TEX_1D  { $$ = TEXTURE_1D_INDEX; }
5343464ebd5Sriastradh	| TEX_2D   { $$ = TEXTURE_2D_INDEX; }
5353464ebd5Sriastradh	| TEX_3D   { $$ = TEXTURE_3D_INDEX; }
5363464ebd5Sriastradh	| TEX_CUBE { $$ = TEXTURE_CUBE_INDEX; }
5373464ebd5Sriastradh	| TEX_RECT { $$ = TEXTURE_RECT_INDEX; }
5383464ebd5Sriastradh	| TEX_SHADOW1D   { $$ = -TEXTURE_1D_INDEX; }
5393464ebd5Sriastradh	| TEX_SHADOW2D   { $$ = -TEXTURE_2D_INDEX; }
5403464ebd5Sriastradh	| TEX_SHADOWRECT { $$ = -TEXTURE_RECT_INDEX; }
5413464ebd5Sriastradh	| TEX_ARRAY1D         { $$ = TEXTURE_1D_ARRAY_INDEX; }
5423464ebd5Sriastradh	| TEX_ARRAY2D         { $$ = TEXTURE_2D_ARRAY_INDEX; }
5433464ebd5Sriastradh	| TEX_ARRAYSHADOW1D   { $$ = -TEXTURE_1D_ARRAY_INDEX; }
5443464ebd5Sriastradh	| TEX_ARRAYSHADOW2D   { $$ = -TEXTURE_2D_ARRAY_INDEX; }
5453464ebd5Sriastradh	;
5463464ebd5Sriastradh
5473464ebd5SriastradhSWZ_instruction: SWZ maskedDstReg ',' srcReg ',' extendedSwizzle
5483464ebd5Sriastradh	{
5493464ebd5Sriastradh	   /* FIXME: Is this correct?  Should the extenedSwizzle be applied
5503464ebd5Sriastradh	    * FIXME: to the existing swizzle?
5513464ebd5Sriastradh	    */
5523464ebd5Sriastradh	   $4.Base.Swizzle = $6.swizzle;
5533464ebd5Sriastradh	   $4.Base.Negate = $6.mask;
5543464ebd5Sriastradh
5553464ebd5Sriastradh	   $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
5563464ebd5Sriastradh	}
5573464ebd5Sriastradh	;
5583464ebd5Sriastradh
5593464ebd5SriastradhscalarSrcReg: optionalSign scalarUse
5603464ebd5Sriastradh	{
5613464ebd5Sriastradh	   $$ = $2;
5623464ebd5Sriastradh
5633464ebd5Sriastradh	   if ($1) {
5643464ebd5Sriastradh	      $$.Base.Negate = ~$$.Base.Negate;
5653464ebd5Sriastradh	   }
5663464ebd5Sriastradh	}
5673464ebd5Sriastradh	;
5683464ebd5Sriastradh
5693464ebd5SriastradhscalarUse:  srcReg scalarSuffix
5703464ebd5Sriastradh	{
5713464ebd5Sriastradh	   $$ = $1;
5723464ebd5Sriastradh
5733464ebd5Sriastradh	   $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
5743464ebd5Sriastradh						    $2.swizzle);
5753464ebd5Sriastradh	}
5763464ebd5Sriastradh	;
5773464ebd5Sriastradh
5783464ebd5SriastradhswizzleSrcReg: optionalSign srcReg swizzleSuffix
5793464ebd5Sriastradh	{
5803464ebd5Sriastradh	   $$ = $2;
5813464ebd5Sriastradh
5823464ebd5Sriastradh	   if ($1) {
5833464ebd5Sriastradh	      $$.Base.Negate = ~$$.Base.Negate;
5843464ebd5Sriastradh	   }
5853464ebd5Sriastradh
5863464ebd5Sriastradh	   $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
5873464ebd5Sriastradh						    $3.swizzle);
5883464ebd5Sriastradh	}
5893464ebd5Sriastradh	;
5903464ebd5Sriastradh
59101e04c3fSmrgmaskedDstReg: dstReg optionalMask
5923464ebd5Sriastradh	{
5933464ebd5Sriastradh	   $$ = $1;
5943464ebd5Sriastradh	   $$.WriteMask = $2.mask;
5953464ebd5Sriastradh
5963464ebd5Sriastradh	   if ($$.File == PROGRAM_OUTPUT) {
5973464ebd5Sriastradh	      /* Technically speaking, this should check that it is in
5983464ebd5Sriastradh	       * vertex program mode.  However, PositionInvariant can never be
5993464ebd5Sriastradh	       * set in fragment program mode, so it is somewhat irrelevant.
6003464ebd5Sriastradh	       */
6013464ebd5Sriastradh	      if (state->option.PositionInvariant
602af69d88dSmrg	       && ($$.Index == VARYING_SLOT_POS)) {
6033464ebd5Sriastradh		 yyerror(& @1, state, "position-invariant programs cannot "
6043464ebd5Sriastradh			 "write position");
6053464ebd5Sriastradh		 YYERROR;
6063464ebd5Sriastradh	      }
6073464ebd5Sriastradh
60801e04c3fSmrg              state->prog->info.outputs_written |= BITFIELD64_BIT($$.Index);
6093464ebd5Sriastradh	   }
6103464ebd5Sriastradh	}
6113464ebd5Sriastradh	;
6123464ebd5Sriastradh
6133464ebd5SriastradhmaskedAddrReg: addrReg addrWriteMask
6143464ebd5Sriastradh	{
6153464ebd5Sriastradh	   set_dst_reg(& $$, PROGRAM_ADDRESS, 0);
6163464ebd5Sriastradh	   $$.WriteMask = $2.mask;
6173464ebd5Sriastradh	}
6183464ebd5Sriastradh	;
6193464ebd5Sriastradh
6203464ebd5SriastradhextendedSwizzle: extSwizComp ',' extSwizComp ',' extSwizComp ',' extSwizComp
6213464ebd5Sriastradh	{
6223464ebd5Sriastradh	   const unsigned xyzw_valid =
6233464ebd5Sriastradh	      ($1.xyzw_valid << 0)
6243464ebd5Sriastradh	      | ($3.xyzw_valid << 1)
6253464ebd5Sriastradh	      | ($5.xyzw_valid << 2)
6263464ebd5Sriastradh	      | ($7.xyzw_valid << 3);
6273464ebd5Sriastradh	   const unsigned rgba_valid =
6283464ebd5Sriastradh	      ($1.rgba_valid << 0)
6293464ebd5Sriastradh	      | ($3.rgba_valid << 1)
6303464ebd5Sriastradh	      | ($5.rgba_valid << 2)
6313464ebd5Sriastradh	      | ($7.rgba_valid << 3);
6323464ebd5Sriastradh
6333464ebd5Sriastradh	   /* All of the swizzle components have to be valid in either RGBA
6343464ebd5Sriastradh	    * or XYZW.  Note that 0 and 1 are valid in both, so both masks
6353464ebd5Sriastradh	    * can have some bits set.
6363464ebd5Sriastradh	    *
6373464ebd5Sriastradh	    * We somewhat deviate from the spec here.  It would be really hard
6383464ebd5Sriastradh	    * to figure out which component is the error, and there probably
6393464ebd5Sriastradh	    * isn't a lot of benefit.
6403464ebd5Sriastradh	    */
6413464ebd5Sriastradh	   if ((rgba_valid != 0x0f) && (xyzw_valid != 0x0f)) {
6423464ebd5Sriastradh	      yyerror(& @1, state, "cannot combine RGBA and XYZW swizzle "
6433464ebd5Sriastradh		      "components");
6443464ebd5Sriastradh	      YYERROR;
6453464ebd5Sriastradh	   }
6463464ebd5Sriastradh
6473464ebd5Sriastradh	   $$.swizzle = MAKE_SWIZZLE4($1.swz, $3.swz, $5.swz, $7.swz);
6483464ebd5Sriastradh	   $$.mask = ($1.negate) | ($3.negate << 1) | ($5.negate << 2)
6493464ebd5Sriastradh	      | ($7.negate << 3);
6503464ebd5Sriastradh	}
6513464ebd5Sriastradh	;
6523464ebd5Sriastradh
6533464ebd5SriastradhextSwizComp: optionalSign extSwizSel
6543464ebd5Sriastradh	{
6553464ebd5Sriastradh	   $$ = $2;
6563464ebd5Sriastradh	   $$.negate = ($1) ? 1 : 0;
6573464ebd5Sriastradh	}
6583464ebd5Sriastradh	;
6593464ebd5Sriastradh
6603464ebd5SriastradhextSwizSel: INTEGER
6613464ebd5Sriastradh	{
6623464ebd5Sriastradh	   if (($1 != 0) && ($1 != 1)) {
6633464ebd5Sriastradh	      yyerror(& @1, state, "invalid extended swizzle selector");
6643464ebd5Sriastradh	      YYERROR;
6653464ebd5Sriastradh	   }
6663464ebd5Sriastradh
6673464ebd5Sriastradh	   $$.swz = ($1 == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE;
668af69d88dSmrg           $$.negate = 0;
6693464ebd5Sriastradh
6703464ebd5Sriastradh	   /* 0 and 1 are valid for both RGBA swizzle names and XYZW
6713464ebd5Sriastradh	    * swizzle names.
6723464ebd5Sriastradh	    */
6733464ebd5Sriastradh	   $$.xyzw_valid = 1;
6743464ebd5Sriastradh	   $$.rgba_valid = 1;
6753464ebd5Sriastradh	}
6763464ebd5Sriastradh	| string
6773464ebd5Sriastradh	{
6783464ebd5Sriastradh	   char s;
6793464ebd5Sriastradh
6803464ebd5Sriastradh	   if (strlen($1) > 1) {
6813464ebd5Sriastradh	      yyerror(& @1, state, "invalid extended swizzle selector");
6823464ebd5Sriastradh	      YYERROR;
6833464ebd5Sriastradh	   }
6843464ebd5Sriastradh
6853464ebd5Sriastradh	   s = $1[0];
6863464ebd5Sriastradh	   free($1);
6873464ebd5Sriastradh
688af69d88dSmrg           $$.rgba_valid = 0;
689af69d88dSmrg           $$.xyzw_valid = 0;
690af69d88dSmrg           $$.negate = 0;
691af69d88dSmrg
6923464ebd5Sriastradh	   switch (s) {
6933464ebd5Sriastradh	   case 'x':
6943464ebd5Sriastradh	      $$.swz = SWIZZLE_X;
6953464ebd5Sriastradh	      $$.xyzw_valid = 1;
6963464ebd5Sriastradh	      break;
6973464ebd5Sriastradh	   case 'y':
6983464ebd5Sriastradh	      $$.swz = SWIZZLE_Y;
6993464ebd5Sriastradh	      $$.xyzw_valid = 1;
7003464ebd5Sriastradh	      break;
7013464ebd5Sriastradh	   case 'z':
7023464ebd5Sriastradh	      $$.swz = SWIZZLE_Z;
7033464ebd5Sriastradh	      $$.xyzw_valid = 1;
7043464ebd5Sriastradh	      break;
7053464ebd5Sriastradh	   case 'w':
7063464ebd5Sriastradh	      $$.swz = SWIZZLE_W;
7073464ebd5Sriastradh	      $$.xyzw_valid = 1;
7083464ebd5Sriastradh	      break;
7093464ebd5Sriastradh
7103464ebd5Sriastradh	   case 'r':
7113464ebd5Sriastradh	      $$.swz = SWIZZLE_X;
7123464ebd5Sriastradh	      $$.rgba_valid = 1;
7133464ebd5Sriastradh	      break;
7143464ebd5Sriastradh	   case 'g':
7153464ebd5Sriastradh	      $$.swz = SWIZZLE_Y;
7163464ebd5Sriastradh	      $$.rgba_valid = 1;
7173464ebd5Sriastradh	      break;
7183464ebd5Sriastradh	   case 'b':
7193464ebd5Sriastradh	      $$.swz = SWIZZLE_Z;
7203464ebd5Sriastradh	      $$.rgba_valid = 1;
7213464ebd5Sriastradh	      break;
7223464ebd5Sriastradh	   case 'a':
7233464ebd5Sriastradh	      $$.swz = SWIZZLE_W;
7243464ebd5Sriastradh	      $$.rgba_valid = 1;
7253464ebd5Sriastradh	      break;
7263464ebd5Sriastradh
7273464ebd5Sriastradh	   default:
7283464ebd5Sriastradh	      yyerror(& @1, state, "invalid extended swizzle selector");
7293464ebd5Sriastradh	      YYERROR;
7303464ebd5Sriastradh	      break;
7313464ebd5Sriastradh	   }
7323464ebd5Sriastradh	}
7333464ebd5Sriastradh	;
7343464ebd5Sriastradh
7353464ebd5SriastradhsrcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */
7363464ebd5Sriastradh	{
7373464ebd5Sriastradh	   struct asm_symbol *const s = (struct asm_symbol *)
73801e04c3fSmrg              _mesa_symbol_table_find_symbol(state->st, $1);
7393464ebd5Sriastradh
7403464ebd5Sriastradh	   free($1);
7413464ebd5Sriastradh
7423464ebd5Sriastradh	   if (s == NULL) {
7433464ebd5Sriastradh	      yyerror(& @1, state, "invalid operand variable");
7443464ebd5Sriastradh	      YYERROR;
7453464ebd5Sriastradh	   } else if ((s->type != at_param) && (s->type != at_temp)
7463464ebd5Sriastradh		      && (s->type != at_attrib)) {
7473464ebd5Sriastradh	      yyerror(& @1, state, "invalid operand variable");
7483464ebd5Sriastradh	      YYERROR;
7493464ebd5Sriastradh	   } else if ((s->type == at_param) && s->param_is_array) {
7503464ebd5Sriastradh	      yyerror(& @1, state, "non-array access to array PARAM");
7513464ebd5Sriastradh	      YYERROR;
7523464ebd5Sriastradh	   }
7533464ebd5Sriastradh
7543464ebd5Sriastradh	   init_src_reg(& $$);
7553464ebd5Sriastradh	   switch (s->type) {
7563464ebd5Sriastradh	   case at_temp:
7573464ebd5Sriastradh	      set_src_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding);
7583464ebd5Sriastradh	      break;
7593464ebd5Sriastradh	   case at_param:
7603464ebd5Sriastradh              set_src_reg_swz(& $$, s->param_binding_type,
7613464ebd5Sriastradh                              s->param_binding_begin,
7623464ebd5Sriastradh                              s->param_binding_swizzle);
7633464ebd5Sriastradh	      break;
7643464ebd5Sriastradh	   case at_attrib:
7653464ebd5Sriastradh	      set_src_reg(& $$, PROGRAM_INPUT, s->attrib_binding);
76601e04c3fSmrg              state->prog->info.inputs_read |= BITFIELD64_BIT($$.Base.Index);
7673464ebd5Sriastradh
7683464ebd5Sriastradh	      if (!validate_inputs(& @1, state)) {
7693464ebd5Sriastradh		 YYERROR;
7703464ebd5Sriastradh	      }
7713464ebd5Sriastradh	      break;
7723464ebd5Sriastradh
7733464ebd5Sriastradh	   default:
7743464ebd5Sriastradh	      YYERROR;
7753464ebd5Sriastradh	      break;
7763464ebd5Sriastradh	   }
7773464ebd5Sriastradh	}
7783464ebd5Sriastradh	| attribBinding
7793464ebd5Sriastradh	{
7803464ebd5Sriastradh	   set_src_reg(& $$, PROGRAM_INPUT, $1);
78101e04c3fSmrg           state->prog->info.inputs_read |= BITFIELD64_BIT($$.Base.Index);
7823464ebd5Sriastradh
7833464ebd5Sriastradh	   if (!validate_inputs(& @1, state)) {
7843464ebd5Sriastradh	      YYERROR;
7853464ebd5Sriastradh	   }
7863464ebd5Sriastradh	}
7873464ebd5Sriastradh	| progParamArray '[' progParamArrayMem ']'
7883464ebd5Sriastradh	{
7893464ebd5Sriastradh	   if (! $3.Base.RelAddr
7903464ebd5Sriastradh	       && ((unsigned) $3.Base.Index >= $1->param_binding_length)) {
7913464ebd5Sriastradh	      yyerror(& @3, state, "out of bounds array access");
7923464ebd5Sriastradh	      YYERROR;
7933464ebd5Sriastradh	   }
7943464ebd5Sriastradh
7953464ebd5Sriastradh	   init_src_reg(& $$);
7963464ebd5Sriastradh	   $$.Base.File = $1->param_binding_type;
7973464ebd5Sriastradh
7983464ebd5Sriastradh	   if ($3.Base.RelAddr) {
79901e04c3fSmrg              state->prog->arb.IndirectRegisterFiles |= (1 << $$.Base.File);
8003464ebd5Sriastradh	      $1->param_accessed_indirectly = 1;
8013464ebd5Sriastradh
8023464ebd5Sriastradh	      $$.Base.RelAddr = 1;
8033464ebd5Sriastradh	      $$.Base.Index = $3.Base.Index;
8043464ebd5Sriastradh	      $$.Symbol = $1;
8053464ebd5Sriastradh	   } else {
8063464ebd5Sriastradh	      $$.Base.Index = $1->param_binding_begin + $3.Base.Index;
8073464ebd5Sriastradh	   }
8083464ebd5Sriastradh	}
8093464ebd5Sriastradh	| paramSingleItemUse
8103464ebd5Sriastradh	{
8117ec681f3Smrg           gl_register_file file = ($1.name != NULL)
8123464ebd5Sriastradh	      ? $1.param_binding_type
8133464ebd5Sriastradh	      : PROGRAM_CONSTANT;
8143464ebd5Sriastradh           set_src_reg_swz(& $$, file, $1.param_binding_begin,
8153464ebd5Sriastradh                           $1.param_binding_swizzle);
8163464ebd5Sriastradh	}
8173464ebd5Sriastradh	;
8183464ebd5Sriastradh
8193464ebd5SriastradhdstReg: resultBinding
8203464ebd5Sriastradh	{
8213464ebd5Sriastradh	   set_dst_reg(& $$, PROGRAM_OUTPUT, $1);
8223464ebd5Sriastradh	}
8233464ebd5Sriastradh	| USED_IDENTIFIER /* temporaryReg | vertexResultReg */
8243464ebd5Sriastradh	{
8253464ebd5Sriastradh	   struct asm_symbol *const s = (struct asm_symbol *)
82601e04c3fSmrg              _mesa_symbol_table_find_symbol(state->st, $1);
8273464ebd5Sriastradh
8283464ebd5Sriastradh	   free($1);
8293464ebd5Sriastradh
8303464ebd5Sriastradh	   if (s == NULL) {
8313464ebd5Sriastradh	      yyerror(& @1, state, "invalid operand variable");
8323464ebd5Sriastradh	      YYERROR;
8333464ebd5Sriastradh	   } else if ((s->type != at_output) && (s->type != at_temp)) {
8343464ebd5Sriastradh	      yyerror(& @1, state, "invalid operand variable");
8353464ebd5Sriastradh	      YYERROR;
8363464ebd5Sriastradh	   }
8373464ebd5Sriastradh
8383464ebd5Sriastradh	   switch (s->type) {
8393464ebd5Sriastradh	   case at_temp:
8403464ebd5Sriastradh	      set_dst_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding);
8413464ebd5Sriastradh	      break;
8423464ebd5Sriastradh	   case at_output:
8433464ebd5Sriastradh	      set_dst_reg(& $$, PROGRAM_OUTPUT, s->output_binding);
8443464ebd5Sriastradh	      break;
8453464ebd5Sriastradh	   default:
8463464ebd5Sriastradh	      set_dst_reg(& $$, s->param_binding_type, s->param_binding_begin);
8473464ebd5Sriastradh	      break;
8483464ebd5Sriastradh	   }
8493464ebd5Sriastradh	}
8503464ebd5Sriastradh	;
8513464ebd5Sriastradh
8523464ebd5SriastradhprogParamArray: USED_IDENTIFIER
8533464ebd5Sriastradh	{
8543464ebd5Sriastradh	   struct asm_symbol *const s = (struct asm_symbol *)
85501e04c3fSmrg              _mesa_symbol_table_find_symbol(state->st, $1);
8563464ebd5Sriastradh
8573464ebd5Sriastradh	   free($1);
8583464ebd5Sriastradh
8593464ebd5Sriastradh	   if (s == NULL) {
8603464ebd5Sriastradh	      yyerror(& @1, state, "invalid operand variable");
8613464ebd5Sriastradh	      YYERROR;
8623464ebd5Sriastradh	   } else if ((s->type != at_param) || !s->param_is_array) {
8633464ebd5Sriastradh	      yyerror(& @1, state, "array access to non-PARAM variable");
8643464ebd5Sriastradh	      YYERROR;
8653464ebd5Sriastradh	   } else {
8663464ebd5Sriastradh	      $$ = s;
8673464ebd5Sriastradh	   }
8683464ebd5Sriastradh	}
8693464ebd5Sriastradh	;
8703464ebd5Sriastradh
8713464ebd5SriastradhprogParamArrayMem: progParamArrayAbs | progParamArrayRel;
8723464ebd5Sriastradh
8733464ebd5SriastradhprogParamArrayAbs: INTEGER
8743464ebd5Sriastradh	{
8753464ebd5Sriastradh	   init_src_reg(& $$);
8763464ebd5Sriastradh	   $$.Base.Index = $1;
8773464ebd5Sriastradh	}
8783464ebd5Sriastradh	;
8793464ebd5Sriastradh
8803464ebd5SriastradhprogParamArrayRel: addrReg addrComponent addrRegRelOffset
8813464ebd5Sriastradh	{
8823464ebd5Sriastradh	   /* FINISHME: Add support for multiple address registers.
8833464ebd5Sriastradh	    */
8843464ebd5Sriastradh	   /* FINISHME: Add support for 4-component address registers.
8853464ebd5Sriastradh	    */
8863464ebd5Sriastradh	   init_src_reg(& $$);
8873464ebd5Sriastradh	   $$.Base.RelAddr = 1;
8883464ebd5Sriastradh	   $$.Base.Index = $3;
8893464ebd5Sriastradh	}
8903464ebd5Sriastradh	;
8913464ebd5Sriastradh
8923464ebd5SriastradhaddrRegRelOffset:              { $$ = 0; }
8933464ebd5Sriastradh	| '+' addrRegPosOffset { $$ = $2; }
8943464ebd5Sriastradh	| '-' addrRegNegOffset { $$ = -$2; }
8953464ebd5Sriastradh	;
8963464ebd5Sriastradh
8973464ebd5SriastradhaddrRegPosOffset: INTEGER
8983464ebd5Sriastradh	{
8993464ebd5Sriastradh	   if (($1 < 0) || ($1 > (state->limits->MaxAddressOffset - 1))) {
9003464ebd5Sriastradh              char s[100];
9017ec681f3Smrg              snprintf(s, sizeof(s),
9023464ebd5Sriastradh                             "relative address offset too large (%d)", $1);
9033464ebd5Sriastradh	      yyerror(& @1, state, s);
9043464ebd5Sriastradh	      YYERROR;
9053464ebd5Sriastradh	   } else {
9063464ebd5Sriastradh	      $$ = $1;
9073464ebd5Sriastradh	   }
9083464ebd5Sriastradh	}
9093464ebd5Sriastradh	;
9103464ebd5Sriastradh
9113464ebd5SriastradhaddrRegNegOffset: INTEGER
9123464ebd5Sriastradh	{
9133464ebd5Sriastradh	   if (($1 < 0) || ($1 > state->limits->MaxAddressOffset)) {
9143464ebd5Sriastradh              char s[100];
9157ec681f3Smrg              snprintf(s, sizeof(s),
9163464ebd5Sriastradh                             "relative address offset too large (%d)", $1);
9173464ebd5Sriastradh	      yyerror(& @1, state, s);
9183464ebd5Sriastradh	      YYERROR;
9193464ebd5Sriastradh	   } else {
9203464ebd5Sriastradh	      $$ = $1;
9213464ebd5Sriastradh	   }
9223464ebd5Sriastradh	}
9233464ebd5Sriastradh	;
9243464ebd5Sriastradh
9253464ebd5SriastradhaddrReg: USED_IDENTIFIER
9263464ebd5Sriastradh	{
9273464ebd5Sriastradh	   struct asm_symbol *const s = (struct asm_symbol *)
92801e04c3fSmrg              _mesa_symbol_table_find_symbol(state->st, $1);
9293464ebd5Sriastradh
9303464ebd5Sriastradh	   free($1);
9313464ebd5Sriastradh
9323464ebd5Sriastradh	   if (s == NULL) {
9333464ebd5Sriastradh	      yyerror(& @1, state, "invalid array member");
9343464ebd5Sriastradh	      YYERROR;
9353464ebd5Sriastradh	   } else if (s->type != at_address) {
9363464ebd5Sriastradh	      yyerror(& @1, state,
9373464ebd5Sriastradh		      "invalid variable for indexed array access");
9383464ebd5Sriastradh	      YYERROR;
9393464ebd5Sriastradh	   } else {
9403464ebd5Sriastradh	      $$ = s;
9413464ebd5Sriastradh	   }
9423464ebd5Sriastradh	}
9433464ebd5Sriastradh	;
9443464ebd5Sriastradh
9453464ebd5SriastradhaddrComponent: MASK1
9463464ebd5Sriastradh	{
9473464ebd5Sriastradh	   if ($1.mask != WRITEMASK_X) {
9483464ebd5Sriastradh	      yyerror(& @1, state, "invalid address component selector");
9493464ebd5Sriastradh	      YYERROR;
9503464ebd5Sriastradh	   } else {
9513464ebd5Sriastradh	      $$ = $1;
9523464ebd5Sriastradh	   }
9533464ebd5Sriastradh	}
9543464ebd5Sriastradh	;
9553464ebd5Sriastradh
9563464ebd5SriastradhaddrWriteMask: MASK1
9573464ebd5Sriastradh	{
9583464ebd5Sriastradh	   if ($1.mask != WRITEMASK_X) {
9593464ebd5Sriastradh	      yyerror(& @1, state,
9603464ebd5Sriastradh		      "address register write mask must be \".x\"");
9613464ebd5Sriastradh	      YYERROR;
9623464ebd5Sriastradh	   } else {
9633464ebd5Sriastradh	      $$ = $1;
9643464ebd5Sriastradh	   }
9653464ebd5Sriastradh	}
9663464ebd5Sriastradh	;
9673464ebd5Sriastradh
9683464ebd5SriastradhscalarSuffix: MASK1;
9693464ebd5Sriastradh
9703464ebd5SriastradhswizzleSuffix: MASK1
9713464ebd5Sriastradh	| MASK4
9723464ebd5Sriastradh	| SWIZZLE
9733464ebd5Sriastradh	|              { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
9743464ebd5Sriastradh	;
9753464ebd5Sriastradh
9767ec681f3SmrgoptionalMask: MASK4 | MASK3 | MASK2 | MASK1
9773464ebd5Sriastradh	|              { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
9783464ebd5Sriastradh	;
9793464ebd5Sriastradh
9803464ebd5SriastradhnamingStatement: ATTRIB_statement
9813464ebd5Sriastradh	| PARAM_statement
9823464ebd5Sriastradh	| TEMP_statement
9833464ebd5Sriastradh	| ADDRESS_statement
9843464ebd5Sriastradh	| OUTPUT_statement
9853464ebd5Sriastradh	| ALIAS_statement
9863464ebd5Sriastradh	;
9873464ebd5Sriastradh
9883464ebd5SriastradhATTRIB_statement: ATTRIB IDENTIFIER '=' attribBinding
9893464ebd5Sriastradh	{
9903464ebd5Sriastradh	   struct asm_symbol *const s =
9913464ebd5Sriastradh	      declare_variable(state, $2, at_attrib, & @2);
9923464ebd5Sriastradh
9933464ebd5Sriastradh	   if (s == NULL) {
9943464ebd5Sriastradh	      free($2);
9953464ebd5Sriastradh	      YYERROR;
9963464ebd5Sriastradh	   } else {
9973464ebd5Sriastradh	      s->attrib_binding = $4;
998af69d88dSmrg	      state->InputsBound |= BITFIELD64_BIT(s->attrib_binding);
9993464ebd5Sriastradh
10003464ebd5Sriastradh	      if (!validate_inputs(& @4, state)) {
10013464ebd5Sriastradh		 YYERROR;
10023464ebd5Sriastradh	      }
10033464ebd5Sriastradh	   }
10043464ebd5Sriastradh	}
10053464ebd5Sriastradh	;
10063464ebd5Sriastradh
10073464ebd5SriastradhattribBinding: VERTEX vtxAttribItem
10083464ebd5Sriastradh	{
10093464ebd5Sriastradh	   $$ = $2;
10103464ebd5Sriastradh	}
10113464ebd5Sriastradh	| FRAGMENT fragAttribItem
10123464ebd5Sriastradh	{
10133464ebd5Sriastradh	   $$ = $2;
10143464ebd5Sriastradh	}
10153464ebd5Sriastradh	;
10163464ebd5Sriastradh
10173464ebd5SriastradhvtxAttribItem: POSITION
10183464ebd5Sriastradh	{
10193464ebd5Sriastradh	   $$ = VERT_ATTRIB_POS;
10203464ebd5Sriastradh	}
10213464ebd5Sriastradh	| NORMAL
10223464ebd5Sriastradh	{
10233464ebd5Sriastradh	   $$ = VERT_ATTRIB_NORMAL;
10243464ebd5Sriastradh	}
10253464ebd5Sriastradh	| COLOR optColorType
10263464ebd5Sriastradh	{
10273464ebd5Sriastradh	   $$ = VERT_ATTRIB_COLOR0 + $2;
10283464ebd5Sriastradh	}
10293464ebd5Sriastradh	| FOGCOORD
10303464ebd5Sriastradh	{
10313464ebd5Sriastradh	   $$ = VERT_ATTRIB_FOG;
10323464ebd5Sriastradh	}
10333464ebd5Sriastradh	| TEXCOORD optTexCoordUnitNum
10343464ebd5Sriastradh	{
10353464ebd5Sriastradh	   $$ = VERT_ATTRIB_TEX0 + $2;
10363464ebd5Sriastradh	}
10373464ebd5Sriastradh	| MATRIXINDEX '[' vtxWeightNum ']'
10383464ebd5Sriastradh	{
10393464ebd5Sriastradh	   yyerror(& @1, state, "GL_ARB_matrix_palette not supported");
10403464ebd5Sriastradh	   YYERROR;
10413464ebd5Sriastradh	}
10423464ebd5Sriastradh	| VTXATTRIB '[' vtxAttribNum ']'
10433464ebd5Sriastradh	{
10443464ebd5Sriastradh	   $$ = VERT_ATTRIB_GENERIC0 + $3;
10453464ebd5Sriastradh	}
10463464ebd5Sriastradh	;
10473464ebd5Sriastradh
10483464ebd5SriastradhvtxAttribNum: INTEGER
10493464ebd5Sriastradh	{
10503464ebd5Sriastradh	   if ((unsigned) $1 >= state->limits->MaxAttribs) {
10513464ebd5Sriastradh	      yyerror(& @1, state, "invalid vertex attribute reference");
10523464ebd5Sriastradh	      YYERROR;
10533464ebd5Sriastradh	   }
10543464ebd5Sriastradh
10553464ebd5Sriastradh	   $$ = $1;
10563464ebd5Sriastradh	}
10573464ebd5Sriastradh	;
10583464ebd5Sriastradh
10593464ebd5SriastradhvtxWeightNum: INTEGER;
10603464ebd5Sriastradh
10613464ebd5SriastradhfragAttribItem: POSITION
10623464ebd5Sriastradh	{
1063af69d88dSmrg	   $$ = VARYING_SLOT_POS;
10643464ebd5Sriastradh	}
10653464ebd5Sriastradh	| COLOR optColorType
10663464ebd5Sriastradh	{
1067af69d88dSmrg	   $$ = VARYING_SLOT_COL0 + $2;
10683464ebd5Sriastradh	}
10693464ebd5Sriastradh	| FOGCOORD
10703464ebd5Sriastradh	{
1071af69d88dSmrg	   $$ = VARYING_SLOT_FOGC;
10723464ebd5Sriastradh	}
10733464ebd5Sriastradh	| TEXCOORD optTexCoordUnitNum
10743464ebd5Sriastradh	{
1075af69d88dSmrg	   $$ = VARYING_SLOT_TEX0 + $2;
10763464ebd5Sriastradh	}
10773464ebd5Sriastradh	;
10783464ebd5Sriastradh
10793464ebd5SriastradhPARAM_statement: PARAM_singleStmt | PARAM_multipleStmt;
10803464ebd5Sriastradh
10813464ebd5SriastradhPARAM_singleStmt: PARAM IDENTIFIER paramSingleInit
10823464ebd5Sriastradh	{
10833464ebd5Sriastradh	   struct asm_symbol *const s =
10843464ebd5Sriastradh	      declare_variable(state, $2, at_param, & @2);
10853464ebd5Sriastradh
10863464ebd5Sriastradh	   if (s == NULL) {
10873464ebd5Sriastradh	      free($2);
10883464ebd5Sriastradh	      YYERROR;
10893464ebd5Sriastradh	   } else {
10903464ebd5Sriastradh	      s->param_binding_type = $3.param_binding_type;
10913464ebd5Sriastradh	      s->param_binding_begin = $3.param_binding_begin;
10923464ebd5Sriastradh	      s->param_binding_length = $3.param_binding_length;
10933464ebd5Sriastradh              s->param_binding_swizzle = $3.param_binding_swizzle;
10943464ebd5Sriastradh	      s->param_is_array = 0;
10953464ebd5Sriastradh	   }
10963464ebd5Sriastradh	}
10973464ebd5Sriastradh	;
10983464ebd5Sriastradh
10993464ebd5SriastradhPARAM_multipleStmt: PARAM IDENTIFIER '[' optArraySize ']' paramMultipleInit
11003464ebd5Sriastradh	{
11013464ebd5Sriastradh	   if (($4 != 0) && ((unsigned) $4 != $6.param_binding_length)) {
11023464ebd5Sriastradh	      free($2);
11037ec681f3Smrg	      yyerror(& @4, state,
11043464ebd5Sriastradh		      "parameter array size and number of bindings must match");
11053464ebd5Sriastradh	      YYERROR;
11063464ebd5Sriastradh	   } else {
11073464ebd5Sriastradh	      struct asm_symbol *const s =
11083464ebd5Sriastradh		 declare_variable(state, $2, $6.type, & @2);
11093464ebd5Sriastradh
11103464ebd5Sriastradh	      if (s == NULL) {
11113464ebd5Sriastradh		 free($2);
11123464ebd5Sriastradh		 YYERROR;
11133464ebd5Sriastradh	      } else {
11143464ebd5Sriastradh		 s->param_binding_type = $6.param_binding_type;
11153464ebd5Sriastradh		 s->param_binding_begin = $6.param_binding_begin;
11163464ebd5Sriastradh		 s->param_binding_length = $6.param_binding_length;
11173464ebd5Sriastradh                 s->param_binding_swizzle = SWIZZLE_XYZW;
11183464ebd5Sriastradh		 s->param_is_array = 1;
11193464ebd5Sriastradh	      }
11203464ebd5Sriastradh	   }
11213464ebd5Sriastradh	}
11223464ebd5Sriastradh	;
11233464ebd5Sriastradh
11243464ebd5SriastradhoptArraySize:
11253464ebd5Sriastradh	{
11263464ebd5Sriastradh	   $$ = 0;
11273464ebd5Sriastradh	}
11283464ebd5Sriastradh	| INTEGER
11293464ebd5Sriastradh        {
11303464ebd5Sriastradh	   if (($1 < 1) || ((unsigned) $1 > state->limits->MaxParameters)) {
11313464ebd5Sriastradh              char msg[100];
11327ec681f3Smrg              snprintf(msg, sizeof(msg),
11333464ebd5Sriastradh                             "invalid parameter array size (size=%d max=%u)",
11343464ebd5Sriastradh                             $1, state->limits->MaxParameters);
11353464ebd5Sriastradh	      yyerror(& @1, state, msg);
11363464ebd5Sriastradh	      YYERROR;
11373464ebd5Sriastradh	   } else {
11383464ebd5Sriastradh	      $$ = $1;
11393464ebd5Sriastradh	   }
11403464ebd5Sriastradh	}
11413464ebd5Sriastradh	;
11423464ebd5Sriastradh
11433464ebd5SriastradhparamSingleInit: '=' paramSingleItemDecl
11443464ebd5Sriastradh	{
11453464ebd5Sriastradh	   $$ = $2;
11463464ebd5Sriastradh	}
11473464ebd5Sriastradh	;
11483464ebd5Sriastradh
11493464ebd5SriastradhparamMultipleInit: '=' '{' paramMultInitList '}'
11503464ebd5Sriastradh	{
11513464ebd5Sriastradh	   $$ = $3;
11523464ebd5Sriastradh	}
11533464ebd5Sriastradh	;
11543464ebd5Sriastradh
11553464ebd5SriastradhparamMultInitList: paramMultipleItem
11563464ebd5Sriastradh	| paramMultInitList ',' paramMultipleItem
11573464ebd5Sriastradh	{
11583464ebd5Sriastradh	   $1.param_binding_length += $3.param_binding_length;
11593464ebd5Sriastradh	   $$ = $1;
11603464ebd5Sriastradh	}
11613464ebd5Sriastradh	;
11623464ebd5Sriastradh
11633464ebd5SriastradhparamSingleItemDecl: stateSingleItem
11643464ebd5Sriastradh	{
11653464ebd5Sriastradh	   memset(& $$, 0, sizeof($$));
11663464ebd5Sriastradh	   $$.param_binding_begin = ~0;
11673464ebd5Sriastradh	   initialize_symbol_from_state(state->prog, & $$, $1);
11683464ebd5Sriastradh	}
11693464ebd5Sriastradh	| programSingleItem
11703464ebd5Sriastradh	{
11713464ebd5Sriastradh	   memset(& $$, 0, sizeof($$));
11723464ebd5Sriastradh	   $$.param_binding_begin = ~0;
11733464ebd5Sriastradh	   initialize_symbol_from_param(state->prog, & $$, $1);
11743464ebd5Sriastradh	}
11753464ebd5Sriastradh	| paramConstDecl
11763464ebd5Sriastradh	{
11773464ebd5Sriastradh	   memset(& $$, 0, sizeof($$));
11783464ebd5Sriastradh	   $$.param_binding_begin = ~0;
11793464ebd5Sriastradh	   initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE);
11803464ebd5Sriastradh	}
11813464ebd5Sriastradh	;
11823464ebd5Sriastradh
11833464ebd5SriastradhparamSingleItemUse: stateSingleItem
11843464ebd5Sriastradh	{
11853464ebd5Sriastradh	   memset(& $$, 0, sizeof($$));
11863464ebd5Sriastradh	   $$.param_binding_begin = ~0;
11873464ebd5Sriastradh	   initialize_symbol_from_state(state->prog, & $$, $1);
11883464ebd5Sriastradh	}
11893464ebd5Sriastradh	| programSingleItem
11903464ebd5Sriastradh	{
11913464ebd5Sriastradh	   memset(& $$, 0, sizeof($$));
11923464ebd5Sriastradh	   $$.param_binding_begin = ~0;
11933464ebd5Sriastradh	   initialize_symbol_from_param(state->prog, & $$, $1);
11943464ebd5Sriastradh	}
11953464ebd5Sriastradh	| paramConstUse
11963464ebd5Sriastradh	{
11973464ebd5Sriastradh	   memset(& $$, 0, sizeof($$));
11983464ebd5Sriastradh	   $$.param_binding_begin = ~0;
11993464ebd5Sriastradh	   initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE);
12003464ebd5Sriastradh	}
12013464ebd5Sriastradh	;
12023464ebd5Sriastradh
12033464ebd5SriastradhparamMultipleItem: stateMultipleItem
12043464ebd5Sriastradh	{
12053464ebd5Sriastradh	   memset(& $$, 0, sizeof($$));
12063464ebd5Sriastradh	   $$.param_binding_begin = ~0;
12073464ebd5Sriastradh	   initialize_symbol_from_state(state->prog, & $$, $1);
12083464ebd5Sriastradh	}
12093464ebd5Sriastradh	| programMultipleItem
12103464ebd5Sriastradh	{
12113464ebd5Sriastradh	   memset(& $$, 0, sizeof($$));
12123464ebd5Sriastradh	   $$.param_binding_begin = ~0;
12133464ebd5Sriastradh	   initialize_symbol_from_param(state->prog, & $$, $1);
12143464ebd5Sriastradh	}
12153464ebd5Sriastradh	| paramConstDecl
12163464ebd5Sriastradh	{
12173464ebd5Sriastradh	   memset(& $$, 0, sizeof($$));
12183464ebd5Sriastradh	   $$.param_binding_begin = ~0;
12193464ebd5Sriastradh	   initialize_symbol_from_const(state->prog, & $$, & $1, GL_FALSE);
12203464ebd5Sriastradh	}
12213464ebd5Sriastradh	;
12223464ebd5Sriastradh
12233464ebd5SriastradhstateMultipleItem: stateSingleItem        { memcpy($$, $1, sizeof($$)); }
12243464ebd5Sriastradh	| STATE stateMatrixRows           { memcpy($$, $2, sizeof($$)); }
12253464ebd5Sriastradh	;
12263464ebd5Sriastradh
12273464ebd5SriastradhstateSingleItem: STATE stateMaterialItem  { memcpy($$, $2, sizeof($$)); }
12283464ebd5Sriastradh	| STATE stateLightItem            { memcpy($$, $2, sizeof($$)); }
12293464ebd5Sriastradh	| STATE stateLightModelItem       { memcpy($$, $2, sizeof($$)); }
12303464ebd5Sriastradh	| STATE stateLightProdItem        { memcpy($$, $2, sizeof($$)); }
12313464ebd5Sriastradh	| STATE stateTexGenItem           { memcpy($$, $2, sizeof($$)); }
12323464ebd5Sriastradh	| STATE stateTexEnvItem           { memcpy($$, $2, sizeof($$)); }
12333464ebd5Sriastradh	| STATE stateFogItem              { memcpy($$, $2, sizeof($$)); }
12343464ebd5Sriastradh	| STATE stateClipPlaneItem        { memcpy($$, $2, sizeof($$)); }
12353464ebd5Sriastradh	| STATE statePointItem            { memcpy($$, $2, sizeof($$)); }
12363464ebd5Sriastradh	| STATE stateMatrixRow            { memcpy($$, $2, sizeof($$)); }
12373464ebd5Sriastradh	| STATE stateDepthItem            { memcpy($$, $2, sizeof($$)); }
12383464ebd5Sriastradh	;
12393464ebd5Sriastradh
12403464ebd5SriastradhstateMaterialItem: MATERIAL optFaceType stateMatProperty
12413464ebd5Sriastradh	{
12423464ebd5Sriastradh	   memset($$, 0, sizeof($$));
12433464ebd5Sriastradh	   $$[0] = STATE_MATERIAL;
12447ec681f3Smrg	   $$[1] = $3 + $2;
12457ec681f3Smrg	   $$[2] = 0;
12463464ebd5Sriastradh	}
12473464ebd5Sriastradh	;
12483464ebd5Sriastradh
12497ec681f3SmrgstateMatProperty: ambDiffSpecPropertyMaterial
12503464ebd5Sriastradh	{
12513464ebd5Sriastradh	   $$ = $1;
12523464ebd5Sriastradh	}
12533464ebd5Sriastradh	| EMISSION
12543464ebd5Sriastradh	{
12557ec681f3Smrg	   $$ = MAT_ATTRIB_FRONT_EMISSION;
12563464ebd5Sriastradh	}
12573464ebd5Sriastradh	| SHININESS
12583464ebd5Sriastradh	{
12597ec681f3Smrg	   $$ = MAT_ATTRIB_FRONT_SHININESS;
12603464ebd5Sriastradh	}
12613464ebd5Sriastradh	;
12623464ebd5Sriastradh
12633464ebd5SriastradhstateLightItem: LIGHT '[' stateLightNumber ']' stateLightProperty
12643464ebd5Sriastradh	{
12653464ebd5Sriastradh	   memset($$, 0, sizeof($$));
12663464ebd5Sriastradh	   $$[0] = STATE_LIGHT;
12673464ebd5Sriastradh	   $$[1] = $3;
12683464ebd5Sriastradh	   $$[2] = $5;
12693464ebd5Sriastradh	}
12703464ebd5Sriastradh	;
12713464ebd5Sriastradh
12727ec681f3SmrgstateLightProperty: ambDiffSpecPropertyLight
12733464ebd5Sriastradh	{
12743464ebd5Sriastradh	   $$ = $1;
12753464ebd5Sriastradh	}
12763464ebd5Sriastradh	| POSITION
12773464ebd5Sriastradh	{
12783464ebd5Sriastradh	   $$ = STATE_POSITION;
12793464ebd5Sriastradh	}
12803464ebd5Sriastradh	| ATTENUATION
12813464ebd5Sriastradh	{
12823464ebd5Sriastradh	   if (!state->ctx->Extensions.EXT_point_parameters) {
12833464ebd5Sriastradh	      yyerror(& @1, state, "GL_ARB_point_parameters not supported");
12843464ebd5Sriastradh	      YYERROR;
12853464ebd5Sriastradh	   }
12863464ebd5Sriastradh
12873464ebd5Sriastradh	   $$ = STATE_ATTENUATION;
12883464ebd5Sriastradh	}
12893464ebd5Sriastradh	| SPOT stateSpotProperty
12903464ebd5Sriastradh	{
12913464ebd5Sriastradh	   $$ = $2;
12923464ebd5Sriastradh	}
12933464ebd5Sriastradh	| HALF
12943464ebd5Sriastradh	{
12953464ebd5Sriastradh	   $$ = STATE_HALF_VECTOR;
12963464ebd5Sriastradh	}
12973464ebd5Sriastradh	;
12983464ebd5Sriastradh
12993464ebd5SriastradhstateSpotProperty: DIRECTION
13003464ebd5Sriastradh	{
13013464ebd5Sriastradh	   $$ = STATE_SPOT_DIRECTION;
13023464ebd5Sriastradh	}
13033464ebd5Sriastradh	;
13043464ebd5Sriastradh
13053464ebd5SriastradhstateLightModelItem: LIGHTMODEL stateLModProperty
13063464ebd5Sriastradh	{
13073464ebd5Sriastradh	   $$[0] = $2[0];
13083464ebd5Sriastradh	   $$[1] = $2[1];
13093464ebd5Sriastradh	}
13103464ebd5Sriastradh	;
13113464ebd5Sriastradh
13123464ebd5SriastradhstateLModProperty: AMBIENT
13133464ebd5Sriastradh	{
13143464ebd5Sriastradh	   memset($$, 0, sizeof($$));
13153464ebd5Sriastradh	   $$[0] = STATE_LIGHTMODEL_AMBIENT;
13163464ebd5Sriastradh	}
13173464ebd5Sriastradh	| optFaceType SCENECOLOR
13183464ebd5Sriastradh	{
13193464ebd5Sriastradh	   memset($$, 0, sizeof($$));
13203464ebd5Sriastradh	   $$[0] = STATE_LIGHTMODEL_SCENECOLOR;
13213464ebd5Sriastradh	   $$[1] = $1;
13223464ebd5Sriastradh	}
13233464ebd5Sriastradh	;
13243464ebd5Sriastradh
13253464ebd5SriastradhstateLightProdItem: LIGHTPROD '[' stateLightNumber ']' optFaceType stateLProdProperty
13263464ebd5Sriastradh	{
13273464ebd5Sriastradh	   memset($$, 0, sizeof($$));
13283464ebd5Sriastradh	   $$[0] = STATE_LIGHTPROD;
13293464ebd5Sriastradh	   $$[1] = $3;
13307ec681f3Smrg	   $$[2] = $6 + $5;
13317ec681f3Smrg	   $$[3] = 0;
13323464ebd5Sriastradh	}
13333464ebd5Sriastradh	;
13343464ebd5Sriastradh
13357ec681f3SmrgstateLProdProperty: ambDiffSpecPropertyMaterial;
13363464ebd5Sriastradh
13373464ebd5SriastradhstateTexEnvItem: TEXENV optLegacyTexUnitNum stateTexEnvProperty
13383464ebd5Sriastradh	{
13393464ebd5Sriastradh	   memset($$, 0, sizeof($$));
13403464ebd5Sriastradh	   $$[0] = $3;
13413464ebd5Sriastradh	   $$[1] = $2;
13423464ebd5Sriastradh	}
13433464ebd5Sriastradh	;
13443464ebd5Sriastradh
13453464ebd5SriastradhstateTexEnvProperty: COLOR
13463464ebd5Sriastradh	{
13473464ebd5Sriastradh	   $$ = STATE_TEXENV_COLOR;
13483464ebd5Sriastradh	}
13493464ebd5Sriastradh	;
13503464ebd5Sriastradh
13517ec681f3SmrgambDiffSpecPropertyMaterial: AMBIENT
13523464ebd5Sriastradh	{
13537ec681f3Smrg	   $$ = MAT_ATTRIB_FRONT_AMBIENT;
13543464ebd5Sriastradh	}
13553464ebd5Sriastradh	| DIFFUSE
13563464ebd5Sriastradh	{
13577ec681f3Smrg	   $$ = MAT_ATTRIB_FRONT_DIFFUSE;
13583464ebd5Sriastradh	}
13593464ebd5Sriastradh	| SPECULAR
13603464ebd5Sriastradh	{
13617ec681f3Smrg	   $$ = MAT_ATTRIB_FRONT_SPECULAR;
13623464ebd5Sriastradh	}
13633464ebd5Sriastradh	;
13643464ebd5Sriastradh
13657ec681f3SmrgambDiffSpecPropertyLight: AMBIENT
13667ec681f3Smrg        {
13677ec681f3Smrg           $$ = STATE_AMBIENT;
13687ec681f3Smrg        }
13697ec681f3Smrg        | DIFFUSE
13707ec681f3Smrg        {
13717ec681f3Smrg           $$ = STATE_DIFFUSE;
13727ec681f3Smrg        }
13737ec681f3Smrg        | SPECULAR
13747ec681f3Smrg        {
13757ec681f3Smrg           $$ = STATE_SPECULAR;
13767ec681f3Smrg        }
13777ec681f3Smrg        ;
13787ec681f3Smrg
13793464ebd5SriastradhstateLightNumber: INTEGER
13803464ebd5Sriastradh	{
13813464ebd5Sriastradh	   if ((unsigned) $1 >= state->MaxLights) {
13823464ebd5Sriastradh	      yyerror(& @1, state, "invalid light selector");
13833464ebd5Sriastradh	      YYERROR;
13843464ebd5Sriastradh	   }
13853464ebd5Sriastradh
13863464ebd5Sriastradh	   $$ = $1;
13873464ebd5Sriastradh	}
13883464ebd5Sriastradh	;
13893464ebd5Sriastradh
13903464ebd5SriastradhstateTexGenItem: TEXGEN optTexCoordUnitNum stateTexGenType stateTexGenCoord
13913464ebd5Sriastradh	{
13923464ebd5Sriastradh	   memset($$, 0, sizeof($$));
13933464ebd5Sriastradh	   $$[0] = STATE_TEXGEN;
13943464ebd5Sriastradh	   $$[1] = $2;
13953464ebd5Sriastradh	   $$[2] = $3 + $4;
13963464ebd5Sriastradh	}
13973464ebd5Sriastradh	;
13983464ebd5Sriastradh
13993464ebd5SriastradhstateTexGenType: EYE
14003464ebd5Sriastradh	{
14013464ebd5Sriastradh	   $$ = STATE_TEXGEN_EYE_S;
14023464ebd5Sriastradh	}
14033464ebd5Sriastradh	| OBJECT
14043464ebd5Sriastradh	{
14053464ebd5Sriastradh	   $$ = STATE_TEXGEN_OBJECT_S;
14063464ebd5Sriastradh	}
14073464ebd5Sriastradh	;
14083464ebd5SriastradhstateTexGenCoord: TEXGEN_S
14093464ebd5Sriastradh	{
14103464ebd5Sriastradh	   $$ = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S;
14113464ebd5Sriastradh	}
14123464ebd5Sriastradh	| TEXGEN_T
14133464ebd5Sriastradh	{
14143464ebd5Sriastradh	   $$ = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S;
14153464ebd5Sriastradh	}
14163464ebd5Sriastradh	| TEXGEN_R
14173464ebd5Sriastradh	{
14183464ebd5Sriastradh	   $$ = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S;
14193464ebd5Sriastradh	}
14203464ebd5Sriastradh	| TEXGEN_Q
14213464ebd5Sriastradh	{
14223464ebd5Sriastradh	   $$ = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S;
14233464ebd5Sriastradh	}
14243464ebd5Sriastradh	;
14253464ebd5Sriastradh
14263464ebd5SriastradhstateFogItem: FOG stateFogProperty
14273464ebd5Sriastradh	{
14283464ebd5Sriastradh	   memset($$, 0, sizeof($$));
14293464ebd5Sriastradh	   $$[0] = $2;
14303464ebd5Sriastradh	}
14313464ebd5Sriastradh	;
14323464ebd5Sriastradh
14333464ebd5SriastradhstateFogProperty: COLOR
14343464ebd5Sriastradh	{
14353464ebd5Sriastradh	   $$ = STATE_FOG_COLOR;
14363464ebd5Sriastradh	}
14373464ebd5Sriastradh	| PARAMS
14383464ebd5Sriastradh	{
14393464ebd5Sriastradh	   $$ = STATE_FOG_PARAMS;
14403464ebd5Sriastradh	}
14413464ebd5Sriastradh	;
14423464ebd5Sriastradh
14433464ebd5SriastradhstateClipPlaneItem: CLIP '[' stateClipPlaneNum ']' PLANE
14443464ebd5Sriastradh	{
14453464ebd5Sriastradh	   memset($$, 0, sizeof($$));
14463464ebd5Sriastradh	   $$[0] = STATE_CLIPPLANE;
14473464ebd5Sriastradh	   $$[1] = $3;
14483464ebd5Sriastradh	}
14493464ebd5Sriastradh	;
14503464ebd5Sriastradh
14513464ebd5SriastradhstateClipPlaneNum: INTEGER
14523464ebd5Sriastradh	{
14533464ebd5Sriastradh	   if ((unsigned) $1 >= state->MaxClipPlanes) {
14543464ebd5Sriastradh	      yyerror(& @1, state, "invalid clip plane selector");
14553464ebd5Sriastradh	      YYERROR;
14563464ebd5Sriastradh	   }
14573464ebd5Sriastradh
14583464ebd5Sriastradh	   $$ = $1;
14593464ebd5Sriastradh	}
14603464ebd5Sriastradh	;
14613464ebd5Sriastradh
14623464ebd5SriastradhstatePointItem: POINT_TOK statePointProperty
14633464ebd5Sriastradh	{
14643464ebd5Sriastradh	   memset($$, 0, sizeof($$));
14653464ebd5Sriastradh	   $$[0] = $2;
14663464ebd5Sriastradh	}
14673464ebd5Sriastradh	;
14683464ebd5Sriastradh
14693464ebd5SriastradhstatePointProperty: SIZE_TOK
14703464ebd5Sriastradh	{
14713464ebd5Sriastradh	   $$ = STATE_POINT_SIZE;
14723464ebd5Sriastradh	}
14733464ebd5Sriastradh	| ATTENUATION
14743464ebd5Sriastradh	{
14753464ebd5Sriastradh	   $$ = STATE_POINT_ATTENUATION;
14763464ebd5Sriastradh	}
14773464ebd5Sriastradh	;
14783464ebd5Sriastradh
14793464ebd5SriastradhstateMatrixRow: stateMatrixItem ROW '[' stateMatrixRowNum ']'
14803464ebd5Sriastradh	{
14817ec681f3Smrg	   $$[0] = $1[0] + $1[2];
14823464ebd5Sriastradh	   $$[1] = $1[1];
14833464ebd5Sriastradh	   $$[2] = $4;
14843464ebd5Sriastradh	   $$[3] = $4;
14853464ebd5Sriastradh	}
14863464ebd5Sriastradh	;
14873464ebd5Sriastradh
14883464ebd5SriastradhstateMatrixRows: stateMatrixItem optMatrixRows
14893464ebd5Sriastradh	{
14907ec681f3Smrg	   $$[0] = $1[0] + $1[2];
14913464ebd5Sriastradh	   $$[1] = $1[1];
14923464ebd5Sriastradh	   $$[2] = $2[2];
14933464ebd5Sriastradh	   $$[3] = $2[3];
14943464ebd5Sriastradh	}
14953464ebd5Sriastradh	;
14963464ebd5Sriastradh
14973464ebd5SriastradhoptMatrixRows:
14983464ebd5Sriastradh	{
14993464ebd5Sriastradh	   $$[2] = 0;
15003464ebd5Sriastradh	   $$[3] = 3;
15013464ebd5Sriastradh	}
15023464ebd5Sriastradh	| ROW '[' stateMatrixRowNum DOT_DOT stateMatrixRowNum ']'
15033464ebd5Sriastradh	{
15043464ebd5Sriastradh	   /* It seems logical that the matrix row range specifier would have
15053464ebd5Sriastradh	    * to specify a range or more than one row (i.e., $5 > $3).
15063464ebd5Sriastradh	    * However, the ARB_vertex_program spec says "a program will fail
15073464ebd5Sriastradh	    * to load if <a> is greater than <b>."  This means that $3 == $5
15083464ebd5Sriastradh	    * is valid.
15093464ebd5Sriastradh	    */
15103464ebd5Sriastradh	   if ($3 > $5) {
15113464ebd5Sriastradh	      yyerror(& @3, state, "invalid matrix row range");
15123464ebd5Sriastradh	      YYERROR;
15133464ebd5Sriastradh	   }
15143464ebd5Sriastradh
15153464ebd5Sriastradh	   $$[2] = $3;
15163464ebd5Sriastradh	   $$[3] = $5;
15173464ebd5Sriastradh	}
15183464ebd5Sriastradh	;
15193464ebd5Sriastradh
15203464ebd5SriastradhstateMatrixItem: MATRIX stateMatrixName stateOptMatModifier
15213464ebd5Sriastradh	{
15223464ebd5Sriastradh	   $$[0] = $2[0];
15233464ebd5Sriastradh	   $$[1] = $2[1];
15243464ebd5Sriastradh	   $$[2] = $3;
15253464ebd5Sriastradh	}
15263464ebd5Sriastradh	;
15273464ebd5Sriastradh
15287ec681f3SmrgstateOptMatModifier:
15293464ebd5Sriastradh	{
15307ec681f3Smrg	   $$ = STATE_MATRIX_NO_MODIFIER;
15313464ebd5Sriastradh	}
15323464ebd5Sriastradh	| stateMatModifier
15333464ebd5Sriastradh	{
15343464ebd5Sriastradh	   $$ = $1;
15353464ebd5Sriastradh	}
15363464ebd5Sriastradh	;
15373464ebd5Sriastradh
15387ec681f3SmrgstateMatModifier: INVERSE
15393464ebd5Sriastradh	{
15403464ebd5Sriastradh	   $$ = STATE_MATRIX_INVERSE;
15413464ebd5Sriastradh	}
15427ec681f3Smrg	| TRANSPOSE
15433464ebd5Sriastradh	{
15443464ebd5Sriastradh	   $$ = STATE_MATRIX_TRANSPOSE;
15453464ebd5Sriastradh	}
15463464ebd5Sriastradh	| INVTRANS
15473464ebd5Sriastradh	{
15483464ebd5Sriastradh	   $$ = STATE_MATRIX_INVTRANS;
15493464ebd5Sriastradh	}
15503464ebd5Sriastradh	;
15513464ebd5Sriastradh
15523464ebd5SriastradhstateMatrixRowNum: INTEGER
15533464ebd5Sriastradh	{
15543464ebd5Sriastradh	   if ($1 > 3) {
15553464ebd5Sriastradh	      yyerror(& @1, state, "invalid matrix row reference");
15563464ebd5Sriastradh	      YYERROR;
15573464ebd5Sriastradh	   }
15583464ebd5Sriastradh
15593464ebd5Sriastradh	   $$ = $1;
15603464ebd5Sriastradh	}
15613464ebd5Sriastradh	;
15623464ebd5Sriastradh
15633464ebd5SriastradhstateMatrixName: MODELVIEW stateOptModMatNum
15643464ebd5Sriastradh	{
15653464ebd5Sriastradh	   $$[0] = STATE_MODELVIEW_MATRIX;
15663464ebd5Sriastradh	   $$[1] = $2;
15673464ebd5Sriastradh	}
15683464ebd5Sriastradh	| PROJECTION
15693464ebd5Sriastradh	{
15703464ebd5Sriastradh	   $$[0] = STATE_PROJECTION_MATRIX;
15713464ebd5Sriastradh	   $$[1] = 0;
15723464ebd5Sriastradh	}
15733464ebd5Sriastradh	| MVP
15743464ebd5Sriastradh	{
15753464ebd5Sriastradh	   $$[0] = STATE_MVP_MATRIX;
15763464ebd5Sriastradh	   $$[1] = 0;
15773464ebd5Sriastradh	}
15783464ebd5Sriastradh	| TEXTURE optTexCoordUnitNum
15793464ebd5Sriastradh	{
15803464ebd5Sriastradh	   $$[0] = STATE_TEXTURE_MATRIX;
15813464ebd5Sriastradh	   $$[1] = $2;
15823464ebd5Sriastradh	}
15833464ebd5Sriastradh	| PALETTE '[' statePaletteMatNum ']'
15843464ebd5Sriastradh	{
15853464ebd5Sriastradh	   yyerror(& @1, state, "GL_ARB_matrix_palette not supported");
15863464ebd5Sriastradh	   YYERROR;
15873464ebd5Sriastradh	}
15883464ebd5Sriastradh	| MAT_PROGRAM '[' stateProgramMatNum ']'
15893464ebd5Sriastradh	{
15903464ebd5Sriastradh	   $$[0] = STATE_PROGRAM_MATRIX;
15913464ebd5Sriastradh	   $$[1] = $3;
15923464ebd5Sriastradh	}
15933464ebd5Sriastradh	;
15943464ebd5Sriastradh
15953464ebd5SriastradhstateOptModMatNum:
15963464ebd5Sriastradh	{
15973464ebd5Sriastradh	   $$ = 0;
15983464ebd5Sriastradh	}
15993464ebd5Sriastradh	| '[' stateModMatNum ']'
16003464ebd5Sriastradh	{
16013464ebd5Sriastradh	   $$ = $2;
16023464ebd5Sriastradh	}
16033464ebd5Sriastradh	;
16043464ebd5SriastradhstateModMatNum: INTEGER
16053464ebd5Sriastradh	{
16063464ebd5Sriastradh	   /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix
16073464ebd5Sriastradh	    * zero is valid.
16083464ebd5Sriastradh	    */
16093464ebd5Sriastradh	   if ($1 != 0) {
16103464ebd5Sriastradh	      yyerror(& @1, state, "invalid modelview matrix index");
16113464ebd5Sriastradh	      YYERROR;
16123464ebd5Sriastradh	   }
16133464ebd5Sriastradh
16143464ebd5Sriastradh	   $$ = $1;
16153464ebd5Sriastradh	}
16163464ebd5Sriastradh	;
16173464ebd5SriastradhstatePaletteMatNum: INTEGER
16183464ebd5Sriastradh	{
16193464ebd5Sriastradh	   /* Since GL_ARB_matrix_palette isn't supported, just let any value
16203464ebd5Sriastradh	    * through here.  The error will be generated later.
16213464ebd5Sriastradh	    */
16223464ebd5Sriastradh	   $$ = $1;
16233464ebd5Sriastradh	}
16243464ebd5Sriastradh	;
16253464ebd5SriastradhstateProgramMatNum: INTEGER
16263464ebd5Sriastradh	{
16273464ebd5Sriastradh	   if ((unsigned) $1 >= state->MaxProgramMatrices) {
16283464ebd5Sriastradh	      yyerror(& @1, state, "invalid program matrix selector");
16293464ebd5Sriastradh	      YYERROR;
16303464ebd5Sriastradh	   }
16313464ebd5Sriastradh
16323464ebd5Sriastradh	   $$ = $1;
16333464ebd5Sriastradh	}
16343464ebd5Sriastradh	;
16353464ebd5Sriastradh
16363464ebd5SriastradhstateDepthItem: DEPTH RANGE
16373464ebd5Sriastradh	{
16383464ebd5Sriastradh	   memset($$, 0, sizeof($$));
16393464ebd5Sriastradh	   $$[0] = STATE_DEPTH_RANGE;
16403464ebd5Sriastradh	}
16413464ebd5Sriastradh	;
16423464ebd5Sriastradh
16433464ebd5Sriastradh
16443464ebd5SriastradhprogramSingleItem: progEnvParam | progLocalParam;
16453464ebd5Sriastradh
16463464ebd5SriastradhprogramMultipleItem: progEnvParams | progLocalParams;
16473464ebd5Sriastradh
16483464ebd5SriastradhprogEnvParams: PROGRAM ENV '[' progEnvParamNums ']'
16493464ebd5Sriastradh	{
16503464ebd5Sriastradh	   memset($$, 0, sizeof($$));
16517ec681f3Smrg	   $$[0] = state->state_param_enum_env;
16527ec681f3Smrg	   $$[1] = $4[0];
16537ec681f3Smrg	   $$[2] = $4[1];
16547ec681f3Smrg           $$[3] = 0;
16553464ebd5Sriastradh	}
16563464ebd5Sriastradh	;
16573464ebd5Sriastradh
16583464ebd5SriastradhprogEnvParamNums: progEnvParamNum
16593464ebd5Sriastradh	{
16603464ebd5Sriastradh	   $$[0] = $1;
16613464ebd5Sriastradh	   $$[1] = $1;
16623464ebd5Sriastradh	}
16633464ebd5Sriastradh	| progEnvParamNum DOT_DOT progEnvParamNum
16643464ebd5Sriastradh	{
16653464ebd5Sriastradh	   $$[0] = $1;
16663464ebd5Sriastradh	   $$[1] = $3;
16673464ebd5Sriastradh	}
16683464ebd5Sriastradh	;
16693464ebd5Sriastradh
16703464ebd5SriastradhprogEnvParam: PROGRAM ENV '[' progEnvParamNum ']'
16713464ebd5Sriastradh	{
16723464ebd5Sriastradh	   memset($$, 0, sizeof($$));
16737ec681f3Smrg	   $$[0] = state->state_param_enum_env;
16747ec681f3Smrg	   $$[1] = $4;
16753464ebd5Sriastradh	   $$[2] = $4;
16767ec681f3Smrg           $$[3] = 0;
16773464ebd5Sriastradh	}
16783464ebd5Sriastradh	;
16793464ebd5Sriastradh
16803464ebd5SriastradhprogLocalParams: PROGRAM LOCAL '[' progLocalParamNums ']'
16813464ebd5Sriastradh	{
16823464ebd5Sriastradh	   memset($$, 0, sizeof($$));
16837ec681f3Smrg	   $$[0] = state->state_param_enum_local;
16847ec681f3Smrg	   $$[1] = $4[0];
16857ec681f3Smrg	   $$[2] = $4[1];
16867ec681f3Smrg           $$[3] = 0;
16873464ebd5Sriastradh	}
16883464ebd5Sriastradh
16893464ebd5SriastradhprogLocalParamNums: progLocalParamNum
16903464ebd5Sriastradh	{
16913464ebd5Sriastradh	   $$[0] = $1;
16923464ebd5Sriastradh	   $$[1] = $1;
16933464ebd5Sriastradh	}
16943464ebd5Sriastradh	| progLocalParamNum DOT_DOT progLocalParamNum
16953464ebd5Sriastradh	{
16963464ebd5Sriastradh	   $$[0] = $1;
16973464ebd5Sriastradh	   $$[1] = $3;
16983464ebd5Sriastradh	}
16993464ebd5Sriastradh	;
17003464ebd5Sriastradh
17013464ebd5SriastradhprogLocalParam: PROGRAM LOCAL '[' progLocalParamNum ']'
17023464ebd5Sriastradh	{
17033464ebd5Sriastradh	   memset($$, 0, sizeof($$));
17047ec681f3Smrg	   $$[0] = state->state_param_enum_local;
17057ec681f3Smrg	   $$[1] = $4;
17063464ebd5Sriastradh	   $$[2] = $4;
17077ec681f3Smrg           $$[3] = 0;
17083464ebd5Sriastradh	}
17093464ebd5Sriastradh	;
17103464ebd5Sriastradh
17113464ebd5SriastradhprogEnvParamNum: INTEGER
17123464ebd5Sriastradh	{
17133464ebd5Sriastradh	   if ((unsigned) $1 >= state->limits->MaxEnvParams) {
17143464ebd5Sriastradh	      yyerror(& @1, state, "invalid environment parameter reference");
17153464ebd5Sriastradh	      YYERROR;
17163464ebd5Sriastradh	   }
17173464ebd5Sriastradh	   $$ = $1;
17183464ebd5Sriastradh	}
17193464ebd5Sriastradh	;
17203464ebd5Sriastradh
17213464ebd5SriastradhprogLocalParamNum: INTEGER
17223464ebd5Sriastradh	{
17233464ebd5Sriastradh	   if ((unsigned) $1 >= state->limits->MaxLocalParams) {
17243464ebd5Sriastradh	      yyerror(& @1, state, "invalid local parameter reference");
17253464ebd5Sriastradh	      YYERROR;
17263464ebd5Sriastradh	   }
17273464ebd5Sriastradh	   $$ = $1;
17283464ebd5Sriastradh	}
17293464ebd5Sriastradh	;
17303464ebd5Sriastradh
17313464ebd5Sriastradh
17323464ebd5Sriastradh
17333464ebd5SriastradhparamConstDecl: paramConstScalarDecl | paramConstVector;
17343464ebd5SriastradhparamConstUse: paramConstScalarUse | paramConstVector;
17353464ebd5Sriastradh
17363464ebd5SriastradhparamConstScalarDecl: signedFloatConstant
17373464ebd5Sriastradh	{
17383464ebd5Sriastradh	   $$.count = 4;
1739af69d88dSmrg	   $$.data[0].f = $1;
1740af69d88dSmrg	   $$.data[1].f = $1;
1741af69d88dSmrg	   $$.data[2].f = $1;
1742af69d88dSmrg	   $$.data[3].f = $1;
17433464ebd5Sriastradh	}
17443464ebd5Sriastradh	;
17453464ebd5Sriastradh
17463464ebd5SriastradhparamConstScalarUse: REAL
17473464ebd5Sriastradh	{
17483464ebd5Sriastradh	   $$.count = 1;
1749af69d88dSmrg	   $$.data[0].f = $1;
1750af69d88dSmrg	   $$.data[1].f = $1;
1751af69d88dSmrg	   $$.data[2].f = $1;
1752af69d88dSmrg	   $$.data[3].f = $1;
17533464ebd5Sriastradh	}
17543464ebd5Sriastradh	| INTEGER
17553464ebd5Sriastradh	{
17563464ebd5Sriastradh	   $$.count = 1;
1757af69d88dSmrg	   $$.data[0].f = (float) $1;
1758af69d88dSmrg	   $$.data[1].f = (float) $1;
1759af69d88dSmrg	   $$.data[2].f = (float) $1;
1760af69d88dSmrg	   $$.data[3].f = (float) $1;
17613464ebd5Sriastradh	}
17623464ebd5Sriastradh	;
17633464ebd5Sriastradh
17643464ebd5SriastradhparamConstVector: '{' signedFloatConstant '}'
17653464ebd5Sriastradh	{
17663464ebd5Sriastradh	   $$.count = 4;
1767af69d88dSmrg	   $$.data[0].f = $2;
1768af69d88dSmrg	   $$.data[1].f = 0.0f;
1769af69d88dSmrg	   $$.data[2].f = 0.0f;
1770af69d88dSmrg	   $$.data[3].f = 1.0f;
17713464ebd5Sriastradh	}
17723464ebd5Sriastradh	| '{' signedFloatConstant ',' signedFloatConstant '}'
17733464ebd5Sriastradh	{
17743464ebd5Sriastradh	   $$.count = 4;
1775af69d88dSmrg	   $$.data[0].f = $2;
1776af69d88dSmrg	   $$.data[1].f = $4;
1777af69d88dSmrg	   $$.data[2].f = 0.0f;
1778af69d88dSmrg	   $$.data[3].f = 1.0f;
17793464ebd5Sriastradh	}
17803464ebd5Sriastradh	| '{' signedFloatConstant ',' signedFloatConstant ','
17813464ebd5Sriastradh              signedFloatConstant '}'
17823464ebd5Sriastradh	{
17833464ebd5Sriastradh	   $$.count = 4;
1784af69d88dSmrg	   $$.data[0].f = $2;
1785af69d88dSmrg	   $$.data[1].f = $4;
1786af69d88dSmrg	   $$.data[2].f = $6;
1787af69d88dSmrg	   $$.data[3].f = 1.0f;
17883464ebd5Sriastradh	}
17893464ebd5Sriastradh	| '{' signedFloatConstant ',' signedFloatConstant ','
17903464ebd5Sriastradh              signedFloatConstant ',' signedFloatConstant '}'
17913464ebd5Sriastradh	{
17923464ebd5Sriastradh	   $$.count = 4;
1793af69d88dSmrg	   $$.data[0].f = $2;
1794af69d88dSmrg	   $$.data[1].f = $4;
1795af69d88dSmrg	   $$.data[2].f = $6;
1796af69d88dSmrg	   $$.data[3].f = $8;
17973464ebd5Sriastradh	}
17983464ebd5Sriastradh	;
17993464ebd5Sriastradh
18003464ebd5SriastradhsignedFloatConstant: optionalSign REAL
18013464ebd5Sriastradh	{
18023464ebd5Sriastradh	   $$ = ($1) ? -$2 : $2;
18033464ebd5Sriastradh	}
18043464ebd5Sriastradh	| optionalSign INTEGER
18053464ebd5Sriastradh	{
18063464ebd5Sriastradh	   $$ = (float)(($1) ? -$2 : $2);
18073464ebd5Sriastradh	}
18083464ebd5Sriastradh	;
18093464ebd5Sriastradh
18103464ebd5SriastradhoptionalSign: '+'        { $$ = FALSE; }
18113464ebd5Sriastradh	| '-'            { $$ = TRUE;  }
18123464ebd5Sriastradh	|                { $$ = FALSE; }
18133464ebd5Sriastradh	;
18143464ebd5Sriastradh
181501e04c3fSmrgTEMP_statement: TEMP { $<integer>$ = $1; } varNameList
18163464ebd5Sriastradh	;
18173464ebd5Sriastradh
18183464ebd5SriastradhADDRESS_statement: ADDRESS { $<integer>$ = $1; } varNameList
18193464ebd5Sriastradh	;
18203464ebd5Sriastradh
18213464ebd5SriastradhvarNameList: varNameList ',' IDENTIFIER
18223464ebd5Sriastradh	{
18233464ebd5Sriastradh	   if (!declare_variable(state, $3, $<integer>0, & @3)) {
18243464ebd5Sriastradh	      free($3);
18253464ebd5Sriastradh	      YYERROR;
18263464ebd5Sriastradh	   }
18273464ebd5Sriastradh	}
18283464ebd5Sriastradh	| IDENTIFIER
18293464ebd5Sriastradh	{
18303464ebd5Sriastradh	   if (!declare_variable(state, $1, $<integer>0, & @1)) {
18313464ebd5Sriastradh	      free($1);
18323464ebd5Sriastradh	      YYERROR;
18333464ebd5Sriastradh	   }
18343464ebd5Sriastradh	}
18353464ebd5Sriastradh	;
18363464ebd5Sriastradh
183701e04c3fSmrgOUTPUT_statement: OUTPUT IDENTIFIER '=' resultBinding
18383464ebd5Sriastradh	{
18393464ebd5Sriastradh	   struct asm_symbol *const s =
184001e04c3fSmrg	      declare_variable(state, $2, at_output, & @2);
18413464ebd5Sriastradh
18423464ebd5Sriastradh	   if (s == NULL) {
184301e04c3fSmrg	      free($2);
18443464ebd5Sriastradh	      YYERROR;
18453464ebd5Sriastradh	   } else {
184601e04c3fSmrg	      s->output_binding = $4;
18473464ebd5Sriastradh	   }
18483464ebd5Sriastradh	}
18493464ebd5Sriastradh	;
18503464ebd5Sriastradh
18513464ebd5SriastradhresultBinding: RESULT POSITION
18523464ebd5Sriastradh	{
18533464ebd5Sriastradh	   if (state->mode == ARB_vertex) {
1854af69d88dSmrg	      $$ = VARYING_SLOT_POS;
18553464ebd5Sriastradh	   } else {
18563464ebd5Sriastradh	      yyerror(& @2, state, "invalid program result name");
18573464ebd5Sriastradh	      YYERROR;
18583464ebd5Sriastradh	   }
18593464ebd5Sriastradh	}
18603464ebd5Sriastradh	| RESULT FOGCOORD
18613464ebd5Sriastradh	{
18623464ebd5Sriastradh	   if (state->mode == ARB_vertex) {
1863af69d88dSmrg	      $$ = VARYING_SLOT_FOGC;
18643464ebd5Sriastradh	   } else {
18653464ebd5Sriastradh	      yyerror(& @2, state, "invalid program result name");
18663464ebd5Sriastradh	      YYERROR;
18673464ebd5Sriastradh	   }
18683464ebd5Sriastradh	}
18693464ebd5Sriastradh	| RESULT resultColBinding
18703464ebd5Sriastradh	{
18713464ebd5Sriastradh	   $$ = $2;
18723464ebd5Sriastradh	}
18733464ebd5Sriastradh	| RESULT POINTSIZE
18743464ebd5Sriastradh	{
18753464ebd5Sriastradh	   if (state->mode == ARB_vertex) {
1876af69d88dSmrg	      $$ = VARYING_SLOT_PSIZ;
18773464ebd5Sriastradh	   } else {
18783464ebd5Sriastradh	      yyerror(& @2, state, "invalid program result name");
18793464ebd5Sriastradh	      YYERROR;
18803464ebd5Sriastradh	   }
18813464ebd5Sriastradh	}
18823464ebd5Sriastradh	| RESULT TEXCOORD optTexCoordUnitNum
18833464ebd5Sriastradh	{
18843464ebd5Sriastradh	   if (state->mode == ARB_vertex) {
1885af69d88dSmrg	      $$ = VARYING_SLOT_TEX0 + $3;
18863464ebd5Sriastradh	   } else {
18873464ebd5Sriastradh	      yyerror(& @2, state, "invalid program result name");
18883464ebd5Sriastradh	      YYERROR;
18893464ebd5Sriastradh	   }
18903464ebd5Sriastradh	}
18913464ebd5Sriastradh	| RESULT DEPTH
18923464ebd5Sriastradh	{
18933464ebd5Sriastradh	   if (state->mode == ARB_fragment) {
18943464ebd5Sriastradh	      $$ = FRAG_RESULT_DEPTH;
18953464ebd5Sriastradh	   } else {
18963464ebd5Sriastradh	      yyerror(& @2, state, "invalid program result name");
18973464ebd5Sriastradh	      YYERROR;
18983464ebd5Sriastradh	   }
18993464ebd5Sriastradh	}
19003464ebd5Sriastradh	;
19013464ebd5Sriastradh
19023464ebd5SriastradhresultColBinding: COLOR optResultFaceType optResultColorType
19033464ebd5Sriastradh	{
19043464ebd5Sriastradh	   $$ = $2 + $3;
19053464ebd5Sriastradh	}
19063464ebd5Sriastradh	;
19073464ebd5Sriastradh
19083464ebd5SriastradhoptResultFaceType:
19093464ebd5Sriastradh	{
19103464ebd5Sriastradh	   if (state->mode == ARB_vertex) {
1911af69d88dSmrg	      $$ = VARYING_SLOT_COL0;
19123464ebd5Sriastradh	   } else {
19133464ebd5Sriastradh	      if (state->option.DrawBuffers)
19143464ebd5Sriastradh		 $$ = FRAG_RESULT_DATA0;
19153464ebd5Sriastradh	      else
19163464ebd5Sriastradh		 $$ = FRAG_RESULT_COLOR;
19173464ebd5Sriastradh	   }
19183464ebd5Sriastradh	}
19193464ebd5Sriastradh	| '[' INTEGER ']'
19203464ebd5Sriastradh	{
19213464ebd5Sriastradh	   if (state->mode == ARB_vertex) {
19223464ebd5Sriastradh	      yyerror(& @1, state, "invalid program result name");
19233464ebd5Sriastradh	      YYERROR;
19243464ebd5Sriastradh	   } else {
19253464ebd5Sriastradh	      if (!state->option.DrawBuffers) {
19263464ebd5Sriastradh		 /* From the ARB_draw_buffers spec (same text exists
19273464ebd5Sriastradh		  * for ATI_draw_buffers):
19283464ebd5Sriastradh		  *
19293464ebd5Sriastradh		  *     If this option is not specified, a fragment
19303464ebd5Sriastradh		  *     program that attempts to bind
19313464ebd5Sriastradh		  *     "result.color[n]" will fail to load, and only
19323464ebd5Sriastradh		  *     "result.color" will be allowed.
19333464ebd5Sriastradh		  */
19343464ebd5Sriastradh		 yyerror(& @1, state,
19353464ebd5Sriastradh			 "result.color[] used without "
19363464ebd5Sriastradh			 "`OPTION ARB_draw_buffers' or "
19373464ebd5Sriastradh			 "`OPTION ATI_draw_buffers'");
19383464ebd5Sriastradh		 YYERROR;
19393464ebd5Sriastradh	      } else if ($2 >= state->MaxDrawBuffers) {
19403464ebd5Sriastradh		 yyerror(& @1, state,
19413464ebd5Sriastradh			 "result.color[] exceeds MAX_DRAW_BUFFERS_ARB");
19423464ebd5Sriastradh		 YYERROR;
19433464ebd5Sriastradh	      }
19443464ebd5Sriastradh	      $$ = FRAG_RESULT_DATA0 + $2;
19453464ebd5Sriastradh	   }
19463464ebd5Sriastradh	}
19473464ebd5Sriastradh	| FRONT
19483464ebd5Sriastradh	{
19493464ebd5Sriastradh	   if (state->mode == ARB_vertex) {
1950af69d88dSmrg	      $$ = VARYING_SLOT_COL0;
19513464ebd5Sriastradh	   } else {
19523464ebd5Sriastradh	      yyerror(& @1, state, "invalid program result name");
19533464ebd5Sriastradh	      YYERROR;
19543464ebd5Sriastradh	   }
19553464ebd5Sriastradh	}
19563464ebd5Sriastradh	| BACK
19573464ebd5Sriastradh	{
19583464ebd5Sriastradh	   if (state->mode == ARB_vertex) {
1959af69d88dSmrg	      $$ = VARYING_SLOT_BFC0;
19603464ebd5Sriastradh	   } else {
19613464ebd5Sriastradh	      yyerror(& @1, state, "invalid program result name");
19623464ebd5Sriastradh	      YYERROR;
19633464ebd5Sriastradh	   }
19643464ebd5Sriastradh	}
19653464ebd5Sriastradh	;
19663464ebd5Sriastradh
19673464ebd5SriastradhoptResultColorType:
19683464ebd5Sriastradh	{
19697ec681f3Smrg	   $$ = 0;
19703464ebd5Sriastradh	}
19713464ebd5Sriastradh	| PRIMARY
19723464ebd5Sriastradh	{
19733464ebd5Sriastradh	   if (state->mode == ARB_vertex) {
19743464ebd5Sriastradh	      $$ = 0;
19753464ebd5Sriastradh	   } else {
19763464ebd5Sriastradh	      yyerror(& @1, state, "invalid program result name");
19773464ebd5Sriastradh	      YYERROR;
19783464ebd5Sriastradh	   }
19793464ebd5Sriastradh	}
19803464ebd5Sriastradh	| SECONDARY
19813464ebd5Sriastradh	{
19823464ebd5Sriastradh	   if (state->mode == ARB_vertex) {
19833464ebd5Sriastradh	      $$ = 1;
19843464ebd5Sriastradh	   } else {
19853464ebd5Sriastradh	      yyerror(& @1, state, "invalid program result name");
19863464ebd5Sriastradh	      YYERROR;
19873464ebd5Sriastradh	   }
19883464ebd5Sriastradh	}
19893464ebd5Sriastradh	;
19903464ebd5Sriastradh
19913464ebd5SriastradhoptFaceType:    { $$ = 0; }
19923464ebd5Sriastradh	| FRONT	{ $$ = 0; }
19933464ebd5Sriastradh	| BACK  { $$ = 1; }
19943464ebd5Sriastradh	;
19953464ebd5Sriastradh
19963464ebd5SriastradhoptColorType:       { $$ = 0; }
19973464ebd5Sriastradh	| PRIMARY   { $$ = 0; }
19983464ebd5Sriastradh	| SECONDARY { $$ = 1; }
19993464ebd5Sriastradh	;
20003464ebd5Sriastradh
20013464ebd5SriastradhoptTexCoordUnitNum:                { $$ = 0; }
20023464ebd5Sriastradh	| '[' texCoordUnitNum ']'  { $$ = $2; }
20033464ebd5Sriastradh	;
20043464ebd5Sriastradh
20053464ebd5SriastradhoptTexImageUnitNum:                { $$ = 0; }
20063464ebd5Sriastradh	| '[' texImageUnitNum ']'  { $$ = $2; }
20073464ebd5Sriastradh	;
20083464ebd5Sriastradh
20093464ebd5SriastradhoptLegacyTexUnitNum:               { $$ = 0; }
20103464ebd5Sriastradh	| '[' legacyTexUnitNum ']' { $$ = $2; }
20113464ebd5Sriastradh	;
20123464ebd5Sriastradh
20133464ebd5SriastradhtexCoordUnitNum: INTEGER
20143464ebd5Sriastradh	{
20153464ebd5Sriastradh	   if ((unsigned) $1 >= state->MaxTextureCoordUnits) {
20163464ebd5Sriastradh	      yyerror(& @1, state, "invalid texture coordinate unit selector");
20173464ebd5Sriastradh	      YYERROR;
20183464ebd5Sriastradh	   }
20193464ebd5Sriastradh
20203464ebd5Sriastradh	   $$ = $1;
20213464ebd5Sriastradh	}
20223464ebd5Sriastradh	;
20233464ebd5Sriastradh
20243464ebd5SriastradhtexImageUnitNum: INTEGER
20253464ebd5Sriastradh	{
20263464ebd5Sriastradh	   if ((unsigned) $1 >= state->MaxTextureImageUnits) {
20273464ebd5Sriastradh	      yyerror(& @1, state, "invalid texture image unit selector");
20283464ebd5Sriastradh	      YYERROR;
20293464ebd5Sriastradh	   }
20303464ebd5Sriastradh
20313464ebd5Sriastradh	   $$ = $1;
20323464ebd5Sriastradh	}
20333464ebd5Sriastradh	;
20343464ebd5Sriastradh
20353464ebd5SriastradhlegacyTexUnitNum: INTEGER
20363464ebd5Sriastradh	{
20373464ebd5Sriastradh	   if ((unsigned) $1 >= state->MaxTextureUnits) {
20383464ebd5Sriastradh	      yyerror(& @1, state, "invalid texture unit selector");
20393464ebd5Sriastradh	      YYERROR;
20403464ebd5Sriastradh	   }
20413464ebd5Sriastradh
20423464ebd5Sriastradh	   $$ = $1;
20433464ebd5Sriastradh	}
20443464ebd5Sriastradh	;
20453464ebd5Sriastradh
20463464ebd5SriastradhALIAS_statement: ALIAS IDENTIFIER '=' USED_IDENTIFIER
20473464ebd5Sriastradh	{
20483464ebd5Sriastradh	   struct asm_symbol *exist = (struct asm_symbol *)
204901e04c3fSmrg              _mesa_symbol_table_find_symbol(state->st, $2);
20503464ebd5Sriastradh	   struct asm_symbol *target = (struct asm_symbol *)
205101e04c3fSmrg              _mesa_symbol_table_find_symbol(state->st, $4);
20523464ebd5Sriastradh
20533464ebd5Sriastradh	   free($4);
20543464ebd5Sriastradh
20553464ebd5Sriastradh	   if (exist != NULL) {
20563464ebd5Sriastradh	      char m[1000];
20577ec681f3Smrg	      snprintf(m, sizeof(m), "redeclared identifier: %s", $2);
20583464ebd5Sriastradh	      free($2);
20593464ebd5Sriastradh	      yyerror(& @2, state, m);
20603464ebd5Sriastradh	      YYERROR;
20613464ebd5Sriastradh	   } else if (target == NULL) {
20623464ebd5Sriastradh	      free($2);
20633464ebd5Sriastradh	      yyerror(& @4, state,
20643464ebd5Sriastradh		      "undefined variable binding in ALIAS statement");
20653464ebd5Sriastradh	      YYERROR;
20663464ebd5Sriastradh	   } else {
206701e04c3fSmrg              _mesa_symbol_table_add_symbol(state->st, $2, target);
20683464ebd5Sriastradh	   }
20693464ebd5Sriastradh	}
20703464ebd5Sriastradh	;
20713464ebd5Sriastradh
20723464ebd5Sriastradhstring: IDENTIFIER
20733464ebd5Sriastradh	| USED_IDENTIFIER
20743464ebd5Sriastradh	;
20753464ebd5Sriastradh
20763464ebd5Sriastradh%%
20773464ebd5Sriastradh
20783464ebd5Sriastradhvoid
20793464ebd5Sriastradhasm_instruction_set_operands(struct asm_instruction *inst,
20803464ebd5Sriastradh			     const struct prog_dst_register *dst,
20813464ebd5Sriastradh			     const struct asm_src_register *src0,
20823464ebd5Sriastradh			     const struct asm_src_register *src1,
20833464ebd5Sriastradh			     const struct asm_src_register *src2)
20843464ebd5Sriastradh{
20853464ebd5Sriastradh   /* In the core ARB extensions only the KIL instruction doesn't have a
20863464ebd5Sriastradh    * destination register.
20873464ebd5Sriastradh    */
20883464ebd5Sriastradh   if (dst == NULL) {
20893464ebd5Sriastradh      init_dst_reg(& inst->Base.DstReg);
20903464ebd5Sriastradh   } else {
20913464ebd5Sriastradh      inst->Base.DstReg = *dst;
20923464ebd5Sriastradh   }
20933464ebd5Sriastradh
20943464ebd5Sriastradh   if (src0 != NULL) {
20953464ebd5Sriastradh      inst->Base.SrcReg[0] = src0->Base;
20963464ebd5Sriastradh      inst->SrcReg[0] = *src0;
20973464ebd5Sriastradh   } else {
20983464ebd5Sriastradh      init_src_reg(& inst->SrcReg[0]);
20993464ebd5Sriastradh   }
21003464ebd5Sriastradh
21013464ebd5Sriastradh   if (src1 != NULL) {
21023464ebd5Sriastradh      inst->Base.SrcReg[1] = src1->Base;
21033464ebd5Sriastradh      inst->SrcReg[1] = *src1;
21043464ebd5Sriastradh   } else {
21053464ebd5Sriastradh      init_src_reg(& inst->SrcReg[1]);
21063464ebd5Sriastradh   }
21073464ebd5Sriastradh
21083464ebd5Sriastradh   if (src2 != NULL) {
21093464ebd5Sriastradh      inst->Base.SrcReg[2] = src2->Base;
21103464ebd5Sriastradh      inst->SrcReg[2] = *src2;
21113464ebd5Sriastradh   } else {
21123464ebd5Sriastradh      init_src_reg(& inst->SrcReg[2]);
21133464ebd5Sriastradh   }
21143464ebd5Sriastradh}
21153464ebd5Sriastradh
21163464ebd5Sriastradh
21173464ebd5Sriastradhstruct asm_instruction *
211801e04c3fSmrgasm_instruction_ctor(enum prog_opcode op,
21193464ebd5Sriastradh		     const struct prog_dst_register *dst,
21203464ebd5Sriastradh		     const struct asm_src_register *src0,
21213464ebd5Sriastradh		     const struct asm_src_register *src1,
21223464ebd5Sriastradh		     const struct asm_src_register *src2)
21233464ebd5Sriastradh{
21243464ebd5Sriastradh   struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
21253464ebd5Sriastradh
21263464ebd5Sriastradh   if (inst) {
21273464ebd5Sriastradh      _mesa_init_instructions(& inst->Base, 1);
21283464ebd5Sriastradh      inst->Base.Opcode = op;
21293464ebd5Sriastradh
21303464ebd5Sriastradh      asm_instruction_set_operands(inst, dst, src0, src1, src2);
21313464ebd5Sriastradh   }
21323464ebd5Sriastradh
21333464ebd5Sriastradh   return inst;
21343464ebd5Sriastradh}
21353464ebd5Sriastradh
21363464ebd5Sriastradh
21373464ebd5Sriastradhstruct asm_instruction *
21383464ebd5Sriastradhasm_instruction_copy_ctor(const struct prog_instruction *base,
21393464ebd5Sriastradh			  const struct prog_dst_register *dst,
21403464ebd5Sriastradh			  const struct asm_src_register *src0,
21413464ebd5Sriastradh			  const struct asm_src_register *src1,
21423464ebd5Sriastradh			  const struct asm_src_register *src2)
21433464ebd5Sriastradh{
21443464ebd5Sriastradh   struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
21453464ebd5Sriastradh
21463464ebd5Sriastradh   if (inst) {
21473464ebd5Sriastradh      _mesa_init_instructions(& inst->Base, 1);
21483464ebd5Sriastradh      inst->Base.Opcode = base->Opcode;
214901e04c3fSmrg      inst->Base.Saturate = base->Saturate;
21503464ebd5Sriastradh
21513464ebd5Sriastradh      asm_instruction_set_operands(inst, dst, src0, src1, src2);
21523464ebd5Sriastradh   }
21533464ebd5Sriastradh
21543464ebd5Sriastradh   return inst;
21553464ebd5Sriastradh}
21563464ebd5Sriastradh
21573464ebd5Sriastradh
21583464ebd5Sriastradhvoid
21593464ebd5Sriastradhinit_dst_reg(struct prog_dst_register *r)
21603464ebd5Sriastradh{
21613464ebd5Sriastradh   memset(r, 0, sizeof(*r));
21623464ebd5Sriastradh   r->File = PROGRAM_UNDEFINED;
21633464ebd5Sriastradh   r->WriteMask = WRITEMASK_XYZW;
21643464ebd5Sriastradh}
21653464ebd5Sriastradh
21663464ebd5Sriastradh
21673464ebd5Sriastradh/** Like init_dst_reg() but set the File and Index fields. */
21683464ebd5Sriastradhvoid
21693464ebd5Sriastradhset_dst_reg(struct prog_dst_register *r, gl_register_file file, GLint index)
21703464ebd5Sriastradh{
21713464ebd5Sriastradh   const GLint maxIndex = 1 << INST_INDEX_BITS;
21723464ebd5Sriastradh   const GLint minIndex = 0;
217301e04c3fSmrg   assert(index >= minIndex);
21743464ebd5Sriastradh   (void) minIndex;
217501e04c3fSmrg   assert(index <= maxIndex);
21763464ebd5Sriastradh   (void) maxIndex;
217701e04c3fSmrg   assert(file == PROGRAM_TEMPORARY ||
21783464ebd5Sriastradh	  file == PROGRAM_ADDRESS ||
21793464ebd5Sriastradh	  file == PROGRAM_OUTPUT);
21803464ebd5Sriastradh   memset(r, 0, sizeof(*r));
21813464ebd5Sriastradh   r->File = file;
21823464ebd5Sriastradh   r->Index = index;
21833464ebd5Sriastradh   r->WriteMask = WRITEMASK_XYZW;
21843464ebd5Sriastradh}
21853464ebd5Sriastradh
21863464ebd5Sriastradh
21873464ebd5Sriastradhvoid
21883464ebd5Sriastradhinit_src_reg(struct asm_src_register *r)
21893464ebd5Sriastradh{
21903464ebd5Sriastradh   memset(r, 0, sizeof(*r));
21913464ebd5Sriastradh   r->Base.File = PROGRAM_UNDEFINED;
21923464ebd5Sriastradh   r->Base.Swizzle = SWIZZLE_NOOP;
21933464ebd5Sriastradh   r->Symbol = NULL;
21943464ebd5Sriastradh}
21953464ebd5Sriastradh
21963464ebd5Sriastradh
21973464ebd5Sriastradh/** Like init_src_reg() but set the File and Index fields.
21983464ebd5Sriastradh * \return GL_TRUE if a valid src register, GL_FALSE otherwise
21993464ebd5Sriastradh */
22003464ebd5Sriastradhvoid
22013464ebd5Sriastradhset_src_reg(struct asm_src_register *r, gl_register_file file, GLint index)
22023464ebd5Sriastradh{
22033464ebd5Sriastradh   set_src_reg_swz(r, file, index, SWIZZLE_XYZW);
22043464ebd5Sriastradh}
22053464ebd5Sriastradh
22063464ebd5Sriastradh
22073464ebd5Sriastradhvoid
22083464ebd5Sriastradhset_src_reg_swz(struct asm_src_register *r, gl_register_file file, GLint index,
22093464ebd5Sriastradh                GLuint swizzle)
22103464ebd5Sriastradh{
22113464ebd5Sriastradh   const GLint maxIndex = (1 << INST_INDEX_BITS) - 1;
22123464ebd5Sriastradh   const GLint minIndex = -(1 << INST_INDEX_BITS);
221301e04c3fSmrg   assert(file < PROGRAM_FILE_MAX);
221401e04c3fSmrg   assert(index >= minIndex);
22153464ebd5Sriastradh   (void) minIndex;
221601e04c3fSmrg   assert(index <= maxIndex);
22173464ebd5Sriastradh   (void) maxIndex;
22183464ebd5Sriastradh   memset(r, 0, sizeof(*r));
22193464ebd5Sriastradh   r->Base.File = file;
22203464ebd5Sriastradh   r->Base.Index = index;
22213464ebd5Sriastradh   r->Base.Swizzle = swizzle;
22223464ebd5Sriastradh   r->Symbol = NULL;
22233464ebd5Sriastradh}
22243464ebd5Sriastradh
22253464ebd5Sriastradh
22263464ebd5Sriastradh/**
22273464ebd5Sriastradh * Validate the set of inputs used by a program
22283464ebd5Sriastradh *
22293464ebd5Sriastradh * Validates that legal sets of inputs are used by the program.  In this case
22303464ebd5Sriastradh * "used" included both reading the input or binding the input to a name using
22313464ebd5Sriastradh * the \c ATTRIB command.
22323464ebd5Sriastradh *
22333464ebd5Sriastradh * \return
22343464ebd5Sriastradh * \c TRUE if the combination of inputs used is valid, \c FALSE otherwise.
22353464ebd5Sriastradh */
22363464ebd5Sriastradhint
22373464ebd5Sriastradhvalidate_inputs(struct YYLTYPE *locp, struct asm_parser_state *state)
22383464ebd5Sriastradh{
223901e04c3fSmrg   const GLbitfield64 inputs = state->prog->info.inputs_read | state->InputsBound;
224001e04c3fSmrg   GLbitfield ff_inputs = 0;
22413464ebd5Sriastradh
224201e04c3fSmrg   /* Since Mesa internal attribute indices are different from
224301e04c3fSmrg    * how NV_vertex_program defines attribute aliasing, we have to construct
224401e04c3fSmrg    * a separate usage mask based on how the aliasing is defined.
224501e04c3fSmrg    *
224601e04c3fSmrg    * Note that attribute aliasing is optional if NV_vertex_program is
224701e04c3fSmrg    * unsupported.
224801e04c3fSmrg    */
224901e04c3fSmrg   if (inputs & VERT_BIT_POS)
225001e04c3fSmrg      ff_inputs |= 1 << 0;
225101e04c3fSmrg   if (inputs & VERT_BIT_NORMAL)
225201e04c3fSmrg      ff_inputs |= 1 << 2;
225301e04c3fSmrg   if (inputs & VERT_BIT_COLOR0)
225401e04c3fSmrg      ff_inputs |= 1 << 3;
225501e04c3fSmrg   if (inputs & VERT_BIT_COLOR1)
225601e04c3fSmrg      ff_inputs |= 1 << 4;
225701e04c3fSmrg   if (inputs & VERT_BIT_FOG)
225801e04c3fSmrg      ff_inputs |= 1 << 5;
225901e04c3fSmrg
226001e04c3fSmrg   ff_inputs |= ((inputs & VERT_BIT_TEX_ALL) >> VERT_ATTRIB_TEX0) << 8;
226101e04c3fSmrg
226201e04c3fSmrg   if ((ff_inputs & (inputs >> VERT_ATTRIB_GENERIC0)) != 0) {
22633464ebd5Sriastradh      yyerror(locp, state, "illegal use of generic attribute and name attribute");
22643464ebd5Sriastradh      return 0;
22653464ebd5Sriastradh   }
22663464ebd5Sriastradh
22673464ebd5Sriastradh   return 1;
22683464ebd5Sriastradh}
22693464ebd5Sriastradh
22703464ebd5Sriastradh
22713464ebd5Sriastradhstruct asm_symbol *
22723464ebd5Sriastradhdeclare_variable(struct asm_parser_state *state, char *name, enum asm_type t,
22733464ebd5Sriastradh		 struct YYLTYPE *locp)
22743464ebd5Sriastradh{
22753464ebd5Sriastradh   struct asm_symbol *s = NULL;
22763464ebd5Sriastradh   struct asm_symbol *exist = (struct asm_symbol *)
227701e04c3fSmrg      _mesa_symbol_table_find_symbol(state->st, name);
22783464ebd5Sriastradh
22793464ebd5Sriastradh
22803464ebd5Sriastradh   if (exist != NULL) {
22813464ebd5Sriastradh      yyerror(locp, state, "redeclared identifier");
22823464ebd5Sriastradh   } else {
22833464ebd5Sriastradh      s = calloc(1, sizeof(struct asm_symbol));
22843464ebd5Sriastradh      s->name = name;
22853464ebd5Sriastradh      s->type = t;
22863464ebd5Sriastradh
22873464ebd5Sriastradh      switch (t) {
22883464ebd5Sriastradh      case at_temp:
228901e04c3fSmrg         if (state->prog->arb.NumTemporaries >= state->limits->MaxTemps) {
22903464ebd5Sriastradh	    yyerror(locp, state, "too many temporaries declared");
22913464ebd5Sriastradh	    free(s);
22923464ebd5Sriastradh	    return NULL;
22933464ebd5Sriastradh	 }
22943464ebd5Sriastradh
229501e04c3fSmrg         s->temp_binding = state->prog->arb.NumTemporaries;
229601e04c3fSmrg         state->prog->arb.NumTemporaries++;
22973464ebd5Sriastradh	 break;
22983464ebd5Sriastradh
22993464ebd5Sriastradh      case at_address:
230001e04c3fSmrg         if (state->prog->arb.NumAddressRegs >=
230101e04c3fSmrg             state->limits->MaxAddressRegs) {
23023464ebd5Sriastradh	    yyerror(locp, state, "too many address registers declared");
23033464ebd5Sriastradh	    free(s);
23043464ebd5Sriastradh	    return NULL;
23053464ebd5Sriastradh	 }
23063464ebd5Sriastradh
23073464ebd5Sriastradh	 /* FINISHME: Add support for multiple address registers.
23083464ebd5Sriastradh	  */
230901e04c3fSmrg         state->prog->arb.NumAddressRegs++;
23103464ebd5Sriastradh	 break;
23113464ebd5Sriastradh
23123464ebd5Sriastradh      default:
23133464ebd5Sriastradh	 break;
23143464ebd5Sriastradh      }
23153464ebd5Sriastradh
231601e04c3fSmrg      _mesa_symbol_table_add_symbol(state->st, s->name, s);
23173464ebd5Sriastradh      s->next = state->sym;
23183464ebd5Sriastradh      state->sym = s;
23193464ebd5Sriastradh   }
23203464ebd5Sriastradh
23213464ebd5Sriastradh   return s;
23223464ebd5Sriastradh}
23233464ebd5Sriastradh
23243464ebd5Sriastradh
23253464ebd5Sriastradhint add_state_reference(struct gl_program_parameter_list *param_list,
232601e04c3fSmrg			const gl_state_index16 tokens[STATE_LENGTH])
23273464ebd5Sriastradh{
23283464ebd5Sriastradh   const GLuint size = 4; /* XXX fix */
23293464ebd5Sriastradh   char *name;
23303464ebd5Sriastradh   GLint index;
23313464ebd5Sriastradh
23323464ebd5Sriastradh   name = _mesa_program_state_string(tokens);
23333464ebd5Sriastradh   index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name,
233401e04c3fSmrg                               size, GL_NONE, NULL, tokens, true);
23353464ebd5Sriastradh   param_list->StateFlags |= _mesa_program_state_flags(tokens);
23363464ebd5Sriastradh
23373464ebd5Sriastradh   /* free name string here since we duplicated it in add_parameter() */
23383464ebd5Sriastradh   free(name);
23393464ebd5Sriastradh
23403464ebd5Sriastradh   return index;
23413464ebd5Sriastradh}
23423464ebd5Sriastradh
23433464ebd5Sriastradh
23443464ebd5Sriastradhint
23453464ebd5Sriastradhinitialize_symbol_from_state(struct gl_program *prog,
23467ec681f3Smrg			     struct asm_symbol *param_var,
234701e04c3fSmrg			     const gl_state_index16 tokens[STATE_LENGTH])
23483464ebd5Sriastradh{
23493464ebd5Sriastradh   int idx = -1;
235001e04c3fSmrg   gl_state_index16 state_tokens[STATE_LENGTH];
23513464ebd5Sriastradh
23523464ebd5Sriastradh
23533464ebd5Sriastradh   memcpy(state_tokens, tokens, sizeof(state_tokens));
23543464ebd5Sriastradh
23553464ebd5Sriastradh   param_var->type = at_param;
23563464ebd5Sriastradh   param_var->param_binding_type = PROGRAM_STATE_VAR;
23573464ebd5Sriastradh
23583464ebd5Sriastradh   /* If we are adding a STATE_MATRIX that has multiple rows, we need to
23593464ebd5Sriastradh    * unroll it and call add_state_reference() for each row
23603464ebd5Sriastradh    */
23617ec681f3Smrg   if (state_tokens[0] >= STATE_MODELVIEW_MATRIX &&
23627ec681f3Smrg       state_tokens[0] <= STATE_PROGRAM_MATRIX_INVTRANS
23633464ebd5Sriastradh       && (state_tokens[2] != state_tokens[3])) {
23643464ebd5Sriastradh      int row;
23653464ebd5Sriastradh      const int first_row = state_tokens[2];
23663464ebd5Sriastradh      const int last_row = state_tokens[3];
23673464ebd5Sriastradh
23683464ebd5Sriastradh      for (row = first_row; row <= last_row; row++) {
23693464ebd5Sriastradh	 state_tokens[2] = state_tokens[3] = row;
23703464ebd5Sriastradh
23713464ebd5Sriastradh	 idx = add_state_reference(prog->Parameters, state_tokens);
23723464ebd5Sriastradh	 if (param_var->param_binding_begin == ~0U) {
23733464ebd5Sriastradh	    param_var->param_binding_begin = idx;
23743464ebd5Sriastradh            param_var->param_binding_swizzle = SWIZZLE_XYZW;
23753464ebd5Sriastradh         }
23763464ebd5Sriastradh
23773464ebd5Sriastradh	 param_var->param_binding_length++;
23783464ebd5Sriastradh      }
23793464ebd5Sriastradh   }
23803464ebd5Sriastradh   else {
23813464ebd5Sriastradh      idx = add_state_reference(prog->Parameters, state_tokens);
23823464ebd5Sriastradh      if (param_var->param_binding_begin == ~0U) {
23833464ebd5Sriastradh	 param_var->param_binding_begin = idx;
23843464ebd5Sriastradh         param_var->param_binding_swizzle = SWIZZLE_XYZW;
23853464ebd5Sriastradh      }
23863464ebd5Sriastradh      param_var->param_binding_length++;
23873464ebd5Sriastradh   }
23883464ebd5Sriastradh
23893464ebd5Sriastradh   return idx;
23903464ebd5Sriastradh}
23913464ebd5Sriastradh
23923464ebd5Sriastradh
23933464ebd5Sriastradhint
23943464ebd5Sriastradhinitialize_symbol_from_param(struct gl_program *prog,
23957ec681f3Smrg			     struct asm_symbol *param_var,
239601e04c3fSmrg			     const gl_state_index16 tokens[STATE_LENGTH])
23973464ebd5Sriastradh{
23983464ebd5Sriastradh   int idx = -1;
239901e04c3fSmrg   gl_state_index16 state_tokens[STATE_LENGTH];
24003464ebd5Sriastradh
24013464ebd5Sriastradh
24023464ebd5Sriastradh   memcpy(state_tokens, tokens, sizeof(state_tokens));
24033464ebd5Sriastradh
24047ec681f3Smrg   assert(state_tokens[0] == STATE_VERTEX_PROGRAM_ENV ||
24057ec681f3Smrg          state_tokens[0] == STATE_VERTEX_PROGRAM_LOCAL ||
24067ec681f3Smrg          state_tokens[0] == STATE_FRAGMENT_PROGRAM_ENV ||
24077ec681f3Smrg          state_tokens[0] == STATE_FRAGMENT_PROGRAM_LOCAL);
24083464ebd5Sriastradh
24093464ebd5Sriastradh   /*
24103464ebd5Sriastradh    * The param type is STATE_VAR.  The program parameter entry will
24113464ebd5Sriastradh    * effectively be a pointer into the LOCAL or ENV parameter array.
24123464ebd5Sriastradh    */
24133464ebd5Sriastradh   param_var->type = at_param;
24143464ebd5Sriastradh   param_var->param_binding_type = PROGRAM_STATE_VAR;
24153464ebd5Sriastradh
24163464ebd5Sriastradh   /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements,
24173464ebd5Sriastradh    * we need to unroll it and call add_state_reference() for each row
24183464ebd5Sriastradh    */
24197ec681f3Smrg   if (state_tokens[1] != state_tokens[2]) {
24203464ebd5Sriastradh      int row;
24217ec681f3Smrg      const int first_row = state_tokens[1];
24227ec681f3Smrg      const int last_row = state_tokens[2];
24233464ebd5Sriastradh
24243464ebd5Sriastradh      for (row = first_row; row <= last_row; row++) {
24257ec681f3Smrg	 state_tokens[1] = state_tokens[2] = row;
24263464ebd5Sriastradh
24273464ebd5Sriastradh	 idx = add_state_reference(prog->Parameters, state_tokens);
24283464ebd5Sriastradh	 if (param_var->param_binding_begin == ~0U) {
24293464ebd5Sriastradh	    param_var->param_binding_begin = idx;
24303464ebd5Sriastradh            param_var->param_binding_swizzle = SWIZZLE_XYZW;
24313464ebd5Sriastradh         }
24323464ebd5Sriastradh	 param_var->param_binding_length++;
24333464ebd5Sriastradh      }
24343464ebd5Sriastradh   }
24353464ebd5Sriastradh   else {
24363464ebd5Sriastradh      idx = add_state_reference(prog->Parameters, state_tokens);
24373464ebd5Sriastradh      if (param_var->param_binding_begin == ~0U) {
24383464ebd5Sriastradh	 param_var->param_binding_begin = idx;
24393464ebd5Sriastradh         param_var->param_binding_swizzle = SWIZZLE_XYZW;
24403464ebd5Sriastradh      }
24413464ebd5Sriastradh      param_var->param_binding_length++;
24423464ebd5Sriastradh   }
24433464ebd5Sriastradh
24443464ebd5Sriastradh   return idx;
24453464ebd5Sriastradh}
24463464ebd5Sriastradh
24473464ebd5Sriastradh
24483464ebd5Sriastradh/**
24493464ebd5Sriastradh * Put a float/vector constant/literal into the parameter list.
24503464ebd5Sriastradh * \param param_var  returns info about the parameter/constant's location,
24513464ebd5Sriastradh *                   binding, type, etc.
24523464ebd5Sriastradh * \param vec  the vector/constant to add
24533464ebd5Sriastradh * \param allowSwizzle  if true, try to consolidate constants which only differ
24543464ebd5Sriastradh *                      by a swizzle.  We don't want to do this when building
24553464ebd5Sriastradh *                      arrays of constants that may be indexed indirectly.
24563464ebd5Sriastradh * \return index of the constant in the parameter list.
24573464ebd5Sriastradh */
24583464ebd5Sriastradhint
24593464ebd5Sriastradhinitialize_symbol_from_const(struct gl_program *prog,
24607ec681f3Smrg			     struct asm_symbol *param_var,
24613464ebd5Sriastradh			     const struct asm_vector *vec,
24623464ebd5Sriastradh                             GLboolean allowSwizzle)
24633464ebd5Sriastradh{
24643464ebd5Sriastradh   unsigned swizzle;
24653464ebd5Sriastradh   const int idx = _mesa_add_unnamed_constant(prog->Parameters,
24663464ebd5Sriastradh                                              vec->data, vec->count,
24673464ebd5Sriastradh                                              allowSwizzle ? &swizzle : NULL);
24683464ebd5Sriastradh
24693464ebd5Sriastradh   param_var->type = at_param;
24703464ebd5Sriastradh   param_var->param_binding_type = PROGRAM_CONSTANT;
24713464ebd5Sriastradh
24723464ebd5Sriastradh   if (param_var->param_binding_begin == ~0U) {
24733464ebd5Sriastradh      param_var->param_binding_begin = idx;
24743464ebd5Sriastradh      param_var->param_binding_swizzle = allowSwizzle ? swizzle : SWIZZLE_XYZW;
24753464ebd5Sriastradh   }
24763464ebd5Sriastradh   param_var->param_binding_length++;
24773464ebd5Sriastradh
24783464ebd5Sriastradh   return idx;
24793464ebd5Sriastradh}
24803464ebd5Sriastradh
24813464ebd5Sriastradh
24823464ebd5Sriastradhchar *
24833464ebd5Sriastradhmake_error_string(const char *fmt, ...)
24843464ebd5Sriastradh{
24853464ebd5Sriastradh   int length;
24863464ebd5Sriastradh   char *str;
24873464ebd5Sriastradh   va_list args;
24883464ebd5Sriastradh
24893464ebd5Sriastradh
24903464ebd5Sriastradh   /* Call vsnprintf once to determine how large the final string is.  Call it
24913464ebd5Sriastradh    * again to do the actual formatting.  from the vsnprintf manual page:
24923464ebd5Sriastradh    *
24933464ebd5Sriastradh    *    Upon successful return, these functions return the number of
24943464ebd5Sriastradh    *    characters printed  (not including the trailing '\0' used to end
24953464ebd5Sriastradh    *    output to strings).
24963464ebd5Sriastradh    */
24973464ebd5Sriastradh   va_start(args, fmt);
24983464ebd5Sriastradh   length = 1 + vsnprintf(NULL, 0, fmt, args);
24993464ebd5Sriastradh   va_end(args);
25003464ebd5Sriastradh
25013464ebd5Sriastradh   str = malloc(length);
25023464ebd5Sriastradh   if (str) {
25033464ebd5Sriastradh      va_start(args, fmt);
25043464ebd5Sriastradh      vsnprintf(str, length, fmt, args);
25053464ebd5Sriastradh      va_end(args);
25063464ebd5Sriastradh   }
25073464ebd5Sriastradh
25083464ebd5Sriastradh   return str;
25093464ebd5Sriastradh}
25103464ebd5Sriastradh
25113464ebd5Sriastradh
25123464ebd5Sriastradhvoid
25133464ebd5Sriastradhyyerror(YYLTYPE *locp, struct asm_parser_state *state, const char *s)
25143464ebd5Sriastradh{
25153464ebd5Sriastradh   char *err_str;
25163464ebd5Sriastradh
25173464ebd5Sriastradh
25183464ebd5Sriastradh   err_str = make_error_string("glProgramStringARB(%s)\n", s);
25193464ebd5Sriastradh   if (err_str) {
25203464ebd5Sriastradh      _mesa_error(state->ctx, GL_INVALID_OPERATION, "%s", err_str);
25213464ebd5Sriastradh      free(err_str);
25223464ebd5Sriastradh   }
25233464ebd5Sriastradh
25243464ebd5Sriastradh   err_str = make_error_string("line %u, char %u: error: %s\n",
25253464ebd5Sriastradh			       locp->first_line, locp->first_column, s);
25263464ebd5Sriastradh   _mesa_set_program_error(state->ctx, locp->position, err_str);
25273464ebd5Sriastradh
25283464ebd5Sriastradh   if (err_str) {
25293464ebd5Sriastradh      free(err_str);
25303464ebd5Sriastradh   }
25313464ebd5Sriastradh}
25323464ebd5Sriastradh
25333464ebd5Sriastradh
25343464ebd5SriastradhGLboolean
25353464ebd5Sriastradh_mesa_parse_arb_program(struct gl_context *ctx, GLenum target, const GLubyte *str,
25363464ebd5Sriastradh			GLsizei len, struct asm_parser_state *state)
25373464ebd5Sriastradh{
25383464ebd5Sriastradh   struct asm_instruction *inst;
25393464ebd5Sriastradh   unsigned i;
25403464ebd5Sriastradh   GLubyte *strz;
25413464ebd5Sriastradh   GLboolean result = GL_FALSE;
25423464ebd5Sriastradh   void *temp;
25433464ebd5Sriastradh   struct asm_symbol *sym;
25443464ebd5Sriastradh
25453464ebd5Sriastradh   state->ctx = ctx;
25463464ebd5Sriastradh   state->prog->Target = target;
25473464ebd5Sriastradh   state->prog->Parameters = _mesa_new_parameter_list();
25483464ebd5Sriastradh
25493464ebd5Sriastradh   /* Make a copy of the program string and force it to be NUL-terminated.
25503464ebd5Sriastradh    */
255101e04c3fSmrg   strz = (GLubyte *) ralloc_size(state->mem_ctx, len + 1);
25523464ebd5Sriastradh   if (strz == NULL) {
25537ec681f3Smrg      if (state->prog->Parameters) {
25547ec681f3Smrg         _mesa_free_parameter_list(state->prog->Parameters);
25557ec681f3Smrg         state->prog->Parameters = NULL;
25567ec681f3Smrg      }
25573464ebd5Sriastradh      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
25583464ebd5Sriastradh      return GL_FALSE;
25593464ebd5Sriastradh   }
25603464ebd5Sriastradh   memcpy (strz, str, len);
25613464ebd5Sriastradh   strz[len] = '\0';
25623464ebd5Sriastradh
25633464ebd5Sriastradh   state->prog->String = strz;
25643464ebd5Sriastradh
25653464ebd5Sriastradh   state->st = _mesa_symbol_table_ctor();
25663464ebd5Sriastradh
25673464ebd5Sriastradh   state->limits = (target == GL_VERTEX_PROGRAM_ARB)
2568af69d88dSmrg      ? & ctx->Const.Program[MESA_SHADER_VERTEX]
2569af69d88dSmrg      : & ctx->Const.Program[MESA_SHADER_FRAGMENT];
25703464ebd5Sriastradh
2571af69d88dSmrg   state->MaxTextureImageUnits = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits;
25723464ebd5Sriastradh   state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits;
25733464ebd5Sriastradh   state->MaxTextureUnits = ctx->Const.MaxTextureUnits;
25743464ebd5Sriastradh   state->MaxClipPlanes = ctx->Const.MaxClipPlanes;
25753464ebd5Sriastradh   state->MaxLights = ctx->Const.MaxLights;
25763464ebd5Sriastradh   state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices;
25773464ebd5Sriastradh   state->MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
25783464ebd5Sriastradh
25797ec681f3Smrg   state->state_param_enum_env = (target == GL_VERTEX_PROGRAM_ARB)
25807ec681f3Smrg      ? STATE_VERTEX_PROGRAM_ENV : STATE_FRAGMENT_PROGRAM_ENV;
25817ec681f3Smrg   state->state_param_enum_local = (target == GL_VERTEX_PROGRAM_ARB)
25827ec681f3Smrg      ? STATE_VERTEX_PROGRAM_LOCAL : STATE_FRAGMENT_PROGRAM_LOCAL;
25833464ebd5Sriastradh
25843464ebd5Sriastradh   _mesa_set_program_error(ctx, -1, NULL);
25853464ebd5Sriastradh
25863464ebd5Sriastradh   _mesa_program_lexer_ctor(& state->scanner, state, (const char *) str, len);
25873464ebd5Sriastradh   yyparse(state);
25883464ebd5Sriastradh   _mesa_program_lexer_dtor(state->scanner);
25893464ebd5Sriastradh
25903464ebd5Sriastradh
25913464ebd5Sriastradh   if (ctx->Program.ErrorPos != -1) {
25923464ebd5Sriastradh      goto error;
25933464ebd5Sriastradh   }
25943464ebd5Sriastradh
25953464ebd5Sriastradh   if (! _mesa_layout_parameters(state)) {
25963464ebd5Sriastradh      struct YYLTYPE loc;
25973464ebd5Sriastradh
25983464ebd5Sriastradh      loc.first_line = 0;
25993464ebd5Sriastradh      loc.first_column = 0;
26003464ebd5Sriastradh      loc.position = len;
26013464ebd5Sriastradh
26023464ebd5Sriastradh      yyerror(& loc, state, "invalid PARAM usage");
26033464ebd5Sriastradh      goto error;
26043464ebd5Sriastradh   }
26053464ebd5Sriastradh
26063464ebd5Sriastradh
26077ec681f3Smrg
26083464ebd5Sriastradh   /* Add one instruction to store the "END" instruction.
26093464ebd5Sriastradh    */
261001e04c3fSmrg   state->prog->arb.Instructions =
261101e04c3fSmrg      rzalloc_array(state->mem_ctx, struct prog_instruction,
261201e04c3fSmrg                    state->prog->arb.NumInstructions + 1);
2613af69d88dSmrg
261401e04c3fSmrg   if (state->prog->arb.Instructions == NULL) {
2615af69d88dSmrg      goto error;
2616af69d88dSmrg   }
2617af69d88dSmrg
26183464ebd5Sriastradh   inst = state->inst_head;
261901e04c3fSmrg   for (i = 0; i < state->prog->arb.NumInstructions; i++) {
26203464ebd5Sriastradh      struct asm_instruction *const temp = inst->next;
26213464ebd5Sriastradh
262201e04c3fSmrg      state->prog->arb.Instructions[i] = inst->Base;
26233464ebd5Sriastradh      inst = temp;
26243464ebd5Sriastradh   }
26253464ebd5Sriastradh
26263464ebd5Sriastradh   /* Finally, tag on an OPCODE_END instruction */
26273464ebd5Sriastradh   {
262801e04c3fSmrg      const GLuint numInst = state->prog->arb.NumInstructions;
262901e04c3fSmrg      _mesa_init_instructions(state->prog->arb.Instructions + numInst, 1);
263001e04c3fSmrg      state->prog->arb.Instructions[numInst].Opcode = OPCODE_END;
26313464ebd5Sriastradh   }
263201e04c3fSmrg   state->prog->arb.NumInstructions++;
26333464ebd5Sriastradh
263401e04c3fSmrg   state->prog->arb.NumParameters = state->prog->Parameters->NumParameters;
263501e04c3fSmrg   state->prog->arb.NumAttributes =
263601e04c3fSmrg      util_bitcount64(state->prog->info.inputs_read);
26373464ebd5Sriastradh
26383464ebd5Sriastradh   /*
26393464ebd5Sriastradh    * Initialize native counts to logical counts.  The device driver may
26403464ebd5Sriastradh    * change them if program is translated into a hardware program.
26413464ebd5Sriastradh    */
264201e04c3fSmrg   state->prog->arb.NumNativeInstructions = state->prog->arb.NumInstructions;
264301e04c3fSmrg   state->prog->arb.NumNativeTemporaries = state->prog->arb.NumTemporaries;
264401e04c3fSmrg   state->prog->arb.NumNativeParameters = state->prog->arb.NumParameters;
264501e04c3fSmrg   state->prog->arb.NumNativeAttributes = state->prog->arb.NumAttributes;
264601e04c3fSmrg   state->prog->arb.NumNativeAddressRegs = state->prog->arb.NumAddressRegs;
26473464ebd5Sriastradh
26483464ebd5Sriastradh   result = GL_TRUE;
26493464ebd5Sriastradh
26503464ebd5Sriastradherror:
26513464ebd5Sriastradh   for (inst = state->inst_head; inst != NULL; inst = temp) {
26523464ebd5Sriastradh      temp = inst->next;
26533464ebd5Sriastradh      free(inst);
26543464ebd5Sriastradh   }
26553464ebd5Sriastradh
26563464ebd5Sriastradh   state->inst_head = NULL;
26573464ebd5Sriastradh   state->inst_tail = NULL;
26583464ebd5Sriastradh
26593464ebd5Sriastradh   for (sym = state->sym; sym != NULL; sym = temp) {
26603464ebd5Sriastradh      temp = sym->next;
26613464ebd5Sriastradh
26623464ebd5Sriastradh      free((void *) sym->name);
26633464ebd5Sriastradh      free(sym);
26643464ebd5Sriastradh   }
26653464ebd5Sriastradh   state->sym = NULL;
26663464ebd5Sriastradh
26673464ebd5Sriastradh   _mesa_symbol_table_dtor(state->st);
26683464ebd5Sriastradh   state->st = NULL;
26693464ebd5Sriastradh
26707ec681f3Smrg   if (result != GL_TRUE) {
26717ec681f3Smrg      if (state->prog->Parameters) {
26727ec681f3Smrg         _mesa_free_parameter_list(state->prog->Parameters);
26737ec681f3Smrg         state->prog->Parameters = NULL;
26747ec681f3Smrg      }
26757ec681f3Smrg      ralloc_free(state->prog->String);
26767ec681f3Smrg      state->prog->String = NULL;
26777ec681f3Smrg   }
26787ec681f3Smrg
26793464ebd5Sriastradh   return result;
26803464ebd5Sriastradh}
2681