1 %{
2 /*
3 * Copyright © 2018 Intel Corporation
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <strings.h>
29 #include "brw_asm_internal.h"
30
31 #undef yyerror
32 #ifdef YYBYACC
33 struct YYLTYPE;
34 void yyerror (struct YYLTYPE *, char *);
35 #else
36 void yyerror (char *);
37 #endif
38
39 #undef ALIGN16
40
41 #define YYLTYPE YYLTYPE
42 typedef struct YYLTYPE
43 {
44 int first_line;
45 int first_column;
46 int last_line;
47 int last_column;
48 } YYLTYPE;
49
50 enum message_level {
51 WARN,
52 ERROR,
53 };
54
55 int yydebug = 1;
56
57 static void
message(enum message_level level,YYLTYPE * location,const char * fmt,...)58 message(enum message_level level, YYLTYPE *location,
59 const char *fmt, ...)
60 {
61 static const char *level_str[] = { "warning", "error" };
62 va_list args;
63
64 if (location)
65 fprintf(stderr, "%s:%d:%d: %s: ", input_filename,
66 location->first_line,
67 location->first_column, level_str[level]);
68 else
69 fprintf(stderr, "%s:%s: ", input_filename, level_str[level]);
70
71 va_start(args, fmt);
72 vfprintf(stderr, fmt, args);
73 va_end(args);
74 }
75
76 #define warn(flag, l, fmt, ...) \
77 do { \
78 if (warning_flags & WARN_ ## flag) \
79 message(WARN, l, fmt, ## __VA_ARGS__); \
80 } while (0)
81
82 #define error(l, fmt, ...) \
83 do { \
84 message(ERROR, l, fmt, ## __VA_ARGS__); \
85 } while (0)
86
87 static bool
isPowerofTwo(unsigned int x)88 isPowerofTwo(unsigned int x)
89 {
90 return x && (!(x & (x - 1)));
91 }
92
93 static struct brw_reg
set_direct_src_operand(struct brw_reg * reg,int type)94 set_direct_src_operand(struct brw_reg *reg, int type)
95 {
96 return brw_make_reg(reg->file,
97 reg->nr,
98 reg->subnr,
99 0, // negate
100 0, // abs
101 type,
102 0, // vstride
103 0, // width
104 0, // hstride
105 BRW_SWIZZLE_NOOP,
106 WRITEMASK_XYZW);
107 }
108
109 static void
i965_asm_unary_instruction(int opcode,struct brw_codegen * p,struct brw_reg dest,struct brw_reg src0)110 i965_asm_unary_instruction(int opcode, struct brw_codegen *p,
111 struct brw_reg dest, struct brw_reg src0)
112 {
113 switch (opcode) {
114 case BRW_OPCODE_BFREV:
115 brw_BFREV(p, dest, src0);
116 break;
117 case BRW_OPCODE_CBIT:
118 brw_CBIT(p, dest, src0);
119 break;
120 case BRW_OPCODE_MOV:
121 brw_MOV(p, dest, src0);
122 break;
123 case BRW_OPCODE_FBL:
124 brw_FBL(p, dest, src0);
125 break;
126 case BRW_OPCODE_FRC:
127 brw_FRC(p, dest, src0);
128 break;
129 case BRW_OPCODE_FBH:
130 brw_FBH(p, dest, src0);
131 break;
132 case BRW_OPCODE_NOT:
133 brw_NOT(p, dest, src0);
134 break;
135 case BRW_OPCODE_RNDE:
136 brw_RNDE(p, dest, src0);
137 break;
138 case BRW_OPCODE_RNDZ:
139 brw_RNDZ(p, dest, src0);
140 break;
141 case BRW_OPCODE_RNDD:
142 brw_RNDD(p, dest, src0);
143 break;
144 case BRW_OPCODE_LZD:
145 brw_LZD(p, dest, src0);
146 break;
147 case BRW_OPCODE_RNDU:
148 fprintf(stderr, "Opcode BRW_OPCODE_RNDU unhandled\n");
149 break;
150 default:
151 fprintf(stderr, "Unsupported unary opcode\n");
152 }
153 }
154
155 static void
i965_asm_binary_instruction(int opcode,struct brw_codegen * p,struct brw_reg dest,struct brw_reg src0,struct brw_reg src1)156 i965_asm_binary_instruction(int opcode,
157 struct brw_codegen *p,
158 struct brw_reg dest,
159 struct brw_reg src0,
160 struct brw_reg src1)
161 {
162 switch (opcode) {
163 case BRW_OPCODE_ADDC:
164 brw_ADDC(p, dest, src0, src1);
165 break;
166 case BRW_OPCODE_BFI1:
167 brw_BFI1(p, dest, src0, src1);
168 break;
169 case BRW_OPCODE_DP2:
170 brw_DP2(p, dest, src0, src1);
171 break;
172 case BRW_OPCODE_DP3:
173 brw_DP3(p, dest, src0, src1);
174 break;
175 case BRW_OPCODE_DP4:
176 brw_DP4(p, dest, src0, src1);
177 break;
178 case BRW_OPCODE_DPH:
179 brw_DPH(p, dest, src0, src1);
180 break;
181 case BRW_OPCODE_LINE:
182 brw_LINE(p, dest, src0, src1);
183 break;
184 case BRW_OPCODE_MAC:
185 brw_MAC(p, dest, src0, src1);
186 break;
187 case BRW_OPCODE_MACH:
188 brw_MACH(p, dest, src0, src1);
189 break;
190 case BRW_OPCODE_PLN:
191 brw_PLN(p, dest, src0, src1);
192 break;
193 case BRW_OPCODE_ROL:
194 brw_ROL(p, dest, src0, src1);
195 break;
196 case BRW_OPCODE_ROR:
197 brw_ROR(p, dest, src0, src1);
198 break;
199 case BRW_OPCODE_SUBB:
200 brw_SUBB(p, dest, src0, src1);
201 break;
202 case BRW_OPCODE_ADD:
203 brw_ADD(p, dest, src0, src1);
204 break;
205 case BRW_OPCODE_CMP:
206 /* Third parameter is conditional modifier
207 * which gets updated later
208 */
209 brw_CMP(p, dest, 0, src0, src1);
210 break;
211 case BRW_OPCODE_AND:
212 brw_AND(p, dest, src0, src1);
213 break;
214 case BRW_OPCODE_ASR:
215 brw_ASR(p, dest, src0, src1);
216 break;
217 case BRW_OPCODE_AVG:
218 brw_AVG(p, dest, src0, src1);
219 break;
220 case BRW_OPCODE_OR:
221 brw_OR(p, dest, src0, src1);
222 break;
223 case BRW_OPCODE_SEL:
224 brw_SEL(p, dest, src0, src1);
225 break;
226 case BRW_OPCODE_SHL:
227 brw_SHL(p, dest, src0, src1);
228 break;
229 case BRW_OPCODE_SHR:
230 brw_SHR(p, dest, src0, src1);
231 break;
232 case BRW_OPCODE_XOR:
233 brw_XOR(p, dest, src0, src1);
234 break;
235 case BRW_OPCODE_MUL:
236 brw_MUL(p, dest, src0, src1);
237 break;
238 default:
239 fprintf(stderr, "Unsupported binary opcode\n");
240 }
241 }
242
243 static void
i965_asm_ternary_instruction(int opcode,struct brw_codegen * p,struct brw_reg dest,struct brw_reg src0,struct brw_reg src1,struct brw_reg src2)244 i965_asm_ternary_instruction(int opcode,
245 struct brw_codegen *p,
246 struct brw_reg dest,
247 struct brw_reg src0,
248 struct brw_reg src1,
249 struct brw_reg src2)
250 {
251 switch (opcode) {
252 case BRW_OPCODE_MAD:
253 brw_MAD(p, dest, src0, src1, src2);
254 break;
255 case BRW_OPCODE_CSEL:
256 brw_CSEL(p, dest, src0, src1, src2);
257 break;
258 case BRW_OPCODE_LRP:
259 brw_LRP(p, dest, src0, src1, src2);
260 break;
261 case BRW_OPCODE_BFE:
262 brw_BFE(p, dest, src0, src1, src2);
263 break;
264 case BRW_OPCODE_BFI2:
265 brw_BFI2(p, dest, src0, src1, src2);
266 break;
267 case BRW_OPCODE_DP4A:
268 brw_DP4A(p, dest, src0, src1, src2);
269 break;
270 case BRW_OPCODE_ADD3:
271 brw_ADD3(p, dest, src0, src1, src2);
272 break;
273 default:
274 fprintf(stderr, "Unsupported ternary opcode\n");
275 }
276 }
277
278 static void
i965_asm_set_instruction_options(struct brw_codegen * p,struct options options)279 i965_asm_set_instruction_options(struct brw_codegen *p,
280 struct options options)
281 {
282 brw_inst_set_access_mode(p->devinfo, brw_last_inst,
283 options.access_mode);
284 brw_inst_set_mask_control(p->devinfo, brw_last_inst,
285 options.mask_control);
286 if (p->devinfo->ver < 12) {
287 brw_inst_set_thread_control(p->devinfo, brw_last_inst,
288 options.thread_control);
289 brw_inst_set_no_dd_check(p->devinfo, brw_last_inst,
290 options.no_dd_check);
291 brw_inst_set_no_dd_clear(p->devinfo, brw_last_inst,
292 options.no_dd_clear);
293 } else {
294 enum opcode opcode = brw_inst_opcode(p->isa, brw_last_inst);
295 brw_inst_set_swsb(p->devinfo, brw_last_inst,
296 tgl_swsb_encode(p->devinfo, options.depinfo,
297 opcode));
298 }
299 brw_inst_set_debug_control(p->devinfo, brw_last_inst,
300 options.debug_control);
301 if (p->devinfo->ver < 20) {
302 brw_inst_set_acc_wr_control(p->devinfo, brw_last_inst,
303 options.acc_wr_control);
304 }
305 brw_inst_set_cmpt_control(p->devinfo, brw_last_inst,
306 options.compaction);
307 }
308
309 static void
add_label(struct brw_codegen * p,const char * label_name,enum instr_label_type type)310 add_label(struct brw_codegen *p, const char* label_name, enum instr_label_type type)
311 {
312 if (!label_name) {
313 return;
314 }
315
316 struct instr_label *label = rzalloc(p->mem_ctx, struct instr_label);
317
318 label->name = ralloc_strdup(p->mem_ctx, label_name);
319 label->offset = p->next_insn_offset;
320 label->type = type;
321
322 list_addtail(&label->link, &instr_labels);
323 }
324
325 %}
326
327 %locations
328
329 %start ROOT
330
331 %union {
332 char *string;
333 double number;
334 int integer;
335 unsigned long long int llint;
336 struct brw_reg reg;
337 enum brw_reg_type reg_type;
338 struct brw_codegen *program;
339 struct predicate predicate;
340 struct condition condition;
341 struct options options;
342 struct instoption instoption;
343 struct msgdesc msgdesc;
344 struct tgl_swsb depinfo;
345 brw_inst *instruction;
346 }
347
348 %token ABS
349 %token COLON
350 %token COMMA
351 %token DOT
352 %token LANGLE RANGLE
353 %token LCURLY RCURLY
354 %token LPAREN RPAREN
355 %token LSQUARE RSQUARE
356 %token PLUS MINUS
357 %token SEMICOLON
358 %token ASSIGN
359
360 /* datatypes */
361 %token <integer> TYPE_B TYPE_UB
362 %token <integer> TYPE_W TYPE_UW
363 %token <integer> TYPE_D TYPE_UD
364 %token <integer> TYPE_Q TYPE_UQ
365 %token <integer> TYPE_V TYPE_UV
366 %token <integer> TYPE_F TYPE_HF
367 %token <integer> TYPE_DF
368 %token <integer> TYPE_VF
369
370 /* label */
371 %token <string> JUMP_LABEL
372 %token <string> JUMP_LABEL_TARGET
373
374 /* opcodes */
375 %token <integer> ADD ADD3 ADDC AND ASR AVG
376 %token <integer> BFE BFI1 BFI2 BFB BFREV BRC BRD BREAK
377 %token <integer> CALL CALLA CASE CBIT CMP CMPN CONT CSEL
378 %token <integer> DIM DO DPAS DPASW DP2 DP3 DP4 DP4A DPH
379 %token <integer> ELSE ENDIF FBH FBL FORK FRC
380 %token <integer> GOTO
381 %token <integer> HALT
382 %token <integer> IF ILLEGAL
383 %token <integer> JMPI JOIN
384 %token <integer> LINE LRP LZD
385 %token <integer> MAC MACH MAD MADM MATH MOV MOVI MUL MREST MSAVE
386 %token <integer> NENOP NOP NOT
387 %token <integer> OR
388 %token <integer> PLN POP PUSH
389 %token <integer> RET RNDD RNDE RNDU RNDZ ROL ROR
390 %token <integer> SEL SENDS SENDSC SHL SHR SMOV SUBB SYNC
391 %token <integer> SEND_GFX4 SENDC_GFX4 SEND_GFX12 SENDC_GFX12
392 %token <integer> WAIT WHILE
393 %token <integer> XOR
394
395 /* extended math functions */
396 %token <integer> COS EXP FDIV INV INVM INTDIV INTDIVMOD INTMOD LOG POW RSQ
397 %token <integer> RSQRTM SIN SINCOS SQRT
398
399 /* sync instruction */
400 %token <integer> ALLRD ALLWR FENCE BAR HOST
401 %type <integer> sync_function
402 %type <reg> sync_arg
403
404 /* shared functions for send */
405 %token CONST CRE DATA DP_DATA_1 GATEWAY PIXEL_INTERP RENDER SAMPLER
406 %token THREAD_SPAWNER URB VME DP_SAMPLER RT_ACCEL SLM TGM UGM
407
408 /* message details for send */
409 %token MSGDESC_BEGIN SRC1_LEN EX_BSO MSGDESC_END
410 %type <msgdesc> msgdesc msgdesc_parts;
411
412 /* Conditional modifiers */
413 %token <integer> EQUAL GREATER GREATER_EQUAL LESS LESS_EQUAL NOT_EQUAL
414 %token <integer> NOT_ZERO OVERFLOW UNORDERED ZERO
415
416 /* register Access Modes */
417 %token ALIGN1 ALIGN16
418
419 /* accumulator write control */
420 %token ACCWREN
421
422 /* compaction control */
423 %token CMPTCTRL
424
425 /* mask control (WeCtrl) */
426 %token WECTRL
427
428 /* debug control */
429 %token BREAKPOINT
430
431 /* dependency control */
432 %token NODDCLR NODDCHK
433
434 /* end of thread */
435 %token EOT
436
437 /* mask control */
438 %token MASK_DISABLE;
439
440 /* predicate control */
441 %token <integer> ANYV ALLV ANY2H ALL2H ANY4H ALL4H ANY8H ALL8H ANY16H ALL16H
442 %token <integer> ANY32H ALL32H
443
444 /* round instructions */
445 %token <integer> ROUND_INCREMENT
446
447 /* staturation */
448 %token SATURATE
449
450 /* thread control */
451 %token ATOMIC SWITCH
452
453 /* quater control */
454 %token QTR_2Q QTR_3Q QTR_4Q QTR_2H QTR_2N QTR_3N QTR_4N QTR_5N
455 %token QTR_6N QTR_7N QTR_8N
456
457 /* channels */
458 %token <integer> X Y Z W
459
460 /* reg files */
461 %token GENREGFILE
462
463 /* vertical stride in register region */
464 %token VxH
465
466 /* register type */
467 %token <integer> GENREG ADDRREG ACCREG FLAGREG NOTIFYREG STATEREG
468 %token <integer> CONTROLREG IPREG PERFORMANCEREG THREADREG CHANNELENABLEREG
469 %token <integer> MASKREG
470
471 %token <integer> INTEGER
472 %token <llint> LONG
473 %token NULL_TOKEN
474
475 %nonassoc SUBREGNUM
476 %left PLUS MINUS
477 %nonassoc DOT
478 %nonassoc EMPTYEXECSIZE
479 %nonassoc LPAREN
480
481 %type <integer> execsize exp
482 %type <llint> exp2
483
484 /* predicate control */
485 %type <integer> predctrl predstate
486 %type <predicate> predicate
487
488 /* conditional modifier */
489 %type <condition> cond_mod
490 %type <integer> condModifiers
491
492 /* instruction options */
493 %type <options> instoptions instoption_list
494 %type <instoption> instoption
495
496 /* writemask */
497 %type <integer> writemask_x writemask_y writemask_z writemask_w
498 %type <integer> writemask
499
500 /* dst operand */
501 %type <reg> dst dstoperand dstoperandex dstoperandex_typed dstreg
502 %type <integer> dstregion
503
504 %type <integer> saturate
505 %type <reg> relativelocation2
506
507 /* src operand */
508 %type <reg> directsrcoperand directsrcaccoperand indirectsrcoperand srcacc
509 %type <reg> srcarcoperandex srcaccimm srcarcoperandex_typed srcimm
510 %type <reg> indirectgenreg indirectregion
511 %type <reg> immreg src reg32 payload directgenreg_list addrparam region
512 %type <reg> region_wh directgenreg
513 %type <reg> desc ex_desc reg32a
514 %type <integer> swizzle
515
516 /* registers */
517 %type <reg> accreg addrreg channelenablereg controlreg flagreg ipreg
518 %type <reg> notifyreg nullreg performancereg threadcontrolreg statereg maskreg
519 %type <integer> subregnum
520
521 /* register types */
522 %type <reg_type> reg_type imm_type
523
524 /* immediate values */
525 %type <llint> immval
526
527 /* instruction opcodes */
528 %type <integer> unaryopcodes binaryopcodes binaryaccopcodes ternaryopcodes
529 %type <integer> sendop sendsop
530 %type <instruction> sendopcode sendsopcode
531
532 %type <integer> negate abs chansel math_function sharedfunction
533
534 %type <string> jumplabeltarget
535 %type <string> jumplabel
536
537 /* SWSB */
538 %token <integer> REG_DIST_CURRENT
539 %token <integer> REG_DIST_FLOAT
540 %token <integer> REG_DIST_INT
541 %token <integer> REG_DIST_LONG
542 %token <integer> REG_DIST_ALL
543 %token <integer> SBID_ALLOC
544 %token <integer> SBID_WAIT_SRC
545 %token <integer> SBID_WAIT_DST
546
547 %type <depinfo> depinfo
548
549 %code {
550
551 static void
add_instruction_option(struct options * options,struct instoption opt)552 add_instruction_option(struct options *options, struct instoption opt)
553 {
554 if (opt.type == INSTOPTION_DEP_INFO) {
555 if (opt.depinfo_value.regdist) {
556 options->depinfo.regdist = opt.depinfo_value.regdist;
557 options->depinfo.pipe = opt.depinfo_value.pipe;
558 } else {
559 options->depinfo.sbid = opt.depinfo_value.sbid;
560 options->depinfo.mode = opt.depinfo_value.mode;
561 }
562 return;
563 }
564 if (opt.type == INSTOPTION_CHAN_OFFSET) {
565 options->chan_offset = opt.uint_value;
566 return;
567 }
568 switch (opt.uint_value) {
569 case ALIGN1:
570 options->access_mode = BRW_ALIGN_1;
571 break;
572 case ALIGN16:
573 options->access_mode = BRW_ALIGN_16;
574 break;
575 case SWITCH:
576 options->thread_control |= BRW_THREAD_SWITCH;
577 break;
578 case ATOMIC:
579 options->thread_control |= BRW_THREAD_ATOMIC;
580 break;
581 case NODDCHK:
582 options->no_dd_check = true;
583 break;
584 case NODDCLR:
585 options->no_dd_clear = true;
586 break;
587 case MASK_DISABLE:
588 options->mask_control |= BRW_MASK_DISABLE;
589 break;
590 case BREAKPOINT:
591 options->debug_control = BRW_DEBUG_BREAKPOINT;
592 break;
593 case WECTRL:
594 options->mask_control |= BRW_WE_ALL;
595 break;
596 case CMPTCTRL:
597 options->compaction = true;
598 break;
599 case ACCWREN:
600 options->acc_wr_control = true;
601 break;
602 case EOT:
603 options->end_of_thread = true;
604 break;
605 }
606 }
607 }
608 %%
609
610 ROOT:
611 instrseq
612 ;
613
614 instrseq:
615 instrseq instruction SEMICOLON
616 | instrseq relocatableinstruction SEMICOLON
617 | instruction SEMICOLON
618 | relocatableinstruction SEMICOLON
619 | instrseq jumplabeltarget
620 | jumplabeltarget
621 ;
622
623 /* Instruction Group */
624 instruction:
625 unaryinstruction
626 | binaryinstruction
627 | binaryaccinstruction
628 | mathinstruction
629 | nopinstruction
630 | waitinstruction
631 | ternaryinstruction
632 | sendinstruction
633 | illegalinstruction
634 | syncinstruction
635 ;
636
637 relocatableinstruction:
638 jumpinstruction
639 | branchinstruction
640 | breakinstruction
641 | loopinstruction
642 ;
643
644 illegalinstruction:
645 ILLEGAL execsize instoptions
646 {
647 brw_next_insn(p, $1);
648 brw_inst_set_exec_size(p->devinfo, brw_last_inst, $2);
649 i965_asm_set_instruction_options(p, $3);
650 }
651 ;
652
653 /* Unary instruction */
654 unaryinstruction:
655 predicate unaryopcodes saturate cond_mod execsize dst srcaccimm instoptions
656 {
657 brw_set_default_access_mode(p, $8.access_mode);
658 i965_asm_unary_instruction($2, p, $6, $7);
659 brw_pop_insn_state(p);
660 i965_asm_set_instruction_options(p, $8);
661 brw_inst_set_cond_modifier(p->devinfo, brw_last_inst,
662 $4.cond_modifier);
663
664 if (!brw_inst_flag_reg_nr(p->devinfo, brw_last_inst)) {
665 brw_inst_set_flag_reg_nr(p->devinfo,
666 brw_last_inst,
667 $4.flag_reg_nr);
668 brw_inst_set_flag_subreg_nr(p->devinfo,
669 brw_last_inst,
670 $4.flag_subreg_nr);
671 }
672
673 if ($7.file != IMM) {
674 brw_inst_set_src0_vstride(p->devinfo, brw_last_inst,
675 $7.vstride);
676 }
677 brw_inst_set_saturate(p->devinfo, brw_last_inst, $3);
678 brw_inst_set_exec_size(p->devinfo, brw_last_inst, $5);
679 brw_inst_set_group(p->devinfo, brw_last_inst, $8.chan_offset);
680 }
681 ;
682
683 unaryopcodes:
684 BFREV
685 | CBIT
686 | DIM
687 | FBH
688 | FBL
689 | FRC
690 | LZD
691 | MOV
692 | NOT
693 | RNDD
694 | RNDE
695 | RNDU
696 | RNDZ
697 ;
698
699 /* Binary instruction */
700 binaryinstruction:
701 predicate binaryopcodes saturate cond_mod execsize dst srcimm srcimm instoptions
702 {
703 brw_set_default_access_mode(p, $9.access_mode);
704 i965_asm_binary_instruction($2, p, $6, $7, $8);
705 i965_asm_set_instruction_options(p, $9);
706 brw_inst_set_cond_modifier(p->devinfo, brw_last_inst,
707 $4.cond_modifier);
708
709 if (!brw_inst_flag_reg_nr(p->devinfo, brw_last_inst)) {
710 brw_inst_set_flag_reg_nr(p->devinfo, brw_last_inst,
711 $4.flag_reg_nr);
712 brw_inst_set_flag_subreg_nr(p->devinfo, brw_last_inst,
713 $4.flag_subreg_nr);
714 }
715
716 brw_inst_set_saturate(p->devinfo, brw_last_inst, $3);
717 brw_inst_set_exec_size(p->devinfo, brw_last_inst, $5);
718 brw_inst_set_group(p->devinfo, brw_last_inst, $9.chan_offset);
719
720 brw_pop_insn_state(p);
721 }
722 ;
723
724 binaryopcodes:
725 ADDC
726 | BFI1
727 | DP2
728 | DP3
729 | DP4
730 | DPH
731 | LINE
732 | MAC
733 | MACH
734 | MUL
735 | PLN
736 | ROL
737 | ROR
738 | SUBB
739 ;
740
741 /* Binary acc instruction */
742 binaryaccinstruction:
743 predicate binaryaccopcodes saturate cond_mod execsize dst srcacc srcimm instoptions
744 {
745 brw_set_default_access_mode(p, $9.access_mode);
746 i965_asm_binary_instruction($2, p, $6, $7, $8);
747 brw_pop_insn_state(p);
748 i965_asm_set_instruction_options(p, $9);
749 brw_inst_set_cond_modifier(p->devinfo, brw_last_inst,
750 $4.cond_modifier);
751
752 if (!brw_inst_flag_reg_nr(p->devinfo, brw_last_inst)) {
753 brw_inst_set_flag_reg_nr(p->devinfo,
754 brw_last_inst,
755 $4.flag_reg_nr);
756 brw_inst_set_flag_subreg_nr(p->devinfo,
757 brw_last_inst,
758 $4.flag_subreg_nr);
759 }
760
761 brw_inst_set_saturate(p->devinfo, brw_last_inst, $3);
762 brw_inst_set_exec_size(p->devinfo, brw_last_inst, $5);
763 brw_inst_set_group(p->devinfo, brw_last_inst, $9.chan_offset);
764 }
765 ;
766
767 binaryaccopcodes:
768 ADD
769 | AND
770 | ASR
771 | AVG
772 | CMP
773 | CMPN
774 | OR
775 | SEL
776 | SHL
777 | SHR
778 | XOR
779 ;
780
781 /* Math instruction */
782 mathinstruction:
783 predicate MATH saturate math_function execsize dst src srcimm instoptions
784 {
785 brw_set_default_access_mode(p, $9.access_mode);
786 gfx6_math(p, $6, $4, $7, $8);
787 i965_asm_set_instruction_options(p, $9);
788 brw_inst_set_exec_size(p->devinfo, brw_last_inst, $5);
789 brw_inst_set_saturate(p->devinfo, brw_last_inst, $3);
790 brw_inst_set_group(p->devinfo, brw_last_inst, $9.chan_offset);
791 brw_pop_insn_state(p);
792 }
793 ;
794
795 math_function:
796 COS
797 | EXP
798 | FDIV
799 | INV
800 | INVM
801 | INTDIV
802 | INTDIVMOD
803 | INTMOD
804 | LOG
805 | POW
806 | RSQ
807 | RSQRTM
808 | SIN
809 | SQRT
810 | SINCOS
811 ;
812
813 /* NOP instruction */
814 nopinstruction:
815 NOP
816 {
817 brw_NOP(p);
818 }
819 ;
820
821 /* Ternary operand instruction */
822 ternaryinstruction:
823 predicate ternaryopcodes saturate cond_mod execsize dst srcimm src srcimm instoptions
824 {
825 brw_set_default_access_mode(p, $10.access_mode);
826 i965_asm_ternary_instruction($2, p, $6, $7, $8, $9);
827 brw_pop_insn_state(p);
828 i965_asm_set_instruction_options(p, $10);
829 brw_inst_set_cond_modifier(p->devinfo, brw_last_inst,
830 $4.cond_modifier);
831
832 if (p->devinfo->ver < 12) {
833 brw_inst_set_3src_a16_flag_reg_nr(p->devinfo, brw_last_inst,
834 $4.flag_reg_nr);
835 brw_inst_set_3src_a16_flag_subreg_nr(p->devinfo, brw_last_inst,
836 $4.flag_subreg_nr);
837 }
838
839 brw_inst_set_saturate(p->devinfo, brw_last_inst, $3);
840 brw_inst_set_exec_size(p->devinfo, brw_last_inst, $5);
841 brw_inst_set_group(p->devinfo, brw_last_inst, $10.chan_offset);
842 }
843 ;
844
845 ternaryopcodes:
846 CSEL
847 | BFE
848 | BFI2
849 | LRP
850 | MAD
851 | DP4A
852 | ADD3
853 ;
854
855 /* Wait instruction */
856 waitinstruction:
857 WAIT execsize dst instoptions
858 {
859 brw_next_insn(p, $1);
860 i965_asm_set_instruction_options(p, $4);
861 brw_inst_set_exec_size(p->devinfo, brw_last_inst, $2);
862 brw_set_default_access_mode(p, $4.access_mode);
863 struct brw_reg dest = $3;
864 dest.swizzle = brw_swizzle_for_mask(dest.writemask);
865 if (dest.file != ARF || dest.nr != BRW_ARF_NOTIFICATION_COUNT)
866 error(&@1, "WAIT must use the notification register\n");
867 brw_set_dest(p, brw_last_inst, dest);
868 brw_set_src0(p, brw_last_inst, dest);
869 brw_set_src1(p, brw_last_inst, brw_null_reg());
870 brw_inst_set_mask_control(p->devinfo, brw_last_inst, BRW_MASK_DISABLE);
871 }
872 ;
873
874 /* Send instruction */
875 sendinstruction:
876 predicate sendopcode execsize dst payload exp2 sharedfunction msgdesc instoptions
877 {
878 i965_asm_set_instruction_options(p, $9);
879 brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3);
880 brw_set_dest(p, brw_last_inst, $4);
881 brw_set_src0(p, brw_last_inst, $5);
882 brw_inst_set_bits(brw_last_inst, 127, 96, $6);
883 brw_inst_set_src1_file_type(p->devinfo, brw_last_inst,
884 IMM,
885 BRW_TYPE_UD);
886 brw_inst_set_sfid(p->devinfo, brw_last_inst, $7);
887 brw_inst_set_eot(p->devinfo, brw_last_inst, $9.end_of_thread);
888 brw_inst_set_group(p->devinfo, brw_last_inst, $9.chan_offset);
889
890 brw_pop_insn_state(p);
891 }
892 | predicate sendopcode execsize dst payload payload exp2 sharedfunction msgdesc instoptions
893 {
894 assert(p->devinfo->ver < 12);
895
896 i965_asm_set_instruction_options(p, $10);
897 brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3);
898 brw_set_dest(p, brw_last_inst, $4);
899 brw_set_src0(p, brw_last_inst, $5);
900 brw_inst_set_bits(brw_last_inst, 127, 96, $7);
901 brw_inst_set_sfid(p->devinfo, brw_last_inst, $8);
902 brw_inst_set_eot(p->devinfo, brw_last_inst, $10.end_of_thread);
903 brw_inst_set_group(p->devinfo, brw_last_inst, $10.chan_offset);
904
905 brw_pop_insn_state(p);
906 }
907 | predicate sendsopcode execsize dst payload payload desc ex_desc sharedfunction msgdesc instoptions
908 {
909 i965_asm_set_instruction_options(p, $11);
910 brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3);
911 brw_set_dest(p, brw_last_inst, $4);
912 brw_set_src0(p, brw_last_inst, $5);
913 brw_set_src1(p, brw_last_inst, $6);
914
915 if ($7.file == IMM) {
916 brw_inst_set_send_sel_reg32_desc(p->devinfo, brw_last_inst, 0);
917 brw_inst_set_send_desc(p->devinfo, brw_last_inst, $7.ud);
918 } else {
919 brw_inst_set_send_sel_reg32_desc(p->devinfo, brw_last_inst, 1);
920 }
921
922 if ($8.file == IMM) {
923 brw_inst_set_send_sel_reg32_ex_desc(p->devinfo, brw_last_inst, 0);
924 brw_inst_set_sends_ex_desc(p->devinfo, brw_last_inst, $8.ud);
925 } else {
926 brw_inst_set_send_sel_reg32_ex_desc(p->devinfo, brw_last_inst, 1);
927 brw_inst_set_send_ex_desc_ia_subreg_nr(p->devinfo, brw_last_inst, $8.subnr >> 2);
928 }
929
930 brw_inst_set_sfid(p->devinfo, brw_last_inst, $9);
931 brw_inst_set_eot(p->devinfo, brw_last_inst, $11.end_of_thread);
932 brw_inst_set_group(p->devinfo, brw_last_inst, $11.chan_offset);
933
934 if (p->devinfo->verx10 >= 125 && $10.ex_bso) {
935 brw_inst_set_send_ex_bso(p->devinfo, brw_last_inst, 1);
936 brw_inst_set_send_src1_len(p->devinfo, brw_last_inst,
937 $10.src1_len);
938 }
939
940 brw_pop_insn_state(p);
941 }
942 ;
943
944 sendop:
945 SEND_GFX4
946 | SENDC_GFX4
947 ;
948
949 sendsop:
950 SEND_GFX12
951 | SENDC_GFX12
952 | SENDS
953 | SENDSC
954 ;
955
956 sendopcode:
957 sendop { $$ = brw_next_insn(p, $1); }
958 ;
959
960 sendsopcode:
961 sendsop { $$ = brw_next_insn(p, $1); }
962 ;
963
964 sharedfunction:
965 NULL_TOKEN { $$ = BRW_SFID_NULL; }
966 | GATEWAY { $$ = BRW_SFID_MESSAGE_GATEWAY; }
967 | URB { $$ = BRW_SFID_URB; }
968 | THREAD_SPAWNER { $$ = BRW_SFID_THREAD_SPAWNER; }
969 | VME { $$ = BRW_SFID_VME; }
970 | RENDER { $$ = GFX6_SFID_DATAPORT_RENDER_CACHE; }
971 | CONST { $$ = GFX6_SFID_DATAPORT_CONSTANT_CACHE; }
972 | DATA { $$ = GFX7_SFID_DATAPORT_DATA_CACHE; }
973 | PIXEL_INTERP { $$ = GFX7_SFID_PIXEL_INTERPOLATOR; }
974 | DP_DATA_1 { $$ = HSW_SFID_DATAPORT_DATA_CACHE_1; }
975 | CRE { $$ = HSW_SFID_CRE; }
976 | SAMPLER { $$ = BRW_SFID_SAMPLER; }
977 | DP_SAMPLER { $$ = GFX6_SFID_DATAPORT_SAMPLER_CACHE; }
978 | RT_ACCEL { $$ = GEN_RT_SFID_RAY_TRACE_ACCELERATOR; }
979 | SLM { $$ = GFX12_SFID_SLM; }
980 | TGM { $$ = GFX12_SFID_TGM; }
981 | UGM { $$ = GFX12_SFID_UGM; }
982 ;
983
984 exp2:
985 LONG { $$ = $1; }
986 | MINUS LONG { $$ = -$2; }
987 ;
988
989 desc:
990 reg32a
991 | exp2
992 {
993 $$ = brw_imm_ud($1);
994 }
995 ;
996
997 ex_desc:
998 reg32a
999 | exp2
1000 {
1001 $$ = brw_imm_ud($1);
1002 }
1003 ;
1004
1005 reg32a:
1006 addrreg region reg_type
1007 {
1008 $$ = set_direct_src_operand(&$1, $3);
1009 $$ = stride($$, $2.vstride, $2.width, $2.hstride);
1010 }
1011 ;
1012
1013
1014 /* Jump instruction */
1015 jumpinstruction:
1016 predicate JMPI execsize relativelocation2 instoptions
1017 {
1018 brw_next_insn(p, $2);
1019 i965_asm_set_instruction_options(p, $5);
1020 brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3);
1021 brw_set_dest(p, brw_last_inst, brw_ip_reg());
1022 brw_set_src0(p, brw_last_inst, brw_ip_reg());
1023 brw_set_src1(p, brw_last_inst, $4);
1024 brw_inst_set_pred_control(p->devinfo, brw_last_inst,
1025 brw_inst_pred_control(p->devinfo,
1026 brw_last_inst));
1027 brw_pop_insn_state(p);
1028 }
1029 ;
1030
1031 /* branch instruction */
1032 branchinstruction:
1033 predicate ENDIF execsize JUMP_LABEL instoptions
1034 {
1035 add_label(p, $4, INSTR_LABEL_JIP);
1036
1037 brw_next_insn(p, $2);
1038 i965_asm_set_instruction_options(p, $5);
1039 brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3);
1040
1041 brw_set_src0(p, brw_last_inst, brw_imm_d(0x0));
1042
1043 brw_pop_insn_state(p);
1044 }
1045 | ELSE execsize JUMP_LABEL jumplabel instoptions
1046 {
1047 add_label(p, $3, INSTR_LABEL_JIP);
1048 add_label(p, $4, INSTR_LABEL_UIP);
1049
1050 brw_next_insn(p, $1);
1051 i965_asm_set_instruction_options(p, $5);
1052 brw_inst_set_exec_size(p->devinfo, brw_last_inst, $2);
1053
1054 brw_set_dest(p, brw_last_inst, retype(brw_null_reg(),
1055 BRW_TYPE_D));
1056 if (p->devinfo->ver < 12)
1057 brw_set_src0(p, brw_last_inst, brw_imm_d(0));
1058 }
1059 | predicate IF execsize JUMP_LABEL jumplabel instoptions
1060 {
1061 add_label(p, $4, INSTR_LABEL_JIP);
1062 add_label(p, $5, INSTR_LABEL_UIP);
1063
1064 brw_next_insn(p, $2);
1065 i965_asm_set_instruction_options(p, $6);
1066 brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3);
1067
1068 brw_set_dest(p, brw_last_inst,
1069 vec1(retype(brw_null_reg(),
1070 BRW_TYPE_D)));
1071 if (p->devinfo->ver < 12)
1072 brw_set_src0(p, brw_last_inst, brw_imm_d(0x0));
1073
1074 brw_pop_insn_state(p);
1075 }
1076 ;
1077
1078 /* break instruction */
1079 breakinstruction:
1080 predicate BREAK execsize JUMP_LABEL JUMP_LABEL instoptions
1081 {
1082 add_label(p, $4, INSTR_LABEL_JIP);
1083 add_label(p, $5, INSTR_LABEL_UIP);
1084
1085 brw_next_insn(p, $2);
1086 i965_asm_set_instruction_options(p, $6);
1087 brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3);
1088
1089 brw_set_dest(p, brw_last_inst, retype(brw_null_reg(),
1090 BRW_TYPE_D));
1091 brw_set_src0(p, brw_last_inst, brw_imm_d(0x0));
1092
1093 brw_pop_insn_state(p);
1094 }
1095 | predicate HALT execsize JUMP_LABEL JUMP_LABEL instoptions
1096 {
1097 add_label(p, $4, INSTR_LABEL_JIP);
1098 add_label(p, $5, INSTR_LABEL_UIP);
1099
1100 brw_next_insn(p, $2);
1101 i965_asm_set_instruction_options(p, $6);
1102 brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3);
1103
1104 brw_set_dest(p, brw_last_inst, retype(brw_null_reg(),
1105 BRW_TYPE_D));
1106
1107 if (p->devinfo->ver < 12) {
1108 brw_set_src0(p, brw_last_inst, brw_imm_d(0x0));
1109 }
1110
1111 brw_pop_insn_state(p);
1112 }
1113 | predicate CONT execsize JUMP_LABEL JUMP_LABEL instoptions
1114 {
1115 add_label(p, $4, INSTR_LABEL_JIP);
1116 add_label(p, $5, INSTR_LABEL_UIP);
1117
1118 brw_next_insn(p, $2);
1119 i965_asm_set_instruction_options(p, $6);
1120 brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3);
1121 brw_set_dest(p, brw_last_inst, brw_ip_reg());
1122
1123 brw_set_src0(p, brw_last_inst, brw_imm_d(0x0));
1124
1125 brw_pop_insn_state(p);
1126 }
1127 ;
1128
1129 /* loop instruction */
1130 loopinstruction:
1131 predicate WHILE execsize JUMP_LABEL instoptions
1132 {
1133 add_label(p, $4, INSTR_LABEL_JIP);
1134
1135 brw_next_insn(p, $2);
1136 i965_asm_set_instruction_options(p, $5);
1137 brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3);
1138
1139 brw_set_dest(p, brw_last_inst,
1140 retype(brw_null_reg(),
1141 BRW_TYPE_D));
1142 if (p->devinfo->ver < 12)
1143 brw_set_src0(p, brw_last_inst, brw_imm_d(0x0));
1144
1145 brw_pop_insn_state(p);
1146 }
1147 | DO execsize instoptions
1148 {
1149 brw_next_insn(p, $1);
1150 }
1151 ;
1152
1153 /* sync instruction */
1154 syncinstruction:
1155 predicate SYNC sync_function execsize sync_arg instoptions
1156 {
1157 if (p->devinfo->ver < 12) {
1158 error(&@2, "sync instruction is supported only on gfx12+\n");
1159 }
1160
1161 if ($5.file == IMM &&
1162 $3 != TGL_SYNC_ALLRD &&
1163 $3 != TGL_SYNC_ALLWR) {
1164 error(&@2, "Only allrd and allwr support immediate argument\n");
1165 }
1166
1167 brw_set_default_access_mode(p, $6.access_mode);
1168 brw_SYNC(p, $3);
1169 i965_asm_set_instruction_options(p, $6);
1170 brw_inst_set_exec_size(p->devinfo, brw_last_inst, $4);
1171 brw_set_src0(p, brw_last_inst, $5);
1172 brw_inst_set_eot(p->devinfo, brw_last_inst, $6.end_of_thread);
1173 brw_inst_set_group(p->devinfo, brw_last_inst, $6.chan_offset);
1174
1175 brw_pop_insn_state(p);
1176 }
1177 ;
1178
1179 sync_function:
1180 NOP { $$ = TGL_SYNC_NOP; }
1181 | ALLRD
1182 | ALLWR
1183 | FENCE
1184 | BAR
1185 | HOST
1186 ;
1187
1188 sync_arg:
1189 nullreg region reg_type
1190 {
1191 $$ = $1;
1192 $$.vstride = $2.vstride;
1193 $$.width = $2.width;
1194 $$.hstride = $2.hstride;
1195 $$.type = $3;
1196 }
1197 | immreg
1198 ;
1199
1200 /* Relative location */
1201 relativelocation2:
1202 immreg
1203 | reg32
1204 ;
1205
1206 jumplabel:
1207 JUMP_LABEL { $$ = $1; }
1208 | /* empty */ { $$ = NULL; }
1209 ;
1210
1211 jumplabeltarget:
1212 JUMP_LABEL_TARGET
1213 {
1214 struct target_label *label = rzalloc(p->mem_ctx, struct target_label);
1215
1216 label->name = ralloc_strdup(p->mem_ctx, $1);
1217 label->offset = p->next_insn_offset;
1218
1219 list_addtail(&label->link, &target_labels);
1220 }
1221 ;
1222
1223 /* Destination register */
1224 dst:
1225 dstoperand
1226 | dstoperandex
1227 ;
1228
1229 dstoperand:
1230 dstreg dstregion writemask reg_type
1231 {
1232 $$ = $1;
1233 $$.vstride = BRW_VERTICAL_STRIDE_1;
1234 $$.width = BRW_WIDTH_1;
1235 $$.hstride = $2;
1236 $$.type = $4;
1237 $$.writemask = $3;
1238 $$.swizzle = BRW_SWIZZLE_NOOP;
1239 $$.subnr = $$.subnr * brw_type_size_bytes($4);
1240 }
1241 ;
1242
1243 dstoperandex:
1244 dstoperandex_typed dstregion writemask reg_type
1245 {
1246 $$ = $1;
1247 $$.hstride = $2;
1248 $$.type = $4;
1249 $$.writemask = $3;
1250 $$.subnr = $$.subnr * brw_type_size_bytes($4);
1251 }
1252 /* BSpec says "When the conditional modifier is present, updates
1253 * to the selected flag register also occur. In this case, the
1254 * register region fields of the ‘null’ operand are valid."
1255 */
1256 | nullreg dstregion writemask reg_type
1257 {
1258 $$ = $1;
1259 $$.vstride = BRW_VERTICAL_STRIDE_1;
1260 $$.width = BRW_WIDTH_1;
1261 $$.hstride = $2;
1262 $$.writemask = $3;
1263 $$.type = $4;
1264 }
1265 | threadcontrolreg
1266 {
1267 $$ = $1;
1268 $$.hstride = 1;
1269 $$.type = BRW_TYPE_UW;
1270 }
1271 ;
1272
1273 dstoperandex_typed:
1274 accreg
1275 | addrreg
1276 | channelenablereg
1277 | controlreg
1278 | flagreg
1279 | ipreg
1280 | maskreg
1281 | notifyreg
1282 | performancereg
1283 | statereg
1284 ;
1285
1286 dstreg:
1287 directgenreg
1288 {
1289 $$ = $1;
1290 $$.address_mode = BRW_ADDRESS_DIRECT;
1291 }
1292 | indirectgenreg
1293 {
1294 $$ = $1;
1295 $$.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
1296 }
1297 ;
1298
1299 /* Source register */
1300 srcaccimm:
1301 srcacc
1302 | immreg
1303 ;
1304
1305 immreg:
1306 immval imm_type
1307 {
1308 switch ($2) {
1309 case BRW_TYPE_UD:
1310 $$ = brw_imm_ud($1);
1311 break;
1312 case BRW_TYPE_D:
1313 $$ = brw_imm_d($1);
1314 break;
1315 case BRW_TYPE_UW:
1316 $$ = brw_imm_uw($1 | ($1 << 16));
1317 break;
1318 case BRW_TYPE_W:
1319 $$ = brw_imm_w($1);
1320 break;
1321 case BRW_TYPE_F:
1322 $$ = brw_imm_reg(BRW_TYPE_F);
1323 /* Set u64 instead of ud since DIM uses a 64-bit F-typed imm */
1324 $$.u64 = $1;
1325 break;
1326 case BRW_TYPE_V:
1327 $$ = brw_imm_v($1);
1328 break;
1329 case BRW_TYPE_UV:
1330 $$ = brw_imm_uv($1);
1331 break;
1332 case BRW_TYPE_VF:
1333 $$ = brw_imm_vf($1);
1334 break;
1335 case BRW_TYPE_Q:
1336 $$ = brw_imm_q($1);
1337 break;
1338 case BRW_TYPE_UQ:
1339 $$ = brw_imm_uq($1);
1340 break;
1341 case BRW_TYPE_DF:
1342 $$ = brw_imm_reg(BRW_TYPE_DF);
1343 $$.d64 = $1;
1344 break;
1345 case BRW_TYPE_HF:
1346 $$ = brw_imm_reg(BRW_TYPE_HF);
1347 $$.ud = $1 | ($1 << 16);
1348 break;
1349 default:
1350 error(&@2, "Unknown immediate type %s\n",
1351 brw_reg_type_to_letters($2));
1352 }
1353 }
1354 ;
1355
1356 reg32:
1357 directgenreg region reg_type
1358 {
1359 $$ = set_direct_src_operand(&$1, $3);
1360 $$ = stride($$, $2.vstride, $2.width, $2.hstride);
1361 }
1362 ;
1363
1364 payload:
1365 directsrcoperand
1366 ;
1367
1368 src:
1369 directsrcoperand
1370 | indirectsrcoperand
1371 ;
1372
1373 srcacc:
1374 directsrcaccoperand
1375 | indirectsrcoperand
1376 ;
1377
1378 srcimm:
1379 directsrcoperand
1380 | indirectsrcoperand
1381 | immreg
1382 ;
1383
1384 directsrcaccoperand:
1385 directsrcoperand
1386 | negate abs accreg region reg_type
1387 {
1388 $$ = set_direct_src_operand(&$3, $5);
1389 $$.negate = $1;
1390 $$.abs = $2;
1391 $$.vstride = $4.vstride;
1392 $$.width = $4.width;
1393 $$.hstride = $4.hstride;
1394 }
1395 ;
1396
1397 srcarcoperandex:
1398 srcarcoperandex_typed region reg_type
1399 {
1400 $$ = brw_make_reg($1.file,
1401 $1.nr,
1402 $1.subnr,
1403 0,
1404 0,
1405 $3,
1406 $2.vstride,
1407 $2.width,
1408 $2.hstride,
1409 BRW_SWIZZLE_NOOP,
1410 WRITEMASK_XYZW);
1411 }
1412 | nullreg region reg_type
1413 {
1414 $$ = set_direct_src_operand(&$1, $3);
1415 $$.vstride = $2.vstride;
1416 $$.width = $2.width;
1417 $$.hstride = $2.hstride;
1418 }
1419 | threadcontrolreg
1420 {
1421 $$ = set_direct_src_operand(&$1, BRW_TYPE_UW);
1422 }
1423 ;
1424
1425 srcarcoperandex_typed:
1426 channelenablereg
1427 | controlreg
1428 | flagreg
1429 | ipreg
1430 | maskreg
1431 | statereg
1432 ;
1433
1434 indirectsrcoperand:
1435 negate abs indirectgenreg indirectregion swizzle reg_type
1436 {
1437 $$ = brw_make_reg($3.file,
1438 0,
1439 $3.subnr,
1440 $1, // negate
1441 $2, // abs
1442 $6,
1443 $4.vstride,
1444 $4.width,
1445 $4.hstride,
1446 $5,
1447 WRITEMASK_X);
1448
1449 $$.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
1450 // brw_reg set indirect_offset to 0 so set it to valid value
1451 $$.indirect_offset = $3.indirect_offset;
1452 }
1453 ;
1454
1455 directgenreg_list:
1456 directgenreg
1457 | notifyreg
1458 | addrreg
1459 | performancereg
1460 ;
1461
1462 directsrcoperand:
1463 negate abs directgenreg_list region swizzle reg_type
1464 {
1465 $$ = brw_make_reg($3.file,
1466 $3.nr,
1467 $3.subnr,
1468 $1,
1469 $2,
1470 $6,
1471 $4.vstride,
1472 $4.width,
1473 $4.hstride,
1474 $5,
1475 WRITEMASK_X);
1476 }
1477 | srcarcoperandex
1478 ;
1479
1480 /* Address register */
1481 addrparam:
1482 addrreg exp
1483 {
1484 memset(&$$, '\0', sizeof($$));
1485 $$.subnr = $1.subnr;
1486 $$.indirect_offset = $2;
1487 }
1488 | addrreg
1489 ;
1490
1491 /* Register files and register numbers */
1492 exp:
1493 INTEGER { $$ = $1; }
1494 | LONG { $$ = $1; }
1495 ;
1496
1497 subregnum:
1498 DOT exp { $$ = $2; }
1499 | /* empty */ %prec SUBREGNUM { $$ = 0; }
1500 ;
1501
1502 directgenreg:
1503 GENREG subregnum
1504 {
1505 memset(&$$, '\0', sizeof($$));
1506 $$.file = FIXED_GRF;
1507 $$.nr = $1 * reg_unit(p->devinfo);
1508 $$.subnr = $2;
1509 }
1510 ;
1511
1512 indirectgenreg:
1513 GENREGFILE LSQUARE addrparam RSQUARE
1514 {
1515 memset(&$$, '\0', sizeof($$));
1516 $$.file = FIXED_GRF;
1517 $$.subnr = $3.subnr;
1518 $$.indirect_offset = $3.indirect_offset;
1519 }
1520 ;
1521
1522 addrreg:
1523 ADDRREG subregnum
1524 {
1525 int subnr = 16;
1526
1527 if ($2 > subnr)
1528 error(&@2, "Address sub register number %d"
1529 "out of range\n", $2);
1530
1531 $$.file = ARF;
1532 $$.nr = BRW_ARF_ADDRESS;
1533 $$.subnr = $2;
1534 }
1535 ;
1536
1537 accreg:
1538 ACCREG subregnum
1539 {
1540 int nr_reg = 10;
1541
1542 if ($1 > nr_reg)
1543 error(&@1, "Accumulator register number %d"
1544 " out of range\n", $1);
1545
1546 memset(&$$, '\0', sizeof($$));
1547 $$.file = ARF;
1548 $$.nr = BRW_ARF_ACCUMULATOR;
1549 $$.subnr = $2;
1550 }
1551 ;
1552
1553 flagreg:
1554 FLAGREG subregnum
1555 {
1556 // 2 flag reg
1557 int nr_reg = 2;
1558 int subnr = nr_reg;
1559
1560 if ($1 > nr_reg)
1561 error(&@1, "Flag register number %d"
1562 " out of range \n", $1);
1563 if ($2 > subnr)
1564 error(&@2, "Flag subregister number %d"
1565 " out of range\n", $2);
1566
1567 $$.file = ARF;
1568 $$.nr = BRW_ARF_FLAG | $1;
1569 $$.subnr = $2;
1570 }
1571 ;
1572
1573 maskreg:
1574 MASKREG subregnum
1575 {
1576 if ($1 > 0)
1577 error(&@1, "Mask register number %d"
1578 " out of range\n", $1);
1579
1580 $$.file = ARF;
1581 $$.nr = BRW_ARF_MASK;
1582 $$.subnr = $2;
1583 }
1584 ;
1585
1586 notifyreg:
1587 NOTIFYREG subregnum
1588 {
1589 int subnr = (p->devinfo->ver >= 11) ? 2 : 3;
1590 if ($2 > subnr)
1591 error(&@2, "Notification sub register number %d"
1592 " out of range\n", $2);
1593
1594 $$.file = ARF;
1595 $$.nr = BRW_ARF_NOTIFICATION_COUNT;
1596 $$.subnr = $2;
1597 }
1598 ;
1599
1600 statereg:
1601 STATEREG subregnum
1602 {
1603 if ($1 > 2)
1604 error(&@1, "State register number %d"
1605 " out of range\n", $1);
1606
1607 if ($2 > 4)
1608 error(&@2, "State sub register number %d"
1609 " out of range\n", $2);
1610
1611 $$.file = ARF;
1612 $$.nr = BRW_ARF_STATE;
1613 $$.subnr = $2;
1614 }
1615 ;
1616
1617 controlreg:
1618 CONTROLREG subregnum
1619 {
1620 if ($2 > 3)
1621 error(&@2, "control sub register number %d"
1622 " out of range\n", $2);
1623
1624 $$.file = ARF;
1625 $$.nr = BRW_ARF_CONTROL;
1626 $$.subnr = $2;
1627 }
1628 ;
1629
1630 ipreg:
1631 IPREG { $$ = brw_ip_reg(); }
1632 ;
1633
1634 nullreg:
1635 NULL_TOKEN { $$ = brw_null_reg(); }
1636 ;
1637
1638 threadcontrolreg:
1639 THREADREG subregnum
1640 {
1641 if ($2 > 7)
1642 error(&@2, "Thread control sub register number %d"
1643 " out of range\n", $2);
1644
1645 $$.file = ARF;
1646 $$.nr = BRW_ARF_TDR;
1647 $$.subnr = $2;
1648 }
1649 ;
1650
1651 performancereg:
1652 PERFORMANCEREG subregnum
1653 {
1654 int subnr;
1655 if (p->devinfo->ver >= 10)
1656 subnr = 5;
1657 else
1658 subnr = 4;
1659
1660 if ($2 > subnr)
1661 error(&@2, "Performance sub register number %d"
1662 " out of range\n", $2);
1663
1664 $$.file = ARF;
1665 $$.nr = BRW_ARF_TIMESTAMP;
1666 $$.subnr = $2;
1667 }
1668 ;
1669
1670 channelenablereg:
1671 CHANNELENABLEREG subregnum
1672 {
1673 if ($1 > 0)
1674 error(&@1, "Channel enable register number %d"
1675 " out of range\n", $1);
1676
1677 $$.file = ARF;
1678 $$.nr = BRW_ARF_MASK;
1679 $$.subnr = $2;
1680 }
1681 ;
1682
1683 /* Immediate values */
1684 immval:
1685 exp2
1686 {
1687 $$ = $1;
1688 }
1689 | LSQUARE exp2 COMMA exp2 COMMA exp2 COMMA exp2 RSQUARE
1690 {
1691 $$ = ($2 << 0) | ($4 << 8) | ($6 << 16) | ($8 << 24);
1692 }
1693 ;
1694
1695 /* Regions */
1696 dstregion:
1697 /* empty */
1698 {
1699 $$ = BRW_HORIZONTAL_STRIDE_1;
1700 }
1701 | LANGLE exp RANGLE
1702 {
1703 if ($2 != 0 && ($2 > 4 || !isPowerofTwo($2)))
1704 error(&@2, "Invalid Horizontal stride %d\n", $2);
1705
1706 $$ = ffs($2);
1707 }
1708 ;
1709
1710 indirectregion:
1711 region
1712 | region_wh
1713 ;
1714
1715 region:
1716 /* empty */
1717 {
1718 $$ = stride($$, 0, 1, 0);
1719 }
1720 | LANGLE exp RANGLE
1721 {
1722 if ($2 != 0 && ($2 > 32 || !isPowerofTwo($2)))
1723 error(&@2, "Invalid VertStride %d\n", $2);
1724
1725 $$ = stride($$, $2, 1, 0);
1726 }
1727 | LANGLE exp COMMA exp COMMA exp RANGLE
1728 {
1729
1730 if ($2 != 0 && ($2 > 32 || !isPowerofTwo($2)))
1731 error(&@2, "Invalid VertStride %d\n", $2);
1732
1733 if ($4 > 16 || !isPowerofTwo($4))
1734 error(&@4, "Invalid width %d\n", $4);
1735
1736 if ($6 != 0 && ($6 > 4 || !isPowerofTwo($6)))
1737 error(&@6, "Invalid Horizontal stride in"
1738 " region_wh %d\n", $6);
1739
1740 $$ = stride($$, $2, $4, $6);
1741 }
1742 | LANGLE exp SEMICOLON exp COMMA exp RANGLE
1743 {
1744 if ($2 != 0 && ($2 > 32 || !isPowerofTwo($2)))
1745 error(&@2, "Invalid VertStride %d\n", $2);
1746
1747 if ($4 > 16 || !isPowerofTwo($4))
1748 error(&@4, "Invalid width %d\n", $4);
1749
1750 if ($6 != 0 && ($6 > 4 || !isPowerofTwo($6)))
1751 error(&@6, "Invalid Horizontal stride in"
1752 " region_wh %d\n", $6);
1753
1754 $$ = stride($$, $2, $4, $6);
1755 }
1756 | LANGLE VxH COMMA exp COMMA exp RANGLE
1757 {
1758 if ($4 > 16 || !isPowerofTwo($4))
1759 error(&@4, "Invalid width %d\n", $4);
1760
1761 if ($6 != 0 && ($6 > 4 || !isPowerofTwo($6)))
1762 error(&@6, "Invalid Horizontal stride in"
1763 " region_wh %d\n", $6);
1764
1765 $$ = brw_VxH_indirect(0, 0);
1766 }
1767 ;
1768
1769 region_wh:
1770 LANGLE exp COMMA exp RANGLE
1771 {
1772 if ($2 > 16 || !isPowerofTwo($2))
1773 error(&@2, "Invalid width %d\n", $2);
1774
1775 if ($4 != 0 && ($4 > 4 || !isPowerofTwo($4)))
1776 error(&@4, "Invalid Horizontal stride in"
1777 " region_wh %d\n", $4);
1778
1779 $$ = stride($$, 0, $2, $4);
1780 $$.vstride = BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL;
1781 }
1782 ;
1783
1784 reg_type:
1785 TYPE_F { $$ = BRW_TYPE_F; }
1786 | TYPE_UD { $$ = BRW_TYPE_UD; }
1787 | TYPE_D { $$ = BRW_TYPE_D; }
1788 | TYPE_UW { $$ = BRW_TYPE_UW; }
1789 | TYPE_W { $$ = BRW_TYPE_W; }
1790 | TYPE_UB { $$ = BRW_TYPE_UB; }
1791 | TYPE_B { $$ = BRW_TYPE_B; }
1792 | TYPE_DF { $$ = BRW_TYPE_DF; }
1793 | TYPE_UQ { $$ = BRW_TYPE_UQ; }
1794 | TYPE_Q { $$ = BRW_TYPE_Q; }
1795 | TYPE_HF { $$ = BRW_TYPE_HF; }
1796 ;
1797
1798 imm_type:
1799 reg_type { $$ = $1; }
1800 | TYPE_V { $$ = BRW_TYPE_V; }
1801 | TYPE_VF { $$ = BRW_TYPE_VF; }
1802 | TYPE_UV { $$ = BRW_TYPE_UV; }
1803 ;
1804
1805 writemask:
1806 /* empty */
1807 {
1808 $$ = WRITEMASK_XYZW;
1809 }
1810 | DOT writemask_x writemask_y writemask_z writemask_w
1811 {
1812 $$ = $2 | $3 | $4 | $5;
1813 }
1814 ;
1815
1816 writemask_x:
1817 /* empty */ { $$ = 0; }
1818 | X { $$ = 1 << BRW_CHANNEL_X; }
1819 ;
1820
1821 writemask_y:
1822 /* empty */ { $$ = 0; }
1823 | Y { $$ = 1 << BRW_CHANNEL_Y; }
1824 ;
1825
1826 writemask_z:
1827 /* empty */ { $$ = 0; }
1828 | Z { $$ = 1 << BRW_CHANNEL_Z; }
1829 ;
1830
1831 writemask_w:
1832 /* empty */ { $$ = 0; }
1833 | W { $$ = 1 << BRW_CHANNEL_W; }
1834 ;
1835
1836 swizzle:
1837 /* empty */
1838 {
1839 $$ = BRW_SWIZZLE_NOOP;
1840 }
1841 | DOT chansel
1842 {
1843 $$ = BRW_SWIZZLE4($2, $2, $2, $2);
1844 }
1845 | DOT chansel chansel chansel chansel
1846 {
1847 $$ = BRW_SWIZZLE4($2, $3, $4, $5);
1848 }
1849 ;
1850
1851 chansel:
1852 X
1853 | Y
1854 | Z
1855 | W
1856 ;
1857
1858 /* Instruction prediction and modifiers */
1859 predicate:
1860 /* empty */
1861 {
1862 brw_push_insn_state(p);
1863 brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
1864 brw_set_default_flag_reg(p, 0, 0);
1865 brw_set_default_predicate_inverse(p, false);
1866 }
1867 | LPAREN predstate flagreg predctrl RPAREN
1868 {
1869 brw_push_insn_state(p);
1870 brw_set_default_predicate_inverse(p, $2);
1871 brw_set_default_flag_reg(p, $3.nr, $3.subnr);
1872 brw_set_default_predicate_control(p, $4);
1873 }
1874 ;
1875
1876 predstate:
1877 /* empty */ { $$ = 0; }
1878 | PLUS { $$ = 0; }
1879 | MINUS { $$ = 1; }
1880 ;
1881
1882 predctrl:
1883 /* empty */ { $$ = BRW_PREDICATE_NORMAL; }
1884 | DOT X { $$ = BRW_PREDICATE_ALIGN16_REPLICATE_X; }
1885 | DOT Y { $$ = BRW_PREDICATE_ALIGN16_REPLICATE_Y; }
1886 | DOT Z { $$ = BRW_PREDICATE_ALIGN16_REPLICATE_Z; }
1887 | DOT W { $$ = BRW_PREDICATE_ALIGN16_REPLICATE_W; }
1888 | ANYV
1889 | ALLV
1890 | ANY2H
1891 | ALL2H
1892 | ANY4H
1893 | ALL4H
1894 | ANY8H
1895 | ALL8H
1896 | ANY16H
1897 | ALL16H
1898 | ANY32H
1899 | ALL32H
1900 ;
1901
1902 /* Source Modification */
1903 negate:
1904 /* empty */ { $$ = 0; }
1905 | MINUS { $$ = 1; }
1906 ;
1907
1908 abs:
1909 /* empty */ { $$ = 0; }
1910 | ABS { $$ = 1; }
1911 ;
1912
1913 /* Flag (Conditional) Modifier */
1914 cond_mod:
1915 condModifiers
1916 {
1917 $$.cond_modifier = $1;
1918 $$.flag_reg_nr = 0;
1919 $$.flag_subreg_nr = 0;
1920 }
1921 | condModifiers DOT flagreg
1922 {
1923 $$.cond_modifier = $1;
1924 $$.flag_reg_nr = $3.nr;
1925 $$.flag_subreg_nr = $3.subnr;
1926 }
1927 ;
1928
1929 condModifiers:
1930 /* empty */ { $$ = BRW_CONDITIONAL_NONE; }
1931 | ZERO
1932 | EQUAL
1933 | NOT_ZERO
1934 | NOT_EQUAL
1935 | GREATER
1936 | GREATER_EQUAL
1937 | LESS
1938 | LESS_EQUAL
1939 | OVERFLOW
1940 | ROUND_INCREMENT
1941 | UNORDERED
1942 ;
1943
1944 /* message details for send */
1945 msgdesc:
1946 MSGDESC_BEGIN msgdesc_parts MSGDESC_END { $$ = $2; }
1947 ;
1948
1949 msgdesc_parts:
1950 SRC1_LEN ASSIGN INTEGER msgdesc_parts
1951 {
1952 $$ = $4;
1953 $$.src1_len = $3;
1954 }
1955 | EX_BSO msgdesc_parts
1956 {
1957 $$ = $2;
1958 $$.ex_bso = 1;
1959 }
1960 | INTEGER msgdesc_parts { $$ = $2; }
1961 | ASSIGN msgdesc_parts { $$ = $2; }
1962 | /* empty */
1963 {
1964 memset(&$$, 0, sizeof($$));
1965 }
1966 ;
1967
1968 saturate:
1969 /* empty */ { $$ = BRW_INSTRUCTION_NORMAL; }
1970 | SATURATE { $$ = BRW_INSTRUCTION_SATURATE; }
1971 ;
1972
1973 /* Execution size */
1974 execsize:
1975 /* empty */ %prec EMPTYEXECSIZE
1976 {
1977 $$ = 0;
1978 }
1979 | LPAREN exp2 RPAREN
1980 {
1981 if ($2 > 32 || !isPowerofTwo($2))
1982 error(&@2, "Invalid execution size %llu\n", $2);
1983
1984 $$ = cvt($2) - 1;
1985 }
1986 ;
1987
1988 /* Instruction options */
1989 instoptions:
1990 /* empty */
1991 {
1992 memset(&$$, 0, sizeof($$));
1993 }
1994 | LCURLY instoption_list RCURLY
1995 {
1996 memset(&$$, 0, sizeof($$));
1997 $$ = $2;
1998 }
1999 ;
2000
2001 instoption_list:
2002 instoption_list COMMA instoption
2003 {
2004 memset(&$$, 0, sizeof($$));
2005 $$ = $1;
2006 add_instruction_option(&$$, $3);
2007 }
2008 | instoption_list instoption
2009 {
2010 memset(&$$, 0, sizeof($$));
2011 $$ = $1;
2012 add_instruction_option(&$$, $2);
2013 }
2014 | /* empty */
2015 {
2016 memset(&$$, 0, sizeof($$));
2017 }
2018 ;
2019
2020 depinfo:
2021 REG_DIST_CURRENT
2022 {
2023 memset(&$$, 0, sizeof($$));
2024 $$.regdist = $1;
2025 $$.pipe = TGL_PIPE_NONE;
2026 }
2027 | REG_DIST_FLOAT
2028 {
2029 memset(&$$, 0, sizeof($$));
2030 $$.regdist = $1;
2031 $$.pipe = TGL_PIPE_FLOAT;
2032 }
2033 | REG_DIST_INT
2034 {
2035 memset(&$$, 0, sizeof($$));
2036 $$.regdist = $1;
2037 $$.pipe = TGL_PIPE_INT;
2038 }
2039 | REG_DIST_LONG
2040 {
2041 memset(&$$, 0, sizeof($$));
2042 $$.regdist = $1;
2043 $$.pipe = TGL_PIPE_LONG;
2044 }
2045 | REG_DIST_ALL
2046 {
2047 memset(&$$, 0, sizeof($$));
2048 $$.regdist = $1;
2049 $$.pipe = TGL_PIPE_ALL;
2050 }
2051 | SBID_ALLOC
2052 {
2053 memset(&$$, 0, sizeof($$));
2054 $$.sbid = $1;
2055 $$.mode = TGL_SBID_SET;
2056 }
2057 | SBID_WAIT_SRC
2058 {
2059 memset(&$$, 0, sizeof($$));
2060 $$.sbid = $1;
2061 $$.mode = TGL_SBID_SRC;
2062 }
2063 | SBID_WAIT_DST
2064 {
2065 memset(&$$, 0, sizeof($$));
2066 $$.sbid = $1;
2067 $$.mode = TGL_SBID_DST;
2068 }
2069
2070 instoption:
2071 ALIGN1 { $$.type = INSTOPTION_FLAG; $$.uint_value = ALIGN1;}
2072 | ALIGN16 { $$.type = INSTOPTION_FLAG; $$.uint_value = ALIGN16; }
2073 | ACCWREN
2074 {
2075 if (p->devinfo->ver >= 20)
2076 error(&@1, "AccWrEnable not supported in Xe2+\n");
2077 $$.type = INSTOPTION_FLAG;
2078 $$.uint_value = ACCWREN;
2079 }
2080 | BREAKPOINT { $$.type = INSTOPTION_FLAG; $$.uint_value = BREAKPOINT; }
2081 | NODDCLR { $$.type = INSTOPTION_FLAG; $$.uint_value = NODDCLR; }
2082 | NODDCHK { $$.type = INSTOPTION_FLAG; $$.uint_value = NODDCHK; }
2083 | MASK_DISABLE { $$.type = INSTOPTION_FLAG; $$.uint_value = MASK_DISABLE; }
2084 | EOT { $$.type = INSTOPTION_FLAG; $$.uint_value = EOT; }
2085 | SWITCH { $$.type = INSTOPTION_FLAG; $$.uint_value = SWITCH; }
2086 | ATOMIC { $$.type = INSTOPTION_FLAG; $$.uint_value = ATOMIC; }
2087 | CMPTCTRL { $$.type = INSTOPTION_FLAG; $$.uint_value = CMPTCTRL; }
2088 | WECTRL { $$.type = INSTOPTION_FLAG; $$.uint_value = WECTRL; }
2089 | QTR_2Q { $$.type = INSTOPTION_CHAN_OFFSET; $$.uint_value = 8; }
2090 | QTR_3Q { $$.type = INSTOPTION_CHAN_OFFSET; $$.uint_value = 16; }
2091 | QTR_4Q { $$.type = INSTOPTION_CHAN_OFFSET; $$.uint_value = 24; }
2092 | QTR_2H { $$.type = INSTOPTION_CHAN_OFFSET; $$.uint_value = 16; }
2093 | QTR_2N
2094 {
2095 if (p->devinfo->ver >= 20)
2096 error(&@1, "Channel offset must be multiple of 8 in Xe2+\n");
2097 $$.type = INSTOPTION_CHAN_OFFSET;
2098 $$.uint_value = 4;
2099 }
2100 | QTR_3N { $$.type = INSTOPTION_CHAN_OFFSET; $$.uint_value = 8; }
2101 | QTR_4N
2102 {
2103 if (p->devinfo->ver >= 20)
2104 error(&@1, "Channel offset must be multiple of 8 in Xe2+\n");
2105 $$.type = INSTOPTION_CHAN_OFFSET; $$.uint_value = 12;
2106 }
2107 | QTR_5N { $$.type = INSTOPTION_CHAN_OFFSET; $$.uint_value = 16; }
2108 | QTR_6N
2109 {
2110 if (p->devinfo->ver >= 20)
2111 error(&@1, "Channel offset must be multiple of 8 in Xe2+\n");
2112 $$.type = INSTOPTION_CHAN_OFFSET; $$.uint_value = 20;
2113 }
2114 | QTR_7N { $$.type = INSTOPTION_CHAN_OFFSET; $$.uint_value = 24; }
2115 | QTR_8N
2116 {
2117 if (p->devinfo->ver >= 20)
2118 error(&@1, "Channel offset must be multiple of 8 in Xe2+\n");
2119 $$.type = INSTOPTION_CHAN_OFFSET; $$.uint_value = 28;
2120 }
2121 | depinfo { $$.type = INSTOPTION_DEP_INFO; $$.depinfo_value = $1; }
2122 ;
2123
2124 %%
2125
2126 extern int yylineno;
2127
2128 #ifdef YYBYACC
2129 void
yyerror(YYLTYPE * ltype,char * msg)2130 yyerror(YYLTYPE *ltype, char *msg)
2131 #else
2132 void
2133 yyerror(char *msg)
2134 #endif
2135 {
2136 fprintf(stderr, "%s: %d: %s at \"%s\"\n",
2137 input_filename, yylineno, msg, lex_text());
2138 ++errors;
2139 }
2140