comctl32/tests: Flush events before testing edit control IME messages.
[wine.git] / dlls / d3dcompiler_43 / asmshader.y
blobcdc75c18a3edef53e40b034d75ccfd48d3f6539e
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 va_list args;
35 va_start(args, fmt);
36 compilation_message(&ctx->messages, fmt, args);
37 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->swizzle = rel->swizzle;
58 reg->rel_reg->regnum = rel->rel_regnum;
62 /* Needed lexer functions declarations */
63 int asmshader_lex(void);
68 %define api.prefix {asmshader_}
70 %union {
71 struct {
72 float val;
73 BOOL integer;
74 } immval;
75 BOOL immbool;
76 unsigned int regnum;
77 struct shader_reg reg;
78 uint32_t srcmod;
79 uint32_t writemask;
80 struct {
81 uint32_t writemask;
82 uint32_t idx;
83 uint32_t last;
84 } wm_components;
85 uint32_t swizzle;
86 struct {
87 uint32_t swizzle;
88 uint32_t idx;
89 } sw_components;
90 uint32_t component;
91 struct {
92 uint32_t mod;
93 uint32_t shift;
94 } modshift;
95 enum bwriter_comparison_type comptype;
96 struct {
97 uint32_t dclusage;
98 unsigned int regnum;
99 } declaration;
100 enum bwritersampler_texture_type samplertype;
101 struct rel_reg rel_reg;
102 struct src_regs sregs;
105 /* Common instructions between vertex and pixel shaders */
106 %token INSTR_ADD
107 %token INSTR_NOP
108 %token INSTR_MOV
109 %token INSTR_SUB
110 %token INSTR_MAD
111 %token INSTR_MUL
112 %token INSTR_RCP
113 %token INSTR_RSQ
114 %token INSTR_DP3
115 %token INSTR_DP4
116 %token INSTR_MIN
117 %token INSTR_MAX
118 %token INSTR_SLT
119 %token INSTR_SGE
120 %token INSTR_ABS
121 %token INSTR_EXP
122 %token INSTR_LOG
123 %token INSTR_EXPP
124 %token INSTR_LOGP
125 %token INSTR_DST
126 %token INSTR_LRP
127 %token INSTR_FRC
128 %token INSTR_POW
129 %token INSTR_CRS
130 %token INSTR_SGN
131 %token INSTR_NRM
132 %token INSTR_SINCOS
133 %token INSTR_M4x4
134 %token INSTR_M4x3
135 %token INSTR_M3x4
136 %token INSTR_M3x3
137 %token INSTR_M3x2
138 %token INSTR_DCL
139 %token INSTR_DEF
140 %token INSTR_DEFB
141 %token INSTR_DEFI
142 %token INSTR_REP
143 %token INSTR_ENDREP
144 %token INSTR_IF
145 %token INSTR_ELSE
146 %token INSTR_ENDIF
147 %token INSTR_BREAK
148 %token INSTR_BREAKP
149 %token INSTR_CALL
150 %token INSTR_CALLNZ
151 %token INSTR_LOOP
152 %token INSTR_RET
153 %token INSTR_ENDLOOP
154 %token INSTR_LABEL
155 %token INSTR_SETP
156 %token INSTR_TEXLDL
158 /* Vertex shader only instructions */
159 %token INSTR_LIT
160 %token INSTR_MOVA
162 /* Pixel shader only instructions */
163 %token INSTR_CND
164 %token INSTR_CMP
165 %token INSTR_DP2ADD
166 %token INSTR_TEXCOORD
167 %token INSTR_TEXCRD
168 %token INSTR_TEXKILL
169 %token INSTR_TEX
170 %token INSTR_TEXLD
171 %token INSTR_TEXBEM
172 %token INSTR_TEXBEML
173 %token INSTR_TEXREG2AR
174 %token INSTR_TEXREG2GB
175 %token INSTR_TEXREG2RGB
176 %token INSTR_TEXM3x2PAD
177 %token INSTR_TEXM3x2TEX
178 %token INSTR_TEXM3x3PAD
179 %token INSTR_TEXM3x3SPEC
180 %token INSTR_TEXM3x3VSPEC
181 %token INSTR_TEXM3x3TEX
182 %token INSTR_TEXDP3TEX
183 %token INSTR_TEXM3x2DEPTH
184 %token INSTR_TEXDP3
185 %token INSTR_TEXM3x3
186 %token INSTR_TEXDEPTH
187 %token INSTR_BEM
188 %token INSTR_DSX
189 %token INSTR_DSY
190 %token INSTR_TEXLDP
191 %token INSTR_TEXLDB
192 %token INSTR_TEXLDD
193 %token INSTR_PHASE
195 /* Registers */
196 %token <regnum> REG_TEMP
197 %token <regnum> REG_OUTPUT
198 %token <regnum> REG_INPUT
199 %token <regnum> REG_CONSTFLOAT
200 %token <regnum> REG_CONSTINT
201 %token <regnum> REG_CONSTBOOL
202 %token <regnum> REG_TEXTURE
203 %token <regnum> REG_SAMPLER
204 %token <regnum> REG_TEXCRDOUT
205 %token REG_OPOS
206 %token REG_OFOG
207 %token REG_OPTS
208 %token <regnum> REG_VERTEXCOLOR
209 %token <regnum> REG_FRAGCOLOR
210 %token REG_FRAGDEPTH
211 %token REG_VPOS
212 %token REG_VFACE
213 %token REG_ADDRESS
214 %token REG_LOOP
215 %token REG_PREDICATE
216 %token <regnum> REG_LABEL
218 /* Version tokens */
219 %token VER_VS10
220 %token VER_VS11
221 %token VER_VS20
222 %token VER_VS2X
223 %token VER_VS30
225 %token VER_PS10
226 %token VER_PS11
227 %token VER_PS12
228 %token VER_PS13
229 %token VER_PS14
230 %token VER_PS20
231 %token VER_PS2X
232 %token VER_PS30
234 /* Output modifiers */
235 %token SHIFT_X2
236 %token SHIFT_X4
237 %token SHIFT_X8
238 %token SHIFT_D2
239 %token SHIFT_D4
240 %token SHIFT_D8
241 %token MOD_SAT
242 %token MOD_PP
243 %token MOD_CENTROID
245 /* Compare tokens */
246 %token COMP_GT
247 %token COMP_LT
248 %token COMP_GE
249 %token COMP_LE
250 %token COMP_EQ
251 %token COMP_NE
253 /* Source register modifiers */
254 %token SMOD_BIAS
255 %token SMOD_SCALEBIAS
256 %token SMOD_DZ
257 %token SMOD_DW
258 %token SMOD_ABS
259 %token SMOD_NOT
261 /* Sampler types */
262 %token SAMPTYPE_1D
263 %token SAMPTYPE_2D
264 %token SAMPTYPE_CUBE
265 %token SAMPTYPE_VOLUME
267 /* Usage declaration tokens */
268 %token <regnum> USAGE_POSITION
269 %token <regnum> USAGE_BLENDWEIGHT
270 %token <regnum> USAGE_BLENDINDICES
271 %token <regnum> USAGE_NORMAL
272 %token <regnum> USAGE_PSIZE
273 %token <regnum> USAGE_TEXCOORD
274 %token <regnum> USAGE_TANGENT
275 %token <regnum> USAGE_BINORMAL
276 %token <regnum> USAGE_TESSFACTOR
277 %token <regnum> USAGE_POSITIONT
278 %token <regnum> USAGE_COLOR
279 %token <regnum> USAGE_FOG
280 %token <regnum> USAGE_DEPTH
281 %token <regnum> USAGE_SAMPLE
283 /* Misc stuff */
284 %token <component> COMPONENT
285 %token <immval> IMMVAL
286 %token <immbool> IMMBOOL
288 %type <reg> dreg_name
289 %type <reg> dreg
290 %type <reg> sreg_name
291 %type <reg> relreg_name
292 %type <reg> sreg
293 %type <srcmod> smod
294 %type <writemask> writemask
295 %type <wm_components> wm_components
296 %type <swizzle> swizzle
297 %type <sw_components> sw_components
298 %type <modshift> omods
299 %type <modshift> omodifier
300 %type <comptype> comp
301 %type <declaration> dclusage
302 %type <reg> dcl_inputreg
303 %type <samplertype> sampdcl
304 %type <rel_reg> rel_reg
305 %type <reg> predicate
306 %type <immval> immsum
307 %type <immval> signed_integer
308 %type <immval> signed_float
309 %type <sregs> sregs
313 shader: version_marker instructions
315 asm_ctx.funcs->end(&asm_ctx);
318 version_marker: VER_VS10
320 TRACE("Vertex shader 1.0\n");
321 create_vs10_parser(&asm_ctx);
323 | VER_VS11
325 TRACE("Vertex shader 1.1\n");
326 create_vs11_parser(&asm_ctx);
328 | VER_VS20
330 TRACE("Vertex shader 2.0\n");
331 create_vs20_parser(&asm_ctx);
333 | VER_VS2X
335 TRACE("Vertex shader 2.x\n");
336 create_vs2x_parser(&asm_ctx);
338 | VER_VS30
340 TRACE("Vertex shader 3.0\n");
341 create_vs30_parser(&asm_ctx);
343 | VER_PS10
345 TRACE("Pixel shader 1.0\n");
346 create_ps10_parser(&asm_ctx);
348 | VER_PS11
350 TRACE("Pixel shader 1.1\n");
351 create_ps11_parser(&asm_ctx);
353 | VER_PS12
355 TRACE("Pixel shader 1.2\n");
356 create_ps12_parser(&asm_ctx);
358 | VER_PS13
360 TRACE("Pixel shader 1.3\n");
361 create_ps13_parser(&asm_ctx);
363 | VER_PS14
365 TRACE("Pixel shader 1.4\n");
366 create_ps14_parser(&asm_ctx);
368 | VER_PS20
370 TRACE("Pixel shader 2.0\n");
371 create_ps20_parser(&asm_ctx);
373 | VER_PS2X
375 TRACE("Pixel shader 2.x\n");
376 create_ps2x_parser(&asm_ctx);
378 | VER_PS30
380 TRACE("Pixel shader 3.0\n");
381 create_ps30_parser(&asm_ctx);
384 instructions: /* empty */
385 | instructions complexinstr
387 /* Nothing to do */
390 complexinstr: instruction
394 | predicate instruction
396 TRACE("predicate\n");
397 asm_ctx.funcs->predicate(&asm_ctx, &$1);
399 | '+' instruction
401 TRACE("coissue\n");
402 asm_ctx.funcs->coissue(&asm_ctx);
405 instruction: INSTR_ADD omods dreg ',' sregs
407 TRACE("ADD\n");
408 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ADD, $2.mod, $2.shift, 0, &$3, &$5, 2);
410 | INSTR_NOP
412 TRACE("NOP\n");
413 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_NOP, 0, 0, 0, 0, 0, 0);
415 | INSTR_MOV omods dreg ',' sregs
417 TRACE("MOV\n");
418 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_MOV, $2.mod, $2.shift, 0, &$3, &$5, 1);
420 | INSTR_SUB omods dreg ',' sregs
422 TRACE("SUB\n");
423 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_SUB, $2.mod, $2.shift, 0, &$3, &$5, 2);
425 | INSTR_MAD omods dreg ',' sregs
427 TRACE("MAD\n");
428 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_MAD, $2.mod, $2.shift, 0, &$3, &$5, 3);
430 | INSTR_MUL omods dreg ',' sregs
432 TRACE("MUL\n");
433 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_MUL, $2.mod, $2.shift, 0, &$3, &$5, 2);
435 | INSTR_RCP omods dreg ',' sregs
437 TRACE("RCP\n");
438 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_RCP, $2.mod, $2.shift, 0, &$3, &$5, 1);
440 | INSTR_RSQ omods dreg ',' sregs
442 TRACE("RSQ\n");
443 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_RSQ, $2.mod, $2.shift, 0, &$3, &$5, 1);
445 | INSTR_DP3 omods dreg ',' sregs
447 TRACE("DP3\n");
448 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_DP3, $2.mod, $2.shift, 0, &$3, &$5, 2);
450 | INSTR_DP4 omods dreg ',' sregs
452 TRACE("DP4\n");
453 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_DP4, $2.mod, $2.shift, 0, &$3, &$5, 2);
455 | INSTR_MIN omods dreg ',' sregs
457 TRACE("MIN\n");
458 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_MIN, $2.mod, $2.shift, 0, &$3, &$5, 2);
460 | INSTR_MAX omods dreg ',' sregs
462 TRACE("MAX\n");
463 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_MAX, $2.mod, $2.shift, 0, &$3, &$5, 2);
465 | INSTR_SLT omods dreg ',' sregs
467 TRACE("SLT\n");
468 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_SLT, $2.mod, $2.shift, 0, &$3, &$5, 2);
470 | INSTR_SGE omods dreg ',' sregs
472 TRACE("SGE\n");
473 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_SGE, $2.mod, $2.shift, 0, &$3, &$5, 2);
475 | INSTR_ABS omods dreg ',' sregs
477 TRACE("ABS\n");
478 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ABS, $2.mod, $2.shift, 0, &$3, &$5, 1);
480 | INSTR_EXP omods dreg ',' sregs
482 TRACE("EXP\n");
483 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_EXP, $2.mod, $2.shift, 0, &$3, &$5, 1);
485 | INSTR_LOG omods dreg ',' sregs
487 TRACE("LOG\n");
488 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LOG, $2.mod, $2.shift, 0, &$3, &$5, 1);
490 | INSTR_LOGP omods dreg ',' sregs
492 TRACE("LOGP\n");
493 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LOGP, $2.mod, $2.shift, 0, &$3, &$5, 1);
495 | INSTR_EXPP omods dreg ',' sregs
497 TRACE("EXPP\n");
498 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_EXPP, $2.mod, $2.shift, 0, &$3, &$5, 1);
500 | INSTR_DST omods dreg ',' sregs
502 TRACE("DST\n");
503 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_DST, $2.mod, $2.shift, 0, &$3, &$5, 2);
505 | INSTR_LRP omods dreg ',' sregs
507 TRACE("LRP\n");
508 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LRP, $2.mod, $2.shift, 0, &$3, &$5, 3);
510 | INSTR_FRC omods dreg ',' sregs
512 TRACE("FRC\n");
513 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_FRC, $2.mod, $2.shift, 0, &$3, &$5, 1);
515 | INSTR_POW omods dreg ',' sregs
517 TRACE("POW\n");
518 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_POW, $2.mod, $2.shift, 0, &$3, &$5, 2);
520 | INSTR_CRS omods dreg ',' sregs
522 TRACE("CRS\n");
523 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_CRS, $2.mod, $2.shift, 0, &$3, &$5, 2);
525 | INSTR_SGN omods dreg ',' sregs
527 TRACE("SGN\n");
528 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_SGN, $2.mod, $2.shift, 0, &$3, &$5, 3);
530 | INSTR_NRM omods dreg ',' sregs
532 TRACE("NRM\n");
533 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_NRM, $2.mod, $2.shift, 0, &$3, &$5, 1);
535 | INSTR_SINCOS omods dreg ',' sregs
537 TRACE("SINCOS\n");
538 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_SINCOS, $2.mod, $2.shift, 0, &$3, &$5, 1);
540 | INSTR_M4x4 omods dreg ',' sregs
542 TRACE("M4x4\n");
543 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_M4x4, $2.mod, $2.shift, 0, &$3, &$5, 2);
545 | INSTR_M4x3 omods dreg ',' sregs
547 TRACE("M4x3\n");
548 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_M4x3, $2.mod, $2.shift, 0, &$3, &$5, 2);
550 | INSTR_M3x4 omods dreg ',' sregs
552 TRACE("M3x4\n");
553 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_M3x4, $2.mod, $2.shift, 0, &$3, &$5, 2);
555 | INSTR_M3x3 omods dreg ',' sregs
557 TRACE("M3x3\n");
558 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_M3x3, $2.mod, $2.shift, 0, &$3, &$5, 2);
560 | INSTR_M3x2 omods dreg ',' sregs
562 TRACE("M3x2\n");
563 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_M3x2, $2.mod, $2.shift, 0, &$3, &$5, 2);
565 | INSTR_DCL dclusage REG_OUTPUT
567 struct shader_reg reg;
568 TRACE("Output reg declaration\n");
569 ZeroMemory(&reg, sizeof(reg));
570 reg.type = BWRITERSPR_OUTPUT;
571 reg.regnum = $3;
572 reg.rel_reg = NULL;
573 reg.srcmod = 0;
574 reg.writemask = BWRITERSP_WRITEMASK_ALL;
575 asm_ctx.funcs->dcl_output(&asm_ctx, $2.dclusage, $2.regnum, &reg);
577 | INSTR_DCL dclusage REG_OUTPUT writemask
579 struct shader_reg reg;
580 TRACE("Output reg declaration\n");
581 ZeroMemory(&reg, sizeof(reg));
582 reg.type = BWRITERSPR_OUTPUT;
583 reg.regnum = $3;
584 reg.rel_reg = NULL;
585 reg.srcmod = 0;
586 reg.writemask = $4;
587 asm_ctx.funcs->dcl_output(&asm_ctx, $2.dclusage, $2.regnum, &reg);
589 | INSTR_DCL dclusage omods dcl_inputreg
591 struct shader_reg reg;
592 TRACE("Input reg declaration\n");
593 if($3.shift != 0) {
594 asmparser_message(&asm_ctx, "Line %u: Shift modifier not allowed here\n",
595 asm_ctx.line_no);
596 set_parse_status(&asm_ctx.status, PARSE_ERR);
598 if (asm_ctx.shader->type == ST_PIXEL && asm_ctx.shader->major_version == 2)
600 asmparser_message(&asm_ctx, "Line %u: Declaration not supported in PS 2\n",
601 asm_ctx.line_no);
602 set_parse_status(&asm_ctx.status, PARSE_ERR);
604 ZeroMemory(&reg, sizeof(reg));
605 reg.type = $4.type;
606 reg.regnum = $4.regnum;
607 reg.rel_reg = NULL;
608 reg.srcmod = 0;
609 reg.writemask = BWRITERSP_WRITEMASK_ALL;
610 asm_ctx.funcs->dcl_input(&asm_ctx, $2.dclusage, $2.regnum, $3.mod, &reg);
612 | INSTR_DCL dclusage omods dcl_inputreg writemask
614 struct shader_reg reg;
615 TRACE("Input reg declaration\n");
616 if($3.shift != 0) {
617 asmparser_message(&asm_ctx, "Line %u: Shift modifier not allowed here\n",
618 asm_ctx.line_no);
619 set_parse_status(&asm_ctx.status, PARSE_ERR);
621 if (asm_ctx.shader->type == ST_PIXEL && asm_ctx.shader->major_version == 2)
623 asmparser_message(&asm_ctx, "Line %u: Declaration not supported in PS 2\n",
624 asm_ctx.line_no);
625 set_parse_status(&asm_ctx.status, PARSE_ERR);
627 ZeroMemory(&reg, sizeof(reg));
628 reg.type = $4.type;
629 reg.regnum = $4.regnum;
630 reg.rel_reg = NULL;
631 reg.srcmod = 0;
632 reg.writemask = $5;
633 asm_ctx.funcs->dcl_input(&asm_ctx, $2.dclusage, $2.regnum, $3.mod, &reg);
635 | INSTR_DCL omods dcl_inputreg
637 struct shader_reg reg;
638 TRACE("Input reg declaration\n");
639 if($2.shift != 0) {
640 asmparser_message(&asm_ctx, "Line %u: Shift modifier not allowed here\n",
641 asm_ctx.line_no);
642 set_parse_status(&asm_ctx.status, PARSE_ERR);
644 if(asm_ctx.shader->type != ST_PIXEL) {
645 asmparser_message(&asm_ctx, "Line %u: Declaration needs a semantic\n",
646 asm_ctx.line_no);
647 set_parse_status(&asm_ctx.status, PARSE_ERR);
649 ZeroMemory(&reg, sizeof(reg));
650 reg.type = $3.type;
651 reg.regnum = $3.regnum;
652 reg.rel_reg = NULL;
653 reg.srcmod = 0;
654 reg.writemask = BWRITERSP_WRITEMASK_ALL;
655 asm_ctx.funcs->dcl_input(&asm_ctx, 0, 0, $2.mod, &reg);
657 | INSTR_DCL omods dcl_inputreg writemask
659 struct shader_reg reg;
660 TRACE("Input reg declaration\n");
661 if($2.shift != 0) {
662 asmparser_message(&asm_ctx, "Line %u: Shift modifier not allowed here\n",
663 asm_ctx.line_no);
664 set_parse_status(&asm_ctx.status, PARSE_ERR);
666 if(asm_ctx.shader->type != ST_PIXEL) {
667 asmparser_message(&asm_ctx, "Line %u: Declaration needs a semantic\n",
668 asm_ctx.line_no);
669 set_parse_status(&asm_ctx.status, PARSE_ERR);
671 ZeroMemory(&reg, sizeof(reg));
672 reg.type = $3.type;
673 reg.regnum = $3.regnum;
674 reg.rel_reg = NULL;
675 reg.srcmod = 0;
676 reg.writemask = $4;
677 asm_ctx.funcs->dcl_input(&asm_ctx, 0, 0, $2.mod, &reg);
679 | INSTR_DCL sampdcl omods REG_SAMPLER
681 TRACE("Sampler declared\n");
682 if($3.shift != 0) {
683 asmparser_message(&asm_ctx, "Line %u: Shift modifier not allowed here\n",
684 asm_ctx.line_no);
685 set_parse_status(&asm_ctx.status, PARSE_ERR);
687 asm_ctx.funcs->dcl_sampler(&asm_ctx, $2, $3.mod, $4, asm_ctx.line_no);
689 | INSTR_DCL omods REG_SAMPLER
691 TRACE("Sampler declared\n");
692 if($2.shift != 0) {
693 asmparser_message(&asm_ctx, "Line %u: Shift modifier not allowed here\n",
694 asm_ctx.line_no);
695 set_parse_status(&asm_ctx.status, PARSE_ERR);
697 if(asm_ctx.shader->type != ST_PIXEL) {
698 asmparser_message(&asm_ctx, "Line %u: Declaration needs a sampler type\n",
699 asm_ctx.line_no);
700 set_parse_status(&asm_ctx.status, PARSE_ERR);
702 asm_ctx.funcs->dcl_sampler(&asm_ctx, BWRITERSTT_UNKNOWN, $2.mod, $3, asm_ctx.line_no);
704 | INSTR_DCL sampdcl omods dcl_inputreg
706 TRACE("Error rule: sampler decl of input reg\n");
707 asmparser_message(&asm_ctx, "Line %u: Sampler declarations of input regs is not valid\n",
708 asm_ctx.line_no);
709 set_parse_status(&asm_ctx.status, PARSE_WARN);
711 | INSTR_DCL sampdcl omods REG_OUTPUT
713 TRACE("Error rule: sampler decl of output reg\n");
714 asmparser_message(&asm_ctx, "Line %u: Sampler declarations of output regs is not valid\n",
715 asm_ctx.line_no);
716 set_parse_status(&asm_ctx.status, PARSE_WARN);
718 | INSTR_DEF REG_CONSTFLOAT ',' signed_float ',' signed_float ',' signed_float ',' signed_float
720 asm_ctx.funcs->constF(&asm_ctx, $2, $4.val, $6.val, $8.val, $10.val);
722 | INSTR_DEFI REG_CONSTINT ',' signed_integer ',' signed_integer ',' signed_integer ',' signed_integer
724 asm_ctx.funcs->constI(&asm_ctx, $2, $4.val, $6.val, $8.val, $10.val);
726 | INSTR_DEFB REG_CONSTBOOL ',' IMMBOOL
728 asm_ctx.funcs->constB(&asm_ctx, $2, $4);
730 | INSTR_REP sregs
732 TRACE("REP\n");
733 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_REP, 0, 0, 0, 0, &$2, 1);
735 | INSTR_ENDREP
737 TRACE("ENDREP\n");
738 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ENDREP, 0, 0, 0, 0, 0, 0);
740 | INSTR_IF sregs
742 TRACE("IF\n");
743 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_IF, 0, 0, 0, 0, &$2, 1);
745 | INSTR_IF comp sregs
747 TRACE("IFC\n");
748 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_IFC, 0, 0, $2, 0, &$3, 2);
750 | INSTR_ELSE
752 TRACE("ELSE\n");
753 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ELSE, 0, 0, 0, 0, 0, 0);
755 | INSTR_ENDIF
757 TRACE("ENDIF\n");
758 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ENDIF, 0, 0, 0, 0, 0, 0);
760 | INSTR_BREAK
762 TRACE("BREAK\n");
763 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_BREAK, 0, 0, 0, 0, 0, 0);
765 | INSTR_BREAK comp sregs
767 TRACE("BREAKC\n");
768 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_BREAKC, 0, 0, $2, 0, &$3, 2);
770 | INSTR_BREAKP sregs
772 TRACE("BREAKP\n");
773 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_BREAKP, 0, 0, 0, 0, &$2, 1);
775 | INSTR_CALL sregs
777 TRACE("CALL\n");
778 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_CALL, 0, 0, 0, 0, &$2, 1);
780 | INSTR_CALLNZ sregs
782 TRACE("CALLNZ\n");
783 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_CALLNZ, 0, 0, 0, 0, &$2, 2);
785 | INSTR_LOOP sregs
787 TRACE("LOOP\n");
788 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LOOP, 0, 0, 0, 0, &$2, 2);
790 | INSTR_RET
792 TRACE("RET\n");
793 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_RET, 0, 0, 0, 0, 0, 0);
795 | INSTR_ENDLOOP
797 TRACE("ENDLOOP\n");
798 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ENDLOOP, 0, 0, 0, 0, 0, 0);
800 | INSTR_LABEL sregs
802 TRACE("LABEL\n");
803 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LABEL, 0, 0, 0, 0, &$2, 1);
805 | INSTR_SETP comp dreg ',' sregs
807 TRACE("SETP\n");
808 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_SETP, 0, 0, $2, &$3, &$5, 2);
810 | INSTR_TEXLDL omods dreg ',' sregs
812 TRACE("TEXLDL\n");
813 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXLDL, $2.mod, $2.shift, 0, &$3, &$5, 2);
815 | INSTR_LIT omods dreg ',' sregs
817 TRACE("LIT\n");
818 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LIT, $2.mod, $2.shift, 0, &$3, &$5, 1);
820 | INSTR_MOVA omods dreg ',' sregs
822 TRACE("MOVA\n");
823 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_MOVA, $2.mod, $2.shift, 0, &$3, &$5, 1);
825 | INSTR_CND omods dreg ',' sregs
827 TRACE("CND\n");
828 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_CND, $2.mod, $2.shift, 0, &$3, &$5, 3);
830 | INSTR_CMP omods dreg ',' sregs
832 TRACE("CMP\n");
833 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_CMP, $2.mod, $2.shift, 0, &$3, &$5, 3);
835 | INSTR_DP2ADD omods dreg ',' sregs
837 TRACE("DP2ADD\n");
838 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_DP2ADD, $2.mod, $2.shift, 0, &$3, &$5, 3);
840 | INSTR_TEXCOORD omods dreg
842 TRACE("TEXCOORD\n");
843 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXCOORD, $2.mod, $2.shift, 0, &$3, 0, 0);
845 | INSTR_TEXCRD omods dreg ',' sregs
847 TRACE("TEXCRD\n");
848 /* texcoord and texcrd share the same opcode */
849 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXCOORD, $2.mod, $2.shift, 0, &$3, &$5, 1);
851 | INSTR_TEXKILL dreg
853 TRACE("TEXKILL\n");
854 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXKILL, 0, 0, 0, &$2, 0, 0);
856 | INSTR_TEX omods dreg
858 TRACE("TEX\n");
859 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEX, $2.mod, $2.shift, 0, &$3, 0, 0);
861 | INSTR_TEXDEPTH omods dreg
863 TRACE("TEXDEPTH\n");
864 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXDEPTH, $2.mod, $2.shift, 0, &$3, 0, 0);
866 | INSTR_TEXLD omods dreg ',' sregs
868 TRACE("TEXLD\n");
869 /* There is more than one acceptable syntax for texld:
870 with 1 sreg (PS 1.4) or
871 with 2 sregs (PS 2.0+)
872 Moreover, texld shares the same opcode as the tex instruction,
873 so there are a total of 3 valid syntaxes
874 These variations are handled in asmparser.c */
875 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEX, $2.mod, $2.shift, 0, &$3, &$5, 2);
877 | INSTR_TEXLDP omods dreg ',' sregs
879 TRACE("TEXLDP\n");
880 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXLDP, $2.mod, $2.shift, 0, &$3, &$5, 2);
882 | INSTR_TEXLDB omods dreg ',' sregs
884 TRACE("TEXLDB\n");
885 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXLDB, $2.mod, $2.shift, 0, &$3, &$5, 2);
887 | INSTR_TEXBEM omods dreg ',' sregs
889 TRACE("TEXBEM\n");
890 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXBEM, $2.mod, $2.shift, 0, &$3, &$5, 1);
892 | INSTR_TEXBEML omods dreg ',' sregs
894 TRACE("TEXBEML\n");
895 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXBEML, $2.mod, $2.shift, 0, &$3, &$5, 1);
897 | INSTR_TEXREG2AR omods dreg ',' sregs
899 TRACE("TEXREG2AR\n");
900 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXREG2AR, $2.mod, $2.shift, 0, &$3, &$5, 1);
902 | INSTR_TEXREG2GB omods dreg ',' sregs
904 TRACE("TEXREG2GB\n");
905 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXREG2GB, $2.mod, $2.shift, 0, &$3, &$5, 1);
907 | INSTR_TEXREG2RGB omods dreg ',' sregs
909 TRACE("TEXREG2RGB\n");
910 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXREG2RGB, $2.mod, $2.shift, 0, &$3, &$5, 1);
912 | INSTR_TEXM3x2PAD omods dreg ',' sregs
914 TRACE("TEXM3x2PAD\n");
915 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXM3x2PAD, $2.mod, $2.shift, 0, &$3, &$5, 1);
917 | INSTR_TEXM3x3PAD omods dreg ',' sregs
919 TRACE("INSTR_TEXM3x3PAD\n");
920 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXM3x3PAD, $2.mod, $2.shift, 0, &$3, &$5, 1);
922 | INSTR_TEXM3x3SPEC omods dreg ',' sregs
924 TRACE("TEXM3x3SPEC\n");
925 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXM3x3SPEC, $2.mod, $2.shift, 0, &$3, &$5, 2);
927 | INSTR_TEXM3x3VSPEC omods dreg ',' sregs
929 TRACE("TEXM3x3VSPEC\n");
930 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXM3x3VSPEC, $2.mod, $2.shift, 0, &$3, &$5, 1);
932 | INSTR_TEXM3x3TEX omods dreg ',' sregs
934 TRACE("TEXM3x3TEX\n");
935 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXM3x3TEX, $2.mod, $2.shift, 0, &$3, &$5, 1);
937 | INSTR_TEXDP3TEX omods dreg ',' sregs
939 TRACE("TEXDP3TEX\n");
940 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXDP3TEX, $2.mod, $2.shift, 0, &$3, &$5, 1);
942 | INSTR_TEXM3x2DEPTH omods dreg ',' sregs
944 TRACE("TEXM3x2DEPTH\n");
945 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXM3x2DEPTH, $2.mod, $2.shift, 0, &$3, &$5, 1);
947 | INSTR_TEXM3x2TEX omods dreg ',' sregs
949 TRACE("TEXM3x2TEX\n");
950 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXM3x2TEX, $2.mod, $2.shift, 0, &$3, &$5, 1);
952 | INSTR_TEXDP3 omods dreg ',' sregs
954 TRACE("TEXDP3\n");
955 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXDP3, $2.mod, $2.shift, 0, &$3, &$5, 1);
957 | INSTR_TEXM3x3 omods dreg ',' sregs
959 TRACE("TEXM3x3\n");
960 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXM3x3, $2.mod, $2.shift, 0, &$3, &$5, 1);
962 | INSTR_BEM omods dreg ',' sregs
964 TRACE("BEM\n");
965 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_BEM, $2.mod, $2.shift, 0, &$3, &$5, 2);
967 | INSTR_DSX omods dreg ',' sregs
969 TRACE("DSX\n");
970 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_DSX, $2.mod, $2.shift, 0, &$3, &$5, 1);
972 | INSTR_DSY omods dreg ',' sregs
974 TRACE("DSY\n");
975 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_DSY, $2.mod, $2.shift, 0, &$3, &$5, 1);
977 | INSTR_TEXLDD omods dreg ',' sregs
979 TRACE("TEXLDD\n");
980 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXLDD, $2.mod, $2.shift, 0, &$3, &$5, 4);
982 | INSTR_PHASE
984 TRACE("PHASE\n");
985 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_PHASE, 0, 0, 0, 0, 0, 0);
989 dreg: dreg_name rel_reg
991 $$.regnum = $1.regnum;
992 $$.type = $1.type;
993 $$.writemask = BWRITERSP_WRITEMASK_ALL;
994 $$.srcmod = BWRITERSPSM_NONE;
995 set_rel_reg(&$$, &$2);
997 | dreg_name writemask
999 $$.regnum = $1.regnum;
1000 $$.type = $1.type;
1001 $$.writemask = $2;
1002 $$.srcmod = BWRITERSPSM_NONE;
1003 $$.rel_reg = NULL;
1006 dreg_name: REG_TEMP
1008 $$.regnum = $1; $$.type = BWRITERSPR_TEMP;
1010 | REG_OUTPUT
1012 $$.regnum = $1; $$.type = BWRITERSPR_OUTPUT;
1014 | REG_INPUT
1016 $$.regnum = $1; $$.type = BWRITERSPR_INPUT;
1018 | REG_CONSTFLOAT
1020 asmparser_message(&asm_ctx, "Line %u: Register c%u is not a valid destination register\n",
1021 asm_ctx.line_no, $1);
1022 set_parse_status(&asm_ctx.status, PARSE_WARN);
1024 | REG_CONSTINT
1026 asmparser_message(&asm_ctx, "Line %u: Register i%u is not a valid destination register\n",
1027 asm_ctx.line_no, $1);
1028 set_parse_status(&asm_ctx.status, PARSE_WARN);
1030 | REG_CONSTBOOL
1032 asmparser_message(&asm_ctx, "Line %u: Register b%u is not a valid destination register\n",
1033 asm_ctx.line_no, $1);
1034 set_parse_status(&asm_ctx.status, PARSE_WARN);
1036 | REG_TEXTURE
1038 $$.regnum = $1; $$.type = BWRITERSPR_TEXTURE;
1040 | REG_TEXCRDOUT
1042 $$.regnum = $1; $$.type = BWRITERSPR_TEXCRDOUT;
1044 | REG_SAMPLER
1046 asmparser_message(&asm_ctx, "Line %u: Register s%u is not a valid destination register\n",
1047 asm_ctx.line_no, $1);
1048 set_parse_status(&asm_ctx.status, PARSE_WARN);
1050 | REG_OPOS
1052 $$.regnum = BWRITERSRO_POSITION; $$.type = BWRITERSPR_RASTOUT;
1054 | REG_OPTS
1056 $$.regnum = BWRITERSRO_POINT_SIZE; $$.type = BWRITERSPR_RASTOUT;
1058 | REG_OFOG
1060 $$.regnum = BWRITERSRO_FOG; $$.type = BWRITERSPR_RASTOUT;
1062 | REG_VERTEXCOLOR
1064 $$.regnum = $1; $$.type = BWRITERSPR_ATTROUT;
1066 | REG_FRAGCOLOR
1068 $$.regnum = $1; $$.type = BWRITERSPR_COLOROUT;
1070 | REG_FRAGDEPTH
1072 $$.regnum = 0; $$.type = BWRITERSPR_DEPTHOUT;
1074 | REG_PREDICATE
1076 $$.regnum = 0; $$.type = BWRITERSPR_PREDICATE;
1078 | REG_VPOS
1080 asmparser_message(&asm_ctx, "Line %u: Register vPos is not a valid destination register\n",
1081 asm_ctx.line_no);
1082 set_parse_status(&asm_ctx.status, PARSE_WARN);
1084 | REG_VFACE
1086 asmparser_message(&asm_ctx, "Line %u: Register vFace is not a valid destination register\n",
1087 asm_ctx.line_no);
1088 set_parse_status(&asm_ctx.status, PARSE_WARN);
1090 | REG_ADDRESS
1092 /* index 0 is hardcoded for the addr register */
1093 $$.regnum = 0; $$.type = BWRITERSPR_ADDR;
1095 | REG_LOOP
1097 asmparser_message(&asm_ctx, "Line %u: Register aL is not a valid destination register\n",
1098 asm_ctx.line_no);
1099 set_parse_status(&asm_ctx.status, PARSE_WARN);
1102 writemask: '.' wm_components
1104 if($2.writemask == SWIZZLE_ERR) {
1105 asmparser_message(&asm_ctx, "Line %u: Invalid writemask specified\n",
1106 asm_ctx.line_no);
1107 set_parse_status(&asm_ctx.status, PARSE_ERR);
1108 /* Provide a correct writemask to prevent following complaints */
1109 $$ = BWRITERSP_WRITEMASK_ALL;
1111 else {
1112 $$ = $2.writemask;
1113 TRACE("Writemask: %x\n", $$);
1117 wm_components: COMPONENT
1119 $$.writemask = 1 << $1;
1120 $$.last = $1;
1121 $$.idx = 1;
1123 | wm_components COMPONENT
1125 if($1.writemask == SWIZZLE_ERR || $1.idx == 4)
1126 /* Wrong writemask */
1127 $$.writemask = SWIZZLE_ERR;
1128 else {
1129 if($2 <= $1.last)
1130 $$.writemask = SWIZZLE_ERR;
1131 else {
1132 $$.writemask = $1.writemask | (1 << $2);
1133 $$.idx = $1.idx + 1;
1138 swizzle: /* empty */
1140 $$ = BWRITERVS_NOSWIZZLE;
1141 TRACE("Default swizzle: %08x\n", $$);
1143 | '.' sw_components
1145 if($2.swizzle == SWIZZLE_ERR) {
1146 asmparser_message(&asm_ctx, "Line %u: Invalid swizzle\n",
1147 asm_ctx.line_no);
1148 set_parse_status(&asm_ctx.status, PARSE_ERR);
1149 /* Provide a correct swizzle to prevent following complaints */
1150 $$ = BWRITERVS_NOSWIZZLE;
1152 else {
1153 uint32_t last, i;
1155 $$ = $2.swizzle;
1156 /* Fill the swizzle by extending the last component */
1157 last = ($2.swizzle >> 2 * ($2.idx - 1)) & 0x03;
1158 for(i = $2.idx; i < 4; i++){
1159 $$ |= last << (2 * i);
1161 TRACE("Got a swizzle: %08x\n", $$);
1165 sw_components: COMPONENT
1167 $$.swizzle = $1;
1168 $$.idx = 1;
1170 | sw_components COMPONENT
1172 if($1.idx == 4) {
1173 /* Too many sw_components */
1174 $$.swizzle = SWIZZLE_ERR;
1175 $$.idx = 4;
1177 else {
1178 $$.swizzle = $1.swizzle | ($2 << 2 * $1.idx);
1179 $$.idx = $1.idx + 1;
1183 omods: /* Empty */
1185 $$.mod = 0;
1186 $$.shift = 0;
1188 | omods omodifier
1190 $$.mod = $1.mod | $2.mod;
1191 if($1.shift && $2.shift) {
1192 asmparser_message(&asm_ctx, "Line %u: More than one shift flag\n",
1193 asm_ctx.line_no);
1194 set_parse_status(&asm_ctx.status, PARSE_ERR);
1195 $$.shift = $1.shift;
1196 } else {
1197 $$.shift = $1.shift | $2.shift;
1201 omodifier: SHIFT_X2
1203 $$.mod = 0;
1204 $$.shift = 1;
1206 | SHIFT_X4
1208 $$.mod = 0;
1209 $$.shift = 2;
1211 | SHIFT_X8
1213 $$.mod = 0;
1214 $$.shift = 3;
1216 | SHIFT_D2
1218 $$.mod = 0;
1219 $$.shift = 15;
1221 | SHIFT_D4
1223 $$.mod = 0;
1224 $$.shift = 14;
1226 | SHIFT_D8
1228 $$.mod = 0;
1229 $$.shift = 13;
1231 | MOD_SAT
1233 $$.mod = BWRITERSPDM_SATURATE;
1234 $$.shift = 0;
1236 | MOD_PP
1238 $$.mod = BWRITERSPDM_PARTIALPRECISION;
1239 $$.shift = 0;
1241 | MOD_CENTROID
1243 $$.mod = BWRITERSPDM_MSAMPCENTROID;
1244 $$.shift = 0;
1247 sregs: sreg
1249 $$.reg[0] = $1;
1250 $$.count = 1;
1252 | sregs ',' sreg
1254 if($$.count == MAX_SRC_REGS){
1255 asmparser_message(&asm_ctx, "Line %u: Too many source registers in this instruction\n",
1256 asm_ctx.line_no);
1257 set_parse_status(&asm_ctx.status, PARSE_ERR);
1259 else
1260 $$.reg[$$.count++] = $3;
1263 sreg: sreg_name rel_reg swizzle
1265 $$.type = $1.type;
1266 $$.regnum = $1.regnum;
1267 $$.swizzle = $3;
1268 $$.srcmod = BWRITERSPSM_NONE;
1269 set_rel_reg(&$$, &$2);
1271 | sreg_name rel_reg smod swizzle
1273 $$.type = $1.type;
1274 $$.regnum = $1.regnum;
1275 set_rel_reg(&$$, &$2);
1276 $$.srcmod = $3;
1277 $$.swizzle = $4;
1279 | '-' sreg_name rel_reg swizzle
1281 $$.type = $2.type;
1282 $$.regnum = $2.regnum;
1283 $$.srcmod = BWRITERSPSM_NEG;
1284 set_rel_reg(&$$, &$3);
1285 $$.swizzle = $4;
1287 | '-' sreg_name rel_reg smod swizzle
1289 $$.type = $2.type;
1290 $$.regnum = $2.regnum;
1291 set_rel_reg(&$$, &$3);
1292 switch($4) {
1293 case BWRITERSPSM_BIAS: $$.srcmod = BWRITERSPSM_BIASNEG; break;
1294 case BWRITERSPSM_X2: $$.srcmod = BWRITERSPSM_X2NEG; break;
1295 case BWRITERSPSM_SIGN: $$.srcmod = BWRITERSPSM_SIGNNEG; break;
1296 case BWRITERSPSM_ABS: $$.srcmod = BWRITERSPSM_ABSNEG; break;
1297 case BWRITERSPSM_DZ:
1298 asmparser_message(&asm_ctx, "Line %u: Incompatible source modifiers: NEG and DZ\n",
1299 asm_ctx.line_no);
1300 set_parse_status(&asm_ctx.status, PARSE_ERR);
1301 break;
1302 case BWRITERSPSM_DW:
1303 asmparser_message(&asm_ctx, "Line %u: Incompatible source modifiers: NEG and DW\n",
1304 asm_ctx.line_no);
1305 set_parse_status(&asm_ctx.status, PARSE_ERR);
1306 break;
1307 default:
1308 FIXME("Unhandled combination of NEGATE and %u\n", $4);
1310 $$.swizzle = $5;
1312 | IMMVAL '-' sreg_name rel_reg swizzle
1314 if($1.val != 1.0 || (!$1.integer)) {
1315 asmparser_message(&asm_ctx, "Line %u: Only \"1 - reg\" is valid for D3DSPSM_COMP, "
1316 "%g - reg found\n", asm_ctx.line_no, $1.val);
1317 set_parse_status(&asm_ctx.status, PARSE_ERR);
1319 /* Complement - not compatible with other source modifiers */
1320 $$.type = $3.type;
1321 $$.regnum = $3.regnum;
1322 $$.srcmod = BWRITERSPSM_COMP;
1323 set_rel_reg(&$$, &$4);
1324 $$.swizzle = $5;
1326 | IMMVAL '-' sreg_name rel_reg smod swizzle
1328 /* For nicer error reporting */
1329 if($1.val != 1.0 || (!$1.integer)) {
1330 asmparser_message(&asm_ctx, "Line %u: Only \"1 - reg\" is valid for D3DSPSM_COMP\n",
1331 asm_ctx.line_no);
1332 set_parse_status(&asm_ctx.status, PARSE_ERR);
1333 } else {
1334 asmparser_message(&asm_ctx, "Line %u: Incompatible source modifiers: D3DSPSM_COMP and %s\n",
1335 asm_ctx.line_no,
1336 debug_print_srcmod($5));
1337 set_parse_status(&asm_ctx.status, PARSE_ERR);
1340 | SMOD_NOT sreg_name swizzle
1342 $$.type = $2.type;
1343 $$.regnum = $2.regnum;
1344 $$.rel_reg = NULL;
1345 $$.srcmod = BWRITERSPSM_NOT;
1346 $$.swizzle = $3;
1349 rel_reg: /* empty */
1351 $$.has_rel_reg = FALSE;
1352 $$.additional_offset = 0;
1354 | '[' immsum ']'
1356 $$.has_rel_reg = FALSE;
1357 $$.additional_offset = $2.val;
1359 | '[' relreg_name swizzle ']'
1361 $$.has_rel_reg = TRUE;
1362 $$.type = $2.type;
1363 $$.additional_offset = 0;
1364 $$.rel_regnum = $2.regnum;
1365 $$.swizzle = $3;
1367 | '[' immsum '+' relreg_name swizzle ']'
1369 $$.has_rel_reg = TRUE;
1370 $$.type = $4.type;
1371 $$.additional_offset = $2.val;
1372 $$.rel_regnum = $4.regnum;
1373 $$.swizzle = $5;
1375 | '[' relreg_name swizzle '+' immsum ']'
1377 $$.has_rel_reg = TRUE;
1378 $$.type = $2.type;
1379 $$.additional_offset = $5.val;
1380 $$.rel_regnum = $2.regnum;
1381 $$.swizzle = $3;
1383 | '[' immsum '+' relreg_name swizzle '+' immsum ']'
1385 $$.has_rel_reg = TRUE;
1386 $$.type = $4.type;
1387 $$.additional_offset = $2.val + $7.val;
1388 $$.rel_regnum = $4.regnum;
1389 $$.swizzle = $5;
1392 immsum: signed_integer
1393 | immsum '+' signed_integer
1395 $$.val = $1.val + $3.val;
1397 | immsum '-' signed_integer
1399 $$.val = $1.val - $3.val;
1402 signed_integer:
1403 IMMVAL
1405 if (!$1.integer)
1407 asmparser_message(&asm_ctx, "Line %u: Unexpected float %f\n",
1408 asm_ctx.line_no, $1.val);
1409 set_parse_status(&asm_ctx.status, PARSE_ERR);
1411 $$.val = $1.val;
1413 | '-' IMMVAL
1415 if (!$2.integer)
1417 asmparser_message(&asm_ctx, "Line %u: Unexpected float %f\n",
1418 asm_ctx.line_no, $2.val);
1419 set_parse_status(&asm_ctx.status, PARSE_ERR);
1421 $$.val = -$2.val;
1424 signed_float:
1425 IMMVAL
1427 $$.val = $1.val;
1429 | '-' IMMVAL
1431 $$.val = -$2.val;
1434 smod: SMOD_BIAS
1436 $$ = BWRITERSPSM_BIAS;
1438 | SHIFT_X2
1440 $$ = BWRITERSPSM_X2;
1442 | SMOD_SCALEBIAS
1444 $$ = BWRITERSPSM_SIGN;
1446 | SMOD_DZ
1448 $$ = BWRITERSPSM_DZ;
1450 | SMOD_DW
1452 $$ = BWRITERSPSM_DW;
1454 | SMOD_ABS
1456 $$ = BWRITERSPSM_ABS;
1459 relreg_name: REG_ADDRESS
1461 $$.regnum = 0; $$.type = BWRITERSPR_ADDR;
1463 | REG_LOOP
1465 $$.regnum = 0; $$.type = BWRITERSPR_LOOP;
1468 sreg_name: REG_TEMP
1470 $$.regnum = $1; $$.type = BWRITERSPR_TEMP;
1472 | REG_OUTPUT
1474 asmparser_message(&asm_ctx, "Line %u: Register o%u is not a valid source register\n",
1475 asm_ctx.line_no, $1);
1476 set_parse_status(&asm_ctx.status, PARSE_WARN);
1478 | REG_INPUT
1480 $$.regnum = $1; $$.type = BWRITERSPR_INPUT;
1482 | REG_CONSTFLOAT
1484 $$.regnum = $1; $$.type = BWRITERSPR_CONST;
1486 | REG_CONSTINT
1488 $$.regnum = $1; $$.type = BWRITERSPR_CONSTINT;
1490 | REG_CONSTBOOL
1492 $$.regnum = $1; $$.type = BWRITERSPR_CONSTBOOL;
1494 | REG_TEXTURE
1496 $$.regnum = $1; $$.type = BWRITERSPR_TEXTURE;
1498 | REG_TEXCRDOUT
1500 asmparser_message(&asm_ctx, "Line %u: Register oT%u is not a valid source register\n",
1501 asm_ctx.line_no, $1);
1502 set_parse_status(&asm_ctx.status, PARSE_WARN);
1504 | REG_SAMPLER
1506 $$.regnum = $1; $$.type = BWRITERSPR_SAMPLER;
1508 | REG_OPOS
1510 asmparser_message(&asm_ctx, "Line %u: Register oPos is not a valid source register\n",
1511 asm_ctx.line_no);
1512 set_parse_status(&asm_ctx.status, PARSE_WARN);
1514 | REG_OFOG
1516 asmparser_message(&asm_ctx, "Line %u: Register oFog is not a valid source register\n",
1517 asm_ctx.line_no);
1518 set_parse_status(&asm_ctx.status, PARSE_WARN);
1520 | REG_VERTEXCOLOR
1522 asmparser_message(&asm_ctx, "Line %u: Register oD%u is not a valid source register\n",
1523 asm_ctx.line_no, $1);
1524 set_parse_status(&asm_ctx.status, PARSE_WARN);
1526 | REG_FRAGCOLOR
1528 asmparser_message(&asm_ctx, "Line %u: Register oC%u is not a valid source register\n",
1529 asm_ctx.line_no, $1);
1530 set_parse_status(&asm_ctx.status, PARSE_WARN);
1532 | REG_FRAGDEPTH
1534 asmparser_message(&asm_ctx, "Line %u: Register oDepth is not a valid source register\n",
1535 asm_ctx.line_no);
1536 set_parse_status(&asm_ctx.status, PARSE_WARN);
1538 | REG_PREDICATE
1540 $$.regnum = 0; $$.type = BWRITERSPR_PREDICATE;
1542 | REG_VPOS
1544 $$.regnum = 0; $$.type = BWRITERSPR_MISCTYPE;
1546 | REG_VFACE
1548 $$.regnum = 1; $$.type = BWRITERSPR_MISCTYPE;
1550 | REG_ADDRESS
1552 $$.regnum = 0; $$.type = BWRITERSPR_ADDR;
1554 | REG_LOOP
1556 $$.regnum = 0; $$.type = BWRITERSPR_LOOP;
1558 | REG_LABEL
1560 $$.regnum = $1; $$.type = BWRITERSPR_LABEL;
1563 comp: COMP_GT { $$ = BWRITER_COMPARISON_GT; }
1564 | COMP_LT { $$ = BWRITER_COMPARISON_LT; }
1565 | COMP_GE { $$ = BWRITER_COMPARISON_GE; }
1566 | COMP_LE { $$ = BWRITER_COMPARISON_LE; }
1567 | COMP_EQ { $$ = BWRITER_COMPARISON_EQ; }
1568 | COMP_NE { $$ = BWRITER_COMPARISON_NE; }
1570 dclusage: USAGE_POSITION
1572 TRACE("dcl_position%u\n", $1);
1573 $$.regnum = $1;
1574 $$.dclusage = BWRITERDECLUSAGE_POSITION;
1576 | USAGE_BLENDWEIGHT
1578 TRACE("dcl_blendweight%u\n", $1);
1579 $$.regnum = $1;
1580 $$.dclusage = BWRITERDECLUSAGE_BLENDWEIGHT;
1582 | USAGE_BLENDINDICES
1584 TRACE("dcl_blendindices%u\n", $1);
1585 $$.regnum = $1;
1586 $$.dclusage = BWRITERDECLUSAGE_BLENDINDICES;
1588 | USAGE_NORMAL
1590 TRACE("dcl_normal%u\n", $1);
1591 $$.regnum = $1;
1592 $$.dclusage = BWRITERDECLUSAGE_NORMAL;
1594 | USAGE_PSIZE
1596 TRACE("dcl_psize%u\n", $1);
1597 $$.regnum = $1;
1598 $$.dclusage = BWRITERDECLUSAGE_PSIZE;
1600 | USAGE_TEXCOORD
1602 TRACE("dcl_texcoord%u\n", $1);
1603 $$.regnum = $1;
1604 $$.dclusage = BWRITERDECLUSAGE_TEXCOORD;
1606 | USAGE_TANGENT
1608 TRACE("dcl_tangent%u\n", $1);
1609 $$.regnum = $1;
1610 $$.dclusage = BWRITERDECLUSAGE_TANGENT;
1612 | USAGE_BINORMAL
1614 TRACE("dcl_binormal%u\n", $1);
1615 $$.regnum = $1;
1616 $$.dclusage = BWRITERDECLUSAGE_BINORMAL;
1618 | USAGE_TESSFACTOR
1620 TRACE("dcl_tessfactor%u\n", $1);
1621 $$.regnum = $1;
1622 $$.dclusage = BWRITERDECLUSAGE_TESSFACTOR;
1624 | USAGE_POSITIONT
1626 TRACE("dcl_positiont%u\n", $1);
1627 $$.regnum = $1;
1628 $$.dclusage = BWRITERDECLUSAGE_POSITIONT;
1630 | USAGE_COLOR
1632 TRACE("dcl_color%u\n", $1);
1633 $$.regnum = $1;
1634 $$.dclusage = BWRITERDECLUSAGE_COLOR;
1636 | USAGE_FOG
1638 TRACE("dcl_fog%u\n", $1);
1639 $$.regnum = $1;
1640 $$.dclusage = BWRITERDECLUSAGE_FOG;
1642 | USAGE_DEPTH
1644 TRACE("dcl_depth%u\n", $1);
1645 $$.regnum = $1;
1646 $$.dclusage = BWRITERDECLUSAGE_DEPTH;
1648 | USAGE_SAMPLE
1650 TRACE("dcl_sample%u\n", $1);
1651 $$.regnum = $1;
1652 $$.dclusage = BWRITERDECLUSAGE_SAMPLE;
1655 dcl_inputreg: REG_INPUT
1657 $$.regnum = $1; $$.type = BWRITERSPR_INPUT;
1659 | REG_TEXTURE
1661 $$.regnum = $1; $$.type = BWRITERSPR_TEXTURE;
1664 sampdcl: SAMPTYPE_1D
1666 $$ = BWRITERSTT_1D;
1668 | SAMPTYPE_2D
1670 $$ = BWRITERSTT_2D;
1672 | SAMPTYPE_CUBE
1674 $$ = BWRITERSTT_CUBE;
1676 | SAMPTYPE_VOLUME
1678 $$ = BWRITERSTT_VOLUME;
1681 predicate: '(' REG_PREDICATE swizzle ')'
1683 $$.type = BWRITERSPR_PREDICATE;
1684 $$.regnum = 0;
1685 $$.rel_reg = NULL;
1686 $$.srcmod = BWRITERSPSM_NONE;
1687 $$.swizzle = $3;
1689 | '(' SMOD_NOT REG_PREDICATE swizzle ')'
1691 $$.type = BWRITERSPR_PREDICATE;
1692 $$.regnum = 0;
1693 $$.rel_reg = NULL;
1694 $$.srcmod = BWRITERSPSM_NOT;
1695 $$.swizzle = $4;
1700 struct bwriter_shader *parse_asm_shader(char **messages)
1702 struct bwriter_shader *ret = NULL;
1704 asm_ctx.shader = NULL;
1705 asm_ctx.status = PARSE_SUCCESS;
1706 asm_ctx.messages.size = asm_ctx.messages.capacity = 0;
1707 asm_ctx.line_no = 1;
1709 asmshader_parse();
1711 if (asm_ctx.status != PARSE_ERR)
1712 ret = asm_ctx.shader;
1713 else if (asm_ctx.shader)
1714 SlDeleteShader(asm_ctx.shader);
1716 if (messages)
1718 if (asm_ctx.messages.size)
1720 /* Shrink the buffer to the used size */
1721 *messages = d3dcompiler_realloc(asm_ctx.messages.string, asm_ctx.messages.size + 1);
1722 if (!*messages)
1724 ERR("Out of memory, no messages reported\n");
1725 d3dcompiler_free(asm_ctx.messages.string);
1728 else
1730 *messages = NULL;
1733 else
1735 if (asm_ctx.messages.capacity)
1736 d3dcompiler_free(asm_ctx.messages.string);
1739 return ret;