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