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 "elk_asm.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 elk_reg
set_direct_src_operand(struct elk_reg * reg,int type)94 set_direct_src_operand(struct elk_reg *reg, int type)
95 {
96 return elk_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 ELK_SWIZZLE_NOOP,
106 WRITEMASK_XYZW);
107 }
108
109 static void
i965_asm_unary_instruction(int opcode,struct elk_codegen * p,struct elk_reg dest,struct elk_reg src0)110 i965_asm_unary_instruction(int opcode, struct elk_codegen *p,
111 struct elk_reg dest, struct elk_reg src0)
112 {
113 switch (opcode) {
114 case ELK_OPCODE_BFREV:
115 elk_BFREV(p, dest, src0);
116 break;
117 case ELK_OPCODE_CBIT:
118 elk_CBIT(p, dest, src0);
119 break;
120 case ELK_OPCODE_F32TO16:
121 elk_F32TO16(p, dest, src0);
122 break;
123 case ELK_OPCODE_F16TO32:
124 elk_F16TO32(p, dest, src0);
125 break;
126 case ELK_OPCODE_MOV:
127 elk_MOV(p, dest, src0);
128 break;
129 case ELK_OPCODE_FBL:
130 elk_FBL(p, dest, src0);
131 break;
132 case ELK_OPCODE_FRC:
133 elk_FRC(p, dest, src0);
134 break;
135 case ELK_OPCODE_FBH:
136 elk_FBH(p, dest, src0);
137 break;
138 case ELK_OPCODE_NOT:
139 elk_NOT(p, dest, src0);
140 break;
141 case ELK_OPCODE_RNDE:
142 elk_RNDE(p, dest, src0);
143 break;
144 case ELK_OPCODE_RNDZ:
145 elk_RNDZ(p, dest, src0);
146 break;
147 case ELK_OPCODE_RNDD:
148 elk_RNDD(p, dest, src0);
149 break;
150 case ELK_OPCODE_LZD:
151 elk_LZD(p, dest, src0);
152 break;
153 case ELK_OPCODE_DIM:
154 elk_DIM(p, dest, src0);
155 break;
156 case ELK_OPCODE_RNDU:
157 fprintf(stderr, "Opcode ELK_OPCODE_RNDU unhandled\n");
158 break;
159 default:
160 fprintf(stderr, "Unsupported unary opcode\n");
161 }
162 }
163
164 static void
i965_asm_binary_instruction(int opcode,struct elk_codegen * p,struct elk_reg dest,struct elk_reg src0,struct elk_reg src1)165 i965_asm_binary_instruction(int opcode,
166 struct elk_codegen *p,
167 struct elk_reg dest,
168 struct elk_reg src0,
169 struct elk_reg src1)
170 {
171 switch (opcode) {
172 case ELK_OPCODE_ADDC:
173 elk_ADDC(p, dest, src0, src1);
174 break;
175 case ELK_OPCODE_BFI1:
176 elk_BFI1(p, dest, src0, src1);
177 break;
178 case ELK_OPCODE_DP2:
179 elk_DP2(p, dest, src0, src1);
180 break;
181 case ELK_OPCODE_DP3:
182 elk_DP3(p, dest, src0, src1);
183 break;
184 case ELK_OPCODE_DP4:
185 elk_DP4(p, dest, src0, src1);
186 break;
187 case ELK_OPCODE_DPH:
188 elk_DPH(p, dest, src0, src1);
189 break;
190 case ELK_OPCODE_LINE:
191 elk_LINE(p, dest, src0, src1);
192 break;
193 case ELK_OPCODE_MAC:
194 elk_MAC(p, dest, src0, src1);
195 break;
196 case ELK_OPCODE_MACH:
197 elk_MACH(p, dest, src0, src1);
198 break;
199 case ELK_OPCODE_PLN:
200 elk_PLN(p, dest, src0, src1);
201 break;
202 case ELK_OPCODE_ROL:
203 elk_ROL(p, dest, src0, src1);
204 break;
205 case ELK_OPCODE_ROR:
206 elk_ROR(p, dest, src0, src1);
207 break;
208 case ELK_OPCODE_SAD2:
209 fprintf(stderr, "Opcode ELK_OPCODE_SAD2 unhandled\n");
210 break;
211 case ELK_OPCODE_SADA2:
212 fprintf(stderr, "Opcode ELK_OPCODE_SADA2 unhandled\n");
213 break;
214 case ELK_OPCODE_SUBB:
215 elk_SUBB(p, dest, src0, src1);
216 break;
217 case ELK_OPCODE_ADD:
218 elk_ADD(p, dest, src0, src1);
219 break;
220 case ELK_OPCODE_CMP:
221 /* Third parameter is conditional modifier
222 * which gets updated later
223 */
224 elk_CMP(p, dest, 0, src0, src1);
225 break;
226 case ELK_OPCODE_AND:
227 elk_AND(p, dest, src0, src1);
228 break;
229 case ELK_OPCODE_ASR:
230 elk_ASR(p, dest, src0, src1);
231 break;
232 case ELK_OPCODE_AVG:
233 elk_AVG(p, dest, src0, src1);
234 break;
235 case ELK_OPCODE_OR:
236 elk_OR(p, dest, src0, src1);
237 break;
238 case ELK_OPCODE_SEL:
239 elk_SEL(p, dest, src0, src1);
240 break;
241 case ELK_OPCODE_SHL:
242 elk_SHL(p, dest, src0, src1);
243 break;
244 case ELK_OPCODE_SHR:
245 elk_SHR(p, dest, src0, src1);
246 break;
247 case ELK_OPCODE_XOR:
248 elk_XOR(p, dest, src0, src1);
249 break;
250 case ELK_OPCODE_MUL:
251 elk_MUL(p, dest, src0, src1);
252 break;
253 default:
254 fprintf(stderr, "Unsupported binary opcode\n");
255 }
256 }
257
258 static void
i965_asm_ternary_instruction(int opcode,struct elk_codegen * p,struct elk_reg dest,struct elk_reg src0,struct elk_reg src1,struct elk_reg src2)259 i965_asm_ternary_instruction(int opcode,
260 struct elk_codegen *p,
261 struct elk_reg dest,
262 struct elk_reg src0,
263 struct elk_reg src1,
264 struct elk_reg src2)
265 {
266 switch (opcode) {
267 case ELK_OPCODE_MAD:
268 elk_MAD(p, dest, src0, src1, src2);
269 break;
270 case ELK_OPCODE_CSEL:
271 elk_CSEL(p, dest, src0, src1, src2);
272 break;
273 case ELK_OPCODE_LRP:
274 elk_LRP(p, dest, src0, src1, src2);
275 break;
276 case ELK_OPCODE_BFE:
277 elk_BFE(p, dest, src0, src1, src2);
278 break;
279 case ELK_OPCODE_BFI2:
280 elk_BFI2(p, dest, src0, src1, src2);
281 break;
282 case ELK_OPCODE_DP4A:
283 elk_DP4A(p, dest, src0, src1, src2);
284 break;
285 case ELK_OPCODE_ADD3:
286 elk_ADD3(p, dest, src0, src1, src2);
287 break;
288 default:
289 fprintf(stderr, "Unsupported ternary opcode\n");
290 }
291 }
292
293 static void
i965_asm_set_instruction_options(struct elk_codegen * p,struct options options)294 i965_asm_set_instruction_options(struct elk_codegen *p,
295 struct options options)
296 {
297 elk_inst_set_access_mode(p->devinfo, elk_last_inst,
298 options.access_mode);
299 elk_inst_set_mask_control(p->devinfo, elk_last_inst,
300 options.mask_control);
301 if (p->devinfo->ver < 12) {
302 elk_inst_set_thread_control(p->devinfo, elk_last_inst,
303 options.thread_control);
304 elk_inst_set_no_dd_check(p->devinfo, elk_last_inst,
305 options.no_dd_check);
306 elk_inst_set_no_dd_clear(p->devinfo, elk_last_inst,
307 options.no_dd_clear);
308 } else {
309 elk_inst_set_swsb(p->devinfo, elk_last_inst,
310 tgl_swsb_encode(p->devinfo, options.depinfo));
311 }
312 elk_inst_set_debug_control(p->devinfo, elk_last_inst,
313 options.debug_control);
314 if (p->devinfo->ver >= 6)
315 elk_inst_set_acc_wr_control(p->devinfo, elk_last_inst,
316 options.acc_wr_control);
317 elk_inst_set_cmpt_control(p->devinfo, elk_last_inst,
318 options.compaction);
319 }
320
321 static void
i965_asm_set_dst_nr(struct elk_codegen * p,struct elk_reg * reg,struct options options)322 i965_asm_set_dst_nr(struct elk_codegen *p,
323 struct elk_reg *reg,
324 struct options options)
325 {
326 if (p->devinfo->ver <= 6) {
327 if (reg->file == ELK_MESSAGE_REGISTER_FILE &&
328 options.qtr_ctrl == ELK_COMPRESSION_COMPRESSED &&
329 !options.is_compr)
330 reg->nr |= ELK_MRF_COMPR4;
331 }
332 }
333
334 static void
add_label(struct elk_codegen * p,const char * label_name,enum instr_label_type type)335 add_label(struct elk_codegen *p, const char* label_name, enum instr_label_type type)
336 {
337 if (!label_name) {
338 return;
339 }
340
341 struct instr_label *label = rzalloc(p->mem_ctx, struct instr_label);
342
343 label->name = ralloc_strdup(p->mem_ctx, label_name);
344 label->offset = p->next_insn_offset;
345 label->type = type;
346
347 list_addtail(&label->link, &instr_labels);
348 }
349
350 %}
351
352 %locations
353
354 %start ROOT
355
356 %union {
357 char *string;
358 double number;
359 int integer;
360 unsigned long long int llint;
361 struct elk_reg reg;
362 enum elk_reg_type reg_type;
363 struct elk_codegen *program;
364 struct predicate predicate;
365 struct condition condition;
366 struct options options;
367 struct instoption instoption;
368 struct msgdesc msgdesc;
369 struct tgl_swsb depinfo;
370 elk_inst *instruction;
371 }
372
373 %token ABS
374 %token COLON
375 %token COMMA
376 %token DOT
377 %token LANGLE RANGLE
378 %token LCURLY RCURLY
379 %token LPAREN RPAREN
380 %token LSQUARE RSQUARE
381 %token PLUS MINUS
382 %token SEMICOLON
383 %token ASSIGN
384
385 /* datatypes */
386 %token <integer> TYPE_B TYPE_UB
387 %token <integer> TYPE_W TYPE_UW
388 %token <integer> TYPE_D TYPE_UD
389 %token <integer> TYPE_Q TYPE_UQ
390 %token <integer> TYPE_V TYPE_UV
391 %token <integer> TYPE_F TYPE_HF
392 %token <integer> TYPE_DF TYPE_NF
393 %token <integer> TYPE_VF
394
395 /* label */
396 %token <string> JUMP_LABEL
397 %token <string> JUMP_LABEL_TARGET
398
399 /* opcodes */
400 %token <integer> ADD ADD3 ADDC AND ASR AVG
401 %token <integer> BFE BFI1 BFI2 BFB BFREV BRC BRD BREAK
402 %token <integer> CALL CALLA CASE CBIT CMP CMPN CONT CSEL
403 %token <integer> DIM DO DPAS DPASW DP2 DP3 DP4 DP4A DPH
404 %token <integer> ELSE ENDIF F16TO32 F32TO16 FBH FBL FORK FRC
405 %token <integer> GOTO
406 %token <integer> HALT
407 %token <integer> IF IFF ILLEGAL
408 %token <integer> JMPI JOIN
409 %token <integer> LINE LRP LZD
410 %token <integer> MAC MACH MAD MADM MOV MOVI MUL MREST MSAVE
411 %token <integer> NENOP NOP NOT
412 %token <integer> OR
413 %token <integer> PLN POP PUSH
414 %token <integer> RET RNDD RNDE RNDU RNDZ ROL ROR
415 %token <integer> SAD2 SADA2 SEL SENDS SENDSC SHL SHR SMOV SUBB SYNC
416 %token <integer> SEND_GFX4 SENDC_GFX4 SEND_GFX12 SENDC_GFX12
417 %token <integer> WAIT WHILE
418 %token <integer> XOR
419
420 /* extended math functions */
421 %token <integer> COS EXP FDIV INV INVM INTDIV INTDIVMOD INTMOD LOG POW RSQ
422 %token <integer> RSQRTM SIN SINCOS SQRT
423
424 /* sync instruction */
425 %token <integer> ALLRD ALLWR FENCE BAR HOST
426 %type <integer> sync_function
427 %type <reg> sync_arg
428
429 /* shared functions for send */
430 %token CONST CRE DATA DP_DATA_1 GATEWAY MATH PIXEL_INTERP READ RENDER SAMPLER
431 %token THREAD_SPAWNER URB VME WRITE DP_SAMPLER RT_ACCEL SLM TGM UGM
432
433 /* message details for send */
434 %token MSGDESC_BEGIN SRC1_LEN EX_BSO MSGDESC_END
435 %type <msgdesc> msgdesc msgdesc_parts;
436
437 /* Conditional modifiers */
438 %token <integer> EQUAL GREATER GREATER_EQUAL LESS LESS_EQUAL NOT_EQUAL
439 %token <integer> NOT_ZERO OVERFLOW UNORDERED ZERO
440
441 /* register Access Modes */
442 %token ALIGN1 ALIGN16
443
444 /* accumulator write control */
445 %token ACCWREN
446
447 /* compaction control */
448 %token CMPTCTRL
449
450 /* compression control */
451 %token COMPR COMPR4 SECHALF
452
453 /* mask control (WeCtrl) */
454 %token WECTRL
455
456 /* debug control */
457 %token BREAKPOINT
458
459 /* dependency control */
460 %token NODDCLR NODDCHK
461
462 /* end of thread */
463 %token EOT
464
465 /* mask control */
466 %token MASK_DISABLE;
467
468 /* predicate control */
469 %token <integer> ANYV ALLV ANY2H ALL2H ANY4H ALL4H ANY8H ALL8H ANY16H ALL16H
470 %token <integer> ANY32H ALL32H
471
472 /* round instructions */
473 %token <integer> ROUND_INCREMENT
474
475 /* staturation */
476 %token SATURATE
477
478 /* thread control */
479 %token ATOMIC SWITCH
480
481 /* quater control */
482 %token QTR_2Q QTR_3Q QTR_4Q QTR_2H QTR_2N QTR_3N QTR_4N QTR_5N
483 %token QTR_6N QTR_7N QTR_8N
484
485 /* channels */
486 %token <integer> X Y Z W
487
488 /* reg files */
489 %token GENREGFILE MSGREGFILE
490
491 /* vertical stride in register region */
492 %token VxH
493
494 /* register type */
495 %token <integer> GENREG MSGREG ADDRREG ACCREG FLAGREG NOTIFYREG STATEREG
496 %token <integer> CONTROLREG IPREG PERFORMANCEREG THREADREG CHANNELENABLEREG
497 %token <integer> MASKREG
498
499 %token <integer> INTEGER
500 %token <llint> LONG
501 %token NULL_TOKEN
502
503 %nonassoc SUBREGNUM
504 %left PLUS MINUS
505 %nonassoc DOT
506 %nonassoc EMPTYEXECSIZE
507 %nonassoc LPAREN
508
509 %type <integer> execsize simple_int exp
510 %type <llint> exp2
511
512 /* predicate control */
513 %type <integer> predctrl predstate
514 %type <predicate> predicate
515
516 /* conditional modifier */
517 %type <condition> cond_mod
518 %type <integer> condModifiers
519
520 /* instruction options */
521 %type <options> instoptions instoption_list
522 %type <instoption> instoption
523
524 /* writemask */
525 %type <integer> writemask_x writemask_y writemask_z writemask_w
526 %type <integer> writemask
527
528 /* dst operand */
529 %type <reg> dst dstoperand dstoperandex dstoperandex_typed dstreg
530 %type <integer> dstregion
531
532 %type <integer> saturate relativelocation rellocation
533 %type <reg> relativelocation2
534
535 /* src operand */
536 %type <reg> directsrcoperand directsrcaccoperand indirectsrcoperand srcacc
537 %type <reg> srcarcoperandex srcaccimm srcarcoperandex_typed srcimm
538 %type <reg> indirectgenreg indirectregion
539 %type <reg> immreg src reg32 payload directgenreg_list addrparam region
540 %type <reg> region_wh directgenreg directmsgreg indirectmsgreg
541 %type <reg> desc ex_desc reg32a
542 %type <integer> swizzle
543
544 /* registers */
545 %type <reg> accreg addrreg channelenablereg controlreg flagreg ipreg
546 %type <reg> notifyreg nullreg performancereg threadcontrolreg statereg maskreg
547 %type <integer> subregnum
548
549 /* register types */
550 %type <reg_type> reg_type imm_type
551
552 /* immediate values */
553 %type <llint> immval
554
555 /* instruction opcodes */
556 %type <integer> unaryopcodes binaryopcodes binaryaccopcodes ternaryopcodes
557 %type <integer> sendop sendsop
558 %type <instruction> sendopcode sendsopcode
559
560 %type <integer> negate abs chansel math_function sharedfunction
561
562 %type <string> jumplabeltarget
563 %type <string> jumplabel
564
565 /* SWSB */
566 %token <integer> REG_DIST_CURRENT
567 %token <integer> REG_DIST_FLOAT
568 %token <integer> REG_DIST_INT
569 %token <integer> REG_DIST_LONG
570 %token <integer> REG_DIST_ALL
571 %token <integer> SBID_ALLOC
572 %token <integer> SBID_WAIT_SRC
573 %token <integer> SBID_WAIT_DST
574
575 %type <depinfo> depinfo
576
577 %code {
578
579 static void
add_instruction_option(struct options * options,struct instoption opt)580 add_instruction_option(struct options *options, struct instoption opt)
581 {
582 if (opt.type == INSTOPTION_DEP_INFO) {
583 if (opt.depinfo_value.regdist) {
584 options->depinfo.regdist = opt.depinfo_value.regdist;
585 options->depinfo.pipe = opt.depinfo_value.pipe;
586 } else {
587 options->depinfo.sbid = opt.depinfo_value.sbid;
588 options->depinfo.mode = opt.depinfo_value.mode;
589 }
590 return;
591 }
592 switch (opt.uint_value) {
593 case ALIGN1:
594 options->access_mode = ELK_ALIGN_1;
595 break;
596 case ALIGN16:
597 options->access_mode = ELK_ALIGN_16;
598 break;
599 case SECHALF:
600 options->qtr_ctrl |= ELK_COMPRESSION_2NDHALF;
601 break;
602 case COMPR:
603 options->qtr_ctrl |= ELK_COMPRESSION_COMPRESSED;
604 options->is_compr = true;
605 break;
606 case COMPR4:
607 options->qtr_ctrl |= ELK_COMPRESSION_COMPRESSED;
608 break;
609 case SWITCH:
610 options->thread_control |= ELK_THREAD_SWITCH;
611 break;
612 case ATOMIC:
613 options->thread_control |= ELK_THREAD_ATOMIC;
614 break;
615 case NODDCHK:
616 options->no_dd_check = true;
617 break;
618 case NODDCLR:
619 options->no_dd_clear = ELK_DEPENDENCY_NOTCLEARED;
620 break;
621 case MASK_DISABLE:
622 options->mask_control |= ELK_MASK_DISABLE;
623 break;
624 case BREAKPOINT:
625 options->debug_control = ELK_DEBUG_BREAKPOINT;
626 break;
627 case WECTRL:
628 options->mask_control |= ELK_WE_ALL;
629 break;
630 case CMPTCTRL:
631 options->compaction = true;
632 break;
633 case ACCWREN:
634 options->acc_wr_control = true;
635 break;
636 case EOT:
637 options->end_of_thread = true;
638 break;
639 /* TODO : Figure out how to set instruction group and get rid of
640 * code below
641 */
642 case QTR_2Q:
643 options->qtr_ctrl = ELK_COMPRESSION_2NDHALF;
644 break;
645 case QTR_3Q:
646 options->qtr_ctrl = ELK_COMPRESSION_COMPRESSED;
647 break;
648 case QTR_4Q:
649 options->qtr_ctrl = 3;
650 break;
651 case QTR_2H:
652 options->qtr_ctrl = ELK_COMPRESSION_COMPRESSED;
653 break;
654 case QTR_2N:
655 options->qtr_ctrl = ELK_COMPRESSION_NONE;
656 options->nib_ctrl = true;
657 break;
658 case QTR_3N:
659 options->qtr_ctrl = ELK_COMPRESSION_2NDHALF;
660 break;
661 case QTR_4N:
662 options->qtr_ctrl = ELK_COMPRESSION_2NDHALF;
663 options->nib_ctrl = true;
664 break;
665 case QTR_5N:
666 options->qtr_ctrl = ELK_COMPRESSION_COMPRESSED;
667 break;
668 case QTR_6N:
669 options->qtr_ctrl = ELK_COMPRESSION_COMPRESSED;
670 options->nib_ctrl = true;
671 break;
672 case QTR_7N:
673 options->qtr_ctrl = 3;
674 break;
675 case QTR_8N:
676 options->qtr_ctrl = 3;
677 options->nib_ctrl = true;
678 break;
679 }
680 }
681 }
682 %%
683
684 ROOT:
685 instrseq
686 ;
687
688 instrseq:
689 instrseq instruction SEMICOLON
690 | instrseq relocatableinstruction SEMICOLON
691 | instruction SEMICOLON
692 | relocatableinstruction SEMICOLON
693 | instrseq jumplabeltarget
694 | jumplabeltarget
695 ;
696
697 /* Instruction Group */
698 instruction:
699 unaryinstruction
700 | binaryinstruction
701 | binaryaccinstruction
702 | mathinstruction
703 | nopinstruction
704 | waitinstruction
705 | ternaryinstruction
706 | sendinstruction
707 | illegalinstruction
708 | syncinstruction
709 ;
710
711 relocatableinstruction:
712 jumpinstruction
713 | branchinstruction
714 | breakinstruction
715 | loopinstruction
716 ;
717
718 illegalinstruction:
719 ILLEGAL execsize instoptions
720 {
721 elk_next_insn(p, $1);
722 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $2);
723 i965_asm_set_instruction_options(p, $3);
724 }
725 ;
726
727 /* Unary instruction */
728 unaryinstruction:
729 predicate unaryopcodes saturate cond_mod execsize dst srcaccimm instoptions
730 {
731 i965_asm_set_dst_nr(p, &$6, $8);
732 elk_set_default_access_mode(p, $8.access_mode);
733 i965_asm_unary_instruction($2, p, $6, $7);
734 elk_pop_insn_state(p);
735 i965_asm_set_instruction_options(p, $8);
736 elk_inst_set_cond_modifier(p->devinfo, elk_last_inst,
737 $4.cond_modifier);
738
739 if (p->devinfo->ver >= 7 && $2 != ELK_OPCODE_DIM &&
740 !elk_inst_flag_reg_nr(p->devinfo, elk_last_inst)) {
741 elk_inst_set_flag_reg_nr(p->devinfo,
742 elk_last_inst,
743 $4.flag_reg_nr);
744 elk_inst_set_flag_subreg_nr(p->devinfo,
745 elk_last_inst,
746 $4.flag_subreg_nr);
747 }
748
749 if ($7.file != ELK_IMMEDIATE_VALUE) {
750 elk_inst_set_src0_vstride(p->devinfo, elk_last_inst,
751 $7.vstride);
752 }
753 elk_inst_set_saturate(p->devinfo, elk_last_inst, $3);
754 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $5);
755 // TODO: set instruction group instead of qtr and nib ctrl
756 elk_inst_set_qtr_control(p->devinfo, elk_last_inst,
757 $8.qtr_ctrl);
758
759 if (p->devinfo->ver >= 7)
760 elk_inst_set_nib_control(p->devinfo, elk_last_inst,
761 $8.nib_ctrl);
762 }
763 ;
764
765 unaryopcodes:
766 BFREV
767 | CBIT
768 | DIM
769 | F16TO32
770 | F32TO16
771 | FBH
772 | FBL
773 | FRC
774 | LZD
775 | MOV
776 | NOT
777 | RNDD
778 | RNDE
779 | RNDU
780 | RNDZ
781 ;
782
783 /* Binary instruction */
784 binaryinstruction:
785 predicate binaryopcodes saturate cond_mod execsize dst srcimm srcimm instoptions
786 {
787 i965_asm_set_dst_nr(p, &$6, $9);
788 elk_set_default_access_mode(p, $9.access_mode);
789 i965_asm_binary_instruction($2, p, $6, $7, $8);
790 i965_asm_set_instruction_options(p, $9);
791 elk_inst_set_cond_modifier(p->devinfo, elk_last_inst,
792 $4.cond_modifier);
793
794 if (p->devinfo->ver >= 7 &&
795 !elk_inst_flag_reg_nr(p->devinfo, elk_last_inst)) {
796 elk_inst_set_flag_reg_nr(p->devinfo, elk_last_inst,
797 $4.flag_reg_nr);
798 elk_inst_set_flag_subreg_nr(p->devinfo, elk_last_inst,
799 $4.flag_subreg_nr);
800 }
801
802 elk_inst_set_saturate(p->devinfo, elk_last_inst, $3);
803 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $5);
804 // TODO: set instruction group instead of qtr and nib ctrl
805 elk_inst_set_qtr_control(p->devinfo, elk_last_inst,
806 $9.qtr_ctrl);
807
808 if (p->devinfo->ver >= 7)
809 elk_inst_set_nib_control(p->devinfo, elk_last_inst,
810 $9.nib_ctrl);
811
812 elk_pop_insn_state(p);
813 }
814 ;
815
816 binaryopcodes:
817 ADDC
818 | BFI1
819 | DP2
820 | DP3
821 | DP4
822 | DPH
823 | LINE
824 | MAC
825 | MACH
826 | MUL
827 | PLN
828 | ROL
829 | ROR
830 | SAD2
831 | SADA2
832 | SUBB
833 ;
834
835 /* Binary acc instruction */
836 binaryaccinstruction:
837 predicate binaryaccopcodes saturate cond_mod execsize dst srcacc srcimm instoptions
838 {
839 i965_asm_set_dst_nr(p, &$6, $9);
840 elk_set_default_access_mode(p, $9.access_mode);
841 i965_asm_binary_instruction($2, p, $6, $7, $8);
842 elk_pop_insn_state(p);
843 i965_asm_set_instruction_options(p, $9);
844 elk_inst_set_cond_modifier(p->devinfo, elk_last_inst,
845 $4.cond_modifier);
846
847 if (p->devinfo->ver >= 7 &&
848 !elk_inst_flag_reg_nr(p->devinfo, elk_last_inst)) {
849 elk_inst_set_flag_reg_nr(p->devinfo,
850 elk_last_inst,
851 $4.flag_reg_nr);
852 elk_inst_set_flag_subreg_nr(p->devinfo,
853 elk_last_inst,
854 $4.flag_subreg_nr);
855 }
856
857 elk_inst_set_saturate(p->devinfo, elk_last_inst, $3);
858 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $5);
859 // TODO: set instruction group instead of qtr and nib ctrl
860 elk_inst_set_qtr_control(p->devinfo, elk_last_inst,
861 $9.qtr_ctrl);
862
863 if (p->devinfo->ver >= 7)
864 elk_inst_set_nib_control(p->devinfo, elk_last_inst,
865 $9.nib_ctrl);
866 }
867 ;
868
869 binaryaccopcodes:
870 ADD
871 | AND
872 | ASR
873 | AVG
874 | CMP
875 | CMPN
876 | OR
877 | SEL
878 | SHL
879 | SHR
880 | XOR
881 ;
882
883 /* Math instruction */
884 mathinstruction:
885 predicate MATH saturate math_function execsize dst src srcimm instoptions
886 {
887 elk_set_default_access_mode(p, $9.access_mode);
888 elk_gfx6_math(p, $6, $4, $7, $8);
889 i965_asm_set_instruction_options(p, $9);
890 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $5);
891 elk_inst_set_saturate(p->devinfo, elk_last_inst, $3);
892 // TODO: set instruction group instead
893 elk_inst_set_qtr_control(p->devinfo, elk_last_inst,
894 $9.qtr_ctrl);
895
896 if (p->devinfo->ver >= 7)
897 elk_inst_set_nib_control(p->devinfo, elk_last_inst,
898 $9.nib_ctrl);
899
900 elk_pop_insn_state(p);
901 }
902 ;
903
904 math_function:
905 COS
906 | EXP
907 | FDIV
908 | INV
909 | INVM
910 | INTDIV
911 | INTDIVMOD
912 | INTMOD
913 | LOG
914 | POW
915 | RSQ
916 | RSQRTM
917 | SIN
918 | SQRT
919 | SINCOS
920 ;
921
922 /* NOP instruction */
923 nopinstruction:
924 NOP
925 {
926 elk_NOP(p);
927 }
928 ;
929
930 /* Ternary operand instruction */
931 ternaryinstruction:
932 predicate ternaryopcodes saturate cond_mod execsize dst srcimm src srcimm instoptions
933 {
934 elk_set_default_access_mode(p, $10.access_mode);
935 i965_asm_ternary_instruction($2, p, $6, $7, $8, $9);
936 elk_pop_insn_state(p);
937 i965_asm_set_instruction_options(p, $10);
938 elk_inst_set_cond_modifier(p->devinfo, elk_last_inst,
939 $4.cond_modifier);
940
941 if (p->devinfo->ver >= 7 && p->devinfo->ver < 12) {
942 elk_inst_set_3src_a16_flag_reg_nr(p->devinfo, elk_last_inst,
943 $4.flag_reg_nr);
944 elk_inst_set_3src_a16_flag_subreg_nr(p->devinfo, elk_last_inst,
945 $4.flag_subreg_nr);
946 }
947
948 elk_inst_set_saturate(p->devinfo, elk_last_inst, $3);
949 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $5);
950 // TODO: set instruction group instead of qtr and nib ctrl
951 elk_inst_set_qtr_control(p->devinfo, elk_last_inst,
952 $10.qtr_ctrl);
953
954 if (p->devinfo->ver >= 7)
955 elk_inst_set_nib_control(p->devinfo, elk_last_inst,
956 $10.nib_ctrl);
957 }
958 ;
959
960 ternaryopcodes:
961 CSEL
962 | BFE
963 | BFI2
964 | LRP
965 | MAD
966 | DP4A
967 | ADD3
968 ;
969
970 /* Wait instruction */
971 waitinstruction:
972 WAIT execsize dst instoptions
973 {
974 elk_next_insn(p, $1);
975 i965_asm_set_instruction_options(p, $4);
976 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $2);
977 elk_set_default_access_mode(p, $4.access_mode);
978 struct elk_reg dest = $3;
979 dest.swizzle = elk_swizzle_for_mask(dest.writemask);
980 if (dest.file != ARF || dest.nr != ELK_ARF_NOTIFICATION_COUNT)
981 error(&@1, "WAIT must use the notification register\n");
982 elk_set_dest(p, elk_last_inst, dest);
983 elk_set_src0(p, elk_last_inst, dest);
984 elk_set_src1(p, elk_last_inst, elk_null_reg());
985 elk_inst_set_mask_control(p->devinfo, elk_last_inst, ELK_MASK_DISABLE);
986 }
987 ;
988
989 /* Send instruction */
990 sendinstruction:
991 predicate sendopcode execsize dst payload exp2 sharedfunction msgdesc instoptions
992 {
993 i965_asm_set_instruction_options(p, $9);
994 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $3);
995 elk_set_dest(p, elk_last_inst, $4);
996 elk_set_src0(p, elk_last_inst, $5);
997 elk_inst_set_bits(elk_last_inst, 127, 96, $6);
998 elk_inst_set_src1_file_type(p->devinfo, elk_last_inst,
999 ELK_IMMEDIATE_VALUE,
1000 ELK_REGISTER_TYPE_UD);
1001 elk_inst_set_sfid(p->devinfo, elk_last_inst, $7);
1002 elk_inst_set_eot(p->devinfo, elk_last_inst, $9.end_of_thread);
1003 // TODO: set instruction group instead of qtr and nib ctrl
1004 elk_inst_set_qtr_control(p->devinfo, elk_last_inst,
1005 $9.qtr_ctrl);
1006
1007 if (p->devinfo->ver >= 7)
1008 elk_inst_set_nib_control(p->devinfo, elk_last_inst,
1009 $9.nib_ctrl);
1010
1011 elk_pop_insn_state(p);
1012 }
1013 | predicate sendopcode execsize exp dst payload exp2 sharedfunction msgdesc instoptions
1014 {
1015 assert(p->devinfo->ver < 6);
1016
1017 i965_asm_set_instruction_options(p, $10);
1018 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $3);
1019 elk_inst_set_base_mrf(p->devinfo, elk_last_inst, $4);
1020 elk_set_dest(p, elk_last_inst, $5);
1021 elk_set_src0(p, elk_last_inst, $6);
1022 elk_inst_set_bits(elk_last_inst, 127, 96, $7);
1023 elk_inst_set_src1_file_type(p->devinfo, elk_last_inst,
1024 ELK_IMMEDIATE_VALUE,
1025 ELK_REGISTER_TYPE_UD);
1026 elk_inst_set_sfid(p->devinfo, elk_last_inst, $8);
1027 elk_inst_set_eot(p->devinfo, elk_last_inst, $10.end_of_thread);
1028 // TODO: set instruction group instead of qtr and nib ctrl
1029 elk_inst_set_qtr_control(p->devinfo, elk_last_inst,
1030 $10.qtr_ctrl);
1031
1032 elk_pop_insn_state(p);
1033 }
1034 | predicate sendopcode execsize dst payload payload exp2 sharedfunction msgdesc instoptions
1035 {
1036 assert(p->devinfo->ver >= 6 && p->devinfo->ver < 12);
1037
1038 i965_asm_set_instruction_options(p, $10);
1039 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $3);
1040 elk_set_dest(p, elk_last_inst, $4);
1041 elk_set_src0(p, elk_last_inst, $5);
1042 elk_inst_set_bits(elk_last_inst, 127, 96, $7);
1043 elk_inst_set_sfid(p->devinfo, elk_last_inst, $8);
1044 elk_inst_set_eot(p->devinfo, elk_last_inst, $10.end_of_thread);
1045 // TODO: set instruction group instead of qtr and nib ctrl
1046 elk_inst_set_qtr_control(p->devinfo, elk_last_inst,
1047 $10.qtr_ctrl);
1048
1049 if (p->devinfo->ver >= 7)
1050 elk_inst_set_nib_control(p->devinfo, elk_last_inst,
1051 $10.nib_ctrl);
1052
1053 elk_pop_insn_state(p);
1054 }
1055 | predicate sendsopcode execsize dst payload payload desc ex_desc sharedfunction msgdesc instoptions
1056 {
1057 assert(p->devinfo->ver >= 9);
1058
1059 i965_asm_set_instruction_options(p, $11);
1060 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $3);
1061 elk_set_dest(p, elk_last_inst, $4);
1062 elk_set_src0(p, elk_last_inst, $5);
1063 elk_set_src1(p, elk_last_inst, $6);
1064
1065 if ($7.file == ELK_IMMEDIATE_VALUE) {
1066 elk_inst_set_send_sel_reg32_desc(p->devinfo, elk_last_inst, 0);
1067 elk_inst_set_send_desc(p->devinfo, elk_last_inst, $7.ud);
1068 } else {
1069 elk_inst_set_send_sel_reg32_desc(p->devinfo, elk_last_inst, 1);
1070 }
1071
1072 if ($8.file == ELK_IMMEDIATE_VALUE) {
1073 elk_inst_set_send_sel_reg32_ex_desc(p->devinfo, elk_last_inst, 0);
1074 elk_inst_set_sends_ex_desc(p->devinfo, elk_last_inst, $8.ud);
1075 } else {
1076 elk_inst_set_send_sel_reg32_ex_desc(p->devinfo, elk_last_inst, 1);
1077 elk_inst_set_send_ex_desc_ia_subreg_nr(p->devinfo, elk_last_inst, $8.subnr >> 2);
1078 }
1079
1080 elk_inst_set_sfid(p->devinfo, elk_last_inst, $9);
1081 elk_inst_set_eot(p->devinfo, elk_last_inst, $11.end_of_thread);
1082 // TODO: set instruction group instead of qtr and nib ctrl
1083 elk_inst_set_qtr_control(p->devinfo, elk_last_inst,
1084 $11.qtr_ctrl);
1085
1086 elk_inst_set_nib_control(p->devinfo, elk_last_inst,
1087 $11.nib_ctrl);
1088
1089 if (p->devinfo->verx10 >= 125 && $10.ex_bso) {
1090 elk_inst_set_send_ex_bso(p->devinfo, elk_last_inst, 1);
1091 elk_inst_set_send_src1_len(p->devinfo, elk_last_inst,
1092 $10.src1_len);
1093 }
1094
1095 elk_pop_insn_state(p);
1096 }
1097 ;
1098
1099 sendop:
1100 SEND_GFX4
1101 | SENDC_GFX4
1102 ;
1103
1104 sendsop:
1105 SEND_GFX12
1106 | SENDC_GFX12
1107 | SENDS
1108 | SENDSC
1109 ;
1110
1111 sendopcode:
1112 sendop { $$ = elk_next_insn(p, $1); }
1113 ;
1114
1115 sendsopcode:
1116 sendsop { $$ = elk_next_insn(p, $1); }
1117 ;
1118
1119 sharedfunction:
1120 NULL_TOKEN { $$ = ELK_SFID_NULL; }
1121 | MATH { $$ = ELK_SFID_MATH; }
1122 | GATEWAY { $$ = ELK_SFID_MESSAGE_GATEWAY; }
1123 | READ { $$ = ELK_SFID_DATAPORT_READ; }
1124 | WRITE { $$ = ELK_SFID_DATAPORT_WRITE; }
1125 | URB { $$ = ELK_SFID_URB; }
1126 | THREAD_SPAWNER { $$ = ELK_SFID_THREAD_SPAWNER; }
1127 | VME { $$ = ELK_SFID_VME; }
1128 | RENDER { $$ = GFX6_SFID_DATAPORT_RENDER_CACHE; }
1129 | CONST { $$ = GFX6_SFID_DATAPORT_CONSTANT_CACHE; }
1130 | DATA { $$ = GFX7_SFID_DATAPORT_DATA_CACHE; }
1131 | PIXEL_INTERP { $$ = GFX7_SFID_PIXEL_INTERPOLATOR; }
1132 | DP_DATA_1 { $$ = HSW_SFID_DATAPORT_DATA_CACHE_1; }
1133 | CRE { $$ = HSW_SFID_CRE; }
1134 | SAMPLER { $$ = ELK_SFID_SAMPLER; }
1135 | DP_SAMPLER { $$ = GFX6_SFID_DATAPORT_SAMPLER_CACHE; }
1136 | SLM { $$ = GFX12_SFID_SLM; }
1137 | TGM { $$ = GFX12_SFID_TGM; }
1138 | UGM { $$ = GFX12_SFID_UGM; }
1139 ;
1140
1141 exp2:
1142 LONG { $$ = $1; }
1143 | MINUS LONG { $$ = -$2; }
1144 ;
1145
1146 desc:
1147 reg32a
1148 | exp2
1149 {
1150 $$ = elk_imm_ud($1);
1151 }
1152 ;
1153
1154 ex_desc:
1155 reg32a
1156 | exp2
1157 {
1158 $$ = elk_imm_ud($1);
1159 }
1160 ;
1161
1162 reg32a:
1163 addrreg region reg_type
1164 {
1165 $$ = set_direct_src_operand(&$1, $3);
1166 $$ = stride($$, $2.vstride, $2.width, $2.hstride);
1167 }
1168 ;
1169
1170
1171 /* Jump instruction */
1172 jumpinstruction:
1173 predicate JMPI execsize relativelocation2 instoptions
1174 {
1175 elk_next_insn(p, $2);
1176 i965_asm_set_instruction_options(p, $5);
1177 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $3);
1178 elk_set_dest(p, elk_last_inst, elk_ip_reg());
1179 elk_set_src0(p, elk_last_inst, elk_ip_reg());
1180 elk_set_src1(p, elk_last_inst, $4);
1181 elk_inst_set_pred_control(p->devinfo, elk_last_inst,
1182 elk_inst_pred_control(p->devinfo,
1183 elk_last_inst));
1184 elk_pop_insn_state(p);
1185 }
1186 ;
1187
1188 /* branch instruction */
1189 branchinstruction:
1190 predicate ENDIF execsize JUMP_LABEL instoptions
1191 {
1192 add_label(p, $4, INSTR_LABEL_JIP);
1193
1194 elk_next_insn(p, $2);
1195 i965_asm_set_instruction_options(p, $5);
1196 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $3);
1197
1198 if (p->devinfo->ver == 6) {
1199 elk_set_dest(p, elk_last_inst, elk_imm_w(0x0));
1200 elk_set_src0(p, elk_last_inst, retype(elk_null_reg(),
1201 ELK_REGISTER_TYPE_D));
1202 elk_set_src1(p, elk_last_inst, retype(elk_null_reg(),
1203 ELK_REGISTER_TYPE_D));
1204 } else if (p->devinfo->ver == 7) {
1205 elk_set_dest(p, elk_last_inst, retype(elk_null_reg(),
1206 ELK_REGISTER_TYPE_D));
1207 elk_set_src0(p, elk_last_inst, retype(elk_null_reg(),
1208 ELK_REGISTER_TYPE_D));
1209 elk_set_src1(p, elk_last_inst, elk_imm_w(0x0));
1210 } else {
1211 elk_set_src0(p, elk_last_inst, elk_imm_d(0x0));
1212 }
1213
1214 elk_pop_insn_state(p);
1215 }
1216 | predicate ENDIF execsize relativelocation instoptions
1217 {
1218 elk_next_insn(p, $2);
1219 i965_asm_set_instruction_options(p, $5);
1220 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $3);
1221
1222 elk_set_dest(p, elk_last_inst, retype(elk_null_reg(),
1223 ELK_REGISTER_TYPE_D));
1224 elk_set_src0(p, elk_last_inst, retype(elk_null_reg(),
1225 ELK_REGISTER_TYPE_D));
1226 elk_set_src1(p, elk_last_inst, elk_imm_d(0x0));
1227 elk_inst_set_gfx4_pop_count(p->devinfo, elk_last_inst, $4);
1228
1229 elk_inst_set_thread_control(p->devinfo, elk_last_inst,
1230 ELK_THREAD_SWITCH);
1231
1232 elk_pop_insn_state(p);
1233 }
1234 | ELSE execsize JUMP_LABEL jumplabel instoptions
1235 {
1236 add_label(p, $3, INSTR_LABEL_JIP);
1237 add_label(p, $4, INSTR_LABEL_UIP);
1238
1239 elk_next_insn(p, $1);
1240 i965_asm_set_instruction_options(p, $5);
1241 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $2);
1242
1243 if (p->devinfo->ver == 6) {
1244 elk_set_dest(p, elk_last_inst, elk_imm_w(0x0));
1245 elk_set_src0(p, elk_last_inst, retype(elk_null_reg(),
1246 ELK_REGISTER_TYPE_D));
1247 elk_set_src1(p, elk_last_inst, retype(elk_null_reg(),
1248 ELK_REGISTER_TYPE_D));
1249 } else if (p->devinfo->ver == 7) {
1250 elk_set_dest(p, elk_last_inst, retype(elk_null_reg(),
1251 ELK_REGISTER_TYPE_D));
1252 elk_set_src0(p, elk_last_inst, retype(elk_null_reg(),
1253 ELK_REGISTER_TYPE_D));
1254 elk_set_src1(p, elk_last_inst, elk_imm_w(0));
1255 } else {
1256 elk_set_dest(p, elk_last_inst, retype(elk_null_reg(),
1257 ELK_REGISTER_TYPE_D));
1258 if (p->devinfo->ver < 12)
1259 elk_set_src0(p, elk_last_inst, elk_imm_d(0));
1260 }
1261 }
1262 | ELSE execsize relativelocation rellocation instoptions
1263 {
1264 elk_next_insn(p, $1);
1265 i965_asm_set_instruction_options(p, $5);
1266 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $2);
1267
1268 elk_set_dest(p, elk_last_inst, elk_ip_reg());
1269 elk_set_src0(p, elk_last_inst, elk_ip_reg());
1270 elk_set_src1(p, elk_last_inst, elk_imm_d(0x0));
1271 elk_inst_set_gfx4_jump_count(p->devinfo, elk_last_inst, $3);
1272 elk_inst_set_gfx4_pop_count(p->devinfo, elk_last_inst, $4);
1273
1274 if (!p->single_program_flow)
1275 elk_inst_set_thread_control(p->devinfo, elk_last_inst,
1276 ELK_THREAD_SWITCH);
1277 }
1278 | predicate IF execsize JUMP_LABEL jumplabel instoptions
1279 {
1280 add_label(p, $4, INSTR_LABEL_JIP);
1281 add_label(p, $5, INSTR_LABEL_UIP);
1282
1283 elk_next_insn(p, $2);
1284 i965_asm_set_instruction_options(p, $6);
1285 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $3);
1286
1287 if (p->devinfo->ver == 6) {
1288 elk_set_dest(p, elk_last_inst, elk_imm_w(0x0));
1289 elk_set_src0(p, elk_last_inst,
1290 vec1(retype(elk_null_reg(),
1291 ELK_REGISTER_TYPE_D)));
1292 elk_set_src1(p, elk_last_inst,
1293 vec1(retype(elk_null_reg(),
1294 ELK_REGISTER_TYPE_D)));
1295 } else if (p->devinfo->ver == 7) {
1296 elk_set_dest(p, elk_last_inst,
1297 vec1(retype(elk_null_reg(),
1298 ELK_REGISTER_TYPE_D)));
1299 elk_set_src0(p, elk_last_inst,
1300 vec1(retype(elk_null_reg(),
1301 ELK_REGISTER_TYPE_D)));
1302 elk_set_src1(p, elk_last_inst, elk_imm_w(0x0));
1303 } else {
1304 elk_set_dest(p, elk_last_inst,
1305 vec1(retype(elk_null_reg(),
1306 ELK_REGISTER_TYPE_D)));
1307 if (p->devinfo->ver < 12)
1308 elk_set_src0(p, elk_last_inst, elk_imm_d(0x0));
1309 }
1310
1311 elk_pop_insn_state(p);
1312 }
1313 | predicate IF execsize relativelocation rellocation instoptions
1314 {
1315 elk_next_insn(p, $2);
1316 i965_asm_set_instruction_options(p, $6);
1317 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $3);
1318
1319 elk_set_dest(p, elk_last_inst, elk_ip_reg());
1320 elk_set_src0(p, elk_last_inst, elk_ip_reg());
1321 elk_set_src1(p, elk_last_inst, elk_imm_d(0x0));
1322 elk_inst_set_gfx4_jump_count(p->devinfo, elk_last_inst, $4);
1323 elk_inst_set_gfx4_pop_count(p->devinfo, elk_last_inst, $5);
1324
1325 if (!p->single_program_flow)
1326 elk_inst_set_thread_control(p->devinfo, elk_last_inst,
1327 ELK_THREAD_SWITCH);
1328
1329 elk_pop_insn_state(p);
1330 }
1331 | predicate IFF execsize JUMP_LABEL instoptions
1332 {
1333 add_label(p, $4, INSTR_LABEL_JIP);
1334
1335 elk_next_insn(p, $2);
1336 i965_asm_set_instruction_options(p, $5);
1337 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $3);
1338
1339 if (p->devinfo->ver == 6) {
1340 elk_set_src0(p, elk_last_inst,
1341 vec1(retype(elk_null_reg(),
1342 ELK_REGISTER_TYPE_D)));
1343 elk_set_src1(p, elk_last_inst,
1344 vec1(retype(elk_null_reg(),
1345 ELK_REGISTER_TYPE_D)));
1346 } else if (p->devinfo->ver == 7) {
1347 elk_set_dest(p, elk_last_inst,
1348 vec1(retype(elk_null_reg(),
1349 ELK_REGISTER_TYPE_D)));
1350 elk_set_src0(p, elk_last_inst,
1351 vec1(retype(elk_null_reg(),
1352 ELK_REGISTER_TYPE_D)));
1353 elk_set_src1(p, elk_last_inst, elk_imm_w(0x0));
1354 } else {
1355 elk_set_dest(p, elk_last_inst,
1356 vec1(retype(elk_null_reg(),
1357 ELK_REGISTER_TYPE_D)));
1358 if (p->devinfo->ver < 12)
1359 elk_set_src0(p, elk_last_inst, elk_imm_d(0x0));
1360 }
1361
1362 elk_pop_insn_state(p);
1363 }
1364 | predicate IFF execsize relativelocation instoptions
1365 {
1366 elk_next_insn(p, $2);
1367 i965_asm_set_instruction_options(p, $5);
1368 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $3);
1369
1370 elk_set_dest(p, elk_last_inst, elk_ip_reg());
1371 elk_set_src0(p, elk_last_inst, elk_ip_reg());
1372 elk_inst_set_gfx4_jump_count(p->devinfo, elk_last_inst, $4);
1373 elk_set_src1(p, elk_last_inst, elk_imm_d($4));
1374
1375 if (!p->single_program_flow)
1376 elk_inst_set_thread_control(p->devinfo, elk_last_inst,
1377 ELK_THREAD_SWITCH);
1378
1379 elk_pop_insn_state(p);
1380 }
1381 ;
1382
1383 /* break instruction */
1384 breakinstruction:
1385 predicate BREAK execsize JUMP_LABEL JUMP_LABEL instoptions
1386 {
1387 add_label(p, $4, INSTR_LABEL_JIP);
1388 add_label(p, $5, INSTR_LABEL_UIP);
1389
1390 elk_next_insn(p, $2);
1391 i965_asm_set_instruction_options(p, $6);
1392 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $3);
1393
1394 if (p->devinfo->ver >= 8) {
1395 elk_set_dest(p, elk_last_inst, retype(elk_null_reg(),
1396 ELK_REGISTER_TYPE_D));
1397 elk_set_src0(p, elk_last_inst, elk_imm_d(0x0));
1398 } else {
1399 elk_set_dest(p, elk_last_inst, retype(elk_null_reg(),
1400 ELK_REGISTER_TYPE_D));
1401 elk_set_src0(p, elk_last_inst, retype(elk_null_reg(),
1402 ELK_REGISTER_TYPE_D));
1403 elk_set_src1(p, elk_last_inst, elk_imm_d(0x0));
1404 }
1405
1406 elk_pop_insn_state(p);
1407 }
1408 | predicate BREAK execsize relativelocation relativelocation instoptions
1409 {
1410 elk_next_insn(p, $2);
1411 i965_asm_set_instruction_options(p, $6);
1412 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $3);
1413
1414 elk_set_dest(p, elk_last_inst, elk_ip_reg());
1415 elk_set_src0(p, elk_last_inst, elk_ip_reg());
1416 elk_set_src1(p, elk_last_inst, elk_imm_d(0x0));
1417 elk_inst_set_gfx4_jump_count(p->devinfo, elk_last_inst, $4);
1418 elk_inst_set_gfx4_pop_count(p->devinfo, elk_last_inst, $5);
1419
1420 elk_pop_insn_state(p);
1421 }
1422 | predicate HALT execsize JUMP_LABEL JUMP_LABEL instoptions
1423 {
1424 add_label(p, $4, INSTR_LABEL_JIP);
1425 add_label(p, $5, INSTR_LABEL_UIP);
1426
1427 elk_next_insn(p, $2);
1428 i965_asm_set_instruction_options(p, $6);
1429 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $3);
1430
1431 elk_set_dest(p, elk_last_inst, retype(elk_null_reg(),
1432 ELK_REGISTER_TYPE_D));
1433
1434 if (p->devinfo->ver < 8) {
1435 elk_set_src0(p, elk_last_inst, retype(elk_null_reg(),
1436 ELK_REGISTER_TYPE_D));
1437 elk_set_src1(p, elk_last_inst, elk_imm_d(0x0));
1438 } else if (p->devinfo->ver < 12) {
1439 elk_set_src0(p, elk_last_inst, elk_imm_d(0x0));
1440 }
1441
1442 elk_pop_insn_state(p);
1443 }
1444 | predicate CONT execsize JUMP_LABEL JUMP_LABEL instoptions
1445 {
1446 add_label(p, $4, INSTR_LABEL_JIP);
1447 add_label(p, $5, INSTR_LABEL_UIP);
1448
1449 elk_next_insn(p, $2);
1450 i965_asm_set_instruction_options(p, $6);
1451 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $3);
1452 elk_set_dest(p, elk_last_inst, elk_ip_reg());
1453
1454 if (p->devinfo->ver >= 8) {
1455 elk_set_src0(p, elk_last_inst, elk_imm_d(0x0));
1456 } else {
1457 elk_set_src0(p, elk_last_inst, elk_ip_reg());
1458 elk_set_src1(p, elk_last_inst, elk_imm_d(0x0));
1459 }
1460
1461 elk_pop_insn_state(p);
1462 }
1463 | predicate CONT execsize relativelocation relativelocation instoptions
1464 {
1465 elk_next_insn(p, $2);
1466 i965_asm_set_instruction_options(p, $6);
1467 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $3);
1468 elk_set_dest(p, elk_last_inst, elk_ip_reg());
1469
1470 elk_set_src0(p, elk_last_inst, elk_ip_reg());
1471 elk_set_src1(p, elk_last_inst, elk_imm_d(0x0));
1472
1473 elk_inst_set_gfx4_jump_count(p->devinfo, elk_last_inst, $4);
1474 elk_inst_set_gfx4_pop_count(p->devinfo, elk_last_inst, $5);
1475
1476 elk_pop_insn_state(p);
1477 }
1478 ;
1479
1480 /* loop instruction */
1481 loopinstruction:
1482 predicate WHILE execsize JUMP_LABEL instoptions
1483 {
1484 add_label(p, $4, INSTR_LABEL_JIP);
1485
1486 elk_next_insn(p, $2);
1487 i965_asm_set_instruction_options(p, $5);
1488 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $3);
1489
1490 if (p->devinfo->ver >= 8) {
1491 elk_set_dest(p, elk_last_inst,
1492 retype(elk_null_reg(),
1493 ELK_REGISTER_TYPE_D));
1494 if (p->devinfo->ver < 12)
1495 elk_set_src0(p, elk_last_inst, elk_imm_d(0x0));
1496 } else if (p->devinfo->ver == 7) {
1497 elk_set_dest(p, elk_last_inst,
1498 retype(elk_null_reg(),
1499 ELK_REGISTER_TYPE_D));
1500 elk_set_src0(p, elk_last_inst,
1501 retype(elk_null_reg(),
1502 ELK_REGISTER_TYPE_D));
1503 elk_set_src1(p, elk_last_inst,
1504 elk_imm_w(0x0));
1505 } else {
1506 elk_set_dest(p, elk_last_inst, elk_imm_w(0x0));
1507 elk_set_src0(p, elk_last_inst,
1508 retype(elk_null_reg(),
1509 ELK_REGISTER_TYPE_D));
1510 elk_set_src1(p, elk_last_inst,
1511 retype(elk_null_reg(),
1512 ELK_REGISTER_TYPE_D));
1513 }
1514
1515 elk_pop_insn_state(p);
1516 }
1517 | predicate WHILE execsize relativelocation instoptions
1518 {
1519 elk_next_insn(p, $2);
1520 i965_asm_set_instruction_options(p, $5);
1521 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $3);
1522
1523 elk_set_dest(p, elk_last_inst, elk_ip_reg());
1524 elk_set_src0(p, elk_last_inst, elk_ip_reg());
1525 elk_set_src1(p, elk_last_inst, elk_imm_d(0x0));
1526 elk_inst_set_gfx4_jump_count(p->devinfo, elk_last_inst, $4);
1527 elk_inst_set_gfx4_pop_count(p->devinfo, elk_last_inst, 0);
1528
1529 elk_pop_insn_state(p);
1530 }
1531 | DO execsize instoptions
1532 {
1533 elk_next_insn(p, $1);
1534 if (p->devinfo->ver < 6) {
1535 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $2);
1536 i965_asm_set_instruction_options(p, $3);
1537 elk_set_dest(p, elk_last_inst, elk_null_reg());
1538 elk_set_src0(p, elk_last_inst, elk_null_reg());
1539 elk_set_src1(p, elk_last_inst, elk_null_reg());
1540
1541 elk_inst_set_qtr_control(p->devinfo, elk_last_inst, ELK_COMPRESSION_NONE);
1542 }
1543 }
1544 ;
1545
1546 /* sync instruction */
1547 syncinstruction:
1548 predicate SYNC sync_function execsize sync_arg instoptions
1549 {
1550 if (p->devinfo->ver < 12) {
1551 error(&@2, "sync instruction is supported only on gfx12+\n");
1552 }
1553
1554 if ($5.file == ELK_IMMEDIATE_VALUE &&
1555 $3 != TGL_SYNC_ALLRD &&
1556 $3 != TGL_SYNC_ALLWR) {
1557 error(&@2, "Only allrd and allwr support immediate argument\n");
1558 }
1559
1560 elk_set_default_access_mode(p, $6.access_mode);
1561 elk_SYNC(p, $3);
1562 i965_asm_set_instruction_options(p, $6);
1563 elk_inst_set_exec_size(p->devinfo, elk_last_inst, $4);
1564 elk_set_src0(p, elk_last_inst, $5);
1565 elk_inst_set_eot(p->devinfo, elk_last_inst, $6.end_of_thread);
1566 elk_inst_set_qtr_control(p->devinfo, elk_last_inst, $6.qtr_ctrl);
1567 elk_inst_set_nib_control(p->devinfo, elk_last_inst, $6.nib_ctrl);
1568
1569 elk_pop_insn_state(p);
1570 }
1571 ;
1572
1573 sync_function:
1574 NOP { $$ = TGL_SYNC_NOP; }
1575 | ALLRD
1576 | ALLWR
1577 | FENCE
1578 | BAR
1579 | HOST
1580 ;
1581
1582 sync_arg:
1583 nullreg region reg_type
1584 {
1585 $$ = $1;
1586 $$.vstride = $2.vstride;
1587 $$.width = $2.width;
1588 $$.hstride = $2.hstride;
1589 $$.type = $3;
1590 }
1591 | immreg
1592 ;
1593
1594 /* Relative location */
1595 relativelocation2:
1596 immreg
1597 | reg32
1598 ;
1599
1600 simple_int:
1601 INTEGER { $$ = $1; }
1602 | MINUS INTEGER { $$ = -$2; }
1603 | LONG { $$ = $1; }
1604 | MINUS LONG { $$ = -$2; }
1605 ;
1606
1607 rellocation:
1608 relativelocation
1609 | /* empty */ { $$ = 0; }
1610 ;
1611
1612 relativelocation:
1613 simple_int
1614 {
1615 $$ = $1;
1616 }
1617 ;
1618
1619 jumplabel:
1620 JUMP_LABEL { $$ = $1; }
1621 | /* empty */ { $$ = NULL; }
1622 ;
1623
1624 jumplabeltarget:
1625 JUMP_LABEL_TARGET
1626 {
1627 struct target_label *label = rzalloc(p->mem_ctx, struct target_label);
1628
1629 label->name = ralloc_strdup(p->mem_ctx, $1);
1630 label->offset = p->next_insn_offset;
1631
1632 list_addtail(&label->link, &target_labels);
1633 }
1634 ;
1635
1636 /* Destination register */
1637 dst:
1638 dstoperand
1639 | dstoperandex
1640 ;
1641
1642 dstoperand:
1643 dstreg dstregion writemask reg_type
1644 {
1645 $$ = $1;
1646 $$.vstride = ELK_VERTICAL_STRIDE_1;
1647 $$.width = ELK_WIDTH_1;
1648 $$.hstride = $2;
1649 $$.type = $4;
1650 $$.writemask = $3;
1651 $$.swizzle = ELK_SWIZZLE_NOOP;
1652 $$.subnr = $$.subnr * elk_reg_type_to_size($4);
1653 }
1654 ;
1655
1656 dstoperandex:
1657 dstoperandex_typed dstregion writemask reg_type
1658 {
1659 $$ = $1;
1660 $$.hstride = $2;
1661 $$.type = $4;
1662 $$.writemask = $3;
1663 $$.subnr = $$.subnr * elk_reg_type_to_size($4);
1664 }
1665 /* BSpec says "When the conditional modifier is present, updates
1666 * to the selected flag register also occur. In this case, the
1667 * register region fields of the ‘null’ operand are valid."
1668 */
1669 | nullreg dstregion writemask reg_type
1670 {
1671 $$ = $1;
1672 $$.vstride = ELK_VERTICAL_STRIDE_1;
1673 $$.width = ELK_WIDTH_1;
1674 $$.hstride = $2;
1675 $$.writemask = $3;
1676 $$.type = $4;
1677 }
1678 | threadcontrolreg
1679 {
1680 $$ = $1;
1681 $$.hstride = 1;
1682 $$.type = ELK_REGISTER_TYPE_UW;
1683 }
1684 ;
1685
1686 dstoperandex_typed:
1687 accreg
1688 | addrreg
1689 | channelenablereg
1690 | controlreg
1691 | flagreg
1692 | ipreg
1693 | maskreg
1694 | notifyreg
1695 | performancereg
1696 | statereg
1697 ;
1698
1699 dstreg:
1700 directgenreg
1701 {
1702 $$ = $1;
1703 $$.address_mode = ELK_ADDRESS_DIRECT;
1704 }
1705 | indirectgenreg
1706 {
1707 $$ = $1;
1708 $$.address_mode = ELK_ADDRESS_REGISTER_INDIRECT_REGISTER;
1709 }
1710 | directmsgreg
1711 {
1712 $$ = $1;
1713 $$.address_mode = ELK_ADDRESS_DIRECT;
1714 }
1715 | indirectmsgreg
1716 {
1717 $$ = $1;
1718 $$.address_mode = ELK_ADDRESS_REGISTER_INDIRECT_REGISTER;
1719 }
1720 ;
1721
1722 /* Source register */
1723 srcaccimm:
1724 srcacc
1725 | immreg
1726 ;
1727
1728 immreg:
1729 immval imm_type
1730 {
1731 switch ($2) {
1732 case ELK_REGISTER_TYPE_UD:
1733 $$ = elk_imm_ud($1);
1734 break;
1735 case ELK_REGISTER_TYPE_D:
1736 $$ = elk_imm_d($1);
1737 break;
1738 case ELK_REGISTER_TYPE_UW:
1739 $$ = elk_imm_uw($1 | ($1 << 16));
1740 break;
1741 case ELK_REGISTER_TYPE_W:
1742 $$ = elk_imm_w($1);
1743 break;
1744 case ELK_REGISTER_TYPE_F:
1745 $$ = elk_imm_reg(ELK_REGISTER_TYPE_F);
1746 /* Set u64 instead of ud since DIM uses a 64-bit F-typed imm */
1747 $$.u64 = $1;
1748 break;
1749 case ELK_REGISTER_TYPE_V:
1750 $$ = elk_imm_v($1);
1751 break;
1752 case ELK_REGISTER_TYPE_UV:
1753 $$ = elk_imm_uv($1);
1754 break;
1755 case ELK_REGISTER_TYPE_VF:
1756 $$ = elk_imm_vf($1);
1757 break;
1758 case ELK_REGISTER_TYPE_Q:
1759 $$ = elk_imm_q($1);
1760 break;
1761 case ELK_REGISTER_TYPE_UQ:
1762 $$ = elk_imm_uq($1);
1763 break;
1764 case ELK_REGISTER_TYPE_DF:
1765 $$ = elk_imm_reg(ELK_REGISTER_TYPE_DF);
1766 $$.d64 = $1;
1767 break;
1768 case ELK_REGISTER_TYPE_HF:
1769 $$ = elk_imm_reg(ELK_REGISTER_TYPE_HF);
1770 $$.ud = $1 | ($1 << 16);
1771 break;
1772 default:
1773 error(&@2, "Unknown immediate type %s\n",
1774 elk_reg_type_to_letters($2));
1775 }
1776 }
1777 ;
1778
1779 reg32:
1780 directgenreg region reg_type
1781 {
1782 $$ = set_direct_src_operand(&$1, $3);
1783 $$ = stride($$, $2.vstride, $2.width, $2.hstride);
1784 }
1785 ;
1786
1787 payload:
1788 directsrcoperand
1789 ;
1790
1791 src:
1792 directsrcoperand
1793 | indirectsrcoperand
1794 ;
1795
1796 srcacc:
1797 directsrcaccoperand
1798 | indirectsrcoperand
1799 ;
1800
1801 srcimm:
1802 directsrcoperand
1803 | indirectsrcoperand
1804 | immreg
1805 ;
1806
1807 directsrcaccoperand:
1808 directsrcoperand
1809 | negate abs accreg region reg_type
1810 {
1811 $$ = set_direct_src_operand(&$3, $5);
1812 $$.negate = $1;
1813 $$.abs = $2;
1814 $$.vstride = $4.vstride;
1815 $$.width = $4.width;
1816 $$.hstride = $4.hstride;
1817 }
1818 ;
1819
1820 srcarcoperandex:
1821 srcarcoperandex_typed region reg_type
1822 {
1823 $$ = elk_reg($1.file,
1824 $1.nr,
1825 $1.subnr,
1826 0,
1827 0,
1828 $3,
1829 $2.vstride,
1830 $2.width,
1831 $2.hstride,
1832 ELK_SWIZZLE_NOOP,
1833 WRITEMASK_XYZW);
1834 }
1835 | nullreg region reg_type
1836 {
1837 $$ = set_direct_src_operand(&$1, $3);
1838 $$.vstride = $2.vstride;
1839 $$.width = $2.width;
1840 $$.hstride = $2.hstride;
1841 }
1842 | threadcontrolreg
1843 {
1844 $$ = set_direct_src_operand(&$1, ELK_REGISTER_TYPE_UW);
1845 }
1846 ;
1847
1848 srcarcoperandex_typed:
1849 channelenablereg
1850 | controlreg
1851 | flagreg
1852 | ipreg
1853 | maskreg
1854 | statereg
1855 ;
1856
1857 indirectsrcoperand:
1858 negate abs indirectgenreg indirectregion swizzle reg_type
1859 {
1860 $$ = elk_reg($3.file,
1861 0,
1862 $3.subnr,
1863 $1, // negate
1864 $2, // abs
1865 $6,
1866 $4.vstride,
1867 $4.width,
1868 $4.hstride,
1869 $5,
1870 WRITEMASK_X);
1871
1872 $$.address_mode = ELK_ADDRESS_REGISTER_INDIRECT_REGISTER;
1873 // elk_reg set indirect_offset to 0 so set it to valid value
1874 $$.indirect_offset = $3.indirect_offset;
1875 }
1876 ;
1877
1878 directgenreg_list:
1879 directgenreg
1880 | directmsgreg
1881 | notifyreg
1882 | addrreg
1883 | performancereg
1884 ;
1885
1886 directsrcoperand:
1887 negate abs directgenreg_list region swizzle reg_type
1888 {
1889 $$ = elk_reg($3.file,
1890 $3.nr,
1891 $3.subnr,
1892 $1,
1893 $2,
1894 $6,
1895 $4.vstride,
1896 $4.width,
1897 $4.hstride,
1898 $5,
1899 WRITEMASK_X);
1900 }
1901 | srcarcoperandex
1902 ;
1903
1904 /* Address register */
1905 addrparam:
1906 addrreg exp
1907 {
1908 memset(&$$, '\0', sizeof($$));
1909 $$.subnr = $1.subnr;
1910 $$.indirect_offset = $2;
1911 }
1912 | addrreg
1913 ;
1914
1915 /* Register files and register numbers */
1916 exp:
1917 INTEGER { $$ = $1; }
1918 | LONG { $$ = $1; }
1919 ;
1920
1921 subregnum:
1922 DOT exp { $$ = $2; }
1923 | /* empty */ %prec SUBREGNUM { $$ = 0; }
1924 ;
1925
1926 directgenreg:
1927 GENREG subregnum
1928 {
1929 memset(&$$, '\0', sizeof($$));
1930 $$.file = ELK_GENERAL_REGISTER_FILE;
1931 $$.nr = $1;
1932 $$.subnr = $2;
1933 }
1934 ;
1935
1936 indirectgenreg:
1937 GENREGFILE LSQUARE addrparam RSQUARE
1938 {
1939 memset(&$$, '\0', sizeof($$));
1940 $$.file = ELK_GENERAL_REGISTER_FILE;
1941 $$.subnr = $3.subnr;
1942 $$.indirect_offset = $3.indirect_offset;
1943 }
1944 ;
1945
1946 directmsgreg:
1947 MSGREG subregnum
1948 {
1949 $$.file = ELK_MESSAGE_REGISTER_FILE;
1950 $$.nr = $1;
1951 $$.subnr = $2;
1952 }
1953 ;
1954
1955 indirectmsgreg:
1956 MSGREGFILE LSQUARE addrparam RSQUARE
1957 {
1958 memset(&$$, '\0', sizeof($$));
1959 $$.file = ELK_MESSAGE_REGISTER_FILE;
1960 $$.subnr = $3.subnr;
1961 $$.indirect_offset = $3.indirect_offset;
1962 }
1963 ;
1964
1965 addrreg:
1966 ADDRREG subregnum
1967 {
1968 int subnr = (p->devinfo->ver >= 8) ? 16 : 8;
1969
1970 if ($2 > subnr)
1971 error(&@2, "Address sub register number %d"
1972 "out of range\n", $2);
1973
1974 $$.file = ELK_ARCHITECTURE_REGISTER_FILE;
1975 $$.nr = ELK_ARF_ADDRESS;
1976 $$.subnr = $2;
1977 }
1978 ;
1979
1980 accreg:
1981 ACCREG subregnum
1982 {
1983 int nr_reg;
1984 if (p->devinfo->ver < 8)
1985 nr_reg = 2;
1986 else
1987 nr_reg = 10;
1988
1989 if ($1 > nr_reg)
1990 error(&@1, "Accumulator register number %d"
1991 " out of range\n", $1);
1992
1993 memset(&$$, '\0', sizeof($$));
1994 $$.file = ELK_ARCHITECTURE_REGISTER_FILE;
1995 $$.nr = ELK_ARF_ACCUMULATOR;
1996 $$.subnr = $2;
1997 }
1998 ;
1999
2000 flagreg:
2001 FLAGREG subregnum
2002 {
2003 // SNB = 1 flag reg and IVB+ = 2 flag reg
2004 int nr_reg = (p->devinfo->ver >= 7) ? 2 : 1;
2005 int subnr = nr_reg;
2006
2007 if ($1 > nr_reg)
2008 error(&@1, "Flag register number %d"
2009 " out of range \n", $1);
2010 if ($2 > subnr)
2011 error(&@2, "Flag subregister number %d"
2012 " out of range\n", $2);
2013
2014 $$.file = ELK_ARCHITECTURE_REGISTER_FILE;
2015 $$.nr = ELK_ARF_FLAG | $1;
2016 $$.subnr = $2;
2017 }
2018 ;
2019
2020 maskreg:
2021 MASKREG subregnum
2022 {
2023 if ($1 > 0)
2024 error(&@1, "Mask register number %d"
2025 " out of range\n", $1);
2026
2027 $$.file = ELK_ARCHITECTURE_REGISTER_FILE;
2028 $$.nr = ELK_ARF_MASK;
2029 $$.subnr = $2;
2030 }
2031 ;
2032
2033 notifyreg:
2034 NOTIFYREG subregnum
2035 {
2036 int subnr = (p->devinfo->ver >= 11) ? 2 : 3;
2037 if ($2 > subnr)
2038 error(&@2, "Notification sub register number %d"
2039 " out of range\n", $2);
2040
2041 $$.file = ELK_ARCHITECTURE_REGISTER_FILE;
2042 $$.nr = ELK_ARF_NOTIFICATION_COUNT;
2043 $$.subnr = $2;
2044 }
2045 ;
2046
2047 statereg:
2048 STATEREG subregnum
2049 {
2050 if ($1 > 2)
2051 error(&@1, "State register number %d"
2052 " out of range\n", $1);
2053
2054 if ($2 > 4)
2055 error(&@2, "State sub register number %d"
2056 " out of range\n", $2);
2057
2058 $$.file = ELK_ARCHITECTURE_REGISTER_FILE;
2059 $$.nr = ELK_ARF_STATE;
2060 $$.subnr = $2;
2061 }
2062 ;
2063
2064 controlreg:
2065 CONTROLREG subregnum
2066 {
2067 if ($2 > 3)
2068 error(&@2, "control sub register number %d"
2069 " out of range\n", $2);
2070
2071 $$.file = ELK_ARCHITECTURE_REGISTER_FILE;
2072 $$.nr = ELK_ARF_CONTROL;
2073 $$.subnr = $2;
2074 }
2075 ;
2076
2077 ipreg:
2078 IPREG { $$ = elk_ip_reg(); }
2079 ;
2080
2081 nullreg:
2082 NULL_TOKEN { $$ = elk_null_reg(); }
2083 ;
2084
2085 threadcontrolreg:
2086 THREADREG subregnum
2087 {
2088 if ($2 > 7)
2089 error(&@2, "Thread control sub register number %d"
2090 " out of range\n", $2);
2091
2092 $$.file = ELK_ARCHITECTURE_REGISTER_FILE;
2093 $$.nr = ELK_ARF_TDR;
2094 $$.subnr = $2;
2095 }
2096 ;
2097
2098 performancereg:
2099 PERFORMANCEREG subregnum
2100 {
2101 int subnr;
2102 if (p->devinfo->ver >= 10)
2103 subnr = 5;
2104 else if (p->devinfo->ver <= 8)
2105 subnr = 3;
2106 else
2107 subnr = 4;
2108
2109 if ($2 > subnr)
2110 error(&@2, "Performance sub register number %d"
2111 " out of range\n", $2);
2112
2113 $$.file = ELK_ARCHITECTURE_REGISTER_FILE;
2114 $$.nr = ELK_ARF_TIMESTAMP;
2115 $$.subnr = $2;
2116 }
2117 ;
2118
2119 channelenablereg:
2120 CHANNELENABLEREG subregnum
2121 {
2122 if ($1 > 0)
2123 error(&@1, "Channel enable register number %d"
2124 " out of range\n", $1);
2125
2126 $$.file = ELK_ARCHITECTURE_REGISTER_FILE;
2127 $$.nr = ELK_ARF_MASK;
2128 $$.subnr = $2;
2129 }
2130 ;
2131
2132 /* Immediate values */
2133 immval:
2134 exp2
2135 {
2136 $$ = $1;
2137 }
2138 | LSQUARE exp2 COMMA exp2 COMMA exp2 COMMA exp2 RSQUARE
2139 {
2140 $$ = ($2 << 0) | ($4 << 8) | ($6 << 16) | ($8 << 24);
2141 }
2142 ;
2143
2144 /* Regions */
2145 dstregion:
2146 /* empty */
2147 {
2148 $$ = ELK_HORIZONTAL_STRIDE_1;
2149 }
2150 | LANGLE exp RANGLE
2151 {
2152 if ($2 != 0 && ($2 > 4 || !isPowerofTwo($2)))
2153 error(&@2, "Invalid Horizontal stride %d\n", $2);
2154
2155 $$ = ffs($2);
2156 }
2157 ;
2158
2159 indirectregion:
2160 region
2161 | region_wh
2162 ;
2163
2164 region:
2165 /* empty */
2166 {
2167 $$ = stride($$, 0, 1, 0);
2168 }
2169 | LANGLE exp RANGLE
2170 {
2171 if ($2 != 0 && ($2 > 32 || !isPowerofTwo($2)))
2172 error(&@2, "Invalid VertStride %d\n", $2);
2173
2174 $$ = stride($$, $2, 1, 0);
2175 }
2176 | LANGLE exp COMMA exp COMMA exp RANGLE
2177 {
2178
2179 if ($2 != 0 && ($2 > 32 || !isPowerofTwo($2)))
2180 error(&@2, "Invalid VertStride %d\n", $2);
2181
2182 if ($4 > 16 || !isPowerofTwo($4))
2183 error(&@4, "Invalid width %d\n", $4);
2184
2185 if ($6 != 0 && ($6 > 4 || !isPowerofTwo($6)))
2186 error(&@6, "Invalid Horizontal stride in"
2187 " region_wh %d\n", $6);
2188
2189 $$ = stride($$, $2, $4, $6);
2190 }
2191 | LANGLE exp SEMICOLON exp COMMA exp RANGLE
2192 {
2193 if ($2 != 0 && ($2 > 32 || !isPowerofTwo($2)))
2194 error(&@2, "Invalid VertStride %d\n", $2);
2195
2196 if ($4 > 16 || !isPowerofTwo($4))
2197 error(&@4, "Invalid width %d\n", $4);
2198
2199 if ($6 != 0 && ($6 > 4 || !isPowerofTwo($6)))
2200 error(&@6, "Invalid Horizontal stride in"
2201 " region_wh %d\n", $6);
2202
2203 $$ = stride($$, $2, $4, $6);
2204 }
2205 | LANGLE VxH COMMA exp COMMA exp RANGLE
2206 {
2207 if ($4 > 16 || !isPowerofTwo($4))
2208 error(&@4, "Invalid width %d\n", $4);
2209
2210 if ($6 != 0 && ($6 > 4 || !isPowerofTwo($6)))
2211 error(&@6, "Invalid Horizontal stride in"
2212 " region_wh %d\n", $6);
2213
2214 $$ = elk_VxH_indirect(0, 0);
2215 }
2216 ;
2217
2218 region_wh:
2219 LANGLE exp COMMA exp RANGLE
2220 {
2221 if ($2 > 16 || !isPowerofTwo($2))
2222 error(&@2, "Invalid width %d\n", $2);
2223
2224 if ($4 != 0 && ($4 > 4 || !isPowerofTwo($4)))
2225 error(&@4, "Invalid Horizontal stride in"
2226 " region_wh %d\n", $4);
2227
2228 $$ = stride($$, 0, $2, $4);
2229 $$.vstride = ELK_VERTICAL_STRIDE_ONE_DIMENSIONAL;
2230 }
2231 ;
2232
2233 reg_type:
2234 TYPE_F { $$ = ELK_REGISTER_TYPE_F; }
2235 | TYPE_UD { $$ = ELK_REGISTER_TYPE_UD; }
2236 | TYPE_D { $$ = ELK_REGISTER_TYPE_D; }
2237 | TYPE_UW { $$ = ELK_REGISTER_TYPE_UW; }
2238 | TYPE_W { $$ = ELK_REGISTER_TYPE_W; }
2239 | TYPE_UB { $$ = ELK_REGISTER_TYPE_UB; }
2240 | TYPE_B { $$ = ELK_REGISTER_TYPE_B; }
2241 | TYPE_DF { $$ = ELK_REGISTER_TYPE_DF; }
2242 | TYPE_UQ { $$ = ELK_REGISTER_TYPE_UQ; }
2243 | TYPE_Q { $$ = ELK_REGISTER_TYPE_Q; }
2244 | TYPE_HF { $$ = ELK_REGISTER_TYPE_HF; }
2245 | TYPE_NF { $$ = ELK_REGISTER_TYPE_NF; }
2246 ;
2247
2248 imm_type:
2249 reg_type { $$ = $1; }
2250 | TYPE_V { $$ = ELK_REGISTER_TYPE_V; }
2251 | TYPE_VF { $$ = ELK_REGISTER_TYPE_VF; }
2252 | TYPE_UV { $$ = ELK_REGISTER_TYPE_UV; }
2253 ;
2254
2255 writemask:
2256 /* empty */
2257 {
2258 $$ = WRITEMASK_XYZW;
2259 }
2260 | DOT writemask_x writemask_y writemask_z writemask_w
2261 {
2262 $$ = $2 | $3 | $4 | $5;
2263 }
2264 ;
2265
2266 writemask_x:
2267 /* empty */ { $$ = 0; }
2268 | X { $$ = 1 << ELK_CHANNEL_X; }
2269 ;
2270
2271 writemask_y:
2272 /* empty */ { $$ = 0; }
2273 | Y { $$ = 1 << ELK_CHANNEL_Y; }
2274 ;
2275
2276 writemask_z:
2277 /* empty */ { $$ = 0; }
2278 | Z { $$ = 1 << ELK_CHANNEL_Z; }
2279 ;
2280
2281 writemask_w:
2282 /* empty */ { $$ = 0; }
2283 | W { $$ = 1 << ELK_CHANNEL_W; }
2284 ;
2285
2286 swizzle:
2287 /* empty */
2288 {
2289 $$ = ELK_SWIZZLE_NOOP;
2290 }
2291 | DOT chansel
2292 {
2293 $$ = ELK_SWIZZLE4($2, $2, $2, $2);
2294 }
2295 | DOT chansel chansel chansel chansel
2296 {
2297 $$ = ELK_SWIZZLE4($2, $3, $4, $5);
2298 }
2299 ;
2300
2301 chansel:
2302 X
2303 | Y
2304 | Z
2305 | W
2306 ;
2307
2308 /* Instruction prediction and modifiers */
2309 predicate:
2310 /* empty */
2311 {
2312 elk_push_insn_state(p);
2313 elk_set_default_predicate_control(p, ELK_PREDICATE_NONE);
2314 elk_set_default_flag_reg(p, 0, 0);
2315 elk_set_default_predicate_inverse(p, false);
2316 }
2317 | LPAREN predstate flagreg predctrl RPAREN
2318 {
2319 elk_push_insn_state(p);
2320 elk_set_default_predicate_inverse(p, $2);
2321 elk_set_default_flag_reg(p, $3.nr, $3.subnr);
2322 elk_set_default_predicate_control(p, $4);
2323 }
2324 ;
2325
2326 predstate:
2327 /* empty */ { $$ = 0; }
2328 | PLUS { $$ = 0; }
2329 | MINUS { $$ = 1; }
2330 ;
2331
2332 predctrl:
2333 /* empty */ { $$ = ELK_PREDICATE_NORMAL; }
2334 | DOT X { $$ = ELK_PREDICATE_ALIGN16_REPLICATE_X; }
2335 | DOT Y { $$ = ELK_PREDICATE_ALIGN16_REPLICATE_Y; }
2336 | DOT Z { $$ = ELK_PREDICATE_ALIGN16_REPLICATE_Z; }
2337 | DOT W { $$ = ELK_PREDICATE_ALIGN16_REPLICATE_W; }
2338 | ANYV
2339 | ALLV
2340 | ANY2H
2341 | ALL2H
2342 | ANY4H
2343 | ALL4H
2344 | ANY8H
2345 | ALL8H
2346 | ANY16H
2347 | ALL16H
2348 | ANY32H
2349 | ALL32H
2350 ;
2351
2352 /* Source Modification */
2353 negate:
2354 /* empty */ { $$ = 0; }
2355 | MINUS { $$ = 1; }
2356 ;
2357
2358 abs:
2359 /* empty */ { $$ = 0; }
2360 | ABS { $$ = 1; }
2361 ;
2362
2363 /* Flag (Conditional) Modifier */
2364 cond_mod:
2365 condModifiers
2366 {
2367 $$.cond_modifier = $1;
2368 $$.flag_reg_nr = 0;
2369 $$.flag_subreg_nr = 0;
2370 }
2371 | condModifiers DOT flagreg
2372 {
2373 $$.cond_modifier = $1;
2374 $$.flag_reg_nr = $3.nr;
2375 $$.flag_subreg_nr = $3.subnr;
2376 }
2377 ;
2378
2379 condModifiers:
2380 /* empty */ { $$ = ELK_CONDITIONAL_NONE; }
2381 | ZERO
2382 | EQUAL
2383 | NOT_ZERO
2384 | NOT_EQUAL
2385 | GREATER
2386 | GREATER_EQUAL
2387 | LESS
2388 | LESS_EQUAL
2389 | OVERFLOW
2390 | ROUND_INCREMENT
2391 | UNORDERED
2392 ;
2393
2394 /* message details for send */
2395 msgdesc:
2396 MSGDESC_BEGIN msgdesc_parts MSGDESC_END { $$ = $2; }
2397 ;
2398
2399 msgdesc_parts:
2400 SRC1_LEN ASSIGN INTEGER msgdesc_parts
2401 {
2402 $$ = $4;
2403 $$.src1_len = $3;
2404 }
2405 | EX_BSO msgdesc_parts
2406 {
2407 $$ = $2;
2408 $$.ex_bso = 1;
2409 }
2410 | INTEGER msgdesc_parts { $$ = $2; }
2411 | ASSIGN msgdesc_parts { $$ = $2; }
2412 | /* empty */
2413 {
2414 memset(&$$, 0, sizeof($$));
2415 }
2416 ;
2417
2418 saturate:
2419 /* empty */ { $$ = ELK_INSTRUCTION_NORMAL; }
2420 | SATURATE { $$ = ELK_INSTRUCTION_SATURATE; }
2421 ;
2422
2423 /* Execution size */
2424 execsize:
2425 /* empty */ %prec EMPTYEXECSIZE
2426 {
2427 $$ = 0;
2428 }
2429 | LPAREN exp2 RPAREN
2430 {
2431 if ($2 > 32 || !isPowerofTwo($2))
2432 error(&@2, "Invalid execution size %llu\n", $2);
2433
2434 $$ = cvt($2) - 1;
2435 }
2436 ;
2437
2438 /* Instruction options */
2439 instoptions:
2440 /* empty */
2441 {
2442 memset(&$$, 0, sizeof($$));
2443 }
2444 | LCURLY instoption_list RCURLY
2445 {
2446 memset(&$$, 0, sizeof($$));
2447 $$ = $2;
2448 }
2449 ;
2450
2451 instoption_list:
2452 instoption_list COMMA instoption
2453 {
2454 memset(&$$, 0, sizeof($$));
2455 $$ = $1;
2456 add_instruction_option(&$$, $3);
2457 }
2458 | instoption_list instoption
2459 {
2460 memset(&$$, 0, sizeof($$));
2461 $$ = $1;
2462 add_instruction_option(&$$, $2);
2463 }
2464 | /* empty */
2465 {
2466 memset(&$$, 0, sizeof($$));
2467 }
2468 ;
2469
2470 depinfo:
2471 REG_DIST_CURRENT
2472 {
2473 memset(&$$, 0, sizeof($$));
2474 $$.regdist = $1;
2475 $$.pipe = TGL_PIPE_NONE;
2476 }
2477 | REG_DIST_FLOAT
2478 {
2479 memset(&$$, 0, sizeof($$));
2480 $$.regdist = $1;
2481 $$.pipe = TGL_PIPE_FLOAT;
2482 }
2483 | REG_DIST_INT
2484 {
2485 memset(&$$, 0, sizeof($$));
2486 $$.regdist = $1;
2487 $$.pipe = TGL_PIPE_INT;
2488 }
2489 | REG_DIST_LONG
2490 {
2491 memset(&$$, 0, sizeof($$));
2492 $$.regdist = $1;
2493 $$.pipe = TGL_PIPE_LONG;
2494 }
2495 | REG_DIST_ALL
2496 {
2497 memset(&$$, 0, sizeof($$));
2498 $$.regdist = $1;
2499 $$.pipe = TGL_PIPE_ALL;
2500 }
2501 | SBID_ALLOC
2502 {
2503 memset(&$$, 0, sizeof($$));
2504 $$.sbid = $1;
2505 $$.mode = TGL_SBID_SET;
2506 }
2507 | SBID_WAIT_SRC
2508 {
2509 memset(&$$, 0, sizeof($$));
2510 $$.sbid = $1;
2511 $$.mode = TGL_SBID_SRC;
2512 }
2513 | SBID_WAIT_DST
2514 {
2515 memset(&$$, 0, sizeof($$));
2516 $$.sbid = $1;
2517 $$.mode = TGL_SBID_DST;
2518 }
2519
2520 instoption:
2521 ALIGN1 { $$.type = INSTOPTION_FLAG; $$.uint_value = ALIGN1;}
2522 | ALIGN16 { $$.type = INSTOPTION_FLAG; $$.uint_value = ALIGN16; }
2523 | ACCWREN { $$.type = INSTOPTION_FLAG; $$.uint_value = ACCWREN; }
2524 | SECHALF { $$.type = INSTOPTION_FLAG; $$.uint_value = SECHALF; }
2525 | COMPR { $$.type = INSTOPTION_FLAG; $$.uint_value = COMPR; }
2526 | COMPR4 { $$.type = INSTOPTION_FLAG; $$.uint_value = COMPR4; }
2527 | BREAKPOINT { $$.type = INSTOPTION_FLAG; $$.uint_value = BREAKPOINT; }
2528 | NODDCLR { $$.type = INSTOPTION_FLAG; $$.uint_value = NODDCLR; }
2529 | NODDCHK { $$.type = INSTOPTION_FLAG; $$.uint_value = NODDCHK; }
2530 | MASK_DISABLE { $$.type = INSTOPTION_FLAG; $$.uint_value = MASK_DISABLE; }
2531 | EOT { $$.type = INSTOPTION_FLAG; $$.uint_value = EOT; }
2532 | SWITCH { $$.type = INSTOPTION_FLAG; $$.uint_value = SWITCH; }
2533 | ATOMIC { $$.type = INSTOPTION_FLAG; $$.uint_value = ATOMIC; }
2534 | CMPTCTRL { $$.type = INSTOPTION_FLAG; $$.uint_value = CMPTCTRL; }
2535 | WECTRL { $$.type = INSTOPTION_FLAG; $$.uint_value = WECTRL; }
2536 | QTR_2Q { $$.type = INSTOPTION_FLAG; $$.uint_value = QTR_2Q; }
2537 | QTR_3Q { $$.type = INSTOPTION_FLAG; $$.uint_value = QTR_3Q; }
2538 | QTR_4Q { $$.type = INSTOPTION_FLAG; $$.uint_value = QTR_4Q; }
2539 | QTR_2H { $$.type = INSTOPTION_FLAG; $$.uint_value = QTR_2H; }
2540 | QTR_2N { $$.type = INSTOPTION_FLAG; $$.uint_value = QTR_2N; }
2541 | QTR_3N { $$.type = INSTOPTION_FLAG; $$.uint_value = QTR_3N; }
2542 | QTR_4N { $$.type = INSTOPTION_FLAG; $$.uint_value = QTR_4N; }
2543 | QTR_5N { $$.type = INSTOPTION_FLAG; $$.uint_value = QTR_5N; }
2544 | QTR_6N { $$.type = INSTOPTION_FLAG; $$.uint_value = QTR_6N; }
2545 | QTR_7N { $$.type = INSTOPTION_FLAG; $$.uint_value = QTR_7N; }
2546 | QTR_8N { $$.type = INSTOPTION_FLAG; $$.uint_value = QTR_8N; }
2547 | depinfo { $$.type = INSTOPTION_DEP_INFO; $$.depinfo_value = $1; }
2548 ;
2549
2550 %%
2551
2552 extern int yylineno;
2553
2554 #ifdef YYBYACC
2555 void
yyerror(YYLTYPE * ltype,char * msg)2556 yyerror(YYLTYPE *ltype, char *msg)
2557 #else
2558 void
2559 yyerror(char *msg)
2560 #endif
2561 {
2562 fprintf(stderr, "%s: %d: %s at \"%s\"\n",
2563 input_filename, yylineno, msg, lex_text());
2564 ++errors;
2565 }
2566