Subversion Repositories Kolibri OS

Rev

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