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