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