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