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