Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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