msvcrt: Fixed typo in DEFINE_EXCEPTION_TYPE_INFO macro.
[wine/multimedia.git] / dlls / d3dcompiler_43 / asmshader.l
blob8b3bf49d3d55d45368b2e4db97f5afd67d0cf6dd
1 /*
2  * Direct3D shader assembler
3  *
4  * Copyright 2008 Stefan Dösinger
5  * Copyright 2009 Matteo Bruni
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
23 #include "config.h"
24 #include "wine/port.h"
25 #include "wine/debug.h"
27 #include "d3dcompiler_private.h"
28 #include "asmshader.tab.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(asmshader);
33 %option noyywrap
34 %option prefix="asmshader_"
35 %option noinput nounput
37 /* Swizzles and writemasks consist of a dot and up to 4 x, y, z or w characters,
38  * or up to 4 a, r, g, b characters. There are different rules for swizzles and
39  * writemasks wrt repetition, those are handled in the grammar.
40  */
41 DOT                     \.
42 COMPONENT               [xyzw]|[rgba]
44 /* Registers */
45 REG_TEMP                r[0-9]+
46 /* for relative addressing in the form o[x], v[x] and c[x] */
47 REG_OUTPUT              o[0-9]*
48 REG_INPUT               v[0-9]*
49 REG_CONSTFLOAT          c[0-9]*
50 REG_CONSTINT            i[0-9]+
51 REG_CONSTBOOL           b[0-9]+
52 REG_TEXTURE             t[0-9]+
53 REG_TEXCRDOUT           oT[0-9]+
54 REG_SAMPLER             s[0-9]+
55 REG_OPOS                oPos
56 REG_OFOG                oFog
57 REG_OPTS                oPts
58 REG_VERTEXCOLOR         oD[01]
59 REG_FRAGCOLOR           oC[0-9]+
60 REG_FRAGDEPTH           oDepth
61 REG_VPOS                vPos
62 REG_VFACE               vFace
63 REG_ADDRESS             a0
64 REG_LOOP                aL
65 REG_PREDICATE           p0
66 /* Not really a register, but it is considered as such */
67 REG_LABEL               l[0-9]+
69 DCL_POSITION            _position[0-9]*
70 DCL_BLENDWEIGHT         _blendweight[0-9]*
71 DCL_BLENDINDICES        _blendindices[0-9]*
72 DCL_NORMAL              _normal[0-9]*
73 DCL_PSIZE               _psize[0-9]*
74 DCL_TEXCOORD            _texcoord[0-9]*
75 DCL_TANGENT             _tangent[0-9]*
76 DCL_BINORMAL            _binormal[0-9]*
77 DCL_TESSFACTOR          _tessfactor[0-9]*
78 DCL_POSITIONT           _positiont[0-9]*
79 DCL_COLOR               _color[0-9]*
80 DCL_FOG                 _fog[0-9]*
81 DCL_DEPTH               _depth[0-9]*
82 DCL_SAMPLE              _sample[0-9]*
84 DCL_SAMPLER1D           _1d
85 DCL_SAMPLER2D           _2d
86 DCL_SAMPLERCUBE         _cube
87 DCL_SAMPLERVOLUME       _volume
89 PREPROCESSORDIRECTIVE   #[^\n]*\n
91 /* Comments */
92 DOUBLESLASHCOMMENT      "//"[^\n]*
93 SEMICOLONCOMMENT        ";"[^\n]*
95 /* Whitespaces are spaces, tabs and newlines */
96 WHITESPACE              [ \t]+
97 NEWLINE                 (\n)|(\r\n)
99 COMMA                   ","
101 IMMVAL                  \-?(([0-9]+\.?)|([0-9]*\.[0-9]+))(f)?
103 ANY                     (.)
107     /* Common instructions(vertex and pixel shaders) */
108 add                     {return INSTR_ADD;          }
109 nop                     {return INSTR_NOP;          }
110 mov                     {return INSTR_MOV;          }
111 sub                     {return INSTR_SUB;          }
112 mad                     {return INSTR_MAD;          }
113 mul                     {return INSTR_MUL;          }
114 rcp                     {return INSTR_RCP;          }
115 rsq                     {return INSTR_RSQ;          }
116 dp3                     {return INSTR_DP3;          }
117 dp4                     {return INSTR_DP4;          }
118 min                     {return INSTR_MIN;          }
119 max                     {return INSTR_MAX;          }
120 slt                     {return INSTR_SLT;          }
121 sge                     {return INSTR_SGE;          }
122 abs                     {return INSTR_ABS;          }
123 exp                     {return INSTR_EXP;          }
124 log                     {return INSTR_LOG;          }
125 expp                    {return INSTR_EXPP;         }
126 logp                    {return INSTR_LOGP;         }
127 dst                     {return INSTR_DST;          }
128 lrp                     {return INSTR_LRP;          }
129 frc                     {return INSTR_FRC;          }
130 pow                     {return INSTR_POW;          }
131 crs                     {return INSTR_CRS;          }
132 sgn                     {return INSTR_SGN;          }
133 nrm                     {return INSTR_NRM;          }
134 sincos                  {return INSTR_SINCOS;       }
135 m4x4                    {return INSTR_M4x4;         }
136 m4x3                    {return INSTR_M4x3;         }
137 m3x4                    {return INSTR_M3x4;         }
138 m3x3                    {return INSTR_M3x3;         }
139 m3x2                    {return INSTR_M3x2;         }
140 dcl                     {return INSTR_DCL;          }
141 def                     {return INSTR_DEF;          }
142 defb                    {return INSTR_DEFB;         }
143 defi                    {return INSTR_DEFI;         }
144 rep                     {return INSTR_REP;          }
145 endrep                  {return INSTR_ENDREP;       }
146 if                      {return INSTR_IF;           }
147 else                    {return INSTR_ELSE;         }
148 endif                   {return INSTR_ENDIF;        }
149 break                   {return INSTR_BREAK;        }
150 breakp                  {return INSTR_BREAKP;       }
151 call                    {return INSTR_CALL;         }
152 callnz                  {return INSTR_CALLNZ;       }
153 loop                    {return INSTR_LOOP;         }
154 ret                     {return INSTR_RET;          }
155 endloop                 {return INSTR_ENDLOOP;      }
156 label                   {return INSTR_LABEL;        }
157 setp                    {return INSTR_SETP;         }
158 texldl                  {return INSTR_TEXLDL;       }
160     /* Vertex shader only instructions  */
161 lit                     {return INSTR_LIT;          }
162 mova                    {return INSTR_MOVA;         }
164     /* Pixel shader only instructions   */
165 cnd                     {return INSTR_CND;          }
166 cmp                     {return INSTR_CMP;          }
167 dp2add                  {return INSTR_DP2ADD;       }
168 texcoord                {return INSTR_TEXCOORD;     }
169 texcrd                  {return INSTR_TEXCRD;       }
170 texkill                 {return INSTR_TEXKILL;      }
171 tex                     {return INSTR_TEX;          }
172 texld                   {return INSTR_TEXLD;        }
173 texbem                  {return INSTR_TEXBEM;       }
174 texbeml                 {return INSTR_TEXBEML;      }
175 texreg2ar               {return INSTR_TEXREG2AR;    }
176 texreg2gb               {return INSTR_TEXREG2GB;    }
177 texreg2rgb              {return INSTR_TEXREG2RGB;   }
178 texm3x2pad              {return INSTR_TEXM3x2PAD;   }
179 texm3x2tex              {return INSTR_TEXM3x2TEX;   }
180 texm3x3pad              {return INSTR_TEXM3x3PAD;   }
181 texm3x3spec             {return INSTR_TEXM3x3SPEC;  }
182 texm3x3vspec            {return INSTR_TEXM3x3VSPEC; }
183 texm3x3tex              {return INSTR_TEXM3x3TEX;   }
184 texdp3tex               {return INSTR_TEXDP3TEX;    }
185 texm3x2depth            {return INSTR_TEXM3x2DEPTH; }
186 texdp3                  {return INSTR_TEXDP3;       }
187 texm3x3                 {return INSTR_TEXM3x3;      }
188 texdepth                {return INSTR_TEXDEPTH;     }
189 bem                     {return INSTR_BEM;          }
190 dsx                     {return INSTR_DSX;          }
191 dsy                     {return INSTR_DSY;          }
192 texldp                  {return INSTR_TEXLDP;       }
193 texldb                  {return INSTR_TEXLDB;       }
194 texldd                  {return INSTR_TEXLDD;       }
195 phase                   {return INSTR_PHASE;        }
197 {REG_TEMP}              {
198                             asmshader_lval.regnum = atoi(yytext + 1);
199                             return REG_TEMP;
200                         }
201 {REG_OUTPUT}            {
202                             asmshader_lval.regnum = atoi(yytext + 1);
203                             return REG_OUTPUT;
204                         }
205 {REG_INPUT}             {
206                             asmshader_lval.regnum = atoi(yytext + 1);
207                             return REG_INPUT;
208                         }
209 {REG_CONSTFLOAT}        {
210                             asmshader_lval.regnum = atoi(yytext + 1);
211                             return REG_CONSTFLOAT;
212                         }
213 {REG_CONSTINT}          {
214                             asmshader_lval.regnum = atoi(yytext + 1);
215                             return REG_CONSTINT;
216                         }
217 {REG_CONSTBOOL}         {
218                             asmshader_lval.regnum = atoi(yytext + 1);
219                             return REG_CONSTBOOL;
220                         }
221 {REG_TEXTURE}           {
222                             asmshader_lval.regnum = atoi(yytext + 1);
223                             return REG_TEXTURE;
224                         }
225 {REG_TEXCRDOUT}         {
226                             asmshader_lval.regnum = atoi(yytext + 2);
227                             return REG_TEXCRDOUT;
228                         }
229 {REG_SAMPLER}           {
230                             asmshader_lval.regnum = atoi(yytext + 1);
231                             return REG_SAMPLER;
232                         }
233 {REG_OPOS}              {return REG_OPOS;           }
234 {REG_OFOG}              {return REG_OFOG;           }
235 {REG_OPTS}              {return REG_OPTS;           }
236 {REG_VERTEXCOLOR}       {
237                             asmshader_lval.regnum = atoi(yytext + 2);
238                             return REG_VERTEXCOLOR;
239                         }
240 {REG_FRAGCOLOR}         {
241                             asmshader_lval.regnum = atoi(yytext + 2);
242                             return REG_FRAGCOLOR;
243                         }
244 {REG_FRAGDEPTH}         {return REG_FRAGDEPTH;      }
245 {REG_VPOS}              {return REG_VPOS;           }
246 {REG_VFACE}             {return REG_VFACE;          }
247 {REG_ADDRESS}           {return REG_ADDRESS;        }
248 {REG_LOOP}              {return REG_LOOP;           }
249 {REG_PREDICATE}         {return REG_PREDICATE;      }
251 {REG_LABEL}             {
252                             asmshader_lval.regnum = atoi(yytext + 1);
253                             return REG_LABEL;
254                         }
256     /* Shader versions. These are important to select the correct
257      * parser profile.
258      */
259 vs\.1\.0|vs_1_0         {return VER_VS10;       }
260 vs\.1\.1|vs_1_1         {return VER_VS11;       }
262 vs\.2\.0|vs_2_0         {return VER_VS20;       }
263 vs\.2\.x|vs_2_x         {return VER_VS2X;       }
264 vs\.3\.0|vs_3_0         {return VER_VS30;       }
266 ps\.1\.0|ps_1_0         {return VER_PS10;       }
267 ps\.1\.1|ps_1_1         {return VER_PS11;       }
268 ps\.1\.2|ps_1_2         {return VER_PS12;       }
269 ps\.1\.3|ps_1_3         {return VER_PS13;       }
270 ps\.1\.4|ps_1_4         {return VER_PS14;       }
272 ps\.2\.0|ps_2_0         {return VER_PS20;       }
273 ps\.2\.x|ps_2_x         {return VER_PS2X;       }
274 ps\.3\.0|ps_3_0         {return VER_PS30;       }
276 {DOT}                   {return yytext[0];      }
277 {COMPONENT}             {
278                             switch(yytext[0]) {
279                                 case 'x':
280                                 case 'r':
281                                     asmshader_lval.component = 0;
282                                     break;
283                                 case 'y':
284                                 case 'g':
285                                     asmshader_lval.component = 1;
286                                     break;
287                                 case 'z':
288                                 case 'b':
289                                     asmshader_lval.component = 2;
290                                     break;
291                                 case 'w':
292                                 case 'a':
293                                     asmshader_lval.component = 3;
294                                     break;
295                             }
296                             return COMPONENT;
297                         }
299     /* Output modifiers */
300 \_x2                    {return SHIFT_X2;           }
301 \_x4                    {return SHIFT_X4;           }
302 \_x8                    {return SHIFT_X8;           }
303 \_d2                    {return SHIFT_D2;           }
304 \_d4                    {return SHIFT_D4;           }
305 \_d8                    {return SHIFT_D8;           }
306 \_sat                   {return MOD_SAT;            }
307 \_pp                    {return MOD_PP;             }
308 \_centroid              {return MOD_CENTROID;       }
310     /* compare params */
311 \_gt                    {return COMP_GT;            }
312 \_lt                    {return COMP_LT;            }
313 \_ge                    {return COMP_GE;            }
314 \_le                    {return COMP_LE;            }
315 \_eq                    {return COMP_EQ;            }
316 \_ne                    {return COMP_NE;            }
318 {IMMVAL}                {
319                             asmshader_lval.immval.val = atof(yytext);
320                             asmshader_lval.immval.integer = ((strstr(yytext, ".") == NULL) && (strstr(yytext, "f") == NULL));
321                             return IMMVAL;
322                         }
323 true                    {
324                             asmshader_lval.immbool = TRUE;
325                             return IMMBOOL;
326                         }
327 false                   {
328                             asmshader_lval.immbool = FALSE;
329                             return IMMBOOL;
330                         }
332 {COMMA}                 {return yytext[0];          }
333 -                       {return yytext[0];          }
334 \(                      {return yytext[0];          }
335 \)                      {return yytext[0];          }
337     /* for relative addressing */
338 \[|\]|\+                {return yytext[0];          }
340 \_bias                  {return SMOD_BIAS;          }
341     /* No _x2 here; it is identical to MOD_X2 */
342 \_bx2                   {return SMOD_SCALEBIAS;     }
343 \_dz                    {return SMOD_DZ;            }
344 \_dw                    {return SMOD_DW;            }
345 \_abs                   {return SMOD_ABS;           }
347 !                       {return SMOD_NOT;           }
349 {DCL_POSITION}          {
350                             if(yytext[strlen("_position")] == '\0') {
351                                 asmshader_lval.regnum = 0;
352                             } else {
353                                 asmshader_lval.regnum = atoi(yytext + strlen("_position"));
354                             }
355                             return USAGE_POSITION;
356                         }
357 {DCL_BLENDWEIGHT}       {
358                             if(yytext[strlen("_blendweight")] == '\0') {
359                                 asmshader_lval.regnum = 0;
360                             } else {
361                                 asmshader_lval.regnum = atoi(yytext + strlen("_blendweight"));
362                             }
363                             return USAGE_BLENDWEIGHT;
364                         }
365 {DCL_BLENDINDICES}      {
366                             if(yytext[strlen("_blendindices")] == '\0') {
367                                 asmshader_lval.regnum = 0;
368                             } else {
369                                 asmshader_lval.regnum = atoi(yytext + strlen("_blendindices"));
370                             }
371                             return USAGE_BLENDINDICES;
372                         }
373 {DCL_NORMAL}            {
374                             if(yytext[strlen("_normal")] == '\0') {
375                                 asmshader_lval.regnum = 0;
376                             } else {
377                                 asmshader_lval.regnum = atoi(yytext + strlen("_normal"));
378                             }
379                             return USAGE_NORMAL;
380                         }
381 {DCL_PSIZE}             {
382                             if(yytext[strlen("_psize")] == '\0') {
383                                 asmshader_lval.regnum = 0;
384                             } else {
385                                 asmshader_lval.regnum = atoi(yytext + strlen("_psize"));
386                             }
387                             return USAGE_PSIZE;
388                         }
389 {DCL_TEXCOORD}          {
390                             if(yytext[strlen("_texcoord")] == '\0') {
391                                 asmshader_lval.regnum = 0;
392                             } else {
393                                 asmshader_lval.regnum = atoi(yytext + strlen("_texcoord"));
394                             }
395                             return USAGE_TEXCOORD;
396                         }
397 {DCL_TANGENT}           {
398                             if(yytext[strlen("_tangent")] == '\0') {
399                                 asmshader_lval.regnum = 0;
400                             } else {
401                                 asmshader_lval.regnum = atoi(yytext + strlen("_tangent"));
402                             }
403                             return USAGE_TANGENT;
404                         }
405 {DCL_BINORMAL}          {
406                             if(yytext[strlen("_binormal")] == '\0') {
407                                 asmshader_lval.regnum = 0;
408                             } else {
409                                 asmshader_lval.regnum = atoi(yytext + strlen("_binormal"));
410                             }
411                             return USAGE_BINORMAL;
412                         }
413 {DCL_TESSFACTOR}        {
414                             if(yytext[strlen("_tessfactor")] == '\0') {
415                                 asmshader_lval.regnum = 0;
416                             } else {
417                                 asmshader_lval.regnum = atoi(yytext + strlen("_tessfactor"));
418                             }
419                             return USAGE_TESSFACTOR;
420                         }
421 {DCL_POSITIONT}         {
422                             if(yytext[strlen("_positiont")] == '\0') {
423                                 asmshader_lval.regnum = 0;
424                             } else {
425                                 asmshader_lval.regnum = atoi(yytext + strlen("_positiont"));
426                             }
427                             return USAGE_POSITIONT;
428                         }
429 {DCL_COLOR}             {
430                             if(yytext[strlen("_color")] == '\0') {
431                                 asmshader_lval.regnum = 0;
432                             } else {
433                                 asmshader_lval.regnum = atoi(yytext + strlen("_color"));
434                             }
435                             return USAGE_COLOR;
436                         }
437 {DCL_FOG}               {
438                             if(yytext[strlen("_fog")] == '\0') {
439                                 asmshader_lval.regnum = 0;
440                             } else {
441                                 asmshader_lval.regnum = atoi(yytext + strlen("_fog"));
442                             }
443                             return USAGE_FOG;
444                         }
445 {DCL_DEPTH}             {
446                             if(yytext[strlen("_depth")] == '\0') {
447                                 asmshader_lval.regnum = 0;
448                             } else {
449                                 asmshader_lval.regnum = atoi(yytext + strlen("_depth"));
450                             }
451                             return USAGE_DEPTH;
452                         }
453 {DCL_SAMPLE}            {
454                             if(yytext[strlen("_sample")] == '\0') {
455                                 asmshader_lval.regnum = 0;
456                             } else {
457                                 asmshader_lval.regnum = atoi(yytext + strlen("_sample"));
458                             }
459                             return USAGE_SAMPLE;
460                         }
462 {DCL_SAMPLER1D}         { return SAMPTYPE_1D;       }
463 {DCL_SAMPLER2D}         { return SAMPTYPE_2D;       }
464 {DCL_SAMPLERCUBE}       { return SAMPTYPE_CUBE;     }
465 {DCL_SAMPLERVOLUME}     { return SAMPTYPE_VOLUME;   }
467 {PREPROCESSORDIRECTIVE} {
468                             /* TODO: update current line information */
469                             TRACE("line info update: %s", yytext);
470                         }
472     /* Skip comments */
473 {DOUBLESLASHCOMMENT}    {                           }
474 {SEMICOLONCOMMENT}      {                           }
476 {WHITESPACE}            { /* Do nothing */          }
477 {NEWLINE}               {
478                             asm_ctx.line_no++;
479                         }
481 {ANY}                   {
482                             asmparser_message(&asm_ctx, "Line %u: Unexpected input %s\n", asm_ctx.line_no, yytext);
483                             set_parse_status(&asm_ctx.status, PARSE_ERR);
484                         }
488 struct bwriter_shader *SlAssembleShader(const char *text, char **messages) {
489     struct bwriter_shader *ret = NULL;
490     YY_BUFFER_STATE buffer;
491     TRACE("%p, %p\n", text, messages);
493     buffer = asmshader__scan_string(text);
494     asmshader__switch_to_buffer(buffer);
496     ret = parse_asm_shader(messages);
498     asmshader__delete_buffer(buffer);
500     return ret;