d3dx9: Add missing texkill instruction parsing.
[wine/multimedia.git] / dlls / d3dx9_36 / asmshader.y
blob0949ee312f895a44456bfe17b313d809790dcb87
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 "config.h"
24 #include "wine/port.h"
25 #include "wine/debug.h"
27 #include "d3dx9_36_private.h"
29 #include <stdio.h>
31 WINE_DEFAULT_DEBUG_CHANNEL(asmshader);
33 struct asm_parser asm_ctx;
35 /* Needed lexer functions declarations */
36 void asmshader_error(const char *s);
37 int asmshader_lex(void);
39 void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
40 /* We can have an additional offset without true relative addressing
41 * ex. c2[ 4 ] */
42 reg->regnum += rel->additional_offset;
43 if(!rel->has_rel_reg) {
44 reg->rel_reg = NULL;
45 } else {
46 reg->rel_reg = asm_alloc(sizeof(*reg->rel_reg));
47 if(!reg->rel_reg) {
48 return;
50 reg->rel_reg->type = rel->type;
51 reg->rel_reg->swizzle = rel->swizzle;
52 reg->rel_reg->regnum = rel->rel_regnum;
58 %union {
59 struct {
60 float val;
61 BOOL integer;
62 } immval;
63 BOOL immbool;
64 unsigned int regnum;
65 struct shader_reg reg;
66 DWORD srcmod;
67 DWORD writemask;
68 struct {
69 DWORD writemask;
70 DWORD idx;
71 DWORD last;
72 } wm_components;
73 DWORD swizzle;
74 struct {
75 DWORD swizzle;
76 DWORD idx;
77 } sw_components;
78 DWORD component;
79 struct {
80 DWORD mod;
81 DWORD shift;
82 } modshift;
83 BWRITER_COMPARISON_TYPE comptype;
84 struct {
85 DWORD dclusage;
86 unsigned int regnum;
87 } declaration;
88 BWRITERSAMPLER_TEXTURE_TYPE samplertype;
89 struct rel_reg rel_reg;
90 struct src_regs sregs;
93 /* Common instructions between vertex and pixel shaders */
94 %token INSTR_ADD
95 %token INSTR_NOP
96 %token INSTR_MOV
97 %token INSTR_SUB
98 %token INSTR_MAD
99 %token INSTR_MUL
100 %token INSTR_RCP
101 %token INSTR_RSQ
102 %token INSTR_DP3
103 %token INSTR_DP4
104 %token INSTR_MIN
105 %token INSTR_MAX
106 %token INSTR_SLT
107 %token INSTR_SGE
108 %token INSTR_ABS
109 %token INSTR_EXP
110 %token INSTR_LOG
111 %token INSTR_EXPP
112 %token INSTR_LOGP
113 %token INSTR_DST
114 %token INSTR_LRP
115 %token INSTR_FRC
116 %token INSTR_POW
117 %token INSTR_CRS
118 %token INSTR_SGN
119 %token INSTR_NRM
120 %token INSTR_SINCOS
121 %token INSTR_M4x4
122 %token INSTR_M4x3
123 %token INSTR_M3x4
124 %token INSTR_M3x3
125 %token INSTR_M3x2
126 %token INSTR_DCL
127 %token INSTR_DEF
128 %token INSTR_DEFB
129 %token INSTR_DEFI
130 %token INSTR_REP
131 %token INSTR_ENDREP
132 %token INSTR_IF
133 %token INSTR_ELSE
134 %token INSTR_ENDIF
135 %token INSTR_BREAK
136 %token INSTR_BREAKP
137 %token INSTR_CALL
138 %token INSTR_CALLNZ
139 %token INSTR_LOOP
140 %token INSTR_RET
141 %token INSTR_ENDLOOP
142 %token INSTR_LABEL
143 %token INSTR_SETP
144 %token INSTR_TEXLDL
146 /* Vertex shader only instructions */
147 %token INSTR_LIT
148 %token INSTR_MOVA
150 /* Pixel shader only instructions */
151 %token INSTR_CMP
152 %token INSTR_DP2ADD
153 %token INSTR_TEXKILL
154 %token INSTR_TEXLD
155 %token INSTR_DSX
156 %token INSTR_DSY
157 %token INSTR_TEXLDP
158 %token INSTR_TEXLDB
159 %token INSTR_TEXLDD
161 /* Registers */
162 %token <regnum> REG_TEMP
163 %token <regnum> REG_OUTPUT
164 %token <regnum> REG_INPUT
165 %token <regnum> REG_CONSTFLOAT
166 %token <regnum> REG_CONSTINT
167 %token <regnum> REG_CONSTBOOL
168 %token <regnum> REG_TEXTURE
169 %token <regnum> REG_SAMPLER
170 %token <regnum> REG_TEXCRDOUT
171 %token REG_OPOS
172 %token REG_OFOG
173 %token REG_OPTS
174 %token <regnum> REG_VERTEXCOLOR
175 %token <regnum> REG_FRAGCOLOR
176 %token REG_FRAGDEPTH
177 %token REG_VPOS
178 %token REG_VFACE
179 %token REG_ADDRESS
180 %token REG_LOOP
181 %token REG_PREDICATE
182 %token <regnum> REG_LABEL
184 /* Version tokens */
185 %token VER_VS10
186 %token VER_VS11
187 %token VER_VS20
188 %token VER_VS2X
189 %token VER_VS30
191 %token VER_PS10
192 %token VER_PS11
193 %token VER_PS12
194 %token VER_PS13
195 %token VER_PS14
196 %token VER_PS20
197 %token VER_PS2X
198 %token VER_PS30
200 /* Output modifiers */
201 %token MOD_SAT
202 %token MOD_PP
203 %token MOD_CENTROID
205 /* Compare tokens */
206 %token COMP_GT
207 %token COMP_LT
208 %token COMP_GE
209 %token COMP_LE
210 %token COMP_EQ
211 %token COMP_NE
213 /* Source register modifiers */
214 %token SMOD_ABS
215 %token SMOD_NOT
217 /* Sampler types */
218 %token SAMPTYPE_1D
219 %token SAMPTYPE_2D
220 %token SAMPTYPE_CUBE
221 %token SAMPTYPE_VOLUME
223 /* Usage declaration tokens */
224 %token <regnum> USAGE_POSITION
225 %token <regnum> USAGE_BLENDWEIGHT
226 %token <regnum> USAGE_BLENDINDICES
227 %token <regnum> USAGE_NORMAL
228 %token <regnum> USAGE_PSIZE
229 %token <regnum> USAGE_TEXCOORD
230 %token <regnum> USAGE_TANGENT
231 %token <regnum> USAGE_BINORMAL
232 %token <regnum> USAGE_TESSFACTOR
233 %token <regnum> USAGE_POSITIONT
234 %token <regnum> USAGE_COLOR
235 %token <regnum> USAGE_FOG
236 %token <regnum> USAGE_DEPTH
237 %token <regnum> USAGE_SAMPLE
239 /* Misc stuff */
240 %token <component> COMPONENT
241 %token <immval> IMMVAL
242 %token <immbool> IMMBOOL
244 %type <reg> dreg_name
245 %type <reg> dreg
246 %type <reg> sreg_name
247 %type <reg> relreg_name
248 %type <reg> sreg
249 %type <srcmod> smod
250 %type <writemask> writemask
251 %type <wm_components> wm_components
252 %type <swizzle> swizzle
253 %type <sw_components> sw_components
254 %type <modshift> omods
255 %type <modshift> omodifier
256 %type <comptype> comp
257 %type <declaration> dclusage
258 %type <samplertype> sampdcl
259 %type <rel_reg> rel_reg
260 %type <reg> predicate
261 %type <immval> immsum
262 %type <sregs> sregs
266 shader: version_marker instructions
268 asm_ctx.funcs->end(&asm_ctx);
271 version_marker: VER_VS10
273 TRACE("Vertex shader 1.0\n");
274 set_parse_status(&asm_ctx, PARSE_ERR);
275 YYABORT;
277 | VER_VS11
279 TRACE("Vertex shader 1.1\n");
280 set_parse_status(&asm_ctx, PARSE_ERR);
281 YYABORT;
283 | VER_VS20
285 TRACE("Vertex shader 2.0\n");
286 set_parse_status(&asm_ctx, PARSE_ERR);
287 YYABORT;
289 | VER_VS2X
291 TRACE("Vertex shader 2.x\n");
292 set_parse_status(&asm_ctx, PARSE_ERR);
293 YYABORT;
295 | VER_VS30
297 TRACE("Vertex shader 3.0\n");
298 create_vs30_parser(&asm_ctx);
300 | VER_PS10
302 TRACE("Pixel shader 1.0\n");
303 set_parse_status(&asm_ctx, PARSE_ERR);
304 YYABORT;
306 | VER_PS11
308 TRACE("Pixel shader 1.1\n");
309 set_parse_status(&asm_ctx, PARSE_ERR);
310 YYABORT;
312 | VER_PS12
314 TRACE("Pixel shader 1.2\n");
315 set_parse_status(&asm_ctx, PARSE_ERR);
316 YYABORT;
318 | VER_PS13
320 TRACE("Pixel shader 1.3\n");
321 set_parse_status(&asm_ctx, PARSE_ERR);
322 YYABORT;
324 | VER_PS14
326 TRACE("Pixel shader 1.4\n");
327 set_parse_status(&asm_ctx, PARSE_ERR);
328 YYABORT;
330 | VER_PS20
332 TRACE("Pixel shader 2.0\n");
333 set_parse_status(&asm_ctx, PARSE_ERR);
334 YYABORT;
336 | VER_PS2X
338 TRACE("Pixel shader 2.x\n");
339 set_parse_status(&asm_ctx, PARSE_ERR);
340 YYABORT;
342 | VER_PS30
344 TRACE("Pixel shader 3.0\n");
345 create_ps30_parser(&asm_ctx);
348 instructions: /* empty */
349 | instructions complexinstr
351 /* Nothing to do */
354 complexinstr: instruction
358 | predicate instruction
360 TRACE("predicate\n");
361 asm_ctx.funcs->predicate(&asm_ctx, &$1);
364 instruction: INSTR_ADD omods dreg ',' sregs
366 TRACE("ADD\n");
367 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ADD, $2.mod, $2.shift, 0, &$3, &$5, 2);
369 | INSTR_NOP
371 TRACE("NOP\n");
372 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_NOP, 0, 0, 0, 0, 0, 0);
374 | INSTR_MOV omods dreg ',' sregs
376 TRACE("MOV\n");
377 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_MOV, $2.mod, $2.shift, 0, &$3, &$5, 1);
379 | INSTR_SUB omods dreg ',' sregs
381 TRACE("SUB\n");
382 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_SUB, $2.mod, $2.shift, 0, &$3, &$5, 2);
384 | INSTR_MAD omods dreg ',' sregs
386 TRACE("MAD\n");
387 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_MAD, $2.mod, $2.shift, 0, &$3, &$5, 3);
389 | INSTR_MUL omods dreg ',' sregs
391 TRACE("MUL\n");
392 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_MUL, $2.mod, $2.shift, 0, &$3, &$5, 2);
394 | INSTR_RCP omods dreg ',' sregs
396 TRACE("RCP\n");
397 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_RCP, $2.mod, $2.shift, 0, &$3, &$5, 1);
399 | INSTR_RSQ omods dreg ',' sregs
401 TRACE("RSQ\n");
402 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_RSQ, $2.mod, $2.shift, 0, &$3, &$5, 1);
404 | INSTR_DP3 omods dreg ',' sregs
406 TRACE("DP3\n");
407 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_DP3, $2.mod, $2.shift, 0, &$3, &$5, 2);
409 | INSTR_DP4 omods dreg ',' sregs
411 TRACE("DP4\n");
412 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_DP4, $2.mod, $2.shift, 0, &$3, &$5, 2);
414 | INSTR_MIN omods dreg ',' sregs
416 TRACE("MIN\n");
417 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_MIN, $2.mod, $2.shift, 0, &$3, &$5, 2);
419 | INSTR_MAX omods dreg ',' sregs
421 TRACE("MAX\n");
422 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_MAX, $2.mod, $2.shift, 0, &$3, &$5, 2);
424 | INSTR_SLT omods dreg ',' sregs
426 TRACE("SLT\n");
427 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_SLT, $2.mod, $2.shift, 0, &$3, &$5, 2);
429 | INSTR_SGE omods dreg ',' sregs
431 TRACE("SGE\n");
432 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_SGE, $2.mod, $2.shift, 0, &$3, &$5, 2);
434 | INSTR_ABS omods dreg ',' sregs
436 TRACE("ABS\n");
437 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ABS, $2.mod, $2.shift, 0, &$3, &$5, 1);
439 | INSTR_EXP omods dreg ',' sregs
441 TRACE("EXP\n");
442 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_EXP, $2.mod, $2.shift, 0, &$3, &$5, 1);
444 | INSTR_LOG omods dreg ',' sregs
446 TRACE("LOG\n");
447 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LOG, $2.mod, $2.shift, 0, &$3, &$5, 1);
449 | INSTR_LOGP omods dreg ',' sregs
451 TRACE("LOGP\n");
452 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LOGP, $2.mod, $2.shift, 0, &$3, &$5, 1);
454 | INSTR_EXPP omods dreg ',' sregs
456 TRACE("EXPP\n");
457 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_EXPP, $2.mod, $2.shift, 0, &$3, &$5, 1);
459 | INSTR_DST omods dreg ',' sregs
461 TRACE("DST\n");
462 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_DST, $2.mod, $2.shift, 0, &$3, &$5, 2);
464 | INSTR_LRP omods dreg ',' sregs
466 TRACE("LRP\n");
467 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LRP, $2.mod, $2.shift, 0, &$3, &$5, 3);
469 | INSTR_FRC omods dreg ',' sregs
471 TRACE("FRC\n");
472 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_FRC, $2.mod, $2.shift, 0, &$3, &$5, 1);
474 | INSTR_POW omods dreg ',' sregs
476 TRACE("POW\n");
477 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_POW, $2.mod, $2.shift, 0, &$3, &$5, 2);
479 | INSTR_CRS omods dreg ',' sregs
481 TRACE("CRS\n");
482 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_CRS, $2.mod, $2.shift, 0, &$3, &$5, 2);
484 | INSTR_SGN omods dreg ',' sregs
486 TRACE("SGN\n");
487 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_SGN, $2.mod, $2.shift, 0, &$3, &$5, 3);
489 | INSTR_NRM omods dreg ',' sregs
491 TRACE("NRM\n");
492 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_NRM, $2.mod, $2.shift, 0, &$3, &$5, 1);
494 | INSTR_SINCOS omods dreg ',' sregs
496 TRACE("SINCOS\n");
497 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_SINCOS, $2.mod, $2.shift, 0, &$3, &$5, 1);
499 | INSTR_M4x4 omods dreg ',' sregs
501 TRACE("M4x4\n");
502 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_M4x4, $2.mod, $2.shift, 0, &$3, &$5, 2);
504 | INSTR_M4x3 omods dreg ',' sregs
506 TRACE("M4x3\n");
507 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_M4x3, $2.mod, $2.shift, 0, &$3, &$5, 2);
509 | INSTR_M3x4 omods dreg ',' sregs
511 TRACE("M3x4\n");
512 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_M3x4, $2.mod, $2.shift, 0, &$3, &$5, 2);
514 | INSTR_M3x3 omods dreg ',' sregs
516 TRACE("M3x3\n");
517 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_M3x3, $2.mod, $2.shift, 0, &$3, &$5, 2);
519 | INSTR_M3x2 omods dreg ',' sregs
521 TRACE("M3x2\n");
522 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_M3x2, $2.mod, $2.shift, 0, &$3, &$5, 2);
524 | INSTR_DCL dclusage REG_OUTPUT
526 struct shader_reg reg;
527 TRACE("Output reg declaration\n");
528 ZeroMemory(&reg, sizeof(reg));
529 reg.type = BWRITERSPR_OUTPUT;
530 reg.regnum = $3;
531 reg.rel_reg = NULL;
532 reg.srcmod = 0;
533 reg.writemask = BWRITERSP_WRITEMASK_ALL;
534 asm_ctx.funcs->dcl_output(&asm_ctx, $2.dclusage, $2.regnum, &reg);
536 | INSTR_DCL dclusage REG_OUTPUT writemask
538 struct shader_reg reg;
539 TRACE("Output reg declaration\n");
540 ZeroMemory(&reg, sizeof(reg));
541 reg.type = BWRITERSPR_OUTPUT;
542 reg.regnum = $3;
543 reg.rel_reg = NULL;
544 reg.srcmod = 0;
545 reg.writemask = $4;
546 asm_ctx.funcs->dcl_output(&asm_ctx, $2.dclusage, $2.regnum, &reg);
548 | INSTR_DCL dclusage REG_INPUT
550 struct shader_reg reg;
551 TRACE("Input reg declaration\n");
552 ZeroMemory(&reg, sizeof(reg));
553 reg.type = BWRITERSPR_INPUT;
554 reg.regnum = $3;
555 reg.rel_reg = NULL;
556 reg.srcmod = 0;
557 reg.writemask = BWRITERSP_WRITEMASK_ALL;
558 asm_ctx.funcs->dcl_input(&asm_ctx, $2.dclusage, $2.regnum, &reg);
560 | INSTR_DCL dclusage REG_INPUT writemask
562 struct shader_reg reg;
563 TRACE("Input reg declaration\n");
564 ZeroMemory(&reg, sizeof(reg));
565 reg.type = BWRITERSPR_INPUT;
566 reg.regnum = $3;
567 reg.rel_reg = NULL;
568 reg.srcmod = 0;
569 reg.writemask = $4;
570 asm_ctx.funcs->dcl_input(&asm_ctx, $2.dclusage, $2.regnum, &reg);
572 | INSTR_DCL sampdcl REG_SAMPLER
574 TRACE("Sampler declared\n");
575 asm_ctx.funcs->dcl_sampler(&asm_ctx, $2, $3, asm_ctx.line_no);
577 | INSTR_DCL sampdcl REG_INPUT
579 TRACE("Error rule: sampler decl of input reg\n");
580 asmparser_message(&asm_ctx, "Line %u: Sampler declarations of input regs is not valid\n",
581 asm_ctx.line_no);
582 set_parse_status(&asm_ctx, PARSE_WARN);
584 | INSTR_DCL sampdcl REG_OUTPUT
586 TRACE("Error rule: sampler decl of output reg\n");
587 asmparser_message(&asm_ctx, "Line %u: Sampler declarations of output regs is not valid\n",
588 asm_ctx.line_no);
589 set_parse_status(&asm_ctx, PARSE_WARN);
591 | INSTR_DEF REG_CONSTFLOAT ',' IMMVAL ',' IMMVAL ',' IMMVAL ',' IMMVAL
593 asm_ctx.funcs->constF(&asm_ctx, $2, $4.val, $6.val, $8.val, $10.val);
595 | INSTR_DEFI REG_CONSTINT ',' IMMVAL ',' IMMVAL ',' IMMVAL ',' IMMVAL
597 asm_ctx.funcs->constI(&asm_ctx, $2, $4.val, $6.val, $8.val, $10.val);
599 | INSTR_DEFB REG_CONSTBOOL ',' IMMBOOL
601 asm_ctx.funcs->constB(&asm_ctx, $2, $4);
603 | INSTR_REP sregs
605 TRACE("REP\n");
606 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_REP, 0, 0, 0, 0, &$2, 1);
608 | INSTR_ENDREP
610 TRACE("ENDREP\n");
611 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ENDREP, 0, 0, 0, 0, 0, 0);
613 | INSTR_IF sregs
615 TRACE("IF\n");
616 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_IF, 0, 0, 0, 0, &$2, 1);
618 | INSTR_IF comp sregs
620 TRACE("IFC\n");
621 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_IFC, 0, 0, $2, 0, &$3, 2);
623 | INSTR_ELSE
625 TRACE("ELSE\n");
626 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ELSE, 0, 0, 0, 0, 0, 0);
628 | INSTR_ENDIF
630 TRACE("ENDIF\n");
631 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ENDIF, 0, 0, 0, 0, 0, 0);
633 | INSTR_BREAK
635 TRACE("BREAK\n");
636 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_BREAK, 0, 0, 0, 0, 0, 0);
638 | INSTR_BREAK comp sregs
640 TRACE("BREAKC\n");
641 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_BREAKC, 0, 0, $2, 0, &$3, 2);
643 | INSTR_BREAKP sregs
645 TRACE("BREAKP\n");
646 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_BREAKP, 0, 0, 0, 0, &$2, 1);
648 | INSTR_CALL sregs
650 TRACE("CALL\n");
651 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_CALL, 0, 0, 0, 0, &$2, 1);
653 | INSTR_CALLNZ sregs
655 TRACE("CALLNZ\n");
656 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_CALLNZ, 0, 0, 0, 0, &$2, 2);
658 | INSTR_LOOP sregs
660 TRACE("LOOP\n");
661 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LOOP, 0, 0, 0, 0, &$2, 2);
663 | INSTR_RET
665 TRACE("RET\n");
666 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_RET, 0, 0, 0, 0, 0, 0);
668 | INSTR_ENDLOOP
670 TRACE("ENDLOOP\n");
671 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_ENDLOOP, 0, 0, 0, 0, 0, 0);
673 | INSTR_LABEL sregs
675 TRACE("LABEL\n");
676 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LABEL, 0, 0, 0, 0, &$2, 1);
678 | INSTR_SETP comp dreg ',' sregs
680 TRACE("SETP\n");
681 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_SETP, 0, 0, $2, &$3, &$5, 2);
683 | INSTR_TEXLDL omods dreg ',' sregs
685 TRACE("TEXLDL\n");
686 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXLDL, $2.mod, $2.shift, 0, &$3, &$5, 2);
688 | INSTR_LIT omods dreg ',' sregs
690 TRACE("LIT\n");
691 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_LIT, $2.mod, $2.shift, 0, &$3, &$5, 1);
693 | INSTR_MOVA omods dreg ',' sregs
695 TRACE("MOVA\n");
696 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_MOVA, $2.mod, $2.shift, 0, &$3, &$5, 1);
698 | INSTR_CMP omods dreg ',' sregs
700 TRACE("CMP\n");
701 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_CMP, $2.mod, $2.shift, 0, &$3, &$5, 3);
703 | INSTR_DP2ADD omods dreg ',' sregs
705 TRACE("DP2ADD\n");
706 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_DP2ADD, $2.mod, $2.shift, 0, &$3, &$5, 3);
708 | INSTR_TEXKILL dreg
710 TRACE("TEXKILL\n");
711 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXKILL, 0, 0, 0, &$2, 0, 0);
713 | INSTR_TEXLD omods dreg ',' sregs
715 TRACE("TEXLD\n");
716 /* There is more than one acceptable syntax for texld:
717 with 1 sreg (PS 1.4) or
718 with 2 sregs (PS 2.0+)
719 Moreover, texld shares the same opcode as the tex instruction,
720 so there are a total of 3 valid syntaxes
721 These variations are handled in asmparser.c */
722 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEX, $2.mod, $2.shift, 0, &$3, &$5, 2);
724 | INSTR_TEXLDP omods dreg ',' sregs
726 TRACE("TEXLDP\n");
727 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEX | ( BWRITERSI_TEXLD_PROJECT << BWRITER_OPCODESPECIFICCONTROL_SHIFT ), $2.mod, $2.shift, 0, &$3, &$5, 2);
729 | INSTR_TEXLDB omods dreg ',' sregs
731 TRACE("TEXLDB\n");
732 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEX | ( BWRITERSI_TEXLD_BIAS << BWRITER_OPCODESPECIFICCONTROL_SHIFT ), $2.mod, $2.shift, 0, &$3, &$5, 2);
734 | INSTR_DSX omods dreg ',' sregs
736 TRACE("DSX\n");
737 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_DSX, $2.mod, $2.shift, 0, &$3, &$5, 1);
739 | INSTR_DSY omods dreg ',' sregs
741 TRACE("DSY\n");
742 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_DSY, $2.mod, $2.shift, 0, &$3, &$5, 1);
744 | INSTR_TEXLDD omods dreg ',' sregs
746 TRACE("TEXLDD\n");
747 asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_TEXLDD, $2.mod, $2.shift, 0, &$3, &$5, 4);
750 dreg: dreg_name rel_reg
752 $$.regnum = $1.regnum;
753 $$.type = $1.type;
754 $$.writemask = BWRITERSP_WRITEMASK_ALL;
755 $$.srcmod = BWRITERSPSM_NONE;
756 set_rel_reg(&$$, &$2);
758 | dreg_name writemask
760 $$.regnum = $1.regnum;
761 $$.type = $1.type;
762 $$.writemask = $2;
763 $$.srcmod = BWRITERSPSM_NONE;
764 $$.rel_reg = NULL;
767 dreg_name: REG_TEMP
769 $$.regnum = $1; $$.type = BWRITERSPR_TEMP;
771 | REG_OUTPUT
773 $$.regnum = $1; $$.type = BWRITERSPR_OUTPUT;
775 | REG_INPUT
777 $$.regnum = $1; $$.type = BWRITERSPR_INPUT;
779 | REG_CONSTFLOAT
781 asmparser_message(&asm_ctx, "Line %u: Register c%u is not a valid destination register\n",
782 asm_ctx.line_no, $1);
783 set_parse_status(&asm_ctx, PARSE_WARN);
785 | REG_CONSTINT
787 asmparser_message(&asm_ctx, "Line %u: Register i%u is not a valid destination register\n",
788 asm_ctx.line_no, $1);
789 set_parse_status(&asm_ctx, PARSE_WARN);
791 | REG_CONSTBOOL
793 asmparser_message(&asm_ctx, "Line %u: Register b%u is not a valid destination register\n",
794 asm_ctx.line_no, $1);
795 set_parse_status(&asm_ctx, PARSE_WARN);
797 | REG_TEXTURE
799 $$.regnum = $1; $$.type = BWRITERSPR_TEXTURE;
801 | REG_TEXCRDOUT
803 $$.regnum = $1; $$.type = BWRITERSPR_TEXCRDOUT;
805 | REG_SAMPLER
807 asmparser_message(&asm_ctx, "Line %u: Register s%u is not a valid destination register\n",
808 asm_ctx.line_no, $1);
809 set_parse_status(&asm_ctx, PARSE_WARN);
811 | REG_OPOS
813 $$.regnum = BWRITERSRO_POSITION; $$.type = BWRITERSPR_RASTOUT;
815 | REG_OPTS
817 $$.regnum = BWRITERSRO_POINT_SIZE; $$.type = BWRITERSPR_RASTOUT;
819 | REG_OFOG
821 $$.regnum = BWRITERSRO_FOG; $$.type = BWRITERSPR_RASTOUT;
823 | REG_VERTEXCOLOR
825 $$.regnum = $1; $$.type = BWRITERSPR_ATTROUT;
827 | REG_FRAGCOLOR
829 $$.regnum = $1; $$.type = BWRITERSPR_COLOROUT;
831 | REG_FRAGDEPTH
833 $$.regnum = 0; $$.type = BWRITERSPR_DEPTHOUT;
835 | REG_PREDICATE
837 $$.regnum = 0; $$.type = BWRITERSPR_PREDICATE;
839 | REG_VPOS
841 asmparser_message(&asm_ctx, "Line %u: Register vPos is not a valid destination register\n",
842 asm_ctx.line_no);
843 set_parse_status(&asm_ctx, PARSE_WARN);
845 | REG_VFACE
847 asmparser_message(&asm_ctx, "Line %u: Register vFace is not a valid destination register\n",
848 asm_ctx.line_no);
849 set_parse_status(&asm_ctx, PARSE_WARN);
851 | REG_ADDRESS
853 /* index 0 is hardcoded for the addr register */
854 $$.regnum = 0; $$.type = BWRITERSPR_ADDR;
856 | REG_LOOP
858 asmparser_message(&asm_ctx, "Line %u: Register aL is not a valid destination register\n",
859 asm_ctx.line_no);
860 set_parse_status(&asm_ctx, PARSE_WARN);
863 writemask: '.' wm_components
865 if($2.writemask == SWIZZLE_ERR) {
866 asmparser_message(&asm_ctx, "Line %u: Invalid writemask specified\n",
867 asm_ctx.line_no);
868 set_parse_status(&asm_ctx, PARSE_ERR);
869 /* Provide a correct writemask to prevent following complaints */
870 $$ = BWRITERSP_WRITEMASK_ALL;
872 else {
873 $$ = $2.writemask;
874 TRACE("Writemask: %x\n", $$);
878 wm_components: COMPONENT
880 $$.writemask = 1 << $1;
881 $$.last = $1;
882 $$.idx = 1;
884 | wm_components COMPONENT
886 if($1.writemask == SWIZZLE_ERR || $1.idx == 4)
887 /* Wrong writemask */
888 $$.writemask = SWIZZLE_ERR;
889 else {
890 if($2 <= $1.last)
891 $$.writemask = SWIZZLE_ERR;
892 else {
893 $$.writemask = $1.writemask | (1 << $2);
894 $$.idx = $1.idx + 1;
899 swizzle: /* empty */
901 $$ = BWRITERVS_NOSWIZZLE;
902 TRACE("Default swizzle: %08x\n", $$);
904 | '.' sw_components
906 if($2.swizzle == SWIZZLE_ERR) {
907 asmparser_message(&asm_ctx, "Line %u: Invalid swizzle\n",
908 asm_ctx.line_no);
909 set_parse_status(&asm_ctx, PARSE_ERR);
910 /* Provide a correct swizzle to prevent following complaints */
911 $$ = BWRITERVS_NOSWIZZLE;
913 else {
914 DWORD last, i;
916 $$ = $2.swizzle << BWRITERVS_SWIZZLE_SHIFT;
917 /* Fill the swizzle by extending the last component */
918 last = ($2.swizzle >> 2 * ($2.idx - 1)) & 0x03;
919 for(i = $2.idx; i < 4; i++){
920 $$ |= last << (BWRITERVS_SWIZZLE_SHIFT + 2 * i);
922 TRACE("Got a swizzle: %08x\n", $$);
926 sw_components: COMPONENT
928 $$.swizzle = $1;
929 $$.idx = 1;
931 | sw_components COMPONENT
933 if($1.idx == 4) {
934 /* Too many sw_components */
935 $$.swizzle = SWIZZLE_ERR;
936 $$.idx = 4;
938 else {
939 $$.swizzle = $1.swizzle | ($2 << 2 * $1.idx);
940 $$.idx = $1.idx + 1;
944 omods: /* Empty */
946 $$.mod = 0;
947 $$.shift = 0;
949 | omods omodifier
951 $$.mod = $1.mod | $2.mod;
952 if($1.shift && $2.shift) {
953 asmparser_message(&asm_ctx, "Line %u: More than one shift flag\n",
954 asm_ctx.line_no);
955 set_parse_status(&asm_ctx, PARSE_ERR);
956 $$.shift = $1.shift;
957 } else {
958 $$.shift = $1.shift | $2.shift;
962 omodifier: MOD_SAT
964 $$.mod = BWRITERSPDM_SATURATE;
965 $$.shift = 0;
967 | MOD_PP
969 $$.mod = BWRITERSPDM_PARTIALPRECISION;
970 $$.shift = 0;
972 | MOD_CENTROID
974 $$.mod = BWRITERSPDM_MSAMPCENTROID;
975 $$.shift = 0;
978 sregs: sreg
980 $$.reg[0] = $1;
981 $$.count = 1;
983 | sregs ',' sreg
985 if($$.count == MAX_SRC_REGS){
986 asmparser_message(&asm_ctx, "Line %u: Too many source registers in this instruction\n",
987 asm_ctx.line_no);
988 set_parse_status(&asm_ctx, PARSE_ERR);
990 else
991 $$.reg[$$.count++] = $3;
994 sreg: sreg_name rel_reg swizzle
996 $$.type = $1.type;
997 $$.regnum = $1.regnum;
998 $$.swizzle = $3;
999 $$.srcmod = BWRITERSPSM_NONE;
1000 set_rel_reg(&$$, &$2);
1002 | sreg_name rel_reg smod swizzle
1004 $$.type = $1.type;
1005 $$.regnum = $1.regnum;
1006 set_rel_reg(&$$, &$2);
1007 $$.srcmod = $3;
1008 $$.swizzle = $4;
1010 | '-' sreg_name rel_reg swizzle
1012 $$.type = $2.type;
1013 $$.regnum = $2.regnum;
1014 $$.srcmod = BWRITERSPSM_NEG;
1015 set_rel_reg(&$$, &$3);
1016 $$.swizzle = $4;
1018 | '-' sreg_name rel_reg smod swizzle
1020 $$.type = $2.type;
1021 $$.regnum = $2.regnum;
1022 set_rel_reg(&$$, &$3);
1023 switch($4) {
1024 case BWRITERSPSM_ABS: $$.srcmod = BWRITERSPSM_ABSNEG; break;
1025 default:
1026 FIXME("Unhandled combination of NEGATE and %u\n", $4);
1028 $$.swizzle = $5;
1030 | SMOD_NOT sreg_name swizzle
1032 $$.type = $2.type;
1033 $$.regnum = $2.regnum;
1034 $$.rel_reg = NULL;
1035 $$.srcmod = BWRITERSPSM_NOT;
1036 $$.swizzle = $3;
1039 rel_reg: /* empty */
1041 $$.has_rel_reg = FALSE;
1042 $$.additional_offset = 0;
1044 | '[' immsum ']'
1046 $$.has_rel_reg = FALSE;
1047 $$.additional_offset = $2.val;
1049 | '[' relreg_name swizzle ']'
1051 $$.has_rel_reg = TRUE;
1052 $$.type = $2.type;
1053 $$.additional_offset = 0;
1054 $$.rel_regnum = $2.regnum;
1055 $$.swizzle = $3;
1057 | '[' immsum '+' relreg_name swizzle ']'
1059 $$.has_rel_reg = TRUE;
1060 $$.type = $4.type;
1061 $$.additional_offset = $2.val;
1062 $$.rel_regnum = $4.regnum;
1063 $$.swizzle = $5;
1065 | '[' relreg_name swizzle '+' immsum ']'
1067 $$.has_rel_reg = TRUE;
1068 $$.type = $2.type;
1069 $$.additional_offset = $5.val;
1070 $$.rel_regnum = $2.regnum;
1071 $$.swizzle = $3;
1073 | '[' immsum '+' relreg_name swizzle '+' immsum ']'
1075 $$.has_rel_reg = TRUE;
1076 $$.type = $4.type;
1077 $$.additional_offset = $2.val + $7.val;
1078 $$.rel_regnum = $4.regnum;
1079 $$.swizzle = $5;
1082 immsum: IMMVAL
1084 if(!$1.integer) {
1085 asmparser_message(&asm_ctx, "Line %u: Unexpected float %f\n",
1086 asm_ctx.line_no, $1.val);
1087 set_parse_status(&asm_ctx, PARSE_ERR);
1089 $$.val = $1.val;
1091 | immsum '+' IMMVAL
1093 if(!$3.integer) {
1094 asmparser_message(&asm_ctx, "Line %u: Unexpected float %f\n",
1095 asm_ctx.line_no, $3.val);
1096 set_parse_status(&asm_ctx, PARSE_ERR);
1098 $$.val = $1.val + $3.val;
1101 smod: SMOD_ABS
1103 $$ = BWRITERSPSM_ABS;
1106 relreg_name: REG_ADDRESS
1108 $$.regnum = 0; $$.type = BWRITERSPR_ADDR;
1110 | REG_LOOP
1112 $$.regnum = 0; $$.type = BWRITERSPR_LOOP;
1115 sreg_name: REG_TEMP
1117 $$.regnum = $1; $$.type = BWRITERSPR_TEMP;
1119 | REG_OUTPUT
1121 asmparser_message(&asm_ctx, "Line %u: Register o%u is not a valid source register\n",
1122 asm_ctx.line_no, $1);
1123 set_parse_status(&asm_ctx, PARSE_WARN);
1125 | REG_INPUT
1127 $$.regnum = $1; $$.type = BWRITERSPR_INPUT;
1129 | REG_CONSTFLOAT
1131 $$.regnum = $1; $$.type = BWRITERSPR_CONST;
1133 | REG_CONSTINT
1135 $$.regnum = $1; $$.type = BWRITERSPR_CONSTINT;
1137 | REG_CONSTBOOL
1139 $$.regnum = $1; $$.type = BWRITERSPR_CONSTBOOL;
1141 | REG_TEXTURE
1143 $$.regnum = $1; $$.type = BWRITERSPR_TEXTURE;
1145 | REG_TEXCRDOUT
1147 asmparser_message(&asm_ctx, "Line %u: Register oT%u is not a valid source register\n",
1148 asm_ctx.line_no, $1);
1149 set_parse_status(&asm_ctx, PARSE_WARN);
1151 | REG_SAMPLER
1153 $$.regnum = $1; $$.type = BWRITERSPR_SAMPLER;
1155 | REG_OPOS
1157 asmparser_message(&asm_ctx, "Line %u: Register oPos is not a valid source register\n",
1158 asm_ctx.line_no);
1159 set_parse_status(&asm_ctx, PARSE_WARN);
1161 | REG_OFOG
1163 asmparser_message(&asm_ctx, "Line %u: Register oFog is not a valid source register\n",
1164 asm_ctx.line_no);
1165 set_parse_status(&asm_ctx, PARSE_WARN);
1167 | REG_VERTEXCOLOR
1169 asmparser_message(&asm_ctx, "Line %u: Register oD%u is not a valid source register\n",
1170 asm_ctx.line_no, $1);
1171 set_parse_status(&asm_ctx, PARSE_WARN);
1173 | REG_FRAGCOLOR
1175 asmparser_message(&asm_ctx, "Line %u: Register oC%u is not a valid source register\n",
1176 asm_ctx.line_no, $1);
1177 set_parse_status(&asm_ctx, PARSE_WARN);
1179 | REG_FRAGDEPTH
1181 asmparser_message(&asm_ctx, "Line %u: Register oDepth is not a valid source register\n",
1182 asm_ctx.line_no);
1183 set_parse_status(&asm_ctx, PARSE_WARN);
1185 | REG_PREDICATE
1187 $$.regnum = 0; $$.type = BWRITERSPR_PREDICATE;
1189 | REG_VPOS
1191 $$.regnum = 0; $$.type = BWRITERSPR_MISCTYPE;
1193 | REG_VFACE
1195 $$.regnum = 1; $$.type = BWRITERSPR_MISCTYPE;
1197 | REG_ADDRESS
1199 $$.regnum = 0; $$.type = BWRITERSPR_ADDR;
1201 | REG_LOOP
1203 $$.regnum = 0; $$.type = BWRITERSPR_LOOP;
1205 | REG_LABEL
1207 $$.regnum = $1; $$.type = BWRITERSPR_LABEL;
1210 comp: COMP_GT { $$ = BWRITER_COMPARISON_GT; }
1211 | COMP_LT { $$ = BWRITER_COMPARISON_LT; }
1212 | COMP_GE { $$ = BWRITER_COMPARISON_GE; }
1213 | COMP_LE { $$ = BWRITER_COMPARISON_LE; }
1214 | COMP_EQ { $$ = BWRITER_COMPARISON_EQ; }
1215 | COMP_NE { $$ = BWRITER_COMPARISON_NE; }
1217 dclusage: USAGE_POSITION
1219 TRACE("dcl_position%u\n", $1);
1220 $$.regnum = $1;
1221 $$.dclusage = BWRITERDECLUSAGE_POSITION;
1223 | USAGE_BLENDWEIGHT
1225 TRACE("dcl_blendweight%u\n", $1);
1226 $$.regnum = $1;
1227 $$.dclusage = BWRITERDECLUSAGE_BLENDWEIGHT;
1229 | USAGE_BLENDINDICES
1231 TRACE("dcl_blendindices%u\n", $1);
1232 $$.regnum = $1;
1233 $$.dclusage = BWRITERDECLUSAGE_BLENDINDICES;
1235 | USAGE_NORMAL
1237 TRACE("dcl_normal%u\n", $1);
1238 $$.regnum = $1;
1239 $$.dclusage = BWRITERDECLUSAGE_NORMAL;
1241 | USAGE_PSIZE
1243 TRACE("dcl_psize%u\n", $1);
1244 $$.regnum = $1;
1245 $$.dclusage = BWRITERDECLUSAGE_PSIZE;
1247 | USAGE_TEXCOORD
1249 TRACE("dcl_texcoord%u\n", $1);
1250 $$.regnum = $1;
1251 $$.dclusage = BWRITERDECLUSAGE_TEXCOORD;
1253 | USAGE_TANGENT
1255 TRACE("dcl_tangent%u\n", $1);
1256 $$.regnum = $1;
1257 $$.dclusage = BWRITERDECLUSAGE_TANGENT;
1259 | USAGE_BINORMAL
1261 TRACE("dcl_binormal%u\n", $1);
1262 $$.regnum = $1;
1263 $$.dclusage = BWRITERDECLUSAGE_BINORMAL;
1265 | USAGE_TESSFACTOR
1267 TRACE("dcl_tessfactor%u\n", $1);
1268 $$.regnum = $1;
1269 $$.dclusage = BWRITERDECLUSAGE_TESSFACTOR;
1271 | USAGE_POSITIONT
1273 TRACE("dcl_positiont%u\n", $1);
1274 $$.regnum = $1;
1275 $$.dclusage = BWRITERDECLUSAGE_POSITIONT;
1277 | USAGE_COLOR
1279 TRACE("dcl_color%u\n", $1);
1280 $$.regnum = $1;
1281 $$.dclusage = BWRITERDECLUSAGE_COLOR;
1283 | USAGE_FOG
1285 TRACE("dcl_fog%u\n", $1);
1286 $$.regnum = $1;
1287 $$.dclusage = BWRITERDECLUSAGE_FOG;
1289 | USAGE_DEPTH
1291 TRACE("dcl_depth%u\n", $1);
1292 $$.regnum = $1;
1293 $$.dclusage = BWRITERDECLUSAGE_DEPTH;
1295 | USAGE_SAMPLE
1297 TRACE("dcl_sample%u\n", $1);
1298 $$.regnum = $1;
1299 $$.dclusage = BWRITERDECLUSAGE_SAMPLE;
1302 sampdcl: SAMPTYPE_1D
1304 $$ = BWRITERSTT_1D;
1306 | SAMPTYPE_2D
1308 $$ = BWRITERSTT_2D;
1310 | SAMPTYPE_CUBE
1312 $$ = BWRITERSTT_CUBE;
1314 | SAMPTYPE_VOLUME
1316 $$ = BWRITERSTT_VOLUME;
1319 predicate: '(' REG_PREDICATE swizzle ')'
1321 $$.type = BWRITERSPR_PREDICATE;
1322 $$.regnum = 0;
1323 $$.rel_reg = NULL;
1324 $$.srcmod = BWRITERSPSM_NONE;
1325 $$.swizzle = $3;
1327 | '(' SMOD_NOT REG_PREDICATE swizzle ')'
1329 $$.type = BWRITERSPR_PREDICATE;
1330 $$.regnum = 0;
1331 $$.rel_reg = NULL;
1332 $$.srcmod = BWRITERSPSM_NOT;
1333 $$.swizzle = $4;
1338 void asmshader_error (char const *s) {
1339 asmparser_message(&asm_ctx, "Line %u: Error \"%s\" from bison\n", asm_ctx.line_no, s);
1340 set_parse_status(&asm_ctx, PARSE_ERR);
1343 /* Error reporting function */
1344 void asmparser_message(struct asm_parser *ctx, const char *fmt, ...) {
1345 va_list args;
1346 char* newbuffer;
1347 int rc, newsize;
1349 if(ctx->messagecapacity == 0) {
1350 ctx->messages = asm_alloc(MESSAGEBUFFER_INITIAL_SIZE);
1351 if(ctx->messages == NULL) {
1352 ERR("Error allocating memory for parser messages\n");
1353 return;
1355 ctx->messagecapacity = MESSAGEBUFFER_INITIAL_SIZE;
1358 while(1) {
1359 va_start(args, fmt);
1360 rc = vsnprintf(ctx->messages + ctx->messagesize,
1361 ctx->messagecapacity - ctx->messagesize, fmt, args);
1362 va_end(args);
1364 if (rc < 0 || /* C89 */
1365 rc >= ctx->messagecapacity - ctx->messagesize) { /* C99 */
1366 /* Resize the buffer */
1367 newsize = ctx->messagecapacity * 2;
1368 newbuffer = asm_realloc(ctx->messages, newsize);
1369 if(newbuffer == NULL){
1370 ERR("Error reallocating memory for parser messages\n");
1371 return;
1373 ctx->messages = newbuffer;
1374 ctx->messagecapacity = newsize;
1375 } else {
1376 ctx->messagesize += rc;
1377 return;
1382 /* New status is the worst between current status and parameter value */
1383 void set_parse_status(struct asm_parser *ctx, enum parse_status status) {
1384 if(status == PARSE_ERR) ctx->status = PARSE_ERR;
1385 else if(status == PARSE_WARN && ctx->status == PARSE_SUCCESS) ctx->status = PARSE_WARN;
1388 struct bwriter_shader *parse_asm_shader(char **messages) {
1389 struct bwriter_shader *ret = NULL;
1391 asm_ctx.shader = NULL;
1392 asm_ctx.status = PARSE_SUCCESS;
1393 asm_ctx.messagesize = asm_ctx.messagecapacity = 0;
1394 asm_ctx.line_no = 1;
1396 asmshader_parse();
1398 if(asm_ctx.status != PARSE_ERR) ret = asm_ctx.shader;
1399 else if(asm_ctx.shader) SlDeleteShader(asm_ctx.shader);
1401 if(messages) {
1402 if(asm_ctx.messagesize) {
1403 /* Shrink the buffer to the used size */
1404 *messages = asm_realloc(asm_ctx.messages, asm_ctx.messagesize + 1);
1405 if(!*messages) {
1406 ERR("Out of memory, no messages reported\n");
1407 asm_free(asm_ctx.messages);
1409 } else {
1410 *messages = NULL;
1412 } else {
1413 if(asm_ctx.messagecapacity) asm_free(asm_ctx.messages);
1416 return ret;