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(®, 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(¬ify_dst, &$3, BRW_REGISTER_TYPE_D);
1516 notify_dst.width = BRW_WIDTH_1;
1517 set_instruction_dest(&$$, ¬ify_dst);
1518 set_direct_src_operand(¬ify_src, &$3, BRW_REGISTER_TYPE_D);
1519 set_instruction_src0(&$$, ¬ify_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