• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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