i965: split EU defines to brw_eu_defines.h
[mesa.git] / src / mesa / drivers / dri / i965 / brw_eu.c
1 /*
2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics to
4 develop this 3D driver.
5
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 "Software"), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
13
14 The above copyright notice and this permission notice (including the
15 next paragraph) shall be included in all copies or substantial
16 portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **********************************************************************/
27 /*
28 * Authors:
29 * Keith Whitwell <keithw@vmware.com>
30 */
31
32
33 #include "brw_eu_defines.h"
34 #include "brw_eu.h"
35 #include "brw_shader.h"
36 #include "common/gen_debug.h"
37
38 #include "util/ralloc.h"
39
40 /**
41 * Converts a BRW_REGISTER_TYPE_* enum to a short string (F, UD, and so on).
42 *
43 * This is different than reg_encoding from brw_disasm.c in that it operates
44 * on the abstract enum values, rather than the generation-specific encoding.
45 */
46 const char *
47 brw_reg_type_letters(unsigned type)
48 {
49 const char *names[] = {
50 [BRW_REGISTER_TYPE_UD] = "UD",
51 [BRW_REGISTER_TYPE_D] = "D",
52 [BRW_REGISTER_TYPE_UW] = "UW",
53 [BRW_REGISTER_TYPE_W] = "W",
54 [BRW_REGISTER_TYPE_F] = "F",
55 [BRW_REGISTER_TYPE_UB] = "UB",
56 [BRW_REGISTER_TYPE_B] = "B",
57 [BRW_REGISTER_TYPE_UV] = "UV",
58 [BRW_REGISTER_TYPE_V] = "V",
59 [BRW_REGISTER_TYPE_VF] = "VF",
60 [BRW_REGISTER_TYPE_DF] = "DF",
61 [BRW_REGISTER_TYPE_HF] = "HF",
62 [BRW_REGISTER_TYPE_UQ] = "UQ",
63 [BRW_REGISTER_TYPE_Q] = "Q",
64 };
65 assert(type <= BRW_REGISTER_TYPE_Q);
66 return names[type];
67 }
68
69 /* Returns a conditional modifier that negates the condition. */
70 enum brw_conditional_mod
71 brw_negate_cmod(uint32_t cmod)
72 {
73 switch (cmod) {
74 case BRW_CONDITIONAL_Z:
75 return BRW_CONDITIONAL_NZ;
76 case BRW_CONDITIONAL_NZ:
77 return BRW_CONDITIONAL_Z;
78 case BRW_CONDITIONAL_G:
79 return BRW_CONDITIONAL_LE;
80 case BRW_CONDITIONAL_GE:
81 return BRW_CONDITIONAL_L;
82 case BRW_CONDITIONAL_L:
83 return BRW_CONDITIONAL_GE;
84 case BRW_CONDITIONAL_LE:
85 return BRW_CONDITIONAL_G;
86 default:
87 return ~0;
88 }
89 }
90
91 /* Returns the corresponding conditional mod for swapping src0 and
92 * src1 in e.g. CMP.
93 */
94 enum brw_conditional_mod
95 brw_swap_cmod(uint32_t cmod)
96 {
97 switch (cmod) {
98 case BRW_CONDITIONAL_Z:
99 case BRW_CONDITIONAL_NZ:
100 return cmod;
101 case BRW_CONDITIONAL_G:
102 return BRW_CONDITIONAL_L;
103 case BRW_CONDITIONAL_GE:
104 return BRW_CONDITIONAL_LE;
105 case BRW_CONDITIONAL_L:
106 return BRW_CONDITIONAL_G;
107 case BRW_CONDITIONAL_LE:
108 return BRW_CONDITIONAL_GE;
109 default:
110 return BRW_CONDITIONAL_NONE;
111 }
112 }
113
114 /**
115 * Get the least significant bit offset of the i+1-th component of immediate
116 * type \p type. For \p i equal to the two's complement of j, return the
117 * offset of the j-th component starting from the end of the vector. For
118 * scalar register types return zero.
119 */
120 static unsigned
121 imm_shift(enum brw_reg_type type, unsigned i)
122 {
123 assert(type != BRW_REGISTER_TYPE_UV && type != BRW_REGISTER_TYPE_V &&
124 "Not implemented.");
125
126 if (type == BRW_REGISTER_TYPE_VF)
127 return 8 * (i & 3);
128 else
129 return 0;
130 }
131
132 /**
133 * Swizzle an arbitrary immediate \p x of the given type according to the
134 * permutation specified as \p swz.
135 */
136 uint32_t
137 brw_swizzle_immediate(enum brw_reg_type type, uint32_t x, unsigned swz)
138 {
139 if (imm_shift(type, 1)) {
140 const unsigned n = 32 / imm_shift(type, 1);
141 uint32_t y = 0;
142
143 for (unsigned i = 0; i < n; i++) {
144 /* Shift the specified component all the way to the right and left to
145 * discard any undesired L/MSBs, then shift it right into component i.
146 */
147 y |= x >> imm_shift(type, (i & ~3) + BRW_GET_SWZ(swz, i & 3))
148 << imm_shift(type, ~0u)
149 >> imm_shift(type, ~0u - i);
150 }
151
152 return y;
153 } else {
154 return x;
155 }
156 }
157
158 void
159 brw_set_default_exec_size(struct brw_codegen *p, unsigned value)
160 {
161 brw_inst_set_exec_size(p->devinfo, p->current, value);
162 }
163
164 void brw_set_default_predicate_control( struct brw_codegen *p, unsigned pc )
165 {
166 brw_inst_set_pred_control(p->devinfo, p->current, pc);
167 }
168
169 void brw_set_default_predicate_inverse(struct brw_codegen *p, bool predicate_inverse)
170 {
171 brw_inst_set_pred_inv(p->devinfo, p->current, predicate_inverse);
172 }
173
174 void brw_set_default_flag_reg(struct brw_codegen *p, int reg, int subreg)
175 {
176 if (p->devinfo->gen >= 7)
177 brw_inst_set_flag_reg_nr(p->devinfo, p->current, reg);
178
179 brw_inst_set_flag_subreg_nr(p->devinfo, p->current, subreg);
180 }
181
182 void brw_set_default_access_mode( struct brw_codegen *p, unsigned access_mode )
183 {
184 brw_inst_set_access_mode(p->devinfo, p->current, access_mode);
185 }
186
187 void
188 brw_set_default_compression_control(struct brw_codegen *p,
189 enum brw_compression compression_control)
190 {
191 if (p->devinfo->gen >= 6) {
192 /* Since we don't use the SIMD32 support in gen6, we translate
193 * the pre-gen6 compression control here.
194 */
195 switch (compression_control) {
196 case BRW_COMPRESSION_NONE:
197 /* This is the "use the first set of bits of dmask/vmask/arf
198 * according to execsize" option.
199 */
200 brw_inst_set_qtr_control(p->devinfo, p->current, GEN6_COMPRESSION_1Q);
201 break;
202 case BRW_COMPRESSION_2NDHALF:
203 /* For SIMD8, this is "use the second set of 8 bits." */
204 brw_inst_set_qtr_control(p->devinfo, p->current, GEN6_COMPRESSION_2Q);
205 break;
206 case BRW_COMPRESSION_COMPRESSED:
207 /* For SIMD16 instruction compression, use the first set of 16 bits
208 * since we don't do SIMD32 dispatch.
209 */
210 brw_inst_set_qtr_control(p->devinfo, p->current, GEN6_COMPRESSION_1H);
211 break;
212 default:
213 unreachable("not reached");
214 }
215 } else {
216 brw_inst_set_qtr_control(p->devinfo, p->current, compression_control);
217 }
218 }
219
220 /**
221 * Enable or disable instruction compression on the given instruction leaving
222 * the currently selected channel enable group untouched.
223 */
224 void
225 brw_inst_set_compression(const struct gen_device_info *devinfo,
226 brw_inst *inst, bool on)
227 {
228 if (devinfo->gen >= 6) {
229 /* No-op, the EU will figure out for us whether the instruction needs to
230 * be compressed.
231 */
232 } else {
233 /* The channel group and compression controls are non-orthogonal, there
234 * are two possible representations for uncompressed instructions and we
235 * may need to preserve the current one to avoid changing the selected
236 * channel group inadvertently.
237 */
238 if (on)
239 brw_inst_set_qtr_control(devinfo, inst, BRW_COMPRESSION_COMPRESSED);
240 else if (brw_inst_qtr_control(devinfo, inst)
241 == BRW_COMPRESSION_COMPRESSED)
242 brw_inst_set_qtr_control(devinfo, inst, BRW_COMPRESSION_NONE);
243 }
244 }
245
246 void
247 brw_set_default_compression(struct brw_codegen *p, bool on)
248 {
249 brw_inst_set_compression(p->devinfo, p->current, on);
250 }
251
252 /**
253 * Apply the range of channel enable signals given by
254 * [group, group + exec_size) to the instruction passed as argument.
255 */
256 void
257 brw_inst_set_group(const struct gen_device_info *devinfo,
258 brw_inst *inst, unsigned group)
259 {
260 if (devinfo->gen >= 7) {
261 assert(group % 4 == 0 && group < 32);
262 brw_inst_set_qtr_control(devinfo, inst, group / 8);
263 brw_inst_set_nib_control(devinfo, inst, (group / 4) % 2);
264
265 } else if (devinfo->gen == 6) {
266 assert(group % 8 == 0 && group < 32);
267 brw_inst_set_qtr_control(devinfo, inst, group / 8);
268
269 } else {
270 assert(group % 8 == 0 && group < 16);
271 /* The channel group and compression controls are non-orthogonal, there
272 * are two possible representations for group zero and we may need to
273 * preserve the current one to avoid changing the selected compression
274 * enable inadvertently.
275 */
276 if (group == 8)
277 brw_inst_set_qtr_control(devinfo, inst, BRW_COMPRESSION_2NDHALF);
278 else if (brw_inst_qtr_control(devinfo, inst) == BRW_COMPRESSION_2NDHALF)
279 brw_inst_set_qtr_control(devinfo, inst, BRW_COMPRESSION_NONE);
280 }
281 }
282
283 void
284 brw_set_default_group(struct brw_codegen *p, unsigned group)
285 {
286 brw_inst_set_group(p->devinfo, p->current, group);
287 }
288
289 void brw_set_default_mask_control( struct brw_codegen *p, unsigned value )
290 {
291 brw_inst_set_mask_control(p->devinfo, p->current, value);
292 }
293
294 void brw_set_default_saturate( struct brw_codegen *p, bool enable )
295 {
296 brw_inst_set_saturate(p->devinfo, p->current, enable);
297 }
298
299 void brw_set_default_acc_write_control(struct brw_codegen *p, unsigned value)
300 {
301 if (p->devinfo->gen >= 6)
302 brw_inst_set_acc_wr_control(p->devinfo, p->current, value);
303 }
304
305 void brw_push_insn_state( struct brw_codegen *p )
306 {
307 assert(p->current != &p->stack[BRW_EU_MAX_INSN_STACK-1]);
308 memcpy(p->current + 1, p->current, sizeof(brw_inst));
309 p->current++;
310 }
311
312 void brw_pop_insn_state( struct brw_codegen *p )
313 {
314 assert(p->current != p->stack);
315 p->current--;
316 }
317
318
319 /***********************************************************************
320 */
321 void
322 brw_init_codegen(const struct gen_device_info *devinfo,
323 struct brw_codegen *p, void *mem_ctx)
324 {
325 memset(p, 0, sizeof(*p));
326
327 p->devinfo = devinfo;
328 /*
329 * Set the initial instruction store array size to 1024, if found that
330 * isn't enough, then it will double the store size at brw_next_insn()
331 * until out of memory.
332 */
333 p->store_size = 1024;
334 p->store = rzalloc_array(mem_ctx, brw_inst, p->store_size);
335 p->nr_insn = 0;
336 p->current = p->stack;
337 memset(p->current, 0, sizeof(p->current[0]));
338
339 p->mem_ctx = mem_ctx;
340
341 /* Some defaults?
342 */
343 brw_set_default_exec_size(p, BRW_EXECUTE_8);
344 brw_set_default_mask_control(p, BRW_MASK_ENABLE); /* what does this do? */
345 brw_set_default_saturate(p, 0);
346 brw_set_default_compression_control(p, BRW_COMPRESSION_NONE);
347
348 /* Set up control flow stack */
349 p->if_stack_depth = 0;
350 p->if_stack_array_size = 16;
351 p->if_stack = rzalloc_array(mem_ctx, int, p->if_stack_array_size);
352
353 p->loop_stack_depth = 0;
354 p->loop_stack_array_size = 16;
355 p->loop_stack = rzalloc_array(mem_ctx, int, p->loop_stack_array_size);
356 p->if_depth_in_loop = rzalloc_array(mem_ctx, int, p->loop_stack_array_size);
357 }
358
359
360 const unsigned *brw_get_program( struct brw_codegen *p,
361 unsigned *sz )
362 {
363 *sz = p->next_insn_offset;
364 return (const unsigned *)p->store;
365 }
366
367 void
368 brw_disassemble(const struct gen_device_info *devinfo,
369 void *assembly, int start, int end, FILE *out)
370 {
371 bool dump_hex = (INTEL_DEBUG & DEBUG_HEX) != 0;
372
373 for (int offset = start; offset < end;) {
374 brw_inst *insn = assembly + offset;
375 brw_inst uncompacted;
376 bool compacted = brw_inst_cmpt_control(devinfo, insn);
377 if (0)
378 fprintf(out, "0x%08x: ", offset);
379
380 if (compacted) {
381 brw_compact_inst *compacted = (void *)insn;
382 if (dump_hex) {
383 fprintf(out, "0x%08x 0x%08x ",
384 ((uint32_t *)insn)[1],
385 ((uint32_t *)insn)[0]);
386 }
387
388 brw_uncompact_instruction(devinfo, &uncompacted, compacted);
389 insn = &uncompacted;
390 offset += 8;
391 } else {
392 if (dump_hex) {
393 fprintf(out, "0x%08x 0x%08x 0x%08x 0x%08x ",
394 ((uint32_t *)insn)[3],
395 ((uint32_t *)insn)[2],
396 ((uint32_t *)insn)[1],
397 ((uint32_t *)insn)[0]);
398 }
399 offset += 16;
400 }
401
402 brw_disassemble_inst(out, devinfo, insn, compacted);
403 }
404 }
405
406 enum gen {
407 GEN4 = (1 << 0),
408 GEN45 = (1 << 1),
409 GEN5 = (1 << 2),
410 GEN6 = (1 << 3),
411 GEN7 = (1 << 4),
412 GEN75 = (1 << 5),
413 GEN8 = (1 << 6),
414 GEN9 = (1 << 7),
415 GEN_ALL = ~0
416 };
417
418 #define GEN_LT(gen) ((gen) - 1)
419 #define GEN_GE(gen) (~GEN_LT(gen))
420 #define GEN_LE(gen) (GEN_LT(gen) | (gen))
421
422 static const struct opcode_desc opcode_10_descs[] = {
423 { .name = "dim", .nsrc = 1, .ndst = 1, .gens = GEN75 },
424 { .name = "smov", .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN8) },
425 };
426
427 static const struct opcode_desc opcode_35_descs[] = {
428 { .name = "iff", .nsrc = 0, .ndst = 0, .gens = GEN_LE(GEN5) },
429 { .name = "brc", .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN7) },
430 };
431
432 static const struct opcode_desc opcode_38_descs[] = {
433 { .name = "do", .nsrc = 0, .ndst = 0, .gens = GEN_LE(GEN5) },
434 { .name = "case", .nsrc = 0, .ndst = 0, .gens = GEN6 },
435 };
436
437 static const struct opcode_desc opcode_44_descs[] = {
438 { .name = "msave", .nsrc = 0, .ndst = 0, .gens = GEN_LE(GEN5) },
439 { .name = "call", .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN6) },
440 };
441
442 static const struct opcode_desc opcode_45_descs[] = {
443 { .name = "mrest", .nsrc = 0, .ndst = 0, .gens = GEN_LE(GEN5) },
444 { .name = "ret", .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN6) },
445 };
446
447 static const struct opcode_desc opcode_46_descs[] = {
448 { .name = "push", .nsrc = 0, .ndst = 0, .gens = GEN_LE(GEN5) },
449 { .name = "fork", .nsrc = 0, .ndst = 0, .gens = GEN6 },
450 { .name = "goto", .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN8) },
451 };
452
453 static const struct opcode_desc opcode_descs[128] = {
454 [BRW_OPCODE_ILLEGAL] = {
455 .name = "illegal", .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
456 },
457 [BRW_OPCODE_MOV] = {
458 .name = "mov", .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
459 },
460 [BRW_OPCODE_SEL] = {
461 .name = "sel", .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
462 },
463 [BRW_OPCODE_MOVI] = {
464 .name = "movi", .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN45),
465 },
466 [BRW_OPCODE_NOT] = {
467 .name = "not", .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
468 },
469 [BRW_OPCODE_AND] = {
470 .name = "and", .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
471 },
472 [BRW_OPCODE_OR] = {
473 .name = "or", .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
474 },
475 [BRW_OPCODE_XOR] = {
476 .name = "xor", .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
477 },
478 [BRW_OPCODE_SHR] = {
479 .name = "shr", .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
480 },
481 [BRW_OPCODE_SHL] = {
482 .name = "shl", .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
483 },
484 [10] = {
485 .table = opcode_10_descs, .size = ARRAY_SIZE(opcode_10_descs),
486 },
487 /* Reserved - 11 */
488 [BRW_OPCODE_ASR] = {
489 .name = "asr", .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
490 },
491 /* Reserved - 13-15 */
492 [BRW_OPCODE_CMP] = {
493 .name = "cmp", .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
494 },
495 [BRW_OPCODE_CMPN] = {
496 .name = "cmpn", .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
497 },
498 [BRW_OPCODE_CSEL] = {
499 .name = "csel", .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN8),
500 },
501 [BRW_OPCODE_F32TO16] = {
502 .name = "f32to16", .nsrc = 1, .ndst = 1, .gens = GEN7 | GEN75,
503 },
504 [BRW_OPCODE_F16TO32] = {
505 .name = "f16to32", .nsrc = 1, .ndst = 1, .gens = GEN7 | GEN75,
506 },
507 /* Reserved - 21-22 */
508 [BRW_OPCODE_BFREV] = {
509 .name = "bfrev", .nsrc = 1, .ndst = 1, .gens = GEN_GE(GEN7),
510 },
511 [BRW_OPCODE_BFE] = {
512 .name = "bfe", .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN7),
513 },
514 [BRW_OPCODE_BFI1] = {
515 .name = "bfi1", .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN7),
516 },
517 [BRW_OPCODE_BFI2] = {
518 .name = "bfi2", .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN7),
519 },
520 /* Reserved - 27-31 */
521 [BRW_OPCODE_JMPI] = {
522 .name = "jmpi", .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
523 },
524 [33] = {
525 .name = "brd", .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN7),
526 },
527 [BRW_OPCODE_IF] = {
528 .name = "if", .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
529 },
530 [35] = {
531 .table = opcode_35_descs, .size = ARRAY_SIZE(opcode_35_descs),
532 },
533 [BRW_OPCODE_ELSE] = {
534 .name = "else", .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
535 },
536 [BRW_OPCODE_ENDIF] = {
537 .name = "endif", .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
538 },
539 [38] = {
540 .table = opcode_38_descs, .size = ARRAY_SIZE(opcode_38_descs),
541 },
542 [BRW_OPCODE_WHILE] = {
543 .name = "while", .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
544 },
545 [BRW_OPCODE_BREAK] = {
546 .name = "break", .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
547 },
548 [BRW_OPCODE_CONTINUE] = {
549 .name = "cont", .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
550 },
551 [BRW_OPCODE_HALT] = {
552 .name = "halt", .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
553 },
554 [43] = {
555 .name = "calla", .nsrc = 0, .ndst = 0, .gens = GEN_GE(GEN75),
556 },
557 [44] = {
558 .table = opcode_44_descs, .size = ARRAY_SIZE(opcode_44_descs),
559 },
560 [45] = {
561 .table = opcode_45_descs, .size = ARRAY_SIZE(opcode_45_descs),
562 },
563 [46] = {
564 .table = opcode_46_descs, .size = ARRAY_SIZE(opcode_46_descs),
565 },
566 [47] = {
567 .name = "pop", .nsrc = 2, .ndst = 0, .gens = GEN_LE(GEN5),
568 },
569 [BRW_OPCODE_WAIT] = {
570 .name = "wait", .nsrc = 1, .ndst = 0, .gens = GEN_ALL,
571 },
572 [BRW_OPCODE_SEND] = {
573 .name = "send", .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
574 },
575 [BRW_OPCODE_SENDC] = {
576 .name = "sendc", .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
577 },
578 [BRW_OPCODE_SENDS] = {
579 .name = "sends", .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN9),
580 },
581 [BRW_OPCODE_SENDSC] = {
582 .name = "sendsc", .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN9),
583 },
584 /* Reserved 53-55 */
585 [BRW_OPCODE_MATH] = {
586 .name = "math", .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN6),
587 },
588 /* Reserved 57-63 */
589 [BRW_OPCODE_ADD] = {
590 .name = "add", .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
591 },
592 [BRW_OPCODE_MUL] = {
593 .name = "mul", .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
594 },
595 [BRW_OPCODE_AVG] = {
596 .name = "avg", .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
597 },
598 [BRW_OPCODE_FRC] = {
599 .name = "frc", .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
600 },
601 [BRW_OPCODE_RNDU] = {
602 .name = "rndu", .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
603 },
604 [BRW_OPCODE_RNDD] = {
605 .name = "rndd", .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
606 },
607 [BRW_OPCODE_RNDE] = {
608 .name = "rnde", .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
609 },
610 [BRW_OPCODE_RNDZ] = {
611 .name = "rndz", .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
612 },
613 [BRW_OPCODE_MAC] = {
614 .name = "mac", .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
615 },
616 [BRW_OPCODE_MACH] = {
617 .name = "mach", .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
618 },
619 [BRW_OPCODE_LZD] = {
620 .name = "lzd", .nsrc = 1, .ndst = 1, .gens = GEN_ALL,
621 },
622 [BRW_OPCODE_FBH] = {
623 .name = "fbh", .nsrc = 1, .ndst = 1, .gens = GEN_GE(GEN7),
624 },
625 [BRW_OPCODE_FBL] = {
626 .name = "fbl", .nsrc = 1, .ndst = 1, .gens = GEN_GE(GEN7),
627 },
628 [BRW_OPCODE_CBIT] = {
629 .name = "cbit", .nsrc = 1, .ndst = 1, .gens = GEN_GE(GEN7),
630 },
631 [BRW_OPCODE_ADDC] = {
632 .name = "addc", .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN7),
633 },
634 [BRW_OPCODE_SUBB] = {
635 .name = "subb", .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN7),
636 },
637 [BRW_OPCODE_SAD2] = {
638 .name = "sad2", .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
639 },
640 [BRW_OPCODE_SADA2] = {
641 .name = "sada2", .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
642 },
643 /* Reserved 82-83 */
644 [BRW_OPCODE_DP4] = {
645 .name = "dp4", .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
646 },
647 [BRW_OPCODE_DPH] = {
648 .name = "dph", .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
649 },
650 [BRW_OPCODE_DP3] = {
651 .name = "dp3", .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
652 },
653 [BRW_OPCODE_DP2] = {
654 .name = "dp2", .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
655 },
656 /* Reserved 88 */
657 [BRW_OPCODE_LINE] = {
658 .name = "line", .nsrc = 2, .ndst = 1, .gens = GEN_ALL,
659 },
660 [BRW_OPCODE_PLN] = {
661 .name = "pln", .nsrc = 2, .ndst = 1, .gens = GEN_GE(GEN45),
662 },
663 [BRW_OPCODE_MAD] = {
664 .name = "mad", .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN6),
665 },
666 [BRW_OPCODE_LRP] = {
667 .name = "lrp", .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN6),
668 },
669 [93] = {
670 .name = "madm", .nsrc = 3, .ndst = 1, .gens = GEN_GE(GEN8),
671 },
672 /* Reserved 94-124 */
673 [BRW_OPCODE_NENOP] = {
674 .name = "nenop", .nsrc = 0, .ndst = 0, .gens = GEN45,
675 },
676 [BRW_OPCODE_NOP] = {
677 .name = "nop", .nsrc = 0, .ndst = 0, .gens = GEN_ALL,
678 },
679 };
680
681 static enum gen
682 gen_from_devinfo(const struct gen_device_info *devinfo)
683 {
684 switch (devinfo->gen) {
685 case 4: return devinfo->is_g4x ? GEN45 : GEN4;
686 case 5: return GEN5;
687 case 6: return GEN6;
688 case 7: return devinfo->is_haswell ? GEN75 : GEN7;
689 case 8: return GEN8;
690 case 9: return GEN9;
691 default:
692 unreachable("not reached");
693 }
694 }
695
696 /* Return the matching opcode_desc for the specified opcode number and
697 * hardware generation, or NULL if the opcode is not supported by the device.
698 */
699 const struct opcode_desc *
700 brw_opcode_desc(const struct gen_device_info *devinfo, enum opcode opcode)
701 {
702 if (opcode >= ARRAY_SIZE(opcode_descs))
703 return NULL;
704
705 enum gen gen = gen_from_devinfo(devinfo);
706 if (opcode_descs[opcode].gens != 0) {
707 if ((opcode_descs[opcode].gens & gen) != 0) {
708 return &opcode_descs[opcode];
709 }
710 } else if (opcode_descs[opcode].table != NULL) {
711 const struct opcode_desc *table = opcode_descs[opcode].table;
712 for (unsigned i = 0; i < opcode_descs[opcode].size; i++) {
713 if ((table[i].gens & gen) != 0) {
714 return &table[i];
715 }
716 }
717 }
718 return NULL;
719 }