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