program_lexer.l revision 3c716a7ec2cabfc18a2506f9db655406f8c64fb0
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 "main/glheader.h"
25#include "main/imports.h"
26#include "program/prog_instruction.h"
27#include "program/prog_statevars.h"
28#include "program/symbol_table.h"
29#include "program/program_parser.h"
30#include "program/program_parse.tab.h"
31
32#define require_ARB_vp (yyextra->mode == ARB_vertex)
33#define require_ARB_fp (yyextra->mode == ARB_fragment)
34#define require_NV_fp  (yyextra->option.NV_fragment)
35#define require_shadow (yyextra->option.Shadow)
36#define require_rect   (yyextra->option.TexRect)
37#define require_texarray        (yyextra->option.TexArray)
38
39#ifndef HAVE_UNISTD_H
40#define YY_NO_UNISTD_H
41#endif
42
43#define return_token_or_IDENTIFIER(condition, token)	\
44   do {							\
45      if (condition) {					\
46	 return token;					\
47      } else {						\
48	 return handle_ident(yyextra, yytext, yylval);	\
49      }							\
50   } while (0)
51
52#define return_token_or_DOT(condition, token)		\
53   do {							\
54      if (condition) {					\
55	 return token;					\
56      } else {						\
57	 yyless(1);					\
58	 return DOT;					\
59      }							\
60   } while (0)
61
62
63#define return_opcode(condition, token, opcode, len)	\
64   do {							\
65      if (condition &&					\
66	  _mesa_parse_instruction_suffix(yyextra,	\
67					 yytext + len,	\
68					 & yylval->temp_inst)) {	\
69	 yylval->temp_inst.Opcode = OPCODE_ ## opcode;	\
70	 return token;					\
71      } else {						\
72	 return handle_ident(yyextra, yytext, yylval);	\
73      }							\
74   } while (0)
75
76#define SWIZZLE_INVAL  MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \
77				     SWIZZLE_NIL, SWIZZLE_NIL)
78
79static unsigned
80mask_from_char(char c)
81{
82   switch (c) {
83   case 'x':
84   case 'r':
85      return WRITEMASK_X;
86   case 'y':
87   case 'g':
88      return WRITEMASK_Y;
89   case 'z':
90   case 'b':
91      return WRITEMASK_Z;
92   case 'w':
93   case 'a':
94      return WRITEMASK_W;
95   }
96
97   return 0;
98}
99
100static unsigned
101swiz_from_char(char c)
102{
103   switch (c) {
104   case 'x':
105   case 'r':
106      return SWIZZLE_X;
107   case 'y':
108   case 'g':
109      return SWIZZLE_Y;
110   case 'z':
111   case 'b':
112      return SWIZZLE_Z;
113   case 'w':
114   case 'a':
115      return SWIZZLE_W;
116   }
117
118   return 0;
119}
120
121static int
122handle_ident(struct asm_parser_state *state, const char *text, YYSTYPE *lval)
123{
124   lval->string = strdup(text);
125
126   return (_mesa_symbol_table_find_symbol(state->st, 0, text) == NULL)
127      ? IDENTIFIER : USED_IDENTIFIER;
128}
129
130#define YY_USER_ACTION							\
131   do {									\
132      yylloc->first_column = yylloc->last_column;			\
133      yylloc->last_column += yyleng;					\
134      if ((yylloc->first_line == 1)					\
135	  && (yylloc->first_column == 1)) {				\
136	 yylloc->position = 1;						\
137      } else {								\
138	 yylloc->position += yylloc->last_column - yylloc->first_column; \
139      }									\
140   } while(0);
141
142#define YY_EXTRA_TYPE struct asm_parser_state *
143
144/* Flex defines a couple of functions with no declarations nor the
145static keyword. Declare them here to avoid a compiler warning. */
146int yyget_column  (yyscan_t yyscanner);
147void yyset_column (int  column_no , yyscan_t yyscanner);
148
149%}
150
151num    [0-9]+
152exp    [Ee][-+]?[0-9]+
153frac   "."[0-9]+
154dot    "."[ \t]*
155
156sz     [HRX]?
157szf    [HR]?
158cc     C?
159sat    (_SAT)?
160
161%option bison-bridge bison-locations reentrant noyywrap
162%%
163
164"!!ARBvp1.0"              { return ARBvp_10; }
165"!!ARBfp1.0"              { return ARBfp_10; }
166ADDRESS                   {
167   yylval->integer = at_address;
168   return_token_or_IDENTIFIER(require_ARB_vp, ADDRESS);
169}
170ALIAS                     { return ALIAS; }
171ATTRIB                    { return ATTRIB; }
172END                       { return END; }
173OPTION                    { return OPTION; }
174OUTPUT                    { return OUTPUT; }
175PARAM                     { return PARAM; }
176TEMP                      { yylval->integer = at_temp; return TEMP; }
177
178ABS{sz}{cc}{sat}   { return_opcode(             1, VECTOR_OP, ABS, 3); }
179ADD{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, ADD, 3); }
180ARL                { return_opcode(require_ARB_vp, ARL, ARL, 3); }
181
182CMP{sat}           { return_opcode(require_ARB_fp, TRI_OP, CMP, 3); }
183COS{szf}{cc}{sat}  { return_opcode(require_ARB_fp, SCALAR_OP, COS, 3); }
184
185DDX{szf}{cc}{sat}  { return_opcode(require_NV_fp,  VECTOR_OP, DDX, 3); }
186DDY{szf}{cc}{sat}  { return_opcode(require_NV_fp,  VECTOR_OP, DDY, 3); }
187DP3{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, DP3, 3); }
188DP4{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, DP4, 3); }
189DPH{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, DPH, 3); }
190DST{szf}{cc}{sat}  { return_opcode(             1, BIN_OP, DST, 3); }
191
192EX2{szf}{cc}{sat}  { return_opcode(             1, SCALAR_OP, EX2, 3); }
193EXP                { return_opcode(require_ARB_vp, SCALAR_OP, EXP, 3); }
194
195FLR{sz}{cc}{sat}   { return_opcode(             1, VECTOR_OP, FLR, 3); }
196FRC{sz}{cc}{sat}   { return_opcode(             1, VECTOR_OP, FRC, 3); }
197
198KIL                { return_opcode(require_ARB_fp, KIL, KIL, 3); }
199
200LIT{szf}{cc}{sat}  { return_opcode(             1, VECTOR_OP, LIT, 3); }
201LG2{szf}{cc}{sat}  { return_opcode(             1, SCALAR_OP, LG2, 3); }
202LOG                { return_opcode(require_ARB_vp, SCALAR_OP, LOG, 3); }
203LRP{sz}{cc}{sat}   { return_opcode(require_ARB_fp, TRI_OP, LRP, 3); }
204
205MAD{sz}{cc}{sat}   { return_opcode(             1, TRI_OP, MAD, 3); }
206MAX{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, MAX, 3); }
207MIN{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, MIN, 3); }
208MOV{sz}{cc}{sat}   { return_opcode(             1, VECTOR_OP, MOV, 3); }
209MUL{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, MUL, 3); }
210
211PK2H               { return_opcode(require_NV_fp,  VECTOR_OP, PK2H, 4); }
212PK2US              { return_opcode(require_NV_fp,  VECTOR_OP, PK2US, 5); }
213PK4B               { return_opcode(require_NV_fp,  VECTOR_OP, PK4B, 4); }
214PK4UB              { return_opcode(require_NV_fp,  VECTOR_OP, PK4UB, 5); }
215POW{szf}{cc}{sat}  { return_opcode(             1, BINSC_OP, POW, 3); }
216
217RCP{szf}{cc}{sat}  { return_opcode(             1, SCALAR_OP, RCP, 3); }
218RFL{szf}{cc}{sat}  { return_opcode(require_NV_fp,  BIN_OP,    RFL, 3); }
219RSQ{szf}{cc}{sat}  { return_opcode(             1, SCALAR_OP, RSQ, 3); }
220
221SCS{sat}           { return_opcode(require_ARB_fp, SCALAR_OP, SCS, 3); }
222SEQ{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SEQ, 3); }
223SFL{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SFL, 3); }
224SGE{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, SGE, 3); }
225SGT{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SGT, 3); }
226SIN{szf}{cc}{sat}  { return_opcode(require_ARB_fp, SCALAR_OP, SIN, 3); }
227SLE{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SLE, 3); }
228SLT{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, SLT, 3); }
229SNE{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SNE, 3); }
230STR{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, STR, 3); }
231SUB{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, SUB, 3); }
232SWZ{sat}           { return_opcode(             1, SWZ, SWZ, 3); }
233
234TEX{cc}{sat}       { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, 3); }
235TXB{cc}{sat}       { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, 3); }
236TXD{cc}{sat}       { return_opcode(require_NV_fp,  TXD_OP, TXD, 3); }
237TXP{cc}{sat}       { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, 3); }
238
239UP2H{cc}{sat}      { return_opcode(require_NV_fp,  SCALAR_OP, UP2H, 4); }
240UP2US{cc}{sat}     { return_opcode(require_NV_fp,  SCALAR_OP, UP2US, 5); }
241UP4B{cc}{sat}      { return_opcode(require_NV_fp,  SCALAR_OP, UP4B, 4); }
242UP4UB{cc}{sat}     { return_opcode(require_NV_fp,  SCALAR_OP, UP4UB, 5); }
243
244X2D{szf}{cc}{sat}  { return_opcode(require_NV_fp,  TRI_OP, X2D, 3); }
245XPD{sat}           { return_opcode(             1, BIN_OP, XPD, 3); }
246
247vertex                    { return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); }
248fragment                  { return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); }
249program                   { return PROGRAM; }
250state                     { return STATE; }
251result                    { return RESULT; }
252
253{dot}ambient              { return AMBIENT; }
254{dot}attenuation          { return ATTENUATION; }
255{dot}back                 { return BACK; }
256{dot}clip                 { return_token_or_DOT(require_ARB_vp, CLIP); }
257{dot}color                { return COLOR; }
258{dot}depth                { return_token_or_DOT(require_ARB_fp, DEPTH); }
259{dot}diffuse              { return DIFFUSE; }
260{dot}direction            { return DIRECTION; }
261{dot}emission             { return EMISSION; }
262{dot}env                  { return ENV; }
263{dot}eye                  { return EYE; }
264{dot}fogcoord             { return FOGCOORD; }
265{dot}fog                  { return FOG; }
266{dot}front                { return FRONT; }
267{dot}half                 { return HALF; }
268{dot}inverse              { return INVERSE; }
269{dot}invtrans             { return INVTRANS; }
270{dot}light                { return LIGHT; }
271{dot}lightmodel           { return LIGHTMODEL; }
272{dot}lightprod            { return LIGHTPROD; }
273{dot}local                { return LOCAL; }
274{dot}material             { return MATERIAL; }
275{dot}program              { return MAT_PROGRAM; }
276{dot}matrix               { return MATRIX; }
277{dot}matrixindex          { return_token_or_DOT(require_ARB_vp, MATRIXINDEX); }
278{dot}modelview            { return MODELVIEW; }
279{dot}mvp                  { return MVP; }
280{dot}normal               { return_token_or_DOT(require_ARB_vp, NORMAL); }
281{dot}object               { return OBJECT; }
282{dot}palette              { return PALETTE; }
283{dot}params               { return PARAMS; }
284{dot}plane                { return PLANE; }
285{dot}point                { return_token_or_DOT(require_ARB_vp, POINT_TOK); }
286{dot}pointsize            { return_token_or_DOT(require_ARB_vp, POINTSIZE); }
287{dot}position             { return POSITION; }
288{dot}primary              { return PRIMARY; }
289{dot}projection           { return PROJECTION; }
290{dot}range                { return_token_or_DOT(require_ARB_fp, RANGE); }
291{dot}row                  { return ROW; }
292{dot}scenecolor           { return SCENECOLOR; }
293{dot}secondary            { return SECONDARY; }
294{dot}shininess            { return SHININESS; }
295{dot}size                 { return_token_or_DOT(require_ARB_vp, SIZE_TOK); }
296{dot}specular             { return SPECULAR; }
297{dot}spot                 { return SPOT; }
298{dot}texcoord             { return TEXCOORD; }
299{dot}texenv               { return_token_or_DOT(require_ARB_fp, TEXENV); }
300{dot}texgen               { return_token_or_DOT(require_ARB_vp, TEXGEN); }
301{dot}q                    { return_token_or_DOT(require_ARB_vp, TEXGEN_Q); }
302{dot}s                    { return_token_or_DOT(require_ARB_vp, TEXGEN_S); }
303{dot}t                    { return_token_or_DOT(require_ARB_vp, TEXGEN_T); }
304{dot}texture              { return TEXTURE; }
305{dot}transpose            { return TRANSPOSE; }
306{dot}attrib               { return_token_or_DOT(require_ARB_vp, VTXATTRIB); }
307{dot}weight               { return_token_or_DOT(require_ARB_vp, WEIGHT); }
308
309texture                   { return_token_or_IDENTIFIER(require_ARB_fp, TEXTURE_UNIT); }
3101D                        { return_token_or_IDENTIFIER(require_ARB_fp, TEX_1D); }
3112D                        { return_token_or_IDENTIFIER(require_ARB_fp, TEX_2D); }
3123D                        { return_token_or_IDENTIFIER(require_ARB_fp, TEX_3D); }
313CUBE                      { return_token_or_IDENTIFIER(require_ARB_fp, TEX_CUBE); }
314RECT                      { return_token_or_IDENTIFIER(require_ARB_fp && require_rect, TEX_RECT); }
315SHADOW1D                  { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW1D); }
316SHADOW2D                  { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW2D); }
317SHADOWRECT                { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_rect, TEX_SHADOWRECT); }
318ARRAY1D                   { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY1D); }
319ARRAY2D                   { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY2D); }
320ARRAYSHADOW1D             { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW1D); }
321ARRAYSHADOW2D             { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); }
322
323[_a-zA-Z$][_a-zA-Z0-9$]*  { return handle_ident(yyextra, yytext, yylval); }
324
325".."                      { return DOT_DOT; }
326
327{num}                     {
328   yylval->integer = strtol(yytext, NULL, 10);
329   return INTEGER;
330}
331{num}?{frac}{exp}?        {
332   yylval->real = _mesa_strtof(yytext, NULL);
333   return REAL;
334}
335{num}"."/[^.]             {
336   yylval->real = _mesa_strtof(yytext, NULL);
337   return REAL;
338}
339{num}{exp}                {
340   yylval->real = _mesa_strtof(yytext, NULL);
341   return REAL;
342}
343{num}"."{exp}             {
344   yylval->real = _mesa_strtof(yytext, NULL);
345   return REAL;
346}
347
348".xyzw"                   {
349   yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
350   yylval->swiz_mask.mask = WRITEMASK_XYZW;
351   return MASK4;
352}
353
354".xy"[zw]                 {
355   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
356   yylval->swiz_mask.mask = WRITEMASK_XY
357      | mask_from_char(yytext[3]);
358   return MASK3;
359}
360".xzw"                    {
361   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
362   yylval->swiz_mask.mask = WRITEMASK_XZW;
363   return MASK3;
364}
365".yzw"                    {
366   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
367   yylval->swiz_mask.mask = WRITEMASK_YZW;
368   return MASK3;
369}
370
371".x"[yzw]                 {
372   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
373   yylval->swiz_mask.mask = WRITEMASK_X
374      | mask_from_char(yytext[2]);
375   return MASK2;
376}
377".y"[zw]                  {
378   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
379   yylval->swiz_mask.mask = WRITEMASK_Y
380      | mask_from_char(yytext[2]);
381   return MASK2;
382}
383".zw"                     {
384   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
385   yylval->swiz_mask.mask = WRITEMASK_ZW;
386   return MASK2;
387}
388
389"."[xyzw]                 {
390   const unsigned s = swiz_from_char(yytext[1]);
391   yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
392   yylval->swiz_mask.mask = mask_from_char(yytext[1]);
393   return MASK1;
394}
395
396"."[xyzw]{4}              {
397   yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
398					    swiz_from_char(yytext[2]),
399					    swiz_from_char(yytext[3]),
400					    swiz_from_char(yytext[4]));
401   yylval->swiz_mask.mask = 0;
402   return SWIZZLE;
403}
404
405".rgba"                   {
406   yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
407   yylval->swiz_mask.mask = WRITEMASK_XYZW;
408   return_token_or_DOT(require_ARB_fp, MASK4);
409}
410
411".rg"[ba]                 {
412   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
413   yylval->swiz_mask.mask = WRITEMASK_XY
414      | mask_from_char(yytext[3]);
415   return_token_or_DOT(require_ARB_fp, MASK3);
416}
417".rba"                    {
418   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
419   yylval->swiz_mask.mask = WRITEMASK_XZW;
420   return_token_or_DOT(require_ARB_fp, MASK3);
421}
422".gba"                    {
423   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
424   yylval->swiz_mask.mask = WRITEMASK_YZW;
425   return_token_or_DOT(require_ARB_fp, MASK3);
426}
427
428".r"[gba]                 {
429   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
430   yylval->swiz_mask.mask = WRITEMASK_X
431      | mask_from_char(yytext[2]);
432   return_token_or_DOT(require_ARB_fp, MASK2);
433}
434".g"[ba]                  {
435   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
436   yylval->swiz_mask.mask = WRITEMASK_Y
437      | mask_from_char(yytext[2]);
438   return_token_or_DOT(require_ARB_fp, MASK2);
439}
440".ba"                     {
441   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
442   yylval->swiz_mask.mask = WRITEMASK_ZW;
443   return_token_or_DOT(require_ARB_fp, MASK2);
444}
445
446"."[gba]                  {
447   const unsigned s = swiz_from_char(yytext[1]);
448   yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
449   yylval->swiz_mask.mask = mask_from_char(yytext[1]);
450   return_token_or_DOT(require_ARB_fp, MASK1);
451}
452
453
454".r"                      {
455   if (require_ARB_vp) {
456      return TEXGEN_R;
457   } else {
458      yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X,
459						SWIZZLE_X, SWIZZLE_X);
460      yylval->swiz_mask.mask = WRITEMASK_X;
461      return MASK1;
462   }
463}
464
465"."[rgba]{4}              {
466   yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
467					    swiz_from_char(yytext[2]),
468					    swiz_from_char(yytext[3]),
469					    swiz_from_char(yytext[4]));
470   yylval->swiz_mask.mask = 0;
471   return_token_or_DOT(require_ARB_fp, SWIZZLE);
472}
473
474"."                       { return DOT; }
475
476\n                        {
477   yylloc->first_line++;
478   yylloc->first_column = 1;
479   yylloc->last_line++;
480   yylloc->last_column = 1;
481   yylloc->position++;
482}
483[ \t\r]+                  /* eat whitespace */ ;
484#.*$                      /* eat comments */ ;
485.                         { return yytext[0]; }
486%%
487
488void
489_mesa_program_lexer_ctor(void **scanner, struct asm_parser_state *state,
490			 const char *string, size_t len)
491{
492   yylex_init_extra(state, scanner);
493   yy_scan_bytes(string, len, *scanner);
494}
495
496void
497_mesa_program_lexer_dtor(void *scanner)
498{
499   yylex_destroy(scanner);
500}
501