xref: /aosp_15_r20/external/igt-gpu-tools/assembler/gram.y (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1 %{
2 /*
3  * Copyright © 2006 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 FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  *
24  * Authors:
25  *    Eric Anholt <[email protected]>
26  *
27  */
28 
29 #include <stdio.h>
30 #include <string.h>
31 #include <stdlib.h>
32 #include <stdbool.h>
33 #include <stdarg.h>
34 #include <assert.h>
35 #include "gen4asm.h"
36 #include "brw_eu.h"
37 #include "gen8_instruction.h"
38 
39 #define DEFAULT_EXECSIZE (ffs(program_defaults.execute_size) - 1)
40 #define DEFAULT_DSTREGION -1
41 
42 #define SWIZZLE(reg) (reg.dw1.bits.swizzle)
43 
44 #define GEN(i)	(&(i)->insn.gen)
45 #define GEN8(i)	(&(i)->insn.gen8)
46 
47 #define YYLTYPE YYLTYPE
48 typedef struct YYLTYPE
49 {
50  int first_line;
51  int first_column;
52  int last_line;
53  int last_column;
54 } YYLTYPE;
55 
56 extern int need_export;
57 static struct src_operand src_null_reg =
58 {
59     .reg.file = BRW_ARCHITECTURE_REGISTER_FILE,
60     .reg.nr = BRW_ARF_NULL,
61     .reg.type = BRW_REGISTER_TYPE_UD,
62 };
63 static struct brw_reg dst_null_reg =
64 {
65     .file = BRW_ARCHITECTURE_REGISTER_FILE,
66     .nr = BRW_ARF_NULL,
67 };
68 static struct brw_reg ip_dst =
69 {
70     .file = BRW_ARCHITECTURE_REGISTER_FILE,
71     .nr = BRW_ARF_IP,
72     .type = BRW_REGISTER_TYPE_UD,
73     .address_mode = BRW_ADDRESS_DIRECT,
74     .hstride = 1,
75     .dw1.bits.writemask = BRW_WRITEMASK_XYZW,
76 };
77 static struct src_operand ip_src =
78 {
79     .reg.file = BRW_ARCHITECTURE_REGISTER_FILE,
80     .reg.nr = BRW_ARF_IP,
81     .reg.type = BRW_REGISTER_TYPE_UD,
82     .reg.address_mode = BRW_ADDRESS_DIRECT,
83     .reg.dw1.bits.swizzle = BRW_SWIZZLE_NOOP,
84 };
85 
86 static int get_type_size(unsigned type);
87 static void set_instruction_opcode(struct brw_program_instruction *instr,
88 				   unsigned opcode);
89 static int set_instruction_dest(struct brw_program_instruction *instr,
90 				struct brw_reg *dest);
91 static int set_instruction_src0(struct brw_program_instruction *instr,
92 				struct src_operand *src,
93 				YYLTYPE *location);
94 static int set_instruction_src1(struct brw_program_instruction *instr,
95 				struct src_operand *src,
96 				YYLTYPE *location);
97 static int set_instruction_dest_three_src(struct brw_program_instruction *instr,
98 					  struct brw_reg *dest);
99 static int set_instruction_src0_three_src(struct brw_program_instruction *instr,
100 					  struct src_operand *src);
101 static int set_instruction_src1_three_src(struct brw_program_instruction *instr,
102 					  struct src_operand *src);
103 static int set_instruction_src2_three_src(struct brw_program_instruction *instr,
104 					  struct src_operand *src);
105 static void set_instruction_saturate(struct brw_program_instruction *instr,
106 				     int saturate);
107 static void set_instruction_options(struct brw_program_instruction *instr,
108 				    struct options options);
109 static void set_instruction_predicate(struct brw_program_instruction *instr,
110 				      struct predicate *p);
111 static void set_instruction_pred_cond(struct brw_program_instruction *instr,
112 				      struct predicate *p,
113 				      struct condition *c,
114 				      YYLTYPE *location);
115 static void set_direct_dst_operand(struct brw_reg *dst, struct brw_reg *reg,
116 				   int type);
117 static void set_direct_src_operand(struct src_operand *src, struct brw_reg *reg,
118 				   int type);
119 
120 void set_branch_two_offsets(struct brw_program_instruction *insn, int jip_offset, int uip_offset);
121 void set_branch_one_offset(struct brw_program_instruction *insn, int jip_offset);
122 
123 enum message_level {
124     WARN,
125     ERROR,
126 };
127 
message(enum message_level level,YYLTYPE * location,const char * fmt,...)128 static void message(enum message_level level, YYLTYPE *location,
129 		    const char *fmt, ...)
130 {
131     static const char *level_str[] = { "warning", "error" };
132     va_list args;
133 
134     if (location)
135 	fprintf(stderr, "%s:%d:%d: %s: ", input_filename, location->first_line,
136 		location->first_column, level_str[level]);
137     else
138 	fprintf(stderr, "%s:%s: ", input_filename, level_str[level]);
139 
140     va_start(args, fmt);
141     vfprintf(stderr, fmt, args);
142     va_end(args);
143 }
144 
145 #define warn(flag, l, fmt, ...)					\
146     do {							\
147 	if (warning_flags & WARN_ ## flag)			\
148 	    message(WARN, l, fmt, ## __VA_ARGS__);	\
149     } while(0)
150 
151 #define error(l, fmt, ...)			\
152     do {					\
153 	message(ERROR, l, fmt, ## __VA_ARGS__);	\
154     } while(0)
155 
156 /* like strcmp, but handles NULL pointers */
strcmp0(const char * s1,const char * s2)157 static bool strcmp0(const char *s1, const char* s2)
158 {
159     if (!s1)
160 	return -(s1 != s2);
161     if (!s2)
162 	return s1 != s2;
163     return strcmp (s1, s2);
164 }
165 
region_equal(struct region * r1,struct region * r2)166 static bool region_equal(struct region *r1, struct region *r2)
167 {
168     return memcmp(r1, r2, sizeof(struct region)) == 0;
169 }
170 
reg_equal(struct brw_reg * r1,struct brw_reg * r2)171 static bool reg_equal(struct brw_reg *r1, struct brw_reg *r2)
172 {
173     return memcmp(r1, r2, sizeof(struct brw_reg)) == 0;
174 }
175 
declared_register_equal(struct declared_register * r1,struct declared_register * r2)176 static bool declared_register_equal(struct declared_register *r1,
177 				     struct declared_register *r2)
178 {
179     if (strcmp0(r1->name, r2->name) != 0)
180 	return false;
181 
182     if (!reg_equal(&r1->reg, &r2->reg))
183 	return false;
184 
185     if (!region_equal(&r1->src_region, &r2->src_region))
186 	return false;
187 
188     if (r1->element_size != r2->element_size ||
189         r1->dst_region != r2->dst_region)
190 	return false;
191 
192     return true;
193 }
194 
brw_program_init(struct brw_program * p)195 static void brw_program_init(struct brw_program *p)
196 {
197    memset(p, 0, sizeof(struct brw_program));
198 }
199 
brw_program_append_entry(struct brw_program * p,struct brw_program_instruction * entry)200 static void brw_program_append_entry(struct brw_program *p,
201 				     struct brw_program_instruction *entry)
202 {
203     entry->next = NULL;
204     if (p->last)
205 	p->last->next = entry;
206     else
207 	p->first = entry;
208     p->last = entry;
209 }
210 
211 static void
brw_program_add_instruction(struct brw_program * p,struct brw_program_instruction * instruction)212 brw_program_add_instruction(struct brw_program *p,
213 			    struct brw_program_instruction *instruction)
214 {
215     struct brw_program_instruction *list_entry;
216 
217     list_entry = calloc(sizeof(struct brw_program_instruction), 1);
218     list_entry->type = GEN4ASM_INSTRUCTION_GEN;
219     list_entry->insn.gen = instruction->insn.gen;
220     brw_program_append_entry(p, list_entry);
221 }
222 
223 static void
brw_program_add_relocatable(struct brw_program * p,struct brw_program_instruction * instruction)224 brw_program_add_relocatable(struct brw_program *p,
225 			    struct brw_program_instruction *instruction)
226 {
227     struct brw_program_instruction *list_entry;
228 
229     list_entry = calloc(sizeof(struct brw_program_instruction), 1);
230     list_entry->type = GEN4ASM_INSTRUCTION_GEN_RELOCATABLE;
231     list_entry->insn.gen = instruction->insn.gen;
232     list_entry->reloc = instruction->reloc;
233     brw_program_append_entry(p, list_entry);
234 }
235 
brw_program_add_label(struct brw_program * p,const char * label)236 static void brw_program_add_label(struct brw_program *p, const char *label)
237 {
238     struct brw_program_instruction *list_entry;
239 
240     list_entry = calloc(sizeof(struct brw_program_instruction), 1);
241     list_entry->type = GEN4ASM_INSTRUCTION_LABEL;
242     list_entry->insn.label.name = strdup(label);
243     brw_program_append_entry(p, list_entry);
244 }
245 
resolve_dst_region(struct declared_register * reference,int region)246 static int resolve_dst_region(struct declared_register *reference, int region)
247 {
248     int resolved = region;
249 
250     if (resolved == DEFAULT_DSTREGION) {
251 	if (reference)
252 	    resolved = reference->dst_region;
253         else
254             resolved = 1;
255     }
256 
257     assert(resolved == 1 || resolved == 2 || resolved == 3);
258     return resolved;
259 }
260 
access_mode(struct brw_program_instruction * insn)261 static inline int access_mode(struct brw_program_instruction *insn)
262 {
263     if (IS_GENp(8))
264 	return gen8_access_mode(GEN8(insn));
265     else
266 	return GEN(insn)->header.access_mode;
267 }
268 
exec_size(struct brw_program_instruction * insn)269 static inline int exec_size(struct brw_program_instruction *insn)
270 {
271     if (IS_GENp(8))
272 	return gen8_exec_size(GEN8(insn));
273     else
274 	return GEN(insn)->header.execution_size;
275 }
276 
set_execsize(struct brw_program_instruction * insn,int execsize)277 static void set_execsize(struct brw_program_instruction *insn, int execsize)
278 {
279     if (IS_GENp(8))
280 	gen8_set_exec_size(GEN8(insn), execsize);
281     else
282 	GEN(insn)->header.execution_size = execsize;
283 }
284 
validate_dst_reg(struct brw_program_instruction * insn,struct brw_reg * reg)285 static bool validate_dst_reg(struct brw_program_instruction *insn, struct brw_reg *reg)
286 {
287 
288     if (reg->address_mode == BRW_ADDRESS_DIRECT &&
289 	access_mode(insn) == BRW_ALIGN_1 &&
290 	reg->dw1.bits.writemask != 0 &&
291 	reg->dw1.bits.writemask != BRW_WRITEMASK_XYZW)
292     {
293 	fprintf(stderr, "error: write mask set in align1 instruction\n");
294 	return false;
295     }
296 
297     if (reg->address_mode == BRW_ADDRESS_REGISTER_INDIRECT_REGISTER &&
298 	access_mode(insn) == BRW_ALIGN_16) {
299 	fprintf(stderr, "error: indirect Dst addr mode in align16 instruction\n");
300 	return false;
301     }
302 
303     return true;
304 }
305 
validate_src_reg(struct brw_program_instruction * insn,struct brw_reg reg,YYLTYPE * location)306 static bool validate_src_reg(struct brw_program_instruction *insn,
307 			     struct brw_reg reg,
308 			     YYLTYPE *location)
309 {
310     int hstride_for_reg[] = {0, 1, 2, 4};
311     int vstride_for_reg[] = {0, 1, 2, 4, 8, 16, 32, 64, 128, 256};
312     int width_for_reg[] = {1, 2, 4, 8, 16};
313     int execsize_for_reg[] = {1, 2, 4, 8, 16, 32};
314     int width, hstride, vstride, execsize;
315 
316     if (reg.file == BRW_IMMEDIATE_VALUE)
317 	return true;
318 
319     if (access_mode(insn) == BRW_ALIGN_1 &&
320 	SWIZZLE(reg) && SWIZZLE(reg) != BRW_SWIZZLE_NOOP)
321     {
322 	error(location, "swizzle bits set in align1 instruction\n");
323 	return false;
324     }
325 
326     if (reg.address_mode == BRW_ADDRESS_REGISTER_INDIRECT_REGISTER &&
327 	access_mode(insn) == BRW_ALIGN_16) {
328 	fprintf(stderr, "error: indirect Source addr mode in align16 instruction\n");
329 	return false;
330     }
331 
332     assert(reg.hstride >= 0 && reg.hstride < ARRAY_SIZE(hstride_for_reg));
333     hstride = hstride_for_reg[reg.hstride];
334 
335     if (reg.vstride == 0xf) {
336 	vstride = -1;
337     } else {
338 	assert(reg.vstride >= 0 && reg.vstride < ARRAY_SIZE(vstride_for_reg));
339 	vstride = vstride_for_reg[reg.vstride];
340     }
341 
342     assert(reg.width >= 0 && reg.width < ARRAY_SIZE(width_for_reg));
343     width = width_for_reg[reg.width];
344 
345     assert(exec_size(insn) >= 0 &&
346 	   exec_size(insn) < ARRAY_SIZE(execsize_for_reg));
347     execsize = execsize_for_reg[exec_size(insn)];
348 
349     /* Register Region Restrictions */
350 
351     /* B. If ExecSize = Width and HorzStride ≠ 0, VertStride must be set to
352      * Width * HorzStride. */
353     if (execsize == width && hstride != 0) {
354 	if (vstride != -1 && vstride != width * hstride)
355 	    warn(ALL, location, "execution size == width and hstride != 0 but "
356 		 "vstride is not width * hstride\n");
357     }
358 
359     /* D. If Width = 1, HorzStride must be 0 regardless of the values of
360      * ExecSize and VertStride.
361      *
362      * FIXME: In "advanced mode" hstride is set to 1, this is probably a bug
363      * to fix, but it changes the generated opcodes and thus needs validation.
364      */
365     if (width == 1 && hstride != 0)
366 	warn(ALL, location, "region width is 1 but horizontal stride is %d "
367 	     " (should be 0)\n", hstride);
368 
369     /* E. If ExecSize = Width = 1, both VertStride and HorzStride must be 0.
370      * This defines a scalar. */
371     if (execsize == 1 && width == 1) {
372         if (hstride != 0)
373 	    warn(ALL, location, "execution size and region width are 1 but "
374 		 "horizontal stride is %d (should be 0)\n", hstride);
375         if (vstride != 0)
376 	    warn(ALL, location, "execution size and region width are 1 but "
377 		 "vertical stride is %d (should be 0)\n", vstride);
378     }
379 
380     return true;
381 }
382 
get_subreg_address(unsigned regfile,unsigned type,unsigned subreg,unsigned address_mode)383 static int get_subreg_address(unsigned regfile, unsigned type, unsigned subreg, unsigned address_mode)
384 {
385     int unit_size = 1;
386 
387     assert(address_mode == BRW_ADDRESS_DIRECT);
388     assert(regfile != BRW_IMMEDIATE_VALUE);
389 
390     if (advanced_flag)
391 	unit_size = get_type_size(type);
392 
393     return subreg * unit_size;
394 }
395 
396 /* only used in indirect address mode.
397  * input: sub-register number of an address register
398  * output: the value of AddrSubRegNum in the instruction binary code
399  *
400  * input  output(advanced_flag==0)  output(advanced_flag==1)
401  *  a0.0             0                         0
402  *  a0.1        invalid input                  1
403  *  a0.2             1                         2
404  *  a0.3        invalid input                  3
405  *  a0.4             2                         4
406  *  a0.5        invalid input                  5
407  *  a0.6             3                         6
408  *  a0.7        invalid input                  7
409  *  a0.8             4                  invalid input
410  *  a0.10            5                  invalid input
411  *  a0.12            6                  invalid input
412  *  a0.14            7                  invalid input
413  */
get_indirect_subreg_address(unsigned subreg)414 static int get_indirect_subreg_address(unsigned subreg)
415 {
416     return advanced_flag == 0 ? subreg / 2 : subreg;
417 }
418 
resolve_subnr(struct brw_reg * reg)419 static void resolve_subnr(struct brw_reg *reg)
420 {
421    if (reg->file == BRW_IMMEDIATE_VALUE)
422 	return;
423 
424    if (reg->address_mode == BRW_ADDRESS_DIRECT)
425 	reg->subnr = get_subreg_address(reg->file, reg->type, reg->subnr,
426 					reg->address_mode);
427    else
428         reg->subnr = get_indirect_subreg_address(reg->subnr);
429 }
430 
431 
432 %}
433 %locations
434 
435 %start ROOT
436 
437 %union {
438 	char *string;
439 	int integer;
440 	double number;
441 	struct brw_program_instruction instruction;
442 	struct brw_program program;
443 	struct region region;
444 	struct regtype regtype;
445 	struct brw_reg reg;
446 	struct condition condition;
447 	struct predicate predicate;
448 	struct options options;
449 	struct declared_register symbol_reg;
450 	imm32_t imm32;
451 
452 	struct src_operand src_operand;
453 }
454 
455 %token COLON
456 %token SEMICOLON
457 %token LPAREN RPAREN
458 %token LANGLE RANGLE
459 %token LCURLY RCURLY
460 %token LSQUARE RSQUARE
461 %token COMMA EQ
462 %token ABS DOT
463 %token PLUS MINUS MULTIPLY DIVIDE
464 
465 %token <integer> TYPE_UD TYPE_D TYPE_UW TYPE_W TYPE_UB TYPE_B
466 %token <integer> TYPE_VF TYPE_HF TYPE_V TYPE_F
467 
468 %token ALIGN1 ALIGN16 SECHALF COMPR SWITCH ATOMIC NODDCHK NODDCLR
469 %token MASK_DISABLE BREAKPOINT ACCWRCTRL EOT
470 
471 %token SEQ ANY2H ALL2H ANY4H ALL4H ANY8H ALL8H ANY16H ALL16H ANYV ALLV
472 %token <integer> ZERO EQUAL NOT_ZERO NOT_EQUAL GREATER GREATER_EQUAL LESS LESS_EQUAL
473 %token <integer> ROUND_INCREMENT OVERFLOW UNORDERED
474 %token <integer> GENREG MSGREG ADDRESSREG ACCREG FLAGREG
475 %token <integer> MASKREG AMASK IMASK LMASK CMASK
476 %token <integer> MASKSTACKREG LMS IMS MASKSTACKDEPTHREG IMSD LMSD
477 %token <integer> NOTIFYREG STATEREG CONTROLREG IPREG
478 %token GENREGFILE MSGREGFILE
479 
480 %token <integer> MOV FRC RNDU RNDD RNDE RNDZ NOT LZD
481 %token <integer> MUL MAC MACH LINE SAD2 SADA2 DP4 DPH DP3 DP2
482 %token <integer> AVG ADD SEL AND OR XOR SHR SHL ASR CMP CMPN PLN
483 %token <integer> ADDC BFI1 BFREV CBIT F16TO32 F32TO16 FBH FBL
484 %token <integer> SEND SENDC NOP JMPI IF IFF WHILE ELSE BREAK CONT HALT MSAVE
485 %token <integer> PUSH MREST POP WAIT DO ENDIF ILLEGAL
486 %token <integer> MATH_INST
487 %token <integer> MAD LRP BFE BFI2 SUBB
488 %token <integer> CALL RET
489 %token <integer> BRD BRC
490 
491 %token NULL_TOKEN MATH SAMPLER GATEWAY READ WRITE URB THREAD_SPAWNER VME DATA_PORT CRE
492 
493 %token MSGLEN RETURNLEN
494 %token <integer> ALLOCATE USED COMPLETE TRANSPOSE INTERLEAVE
495 %token SATURATE
496 
497 %token <integer> INTEGER
498 %token <string> STRING
499 %token <number> NUMBER
500 
501 %token <integer> INV LOG EXP SQRT RSQ POW SIN COS SINCOS INTDIV INTMOD
502 %token <integer> INTDIVMOD
503 %token SIGNED SCALAR
504 
505 %token <integer> X Y Z W
506 
507 %token <integer> KERNEL_PRAGMA END_KERNEL_PRAGMA CODE_PRAGMA END_CODE_PRAGMA
508 %token <integer> REG_COUNT_PAYLOAD_PRAGMA REG_COUNT_TOTAL_PRAGMA DECLARE_PRAGMA
509 %token <integer> BASE ELEMENTSIZE SRCREGION DSTREGION TYPE
510 
511 %token <integer> DEFAULT_EXEC_SIZE_PRAGMA DEFAULT_REG_TYPE_PRAGMA
512 %precedence SUBREGNUM
513 %precedence SNDOPR
514 %left  PLUS MINUS
515 %left  MULTIPLY DIVIDE
516 %precedence UMINUS
517 %precedence DOT
518 %precedence STR_SYMBOL_REG
519 %precedence EMPTEXECSIZE
520 %precedence LPAREN
521 
522 %type <integer> exp sndopr
523 %type <integer> simple_int
524 %type <instruction> instruction unaryinstruction binaryinstruction
525 %type <instruction> binaryaccinstruction trinaryinstruction sendinstruction
526 %type <instruction> syncinstruction
527 %type <instruction> msgtarget
528 %type <instruction> mathinstruction
529 %type <instruction> nopinstruction
530 %type <instruction> relocatableinstruction breakinstruction
531 %type <instruction> ifelseinstruction loopinstruction haltinstruction
532 %type <instruction> multibranchinstruction subroutineinstruction jumpinstruction
533 %type <string> label
534 %type <program> instrseq
535 %type <integer> instoption
536 %type <integer> unaryop binaryop binaryaccop breakop
537 %type <integer> trinaryop
538 %type <integer> sendop
539 %type <condition> conditionalmodifier
540 %type <predicate> predicate
541 %type <options> instoptions instoption_list
542 %type <integer> condition saturate negate abs chansel
543 %type <integer> writemask_x writemask_y writemask_z writemask_w
544 %type <integer> srcimmtype execsize dstregion immaddroffset
545 %type <integer> subregnum sampler_datatype
546 %type <integer> urb_swizzle urb_allocate urb_used urb_complete
547 %type <integer> math_function math_signed math_scalar
548 %type <integer> predctrl predstate
549 %type <region> region region_wh indirectregion declare_srcregion;
550 %type <regtype> regtype
551 %type <reg> directgenreg directmsgreg addrreg accreg flagreg maskreg
552 %type <reg> maskstackreg notifyreg
553 /* %type <reg>  maskstackdepthreg */
554 %type <reg> statereg controlreg ipreg nullreg
555 %type <reg> dstoperandex_typed srcarchoperandex_typed
556 %type <reg> sendleadreg
557 %type <reg> indirectgenreg indirectmsgreg addrparam
558 %type <integer> mask_subreg maskstack_subreg
559 %type <integer> declare_elementsize declare_dstregion declare_type
560 /* %type <intger> maskstackdepth_subreg */
561 %type <symbol_reg> symbol_reg symbol_reg_p;
562 %type <imm32> imm32
563 %type <reg> dst dstoperand dstoperandex dstreg post_dst writemask
564 %type <reg> declare_base
565 %type <src_operand> directsrcoperand srcarchoperandex directsrcaccoperand
566 %type <src_operand> indirectsrcoperand
567 %type <src_operand> src srcimm imm32reg payload srcacc srcaccimm swizzle
568 %type <src_operand> relativelocation relativelocation2
569 
570 %code {
571 
572 #undef error
573 #define error(l, fmt, ...)			\
574     do {					\
575 	message(ERROR, l, fmt, ## __VA_ARGS__);	\
576 	YYERROR;				\
577     } while(0)
578 
add_option(struct options * options,int option)579 static void add_option(struct options *options, int option)
580 {
581     switch (option) {
582     case ALIGN1:
583 	options->access_mode = BRW_ALIGN_1;
584 	break;
585     case ALIGN16:
586 	options->access_mode = BRW_ALIGN_16;
587 	break;
588     case SECHALF:
589 	options->compression_control |= BRW_COMPRESSION_2NDHALF;
590 	break;
591     case COMPR:
592 	if (!IS_GENp(6))
593 	    options->compression_control |= BRW_COMPRESSION_COMPRESSED;
594 	break;
595     case SWITCH:
596 	options->thread_control |= BRW_THREAD_SWITCH;
597 	break;
598     case ATOMIC:
599 	options->thread_control |= BRW_THREAD_ATOMIC;
600 	break;
601     case NODDCHK:
602 	options->dependency_control |= BRW_DEPENDENCY_NOTCHECKED;
603 	break;
604     case NODDCLR:
605 	options->dependency_control |= BRW_DEPENDENCY_NOTCLEARED;
606 	break;
607     case MASK_DISABLE:
608 	options->mask_control = BRW_MASK_DISABLE;
609 	break;
610     case BREAKPOINT:
611 	options->debug_control = BRW_DEBUG_BREAKPOINT;
612 	break;
613     case ACCWRCTRL:
614 	options->acc_wr_control = BRW_ACCUMULATOR_WRITE_ENABLE;
615 	break;
616     case EOT:
617 	options->end_of_thread = 1;
618 	break;
619     }
620 }
621 
622 }
623 
624 %%
625 simple_int:     INTEGER { $$ = $1; }
626 		| MINUS INTEGER { $$ = -$2;}
627 ;
628 
629 exp:		INTEGER { $$ = $1; }
630 		| exp PLUS exp { $$ = $1 + $3; }
631 		| exp MINUS exp { $$ = $1 - $3; }
632 		| exp MULTIPLY exp { $$ = $1 * $3; }
633 		| exp DIVIDE exp { if ($3) $$ = $1 / $3; else YYERROR;}
634 		| MINUS exp %prec UMINUS { $$ = -$2;}
635 		| LPAREN exp RPAREN { $$ = $2; }
636 		;
637 
638 ROOT:		instrseq
639 		{
640 		  compiled_program = $1;
641 		}
642 ;
643 
644 
645 label:          STRING COLON
646 ;
647 
648 declare_base:  	BASE EQ dstreg
649 	       	{
650 		   $$ = $3;
651 	       	}
652 ;
653 declare_elementsize:  ELEMENTSIZE EQ exp
654 		{
655 		   $$ = $3;
656 		}
657 ;
658 declare_srcregion: %empty /* empty */
659 		{
660 		  /* XXX is this default correct?*/
661 		  memset (&$$, '\0', sizeof ($$));
662 		  $$.vert_stride = ffs(0);
663 		  $$.width = BRW_WIDTH_1;
664 		  $$.horiz_stride = ffs(0);
665 		}
666 		| SRCREGION EQ region
667 		{
668 		    $$ = $3;
669 		}
670 ;
671 declare_dstregion: %empty /* empty */
672 		{
673 		    $$ = 1;
674 		}
675 		| DSTREGION EQ dstregion
676 		{
677 		    $$ = $3;
678 		}
679 ;
680 declare_type:	TYPE EQ regtype
681 		{
682 		    $$ = $3.type;
683 		}
684 ;
685 declare_pragma:	DECLARE_PRAGMA STRING declare_base declare_elementsize declare_srcregion declare_dstregion declare_type
686 		{
687 		    struct declared_register reg, *found, *new_reg;
688 
689 		    reg.name = $2;
690 		    reg.reg = $3;
691 		    reg.element_size = $4;
692 		    reg.src_region = $5;
693 		    reg.dst_region = $6;
694 		    reg.reg.type = $7;
695 
696 		    found = find_register($2);
697 		    if (found) {
698 		        if (!declared_register_equal(&reg, found))
699 			    error(&@1, "%s already defined and definitions "
700 				  "don't agree\n", $2);
701 			free($2); // $2 has been malloc'ed by strdup
702 		    } else {
703 			new_reg = malloc(sizeof(struct declared_register));
704 			*new_reg = reg;
705 			insert_register(new_reg);
706 		    }
707 		}
708 ;
709 
710 reg_count_total_pragma: 	REG_COUNT_TOTAL_PRAGMA exp
711 ;
712 reg_count_payload_pragma: 	REG_COUNT_PAYLOAD_PRAGMA exp
713 ;
714 
715 default_exec_size_pragma:	DEFAULT_EXEC_SIZE_PRAGMA exp
716 				{
717 				    program_defaults.execute_size = $2;
718 				}
719 ;
720 default_reg_type_pragma:	DEFAULT_REG_TYPE_PRAGMA regtype
721 				{
722 				    program_defaults.register_type = $2.type;
723 				}
724 ;
725 pragma:		reg_count_total_pragma
726 		|reg_count_payload_pragma
727 		|default_exec_size_pragma
728 		|default_reg_type_pragma
729 		|declare_pragma
730 ;
731 
732 instrseq:	instrseq pragma
733 		{
734 		    $$ = $1;
735 		}
736 		| instrseq instruction SEMICOLON
737 		{
738 		  brw_program_add_instruction(&$1, &$2);
739 		  $$ = $1;
740 		}
741 		| instruction SEMICOLON
742 		{
743 		  brw_program_init(&$$);
744 		  brw_program_add_instruction(&$$, &$1);
745 		}
746 		| instrseq relocatableinstruction SEMICOLON
747 		{
748 		  brw_program_add_relocatable(&$1, &$2);
749 		  $$ = $1;
750 		}
751 		| relocatableinstruction SEMICOLON
752 		{
753 		  brw_program_init(&$$);
754 		  brw_program_add_relocatable(&$$, &$1);
755 		}
756 		| instrseq SEMICOLON
757 		{
758 		    $$ = $1;
759 		}
760 		| instrseq label
761         	{
762 		  brw_program_add_label(&$1, $2);
763 		  $$ = $1;
764                 }
765 		| label
766 		{
767 		  brw_program_init(&$$);
768 		  brw_program_add_label(&$$, $1);
769 		}
770 		| pragma
771 		{
772 		  $$.first = NULL;
773 		  $$.last = NULL;
774 		}
775 		| instrseq error SEMICOLON {
776 		  $$ = $1;
777 		}
778 ;
779 
780 /* 1.4.1: Instruction groups */
781 // binaryinstruction:    Source operands cannot be accumulators
782 // binaryaccinstruction: Source operands can be accumulators
783 instruction:	unaryinstruction
784 		| binaryinstruction
785 		| binaryaccinstruction
786 		| trinaryinstruction
787 		| sendinstruction
788 		| syncinstruction
789 		| mathinstruction
790 		| nopinstruction
791 ;
792 
793 /* relocatableinstruction are instructions that needs a relocation pass */
794 relocatableinstruction:	ifelseinstruction
795 			| loopinstruction
796 			| haltinstruction
797 			| multibranchinstruction
798 			| subroutineinstruction
799 			| jumpinstruction
800 			| breakinstruction
801 ;
802 
803 ifelseinstruction: ENDIF
804 		{
805 		  // for Gen4
806 		  if(IS_GENp(6)) // For gen6+.
807 		    error(&@1, "should be 'ENDIF execsize relativelocation'\n");
808 		  memset(&$$, 0, sizeof($$));
809 		  set_instruction_opcode(&$$, $1);
810 		  GEN(&$$)->header.thread_control |= BRW_THREAD_SWITCH;
811 		  GEN(&$$)->bits1.da1.dest_horiz_stride = 1;
812 		  GEN(&$$)->bits1.da1.src1_reg_file = BRW_ARCHITECTURE_REGISTER_FILE;
813 		  GEN(&$$)->bits1.da1.src1_reg_type = BRW_REGISTER_TYPE_UD;
814 		}
815 		| ENDIF execsize relativelocation instoptions
816 		{
817 		  // for Gen6+
818 		  /* Gen6, Gen7 bspec: predication is prohibited */
819 		  if(!IS_GENp(6)) // for gen6-
820 		    error(&@1, "ENDIF Syntax error: should be 'ENDIF'\n");
821 		  memset(&$$, 0, sizeof($$));
822 		  set_instruction_opcode(&$$, $1);
823 		  set_execsize(&$$, $2);
824 		  $$.reloc.first_reloc_target = $3.reloc_target;
825 		  $$.reloc.first_reloc_offset = $3.imm32;
826 		}
827 		| ELSE execsize relativelocation instoptions
828 		{
829 		  if(!IS_GENp(6)) {
830 		    // for Gen4, Gen5. gen_level < 60
831 		    /* Set the istack pop count, which must always be 1. */
832 		    $3.imm32 |= (1 << 16);
833 
834 		    memset(&$$, 0, sizeof($$));
835 		    set_instruction_opcode(&$$, $1);
836 		    GEN(&$$)->header.thread_control |= BRW_THREAD_SWITCH;
837 		    ip_dst.width = $2;
838 		    set_instruction_dest(&$$, &ip_dst);
839 		    set_instruction_src0(&$$, &ip_src, NULL);
840 		    set_instruction_src1(&$$, &$3, NULL);
841 		    $$.reloc.first_reloc_target = $3.reloc_target;
842 		    $$.reloc.first_reloc_offset = $3.imm32;
843 		  } else if(IS_GENp(6)) {
844 		    memset(&$$, 0, sizeof($$));
845 		    set_instruction_opcode(&$$, $1);
846 		    set_execsize(&$$, $2);
847 		    $$.reloc.first_reloc_target = $3.reloc_target;
848 		    $$.reloc.first_reloc_offset = $3.imm32;
849 		  } else {
850 		    error(&@1, "'ELSE' instruction is not implemented.\n");
851 		  }
852 		}
853 		| predicate IF execsize relativelocation
854 		{
855 		  /* The branch instructions require that the IP register
856 		   * be the destination and first source operand, while the
857 		   * offset is the second source operand.  The offset is added
858 		   * to the pre-incremented IP.
859 		   */
860 		  if(IS_GENp(7)) /* Error in Gen7+. */
861 		    error(&@2, "IF should be 'IF execsize JIP UIP'\n");
862 
863 		  memset(&$$, 0, sizeof($$));
864 		  set_instruction_predicate(&$$, &$1);
865 		  set_instruction_opcode(&$$, $2);
866 		  if(!IS_GENp(6)) {
867 		    GEN(&$$)->header.thread_control |= BRW_THREAD_SWITCH;
868 		    ip_dst.width = $3;
869 		    set_instruction_dest(&$$, &ip_dst);
870 		    set_instruction_src0(&$$, &ip_src, NULL);
871 		    set_instruction_src1(&$$, &$4, NULL);
872 		  }
873 		  $$.reloc.first_reloc_target = $4.reloc_target;
874 		  $$.reloc.first_reloc_offset = $4.imm32;
875 		}
876 		| predicate IF execsize relativelocation relativelocation
877 		{
878 		  /* for Gen7+ */
879 		  if(!IS_GENp(7))
880 		    error(&@2, "IF should be 'IF execsize relativelocation'\n");
881 
882 		  memset(&$$, 0, sizeof($$));
883 		  set_instruction_predicate(&$$, &$1);
884 		  set_instruction_opcode(&$$, $2);
885 		  set_execsize(&$$, $3);
886 		  $$.reloc.first_reloc_target = $4.reloc_target;
887 		  $$.reloc.first_reloc_offset = $4.imm32;
888 		  $$.reloc.second_reloc_target = $5.reloc_target;
889 		  $$.reloc.second_reloc_offset = $5.imm32;
890 		}
891 ;
892 
893 loopinstruction: predicate WHILE execsize relativelocation instoptions
894 		{
895 		  if(!IS_GENp(6)) {
896 		    /* The branch instructions require that the IP register
897 		     * be the destination and first source operand, while the
898 		     * offset is the second source operand.  The offset is added
899 		     * to the pre-incremented IP.
900 		     */
901 		    ip_dst.width = $3;
902 		    set_instruction_dest(&$$, &ip_dst);
903 		    memset(&$$, 0, sizeof($$));
904 		    set_instruction_predicate(&$$, &$1);
905 		    set_instruction_opcode(&$$, $2);
906 		    GEN(&$$)->header.thread_control |= BRW_THREAD_SWITCH;
907 		    set_instruction_src0(&$$, &ip_src, NULL);
908 		    set_instruction_src1(&$$, &$4, NULL);
909 		    $$.reloc.first_reloc_target = $4.reloc_target;
910 		    $$.reloc.first_reloc_offset = $4.imm32;
911 		  } else if (IS_GENp(6)) {
912 		    /* Gen6 spec:
913 		         dest must have the same element size as src0.
914 		         dest horizontal stride must be 1. */
915 		    memset(&$$, 0, sizeof($$));
916 		    set_instruction_predicate(&$$, &$1);
917 		    set_instruction_opcode(&$$, $2);
918 		    set_execsize(&$$, $3);
919 		    $$.reloc.first_reloc_target = $4.reloc_target;
920 		    $$.reloc.first_reloc_offset = $4.imm32;
921 		  } else {
922 		    error(&@2, "'WHILE' instruction is not implemented!\n");
923 		  }
924 		}
925 		| DO
926 		{
927 		  // deprecated
928 		  memset(&$$, 0, sizeof($$));
929 		  set_instruction_opcode(&$$, $1);
930 		};
931 
932 haltinstruction: predicate HALT execsize relativelocation relativelocation instoptions
933 		{
934 		  // for Gen6, Gen7
935 		  /* Gen6, Gen7 bspec: dst and src0 must be the null reg. */
936 		  memset(&$$, 0, sizeof($$));
937 		  set_instruction_predicate(&$$, &$1);
938 		  set_instruction_opcode(&$$, $2);
939 		  $$.reloc.first_reloc_target = $4.reloc_target;
940 		  $$.reloc.first_reloc_offset = $4.imm32;
941 		  $$.reloc.second_reloc_target = $5.reloc_target;
942 		  $$.reloc.second_reloc_offset = $5.imm32;
943 		  dst_null_reg.width = $3;
944 		  set_instruction_dest(&$$, &dst_null_reg);
945 		  set_instruction_src0(&$$, &src_null_reg, NULL);
946 		};
947 
948 multibranchinstruction:
949 		predicate BRD execsize relativelocation instoptions
950 		{
951 		  /* Gen7 bspec: dest must be null. use Switch option */
952 		  memset(&$$, 0, sizeof($$));
953 		  set_instruction_predicate(&$$, &$1);
954 		  set_instruction_opcode(&$$, $2);
955 		  if (IS_GENp(8))
956                       gen8_set_thread_control(GEN8(&$$), gen8_thread_control(GEN8(&$$)) | BRW_THREAD_SWITCH);
957 		  else
958                       GEN(&$$)->header.thread_control |= BRW_THREAD_SWITCH;
959 		  $$.reloc.first_reloc_target = $4.reloc_target;
960 		  $$.reloc.first_reloc_offset = $4.imm32;
961 		  dst_null_reg.width = $3;
962 		  set_instruction_dest(&$$, &dst_null_reg);
963 		}
964 		| predicate BRC execsize relativelocation relativelocation instoptions
965 		{
966 		  /* Gen7 bspec: dest must be null. src0 must be null. use Switch option */
967 		  memset(&$$, 0, sizeof($$));
968 		  set_instruction_predicate(&$$, &$1);
969 		  set_instruction_opcode(&$$, $2);
970 		  if (IS_GENp(8))
971                       gen8_set_thread_control(GEN8(&$$), gen8_thread_control(GEN8(&$$)) | BRW_THREAD_SWITCH);
972 		  else
973                       GEN(&$$)->header.thread_control |= BRW_THREAD_SWITCH;
974 		  $$.reloc.first_reloc_target = $4.reloc_target;
975 		  $$.reloc.first_reloc_offset = $4.imm32;
976 		  $$.reloc.second_reloc_target = $5.reloc_target;
977 		  $$.reloc.second_reloc_offset = $5.imm32;
978 		  dst_null_reg.width = $3;
979 		  set_instruction_dest(&$$, &dst_null_reg);
980 		  set_instruction_src0(&$$, &src_null_reg, NULL);
981 		}
982 ;
983 
984 subroutineinstruction:
985 		predicate CALL execsize dst relativelocation instoptions
986 		{
987 		  /*
988 		    Gen6 bspec:
989 		       source, dest type should be DWORD.
990 		       dest must be QWord aligned.
991 		       source0 region control must be <2,2,1>.
992 		       execution size must be 2.
993 		       QtrCtrl is prohibited.
994 		       JIP is an immediate operand, must be of type W.
995 		    Gen7 bspec:
996 		       source, dest type should be DWORD.
997 		       dest must be QWord aligned.
998 		       source0 region control must be <2,2,1>.
999 		       execution size must be 2.
1000 		   */
1001 		  memset(&$$, 0, sizeof($$));
1002 		  set_instruction_predicate(&$$, &$1);
1003 		  set_instruction_opcode(&$$, $2);
1004 
1005 		  $4.type = BRW_REGISTER_TYPE_D; /* dest type should be DWORD */
1006 		  $4.width = BRW_WIDTH_2; /* execution size must be 2. */
1007 		  set_instruction_dest(&$$, &$4);
1008 
1009 		  struct src_operand src0;
1010 		  memset(&src0, 0, sizeof(src0));
1011 		  src0.reg.type = BRW_REGISTER_TYPE_D; /* source type should be DWORD */
1012 		  /* source0 region control must be <2,2,1>. */
1013 		  src0.reg.hstride = 1; /*encoded 1*/
1014 		  src0.reg.width = BRW_WIDTH_2;
1015 		  src0.reg.vstride = 2; /*encoded 2*/
1016 		  set_instruction_src0(&$$, &src0, NULL);
1017 
1018 		  $$.reloc.first_reloc_target = $5.reloc_target;
1019 		  $$.reloc.first_reloc_offset = $5.imm32;
1020 		}
1021 		| predicate RET execsize dstoperandex src instoptions
1022 		{
1023 		  /*
1024 		     Gen6, 7:
1025 		       source cannot be accumulator.
1026 		       dest must be null.
1027 		       src0 region control must be <2,2,1> (not specified clearly. should be same as CALL)
1028 		   */
1029 		  memset(&$$, 0, sizeof($$));
1030 		  set_instruction_predicate(&$$, &$1);
1031 		  set_instruction_opcode(&$$, $2);
1032 		  dst_null_reg.width = BRW_WIDTH_2; /* execution size of RET should be 2 */
1033 		  set_instruction_dest(&$$, &dst_null_reg);
1034 		  $5.reg.type = BRW_REGISTER_TYPE_D;
1035 		  $5.reg.hstride = 1; /*encoded 1*/
1036 		  $5.reg.width = BRW_WIDTH_2;
1037 		  $5.reg.vstride = 2; /*encoded 2*/
1038 		  set_instruction_src0(&$$, &$5, NULL);
1039 		}
1040 ;
1041 
1042 unaryinstruction:
1043 		predicate unaryop conditionalmodifier saturate execsize
1044 		dst srcaccimm instoptions
1045 		{
1046 		  memset(&$$, 0, sizeof($$));
1047 		  set_instruction_opcode(&$$, $2);
1048 		  set_instruction_saturate(&$$, $4);
1049 		  $6.width = $5;
1050 		  set_instruction_options(&$$, $8);
1051 		  set_instruction_pred_cond(&$$, &$1, &$3, &@3);
1052 		  if (set_instruction_dest(&$$, &$6) != 0)
1053 		    YYERROR;
1054 		  if (set_instruction_src0(&$$, &$7, &@7) != 0)
1055 		    YYERROR;
1056 
1057 		  if (!IS_GENp(6) &&
1058 				get_type_size(GEN(&$$)->bits1.da1.dest_reg_type) * (1 << $6.width) == 64)
1059 		    GEN(&$$)->header.compression_control = BRW_COMPRESSION_COMPRESSED;
1060 		}
1061 ;
1062 
1063 unaryop:	MOV | FRC | RNDU | RNDD | RNDE | RNDZ | NOT | LZD | BFREV | CBIT
1064           | F16TO32 | F32TO16 | FBH | FBL
1065 ;
1066 
1067 // Source operands cannot be accumulators
1068 binaryinstruction:
1069 		predicate binaryop conditionalmodifier saturate execsize
1070 		dst src srcimm instoptions
1071 		{
1072 		  memset(&$$, 0, sizeof($$));
1073 		  set_instruction_opcode(&$$, $2);
1074 		  set_instruction_saturate(&$$, $4);
1075 		  set_instruction_options(&$$, $9);
1076 		  set_instruction_pred_cond(&$$, &$1, &$3, &@3);
1077 		  $6.width = $5;
1078 		  if (set_instruction_dest(&$$, &$6) != 0)
1079 		    YYERROR;
1080 		  if (set_instruction_src0(&$$, &$7, &@7) != 0)
1081 		    YYERROR;
1082 		  if (set_instruction_src1(&$$, &$8, &@8) != 0)
1083 		    YYERROR;
1084 
1085 		  if (!IS_GENp(6) &&
1086 				get_type_size(GEN(&$$)->bits1.da1.dest_reg_type) * (1 << $6.width) == 64)
1087 		    GEN(&$$)->header.compression_control = BRW_COMPRESSION_COMPRESSED;
1088 		}
1089 ;
1090 
1091 /* bspec: BFI1 should not access accumulator. */
1092 binaryop:	MUL | MAC | MACH | LINE | SAD2 | SADA2 | DP4 | DPH | DP3 | DP2 | PLN | BFI1
1093 ;
1094 
1095 // Source operands can be accumulators
1096 binaryaccinstruction:
1097 		predicate binaryaccop conditionalmodifier saturate execsize
1098 		dst srcacc srcimm instoptions
1099 		{
1100 		  memset(&$$, 0, sizeof($$));
1101 		  set_instruction_opcode(&$$, $2);
1102 		  set_instruction_saturate(&$$, $4);
1103 		  $6.width = $5;
1104 		  set_instruction_options(&$$, $9);
1105 		  set_instruction_pred_cond(&$$, &$1, &$3, &@3);
1106 		  if (set_instruction_dest(&$$, &$6) != 0)
1107 		    YYERROR;
1108 		  if (set_instruction_src0(&$$, &$7, &@7) != 0)
1109 		    YYERROR;
1110 		  if (set_instruction_src1(&$$, &$8, &@8) != 0)
1111 		    YYERROR;
1112 
1113 		  if (!IS_GENp(6) &&
1114 				get_type_size(GEN(&$$)->bits1.da1.dest_reg_type) * (1 << $6.width) == 64)
1115 		    GEN(&$$)->header.compression_control = BRW_COMPRESSION_COMPRESSED;
1116 		}
1117 ;
1118 
1119 /* TODO: bspec says ADDC/SUBB/CMP/CMPN/SHL/BFI1 cannot use accumulator as dest. */
1120 binaryaccop:	AVG | ADD | SEL | AND | OR | XOR | SHR | SHL | ASR | CMP | CMPN | ADDC | SUBB
1121 ;
1122 
1123 trinaryop:	MAD | LRP | BFE | BFI2
1124 ;
1125 
1126 trinaryinstruction:
1127 		predicate trinaryop conditionalmodifier saturate execsize
1128 		dst src src src instoptions
1129 {
1130 		  memset(&$$, 0, sizeof($$));
1131 
1132 		  set_instruction_pred_cond(&$$, &$1, &$3, &@3);
1133 
1134 		  set_instruction_opcode(&$$, $2);
1135 		  set_instruction_saturate(&$$, $4);
1136 		  set_instruction_options(&$$, $10);
1137 
1138 		  $6.width = $5;
1139 		  if (set_instruction_dest_three_src(&$$, &$6))
1140 		    YYERROR;
1141 		  if (set_instruction_src0_three_src(&$$, &$7))
1142 		    YYERROR;
1143 		  if (set_instruction_src1_three_src(&$$, &$8))
1144 		    YYERROR;
1145 		  if (set_instruction_src2_three_src(&$$, &$9))
1146 		    YYERROR;
1147 }
1148 ;
1149 
1150 sendop:		SEND | SENDC
1151 ;
1152 
1153 sendinstruction: predicate sendop execsize exp post_dst payload msgtarget
1154 		MSGLEN exp RETURNLEN exp instoptions
1155 		{
1156 		  /* Send instructions are messy.  The first argument is the
1157 		   * post destination -- the grf register that the response
1158 		   * starts from.  The second argument is the current
1159 		   * destination, which is the start of the message arguments
1160 		   * to the shared function, and where src0 payload is loaded
1161 		   * to if not null.  The payload is typically based on the
1162 		   * grf 0 thread payload of your current thread, and is
1163 		   * implicitly loaded if non-null.
1164 		   */
1165 		  memset(&$$, 0, sizeof($$));
1166 		  set_instruction_opcode(&$$, $2);
1167 		  $5.width = $3;
1168 		  GEN(&$$)->header.destreg__conditionalmod = $4; /* msg reg index */
1169 		  set_instruction_predicate(&$$, &$1);
1170 		  if (set_instruction_dest(&$$, &$5) != 0)
1171 		    YYERROR;
1172 
1173 		  if (IS_GENp(6)) {
1174                       struct src_operand src0;
1175 
1176                       memset(&src0, 0, sizeof(src0));
1177                       src0.reg.address_mode = BRW_ADDRESS_DIRECT;
1178 
1179                       if (IS_GENp(7))
1180                           src0.reg.file = BRW_GENERAL_REGISTER_FILE;
1181                       else
1182                           src0.reg.file = BRW_MESSAGE_REGISTER_FILE;
1183 
1184                       src0.reg.type = BRW_REGISTER_TYPE_D;
1185                       src0.reg.nr = $4;
1186                       src0.reg.subnr = 0;
1187                       set_instruction_src0(&$$, &src0, NULL);
1188 		  } else {
1189                       if (set_instruction_src0(&$$, &$6, &@6) != 0)
1190                           YYERROR;
1191 		  }
1192 
1193 		  if (IS_GENp(9)) {
1194 		      gen8_set_src1_reg_file(GEN8(&$$), BRW_IMMEDIATE_VALUE);
1195 		      gen8_set_src1_reg_type(GEN8(&$$), BRW_REGISTER_TYPE_D);
1196 		      gen9_set_send_extdesc(GEN8(&$$), 0);
1197 		  } else if (IS_GENp(8)) {
1198 		      gen8_set_src1_reg_file(GEN8(&$$), BRW_IMMEDIATE_VALUE);
1199 		      gen8_set_src1_reg_type(GEN8(&$$), BRW_REGISTER_TYPE_D);
1200 		  } else {
1201 		      GEN(&$$)->bits1.da1.src1_reg_file = BRW_IMMEDIATE_VALUE;
1202 		      GEN(&$$)->bits1.da1.src1_reg_type = BRW_REGISTER_TYPE_D;
1203 		  }
1204 
1205 		  if (IS_GENp(8)) {
1206 		      GEN8(&$$)->data[3] = GEN8(&$7)->data[3];
1207 		      gen8_set_sfid(GEN8(&$$), gen8_sfid(GEN8(&$7)));
1208 		      gen8_set_mlen(GEN8(&$$), $9);
1209 		      gen8_set_rlen(GEN8(&$$), $11);
1210 		      gen8_set_eot(GEN8(&$$), $12.end_of_thread);
1211 		  } else if (IS_GENp(5)) {
1212                       if (IS_GENp(6)) {
1213                           GEN(&$$)->header.destreg__conditionalmod = GEN(&$7)->bits2.send_gen5.sfid;
1214                       } else {
1215                           GEN(&$$)->header.destreg__conditionalmod = $4; /* msg reg index */
1216                           GEN(&$$)->bits2.send_gen5.sfid = GEN(&$7)->bits2.send_gen5.sfid;
1217                           GEN(&$$)->bits2.send_gen5.end_of_thread = $12.end_of_thread;
1218                       }
1219 
1220                       GEN(&$$)->bits3.generic_gen5 = GEN(&$7)->bits3.generic_gen5;
1221                       GEN(&$$)->bits3.generic_gen5.msg_length = $9;
1222                       GEN(&$$)->bits3.generic_gen5.response_length = $11;
1223                       GEN(&$$)->bits3.generic_gen5.end_of_thread = $12.end_of_thread;
1224 		  } else {
1225                       GEN(&$$)->header.destreg__conditionalmod = $4; /* msg reg index */
1226                       GEN(&$$)->bits3.generic = GEN(&$7)->bits3.generic;
1227                       GEN(&$$)->bits3.generic.msg_length = $9;
1228                       GEN(&$$)->bits3.generic.response_length = $11;
1229                       GEN(&$$)->bits3.generic.end_of_thread = $12.end_of_thread;
1230 		  }
1231 		}
1232 		| predicate sendop execsize dst sendleadreg payload directsrcoperand instoptions
1233 		{
1234 		  if (IS_GENp(6))
1235                       error(&@2, "invalid syntax for send on gen6+\n");
1236 
1237 		  memset(&$$, 0, sizeof($$));
1238 		  set_instruction_opcode(&$$, $2);
1239 		  GEN(&$$)->header.destreg__conditionalmod = $5.nr; /* msg reg index */
1240 
1241 		  set_instruction_predicate(&$$, &$1);
1242 
1243 		  $4.width = $3;
1244 		  if (set_instruction_dest(&$$, &$4) != 0)
1245 		    YYERROR;
1246 		  if (set_instruction_src0(&$$, &$6, &@6) != 0)
1247 		    YYERROR;
1248 		  /* XXX is this correct? */
1249 		  if (set_instruction_src1(&$$, &$7, &@7) != 0)
1250 		    YYERROR;
1251 
1252 		  }
1253 		| predicate sendop execsize dst sendleadreg payload imm32reg instoptions
1254                 {
1255 		  if (IS_GENp(6))
1256                       error(&@2, "invalid syntax for send on gen6+\n");
1257 
1258 		  if ($7.reg.type != BRW_REGISTER_TYPE_UD &&
1259 		      $7.reg.type != BRW_REGISTER_TYPE_D &&
1260 		      $7.reg.type != BRW_REGISTER_TYPE_V) {
1261 		    error (&@7, "non-int D/UD/V representation: %d,"
1262 			   "type=%d\n", $7.reg.dw1.ud, $7.reg.type);
1263 		  }
1264 		  memset(&$$, 0, sizeof($$));
1265 		  set_instruction_opcode(&$$, $2);
1266 		  GEN(&$$)->header.destreg__conditionalmod = $5.nr; /* msg reg index */
1267 
1268 		  set_instruction_predicate(&$$, &$1);
1269 		  $4.width = $3;
1270 		  if (set_instruction_dest(&$$, &$4) != 0)
1271 		    YYERROR;
1272 		  if (set_instruction_src0(&$$, &$6, &@6) != 0)
1273 		    YYERROR;
1274 		  if (set_instruction_src1(&$$, &$7, &@7) != 0)
1275 		    YYERROR;
1276                 }
1277 		| predicate sendop execsize dst sendleadreg sndopr imm32reg instoptions
1278 		{
1279 		  struct src_operand src0;
1280 
1281 		  if (!IS_GENp(6))
1282                       error(&@2, "invalid syntax for send on gen6+\n");
1283 
1284 		  if ($7.reg.type != BRW_REGISTER_TYPE_UD &&
1285                       $7.reg.type != BRW_REGISTER_TYPE_D &&
1286                       $7.reg.type != BRW_REGISTER_TYPE_V) {
1287                       error(&@7,"non-int D/UD/V representation: %d,"
1288 			    "type=%d\n", $7.reg.dw1.ud, $7.reg.type);
1289 		  }
1290 
1291 		  memset(&$$, 0, sizeof($$));
1292 		  set_instruction_opcode(&$$, $2);
1293 		  set_instruction_predicate(&$$, &$1);
1294 
1295 		  $4.width = $3;
1296 		  if (set_instruction_dest(&$$, &$4) != 0)
1297                       YYERROR;
1298 
1299                   memset(&src0, 0, sizeof(src0));
1300                   src0.reg.address_mode = BRW_ADDRESS_DIRECT;
1301 
1302                   if (IS_GENp(7)) {
1303                       src0.reg.file = BRW_GENERAL_REGISTER_FILE;
1304                       src0.reg.type = BRW_REGISTER_TYPE_UB;
1305                   } else {
1306                       src0.reg.file = BRW_MESSAGE_REGISTER_FILE;
1307                       src0.reg.type = BRW_REGISTER_TYPE_D;
1308                   }
1309 
1310                   src0.reg.nr = $5.nr;
1311                   src0.reg.subnr = 0;
1312                   set_instruction_src0(&$$, &src0, NULL);
1313 		  set_instruction_src1(&$$, &$7, NULL);
1314 
1315                   if (IS_GENp(9)) {
1316                       gen8_set_sfid(GEN8(&$$), $6 & EX_DESC_SFID_MASK);
1317                       gen8_set_eot(GEN8(&$$), !!($6 & EX_DESC_EOT_MASK));
1318                       gen9_set_send_extdesc(GEN8(&$$), $6 & EX_DESC_FUNC_MASK);
1319                   } else if (IS_GENp(8)) {
1320                       gen8_set_sfid(GEN8(&$$), $6 & EX_DESC_SFID_MASK);
1321                       gen8_set_eot(GEN8(&$$), !!($6 & EX_DESC_EOT_MASK));
1322 		  } else {
1323                       GEN(&$$)->header.destreg__conditionalmod = ($6 & EX_DESC_SFID_MASK); /* SFID */
1324                       GEN(&$$)->bits3.generic_gen5.end_of_thread = !!($6 & EX_DESC_EOT_MASK);
1325                   }
1326 		}
1327 		| predicate sendop execsize dst sendleadreg sndopr directsrcoperand instoptions
1328 		{
1329 		  struct src_operand src0;
1330 
1331 		  if (!IS_GENp(6))
1332                       error(&@2, "invalid syntax for send on gen6+\n");
1333 
1334                   if ($7.reg.file != BRW_ARCHITECTURE_REGISTER_FILE ||
1335                       ($7.reg.nr & 0xF0) != BRW_ARF_ADDRESS ||
1336                       ($7.reg.nr & 0x0F) != 0 ||
1337                       $7.reg.subnr != 0) {
1338                       error (&@7, "scalar register must be a0.0<0;1,0>:ud\n");
1339 		  }
1340 
1341 		  memset(&$$, 0, sizeof($$));
1342 		  set_instruction_opcode(&$$, $2);
1343 		  set_instruction_predicate(&$$, &$1);
1344 
1345 		  $4.width = $3;
1346 		  if (set_instruction_dest(&$$, &$4) != 0)
1347                       YYERROR;
1348 
1349                   memset(&src0, 0, sizeof(src0));
1350                   src0.reg.address_mode = BRW_ADDRESS_DIRECT;
1351 
1352                   if (IS_GENp(7)) {
1353                       src0.reg.file = BRW_GENERAL_REGISTER_FILE;
1354                       src0.reg.type = BRW_REGISTER_TYPE_UB;
1355                   } else {
1356                       src0.reg.file = BRW_MESSAGE_REGISTER_FILE;
1357                       src0.reg.type = BRW_REGISTER_TYPE_D;
1358                   }
1359 
1360                   src0.reg.nr = $5.nr;
1361                   src0.reg.subnr = 0;
1362                   set_instruction_src0(&$$, &src0, NULL);
1363 
1364                   set_instruction_src1(&$$, &$7, &@7);
1365 
1366                   if (IS_GENp(8)) {
1367                       gen8_set_sfid(GEN8(&$$), $6 & EX_DESC_SFID_MASK);
1368                       gen8_set_eot(GEN8(&$$), !!($6 & EX_DESC_EOT_MASK));
1369                       gen9_set_send_extdesc(GEN8(&$$), $6 & EX_DESC_FUNC_MASK);
1370 		  } else if (IS_GENp(8)) {
1371                       gen8_set_sfid(GEN8(&$$), $6 & EX_DESC_SFID_MASK);
1372                       gen8_set_eot(GEN8(&$$), !!($6 & EX_DESC_EOT_MASK));
1373 		  } else {
1374                       GEN(&$$)->header.destreg__conditionalmod = ($6 & EX_DESC_SFID_MASK); /* SFID */
1375                       GEN(&$$)->bits3.generic_gen5.end_of_thread = !!($6 & EX_DESC_EOT_MASK);
1376                   }
1377 		}
1378 		| predicate sendop execsize dst sendleadreg payload sndopr imm32reg instoptions
1379 		{
1380 		  if (IS_GENp(6))
1381                       error(&@2, "invalid syntax for send on gen6+\n");
1382 
1383 		  if ($8.reg.type != BRW_REGISTER_TYPE_UD &&
1384 		      $8.reg.type != BRW_REGISTER_TYPE_D &&
1385 		      $8.reg.type != BRW_REGISTER_TYPE_V) {
1386 		    error(&@8, "non-int D/UD/V representation: %d,"
1387 			  "type=%d\n", $8.reg.dw1.ud, $8.reg.type);
1388 		  }
1389 		  memset(&$$, 0, sizeof($$));
1390 		  set_instruction_opcode(&$$, $2);
1391 		  GEN(&$$)->header.destreg__conditionalmod = $5.nr; /* msg reg index */
1392 
1393 		  set_instruction_predicate(&$$, &$1);
1394 		  $4.width = $3;
1395 		  if (set_instruction_dest(&$$, &$4) != 0)
1396 		    YYERROR;
1397 		  if (set_instruction_src0(&$$, &$6, &@6) != 0)
1398 		    YYERROR;
1399 		  if (set_instruction_src1(&$$, &$8, &@8) != 0)
1400 		    YYERROR;
1401 
1402 		  if (IS_GENx(5)) {
1403 		      GEN(&$$)->bits2.send_gen5.sfid = ($7 & EX_DESC_SFID_MASK);
1404 		      GEN(&$$)->bits3.generic_gen5.end_of_thread = !!($7 & EX_DESC_EOT_MASK);
1405 		  }
1406 		}
1407 		| predicate sendop execsize dst sendleadreg payload exp directsrcoperand instoptions
1408 		{
1409 		  if (IS_GENp(6))
1410                       error(&@2, "invalid syntax for send on gen6+\n");
1411 
1412 		  memset(&$$, 0, sizeof($$));
1413 		  set_instruction_opcode(&$$, $2);
1414 		  GEN(&$$)->header.destreg__conditionalmod = $5.nr; /* msg reg index */
1415 
1416 		  set_instruction_predicate(&$$, &$1);
1417 
1418 		  $4.width = $3;
1419 		  if (set_instruction_dest(&$$, &$4) != 0)
1420 		    YYERROR;
1421 		  if (set_instruction_src0(&$$, &$6, &@6) != 0)
1422 		    YYERROR;
1423 		  /* XXX is this correct? */
1424 		  if (set_instruction_src1(&$$, &$8, &@8) != 0)
1425 		    YYERROR;
1426 		  if (IS_GENx(5)) {
1427                       GEN(&$$)->bits2.send_gen5.sfid = $7;
1428 		  }
1429 		}
1430 
1431 ;
1432 
1433 sndopr: exp %prec SNDOPR
1434 		{
1435 			$$ = $1;
1436 		}
1437 ;
1438 
1439 jumpinstruction: predicate JMPI execsize relativelocation2
1440 		{
1441 		  /* The jump instruction requires that the IP register
1442 		   * be the destination and first source operand, while the
1443 		   * offset is the second source operand.  The next instruction
1444 		   * is the post-incremented IP plus the offset.
1445 		   */
1446 		  memset(&$$, 0, sizeof($$));
1447 		  set_instruction_opcode(&$$, $2);
1448 		  if(advanced_flag) {
1449                       if (IS_GENp(8))
1450                           gen8_set_mask_control(GEN8(&$$), BRW_MASK_DISABLE);
1451                       else
1452                           GEN(&$$)->header.mask_control = BRW_MASK_DISABLE;
1453 		  }
1454 		  set_instruction_predicate(&$$, &$1);
1455 		  ip_dst.width = BRW_WIDTH_1;
1456 		  set_instruction_dest(&$$, &ip_dst);
1457 		  set_instruction_src0(&$$, &ip_src, NULL);
1458 		  set_instruction_src1(&$$, &$4, NULL);
1459 		  $$.reloc.first_reloc_target = $4.reloc_target;
1460 		  $$.reloc.first_reloc_offset = $4.imm32;
1461 		}
1462 ;
1463 
1464 mathinstruction: predicate MATH_INST execsize dst src srcimm math_function instoptions
1465 		{
1466 		  memset(&$$, 0, sizeof($$));
1467 		  set_instruction_opcode(&$$, $2);
1468 
1469 		  if (IS_GENp(8))
1470                       gen8_set_math_function(GEN8(&$$), $7);
1471 		  else
1472                       GEN(&$$)->header.destreg__conditionalmod = $7;
1473 
1474 		  set_instruction_options(&$$, $8);
1475 		  set_instruction_predicate(&$$, &$1);
1476 		  $4.width = $3;
1477 		  if (set_instruction_dest(&$$, &$4) != 0)
1478 		    YYERROR;
1479 		  if (set_instruction_src0(&$$, &$5, &@5) != 0)
1480 		    YYERROR;
1481 		  if (set_instruction_src1(&$$, &$6, &@6) != 0)
1482 		    YYERROR;
1483 		}
1484 ;
1485 
1486 breakinstruction: predicate breakop execsize relativelocation relativelocation instoptions
1487 		{
1488 		  // for Gen6, Gen7
1489 		  memset(&$$, 0, sizeof($$));
1490 		  set_instruction_predicate(&$$, &$1);
1491 		  set_instruction_opcode(&$$, $2);
1492 		  set_execsize(&$$, $3);
1493 		  $$.reloc.first_reloc_target = $4.reloc_target;
1494 		  $$.reloc.first_reloc_offset = $4.imm32;
1495 		  $$.reloc.second_reloc_target = $5.reloc_target;
1496 		  $$.reloc.second_reloc_offset = $5.imm32;
1497 		}
1498 ;
1499 
1500 breakop:	BREAK | CONT
1501 ;
1502 
1503 /*
1504 maskpushop:	MSAVE | PUSH
1505 ;
1506  */
1507 
1508 syncinstruction: predicate WAIT notifyreg
1509 		{
1510 		  struct brw_reg notify_dst;
1511 		  struct src_operand notify_src;
1512 
1513 		  memset(&$$, 0, sizeof($$));
1514 		  set_instruction_opcode(&$$, $2);
1515 		  set_direct_dst_operand(&notify_dst, &$3, BRW_REGISTER_TYPE_D);
1516 		  notify_dst.width = BRW_WIDTH_1;
1517 		  set_instruction_dest(&$$, &notify_dst);
1518 		  set_direct_src_operand(&notify_src, &$3, BRW_REGISTER_TYPE_D);
1519 		  set_instruction_src0(&$$, &notify_src, NULL);
1520 		  set_instruction_src1(&$$, &src_null_reg, NULL);
1521 		}
1522 
1523 ;
1524 
1525 nopinstruction: NOP
1526 		{
1527 		  memset(&$$, 0, sizeof($$));
1528 		  set_instruction_opcode(&$$, $1);
1529 		};
1530 
1531 /* XXX! */
1532 payload: directsrcoperand
1533 ;
1534 
1535 post_dst:	dst
1536 ;
1537 
1538 msgtarget:	NULL_TOKEN
1539 		{
1540 		  if (IS_GENp(8)) {
1541 		      gen8_set_sfid(GEN8(&$$), BRW_SFID_NULL);
1542 		      gen8_set_header_present(GEN8(&$$), 0);
1543 		  } else if (IS_GENp(5)) {
1544                       GEN(&$$)->bits2.send_gen5.sfid= BRW_SFID_NULL;
1545                       GEN(&$$)->bits3.generic_gen5.header_present = 0;  /* ??? */
1546 		  } else {
1547                       GEN(&$$)->bits3.generic.msg_target = BRW_SFID_NULL;
1548 		  }
1549 		}
1550 		| SAMPLER LPAREN INTEGER COMMA INTEGER COMMA
1551 		sampler_datatype RPAREN
1552 		{
1553 		  if (IS_GENp(8)) {
1554 		      gen8_set_sfid(GEN8(&$$), BRW_SFID_SAMPLER);
1555 		      gen8_set_header_present(GEN8(&$$), 1); /* ??? */
1556 		      gen8_set_binding_table_index(GEN8(&$$), $3);
1557 		      gen8_set_sampler(GEN8(&$$), $5);
1558 		      gen8_set_sampler_simd_mode(GEN8(&$$), 2); /* SIMD16 */
1559 		  } else if (IS_GENp(7)) {
1560                       GEN(&$$)->bits2.send_gen5.sfid = BRW_SFID_SAMPLER;
1561                       GEN(&$$)->bits3.generic_gen5.header_present = 1;   /* ??? */
1562                       GEN(&$$)->bits3.sampler_gen7.binding_table_index = $3;
1563                       GEN(&$$)->bits3.sampler_gen7.sampler = $5;
1564                       GEN(&$$)->bits3.sampler_gen7.simd_mode = 2; /* SIMD16, maybe we should add a new parameter */
1565 		  } else if (IS_GENp(5)) {
1566                       GEN(&$$)->bits2.send_gen5.sfid = BRW_SFID_SAMPLER;
1567                       GEN(&$$)->bits3.generic_gen5.header_present = 1;   /* ??? */
1568                       GEN(&$$)->bits3.sampler_gen5.binding_table_index = $3;
1569                       GEN(&$$)->bits3.sampler_gen5.sampler = $5;
1570                       GEN(&$$)->bits3.sampler_gen5.simd_mode = 2; /* SIMD16, maybe we should add a new parameter */
1571 		  } else {
1572                       GEN(&$$)->bits3.generic.msg_target = BRW_SFID_SAMPLER;
1573                       GEN(&$$)->bits3.sampler.binding_table_index = $3;
1574                       GEN(&$$)->bits3.sampler.sampler = $5;
1575                       switch ($7) {
1576                       case TYPE_F:
1577                           GEN(&$$)->bits3.sampler.return_format =
1578                               BRW_SAMPLER_RETURN_FORMAT_FLOAT32;
1579                           break;
1580                       case TYPE_UD:
1581                           GEN(&$$)->bits3.sampler.return_format =
1582                               BRW_SAMPLER_RETURN_FORMAT_UINT32;
1583                           break;
1584                       case TYPE_D:
1585                           GEN(&$$)->bits3.sampler.return_format =
1586                               BRW_SAMPLER_RETURN_FORMAT_SINT32;
1587                           break;
1588                       }
1589 		  }
1590 		}
1591 		| MATH math_function saturate math_signed math_scalar
1592 		{
1593 		  if (IS_GENp(6)) {
1594                       error (&@1, "Gen6+ doesn't have math function\n");
1595 		  } else if (IS_GENx(5)) {
1596                       GEN(&$$)->bits2.send_gen5.sfid = BRW_SFID_MATH;
1597                       GEN(&$$)->bits3.generic_gen5.header_present = 0;
1598                       GEN(&$$)->bits3.math_gen5.function = $2;
1599 		      set_instruction_saturate(&$$, $3);
1600                       GEN(&$$)->bits3.math_gen5.int_type = $4;
1601                       GEN(&$$)->bits3.math_gen5.precision = BRW_MATH_PRECISION_FULL;
1602                       GEN(&$$)->bits3.math_gen5.data_type = $5;
1603 		  } else {
1604                       GEN(&$$)->bits3.generic.msg_target = BRW_SFID_MATH;
1605                       GEN(&$$)->bits3.math.function = $2;
1606 		      set_instruction_saturate(&$$, $3);
1607                       GEN(&$$)->bits3.math.int_type = $4;
1608                       GEN(&$$)->bits3.math.precision = BRW_MATH_PRECISION_FULL;
1609                       GEN(&$$)->bits3.math.data_type = $5;
1610 		  }
1611 		}
1612 		| GATEWAY
1613 		{
1614 		  if (IS_GENp(5)) {
1615                       GEN(&$$)->bits2.send_gen5.sfid = BRW_SFID_MESSAGE_GATEWAY;
1616                       GEN(&$$)->bits3.generic_gen5.header_present = 0;  /* ??? */
1617 		  } else {
1618                       GEN(&$$)->bits3.generic.msg_target = BRW_SFID_MESSAGE_GATEWAY;
1619 		  }
1620 		}
1621 		| READ  LPAREN INTEGER COMMA INTEGER COMMA INTEGER COMMA
1622                 INTEGER RPAREN
1623 		{
1624                   if (IS_GENp(9)) {
1625                       if ($5 != 0 &&
1626 			  $5 != GEN6_SFID_DATAPORT_RENDER_CACHE &&
1627 			  $5 != GEN7_SFID_DATAPORT_DATA_CACHE &&
1628 			  $5 != HSW_SFID_DATAPORT_DATA_CACHE1 &&
1629 			  $5 != SKL_SFID_DATAPORT_DCR0 &&
1630 			  $5 != SKL_SFID_DATAPORT_DATA_CACHE2) {
1631 			  error (&@9, "error: wrong cache type\n");
1632 		      }
1633 
1634 		      if ($5 == 0)
1635 			  gen8_set_sfid(GEN8(&$$), HSW_SFID_DATAPORT_DATA_CACHE1);
1636 		      else
1637 			  gen8_set_sfid(GEN8(&$$), $5);
1638 
1639                       gen8_set_header_present(GEN8(&$$), 1);
1640                       gen8_set_dp_binding_table_index(GEN8(&$$), $3);
1641                       gen8_set_dp_message_control(GEN8(&$$), $7);
1642                       gen8_set_dp_message_type(GEN8(&$$), $9);
1643                       gen8_set_dp_category(GEN8(&$$), 0);
1644                   } else if (IS_GENp(8)) {
1645                       gen8_set_sfid(GEN8(&$$), GEN6_SFID_DATAPORT_SAMPLER_CACHE);
1646                       gen8_set_header_present(GEN8(&$$), 1);
1647                       gen8_set_dp_binding_table_index(GEN8(&$$), $3);
1648                       gen8_set_dp_message_control(GEN8(&$$), $7);
1649                       gen8_set_dp_message_type(GEN8(&$$), $9);
1650                       gen8_set_dp_category(GEN8(&$$), 0);
1651 		  } else if (IS_GENx(7)) {
1652                       GEN(&$$)->bits2.send_gen5.sfid =
1653                           GEN6_SFID_DATAPORT_SAMPLER_CACHE;
1654                       GEN(&$$)->bits3.generic_gen5.header_present = 1;
1655                       GEN(&$$)->bits3.gen7_dp.binding_table_index = $3;
1656                       GEN(&$$)->bits3.gen7_dp.msg_control = $7;
1657                       GEN(&$$)->bits3.gen7_dp.msg_type = $9;
1658 		  } else if (IS_GENx(6)) {
1659                       GEN(&$$)->bits2.send_gen5.sfid =
1660                           GEN6_SFID_DATAPORT_SAMPLER_CACHE;
1661                       GEN(&$$)->bits3.generic_gen5.header_present = 1;
1662                       GEN(&$$)->bits3.gen6_dp_sampler_const_cache.binding_table_index = $3;
1663                       GEN(&$$)->bits3.gen6_dp_sampler_const_cache.msg_control = $7;
1664                       GEN(&$$)->bits3.gen6_dp_sampler_const_cache.msg_type = $9;
1665 		  } else if (IS_GENx(5)) {
1666                       GEN(&$$)->bits2.send_gen5.sfid =
1667                           BRW_SFID_DATAPORT_READ;
1668                       GEN(&$$)->bits3.generic_gen5.header_present = 1;
1669                       GEN(&$$)->bits3.dp_read_gen5.binding_table_index = $3;
1670                       GEN(&$$)->bits3.dp_read_gen5.target_cache = $5;
1671                       GEN(&$$)->bits3.dp_read_gen5.msg_control = $7;
1672                       GEN(&$$)->bits3.dp_read_gen5.msg_type = $9;
1673 		  } else {
1674                       GEN(&$$)->bits3.generic.msg_target =
1675                           BRW_SFID_DATAPORT_READ;
1676                       GEN(&$$)->bits3.dp_read.binding_table_index = $3;
1677                       GEN(&$$)->bits3.dp_read.target_cache = $5;
1678                       GEN(&$$)->bits3.dp_read.msg_control = $7;
1679                       GEN(&$$)->bits3.dp_read.msg_type = $9;
1680 		  }
1681 		}
1682 		| WRITE LPAREN INTEGER COMMA INTEGER COMMA INTEGER COMMA
1683 		INTEGER RPAREN
1684 		{
1685 		  if (IS_GENp(8)) {
1686                       if (IS_GENp(9)) {
1687                           if ($9 != 0 &&
1688 			      $9 != GEN6_SFID_DATAPORT_RENDER_CACHE &&
1689 			      $9 != GEN7_SFID_DATAPORT_DATA_CACHE &&
1690 			      $9 != HSW_SFID_DATAPORT_DATA_CACHE1 &&
1691 			      $9 != SKL_SFID_DATAPORT_DATA_CACHE2) {
1692 			      error (&@9, "error: wrong cache type\n");
1693                           }
1694                       } else {
1695                           if ($9 != 0 &&
1696 			      $9 != GEN6_SFID_DATAPORT_RENDER_CACHE &&
1697 			      $9 != GEN7_SFID_DATAPORT_DATA_CACHE &&
1698 			      $9 != HSW_SFID_DATAPORT_DATA_CACHE1) {
1699 			      error (&@9, "error: wrong cache type\n");
1700                           }
1701 		      }
1702 
1703 		      if ($9 == 0)
1704 			  gen8_set_sfid(GEN8(&$$), GEN6_SFID_DATAPORT_RENDER_CACHE);
1705 		      else
1706 			  gen8_set_sfid(GEN8(&$$), $9);
1707 
1708                       gen8_set_header_present(GEN8(&$$), 1);
1709                       gen8_set_dp_binding_table_index(GEN8(&$$), $3);
1710                       gen8_set_dp_message_control(GEN8(&$$), $5);
1711                       gen8_set_dp_message_type(GEN8(&$$), $7);
1712                       gen8_set_dp_category(GEN8(&$$), 0);
1713 		  } else if (IS_GENx(7)) {
1714                       GEN(&$$)->bits2.send_gen5.sfid = GEN6_SFID_DATAPORT_RENDER_CACHE;
1715                       GEN(&$$)->bits3.generic_gen5.header_present = 1;
1716                       GEN(&$$)->bits3.gen7_dp.binding_table_index = $3;
1717                       GEN(&$$)->bits3.gen7_dp.msg_control = $5;
1718                       GEN(&$$)->bits3.gen7_dp.msg_type = $7;
1719                   } else if (IS_GENx(6)) {
1720                       GEN(&$$)->bits2.send_gen5.sfid = GEN6_SFID_DATAPORT_RENDER_CACHE;
1721                       /* Sandybridge supports headerlesss message for render target write.
1722                        * Currently the GFX assembler doesn't support it. so the program must provide
1723                        * message header
1724                        */
1725                       GEN(&$$)->bits3.generic_gen5.header_present = 1;
1726                       GEN(&$$)->bits3.gen6_dp.binding_table_index = $3;
1727                       GEN(&$$)->bits3.gen6_dp.msg_control = $5;
1728                      GEN(&$$)->bits3.gen6_dp.msg_type = $7;
1729                       GEN(&$$)->bits3.gen6_dp.send_commit_msg = $9;
1730 		  } else if (IS_GENx(5)) {
1731                       GEN(&$$)->bits2.send_gen5.sfid =
1732                           BRW_SFID_DATAPORT_WRITE;
1733                       GEN(&$$)->bits3.generic_gen5.header_present = 1;
1734                       GEN(&$$)->bits3.dp_write_gen5.binding_table_index = $3;
1735                       GEN(&$$)->bits3.dp_write_gen5.last_render_target = ($5 & 0x8) >> 3;
1736                       GEN(&$$)->bits3.dp_write_gen5.msg_control = $5 & 0x7;
1737                       GEN(&$$)->bits3.dp_write_gen5.msg_type = $7;
1738                       GEN(&$$)->bits3.dp_write_gen5.send_commit_msg = $9;
1739 		  } else {
1740                       GEN(&$$)->bits3.generic.msg_target =
1741                           BRW_SFID_DATAPORT_WRITE;
1742                       GEN(&$$)->bits3.dp_write.binding_table_index = $3;
1743                       /* The msg control field of brw_struct.h is split into
1744                        * msg control and last_render_target, even though
1745                        * last_render_target isn't common to all write messages.
1746                        */
1747                       GEN(&$$)->bits3.dp_write.last_render_target = ($5 & 0x8) >> 3;
1748                       GEN(&$$)->bits3.dp_write.msg_control = $5 & 0x7;
1749                       GEN(&$$)->bits3.dp_write.msg_type = $7;
1750                       GEN(&$$)->bits3.dp_write.send_commit_msg = $9;
1751 		  }
1752 		}
1753 		| WRITE LPAREN INTEGER COMMA INTEGER COMMA INTEGER COMMA
1754 		INTEGER COMMA INTEGER RPAREN
1755 		{
1756 		  if (IS_GENp(8)) {
1757                       if (IS_GENp(9)) {
1758                           if ($9 != 0 &&
1759 			      $9 != GEN6_SFID_DATAPORT_RENDER_CACHE &&
1760 			      $9 != GEN7_SFID_DATAPORT_DATA_CACHE &&
1761 			      $9 != HSW_SFID_DATAPORT_DATA_CACHE1 &&
1762 			      $9 != SKL_SFID_DATAPORT_DATA_CACHE2) {
1763 			      error (&@9, "error: wrong cache type\n");
1764                           }
1765                       } else {
1766                           if ($9 != 0 &&
1767 			      $9 != GEN6_SFID_DATAPORT_RENDER_CACHE &&
1768 			      $9 != GEN7_SFID_DATAPORT_DATA_CACHE &&
1769 			      $9 != HSW_SFID_DATAPORT_DATA_CACHE1) {
1770 			      error (&@9, "error: wrong cache type\n");
1771                           }
1772 		      }
1773 
1774 		      if ($9 == 0)
1775 			  gen8_set_sfid(GEN8(&$$), GEN6_SFID_DATAPORT_RENDER_CACHE);
1776 		      else
1777 			  gen8_set_sfid(GEN8(&$$), $9);
1778 
1779                       gen8_set_header_present(GEN8(&$$), ($11 != 0));
1780                       gen8_set_dp_binding_table_index(GEN8(&$$), $3);
1781                       gen8_set_dp_message_control(GEN8(&$$), $5);
1782                       gen8_set_dp_message_type(GEN8(&$$), $7);
1783                       gen8_set_dp_category(GEN8(&$$), 0);
1784 		  } else if (IS_GENx(7)) {
1785                       GEN(&$$)->bits2.send_gen5.sfid = GEN6_SFID_DATAPORT_RENDER_CACHE;
1786                       GEN(&$$)->bits3.generic_gen5.header_present = ($11 != 0);
1787                       GEN(&$$)->bits3.gen7_dp.binding_table_index = $3;
1788                       GEN(&$$)->bits3.gen7_dp.msg_control = $5;
1789                       GEN(&$$)->bits3.gen7_dp.msg_type = $7;
1790 		  } else if (IS_GENx(6)) {
1791                       GEN(&$$)->bits2.send_gen5.sfid = GEN6_SFID_DATAPORT_RENDER_CACHE;
1792                       GEN(&$$)->bits3.generic_gen5.header_present = ($11 != 0);
1793                       GEN(&$$)->bits3.gen6_dp.binding_table_index = $3;
1794                       GEN(&$$)->bits3.gen6_dp.msg_control = $5;
1795                      GEN(&$$)->bits3.gen6_dp.msg_type = $7;
1796                       GEN(&$$)->bits3.gen6_dp.send_commit_msg = $9;
1797 		  } else if (IS_GENx(5)) {
1798                       GEN(&$$)->bits2.send_gen5.sfid =
1799                           BRW_SFID_DATAPORT_WRITE;
1800                       GEN(&$$)->bits3.generic_gen5.header_present = ($11 != 0);
1801                       GEN(&$$)->bits3.dp_write_gen5.binding_table_index = $3;
1802                       GEN(&$$)->bits3.dp_write_gen5.last_render_target = ($5 & 0x8) >> 3;
1803                       GEN(&$$)->bits3.dp_write_gen5.msg_control = $5 & 0x7;
1804                       GEN(&$$)->bits3.dp_write_gen5.msg_type = $7;
1805                       GEN(&$$)->bits3.dp_write_gen5.send_commit_msg = $9;
1806 		  } else {
1807                       GEN(&$$)->bits3.generic.msg_target =
1808                           BRW_SFID_DATAPORT_WRITE;
1809                       GEN(&$$)->bits3.dp_write.binding_table_index = $3;
1810                       /* The msg control field of brw_struct.h is split into
1811                        * msg control and last_render_target, even though
1812                        * last_render_target isn't common to all write messages.
1813                        */
1814                       GEN(&$$)->bits3.dp_write.last_render_target = ($5 & 0x8) >> 3;
1815                       GEN(&$$)->bits3.dp_write.msg_control = $5 & 0x7;
1816                       GEN(&$$)->bits3.dp_write.msg_type = $7;
1817                       GEN(&$$)->bits3.dp_write.send_commit_msg = $9;
1818 		  }
1819 		}
1820 		| URB INTEGER urb_swizzle urb_allocate urb_used urb_complete
1821 		{
1822 		  GEN(&$$)->bits3.generic.msg_target = BRW_SFID_URB;
1823 		  if (IS_GENp(5)) {
1824                       GEN(&$$)->bits2.send_gen5.sfid = BRW_SFID_URB;
1825                       GEN(&$$)->bits3.generic_gen5.header_present = 1;
1826 		      set_instruction_opcode(&$$, BRW_URB_OPCODE_WRITE);
1827                       GEN(&$$)->bits3.urb_gen5.offset = $2;
1828                       GEN(&$$)->bits3.urb_gen5.swizzle_control = $3;
1829                       GEN(&$$)->bits3.urb_gen5.pad = 0;
1830                       GEN(&$$)->bits3.urb_gen5.allocate = $4;
1831                       GEN(&$$)->bits3.urb_gen5.used = $5;
1832                       GEN(&$$)->bits3.urb_gen5.complete = $6;
1833 		  } else {
1834                       GEN(&$$)->bits3.generic.msg_target = BRW_SFID_URB;
1835 		      set_instruction_opcode(&$$, BRW_URB_OPCODE_WRITE);
1836                       GEN(&$$)->bits3.urb.offset = $2;
1837                       GEN(&$$)->bits3.urb.swizzle_control = $3;
1838                       GEN(&$$)->bits3.urb.pad = 0;
1839                       GEN(&$$)->bits3.urb.allocate = $4;
1840                       GEN(&$$)->bits3.urb.used = $5;
1841                       GEN(&$$)->bits3.urb.complete = $6;
1842 		  }
1843 		}
1844 		| THREAD_SPAWNER  LPAREN INTEGER COMMA INTEGER COMMA
1845                         INTEGER RPAREN
1846 		{
1847 		  if (IS_GENp(8)) {
1848                       gen8_set_sfid(GEN8(&$$), BRW_SFID_THREAD_SPAWNER);
1849                       gen8_set_header_present(GEN8(&$$), 0); /* Must be 0 */
1850                       gen8_set_ts_opcode(GEN8(&$$), $3);
1851                       gen8_set_ts_request_type(GEN8(&$$), $5);
1852                       gen8_set_ts_resource_select(GEN8(&$$), $7);
1853 		  } else {
1854                       GEN(&$$)->bits3.generic.msg_target =
1855                           BRW_SFID_THREAD_SPAWNER;
1856                       if (IS_GENp(5)) {
1857                           GEN(&$$)->bits2.send_gen5.sfid =
1858                               BRW_SFID_THREAD_SPAWNER;
1859                           GEN(&$$)->bits3.generic_gen5.header_present = 0;
1860                           GEN(&$$)->bits3.thread_spawner_gen5.opcode = $3;
1861                           GEN(&$$)->bits3.thread_spawner_gen5.requester_type  = $5;
1862                           GEN(&$$)->bits3.thread_spawner_gen5.resource_select = $7;
1863                       } else {
1864                           GEN(&$$)->bits3.generic.msg_target =
1865                               BRW_SFID_THREAD_SPAWNER;
1866                           GEN(&$$)->bits3.thread_spawner.opcode = $3;
1867                           GEN(&$$)->bits3.thread_spawner.requester_type  = $5;
1868                           GEN(&$$)->bits3.thread_spawner.resource_select = $7;
1869                       }
1870 		  }
1871 		}
1872 		| VME  LPAREN INTEGER COMMA INTEGER COMMA INTEGER COMMA INTEGER RPAREN
1873 		{
1874 		  GEN(&$$)->bits3.generic.msg_target = GEN6_SFID_VME;
1875 
1876 		  if (IS_GENp(8)) {
1877                       gen8_set_sfid(GEN8(&$$), GEN6_SFID_VME);
1878                       gen8_set_header_present(GEN8(&$$), 1); /* Must be 1 */
1879                       gen8_set_vme_binding_table_index(GEN8(&$$), $3);
1880                       gen8_set_vme_message_type(GEN8(&$$), $9);
1881 		  } else if (IS_GENp(6)) {
1882                       GEN(&$$)->bits2.send_gen5.sfid = GEN6_SFID_VME;
1883                       GEN(&$$)->bits3.vme_gen6.binding_table_index = $3;
1884                       GEN(&$$)->bits3.vme_gen6.search_path_index = $5;
1885                       GEN(&$$)->bits3.vme_gen6.lut_subindex = $7;
1886                       GEN(&$$)->bits3.vme_gen6.message_type = $9;
1887                       GEN(&$$)->bits3.generic_gen5.header_present = 1;
1888 		  } else {
1889                       error (&@1, "Gen6- doesn't have vme function\n");
1890 		  }
1891 		}
1892 		| CRE LPAREN INTEGER COMMA INTEGER RPAREN
1893 		{
1894 		  if (IS_GENp(8)) {
1895                       gen8_set_sfid(GEN8(&$$), HSW_SFID_CRE);
1896                       gen8_set_header_present(GEN8(&$$), 1); /* Must be 1 */
1897                       gen8_set_cre_binding_table_index(GEN8(&$$), $3);
1898                       gen8_set_cre_message_type(GEN8(&$$), $5);
1899 		  } else {
1900                       if (gen_level < 75)
1901                           error (&@1, "Below Gen7.5 doesn't have CRE function\n");
1902 
1903                       GEN(&$$)->bits3.generic.msg_target = HSW_SFID_CRE;
1904 
1905                       GEN(&$$)->bits2.send_gen5.sfid = HSW_SFID_CRE;
1906                       GEN(&$$)->bits3.cre_gen75.binding_table_index = $3;
1907                       GEN(&$$)->bits3.cre_gen75.message_type = $5;
1908                       GEN(&$$)->bits3.generic_gen5.header_present = 1;
1909 		  }
1910 		}
1911 
1912 		| DATA_PORT LPAREN INTEGER COMMA INTEGER COMMA INTEGER COMMA
1913                 INTEGER COMMA INTEGER COMMA INTEGER RPAREN
1914 		{
1915 		  if (IS_GENp(8)) {
1916                       if ($3 != GEN6_SFID_DATAPORT_SAMPLER_CACHE &&
1917                           $3 != GEN6_SFID_DATAPORT_RENDER_CACHE &&
1918                           $3 != GEN6_SFID_DATAPORT_CONSTANT_CACHE &&
1919                           $3 != GEN7_SFID_DATAPORT_DATA_CACHE &&
1920                           $3 != HSW_SFID_DATAPORT_DATA_CACHE1) {
1921                           error (&@3, "error: wrong cache type\n");
1922                       }
1923 
1924                       gen8_set_sfid(GEN8(&$$), $3);
1925                       gen8_set_header_present(GEN8(&$$), ($13 != 0));
1926                       gen8_set_dp_binding_table_index(GEN8(&$$), $9);
1927                       gen8_set_dp_message_control(GEN8(&$$), $7);
1928                       gen8_set_dp_message_type(GEN8(&$$), $5);
1929                       gen8_set_dp_category(GEN8(&$$), $11);
1930 		  } else {
1931                       GEN(&$$)->bits2.send_gen5.sfid = $3;
1932                       GEN(&$$)->bits3.generic_gen5.header_present = ($13 != 0);
1933 
1934                       if (IS_GENp(7)) {
1935                           if ($3 != GEN6_SFID_DATAPORT_SAMPLER_CACHE &&
1936                               $3 != GEN6_SFID_DATAPORT_RENDER_CACHE &&
1937                               $3 != GEN6_SFID_DATAPORT_CONSTANT_CACHE &&
1938                               $3 != GEN7_SFID_DATAPORT_DATA_CACHE) {
1939                               error (&@3, "error: wrong cache type\n");
1940                           }
1941 
1942                           GEN(&$$)->bits3.gen7_dp.category = $11;
1943                           GEN(&$$)->bits3.gen7_dp.binding_table_index = $9;
1944                           GEN(&$$)->bits3.gen7_dp.msg_control = $7;
1945                           GEN(&$$)->bits3.gen7_dp.msg_type = $5;
1946                       } else if (IS_GENx(6)) {
1947                           if ($3 != GEN6_SFID_DATAPORT_SAMPLER_CACHE &&
1948                               $3 != GEN6_SFID_DATAPORT_RENDER_CACHE &&
1949                               $3 != GEN6_SFID_DATAPORT_CONSTANT_CACHE) {
1950                               error (&@3, "error: wrong cache type\n");
1951                           }
1952 
1953                           GEN(&$$)->bits3.gen6_dp.send_commit_msg = $11;
1954                           GEN(&$$)->bits3.gen6_dp.binding_table_index = $9;
1955                           GEN(&$$)->bits3.gen6_dp.msg_control = $7;
1956                           GEN(&$$)->bits3.gen6_dp.msg_type = $5;
1957                       } else if (!IS_GENp(5)) {
1958                           error (&@1, "Gen6- doesn't support data port for sampler/render/constant/data cache\n");
1959                       }
1960                   }
1961 		}
1962 ;
1963 
1964 urb_allocate:	ALLOCATE { $$ = 1; }
1965 		| %empty /* empty */ { $$ = 0; }
1966 ;
1967 
1968 urb_used:	USED { $$ = 1; }
1969 		| %empty /* empty */ { $$ = 0; }
1970 ;
1971 
1972 urb_complete:	COMPLETE { $$ = 1; }
1973 		| %empty /* empty */ { $$ = 0; }
1974 ;
1975 
1976 urb_swizzle:	TRANSPOSE { $$ = BRW_URB_SWIZZLE_TRANSPOSE; }
1977 		| INTERLEAVE { $$ = BRW_URB_SWIZZLE_INTERLEAVE; }
1978 		| %empty /* empty */ { $$ = BRW_URB_SWIZZLE_NONE; }
1979 ;
1980 
1981 sampler_datatype:
1982 		TYPE_F
1983 		| TYPE_UD
1984 		| TYPE_D
1985 ;
1986 
1987 math_function:	INV | LOG | EXP | SQRT | POW | SIN | COS | SINCOS | INTDIV
1988 		| INTMOD | INTDIVMOD | RSQ
1989 ;
1990 
1991 math_signed:	%empty /* empty */ { $$ = 0; }
1992 		| SIGNED { $$ = 1; }
1993 ;
1994 
1995 math_scalar:	%empty /* empty */ { $$ = 0; }
1996 		| SCALAR { $$ = 1; }
1997 ;
1998 
1999 /* 1.4.2: Destination register */
2000 
2001 dst:		dstoperand | dstoperandex
2002 ;
2003 
2004 dstoperand:	symbol_reg dstregion
2005 		{
2006 		  $$ = $1.reg;
2007 	          $$.hstride = resolve_dst_region(&$1, $2);
2008 		}
2009 		| dstreg dstregion writemask regtype
2010 		{
2011 		  /* Returns an instruction with just the destination register
2012 		   * filled in.
2013 		   */
2014 		  $$ = $1;
2015 	          $$.hstride = resolve_dst_region(NULL, $2);
2016 		  $$.dw1.bits.writemask = $3.dw1.bits.writemask;
2017 		  $$.type = $4.type;
2018 		}
2019 ;
2020 
2021 /* The dstoperandex returns an instruction with just the destination register
2022  * filled in.
2023  */
2024 dstoperandex:	dstoperandex_typed dstregion regtype
2025 		{
2026 		  $$ = $1;
2027 	          $$.hstride = resolve_dst_region(NULL, $2);
2028 		  $$.type = $3.type;
2029 		}
2030 		| maskstackreg
2031 		{
2032 		  $$ = $1;
2033 		  $$.hstride = 1;
2034 		  $$.type = BRW_REGISTER_TYPE_UW;
2035 		}
2036 		| controlreg
2037 		{
2038 		  $$ = $1;
2039 		  $$.hstride = 1;
2040 		  $$.type = BRW_REGISTER_TYPE_UD;
2041 		}
2042 		| ipreg
2043 		{
2044 		  $$ = $1;
2045 		  $$.hstride = 1;
2046 		  $$.type = BRW_REGISTER_TYPE_UD;
2047 		}
2048 		| nullreg dstregion regtype
2049 		{
2050 		  $$ = $1;
2051 	          $$.hstride = resolve_dst_region(NULL, $2);
2052 		  $$.type = $3.type;
2053 		}
2054 ;
2055 
2056 dstoperandex_typed: accreg | flagreg | addrreg | maskreg
2057 ;
2058 
2059 symbol_reg:	STRING %prec STR_SYMBOL_REG
2060 		{
2061 		    struct declared_register *dcl_reg = find_register($1);
2062 
2063 		    if (dcl_reg == NULL)
2064 			error(&@1, "can't find register %s\n", $1);
2065 
2066 		    memcpy(&$$, dcl_reg, sizeof(*dcl_reg));
2067 		    free($1); // $1 has been malloc'ed by strdup
2068 		}
2069 		| symbol_reg_p
2070 		{
2071 			$$=$1;
2072 		}
2073 ;
2074 
2075 symbol_reg_p: STRING LPAREN exp RPAREN
2076 		{
2077 		    struct declared_register *dcl_reg = find_register($1);
2078 
2079 		    if (dcl_reg == NULL)
2080 			error(&@1, "can't find register %s\n", $1);
2081 
2082 		    memcpy(&$$, dcl_reg, sizeof(*dcl_reg));
2083 		    $$.reg.nr += $3;
2084 		    free($1);
2085 		}
2086 		| STRING LPAREN exp COMMA exp RPAREN
2087 		{
2088 		    struct declared_register *dcl_reg = find_register($1);
2089 
2090 		    if (dcl_reg == NULL)
2091 			error(&@1, "can't find register %s\n", $1);
2092 
2093 		    memcpy(&$$, dcl_reg, sizeof(*dcl_reg));
2094 		    $$.reg.nr += $3;
2095 		    if(advanced_flag) {
2096 			int size = get_type_size(dcl_reg->reg.type);
2097 		        $$.reg.nr += ($$.reg.subnr + $5) / (32 / size);
2098 		        $$.reg.subnr = ($$.reg.subnr + $5) % (32 / size);
2099 		    } else {
2100 		        $$.reg.nr += ($$.reg.subnr + $5) / 32;
2101 		        $$.reg.subnr = ($$.reg.subnr + $5) % 32;
2102 		    }
2103 		    free($1);
2104 		}
2105 ;
2106 /* Returns a partially complete destination register consisting of the
2107  * direct or indirect register addressing fields, but not stride or writemask.
2108  */
2109 dstreg:		directgenreg
2110 		{
2111 		  $$ = $1;
2112 		  $$.address_mode = BRW_ADDRESS_DIRECT;
2113 		}
2114 		| directmsgreg
2115 		{
2116 		  $$ = $1;
2117 		  $$.address_mode = BRW_ADDRESS_DIRECT;
2118 		}
2119 		| indirectgenreg
2120 		{
2121 		  $$ = $1;
2122 		  $$.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
2123 		}
2124 		| indirectmsgreg
2125 		{
2126 		  $$ = $1;
2127 		  $$.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
2128 		}
2129 ;
2130 
2131 /* 1.4.3: Source register */
2132 srcaccimm:	srcacc | imm32reg
2133 ;
2134 
2135 srcacc:		directsrcaccoperand | indirectsrcoperand
2136 ;
2137 
2138 srcimm:		directsrcoperand | indirectsrcoperand| imm32reg
2139 ;
2140 
2141 imm32reg:	imm32 srcimmtype
2142 		{
2143 		  union {
2144 		    int i;
2145 		    float f;
2146 		  } intfloat;
2147 		  uint32_t	d;
2148 
2149 		  switch ($2) {
2150 		  case BRW_REGISTER_TYPE_UD:
2151 		  case BRW_REGISTER_TYPE_D:
2152 		  case BRW_REGISTER_TYPE_V:
2153 		  case BRW_REGISTER_TYPE_VF:
2154 		    switch ($1.r) {
2155 		    case imm32_d:
2156 		      d = $1.u.d;
2157 		      break;
2158 		    default:
2159 		      error (&@2, "non-int D/UD/V/VF representation: %d,type=%d\n", $1.r, $2);
2160 		    }
2161 		    break;
2162 		  case BRW_REGISTER_TYPE_UW:
2163 		  case BRW_REGISTER_TYPE_W:
2164 		    switch ($1.r) {
2165 		    case imm32_d:
2166 		      d = $1.u.d;
2167 		      break;
2168 		    default:
2169 		      error (&@2, "non-int W/UW representation\n");
2170 		    }
2171 		    d &= 0xffff;
2172 		    d |= d << 16;
2173 		    break;
2174 		  case BRW_REGISTER_TYPE_F:
2175 		    switch ($1.r) {
2176 		    case imm32_f:
2177 		      intfloat.f = $1.u.f;
2178 		      break;
2179 		    case imm32_d:
2180 		      intfloat.f = (float) $1.u.d;
2181 		      break;
2182 		    default:
2183 		      error (&@2, "non-float F representation\n");
2184 		    }
2185 		    d = intfloat.i;
2186 		    break;
2187 #if 0
2188 		  case BRW_REGISTER_TYPE_VF:
2189 		    fprintf (stderr, "Immediate type VF not supported yet\n");
2190 		    YYERROR;
2191 #endif
2192 		  default:
2193 		    error(&@2, "unknown immediate type %d\n", $2);
2194 		  }
2195 		  memset (&$$, '\0', sizeof ($$));
2196 		  $$.reg.file = BRW_IMMEDIATE_VALUE;
2197 		  $$.reg.type = $2;
2198 		  $$.reg.dw1.ud = d;
2199 		}
2200 ;
2201 
2202 directsrcaccoperand:	directsrcoperand
2203 		| accreg region regtype
2204 		{
2205 		  set_direct_src_operand(&$$, &$1, $3.type);
2206 		  $$.reg.vstride = $2.vert_stride;
2207 		  $$.reg.width = $2.width;
2208 		  $$.reg.hstride = $2.horiz_stride;
2209 		  $$.default_region = $2.is_default;
2210 		}
2211 ;
2212 
2213 /* Returns a source operand in the src0 fields of an instruction. */
2214 srcarchoperandex: srcarchoperandex_typed region regtype
2215 		{
2216 		  memset (&$$, '\0', sizeof ($$));
2217 		  $$.reg.file = $1.file;
2218 		  $$.reg.type = $3.type;
2219 		  $$.reg.subnr = $1.subnr;
2220 		  $$.reg.nr = $1.nr;
2221 		  $$.reg.vstride = $2.vert_stride;
2222 		  $$.reg.width = $2.width;
2223 		  $$.reg.hstride = $2.horiz_stride;
2224 		  $$.default_region = $2.is_default;
2225 		  $$.reg.negate = 0;
2226 		  $$.reg.abs = 0;
2227 		}
2228 		| maskstackreg
2229 		{
2230 		  set_direct_src_operand(&$$, &$1, BRW_REGISTER_TYPE_UB);
2231 		}
2232 		| controlreg
2233 		{
2234 		  set_direct_src_operand(&$$, &$1, BRW_REGISTER_TYPE_UD);
2235 		}
2236 /*		| statereg
2237 		{
2238 		  set_direct_src_operand(&$$, &$1, BRW_REGISTER_TYPE_UD);
2239 		}*/
2240 		| notifyreg
2241 		{
2242 		  set_direct_src_operand(&$$, &$1, BRW_REGISTER_TYPE_UD);
2243 		}
2244 		| ipreg
2245 		{
2246 		  set_direct_src_operand(&$$, &$1, BRW_REGISTER_TYPE_UD);
2247 		}
2248 		| nullreg region regtype
2249 		{
2250 		  if ($3.is_default) {
2251 		    set_direct_src_operand(&$$, &$1, BRW_REGISTER_TYPE_UD);
2252 		  } else {
2253 		    set_direct_src_operand(&$$, &$1, $3.type);
2254 		  }
2255 		  $$.default_region = 1;
2256 		}
2257 ;
2258 
2259 srcarchoperandex_typed: flagreg | addrreg | maskreg
2260 ;
2261 
2262 sendleadreg: symbol_reg
2263              {
2264 		  memset (&$$, '\0', sizeof ($$));
2265 		  $$.file = $1.reg.file;
2266 		  $$.nr = $1.reg.nr;
2267 		  $$.subnr = $1.reg.subnr;
2268              }
2269              | directgenreg | directmsgreg
2270 ;
2271 
2272 src:		directsrcoperand | indirectsrcoperand
2273 ;
2274 
2275 directsrcoperand:	negate abs symbol_reg region regtype
2276 		{
2277 		  memset (&$$, '\0', sizeof ($$));
2278 		  $$.reg.address_mode = BRW_ADDRESS_DIRECT;
2279 		  $$.reg.file = $3.reg.file;
2280 		  $$.reg.nr = $3.reg.nr;
2281 		  $$.reg.subnr = $3.reg.subnr;
2282 		  if ($5.is_default) {
2283 		    $$.reg.type = $3.reg.type;
2284 		  } else {
2285 		    $$.reg.type = $5.type;
2286 		  }
2287 		  if ($4.is_default) {
2288 		    $$.reg.vstride = $3.src_region.vert_stride;
2289 		    $$.reg.width = $3.src_region.width;
2290 		    $$.reg.hstride = $3.src_region.horiz_stride;
2291 		  } else {
2292 		    $$.reg.vstride = $4.vert_stride;
2293 		    $$.reg.width = $4.width;
2294 		    $$.reg.hstride = $4.horiz_stride;
2295 		  }
2296 		  $$.reg.negate = $1;
2297 		  $$.reg.abs = $2;
2298 		}
2299 		| statereg region regtype
2300 		{
2301 		  if($2.is_default ==1 && $3.is_default == 1)
2302 		  {
2303 		    set_direct_src_operand(&$$, &$1, BRW_REGISTER_TYPE_UD);
2304 		  }
2305 		  else{
2306 		    memset (&$$, '\0', sizeof ($$));
2307 		    $$.reg.address_mode = BRW_ADDRESS_DIRECT;
2308 		    $$.reg.file = $1.file;
2309 		    $$.reg.nr = $1.nr;
2310 		    $$.reg.subnr = $1.subnr;
2311 		    $$.reg.vstride = $2.vert_stride;
2312 		    $$.reg.width = $2.width;
2313 		    $$.reg.hstride = $2.horiz_stride;
2314 		    $$.reg.type = $3.type;
2315 		  }
2316 		}
2317 		| negate abs directgenreg region swizzle regtype
2318 		{
2319 		  memset (&$$, '\0', sizeof ($$));
2320 		  $$.reg.address_mode = BRW_ADDRESS_DIRECT;
2321 		  $$.reg.file = $3.file;
2322 		  $$.reg.nr = $3.nr;
2323 		  $$.reg.subnr = $3.subnr;
2324 		  $$.reg.type = $6.type;
2325 		  $$.reg.vstride = $4.vert_stride;
2326 		  $$.reg.width = $4.width;
2327 		  $$.reg.hstride = $4.horiz_stride;
2328 		  $$.default_region = $4.is_default;
2329 		  $$.reg.negate = $1;
2330 		  $$.reg.abs = $2;
2331 		  $$.reg.dw1.bits.swizzle = $5.reg.dw1.bits.swizzle;
2332 		}
2333 		| srcarchoperandex
2334 ;
2335 
2336 indirectsrcoperand:
2337 		negate abs indirectgenreg indirectregion regtype swizzle
2338 		{
2339 		  memset (&$$, '\0', sizeof ($$));
2340 		  $$.reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
2341 		  $$.reg.file = $3.file;
2342 		  $$.reg.subnr = $3.subnr;
2343 		  $$.reg.dw1.bits.indirect_offset = $3.dw1.bits.indirect_offset;
2344 		  $$.reg.type = $5.type;
2345 		  $$.reg.vstride = $4.vert_stride;
2346 		  $$.reg.width = $4.width;
2347 		  $$.reg.hstride = $4.horiz_stride;
2348 		  $$.reg.negate = $1;
2349 		  $$.reg.abs = $2;
2350 		  $$.reg.dw1.bits.swizzle = $6.reg.dw1.bits.swizzle;
2351 		}
2352 ;
2353 
2354 /* 1.4.4: Address Registers */
2355 /* Returns a partially-completed struct brw_reg consisting of the address
2356  * register fields for register-indirect access.
2357  */
2358 addrparam:	addrreg COMMA immaddroffset
2359 		{
2360 		  if ($3 < -512 || $3 > 511)
2361 		    error(&@3, "Address immediate offset %d out of range\n", $3);
2362 		  memset (&$$, '\0', sizeof ($$));
2363 		  $$.subnr = $1.subnr;
2364 		  $$.dw1.bits.indirect_offset = $3;
2365 		}
2366 		| addrreg
2367 		{
2368 		  memset (&$$, '\0', sizeof ($$));
2369 		  $$.subnr = $1.subnr;
2370 		  $$.dw1.bits.indirect_offset = 0;
2371 		}
2372 ;
2373 
2374 /* The immaddroffset provides an immediate offset value added to the addresses
2375  * from the address register in register-indirect register access.
2376  */
2377 immaddroffset:	%empty /* empty */ { $$ = 0; }
2378 		| exp
2379 ;
2380 
2381 
2382 /* 1.4.5: Register files and register numbers */
2383 subregnum:	DOT exp
2384 		{
2385 		  $$ = $2;
2386 		}
2387 		|  %empty %prec SUBREGNUM
2388 		{
2389 		  /* Default to subreg 0 if unspecified. */
2390 		  $$ = 0;
2391 		}
2392 ;
2393 
2394 directgenreg:	GENREG subregnum
2395 		{
2396 		  memset (&$$, '\0', sizeof ($$));
2397 		  $$.file = BRW_GENERAL_REGISTER_FILE;
2398 		  $$.nr = $1;
2399 		  $$.subnr = $2;
2400 		}
2401 ;
2402 
2403 indirectgenreg: GENREGFILE LSQUARE addrparam RSQUARE
2404 		{
2405 		  memset (&$$, '\0', sizeof ($$));
2406 		  $$.file = BRW_GENERAL_REGISTER_FILE;
2407 		  $$.subnr = $3.subnr;
2408 		  $$.dw1.bits.indirect_offset = $3.dw1.bits.indirect_offset;
2409 		}
2410 ;
2411 
2412 directmsgreg:	MSGREG subregnum
2413 		{
2414 		  memset (&$$, '\0', sizeof ($$));
2415 		  $$.file = BRW_MESSAGE_REGISTER_FILE;
2416 		  $$.nr = $1;
2417 		  $$.subnr = $2;
2418 		}
2419 ;
2420 
2421 indirectmsgreg: MSGREGFILE LSQUARE addrparam RSQUARE
2422 		{
2423 		  memset (&$$, '\0', sizeof ($$));
2424 		  $$.file = BRW_MESSAGE_REGISTER_FILE;
2425 		  $$.subnr = $3.subnr;
2426 		  $$.dw1.bits.indirect_offset = $3.dw1.bits.indirect_offset;
2427 		}
2428 ;
2429 
2430 addrreg:	ADDRESSREG subregnum
2431 		{
2432 		  if ($1 != 0)
2433 		    error(&@2, "address register number %d out of range", $1);
2434 
2435 		  memset (&$$, '\0', sizeof ($$));
2436 		  $$.file = BRW_ARCHITECTURE_REGISTER_FILE;
2437 		  $$.nr = BRW_ARF_ADDRESS | $1;
2438 		  $$.subnr = $2;
2439 		}
2440 ;
2441 
2442 accreg:		ACCREG subregnum
2443 		{
2444 		  if ($1 > 1)
2445 		    error(&@1, "accumulator register number %d out of range", $1);
2446 		  memset (&$$, '\0', sizeof ($$));
2447 		  $$.file = BRW_ARCHITECTURE_REGISTER_FILE;
2448 		  $$.nr = BRW_ARF_ACCUMULATOR | $1;
2449 		  $$.subnr = $2;
2450 		}
2451 ;
2452 
2453 flagreg:	FLAGREG subregnum
2454 		{
2455 		  if ((!IS_GENp(7) && $1 > 0) ||
2456 		      (IS_GENp(7) && $1 > 1)) {
2457                     error(&@2, "flag register number %d out of range\n", $1);
2458 		  }
2459 
2460 		  if ($2 > 1)
2461 		    error(&@2, "flag subregister number %d out of range\n", $1);
2462 
2463 		  memset (&$$, '\0', sizeof ($$));
2464 		  $$.file = BRW_ARCHITECTURE_REGISTER_FILE;
2465 		  $$.nr = BRW_ARF_FLAG | $1;
2466 		  $$.subnr = $2;
2467 		}
2468 ;
2469 
2470 maskreg:	MASKREG subregnum
2471 		{
2472 		  if ($1 > 0)
2473 		    error(&@1, "mask register number %d out of range", $1);
2474 
2475 		  memset (&$$, '\0', sizeof ($$));
2476 		  $$.file = BRW_ARCHITECTURE_REGISTER_FILE;
2477 		  $$.nr = BRW_ARF_MASK;
2478 		  $$.subnr = $2;
2479 		}
2480 		| mask_subreg
2481 		{
2482 		  memset (&$$, '\0', sizeof ($$));
2483 		  $$.file = BRW_ARCHITECTURE_REGISTER_FILE;
2484 		  $$.nr = BRW_ARF_MASK;
2485 		  $$.subnr = $1;
2486 		}
2487 ;
2488 
2489 mask_subreg:	AMASK | IMASK | LMASK | CMASK
2490 ;
2491 
2492 maskstackreg:	MASKSTACKREG subregnum
2493 		{
2494 		  if ($1 > 0)
2495 		    error(&@1, "mask stack register number %d out of range", $1);
2496 		  memset (&$$, '\0', sizeof ($$));
2497 		  $$.file = BRW_ARCHITECTURE_REGISTER_FILE;
2498 		  $$.nr = BRW_ARF_MASK_STACK;
2499 		  $$.subnr = $2;
2500 		}
2501 		| maskstack_subreg
2502 		{
2503 		  memset (&$$, '\0', sizeof ($$));
2504 		  $$.file = BRW_ARCHITECTURE_REGISTER_FILE;
2505 		  $$.nr = BRW_ARF_MASK_STACK;
2506 		  $$.subnr = $1;
2507 		}
2508 ;
2509 
2510 maskstack_subreg: IMS | LMS
2511 ;
2512 
2513 /*
2514 maskstackdepthreg: MASKSTACKDEPTHREG subregnum
2515 		{
2516 		  if ($1 > 0)
2517 		    error(&@1, "mask stack register number %d out of range", $1);
2518 		  memset (&$$, '\0', sizeof ($$));
2519 		  $$.reg_file = BRW_ARCHITECTURE_REGISTER_FILE;
2520 		  $$.reg_nr = BRW_ARF_MASK_STACK_DEPTH;
2521 		  $$.subreg_nr = $2;
2522 		}
2523 		| maskstackdepth_subreg
2524 		{
2525 		  memset (&$$, '\0', sizeof ($$));
2526 		  $$.reg_file = BRW_ARCHITECTURE_REGISTER_FILE;
2527 		  $$.reg_nr = BRW_ARF_MASK_STACK_DEPTH;
2528 		  $$.subreg_nr = $1;
2529 		}
2530 ;
2531 
2532 maskstackdepth_subreg: IMSD | LMSD
2533 ;
2534  */
2535 
2536 notifyreg:	NOTIFYREG regtype
2537 		{
2538 		  int num_notifyreg = (IS_GENp(6)) ? 3 : 2;
2539 
2540 		  if ($1 > num_notifyreg)
2541 		    error(&@1, "notification register number %d out of range",
2542 			  $1);
2543 
2544 		  memset (&$$, '\0', sizeof ($$));
2545 		  $$.file = BRW_ARCHITECTURE_REGISTER_FILE;
2546 
2547                   if (IS_GENp(6)) {
2548 		    $$.nr = BRW_ARF_NOTIFICATION_COUNT;
2549                     $$.subnr = $1;
2550                   } else {
2551 		    $$.nr = BRW_ARF_NOTIFICATION_COUNT | $1;
2552                     $$.subnr = 0;
2553                   }
2554 		}
2555 /*
2556 		| NOTIFYREG regtype
2557 		{
2558 		  if ($1 > 1) {
2559 		    fprintf(stderr,
2560 			    "notification register number %d out of range",
2561 			    $1);
2562 		    YYERROR;
2563 		  }
2564 		  memset (&$$, '\0', sizeof ($$));
2565 		  $$.reg_file = BRW_ARCHITECTURE_REGISTER_FILE;
2566 		  $$.reg_nr = BRW_ARF_NOTIFICATION_COUNT;
2567 		  $$.subreg_nr = 0;
2568 		}
2569 */
2570 ;
2571 
2572 statereg:	STATEREG subregnum
2573 		{
2574 		  if ($1 > 0)
2575 		    error(&@1, "state register number %d out of range", $1);
2576 
2577 		  if ($2 > 1)
2578 		    error(&@2, "state subregister number %d out of range", $1);
2579 
2580 		  memset (&$$, '\0', sizeof ($$));
2581 		  $$.file = BRW_ARCHITECTURE_REGISTER_FILE;
2582 		  $$.nr = BRW_ARF_STATE | $1;
2583 		  $$.subnr = $2;
2584 		}
2585 ;
2586 
2587 controlreg:	CONTROLREG subregnum
2588 		{
2589 		  if ($1 > 0)
2590 		    error(&@1, "control register number %d out of range", $1);
2591 
2592 		  if ($2 > 2)
2593 		    error(&@2, "control subregister number %d out of range", $1);
2594 		  memset (&$$, '\0', sizeof ($$));
2595 		  $$.file = BRW_ARCHITECTURE_REGISTER_FILE;
2596 		  $$.nr = BRW_ARF_CONTROL | $1;
2597 		  $$.subnr = $2;
2598 		}
2599 ;
2600 
2601 ipreg:		IPREG regtype
2602 		{
2603 		  memset (&$$, '\0', sizeof ($$));
2604 		  $$.file = BRW_ARCHITECTURE_REGISTER_FILE;
2605 		  $$.nr = BRW_ARF_IP;
2606 		  $$.subnr = 0;
2607 		}
2608 ;
2609 
2610 nullreg:	NULL_TOKEN
2611 		{
2612 		  memset (&$$, '\0', sizeof ($$));
2613 		  $$.file = BRW_ARCHITECTURE_REGISTER_FILE;
2614 		  $$.nr = BRW_ARF_NULL;
2615 		  $$.subnr = 0;
2616 		}
2617 ;
2618 
2619 /* 1.4.6: Relative locations */
2620 relativelocation:
2621 		simple_int
2622 		{
2623 		  if (($1 > 32767) || ($1 < -32768))
2624 		    error(&@1, "error: relative offset %d out of range \n", $1);
2625 
2626 		  memset (&$$, '\0', sizeof ($$));
2627 		  $$.reg.file = BRW_IMMEDIATE_VALUE;
2628 		  $$.reg.type = BRW_REGISTER_TYPE_D;
2629 		  $$.imm32 = $1 & 0x0000ffff;
2630 		}
2631 		| STRING
2632 		{
2633 		  memset (&$$, '\0', sizeof ($$));
2634 		  $$.reg.file = BRW_IMMEDIATE_VALUE;
2635 		  $$.reg.type = BRW_REGISTER_TYPE_D;
2636 		  $$.reloc_target = $1;
2637 		}
2638 ;
2639 
2640 relativelocation2:
2641 		  STRING
2642 		{
2643 		  memset (&$$, '\0', sizeof ($$));
2644 		  $$.reg.file = BRW_IMMEDIATE_VALUE;
2645 		  $$.reg.type = BRW_REGISTER_TYPE_D;
2646 		  $$.reloc_target = $1;
2647 		}
2648 		| exp
2649 		{
2650 		  memset (&$$, '\0', sizeof ($$));
2651 		  $$.reg.file = BRW_IMMEDIATE_VALUE;
2652 		  $$.reg.type = BRW_REGISTER_TYPE_D;
2653 		  $$.imm32 = $1;
2654 		}
2655 		| directgenreg region regtype
2656 		{
2657 		  set_direct_src_operand(&$$, &$1, $3.type);
2658 		  $$.reg.vstride = $2.vert_stride;
2659 		  $$.reg.width = $2.width;
2660 		  $$.reg.hstride = $2.horiz_stride;
2661 		  $$.default_region = $2.is_default;
2662 		}
2663 		| symbol_reg_p
2664 		{
2665 		  memset (&$$, '\0', sizeof ($$));
2666 		  $$.reg.address_mode = BRW_ADDRESS_DIRECT;
2667 		  $$.reg.file = $1.reg.file;
2668 		  $$.reg.nr = $1.reg.nr;
2669 		  $$.reg.subnr = $1.reg.subnr;
2670 		  $$.reg.type = $1.reg.type;
2671 		  $$.reg.vstride = $1.src_region.vert_stride;
2672 		  $$.reg.width = $1.src_region.width;
2673 		  $$.reg.hstride = $1.src_region.horiz_stride;
2674 		}
2675 		| indirectgenreg indirectregion regtype
2676 		{
2677 		  memset (&$$, '\0', sizeof ($$));
2678 		  $$.reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
2679 		  $$.reg.file = $1.file;
2680 		  $$.reg.subnr = $1.subnr;
2681 		  $$.reg.dw1.bits.indirect_offset = $1.dw1.bits.indirect_offset;
2682 		  $$.reg.type = $3.type;
2683 		  $$.reg.vstride = $2.vert_stride;
2684 		  $$.reg.width = $2.width;
2685 		  $$.reg.hstride = $2.horiz_stride;
2686 		}
2687 ;
2688 
2689 /* 1.4.7: Regions */
2690 dstregion:	%empty /* empty */
2691 		{
2692 		  $$ = DEFAULT_DSTREGION;
2693 		}
2694 		|LANGLE exp RANGLE
2695 		{
2696 		  /* Returns a value for a horiz_stride field of an
2697 		   * instruction.
2698 		   */
2699 		  if ($2 != 1 && $2 != 2 && $2 != 4)
2700 		    error(&@2, "Invalid horiz size %d\n", $2);
2701 
2702 		  $$ = ffs($2);
2703 		}
2704 ;
2705 
2706 region:		%empty /* empty */
2707 		{
2708 		  /* XXX is this default value correct?*/
2709 		  memset (&$$, '\0', sizeof ($$));
2710 		  $$.vert_stride = ffs(0);
2711 		  $$.width = BRW_WIDTH_1;
2712 		  $$.horiz_stride = ffs(0);
2713 		  $$.is_default = 1;
2714 		}
2715 		|LANGLE exp RANGLE
2716 		{
2717 		  /* XXX is this default value correct for accreg?*/
2718 		  memset (&$$, '\0', sizeof ($$));
2719 		  $$.vert_stride = ffs($2);
2720 		  $$.width = BRW_WIDTH_1;
2721 		  $$.horiz_stride = ffs(0);
2722 		}
2723 		|LANGLE exp COMMA exp COMMA exp RANGLE
2724 		{
2725 		  memset (&$$, '\0', sizeof ($$));
2726 		  $$.vert_stride = ffs($2);
2727 		  $$.width = ffs($4) - 1;
2728 		  $$.horiz_stride = ffs($6);
2729 		}
2730 		| LANGLE exp SEMICOLON exp COMMA exp RANGLE
2731 		{
2732 		  memset (&$$, '\0', sizeof ($$));
2733 		  $$.vert_stride = ffs($2);
2734 		  $$.width = ffs($4) - 1;
2735 		  $$.horiz_stride = ffs($6);
2736 		}
2737 
2738 ;
2739 /* region_wh is used in specifying indirect operands where rather than having
2740  * a vertical stride, you use subsequent address registers to get a new base
2741  * offset for the next row.
2742  */
2743 region_wh:	LANGLE exp COMMA exp RANGLE
2744 		{
2745 		  memset (&$$, '\0', sizeof ($$));
2746 		  $$.vert_stride = BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL;
2747 		  $$.width = ffs($2) - 1;
2748 		  $$.horiz_stride = ffs($4);
2749 		}
2750 ;
2751 
2752 indirectregion:	region | region_wh
2753 ;
2754 
2755 /* 1.4.8: Types */
2756 
2757 /* regtype returns an integer register type suitable for inserting into an
2758  * instruction.
2759  */
2760 regtype:	%empty /* empty */
2761 		{ $$.type = program_defaults.register_type;$$.is_default = 1;}
2762 		| TYPE_F { $$.type = BRW_REGISTER_TYPE_F;$$.is_default = 0; }
2763 		| TYPE_UD { $$.type = BRW_REGISTER_TYPE_UD;$$.is_default = 0; }
2764 		| TYPE_D { $$.type = BRW_REGISTER_TYPE_D;$$.is_default = 0; }
2765 		| TYPE_UW { $$.type = BRW_REGISTER_TYPE_UW;$$.is_default = 0; }
2766 		| TYPE_W { $$.type = BRW_REGISTER_TYPE_W;$$.is_default = 0; }
2767 		| TYPE_UB { $$.type = BRW_REGISTER_TYPE_UB;$$.is_default = 0; }
2768 		| TYPE_B { $$.type = BRW_REGISTER_TYPE_B;$$.is_default = 0; }
2769 ;
2770 
2771 srcimmtype:	%empty /* empty */
2772 		{
2773 		    /* XXX change to default when pragma parse is done */
2774 		   $$ = BRW_REGISTER_TYPE_D;
2775 		}
2776 		|TYPE_F { $$ = BRW_REGISTER_TYPE_F; }
2777 		| TYPE_UD { $$ = BRW_REGISTER_TYPE_UD; }
2778 		| TYPE_D { $$ = BRW_REGISTER_TYPE_D; }
2779 		| TYPE_UW { $$ = BRW_REGISTER_TYPE_UW; }
2780 		| TYPE_W { $$ = BRW_REGISTER_TYPE_W; }
2781 		| TYPE_V { $$ = BRW_REGISTER_TYPE_V; }
2782 		| TYPE_VF { $$ = BRW_REGISTER_TYPE_VF; }
2783 ;
2784 
2785 /* 1.4.10: Swizzle control */
2786 /* Returns the swizzle control for an align16 instruction's source operand
2787  * in the src0 fields.
2788  */
2789 swizzle:	%empty /* empty */
2790 		{
2791 		  $$.reg.dw1.bits.swizzle = BRW_SWIZZLE_NOOP;
2792 		}
2793 		| DOT chansel
2794 		{
2795 		  $$.reg.dw1.bits.swizzle = BRW_SWIZZLE4($2, $2, $2, $2);
2796 		}
2797 		| DOT chansel chansel chansel chansel
2798 		{
2799 		  $$.reg.dw1.bits.swizzle = BRW_SWIZZLE4($2, $3, $4, $5);
2800 		}
2801 ;
2802 
2803 chansel:	X | Y | Z | W
2804 ;
2805 
2806 /* 1.4.9: Write mask */
2807 /* Returns a partially completed struct brw_reg, with just the writemask bits
2808  * filled out.
2809  */
2810 writemask:	%empty /* empty */
2811 		{
2812 		  $$.dw1.bits.writemask = BRW_WRITEMASK_XYZW;
2813 		}
2814 		| DOT writemask_x writemask_y writemask_z writemask_w
2815 		{
2816 		  $$.dw1.bits.writemask = $2 | $3 | $4 | $5;
2817 		}
2818 ;
2819 
2820 writemask_x:	%empty /* empty */ { $$ = 0; }
2821 		 | X { $$ = 1 << BRW_CHANNEL_X; }
2822 ;
2823 
2824 writemask_y:	%empty /* empty */ { $$ = 0; }
2825 		 | Y { $$ = 1 << BRW_CHANNEL_Y; }
2826 ;
2827 
2828 writemask_z:	%empty /* empty */ { $$ = 0; }
2829 		 | Z { $$ = 1 << BRW_CHANNEL_Z; }
2830 ;
2831 
2832 writemask_w:	%empty /* empty */ { $$ = 0; }
2833 		 | W { $$ = 1 << BRW_CHANNEL_W; }
2834 ;
2835 
2836 /* 1.4.11: Immediate values */
2837 imm32:		exp { $$.r = imm32_d; $$.u.d = $1; }
2838 		| NUMBER { $$.r = imm32_f; $$.u.f = $1; }
2839 ;
2840 
2841 /* 1.4.12: Predication and modifiers */
2842 predicate:	%empty /* empty */
2843 		{
2844 		  $$.pred_control = BRW_PREDICATE_NONE;
2845 		  $$.flag_reg_nr = 0;
2846 		  $$.flag_subreg_nr = 0;
2847 		  $$.pred_inverse = 0;
2848 		}
2849 		| LPAREN predstate flagreg predctrl RPAREN
2850 		{
2851 		  $$.pred_control = $4;
2852 		  $$.flag_reg_nr = $3.nr;
2853 		  $$.flag_subreg_nr = $3.subnr;
2854 		  $$.pred_inverse = $2;
2855 		}
2856 ;
2857 
2858 predstate:	%empty /* empty */ { $$ = 0; }
2859 		| PLUS { $$ = 0; }
2860 		| MINUS { $$ = 1; }
2861 ;
2862 
2863 predctrl:	%empty /* empty */ { $$ = BRW_PREDICATE_NORMAL; }
2864 		| DOT X { $$ = BRW_PREDICATE_ALIGN16_REPLICATE_X; }
2865 		| DOT Y { $$ = BRW_PREDICATE_ALIGN16_REPLICATE_Y; }
2866 		| DOT Z { $$ = BRW_PREDICATE_ALIGN16_REPLICATE_Z; }
2867 		| DOT W { $$ = BRW_PREDICATE_ALIGN16_REPLICATE_W; }
2868 		| ANYV { $$ = BRW_PREDICATE_ALIGN1_ANYV; }
2869 		| ALLV { $$ = BRW_PREDICATE_ALIGN1_ALLV; }
2870 		| ANY2H { $$ = BRW_PREDICATE_ALIGN1_ANY2H; }
2871 		| ALL2H { $$ = BRW_PREDICATE_ALIGN1_ALL2H; }
2872 		| ANY4H { $$ = BRW_PREDICATE_ALIGN1_ANY4H; }
2873 		| ALL4H { $$ = BRW_PREDICATE_ALIGN1_ALL4H; }
2874 		| ANY8H { $$ = BRW_PREDICATE_ALIGN1_ANY8H; }
2875 		| ALL8H { $$ = BRW_PREDICATE_ALIGN1_ALL8H; }
2876 		| ANY16H { $$ = BRW_PREDICATE_ALIGN1_ANY16H; }
2877 		| ALL16H { $$ = BRW_PREDICATE_ALIGN1_ALL16H; }
2878 ;
2879 
2880 negate:		%empty /* empty */ { $$ = 0; }
2881 		| MINUS { $$ = 1; }
2882 ;
2883 
2884 abs:		%empty /* empty */ { $$ = 0; }
2885 		| ABS { $$ = 1; }
2886 ;
2887 
2888 execsize:	%empty /* empty */ %prec EMPTEXECSIZE
2889 		{
2890 		  $$ = ffs(program_defaults.execute_size) - 1;
2891 		}
2892 		|LPAREN exp RPAREN
2893 		{
2894 		  /* Returns a value for the execution_size field of an
2895 		   * instruction.
2896 		   */
2897 		  if ($2 != 1 && $2 != 2 && $2 != 4 && $2 != 8 && $2 != 16 &&
2898 		      $2 != 32)
2899 		    error(&@2, "Invalid execution size %d\n", $2);
2900 
2901 		  $$ = ffs($2) - 1;
2902 		}
2903 ;
2904 
2905 saturate:	%empty /* empty */ { $$ = BRW_INSTRUCTION_NORMAL; }
2906 		| SATURATE { $$ = BRW_INSTRUCTION_SATURATE; }
2907 ;
2908 conditionalmodifier: condition
2909 		{
2910 		    $$.cond = $1;
2911 		    $$.flag_reg_nr = 0;
2912 		    $$.flag_subreg_nr = -1;
2913 		}
2914 		| condition DOT flagreg
2915 		{
2916 		    $$.cond = $1;
2917 		    $$.flag_reg_nr = ($3.nr & 0xF);
2918 		    $$.flag_subreg_nr = $3.subnr;
2919 		}
2920 
2921 condition: %empty /* empty */    { $$ = BRW_CONDITIONAL_NONE; }
2922 		| ZERO
2923 		| EQUAL
2924 		| NOT_ZERO
2925 		| NOT_EQUAL
2926 		| GREATER
2927 		| GREATER_EQUAL
2928 		| LESS
2929 		| LESS_EQUAL
2930 		| ROUND_INCREMENT
2931 		| OVERFLOW
2932 		| UNORDERED
2933 ;
2934 
2935 /* 1.4.13: Instruction options */
2936 instoptions:	%empty /* empty */
2937 		{ memset(&$$, 0, sizeof($$)); }
2938 		| LCURLY instoption_list RCURLY
2939 		{ $$ = $2; }
2940 ;
2941 
2942 instoption_list:instoption_list COMMA instoption
2943 		{
2944 		  $$ = $1;
2945 		  add_option(&$$, $3);
2946 		}
2947 		| instoption_list instoption
2948 		{
2949 		  $$ = $1;
2950 		  add_option(&$$, $2);
2951 		}
2952 		| %empty /* empty, header defaults to zeroes. */
2953 		{
2954 		  memset(&$$, 0, sizeof($$));
2955 		}
2956 ;
2957 
2958 instoption:	ALIGN1 { $$ = ALIGN1; }
2959 		| ALIGN16 { $$ = ALIGN16; }
2960 		| SECHALF { $$ = SECHALF; }
2961 		| COMPR { $$ = COMPR; }
2962 		| SWITCH { $$ = SWITCH; }
2963 		| ATOMIC { $$ = ATOMIC; }
2964 		| NODDCHK { $$ = NODDCHK; }
2965 		| NODDCLR { $$ = NODDCLR; }
2966 		| MASK_DISABLE { $$ = MASK_DISABLE; }
2967 		| BREAKPOINT { $$ = BREAKPOINT; }
2968 		| ACCWRCTRL { $$ = ACCWRCTRL; }
2969 		| EOT { $$ = EOT; }
2970 ;
2971 
2972 %%
2973 extern int yylineno;
2974 
yyerror(char * msg)2975 void yyerror (char *msg)
2976 {
2977 	fprintf(stderr, "%s: %d: %s at \"%s\"\n",
2978 		input_filename, yylineno, msg, lex_text());
2979 	++errors;
2980 }
2981 
get_type_size(unsigned type)2982 static int get_type_size(unsigned type)
2983 {
2984     int size = 1;
2985 
2986     switch (type) {
2987     case BRW_REGISTER_TYPE_F:
2988     case BRW_REGISTER_TYPE_UD:
2989     case BRW_REGISTER_TYPE_D:
2990         size = 4;
2991         break;
2992 
2993     case BRW_REGISTER_TYPE_UW:
2994     case BRW_REGISTER_TYPE_W:
2995         size = 2;
2996         break;
2997 
2998     case BRW_REGISTER_TYPE_UB:
2999     case BRW_REGISTER_TYPE_B:
3000         size = 1;
3001         break;
3002 
3003     default:
3004         assert(0);
3005         size = 1;
3006         break;
3007     }
3008 
3009     return size;
3010 }
3011 
reset_instruction_src_region(struct brw_instruction * instr,struct src_operand * src)3012 static void reset_instruction_src_region(struct brw_instruction *instr,
3013                                          struct src_operand *src)
3014 {
3015     if (IS_GENp(8))
3016 	return;
3017 
3018     if (!src->default_region)
3019         return;
3020 
3021     if (src->reg.file == BRW_ARCHITECTURE_REGISTER_FILE &&
3022         ((src->reg.nr & 0xF0) == BRW_ARF_ADDRESS)) {
3023         src->reg.vstride = ffs(0);
3024         src->reg.width = BRW_WIDTH_1;
3025         src->reg.hstride = ffs(0);
3026     } else if (src->reg.file == BRW_ARCHITECTURE_REGISTER_FILE &&
3027                ((src->reg.nr & 0xF0) == BRW_ARF_ACCUMULATOR)) {
3028         int horiz_stride = 1, width, vert_stride;
3029         if (instr->header.compression_control == BRW_COMPRESSION_COMPRESSED) {
3030             width = 16;
3031         } else {
3032             width = 8;
3033         }
3034 
3035         if (width > (1 << instr->header.execution_size))
3036             width = (1 << instr->header.execution_size);
3037 
3038         vert_stride = horiz_stride * width;
3039         src->reg.vstride = ffs(vert_stride);
3040         src->reg.width = ffs(width) - 1;
3041         src->reg.hstride = ffs(horiz_stride);
3042     } else if ((src->reg.file == BRW_ARCHITECTURE_REGISTER_FILE) &&
3043                (src->reg.nr == BRW_ARF_NULL) &&
3044                (instr->header.opcode == BRW_OPCODE_SEND)) {
3045         src->reg.vstride = ffs(8);
3046         src->reg.width = BRW_WIDTH_8;
3047         src->reg.hstride = ffs(1);
3048     } else {
3049 
3050         int horiz_stride = 1, width, vert_stride;
3051 
3052         if (instr->header.execution_size == 0) { /* scalar */
3053             horiz_stride = 0;
3054             width = 1;
3055             vert_stride = 0;
3056         } else {
3057             if ((instr->header.opcode == BRW_OPCODE_MUL) ||
3058                 (instr->header.opcode == BRW_OPCODE_MAC) ||
3059                 (instr->header.opcode == BRW_OPCODE_CMP) ||
3060                 (instr->header.opcode == BRW_OPCODE_ASR) ||
3061                 (instr->header.opcode == BRW_OPCODE_ADD) ||
3062 				(instr->header.opcode == BRW_OPCODE_SHL)) {
3063                 horiz_stride = 0;
3064                 width = 1;
3065                 vert_stride = 0;
3066             } else {
3067                 width = (1 << instr->header.execution_size) / horiz_stride;
3068                 vert_stride = horiz_stride * width;
3069 
3070                 if (get_type_size(src->reg.type) * (width + src->reg.subnr) > 32) {
3071                     horiz_stride = 0;
3072                     width = 1;
3073                     vert_stride = 0;
3074                 }
3075             }
3076         }
3077 
3078         src->reg.vstride = ffs(vert_stride);
3079         src->reg.width = ffs(width) - 1;
3080         src->reg.hstride = ffs(horiz_stride);
3081     }
3082 }
3083 
set_instruction_opcode(struct brw_program_instruction * instr,unsigned opcode)3084 static void set_instruction_opcode(struct brw_program_instruction *instr,
3085 				  unsigned opcode)
3086 {
3087     if (IS_GENp(8))
3088 	gen8_set_opcode(GEN8(instr), opcode);
3089     else
3090 	GEN(instr)->header.opcode = opcode;
3091 }
3092 
3093 /**
3094  * Fills in the destination register information in instr from the bits in dst.
3095  */
set_instruction_dest(struct brw_program_instruction * instr,struct brw_reg * dest)3096 static int set_instruction_dest(struct brw_program_instruction *instr,
3097 				struct brw_reg *dest)
3098 {
3099 	if (!validate_dst_reg(instr, dest))
3100 		return 1;
3101 
3102 	/* the assembler support expressing subnr in bytes or in number of
3103 	 * elements. */
3104 	resolve_subnr(dest);
3105 
3106 	if (IS_GENp(8)) {
3107 		gen8_set_exec_size(GEN8(instr), dest->width);
3108 		gen8_set_dst(GEN8(instr), *dest);
3109 	} else {
3110 		brw_set_dest(&genasm_compile, GEN(instr), *dest);
3111 	}
3112 
3113 	return 0;
3114 }
3115 
3116 /* Sets the first source operand for the instruction.  Returns 0 on success. */
set_instruction_src0(struct brw_program_instruction * instr,struct src_operand * src,YYLTYPE * location)3117 static int set_instruction_src0(struct brw_program_instruction *instr,
3118 				struct src_operand *src,
3119 				YYLTYPE *location)
3120 {
3121 
3122 	if (advanced_flag)
3123 		reset_instruction_src_region(GEN(instr), src);
3124 
3125 	if (!validate_src_reg(instr, src->reg, location))
3126 		return 1;
3127 
3128 	/* the assembler support expressing subnr in bytes or in number of
3129 	 * elements. */
3130 	resolve_subnr(&src->reg);
3131 
3132 	if (IS_GENp(8))
3133 		gen8_set_src0(GEN8(instr), src->reg);
3134 	else
3135 		brw_set_src0(&genasm_compile, GEN(instr), src->reg);
3136 
3137 	return 0;
3138 }
3139 
3140 /* Sets the second source operand for the instruction.  Returns 0 on success.
3141  */
set_instruction_src1(struct brw_program_instruction * instr,struct src_operand * src,YYLTYPE * location)3142 static int set_instruction_src1(struct brw_program_instruction *instr,
3143 				struct src_operand *src,
3144 				YYLTYPE *location)
3145 {
3146 	if (advanced_flag)
3147 		reset_instruction_src_region(GEN(instr), src);
3148 
3149 	if (!validate_src_reg(instr, src->reg, location))
3150 		return 1;
3151 
3152 	/* the assembler support expressing subnr in bytes or in number of
3153 	 * elements. */
3154 	resolve_subnr(&src->reg);
3155 
3156 	if (IS_GENp(8))
3157 		gen8_set_src1(GEN8(instr), src->reg);
3158 	else
3159 		brw_set_src1(&genasm_compile, GEN(instr), src->reg);
3160 
3161 	return 0;
3162 }
3163 
set_instruction_dest_three_src(struct brw_program_instruction * instr,struct brw_reg * dest)3164 static int set_instruction_dest_three_src(struct brw_program_instruction *instr,
3165 					  struct brw_reg *dest)
3166 {
3167     resolve_subnr(dest);
3168     brw_set_3src_dest(&genasm_compile, GEN(instr), *dest);
3169     return 0;
3170 }
3171 
set_instruction_src0_three_src(struct brw_program_instruction * instr,struct src_operand * src)3172 static int set_instruction_src0_three_src(struct brw_program_instruction *instr,
3173 					  struct src_operand *src)
3174 {
3175     if (advanced_flag)
3176 	reset_instruction_src_region(GEN(instr), src);
3177 
3178     resolve_subnr(&src->reg);
3179 
3180     // TODO: src0 modifier, src0 rep_ctrl
3181     brw_set_3src_src0(&genasm_compile, GEN(instr), src->reg);
3182     return 0;
3183 }
3184 
set_instruction_src1_three_src(struct brw_program_instruction * instr,struct src_operand * src)3185 static int set_instruction_src1_three_src(struct brw_program_instruction *instr,
3186 					  struct src_operand *src)
3187 {
3188     if (advanced_flag)
3189 	reset_instruction_src_region(GEN(instr), src);
3190 
3191     resolve_subnr(&src->reg);
3192 
3193     // TODO: src1 modifier, src1 rep_ctrl
3194     brw_set_3src_src1(&genasm_compile, GEN(instr), src->reg);
3195     return 0;
3196 }
3197 
set_instruction_src2_three_src(struct brw_program_instruction * instr,struct src_operand * src)3198 static int set_instruction_src2_three_src(struct brw_program_instruction *instr,
3199 					  struct src_operand *src)
3200 {
3201     if (advanced_flag)
3202 	reset_instruction_src_region(GEN(instr), src);
3203 
3204     resolve_subnr(&src->reg);
3205 
3206     // TODO: src2 modifier, src2 rep_ctrl
3207     brw_set_3src_src2(&genasm_compile, GEN(instr), src->reg);
3208     return 0;
3209 }
3210 
set_instruction_saturate(struct brw_program_instruction * instr,int saturate)3211 static void set_instruction_saturate(struct brw_program_instruction *instr,
3212 				     int saturate)
3213 {
3214     if (IS_GENp(8))
3215 	gen8_set_saturate(GEN8(instr), saturate);
3216     else
3217 	GEN(instr)->header.saturate = saturate;
3218 }
3219 
set_instruction_options(struct brw_program_instruction * instr,struct options options)3220 static void set_instruction_options(struct brw_program_instruction *instr,
3221 				    struct options options)
3222 {
3223     if (IS_GENp(8)) {
3224 	gen8_set_access_mode(GEN8(instr), options.access_mode);
3225 	gen8_set_thread_control(GEN8(instr), options.thread_control);
3226 	gen8_set_dep_control(GEN8(instr), options.dependency_control);
3227 	gen8_set_mask_control(GEN8(instr), options.mask_control);
3228 	gen8_set_debug_control(GEN8(instr), options.debug_control);
3229 	gen8_set_acc_wr_control(GEN8(instr), options.acc_wr_control);
3230 	gen8_set_eot(GEN8(instr), options.end_of_thread);
3231     } else {
3232 	GEN(instr)->header.access_mode = options.access_mode;
3233 	GEN(instr)->header.compression_control = options.compression_control;
3234 	GEN(instr)->header.thread_control = options.thread_control;
3235 	GEN(instr)->header.dependency_control = options.dependency_control;
3236 	GEN(instr)->header.mask_control = options.mask_control;
3237 	GEN(instr)->header.debug_control = options.debug_control;
3238 	GEN(instr)->header.acc_wr_control = options.acc_wr_control;
3239 	GEN(instr)->bits3.generic.end_of_thread = options.end_of_thread;
3240     }
3241 }
3242 
set_instruction_predicate(struct brw_program_instruction * instr,struct predicate * p)3243 static void set_instruction_predicate(struct brw_program_instruction *instr,
3244 				      struct predicate *p)
3245 {
3246     if (IS_GENp(8)) {
3247 	gen8_set_pred_control(GEN8(instr), p->pred_control);
3248 	gen8_set_pred_inv(GEN8(instr), p->pred_inverse);
3249 	gen8_set_flag_reg_nr(GEN8(instr), p->flag_reg_nr);
3250 	gen8_set_flag_subreg_nr(GEN8(instr), p->flag_subreg_nr);
3251     } else {
3252 	GEN(instr)->header.predicate_control = p->pred_control;
3253 	GEN(instr)->header.predicate_inverse = p->pred_inverse;
3254 	GEN(instr)->bits2.da1.flag_reg_nr = p->flag_reg_nr;
3255 	GEN(instr)->bits2.da1.flag_subreg_nr = p->flag_subreg_nr;
3256     }
3257 }
3258 
set_instruction_pred_cond(struct brw_program_instruction * instr,struct predicate * p,struct condition * c,YYLTYPE * location)3259 static void set_instruction_pred_cond(struct brw_program_instruction *instr,
3260 				      struct predicate *p,
3261 				      struct condition *c,
3262 				      YYLTYPE *location)
3263 {
3264     set_instruction_predicate(instr, p);
3265 
3266     if (IS_GENp(8))
3267 	gen8_set_cond_modifier(GEN8(instr), c->cond);
3268     else
3269 	GEN(instr)->header.destreg__conditionalmod = c->cond;
3270 
3271     if (c->flag_subreg_nr == -1)
3272 	return;
3273 
3274     if (p->pred_control != BRW_PREDICATE_NONE &&
3275 	(p->flag_reg_nr != c->flag_reg_nr ||
3276 	 p->flag_subreg_nr != c->flag_subreg_nr))
3277     {
3278 	warn(ALWAYS, location, "must use the same flag register if both "
3279 	     "prediction and conditional modifier are enabled\n");
3280     }
3281 
3282     if (IS_GENp(8)) {
3283 	gen8_set_flag_reg_nr(GEN8(instr), c->flag_reg_nr);
3284 	gen8_set_flag_subreg_nr(GEN8(instr), c->flag_subreg_nr);
3285     } else {
3286 	GEN(instr)->bits2.da1.flag_reg_nr = c->flag_reg_nr;
3287 	GEN(instr)->bits2.da1.flag_subreg_nr = c->flag_subreg_nr;
3288     }
3289 }
3290 
set_direct_dst_operand(struct brw_reg * dst,struct brw_reg * reg,int type)3291 static void set_direct_dst_operand(struct brw_reg *dst, struct brw_reg *reg,
3292 				   int type)
3293 {
3294 	*dst = *reg;
3295 	dst->address_mode = BRW_ADDRESS_DIRECT;
3296 	dst->type = type;
3297 	dst->hstride = 1;
3298 	dst->dw1.bits.writemask = BRW_WRITEMASK_XYZW;
3299 }
3300 
set_direct_src_operand(struct src_operand * src,struct brw_reg * reg,int type)3301 static void set_direct_src_operand(struct src_operand *src, struct brw_reg *reg,
3302 				   int type)
3303 {
3304 	memset(src, 0, sizeof(*src));
3305 	src->reg.address_mode = BRW_ADDRESS_DIRECT;
3306 	src->reg.file = reg->file;
3307 	src->reg.type = type;
3308 	src->reg.subnr = reg->subnr;
3309 	src->reg.nr = reg->nr;
3310 	src->reg.vstride = 0;
3311 	src->reg.width = 0;
3312 	src->reg.hstride = 0;
3313 	src->reg.negate = 0;
3314 	src->reg.abs = 0;
3315 	SWIZZLE(src->reg) = BRW_SWIZZLE_NOOP;
3316 }
3317 
instruction_opcode(struct brw_program_instruction * insn)3318 static inline int instruction_opcode(struct brw_program_instruction *insn)
3319 {
3320     if (IS_GENp(8))
3321 	return gen8_opcode(GEN8(insn));
3322     else
3323 	return GEN(insn)->header.opcode;
3324 }
3325 
3326 /*
3327  * return the offset used in native flow control (branch) instructions
3328  */
branch_offset(struct brw_program_instruction * insn,int offset)3329 static inline int branch_offset(struct brw_program_instruction *insn, int offset)
3330 {
3331     /*
3332      * bspec: Unlike other flow control instructions, the offset used by JMPI
3333      * is relative to the incremented instruction pointer rather than the IP
3334      * value for the instruction itself.
3335      */
3336     if (instruction_opcode(insn) == BRW_OPCODE_JMPI)
3337         offset--;
3338 
3339     /*
3340      * Gen4- bspec: the jump distance is in number of sixteen-byte units
3341      * Gen5+ bspec: the jump distance is in number of eight-byte units
3342      * Gen7.5+: the offset is in unit of 8bits for JMPI, 64bits for other flow
3343      * control instructions
3344      */
3345     if (gen_level >= 75 &&
3346         (instruction_opcode(insn) == BRW_OPCODE_JMPI))
3347         offset *= 16;
3348     else if (gen_level >= 50)
3349         offset *= 2;
3350 
3351     return offset;
3352 }
3353 
set_branch_two_offsets(struct brw_program_instruction * insn,int jip_offset,int uip_offset)3354 void set_branch_two_offsets(struct brw_program_instruction *insn, int jip_offset, int uip_offset)
3355 {
3356     int jip = branch_offset(insn, jip_offset);
3357     int uip = branch_offset(insn, uip_offset);
3358 
3359     assert(instruction_opcode(insn) != BRW_OPCODE_JMPI);
3360 
3361     if (IS_GENp(8)) {
3362         gen8_set_jip(GEN8(insn), jip);
3363 	gen8_set_uip(GEN8(insn), uip);
3364     } else {
3365         GEN(insn)->bits3.break_cont.jip = jip;
3366         GEN(insn)->bits3.break_cont.uip = uip;
3367     }
3368 }
3369 
set_branch_one_offset(struct brw_program_instruction * insn,int jip_offset)3370 void set_branch_one_offset(struct brw_program_instruction *insn, int jip_offset)
3371 {
3372     int jip = branch_offset(insn, jip_offset);
3373 
3374     if (IS_GENp(8)) {
3375         gen8_set_jip(GEN8(insn), jip);
3376     } else if (IS_GENx(7)) {
3377         /* Gen7 JMPI Restrictions in bspec:
3378          * The JIP data type must be Signed DWord
3379          */
3380         if (instruction_opcode(insn) == BRW_OPCODE_JMPI)
3381             GEN(insn)->bits3.JIP = jip;
3382         else
3383             GEN(insn)->bits3.break_cont.jip = jip;
3384     } else if (IS_GENx(6)) {
3385         if ((instruction_opcode(insn) == BRW_OPCODE_CALL) ||
3386             (instruction_opcode(insn) == BRW_OPCODE_JMPI))
3387             GEN(insn)->bits3.JIP = jip;
3388         else
3389             GEN(insn)->bits1.branch_gen6.jump_count = jip; // for CASE,ELSE,FORK,IF,WHILE
3390     } else {
3391         GEN(insn)->bits3.JIP = jip;
3392 
3393         if (instruction_opcode(insn) == BRW_OPCODE_ELSE)
3394             GEN(insn)->bits3.break_cont.uip = 1; // Set the istack pop count, which must always be 1.
3395     }
3396 }
3397