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