rasapi32: Update spec file.
[wine/zf.git] / dlls / d3dcompiler_43 / asmshader.y
blob9e0fec618cd394df5f75052829a49b2a749eb373
1 /*
2 * Direct3D shader assembler
4 * Copyright 2008 Stefan Dösinger
5 * Copyright 2009 Matteo Bruni
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.
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.
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
23 #include "wine/debug.h"
25 #include "d3dcompiler_private.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(asmshader);
29 struct asm_parser asm_ctx;
31 void WINAPIV asmparser_message(struct asm_parser *ctx, const char *fmt, ...)
33 __ms_va_list args;
35 __ms_va_start(args, fmt);
36 compilation_message(&ctx->messages, fmt, args);
37 __ms_va_end(args);
40 static void asmshader_error(char const *s) {
41 asmparser_message(&asm_ctx, "Line %u: Error \"%s\" from bison\n", asm_ctx.line_no, s);
42 set_parse_status(&asm_ctx.status, PARSE_ERR);
45 static void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
46 /* We can have an additional offset without true relative addressing
47 * ex. c2[ 4 ] */
48 reg->regnum += rel->additional_offset;
49 if(!rel->has_rel_reg) {
50 reg->rel_reg = NULL;
51 } else {
52 reg->rel_reg = d3dcompiler_alloc(sizeof(*reg->rel_reg));
53 if(!reg->rel_reg) {
54 return;
56 reg->rel_reg->type = rel->type;
57 reg->rel_reg->u.swizzle = rel->swizzle;
58 reg->rel_reg->regnum = rel->rel_regnum;
62 /* Needed lexer functions declarations */
63 int asmshader_lex(void);
68 %union {
69 struct {
70 float val;
71 BOOL integer;
72 } immval;
73 BOOL immbool;
74 unsigned int regnum;
75 struct shader_reg reg;
76 DWORD srcmod;
77 DWORD writemask;
78 struct {
79 DWORD writemask;
80 DWORD idx;
81 DWORD last;
82 } wm_components;
83 DWORD swizzle;
84 struct {
85 DWORD swizzle;
86 DWORD idx;
87 } sw_components;
88 DWORD component;
89 struct {
90 DWORD mod;
91 DWORD shift;
92 } modshift;
93 enum bwriter_comparison_type comptype;
94 struct {
95 DWORD dclusage;
96 unsigned int regnum;
97 } declaration;
98 enum bwritersampler_texture_type samplertype;
99 struct rel_reg rel_reg;
100 struct src_regs sregs;
103 /* Common instructions between vertex and pixel shaders */
104 %token INSTR_ADD
105 %token INSTR_NOP
106 %token INSTR_MOV
107 %token INSTR_SUB
108 %token INSTR_MAD
109 %token INSTR_MUL
110 %token INSTR_RCP
111 %token INSTR_RSQ
112 %token INSTR_DP3
113 %token INSTR_DP4
114 %token INSTR_MIN
115 %token INSTR_MAX
116 %token INSTR_SLT
117 %token INSTR_SGE
118 %token INSTR_ABS
119 %token INSTR_EXP
120 %token INSTR_LOG
121 %token INSTR_EXPP
122 %token INSTR_LOGP
123 %token INSTR_DST
124 %token INSTR_LRP
125 %token INSTR_FRC
126 %token INSTR_POW
127 %token INSTR_CRS
128 %token INSTR_SGN
129 %token INSTR_NRM
130 %token INSTR_SINCOS
131 %token INSTR_M4x4
132 %token INSTR_M4x3
133 %token INSTR_M3x4
134 %token INSTR_M3x3
135 %token INSTR_M3x2
136 %token INSTR_DCL
137 %token INSTR_DEF
138 %token INSTR_DEFB
139 %token INSTR_DEFI
140 %token INSTR_REP
141 %token INSTR_ENDREP
142 %token INSTR_IF
143 %token INSTR_ELSE
144 %token INSTR_ENDIF
145 %token INSTR_BREAK
146 %token INSTR_BREAKP
147 %token INSTR_CALL
148 %token INSTR_CALLNZ
149 %token INSTR_LOOP
150 %token INSTR_RET
151 %token INSTR_ENDLOOP
152 %token INSTR_LABEL
153 %token INSTR_SETP
154 %token INSTR_TEXLDL
156 /* Vertex shader only instructions */
157 %token INSTR_LIT
158 %token INSTR_MOVA
160 /* Pixel shader only instructions */
161 %token INSTR_CND
162 %token INSTR_CMP
163 %token INSTR_DP2ADD
164 %token INSTR_TEXCOORD
165 %token INSTR_TEXCRD
166 %token INSTR_TEXKILL
167 %token INSTR_TEX
168 %token INSTR_TEXLD
169 %token INSTR_TEXBEM
170 %token INSTR_TEXBEML
171 %token INSTR_TEXREG2AR
172 %token INSTR_TEXREG2GB
173 %token INSTR_TEXREG2RGB
174 %token INSTR_TEXM3x2PAD
175 %token INSTR_TEXM3x2TEX
176 %token INSTR_TEXM3x3PAD
177 %token INSTR_TEXM3x3SPEC
178 %token INSTR_TEXM3x3VSPEC
179 %token INSTR_TEXM3x3TEX
180 %token INSTR_TEXDP3TEX
181 %token INSTR_TEXM3x2DEPTH
182 %token INSTR_TEXDP3
183 %token INSTR_TEXM3x3
184 %token INSTR_TEXDEPTH
185 %token INSTR_BEM
186 %token INSTR_DSX
187 %token INSTR_DSY
188 %token INSTR_TEXLDP
189 %token INSTR_TEXLDB
190 %token INSTR_TEXLDD
191 %token INSTR_PHASE
193 /* Registers */
194 %token <regnum> REG_TEMP
195 %token <regnum> REG_OUTPUT
196 %token <regnum> REG_INPUT
197 %token <regnum> REG_CONSTFLOAT
198 %token <regnum> REG_CONSTINT
199 %token <regnum> REG_CONSTBOOL
200 %token <regnum> REG_TEXTURE
201 %token <regnum> REG_SAMPLER
202 %token <regnum> REG_TEXCRDOUT
203 %token REG_OPOS
204 %token REG_OFOG
205 %token REG_OPTS
206 %token <regnum> REG_VERTEXCOLOR
207 %token <regnum> REG_FRAGCOLOR
208 %token REG_FRAGDEPTH
209 %token REG_VPOS
210 %token REG_VFACE
211 %token REG_ADDRESS
212 %token REG_LOOP
213 %token REG_PREDICATE
214 %token <regnum> REG_LABEL
216 /* Version tokens */
217 %token VER_VS10
218 %token VER_VS11
219 %token VER_VS20
220 %token VER_VS2X
221 %token VER_VS30
223 %token VER_PS10
224 %token VER_PS11
225 %token VER_PS12
226 %token VER_PS13
227 %token VER_PS14
228 %token VER_PS20
229 %token VER_PS2X
230 %token VER_PS30
232 /* Output modifiers */
233 %token SHIFT_X2
234 %token SHIFT_X4
235 %token SHIFT_X8
236 %token SHIFT_D2
237 %token SHIFT_D4
238 %token SHIFT_D8
239 %token MOD_SAT
240 %token MOD_PP
241 %token MOD_CENTROID
243 /* Compare tokens */
244 %token COMP_GT
245 %token COMP_LT
246 %token COMP_GE
247 %token COMP_LE
248 %token COMP_EQ
249 %token COMP_NE
251 /* Source register modifiers */
252 %token SMOD_BIAS
253 %token SMOD_SCALEBIAS
254 %token SMOD_DZ
255 %token SMOD_DW
256 %token SMOD_ABS
257 %token SMOD_NOT
259 /* Sampler types */
260 %token SAMPTYPE_1D
261 %token SAMPTYPE_2D
262 %token SAMPTYPE_CUBE
263 %token SAMPTYPE_VOLUME
265 /* Usage declaration tokens */
266 %token <regnum> USAGE_POSITION
267 %token <regnum> USAGE_BLENDWEIGHT
268 %token <regnum> USAGE_BLENDINDICES
269 %token <regnum> USAGE_NORMAL
270 %token <regnum> USAGE_PSIZE
271 %token <regnum> USAGE_TEXCOORD
272 %token <regnum> USAGE_TANGENT
273 %token <regnum> USAGE_BINORMAL
274 %token <regnum> USAGE_TESSFACTOR
275 %token <regnum> USAGE_POSITIONT
276 %token <regnum> USAGE_COLOR
277 %token <regnum> USAGE_FOG
278 %token <regnum> USAGE_DEPTH
279 %token <regnum> USAGE_SAMPLE
281 /* Misc stuff */
282 %token <component> COMPONENT
283 %token <immval> IMMVAL
284 %token <immbool> IMMBOOL
286 %type <reg> dreg_name
287 %type <reg> dreg
288 %type <reg> sreg_name
289 %type <reg> relreg_name
290 %type <reg> sreg
291 %type <srcmod> smod
292 %type <writemask> writemask
293 %type <wm_components> wm_components
294 %type <swizzle> swizzle
295 %type <sw_components> sw_components
296 %type <modshift> omods
297 %type <modshift> omodifier
298 %type <comptype> comp
299 %type <declaration> dclusage
300 %type <reg> dcl_inputreg
301 %type <samplertype> sampdcl
302 %type <rel_reg> rel_reg
303 %type <reg> predicate
304 %type <immval> immsum
305 %type <sregs> sregs
309 shader: version_marker instructions
311 asm_ctx.funcs->end(&asm_ctx);
314 version_marker: VER_VS10
316 TRACE("Vertex shader 1.0\n");
317 create_vs10_parser(&asm_ctx);
319 | VER_VS11
321 TRACE("Vertex shader 1.1\n");
322 create_vs11_parser(&asm_ctx);
324 | VER_VS20
326 TRACE("Vertex shader 2.0\n");
327 create_vs20_parser(&asm_ctx);
329 | VER_VS2X
331 TRACE("Vertex shader 2.x\n");
332 create_vs2x_parser(&asm_ctx);
334 | VER_VS30
336 TRACE("Vertex shader 3.0\n");
337 create_vs30_parser(&asm_ctx);
339 | VER_PS10
341 TRACE("Pixel shader 1.0\n");
342 create_ps10_parser(&asm_ctx);
344 | VER_PS11
346 TRACE("Pixel shader 1.1\n");
347 create_ps11_parser(&asm_ctx);
349 | VER_PS12
351 TRACE("Pixel shader 1.2\n");
352 create_ps12_parser(&asm_ctx);
354 | VER_PS13
356 TRACE("Pixel shader 1.3\n");
357 create_ps13_parser(&asm_ctx);
359 | VER_PS14
361 TRACE("Pixel shader 1.4\n");
362 create_ps14_parser(&asm_ctx);
364 | VER_PS20
366 TRACE("Pixel shader 2.0\n");
367 create_ps20_parser(&asm_ctx);
369 | VER_PS2X
371 TRACE("Pixel shader 2.x\n");
372 create_ps2x_parser(&asm_ctx);
374 | VER_PS30
376 TRACE("Pixel shader 3.0\n");
377 create_ps30_parser(&asm_ctx);
380 instructions: /* empty */
381 | instructions complexinstr
383 /* Nothing to do */
386 complexinstr: instruction
390 | predicate instruction
392 TRACE("predicate\n");
393 asm_ctx.funcs->predicate(&asm_ctx, &$1);
395 | '+' instruction
397 TRACE("coissue\n");
398 asm_ctx.funcs->coissue(&asm_ctx);
401 instruction: INSTR_ADD omods dreg ',' sregs
403 TRACE("ADD\n");
404 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ADD, $2.mod, $2.shift, 0, &$3, &$5, 2);
406 | INSTR_NOP
408 TRACE("NOP\n");
409 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_NOP, 0, 0, 0, 0, 0, 0);
411 | INSTR_MOV omods dreg ',' sregs
413 TRACE("MOV\n");
414 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_MOV, $2.mod, $2.shift, 0, &$3, &$5, 1);
416 | INSTR_SUB omods dreg ',' sregs
418 TRACE("SUB\n");
419 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_SUB, $2.mod, $2.shift, 0, &$3, &$5, 2);
421 | INSTR_MAD omods dreg ',' sregs
423 TRACE("MAD\n");
424 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_MAD, $2.mod, $2.shift, 0, &$3, &$5, 3);
426 | INSTR_MUL omods dreg ',' sregs
428 TRACE("MUL\n");
429 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_MUL, $2.mod, $2.shift, 0, &$3, &$5, 2);
431 | INSTR_RCP omods dreg ',' sregs
433 TRACE("RCP\n");
434 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_RCP, $2.mod, $2.shift, 0, &$3, &$5, 1);
436 | INSTR_RSQ omods dreg ',' sregs
438 TRACE("RSQ\n");
439 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_RSQ, $2.mod, $2.shift, 0, &$3, &$5, 1);
441 | INSTR_DP3 omods dreg ',' sregs
443 TRACE("DP3\n");
444 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_DP3, $2.mod, $2.shift, 0, &$3, &$5, 2);
446 | INSTR_DP4 omods dreg ',' sregs
448 TRACE("DP4\n");
449 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_DP4, $2.mod, $2.shift, 0, &$3, &$5, 2);
451 | INSTR_MIN omods dreg ',' sregs
453 TRACE("MIN\n");
454 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_MIN, $2.mod, $2.shift, 0, &$3, &$5, 2);
456 | INSTR_MAX omods dreg ',' sregs
458 TRACE("MAX\n");
459 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_MAX, $2.mod, $2.shift, 0, &$3, &$5, 2);
461 | INSTR_SLT omods dreg ',' sregs
463 TRACE("SLT\n");
464 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_SLT, $2.mod, $2.shift, 0, &$3, &$5, 2);
466 | INSTR_SGE omods dreg ',' sregs
468 TRACE("SGE\n");
469 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_SGE, $2.mod, $2.shift, 0, &$3, &$5, 2);
471 | INSTR_ABS omods dreg ',' sregs
473 TRACE("ABS\n");
474 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ABS, $2.mod, $2.shift, 0, &$3, &$5, 1);
476 | INSTR_EXP omods dreg ',' sregs
478 TRACE("EXP\n");
479 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_EXP, $2.mod, $2.shift, 0, &$3, &$5, 1);
481 | INSTR_LOG omods dreg ',' sregs
483 TRACE("LOG\n");
484 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LOG, $2.mod, $2.shift, 0, &$3, &$5, 1);
486 | INSTR_LOGP omods dreg ',' sregs
488 TRACE("LOGP\n");
489 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LOGP, $2.mod, $2.shift, 0, &$3, &$5, 1);
491 | INSTR_EXPP omods dreg ',' sregs
493 TRACE("EXPP\n");
494 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_EXPP, $2.mod, $2.shift, 0, &$3, &$5, 1);
496 | INSTR_DST omods dreg ',' sregs
498 TRACE("DST\n");
499 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_DST, $2.mod, $2.shift, 0, &$3, &$5, 2);
501 | INSTR_LRP omods dreg ',' sregs
503 TRACE("LRP\n");
504 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LRP, $2.mod, $2.shift, 0, &$3, &$5, 3);
506 | INSTR_FRC omods dreg ',' sregs
508 TRACE("FRC\n");
509 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_FRC, $2.mod, $2.shift, 0, &$3, &$5, 1);
511 | INSTR_POW omods dreg ',' sregs
513 TRACE("POW\n");
514 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_POW, $2.mod, $2.shift, 0, &$3, &$5, 2);
516 | INSTR_CRS omods dreg ',' sregs
518 TRACE("CRS\n");
519 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_CRS, $2.mod, $2.shift, 0, &$3, &$5, 2);
521 | INSTR_SGN omods dreg ',' sregs
523 TRACE("SGN\n");
524 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_SGN, $2.mod, $2.shift, 0, &$3, &$5, 3);
526 | INSTR_NRM omods dreg ',' sregs
528 TRACE("NRM\n");
529 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_NRM, $2.mod, $2.shift, 0, &$3, &$5, 1);
531 | INSTR_SINCOS omods dreg ',' sregs
533 TRACE("SINCOS\n");
534 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_SINCOS, $2.mod, $2.shift, 0, &$3, &$5, 1);
536 | INSTR_M4x4 omods dreg ',' sregs
538 TRACE("M4x4\n");
539 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_M4x4, $2.mod, $2.shift, 0, &$3, &$5, 2);
541 | INSTR_M4x3 omods dreg ',' sregs
543 TRACE("M4x3\n");
544 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_M4x3, $2.mod, $2.shift, 0, &$3, &$5, 2);
546 | INSTR_M3x4 omods dreg ',' sregs
548 TRACE("M3x4\n");
549 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_M3x4, $2.mod, $2.shift, 0, &$3, &$5, 2);
551 | INSTR_M3x3 omods dreg ',' sregs
553 TRACE("M3x3\n");
554 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_M3x3, $2.mod, $2.shift, 0, &$3, &$5, 2);
556 | INSTR_M3x2 omods dreg ',' sregs
558 TRACE("M3x2\n");
559 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_M3x2, $2.mod, $2.shift, 0, &$3, &$5, 2);
561 | INSTR_DCL dclusage REG_OUTPUT
563 struct shader_reg reg;
564 TRACE("Output reg declaration\n");
565 ZeroMemory(&reg, sizeof(reg));
566 reg.type = BWRITERSPR_OUTPUT;
567 reg.regnum = $3;
568 reg.rel_reg = NULL;
569 reg.srcmod = 0;
570 reg.u.writemask = BWRITERSP_WRITEMASK_ALL;
571 asm_ctx.funcs->dcl_output(&asm_ctx, $2.dclusage, $2.regnum, &reg);
573 | INSTR_DCL dclusage REG_OUTPUT writemask
575 struct shader_reg reg;
576 TRACE("Output reg declaration\n");
577 ZeroMemory(&reg, sizeof(reg));
578 reg.type = BWRITERSPR_OUTPUT;
579 reg.regnum = $3;
580 reg.rel_reg = NULL;
581 reg.srcmod = 0;
582 reg.u.writemask = $4;
583 asm_ctx.funcs->dcl_output(&asm_ctx, $2.dclusage, $2.regnum, &reg);
585 | INSTR_DCL dclusage omods dcl_inputreg
587 struct shader_reg reg;
588 TRACE("Input reg declaration\n");
589 if($3.shift != 0) {
590 asmparser_message(&asm_ctx, "Line %u: Shift modifier not allowed here\n",
591 asm_ctx.line_no);
592 set_parse_status(&asm_ctx.status, PARSE_ERR);
594 if (asm_ctx.shader->type == ST_PIXEL && asm_ctx.shader->major_version == 2)
596 asmparser_message(&asm_ctx, "Line %u: Declaration not supported in PS 2\n",
597 asm_ctx.line_no);
598 set_parse_status(&asm_ctx.status, PARSE_ERR);
600 ZeroMemory(&reg, sizeof(reg));
601 reg.type = $4.type;
602 reg.regnum = $4.regnum;
603 reg.rel_reg = NULL;
604 reg.srcmod = 0;
605 reg.u.writemask = BWRITERSP_WRITEMASK_ALL;
606 asm_ctx.funcs->dcl_input(&asm_ctx, $2.dclusage, $2.regnum, $3.mod, &reg);
608 | INSTR_DCL dclusage omods dcl_inputreg writemask
610 struct shader_reg reg;
611 TRACE("Input reg declaration\n");
612 if($3.shift != 0) {
613 asmparser_message(&asm_ctx, "Line %u: Shift modifier not allowed here\n",
614 asm_ctx.line_no);
615 set_parse_status(&asm_ctx.status, PARSE_ERR);
617 if (asm_ctx.shader->type == ST_PIXEL && asm_ctx.shader->major_version == 2)
619 asmparser_message(&asm_ctx, "Line %u: Declaration not supported in PS 2\n",
620 asm_ctx.line_no);
621 set_parse_status(&asm_ctx.status, PARSE_ERR);
623 ZeroMemory(&reg, sizeof(reg));
624 reg.type = $4.type;
625 reg.regnum = $4.regnum;
626 reg.rel_reg = NULL;
627 reg.srcmod = 0;
628 reg.u.writemask = $5;
629 asm_ctx.funcs->dcl_input(&asm_ctx, $2.dclusage, $2.regnum, $3.mod, &reg);
631 | INSTR_DCL omods dcl_inputreg
633 struct shader_reg reg;
634 TRACE("Input reg declaration\n");
635 if($2.shift != 0) {
636 asmparser_message(&asm_ctx, "Line %u: Shift modifier not allowed here\n",
637 asm_ctx.line_no);
638 set_parse_status(&asm_ctx.status, PARSE_ERR);
640 if(asm_ctx.shader->type != ST_PIXEL) {
641 asmparser_message(&asm_ctx, "Line %u: Declaration needs a semantic\n",
642 asm_ctx.line_no);
643 set_parse_status(&asm_ctx.status, PARSE_ERR);
645 ZeroMemory(&reg, sizeof(reg));
646 reg.type = $3.type;
647 reg.regnum = $3.regnum;
648 reg.rel_reg = NULL;
649 reg.srcmod = 0;
650 reg.u.writemask = BWRITERSP_WRITEMASK_ALL;
651 asm_ctx.funcs->dcl_input(&asm_ctx, 0, 0, $2.mod, &reg);
653 | INSTR_DCL omods dcl_inputreg writemask
655 struct shader_reg reg;
656 TRACE("Input reg declaration\n");
657 if($2.shift != 0) {
658 asmparser_message(&asm_ctx, "Line %u: Shift modifier not allowed here\n",
659 asm_ctx.line_no);
660 set_parse_status(&asm_ctx.status, PARSE_ERR);
662 if(asm_ctx.shader->type != ST_PIXEL) {
663 asmparser_message(&asm_ctx, "Line %u: Declaration needs a semantic\n",
664 asm_ctx.line_no);
665 set_parse_status(&asm_ctx.status, PARSE_ERR);
667 ZeroMemory(&reg, sizeof(reg));
668 reg.type = $3.type;
669 reg.regnum = $3.regnum;
670 reg.rel_reg = NULL;
671 reg.srcmod = 0;
672 reg.u.writemask = $4;
673 asm_ctx.funcs->dcl_input(&asm_ctx, 0, 0, $2.mod, &reg);
675 | INSTR_DCL sampdcl omods REG_SAMPLER
677 TRACE("Sampler declared\n");
678 if($3.shift != 0) {
679 asmparser_message(&asm_ctx, "Line %u: Shift modifier not allowed here\n",
680 asm_ctx.line_no);
681 set_parse_status(&asm_ctx.status, PARSE_ERR);
683 asm_ctx.funcs->dcl_sampler(&asm_ctx, $2, $3.mod, $4, asm_ctx.line_no);
685 | INSTR_DCL omods REG_SAMPLER
687 TRACE("Sampler declared\n");
688 if($2.shift != 0) {
689 asmparser_message(&asm_ctx, "Line %u: Shift modifier not allowed here\n",
690 asm_ctx.line_no);
691 set_parse_status(&asm_ctx.status, PARSE_ERR);
693 if(asm_ctx.shader->type != ST_PIXEL) {
694 asmparser_message(&asm_ctx, "Line %u: Declaration needs a sampler type\n",
695 asm_ctx.line_no);
696 set_parse_status(&asm_ctx.status, PARSE_ERR);
698 asm_ctx.funcs->dcl_sampler(&asm_ctx, BWRITERSTT_UNKNOWN, $2.mod, $3, asm_ctx.line_no);
700 | INSTR_DCL sampdcl omods dcl_inputreg
702 TRACE("Error rule: sampler decl of input reg\n");
703 asmparser_message(&asm_ctx, "Line %u: Sampler declarations of input regs is not valid\n",
704 asm_ctx.line_no);
705 set_parse_status(&asm_ctx.status, PARSE_WARN);
707 | INSTR_DCL sampdcl omods REG_OUTPUT
709 TRACE("Error rule: sampler decl of output reg\n");
710 asmparser_message(&asm_ctx, "Line %u: Sampler declarations of output regs is not valid\n",
711 asm_ctx.line_no);
712 set_parse_status(&asm_ctx.status, PARSE_WARN);
714 | INSTR_DEF REG_CONSTFLOAT ',' IMMVAL ',' IMMVAL ',' IMMVAL ',' IMMVAL
716 asm_ctx.funcs->constF(&asm_ctx, $2, $4.val, $6.val, $8.val, $10.val);
718 | INSTR_DEFI REG_CONSTINT ',' IMMVAL ',' IMMVAL ',' IMMVAL ',' IMMVAL
720 asm_ctx.funcs->constI(&asm_ctx, $2, $4.val, $6.val, $8.val, $10.val);
722 | INSTR_DEFB REG_CONSTBOOL ',' IMMBOOL
724 asm_ctx.funcs->constB(&asm_ctx, $2, $4);
726 | INSTR_REP sregs
728 TRACE("REP\n");
729 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_REP, 0, 0, 0, 0, &$2, 1);
731 | INSTR_ENDREP
733 TRACE("ENDREP\n");
734 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ENDREP, 0, 0, 0, 0, 0, 0);
736 | INSTR_IF sregs
738 TRACE("IF\n");
739 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_IF, 0, 0, 0, 0, &$2, 1);
741 | INSTR_IF comp sregs
743 TRACE("IFC\n");
744 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_IFC, 0, 0, $2, 0, &$3, 2);
746 | INSTR_ELSE
748 TRACE("ELSE\n");
749 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ELSE, 0, 0, 0, 0, 0, 0);
751 | INSTR_ENDIF
753 TRACE("ENDIF\n");
754 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ENDIF, 0, 0, 0, 0, 0, 0);
756 | INSTR_BREAK
758 TRACE("BREAK\n");
759 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_BREAK, 0, 0, 0, 0, 0, 0);
761 | INSTR_BREAK comp sregs
763 TRACE("BREAKC\n");
764 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_BREAKC, 0, 0, $2, 0, &$3, 2);
766 | INSTR_BREAKP sregs
768 TRACE("BREAKP\n");
769 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_BREAKP, 0, 0, 0, 0, &$2, 1);
771 | INSTR_CALL sregs
773 TRACE("CALL\n");
774 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_CALL, 0, 0, 0, 0, &$2, 1);
776 | INSTR_CALLNZ sregs
778 TRACE("CALLNZ\n");
779 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_CALLNZ, 0, 0, 0, 0, &$2, 2);
781 | INSTR_LOOP sregs
783 TRACE("LOOP\n");
784 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LOOP, 0, 0, 0, 0, &$2, 2);
786 | INSTR_RET
788 TRACE("RET\n");
789 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_RET, 0, 0, 0, 0, 0, 0);
791 | INSTR_ENDLOOP
793 TRACE("ENDLOOP\n");
794 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ENDLOOP, 0, 0, 0, 0, 0, 0);
796 | INSTR_LABEL sregs
798 TRACE("LABEL\n");
799 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LABEL, 0, 0, 0, 0, &$2, 1);
801 | INSTR_SETP comp dreg ',' sregs
803 TRACE("SETP\n");
804 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_SETP, 0, 0, $2, &$3, &$5, 2);
806 | INSTR_TEXLDL omods dreg ',' sregs
808 TRACE("TEXLDL\n");
809 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXLDL, $2.mod, $2.shift, 0, &$3, &$5, 2);
811 | INSTR_LIT omods dreg ',' sregs
813 TRACE("LIT\n");
814 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LIT, $2.mod, $2.shift, 0, &$3, &$5, 1);
816 | INSTR_MOVA omods dreg ',' sregs
818 TRACE("MOVA\n");
819 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_MOVA, $2.mod, $2.shift, 0, &$3, &$5, 1);
821 | INSTR_CND omods dreg ',' sregs
823 TRACE("CND\n");
824 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_CND, $2.mod, $2.shift, 0, &$3, &$5, 3);
826 | INSTR_CMP omods dreg ',' sregs
828 TRACE("CMP\n");
829 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_CMP, $2.mod, $2.shift, 0, &$3, &$5, 3);
831 | INSTR_DP2ADD omods dreg ',' sregs
833 TRACE("DP2ADD\n");
834 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_DP2ADD, $2.mod, $2.shift, 0, &$3, &$5, 3);
836 | INSTR_TEXCOORD omods dreg
838 TRACE("TEXCOORD\n");
839 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXCOORD, $2.mod, $2.shift, 0, &$3, 0, 0);
841 | INSTR_TEXCRD omods dreg ',' sregs
843 TRACE("TEXCRD\n");
844 /* texcoord and texcrd share the same opcode */
845 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXCOORD, $2.mod, $2.shift, 0, &$3, &$5, 1);
847 | INSTR_TEXKILL dreg
849 TRACE("TEXKILL\n");
850 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXKILL, 0, 0, 0, &$2, 0, 0);
852 | INSTR_TEX omods dreg
854 TRACE("TEX\n");
855 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEX, $2.mod, $2.shift, 0, &$3, 0, 0);
857 | INSTR_TEXDEPTH omods dreg
859 TRACE("TEXDEPTH\n");
860 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXDEPTH, $2.mod, $2.shift, 0, &$3, 0, 0);
862 | INSTR_TEXLD omods dreg ',' sregs
864 TRACE("TEXLD\n");
865 /* There is more than one acceptable syntax for texld:
866 with 1 sreg (PS 1.4) or
867 with 2 sregs (PS 2.0+)
868 Moreover, texld shares the same opcode as the tex instruction,
869 so there are a total of 3 valid syntaxes
870 These variations are handled in asmparser.c */
871 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEX, $2.mod, $2.shift, 0, &$3, &$5, 2);
873 | INSTR_TEXLDP omods dreg ',' sregs
875 TRACE("TEXLDP\n");
876 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXLDP, $2.mod, $2.shift, 0, &$3, &$5, 2);
878 | INSTR_TEXLDB omods dreg ',' sregs
880 TRACE("TEXLDB\n");
881 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXLDB, $2.mod, $2.shift, 0, &$3, &$5, 2);
883 | INSTR_TEXBEM omods dreg ',' sregs
885 TRACE("TEXBEM\n");
886 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXBEM, $2.mod, $2.shift, 0, &$3, &$5, 1);
888 | INSTR_TEXBEML omods dreg ',' sregs
890 TRACE("TEXBEML\n");
891 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXBEML, $2.mod, $2.shift, 0, &$3, &$5, 1);
893 | INSTR_TEXREG2AR omods dreg ',' sregs
895 TRACE("TEXREG2AR\n");
896 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXREG2AR, $2.mod, $2.shift, 0, &$3, &$5, 1);
898 | INSTR_TEXREG2GB omods dreg ',' sregs
900 TRACE("TEXREG2GB\n");
901 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXREG2GB, $2.mod, $2.shift, 0, &$3, &$5, 1);
903 | INSTR_TEXREG2RGB omods dreg ',' sregs
905 TRACE("TEXREG2RGB\n");
906 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXREG2RGB, $2.mod, $2.shift, 0, &$3, &$5, 1);
908 | INSTR_TEXM3x2PAD omods dreg ',' sregs
910 TRACE("TEXM3x2PAD\n");
911 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXM3x2PAD, $2.mod, $2.shift, 0, &$3, &$5, 1);
913 | INSTR_TEXM3x3PAD omods dreg ',' sregs
915 TRACE("INSTR_TEXM3x3PAD\n");
916 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXM3x3PAD, $2.mod, $2.shift, 0, &$3, &$5, 1);
918 | INSTR_TEXM3x3SPEC omods dreg ',' sregs
920 TRACE("TEXM3x3SPEC\n");
921 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXM3x3SPEC, $2.mod, $2.shift, 0, &$3, &$5, 2);
923 | INSTR_TEXM3x3VSPEC omods dreg ',' sregs
925 TRACE("TEXM3x3VSPEC\n");
926 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXM3x3VSPEC, $2.mod, $2.shift, 0, &$3, &$5, 1);
928 | INSTR_TEXM3x3TEX omods dreg ',' sregs
930 TRACE("TEXM3x3TEX\n");
931 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXM3x3TEX, $2.mod, $2.shift, 0, &$3, &$5, 1);
933 | INSTR_TEXDP3TEX omods dreg ',' sregs
935 TRACE("TEXDP3TEX\n");
936 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXDP3TEX, $2.mod, $2.shift, 0, &$3, &$5, 1);
938 | INSTR_TEXM3x2DEPTH omods dreg ',' sregs
940 TRACE("TEXM3x2DEPTH\n");
941 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXM3x2DEPTH, $2.mod, $2.shift, 0, &$3, &$5, 1);
943 | INSTR_TEXM3x2TEX omods dreg ',' sregs
945 TRACE("TEXM3x2TEX\n");
946 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXM3x2TEX, $2.mod, $2.shift, 0, &$3, &$5, 1);
948 | INSTR_TEXDP3 omods dreg ',' sregs
950 TRACE("TEXDP3\n");
951 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXDP3, $2.mod, $2.shift, 0, &$3, &$5, 1);
953 | INSTR_TEXM3x3 omods dreg ',' sregs
955 TRACE("TEXM3x3\n");
956 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXM3x3, $2.mod, $2.shift, 0, &$3, &$5, 1);
958 | INSTR_BEM omods dreg ',' sregs
960 TRACE("BEM\n");
961 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_BEM, $2.mod, $2.shift, 0, &$3, &$5, 2);
963 | INSTR_DSX omods dreg ',' sregs
965 TRACE("DSX\n");
966 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_DSX, $2.mod, $2.shift, 0, &$3, &$5, 1);
968 | INSTR_DSY omods dreg ',' sregs
970 TRACE("DSY\n");
971 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_DSY, $2.mod, $2.shift, 0, &$3, &$5, 1);
973 | INSTR_TEXLDD omods dreg ',' sregs
975 TRACE("TEXLDD\n");
976 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXLDD, $2.mod, $2.shift, 0, &$3, &$5, 4);
978 | INSTR_PHASE
980 TRACE("PHASE\n");
981 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_PHASE, 0, 0, 0, 0, 0, 0);
985 dreg: dreg_name rel_reg
987 $$.regnum = $1.regnum;
988 $$.type = $1.type;
989 $$.u.writemask = BWRITERSP_WRITEMASK_ALL;
990 $$.srcmod = BWRITERSPSM_NONE;
991 set_rel_reg(&$$, &$2);
993 | dreg_name writemask
995 $$.regnum = $1.regnum;
996 $$.type = $1.type;
997 $$.u.writemask = $2;
998 $$.srcmod = BWRITERSPSM_NONE;
999 $$.rel_reg = NULL;
1002 dreg_name: REG_TEMP
1004 $$.regnum = $1; $$.type = BWRITERSPR_TEMP;
1006 | REG_OUTPUT
1008 $$.regnum = $1; $$.type = BWRITERSPR_OUTPUT;
1010 | REG_INPUT
1012 $$.regnum = $1; $$.type = BWRITERSPR_INPUT;
1014 | REG_CONSTFLOAT
1016 asmparser_message(&asm_ctx, "Line %u: Register c%u is not a valid destination register\n",
1017 asm_ctx.line_no, $1);
1018 set_parse_status(&asm_ctx.status, PARSE_WARN);
1020 | REG_CONSTINT
1022 asmparser_message(&asm_ctx, "Line %u: Register i%u is not a valid destination register\n",
1023 asm_ctx.line_no, $1);
1024 set_parse_status(&asm_ctx.status, PARSE_WARN);
1026 | REG_CONSTBOOL
1028 asmparser_message(&asm_ctx, "Line %u: Register b%u is not a valid destination register\n",
1029 asm_ctx.line_no, $1);
1030 set_parse_status(&asm_ctx.status, PARSE_WARN);
1032 | REG_TEXTURE
1034 $$.regnum = $1; $$.type = BWRITERSPR_TEXTURE;
1036 | REG_TEXCRDOUT
1038 $$.regnum = $1; $$.type = BWRITERSPR_TEXCRDOUT;
1040 | REG_SAMPLER
1042 asmparser_message(&asm_ctx, "Line %u: Register s%u is not a valid destination register\n",
1043 asm_ctx.line_no, $1);
1044 set_parse_status(&asm_ctx.status, PARSE_WARN);
1046 | REG_OPOS
1048 $$.regnum = BWRITERSRO_POSITION; $$.type = BWRITERSPR_RASTOUT;
1050 | REG_OPTS
1052 $$.regnum = BWRITERSRO_POINT_SIZE; $$.type = BWRITERSPR_RASTOUT;
1054 | REG_OFOG
1056 $$.regnum = BWRITERSRO_FOG; $$.type = BWRITERSPR_RASTOUT;
1058 | REG_VERTEXCOLOR
1060 $$.regnum = $1; $$.type = BWRITERSPR_ATTROUT;
1062 | REG_FRAGCOLOR
1064 $$.regnum = $1; $$.type = BWRITERSPR_COLOROUT;
1066 | REG_FRAGDEPTH
1068 $$.regnum = 0; $$.type = BWRITERSPR_DEPTHOUT;
1070 | REG_PREDICATE
1072 $$.regnum = 0; $$.type = BWRITERSPR_PREDICATE;
1074 | REG_VPOS
1076 asmparser_message(&asm_ctx, "Line %u: Register vPos is not a valid destination register\n",
1077 asm_ctx.line_no);
1078 set_parse_status(&asm_ctx.status, PARSE_WARN);
1080 | REG_VFACE
1082 asmparser_message(&asm_ctx, "Line %u: Register vFace is not a valid destination register\n",
1083 asm_ctx.line_no);
1084 set_parse_status(&asm_ctx.status, PARSE_WARN);
1086 | REG_ADDRESS
1088 /* index 0 is hardcoded for the addr register */
1089 $$.regnum = 0; $$.type = BWRITERSPR_ADDR;
1091 | REG_LOOP
1093 asmparser_message(&asm_ctx, "Line %u: Register aL is not a valid destination register\n",
1094 asm_ctx.line_no);
1095 set_parse_status(&asm_ctx.status, PARSE_WARN);
1098 writemask: '.' wm_components
1100 if($2.writemask == SWIZZLE_ERR) {
1101 asmparser_message(&asm_ctx, "Line %u: Invalid writemask specified\n",
1102 asm_ctx.line_no);
1103 set_parse_status(&asm_ctx.status, PARSE_ERR);
1104 /* Provide a correct writemask to prevent following complaints */
1105 $$ = BWRITERSP_WRITEMASK_ALL;
1107 else {
1108 $$ = $2.writemask;
1109 TRACE("Writemask: %x\n", $$);
1113 wm_components: COMPONENT
1115 $$.writemask = 1 << $1;
1116 $$.last = $1;
1117 $$.idx = 1;
1119 | wm_components COMPONENT
1121 if($1.writemask == SWIZZLE_ERR || $1.idx == 4)
1122 /* Wrong writemask */
1123 $$.writemask = SWIZZLE_ERR;
1124 else {
1125 if($2 <= $1.last)
1126 $$.writemask = SWIZZLE_ERR;
1127 else {
1128 $$.writemask = $1.writemask | (1 << $2);
1129 $$.idx = $1.idx + 1;
1134 swizzle: /* empty */
1136 $$ = BWRITERVS_NOSWIZZLE;
1137 TRACE("Default swizzle: %08x\n", $$);
1139 | '.' sw_components
1141 if($2.swizzle == SWIZZLE_ERR) {
1142 asmparser_message(&asm_ctx, "Line %u: Invalid swizzle\n",
1143 asm_ctx.line_no);
1144 set_parse_status(&asm_ctx.status, PARSE_ERR);
1145 /* Provide a correct swizzle to prevent following complaints */
1146 $$ = BWRITERVS_NOSWIZZLE;
1148 else {
1149 DWORD last, i;
1151 $$ = $2.swizzle;
1152 /* Fill the swizzle by extending the last component */
1153 last = ($2.swizzle >> 2 * ($2.idx - 1)) & 0x03;
1154 for(i = $2.idx; i < 4; i++){
1155 $$ |= last << (2 * i);
1157 TRACE("Got a swizzle: %08x\n", $$);
1161 sw_components: COMPONENT
1163 $$.swizzle = $1;
1164 $$.idx = 1;
1166 | sw_components COMPONENT
1168 if($1.idx == 4) {
1169 /* Too many sw_components */
1170 $$.swizzle = SWIZZLE_ERR;
1171 $$.idx = 4;
1173 else {
1174 $$.swizzle = $1.swizzle | ($2 << 2 * $1.idx);
1175 $$.idx = $1.idx + 1;
1179 omods: /* Empty */
1181 $$.mod = 0;
1182 $$.shift = 0;
1184 | omods omodifier
1186 $$.mod = $1.mod | $2.mod;
1187 if($1.shift && $2.shift) {
1188 asmparser_message(&asm_ctx, "Line %u: More than one shift flag\n",
1189 asm_ctx.line_no);
1190 set_parse_status(&asm_ctx.status, PARSE_ERR);
1191 $$.shift = $1.shift;
1192 } else {
1193 $$.shift = $1.shift | $2.shift;
1197 omodifier: SHIFT_X2
1199 $$.mod = 0;
1200 $$.shift = 1;
1202 | SHIFT_X4
1204 $$.mod = 0;
1205 $$.shift = 2;
1207 | SHIFT_X8
1209 $$.mod = 0;
1210 $$.shift = 3;
1212 | SHIFT_D2
1214 $$.mod = 0;
1215 $$.shift = 15;
1217 | SHIFT_D4
1219 $$.mod = 0;
1220 $$.shift = 14;
1222 | SHIFT_D8
1224 $$.mod = 0;
1225 $$.shift = 13;
1227 | MOD_SAT
1229 $$.mod = BWRITERSPDM_SATURATE;
1230 $$.shift = 0;
1232 | MOD_PP
1234 $$.mod = BWRITERSPDM_PARTIALPRECISION;
1235 $$.shift = 0;
1237 | MOD_CENTROID
1239 $$.mod = BWRITERSPDM_MSAMPCENTROID;
1240 $$.shift = 0;
1243 sregs: sreg
1245 $$.reg[0] = $1;
1246 $$.count = 1;
1248 | sregs ',' sreg
1250 if($$.count == MAX_SRC_REGS){
1251 asmparser_message(&asm_ctx, "Line %u: Too many source registers in this instruction\n",
1252 asm_ctx.line_no);
1253 set_parse_status(&asm_ctx.status, PARSE_ERR);
1255 else
1256 $$.reg[$$.count++] = $3;
1259 sreg: sreg_name rel_reg swizzle
1261 $$.type = $1.type;
1262 $$.regnum = $1.regnum;
1263 $$.u.swizzle = $3;
1264 $$.srcmod = BWRITERSPSM_NONE;
1265 set_rel_reg(&$$, &$2);
1267 | sreg_name rel_reg smod swizzle
1269 $$.type = $1.type;
1270 $$.regnum = $1.regnum;
1271 set_rel_reg(&$$, &$2);
1272 $$.srcmod = $3;
1273 $$.u.swizzle = $4;
1275 | '-' sreg_name rel_reg swizzle
1277 $$.type = $2.type;
1278 $$.regnum = $2.regnum;
1279 $$.srcmod = BWRITERSPSM_NEG;
1280 set_rel_reg(&$$, &$3);
1281 $$.u.swizzle = $4;
1283 | '-' sreg_name rel_reg smod swizzle
1285 $$.type = $2.type;
1286 $$.regnum = $2.regnum;
1287 set_rel_reg(&$$, &$3);
1288 switch($4) {
1289 case BWRITERSPSM_BIAS: $$.srcmod = BWRITERSPSM_BIASNEG; break;
1290 case BWRITERSPSM_X2: $$.srcmod = BWRITERSPSM_X2NEG; break;
1291 case BWRITERSPSM_SIGN: $$.srcmod = BWRITERSPSM_SIGNNEG; break;
1292 case BWRITERSPSM_ABS: $$.srcmod = BWRITERSPSM_ABSNEG; break;
1293 case BWRITERSPSM_DZ:
1294 asmparser_message(&asm_ctx, "Line %u: Incompatible source modifiers: NEG and DZ\n",
1295 asm_ctx.line_no);
1296 set_parse_status(&asm_ctx.status, PARSE_ERR);
1297 break;
1298 case BWRITERSPSM_DW:
1299 asmparser_message(&asm_ctx, "Line %u: Incompatible source modifiers: NEG and DW\n",
1300 asm_ctx.line_no);
1301 set_parse_status(&asm_ctx.status, PARSE_ERR);
1302 break;
1303 default:
1304 FIXME("Unhandled combination of NEGATE and %u\n", $4);
1306 $$.u.swizzle = $5;
1308 | IMMVAL '-' sreg_name rel_reg swizzle
1310 if($1.val != 1.0 || (!$1.integer)) {
1311 asmparser_message(&asm_ctx, "Line %u: Only \"1 - reg\" is valid for D3DSPSM_COMP, "
1312 "%g - reg found\n", asm_ctx.line_no, $1.val);
1313 set_parse_status(&asm_ctx.status, PARSE_ERR);
1315 /* Complement - not compatible with other source modifiers */
1316 $$.type = $3.type;
1317 $$.regnum = $3.regnum;
1318 $$.srcmod = BWRITERSPSM_COMP;
1319 set_rel_reg(&$$, &$4);
1320 $$.u.swizzle = $5;
1322 | IMMVAL '-' sreg_name rel_reg smod swizzle
1324 /* For nicer error reporting */
1325 if($1.val != 1.0 || (!$1.integer)) {
1326 asmparser_message(&asm_ctx, "Line %u: Only \"1 - reg\" is valid for D3DSPSM_COMP\n",
1327 asm_ctx.line_no);
1328 set_parse_status(&asm_ctx.status, PARSE_ERR);
1329 } else {
1330 asmparser_message(&asm_ctx, "Line %u: Incompatible source modifiers: D3DSPSM_COMP and %s\n",
1331 asm_ctx.line_no,
1332 debug_print_srcmod($5));
1333 set_parse_status(&asm_ctx.status, PARSE_ERR);
1336 | SMOD_NOT sreg_name swizzle
1338 $$.type = $2.type;
1339 $$.regnum = $2.regnum;
1340 $$.rel_reg = NULL;
1341 $$.srcmod = BWRITERSPSM_NOT;
1342 $$.u.swizzle = $3;
1345 rel_reg: /* empty */
1347 $$.has_rel_reg = FALSE;
1348 $$.additional_offset = 0;
1350 | '[' immsum ']'
1352 $$.has_rel_reg = FALSE;
1353 $$.additional_offset = $2.val;
1355 | '[' relreg_name swizzle ']'
1357 $$.has_rel_reg = TRUE;
1358 $$.type = $2.type;
1359 $$.additional_offset = 0;
1360 $$.rel_regnum = $2.regnum;
1361 $$.swizzle = $3;
1363 | '[' immsum '+' relreg_name swizzle ']'
1365 $$.has_rel_reg = TRUE;
1366 $$.type = $4.type;
1367 $$.additional_offset = $2.val;
1368 $$.rel_regnum = $4.regnum;
1369 $$.swizzle = $5;
1371 | '[' relreg_name swizzle '+' immsum ']'
1373 $$.has_rel_reg = TRUE;
1374 $$.type = $2.type;
1375 $$.additional_offset = $5.val;
1376 $$.rel_regnum = $2.regnum;
1377 $$.swizzle = $3;
1379 | '[' immsum '+' relreg_name swizzle '+' immsum ']'
1381 $$.has_rel_reg = TRUE;
1382 $$.type = $4.type;
1383 $$.additional_offset = $2.val + $7.val;
1384 $$.rel_regnum = $4.regnum;
1385 $$.swizzle = $5;
1388 immsum: IMMVAL
1390 if(!$1.integer) {
1391 asmparser_message(&asm_ctx, "Line %u: Unexpected float %f\n",
1392 asm_ctx.line_no, $1.val);
1393 set_parse_status(&asm_ctx.status, PARSE_ERR);
1395 $$.val = $1.val;
1397 | immsum '+' IMMVAL
1399 if(!$3.integer) {
1400 asmparser_message(&asm_ctx, "Line %u: Unexpected float %f\n",
1401 asm_ctx.line_no, $3.val);
1402 set_parse_status(&asm_ctx.status, PARSE_ERR);
1404 $$.val = $1.val + $3.val;
1407 smod: SMOD_BIAS
1409 $$ = BWRITERSPSM_BIAS;
1411 | SHIFT_X2
1413 $$ = BWRITERSPSM_X2;
1415 | SMOD_SCALEBIAS
1417 $$ = BWRITERSPSM_SIGN;
1419 | SMOD_DZ
1421 $$ = BWRITERSPSM_DZ;
1423 | SMOD_DW
1425 $$ = BWRITERSPSM_DW;
1427 | SMOD_ABS
1429 $$ = BWRITERSPSM_ABS;
1432 relreg_name: REG_ADDRESS
1434 $$.regnum = 0; $$.type = BWRITERSPR_ADDR;
1436 | REG_LOOP
1438 $$.regnum = 0; $$.type = BWRITERSPR_LOOP;
1441 sreg_name: REG_TEMP
1443 $$.regnum = $1; $$.type = BWRITERSPR_TEMP;
1445 | REG_OUTPUT
1447 asmparser_message(&asm_ctx, "Line %u: Register o%u is not a valid source register\n",
1448 asm_ctx.line_no, $1);
1449 set_parse_status(&asm_ctx.status, PARSE_WARN);
1451 | REG_INPUT
1453 $$.regnum = $1; $$.type = BWRITERSPR_INPUT;
1455 | REG_CONSTFLOAT
1457 $$.regnum = $1; $$.type = BWRITERSPR_CONST;
1459 | REG_CONSTINT
1461 $$.regnum = $1; $$.type = BWRITERSPR_CONSTINT;
1463 | REG_CONSTBOOL
1465 $$.regnum = $1; $$.type = BWRITERSPR_CONSTBOOL;
1467 | REG_TEXTURE
1469 $$.regnum = $1; $$.type = BWRITERSPR_TEXTURE;
1471 | REG_TEXCRDOUT
1473 asmparser_message(&asm_ctx, "Line %u: Register oT%u is not a valid source register\n",
1474 asm_ctx.line_no, $1);
1475 set_parse_status(&asm_ctx.status, PARSE_WARN);
1477 | REG_SAMPLER
1479 $$.regnum = $1; $$.type = BWRITERSPR_SAMPLER;
1481 | REG_OPOS
1483 asmparser_message(&asm_ctx, "Line %u: Register oPos is not a valid source register\n",
1484 asm_ctx.line_no);
1485 set_parse_status(&asm_ctx.status, PARSE_WARN);
1487 | REG_OFOG
1489 asmparser_message(&asm_ctx, "Line %u: Register oFog is not a valid source register\n",
1490 asm_ctx.line_no);
1491 set_parse_status(&asm_ctx.status, PARSE_WARN);
1493 | REG_VERTEXCOLOR
1495 asmparser_message(&asm_ctx, "Line %u: Register oD%u is not a valid source register\n",
1496 asm_ctx.line_no, $1);
1497 set_parse_status(&asm_ctx.status, PARSE_WARN);
1499 | REG_FRAGCOLOR
1501 asmparser_message(&asm_ctx, "Line %u: Register oC%u is not a valid source register\n",
1502 asm_ctx.line_no, $1);
1503 set_parse_status(&asm_ctx.status, PARSE_WARN);
1505 | REG_FRAGDEPTH
1507 asmparser_message(&asm_ctx, "Line %u: Register oDepth is not a valid source register\n",
1508 asm_ctx.line_no);
1509 set_parse_status(&asm_ctx.status, PARSE_WARN);
1511 | REG_PREDICATE
1513 $$.regnum = 0; $$.type = BWRITERSPR_PREDICATE;
1515 | REG_VPOS
1517 $$.regnum = 0; $$.type = BWRITERSPR_MISCTYPE;
1519 | REG_VFACE
1521 $$.regnum = 1; $$.type = BWRITERSPR_MISCTYPE;
1523 | REG_ADDRESS
1525 $$.regnum = 0; $$.type = BWRITERSPR_ADDR;
1527 | REG_LOOP
1529 $$.regnum = 0; $$.type = BWRITERSPR_LOOP;
1531 | REG_LABEL
1533 $$.regnum = $1; $$.type = BWRITERSPR_LABEL;
1536 comp: COMP_GT { $$ = BWRITER_COMPARISON_GT; }
1537 | COMP_LT { $$ = BWRITER_COMPARISON_LT; }
1538 | COMP_GE { $$ = BWRITER_COMPARISON_GE; }
1539 | COMP_LE { $$ = BWRITER_COMPARISON_LE; }
1540 | COMP_EQ { $$ = BWRITER_COMPARISON_EQ; }
1541 | COMP_NE { $$ = BWRITER_COMPARISON_NE; }
1543 dclusage: USAGE_POSITION
1545 TRACE("dcl_position%u\n", $1);
1546 $$.regnum = $1;
1547 $$.dclusage = BWRITERDECLUSAGE_POSITION;
1549 | USAGE_BLENDWEIGHT
1551 TRACE("dcl_blendweight%u\n", $1);
1552 $$.regnum = $1;
1553 $$.dclusage = BWRITERDECLUSAGE_BLENDWEIGHT;
1555 | USAGE_BLENDINDICES
1557 TRACE("dcl_blendindices%u\n", $1);
1558 $$.regnum = $1;
1559 $$.dclusage = BWRITERDECLUSAGE_BLENDINDICES;
1561 | USAGE_NORMAL
1563 TRACE("dcl_normal%u\n", $1);
1564 $$.regnum = $1;
1565 $$.dclusage = BWRITERDECLUSAGE_NORMAL;
1567 | USAGE_PSIZE
1569 TRACE("dcl_psize%u\n", $1);
1570 $$.regnum = $1;
1571 $$.dclusage = BWRITERDECLUSAGE_PSIZE;
1573 | USAGE_TEXCOORD
1575 TRACE("dcl_texcoord%u\n", $1);
1576 $$.regnum = $1;
1577 $$.dclusage = BWRITERDECLUSAGE_TEXCOORD;
1579 | USAGE_TANGENT
1581 TRACE("dcl_tangent%u\n", $1);
1582 $$.regnum = $1;
1583 $$.dclusage = BWRITERDECLUSAGE_TANGENT;
1585 | USAGE_BINORMAL
1587 TRACE("dcl_binormal%u\n", $1);
1588 $$.regnum = $1;
1589 $$.dclusage = BWRITERDECLUSAGE_BINORMAL;
1591 | USAGE_TESSFACTOR
1593 TRACE("dcl_tessfactor%u\n", $1);
1594 $$.regnum = $1;
1595 $$.dclusage = BWRITERDECLUSAGE_TESSFACTOR;
1597 | USAGE_POSITIONT
1599 TRACE("dcl_positiont%u\n", $1);
1600 $$.regnum = $1;
1601 $$.dclusage = BWRITERDECLUSAGE_POSITIONT;
1603 | USAGE_COLOR
1605 TRACE("dcl_color%u\n", $1);
1606 $$.regnum = $1;
1607 $$.dclusage = BWRITERDECLUSAGE_COLOR;
1609 | USAGE_FOG
1611 TRACE("dcl_fog%u\n", $1);
1612 $$.regnum = $1;
1613 $$.dclusage = BWRITERDECLUSAGE_FOG;
1615 | USAGE_DEPTH
1617 TRACE("dcl_depth%u\n", $1);
1618 $$.regnum = $1;
1619 $$.dclusage = BWRITERDECLUSAGE_DEPTH;
1621 | USAGE_SAMPLE
1623 TRACE("dcl_sample%u\n", $1);
1624 $$.regnum = $1;
1625 $$.dclusage = BWRITERDECLUSAGE_SAMPLE;
1628 dcl_inputreg: REG_INPUT
1630 $$.regnum = $1; $$.type = BWRITERSPR_INPUT;
1632 | REG_TEXTURE
1634 $$.regnum = $1; $$.type = BWRITERSPR_TEXTURE;
1637 sampdcl: SAMPTYPE_1D
1639 $$ = BWRITERSTT_1D;
1641 | SAMPTYPE_2D
1643 $$ = BWRITERSTT_2D;
1645 | SAMPTYPE_CUBE
1647 $$ = BWRITERSTT_CUBE;
1649 | SAMPTYPE_VOLUME
1651 $$ = BWRITERSTT_VOLUME;
1654 predicate: '(' REG_PREDICATE swizzle ')'
1656 $$.type = BWRITERSPR_PREDICATE;
1657 $$.regnum = 0;
1658 $$.rel_reg = NULL;
1659 $$.srcmod = BWRITERSPSM_NONE;
1660 $$.u.swizzle = $3;
1662 | '(' SMOD_NOT REG_PREDICATE swizzle ')'
1664 $$.type = BWRITERSPR_PREDICATE;
1665 $$.regnum = 0;
1666 $$.rel_reg = NULL;
1667 $$.srcmod = BWRITERSPSM_NOT;
1668 $$.u.swizzle = $4;
1673 struct bwriter_shader *parse_asm_shader(char **messages)
1675 struct bwriter_shader *ret = NULL;
1677 asm_ctx.shader = NULL;
1678 asm_ctx.status = PARSE_SUCCESS;
1679 asm_ctx.messages.size = asm_ctx.messages.capacity = 0;
1680 asm_ctx.line_no = 1;
1682 asmshader_parse();
1684 if (asm_ctx.status != PARSE_ERR)
1685 ret = asm_ctx.shader;
1686 else if (asm_ctx.shader)
1687 SlDeleteShader(asm_ctx.shader);
1689 if (messages)
1691 if (asm_ctx.messages.size)
1693 /* Shrink the buffer to the used size */
1694 *messages = d3dcompiler_realloc(asm_ctx.messages.string, asm_ctx.messages.size + 1);
1695 if (!*messages)
1697 ERR("Out of memory, no messages reported\n");
1698 d3dcompiler_free(asm_ctx.messages.string);
1701 else
1703 *messages = NULL;
1706 else
1708 if (asm_ctx.messages.capacity)
1709 d3dcompiler_free(asm_ctx.messages.string);
1712 return ret;