1/* 2 * Copyright © 2008 Keith Packard 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that copyright 7 * notice and this permission notice appear in supporting documentation, and 8 * that the name of the copyright holders not be used in advertising or 9 * publicity pertaining to distribution of the software without specific, 10 * written prior permission. The copyright holders make no representations 11 * about the suitability of this software for any purpose. It is provided "as 12 * is" without express or implied warranty. 13 * 14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20 * OF THIS SOFTWARE. 21 */ 22 23#include <stdio.h> 24#include <string.h> 25#include <stdarg.h> 26 27#include "brw_eu_defines.h" 28#include "brw_inst.h" 29#include "brw_shader.h" 30#include "brw_reg.h" 31#include "brw_inst.h" 32#include "brw_eu.h" 33#include "util/half_float.h" 34 35bool 36brw_has_jip(const struct intel_device_info *devinfo, enum opcode opcode) 37{ 38 if (devinfo->ver < 6) 39 return false; 40 41 return opcode == BRW_OPCODE_IF || 42 opcode == BRW_OPCODE_ELSE || 43 opcode == BRW_OPCODE_ENDIF || 44 opcode == BRW_OPCODE_WHILE || 45 opcode == BRW_OPCODE_BREAK || 46 opcode == BRW_OPCODE_CONTINUE || 47 opcode == BRW_OPCODE_HALT; 48} 49 50bool 51brw_has_uip(const struct intel_device_info *devinfo, enum opcode opcode) 52{ 53 if (devinfo->ver < 6) 54 return false; 55 56 return (devinfo->ver >= 7 && opcode == BRW_OPCODE_IF) || 57 (devinfo->ver >= 8 && opcode == BRW_OPCODE_ELSE) || 58 opcode == BRW_OPCODE_BREAK || 59 opcode == BRW_OPCODE_CONTINUE || 60 opcode == BRW_OPCODE_HALT; 61} 62 63static bool 64has_branch_ctrl(const struct intel_device_info *devinfo, enum opcode opcode) 65{ 66 if (devinfo->ver < 8) 67 return false; 68 69 return opcode == BRW_OPCODE_IF || 70 opcode == BRW_OPCODE_ELSE; 71 /* opcode == BRW_OPCODE_GOTO; */ 72} 73 74static bool 75is_logic_instruction(unsigned opcode) 76{ 77 return opcode == BRW_OPCODE_AND || 78 opcode == BRW_OPCODE_NOT || 79 opcode == BRW_OPCODE_OR || 80 opcode == BRW_OPCODE_XOR; 81} 82 83static bool 84is_send(unsigned opcode) 85{ 86 return opcode == BRW_OPCODE_SEND || 87 opcode == BRW_OPCODE_SENDC || 88 opcode == BRW_OPCODE_SENDS || 89 opcode == BRW_OPCODE_SENDSC; 90} 91 92static bool 93is_split_send(UNUSED const struct intel_device_info *devinfo, unsigned opcode) 94{ 95 if (devinfo->ver >= 12) 96 return is_send(opcode); 97 else 98 return opcode == BRW_OPCODE_SENDS || 99 opcode == BRW_OPCODE_SENDSC; 100} 101 102const char *const conditional_modifier[16] = { 103 [BRW_CONDITIONAL_NONE] = "", 104 [BRW_CONDITIONAL_Z] = ".z", 105 [BRW_CONDITIONAL_NZ] = ".nz", 106 [BRW_CONDITIONAL_G] = ".g", 107 [BRW_CONDITIONAL_GE] = ".ge", 108 [BRW_CONDITIONAL_L] = ".l", 109 [BRW_CONDITIONAL_LE] = ".le", 110 [BRW_CONDITIONAL_R] = ".r", 111 [BRW_CONDITIONAL_O] = ".o", 112 [BRW_CONDITIONAL_U] = ".u", 113}; 114 115static const char *const m_negate[2] = { 116 [0] = "", 117 [1] = "-", 118}; 119 120static const char *const _abs[2] = { 121 [0] = "", 122 [1] = "(abs)", 123}; 124 125static const char *const m_bitnot[2] = { "", "~" }; 126 127static const char *const vert_stride[16] = { 128 [0] = "0", 129 [1] = "1", 130 [2] = "2", 131 [3] = "4", 132 [4] = "8", 133 [5] = "16", 134 [6] = "32", 135 [15] = "VxH", 136}; 137 138static const char *const width[8] = { 139 [0] = "1", 140 [1] = "2", 141 [2] = "4", 142 [3] = "8", 143 [4] = "16", 144}; 145 146static const char *const horiz_stride[4] = { 147 [0] = "0", 148 [1] = "1", 149 [2] = "2", 150 [3] = "4" 151}; 152 153static const char *const chan_sel[4] = { 154 [0] = "x", 155 [1] = "y", 156 [2] = "z", 157 [3] = "w", 158}; 159 160static const char *const debug_ctrl[2] = { 161 [0] = "", 162 [1] = ".breakpoint" 163}; 164 165static const char *const saturate[2] = { 166 [0] = "", 167 [1] = ".sat" 168}; 169 170static const char *const cmpt_ctrl[2] = { 171 [0] = "", 172 [1] = "compacted" 173}; 174 175static const char *const accwr[2] = { 176 [0] = "", 177 [1] = "AccWrEnable" 178}; 179 180static const char *const branch_ctrl[2] = { 181 [0] = "", 182 [1] = "BranchCtrl" 183}; 184 185static const char *const wectrl[2] = { 186 [0] = "", 187 [1] = "WE_all" 188}; 189 190static const char *const exec_size[8] = { 191 [0] = "1", 192 [1] = "2", 193 [2] = "4", 194 [3] = "8", 195 [4] = "16", 196 [5] = "32" 197}; 198 199static const char *const pred_inv[2] = { 200 [0] = "+", 201 [1] = "-" 202}; 203 204const char *const pred_ctrl_align16[16] = { 205 [1] = "", 206 [2] = ".x", 207 [3] = ".y", 208 [4] = ".z", 209 [5] = ".w", 210 [6] = ".any4h", 211 [7] = ".all4h", 212}; 213 214static const char *const pred_ctrl_align1[16] = { 215 [BRW_PREDICATE_NORMAL] = "", 216 [BRW_PREDICATE_ALIGN1_ANYV] = ".anyv", 217 [BRW_PREDICATE_ALIGN1_ALLV] = ".allv", 218 [BRW_PREDICATE_ALIGN1_ANY2H] = ".any2h", 219 [BRW_PREDICATE_ALIGN1_ALL2H] = ".all2h", 220 [BRW_PREDICATE_ALIGN1_ANY4H] = ".any4h", 221 [BRW_PREDICATE_ALIGN1_ALL4H] = ".all4h", 222 [BRW_PREDICATE_ALIGN1_ANY8H] = ".any8h", 223 [BRW_PREDICATE_ALIGN1_ALL8H] = ".all8h", 224 [BRW_PREDICATE_ALIGN1_ANY16H] = ".any16h", 225 [BRW_PREDICATE_ALIGN1_ALL16H] = ".all16h", 226 [BRW_PREDICATE_ALIGN1_ANY32H] = ".any32h", 227 [BRW_PREDICATE_ALIGN1_ALL32H] = ".all32h", 228}; 229 230static const char *const thread_ctrl[4] = { 231 [BRW_THREAD_NORMAL] = "", 232 [BRW_THREAD_ATOMIC] = "atomic", 233 [BRW_THREAD_SWITCH] = "switch", 234}; 235 236static const char *const compr_ctrl[4] = { 237 [0] = "", 238 [1] = "sechalf", 239 [2] = "compr", 240 [3] = "compr4", 241}; 242 243static const char *const dep_ctrl[4] = { 244 [0] = "", 245 [1] = "NoDDClr", 246 [2] = "NoDDChk", 247 [3] = "NoDDClr,NoDDChk", 248}; 249 250static const char *const mask_ctrl[4] = { 251 [0] = "", 252 [1] = "nomask", 253}; 254 255static const char *const access_mode[2] = { 256 [0] = "align1", 257 [1] = "align16", 258}; 259 260static const char *const reg_file[4] = { 261 [0] = "A", 262 [1] = "g", 263 [2] = "m", 264 [3] = "imm", 265}; 266 267static const char *const writemask[16] = { 268 [0x0] = ".", 269 [0x1] = ".x", 270 [0x2] = ".y", 271 [0x3] = ".xy", 272 [0x4] = ".z", 273 [0x5] = ".xz", 274 [0x6] = ".yz", 275 [0x7] = ".xyz", 276 [0x8] = ".w", 277 [0x9] = ".xw", 278 [0xa] = ".yw", 279 [0xb] = ".xyw", 280 [0xc] = ".zw", 281 [0xd] = ".xzw", 282 [0xe] = ".yzw", 283 [0xf] = "", 284}; 285 286static const char *const end_of_thread[2] = { 287 [0] = "", 288 [1] = "EOT" 289}; 290 291/* SFIDs on Gfx4-5 */ 292static const char *const gfx4_sfid[16] = { 293 [BRW_SFID_NULL] = "null", 294 [BRW_SFID_MATH] = "math", 295 [BRW_SFID_SAMPLER] = "sampler", 296 [BRW_SFID_MESSAGE_GATEWAY] = "gateway", 297 [BRW_SFID_DATAPORT_READ] = "read", 298 [BRW_SFID_DATAPORT_WRITE] = "write", 299 [BRW_SFID_URB] = "urb", 300 [BRW_SFID_THREAD_SPAWNER] = "thread_spawner", 301 [BRW_SFID_VME] = "vme", 302}; 303 304static const char *const gfx6_sfid[16] = { 305 [BRW_SFID_NULL] = "null", 306 [BRW_SFID_MATH] = "math", 307 [BRW_SFID_SAMPLER] = "sampler", 308 [BRW_SFID_MESSAGE_GATEWAY] = "gateway", 309 [BRW_SFID_URB] = "urb", 310 [BRW_SFID_THREAD_SPAWNER] = "thread_spawner", 311 [GFX6_SFID_DATAPORT_SAMPLER_CACHE] = "dp_sampler", 312 [GFX6_SFID_DATAPORT_RENDER_CACHE] = "render", 313 [GFX6_SFID_DATAPORT_CONSTANT_CACHE] = "const", 314 [GFX7_SFID_DATAPORT_DATA_CACHE] = "data", 315 [GFX7_SFID_PIXEL_INTERPOLATOR] = "pixel interp", 316 [HSW_SFID_DATAPORT_DATA_CACHE_1] = "dp data 1", 317 [HSW_SFID_CRE] = "cre", 318 [GEN_RT_SFID_RAY_TRACE_ACCELERATOR] = "rt accel", 319 [GFX12_SFID_SLM] = "slm", 320 [GFX12_SFID_TGM] = "tgm", 321 [GFX12_SFID_UGM] = "ugm", 322}; 323 324static const char *const gfx7_gateway_subfuncid[8] = { 325 [BRW_MESSAGE_GATEWAY_SFID_OPEN_GATEWAY] = "open", 326 [BRW_MESSAGE_GATEWAY_SFID_CLOSE_GATEWAY] = "close", 327 [BRW_MESSAGE_GATEWAY_SFID_FORWARD_MSG] = "forward msg", 328 [BRW_MESSAGE_GATEWAY_SFID_GET_TIMESTAMP] = "get timestamp", 329 [BRW_MESSAGE_GATEWAY_SFID_BARRIER_MSG] = "barrier msg", 330 [BRW_MESSAGE_GATEWAY_SFID_UPDATE_GATEWAY_STATE] = "update state", 331 [BRW_MESSAGE_GATEWAY_SFID_MMIO_READ_WRITE] = "mmio read/write", 332}; 333 334static const char *const gfx4_dp_read_port_msg_type[4] = { 335 [0b00] = "OWord Block Read", 336 [0b01] = "OWord Dual Block Read", 337 [0b10] = "Media Block Read", 338 [0b11] = "DWord Scattered Read", 339}; 340 341static const char *const g45_dp_read_port_msg_type[8] = { 342 [0b000] = "OWord Block Read", 343 [0b010] = "OWord Dual Block Read", 344 [0b100] = "Media Block Read", 345 [0b110] = "DWord Scattered Read", 346 [0b001] = "Render Target UNORM Read", 347 [0b011] = "AVC Loop Filter Read", 348}; 349 350static const char *const dp_write_port_msg_type[8] = { 351 [0b000] = "OWord block write", 352 [0b001] = "OWord dual block write", 353 [0b010] = "media block write", 354 [0b011] = "DWord scattered write", 355 [0b100] = "RT write", 356 [0b101] = "streamed VB write", 357 [0b110] = "RT UNORM write", /* G45+ */ 358 [0b111] = "flush render cache", 359}; 360 361static const char *const dp_rc_msg_type_gfx6[16] = { 362 [BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ] = "OWORD block read", 363 [GFX6_DATAPORT_READ_MESSAGE_RENDER_UNORM_READ] = "RT UNORM read", 364 [GFX6_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ] = "OWORD dual block read", 365 [GFX6_DATAPORT_READ_MESSAGE_MEDIA_BLOCK_READ] = "media block read", 366 [GFX6_DATAPORT_READ_MESSAGE_OWORD_UNALIGN_BLOCK_READ] = 367 "OWORD unaligned block read", 368 [GFX6_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ] = "DWORD scattered read", 369 [GFX6_DATAPORT_WRITE_MESSAGE_DWORD_ATOMIC_WRITE] = "DWORD atomic write", 370 [GFX6_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE] = "OWORD block write", 371 [GFX6_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE] = 372 "OWORD dual block write", 373 [GFX6_DATAPORT_WRITE_MESSAGE_MEDIA_BLOCK_WRITE] = "media block write", 374 [GFX6_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE] = 375 "DWORD scattered write", 376 [GFX6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE] = "RT write", 377 [GFX6_DATAPORT_WRITE_MESSAGE_STREAMED_VB_WRITE] = "streamed VB write", 378 [GFX6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_UNORM_WRITE] = "RT UNORM write", 379}; 380 381static const char *const dp_rc_msg_type_gfx7[16] = { 382 [GFX7_DATAPORT_RC_MEDIA_BLOCK_READ] = "media block read", 383 [GFX7_DATAPORT_RC_TYPED_SURFACE_READ] = "typed surface read", 384 [GFX7_DATAPORT_RC_TYPED_ATOMIC_OP] = "typed atomic op", 385 [GFX7_DATAPORT_RC_MEMORY_FENCE] = "memory fence", 386 [GFX7_DATAPORT_RC_MEDIA_BLOCK_WRITE] = "media block write", 387 [GFX7_DATAPORT_RC_RENDER_TARGET_WRITE] = "RT write", 388 [GFX7_DATAPORT_RC_TYPED_SURFACE_WRITE] = "typed surface write" 389}; 390 391static const char *const dp_rc_msg_type_gfx9[16] = { 392 [GFX9_DATAPORT_RC_RENDER_TARGET_WRITE] = "RT write", 393 [GFX9_DATAPORT_RC_RENDER_TARGET_READ] = "RT read" 394}; 395 396static const char *const * 397dp_rc_msg_type(const struct intel_device_info *devinfo) 398{ 399 return (devinfo->ver >= 9 ? dp_rc_msg_type_gfx9 : 400 devinfo->ver >= 7 ? dp_rc_msg_type_gfx7 : 401 devinfo->ver >= 6 ? dp_rc_msg_type_gfx6 : 402 dp_write_port_msg_type); 403} 404 405static const char *const m_rt_write_subtype[] = { 406 [0b000] = "SIMD16", 407 [0b001] = "SIMD16/RepData", 408 [0b010] = "SIMD8/DualSrcLow", 409 [0b011] = "SIMD8/DualSrcHigh", 410 [0b100] = "SIMD8", 411 [0b101] = "SIMD8/ImageWrite", /* Gfx6+ */ 412 [0b111] = "SIMD16/RepData-111", /* no idea how this is different than 1 */ 413}; 414 415static const char *const dp_dc0_msg_type_gfx7[16] = { 416 [GFX7_DATAPORT_DC_OWORD_BLOCK_READ] = "DC OWORD block read", 417 [GFX7_DATAPORT_DC_UNALIGNED_OWORD_BLOCK_READ] = 418 "DC unaligned OWORD block read", 419 [GFX7_DATAPORT_DC_OWORD_DUAL_BLOCK_READ] = "DC OWORD dual block read", 420 [GFX7_DATAPORT_DC_DWORD_SCATTERED_READ] = "DC DWORD scattered read", 421 [GFX7_DATAPORT_DC_BYTE_SCATTERED_READ] = "DC byte scattered read", 422 [GFX7_DATAPORT_DC_UNTYPED_SURFACE_READ] = "DC untyped surface read", 423 [GFX7_DATAPORT_DC_UNTYPED_ATOMIC_OP] = "DC untyped atomic", 424 [GFX7_DATAPORT_DC_MEMORY_FENCE] = "DC mfence", 425 [GFX7_DATAPORT_DC_OWORD_BLOCK_WRITE] = "DC OWORD block write", 426 [GFX7_DATAPORT_DC_OWORD_DUAL_BLOCK_WRITE] = "DC OWORD dual block write", 427 [GFX7_DATAPORT_DC_DWORD_SCATTERED_WRITE] = "DC DWORD scatterd write", 428 [GFX7_DATAPORT_DC_BYTE_SCATTERED_WRITE] = "DC byte scattered write", 429 [GFX7_DATAPORT_DC_UNTYPED_SURFACE_WRITE] = "DC untyped surface write", 430}; 431 432static const char *const dp_oword_block_rw[8] = { 433 [BRW_DATAPORT_OWORD_BLOCK_1_OWORDLOW] = "1-low", 434 [BRW_DATAPORT_OWORD_BLOCK_1_OWORDHIGH] = "1-high", 435 [BRW_DATAPORT_OWORD_BLOCK_2_OWORDS] = "2", 436 [BRW_DATAPORT_OWORD_BLOCK_4_OWORDS] = "4", 437 [BRW_DATAPORT_OWORD_BLOCK_8_OWORDS] = "8", 438}; 439 440static const char *const dp_dc1_msg_type_hsw[32] = { 441 [HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_READ] = "untyped surface read", 442 [HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP] = "DC untyped atomic op", 443 [HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP_SIMD4X2] = 444 "DC untyped 4x2 atomic op", 445 [HSW_DATAPORT_DC_PORT1_MEDIA_BLOCK_READ] = "DC media block read", 446 [HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_READ] = "DC typed surface read", 447 [HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP] = "DC typed atomic", 448 [HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP_SIMD4X2] = "DC typed 4x2 atomic op", 449 [HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_WRITE] = "DC untyped surface write", 450 [HSW_DATAPORT_DC_PORT1_MEDIA_BLOCK_WRITE] = "DC media block write", 451 [HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP] = "DC atomic counter op", 452 [HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP_SIMD4X2] = 453 "DC 4x2 atomic counter op", 454 [HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_WRITE] = "DC typed surface write", 455 [GFX9_DATAPORT_DC_PORT1_A64_SCATTERED_READ] = "DC A64 scattered read", 456 [GFX8_DATAPORT_DC_PORT1_A64_UNTYPED_SURFACE_READ] = "DC A64 untyped surface read", 457 [GFX8_DATAPORT_DC_PORT1_A64_UNTYPED_ATOMIC_OP] = "DC A64 untyped atomic op", 458 [GFX9_DATAPORT_DC_PORT1_A64_OWORD_BLOCK_READ] = "DC A64 oword block read", 459 [GFX9_DATAPORT_DC_PORT1_A64_OWORD_BLOCK_WRITE] = "DC A64 oword block write", 460 [GFX8_DATAPORT_DC_PORT1_A64_UNTYPED_SURFACE_WRITE] = "DC A64 untyped surface write", 461 [GFX8_DATAPORT_DC_PORT1_A64_SCATTERED_WRITE] = "DC A64 scattered write", 462 [GFX9_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_FLOAT_OP] = 463 "DC untyped atomic float op", 464 [GFX9_DATAPORT_DC_PORT1_A64_UNTYPED_ATOMIC_FLOAT_OP] = 465 "DC A64 untyped atomic float op", 466 [GFX12_DATAPORT_DC_PORT1_A64_UNTYPED_ATOMIC_HALF_INT_OP] = 467 "DC A64 untyped atomic half-integer op", 468 [GFX12_DATAPORT_DC_PORT1_A64_UNTYPED_ATOMIC_HALF_FLOAT_OP] = 469 "DC A64 untyped atomic half-float op", 470}; 471 472static const char *const aop[16] = { 473 [BRW_AOP_AND] = "and", 474 [BRW_AOP_OR] = "or", 475 [BRW_AOP_XOR] = "xor", 476 [BRW_AOP_MOV] = "mov", 477 [BRW_AOP_INC] = "inc", 478 [BRW_AOP_DEC] = "dec", 479 [BRW_AOP_ADD] = "add", 480 [BRW_AOP_SUB] = "sub", 481 [BRW_AOP_REVSUB] = "revsub", 482 [BRW_AOP_IMAX] = "imax", 483 [BRW_AOP_IMIN] = "imin", 484 [BRW_AOP_UMAX] = "umax", 485 [BRW_AOP_UMIN] = "umin", 486 [BRW_AOP_CMPWR] = "cmpwr", 487 [BRW_AOP_PREDEC] = "predec", 488}; 489 490static const char *const aop_float[5] = { 491 [BRW_AOP_FMAX] = "fmax", 492 [BRW_AOP_FMIN] = "fmin", 493 [BRW_AOP_FCMPWR] = "fcmpwr", 494 [BRW_AOP_FADD] = "fadd", 495}; 496 497static const char * const pixel_interpolator_msg_types[4] = { 498 [GFX7_PIXEL_INTERPOLATOR_LOC_SHARED_OFFSET] = "per_message_offset", 499 [GFX7_PIXEL_INTERPOLATOR_LOC_SAMPLE] = "sample_position", 500 [GFX7_PIXEL_INTERPOLATOR_LOC_CENTROID] = "centroid", 501 [GFX7_PIXEL_INTERPOLATOR_LOC_PER_SLOT_OFFSET] = "per_slot_offset", 502}; 503 504static const char *const math_function[16] = { 505 [BRW_MATH_FUNCTION_INV] = "inv", 506 [BRW_MATH_FUNCTION_LOG] = "log", 507 [BRW_MATH_FUNCTION_EXP] = "exp", 508 [BRW_MATH_FUNCTION_SQRT] = "sqrt", 509 [BRW_MATH_FUNCTION_RSQ] = "rsq", 510 [BRW_MATH_FUNCTION_SIN] = "sin", 511 [BRW_MATH_FUNCTION_COS] = "cos", 512 [BRW_MATH_FUNCTION_SINCOS] = "sincos", 513 [BRW_MATH_FUNCTION_FDIV] = "fdiv", 514 [BRW_MATH_FUNCTION_POW] = "pow", 515 [BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER] = "intdivmod", 516 [BRW_MATH_FUNCTION_INT_DIV_QUOTIENT] = "intdiv", 517 [BRW_MATH_FUNCTION_INT_DIV_REMAINDER] = "intmod", 518 [GFX8_MATH_FUNCTION_INVM] = "invm", 519 [GFX8_MATH_FUNCTION_RSQRTM] = "rsqrtm", 520}; 521 522static const char *const sync_function[16] = { 523 [TGL_SYNC_NOP] = "nop", 524 [TGL_SYNC_ALLRD] = "allrd", 525 [TGL_SYNC_ALLWR] = "allwr", 526 [TGL_SYNC_BAR] = "bar", 527 [TGL_SYNC_HOST] = "host", 528}; 529 530static const char *const math_saturate[2] = { 531 [0] = "", 532 [1] = "sat" 533}; 534 535static const char *const math_signed[2] = { 536 [0] = "", 537 [1] = "signed" 538}; 539 540static const char *const math_scalar[2] = { 541 [0] = "", 542 [1] = "scalar" 543}; 544 545static const char *const math_precision[2] = { 546 [0] = "", 547 [1] = "partial_precision" 548}; 549 550static const char *const gfx5_urb_opcode[] = { 551 [0] = "urb_write", 552 [1] = "ff_sync", 553}; 554 555static const char *const gfx7_urb_opcode[] = { 556 [BRW_URB_OPCODE_WRITE_HWORD] = "write HWord", 557 [BRW_URB_OPCODE_WRITE_OWORD] = "write OWord", 558 [BRW_URB_OPCODE_READ_HWORD] = "read HWord", 559 [BRW_URB_OPCODE_READ_OWORD] = "read OWord", 560 [GFX7_URB_OPCODE_ATOMIC_MOV] = "atomic mov", /* Gfx7+ */ 561 [GFX7_URB_OPCODE_ATOMIC_INC] = "atomic inc", /* Gfx7+ */ 562 [GFX8_URB_OPCODE_ATOMIC_ADD] = "atomic add", /* Gfx8+ */ 563 [GFX8_URB_OPCODE_SIMD8_WRITE] = "SIMD8 write", /* Gfx8+ */ 564 [GFX8_URB_OPCODE_SIMD8_READ] = "SIMD8 read", /* Gfx8+ */ 565 [GFX125_URB_OPCODE_FENCE] = "fence", /* Gfx12.5+ */ 566 /* [10-15] - reserved */ 567}; 568 569static const char *const urb_swizzle[4] = { 570 [BRW_URB_SWIZZLE_NONE] = "", 571 [BRW_URB_SWIZZLE_INTERLEAVE] = "interleave", 572 [BRW_URB_SWIZZLE_TRANSPOSE] = "transpose", 573}; 574 575static const char *const urb_allocate[2] = { 576 [0] = "", 577 [1] = "allocate" 578}; 579 580static const char *const urb_used[2] = { 581 [0] = "", 582 [1] = "used" 583}; 584 585static const char *const urb_complete[2] = { 586 [0] = "", 587 [1] = "complete" 588}; 589 590static const char *const gfx5_sampler_msg_type[] = { 591 [GFX5_SAMPLER_MESSAGE_SAMPLE] = "sample", 592 [GFX5_SAMPLER_MESSAGE_SAMPLE_BIAS] = "sample_b", 593 [GFX5_SAMPLER_MESSAGE_SAMPLE_LOD] = "sample_l", 594 [GFX5_SAMPLER_MESSAGE_SAMPLE_COMPARE] = "sample_c", 595 [GFX5_SAMPLER_MESSAGE_SAMPLE_DERIVS] = "sample_d", 596 [GFX5_SAMPLER_MESSAGE_SAMPLE_BIAS_COMPARE] = "sample_b_c", 597 [GFX5_SAMPLER_MESSAGE_SAMPLE_LOD_COMPARE] = "sample_l_c", 598 [GFX5_SAMPLER_MESSAGE_SAMPLE_LD] = "ld", 599 [GFX7_SAMPLER_MESSAGE_SAMPLE_GATHER4] = "gather4", 600 [GFX5_SAMPLER_MESSAGE_LOD] = "lod", 601 [GFX5_SAMPLER_MESSAGE_SAMPLE_RESINFO] = "resinfo", 602 [GFX6_SAMPLER_MESSAGE_SAMPLE_SAMPLEINFO] = "sampleinfo", 603 [GFX7_SAMPLER_MESSAGE_SAMPLE_GATHER4_C] = "gather4_c", 604 [GFX7_SAMPLER_MESSAGE_SAMPLE_GATHER4_PO] = "gather4_po", 605 [GFX7_SAMPLER_MESSAGE_SAMPLE_GATHER4_PO_C] = "gather4_po_c", 606 [HSW_SAMPLER_MESSAGE_SAMPLE_DERIV_COMPARE] = "sample_d_c", 607 [GFX9_SAMPLER_MESSAGE_SAMPLE_LZ] = "sample_lz", 608 [GFX9_SAMPLER_MESSAGE_SAMPLE_C_LZ] = "sample_c_lz", 609 [GFX9_SAMPLER_MESSAGE_SAMPLE_LD_LZ] = "ld_lz", 610 [GFX9_SAMPLER_MESSAGE_SAMPLE_LD2DMS_W] = "ld2dms_w", 611 [GFX7_SAMPLER_MESSAGE_SAMPLE_LD_MCS] = "ld_mcs", 612 [GFX7_SAMPLER_MESSAGE_SAMPLE_LD2DMS] = "ld2dms", 613 [GFX7_SAMPLER_MESSAGE_SAMPLE_LD2DSS] = "ld2dss", 614}; 615 616static const char *const gfx5_sampler_simd_mode[4] = { 617 [BRW_SAMPLER_SIMD_MODE_SIMD4X2] = "SIMD4x2", 618 [BRW_SAMPLER_SIMD_MODE_SIMD8] = "SIMD8", 619 [BRW_SAMPLER_SIMD_MODE_SIMD16] = "SIMD16", 620 [BRW_SAMPLER_SIMD_MODE_SIMD32_64] = "SIMD32/64", 621}; 622 623static const char *const sampler_target_format[4] = { 624 [0] = "F", 625 [2] = "UD", 626 [3] = "D" 627}; 628 629static const char *const lsc_operation[] = { 630 [LSC_OP_LOAD] = "load", 631 [LSC_OP_LOAD_CMASK] = "load_cmask", 632 [LSC_OP_STORE] = "store", 633 [LSC_OP_STORE_CMASK] = "store_cmask", 634 [LSC_OP_FENCE] = "fence", 635 [LSC_OP_ATOMIC_INC] = "atomic_inc", 636 [LSC_OP_ATOMIC_DEC] = "atomic_dec", 637 [LSC_OP_ATOMIC_LOAD] = "atomic_load", 638 [LSC_OP_ATOMIC_STORE] = "atomic_store", 639 [LSC_OP_ATOMIC_ADD] = "atomic_add", 640 [LSC_OP_ATOMIC_SUB] = "atomic_sub", 641 [LSC_OP_ATOMIC_MIN] = "atomic_min", 642 [LSC_OP_ATOMIC_MAX] = "atomic_max", 643 [LSC_OP_ATOMIC_UMIN] = "atomic_umin", 644 [LSC_OP_ATOMIC_UMAX] = "atomic_umax", 645 [LSC_OP_ATOMIC_CMPXCHG] = "atomic_cmpxchg", 646 [LSC_OP_ATOMIC_FADD] = "atomic_fadd", 647 [LSC_OP_ATOMIC_FSUB] = "atomic_fsub", 648 [LSC_OP_ATOMIC_FMIN] = "atomic_fmin", 649 [LSC_OP_ATOMIC_FMAX] = "atomic_fmax", 650 [LSC_OP_ATOMIC_FCMPXCHG] = "atomic_fcmpxchg", 651 [LSC_OP_ATOMIC_AND] = "atomic_and", 652 [LSC_OP_ATOMIC_OR] = "atomic_or", 653 [LSC_OP_ATOMIC_XOR] = "atomic_xor", 654}; 655 656static const char *const lsc_addr_surface_type[] = { 657 [LSC_ADDR_SURFTYPE_FLAT] = "flat", 658 [LSC_ADDR_SURFTYPE_BSS] = "bss", 659 [LSC_ADDR_SURFTYPE_SS] = "ss", 660 [LSC_ADDR_SURFTYPE_BTI] = "bti", 661}; 662 663static const char* const lsc_fence_scope[] = { 664 [LSC_FENCE_THREADGROUP] = "threadgroup", 665 [LSC_FENCE_LOCAL] = "local", 666 [LSC_FENCE_TILE] = "tile", 667 [LSC_FENCE_GPU] = "gpu", 668 [LSC_FENCE_ALL_GPU] = "all_gpu", 669 [LSC_FENCE_SYSTEM_RELEASE] = "system_release", 670 [LSC_FENCE_SYSTEM_ACQUIRE] = "system_acquire", 671}; 672 673static const char* const lsc_flush_type[] = { 674 [LSC_FLUSH_TYPE_NONE] = "none", 675 [LSC_FLUSH_TYPE_EVICT] = "evict", 676 [LSC_FLUSH_TYPE_INVALIDATE] = "invalidate", 677 [LSC_FLUSH_TYPE_DISCARD] = "discard", 678 [LSC_FLUSH_TYPE_CLEAN] = "clean", 679 [LSC_FLUSH_TYPE_L3ONLY] = "l3only", 680}; 681 682static const char* const lsc_addr_size[] = { 683 [LSC_ADDR_SIZE_A16] = "a16", 684 [LSC_ADDR_SIZE_A32] = "a32", 685 [LSC_ADDR_SIZE_A64] = "a64", 686}; 687 688static const char* const lsc_backup_fence_routing[] = { 689 [LSC_NORMAL_ROUTING] = "normal_routing", 690 [LSC_ROUTE_TO_LSC] = "route_to_lsc", 691}; 692 693static const char* const lsc_data_size[] = { 694 [LSC_DATA_SIZE_D8] = "d8", 695 [LSC_DATA_SIZE_D16] = "d16", 696 [LSC_DATA_SIZE_D32] = "d32", 697 [LSC_DATA_SIZE_D64] = "d64", 698 [LSC_DATA_SIZE_D8U32] = "d8u32", 699 [LSC_DATA_SIZE_D16U32] = "d16u32", 700 [LSC_DATA_SIZE_D16BF32] = "d16bf32", 701}; 702 703static const char* const lsc_vect_size_str[] = { 704 [LSC_VECT_SIZE_V1] = "V1", 705 [LSC_VECT_SIZE_V2] = "V2", 706 [LSC_VECT_SIZE_V3] = "V3", 707 [LSC_VECT_SIZE_V4] = "V4", 708 [LSC_VECT_SIZE_V8] = "V8", 709 [LSC_VECT_SIZE_V16] = "V16", 710 [LSC_VECT_SIZE_V32] = "V32", 711 [LSC_VECT_SIZE_V64] = "V64", 712}; 713 714static const char* const lsc_cmask_str[] = { 715 [LSC_CMASK_X] = "x", 716 [LSC_CMASK_Y] = "y", 717 [LSC_CMASK_XY] = "xy", 718 [LSC_CMASK_Z] = "z", 719 [LSC_CMASK_XZ] = "xz", 720 [LSC_CMASK_YZ] = "yz", 721 [LSC_CMASK_XYZ] = "xyz", 722 [LSC_CMASK_W] = "w", 723 [LSC_CMASK_XW] = "xw", 724 [LSC_CMASK_YW] = "yw", 725 [LSC_CMASK_XYW] = "xyw", 726 [LSC_CMASK_ZW] = "zw", 727 [LSC_CMASK_XZW] = "xzw", 728 [LSC_CMASK_YZW] = "yzw", 729 [LSC_CMASK_XYZW] = "xyzw", 730}; 731 732static const char* const lsc_cache_load[] = { 733 [LSC_CACHE_LOAD_L1STATE_L3MOCS] = "L1STATE_L3MOCS", 734 [LSC_CACHE_LOAD_L1UC_L3UC] = "L1UC_L3UC", 735 [LSC_CACHE_LOAD_L1UC_L3C] = "L1UC_L3C", 736 [LSC_CACHE_LOAD_L1C_L3UC] = "L1C_L3UC", 737 [LSC_CACHE_LOAD_L1C_L3C] = "L1C_L3C", 738 [LSC_CACHE_LOAD_L1S_L3UC] = "L1S_L3UC", 739 [LSC_CACHE_LOAD_L1S_L3C] = "L1S_L3C", 740 [LSC_CACHE_LOAD_L1IAR_L3C] = "L1IAR_L3C", 741}; 742 743static const char* const lsc_cache_store[] = { 744 [LSC_CACHE_STORE_L1STATE_L3MOCS] = "L1STATE_L3MOCS", 745 [LSC_CACHE_STORE_L1UC_L3UC] = "L1UC_L3UC", 746 [LSC_CACHE_STORE_L1UC_L3WB] = "L1UC_L3WB", 747 [LSC_CACHE_STORE_L1WT_L3UC] = "L1WT_L3UC", 748 [LSC_CACHE_STORE_L1WT_L3WB] = "L1WT_L3WB", 749 [LSC_CACHE_STORE_L1S_L3UC] = "L1S_L3UC", 750 [LSC_CACHE_STORE_L1S_L3WB] = "L1S_L3WB", 751 [LSC_CACHE_STORE_L1WB_L3WB] = "L1WB_L3WB", 752}; 753 754static int column; 755 756static int 757string(FILE *file, const char *string) 758{ 759 fputs(string, file); 760 column += strlen(string); 761 return 0; 762} 763 764static int 765format(FILE *f, const char *format, ...) PRINTFLIKE(2, 3); 766 767static int 768format(FILE *f, const char *format, ...) 769{ 770 char buf[1024]; 771 va_list args; 772 va_start(args, format); 773 774 vsnprintf(buf, sizeof(buf) - 1, format, args); 775 va_end(args); 776 string(f, buf); 777 return 0; 778} 779 780static int 781newline(FILE *f) 782{ 783 putc('\n', f); 784 column = 0; 785 return 0; 786} 787 788static int 789pad(FILE *f, int c) 790{ 791 do 792 string(f, " "); 793 while (column < c); 794 return 0; 795} 796 797static int 798control(FILE *file, const char *name, const char *const ctrl[], 799 unsigned id, int *space) 800{ 801 if (!ctrl[id]) { 802 fprintf(file, "*** invalid %s value %d ", name, id); 803 return 1; 804 } 805 if (ctrl[id][0]) { 806 if (space && *space) 807 string(file, " "); 808 string(file, ctrl[id]); 809 if (space) 810 *space = 1; 811 } 812 return 0; 813} 814 815static int 816print_opcode(FILE *file, const struct intel_device_info *devinfo, 817 enum opcode id) 818{ 819 const struct opcode_desc *desc = brw_opcode_desc(devinfo, id); 820 if (!desc) { 821 format(file, "*** invalid opcode value %d ", id); 822 return 1; 823 } 824 string(file, desc->name); 825 return 0; 826} 827 828static int 829reg(FILE *file, unsigned _reg_file, unsigned _reg_nr) 830{ 831 int err = 0; 832 833 /* Clear the Compr4 instruction compression bit. */ 834 if (_reg_file == BRW_MESSAGE_REGISTER_FILE) 835 _reg_nr &= ~BRW_MRF_COMPR4; 836 837 if (_reg_file == BRW_ARCHITECTURE_REGISTER_FILE) { 838 switch (_reg_nr & 0xf0) { 839 case BRW_ARF_NULL: 840 string(file, "null"); 841 break; 842 case BRW_ARF_ADDRESS: 843 format(file, "a%d", _reg_nr & 0x0f); 844 break; 845 case BRW_ARF_ACCUMULATOR: 846 format(file, "acc%d", _reg_nr & 0x0f); 847 break; 848 case BRW_ARF_FLAG: 849 format(file, "f%d", _reg_nr & 0x0f); 850 break; 851 case BRW_ARF_MASK: 852 format(file, "mask%d", _reg_nr & 0x0f); 853 break; 854 case BRW_ARF_MASK_STACK: 855 format(file, "ms%d", _reg_nr & 0x0f); 856 break; 857 case BRW_ARF_MASK_STACK_DEPTH: 858 format(file, "msd%d", _reg_nr & 0x0f); 859 break; 860 case BRW_ARF_STATE: 861 format(file, "sr%d", _reg_nr & 0x0f); 862 break; 863 case BRW_ARF_CONTROL: 864 format(file, "cr%d", _reg_nr & 0x0f); 865 break; 866 case BRW_ARF_NOTIFICATION_COUNT: 867 format(file, "n%d", _reg_nr & 0x0f); 868 break; 869 case BRW_ARF_IP: 870 string(file, "ip"); 871 return -1; 872 break; 873 case BRW_ARF_TDR: 874 format(file, "tdr0"); 875 return -1; 876 case BRW_ARF_TIMESTAMP: 877 format(file, "tm%d", _reg_nr & 0x0f); 878 break; 879 default: 880 format(file, "ARF%d", _reg_nr); 881 break; 882 } 883 } else { 884 err |= control(file, "src reg file", reg_file, _reg_file, NULL); 885 format(file, "%d", _reg_nr); 886 } 887 return err; 888} 889 890static int 891dest(FILE *file, const struct intel_device_info *devinfo, const brw_inst *inst) 892{ 893 enum brw_reg_type type = brw_inst_dst_type(devinfo, inst); 894 unsigned elem_size = brw_reg_type_to_size(type); 895 int err = 0; 896 897 if (is_split_send(devinfo, brw_inst_opcode(devinfo, inst))) { 898 /* These are fixed for split sends */ 899 type = BRW_REGISTER_TYPE_UD; 900 elem_size = 4; 901 if (devinfo->ver >= 12) { 902 err |= reg(file, brw_inst_send_dst_reg_file(devinfo, inst), 903 brw_inst_dst_da_reg_nr(devinfo, inst)); 904 string(file, brw_reg_type_to_letters(type)); 905 } else if (brw_inst_dst_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) { 906 err |= reg(file, brw_inst_send_dst_reg_file(devinfo, inst), 907 brw_inst_dst_da_reg_nr(devinfo, inst)); 908 unsigned subreg_nr = brw_inst_dst_da16_subreg_nr(devinfo, inst); 909 if (subreg_nr) 910 format(file, ".%u", subreg_nr); 911 string(file, brw_reg_type_to_letters(type)); 912 } else { 913 string(file, "g[a0"); 914 if (brw_inst_dst_ia_subreg_nr(devinfo, inst)) 915 format(file, ".%"PRIu64, brw_inst_dst_ia_subreg_nr(devinfo, inst) / 916 elem_size); 917 if (brw_inst_send_dst_ia16_addr_imm(devinfo, inst)) 918 format(file, " %d", brw_inst_send_dst_ia16_addr_imm(devinfo, inst)); 919 string(file, "]<"); 920 string(file, brw_reg_type_to_letters(type)); 921 } 922 } else if (brw_inst_access_mode(devinfo, inst) == BRW_ALIGN_1) { 923 if (brw_inst_dst_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) { 924 err |= reg(file, brw_inst_dst_reg_file(devinfo, inst), 925 brw_inst_dst_da_reg_nr(devinfo, inst)); 926 if (err == -1) 927 return 0; 928 if (brw_inst_dst_da1_subreg_nr(devinfo, inst)) 929 format(file, ".%"PRIu64, brw_inst_dst_da1_subreg_nr(devinfo, inst) / 930 elem_size); 931 string(file, "<"); 932 err |= control(file, "horiz stride", horiz_stride, 933 brw_inst_dst_hstride(devinfo, inst), NULL); 934 string(file, ">"); 935 string(file, brw_reg_type_to_letters(type)); 936 } else { 937 string(file, "g[a0"); 938 if (brw_inst_dst_ia_subreg_nr(devinfo, inst)) 939 format(file, ".%"PRIu64, brw_inst_dst_ia_subreg_nr(devinfo, inst) / 940 elem_size); 941 if (brw_inst_dst_ia1_addr_imm(devinfo, inst)) 942 format(file, " %d", brw_inst_dst_ia1_addr_imm(devinfo, inst)); 943 string(file, "]<"); 944 err |= control(file, "horiz stride", horiz_stride, 945 brw_inst_dst_hstride(devinfo, inst), NULL); 946 string(file, ">"); 947 string(file, brw_reg_type_to_letters(type)); 948 } 949 } else { 950 if (brw_inst_dst_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) { 951 err |= reg(file, brw_inst_dst_reg_file(devinfo, inst), 952 brw_inst_dst_da_reg_nr(devinfo, inst)); 953 if (err == -1) 954 return 0; 955 if (brw_inst_dst_da16_subreg_nr(devinfo, inst)) 956 format(file, ".%u", 16 / elem_size); 957 string(file, "<1>"); 958 err |= control(file, "writemask", writemask, 959 brw_inst_da16_writemask(devinfo, inst), NULL); 960 string(file, brw_reg_type_to_letters(type)); 961 } else { 962 err = 1; 963 string(file, "Indirect align16 address mode not supported"); 964 } 965 } 966 967 return 0; 968} 969 970static int 971dest_3src(FILE *file, const struct intel_device_info *devinfo, 972 const brw_inst *inst) 973{ 974 bool is_align1 = brw_inst_3src_access_mode(devinfo, inst) == BRW_ALIGN_1; 975 int err = 0; 976 uint32_t reg_file; 977 unsigned subreg_nr; 978 enum brw_reg_type type; 979 980 if (devinfo->ver < 10 && is_align1) 981 return 0; 982 983 if (devinfo->ver == 6 && brw_inst_3src_a16_dst_reg_file(devinfo, inst)) 984 reg_file = BRW_MESSAGE_REGISTER_FILE; 985 else if (devinfo->ver >= 12) 986 reg_file = brw_inst_3src_a1_dst_reg_file(devinfo, inst); 987 else if (is_align1 && brw_inst_3src_a1_dst_reg_file(devinfo, inst)) 988 reg_file = BRW_ARCHITECTURE_REGISTER_FILE; 989 else 990 reg_file = BRW_GENERAL_REGISTER_FILE; 991 992 err |= reg(file, reg_file, brw_inst_3src_dst_reg_nr(devinfo, inst)); 993 if (err == -1) 994 return 0; 995 996 if (is_align1) { 997 type = brw_inst_3src_a1_dst_type(devinfo, inst); 998 subreg_nr = brw_inst_3src_a1_dst_subreg_nr(devinfo, inst); 999 } else { 1000 type = brw_inst_3src_a16_dst_type(devinfo, inst); 1001 subreg_nr = brw_inst_3src_a16_dst_subreg_nr(devinfo, inst) * 4; 1002 } 1003 subreg_nr /= brw_reg_type_to_size(type); 1004 1005 if (subreg_nr) 1006 format(file, ".%u", subreg_nr); 1007 string(file, "<1>"); 1008 1009 if (!is_align1) { 1010 err |= control(file, "writemask", writemask, 1011 brw_inst_3src_a16_dst_writemask(devinfo, inst), NULL); 1012 } 1013 string(file, brw_reg_type_to_letters(type)); 1014 1015 return 0; 1016} 1017 1018static int 1019src_align1_region(FILE *file, 1020 unsigned _vert_stride, unsigned _width, 1021 unsigned _horiz_stride) 1022{ 1023 int err = 0; 1024 string(file, "<"); 1025 err |= control(file, "vert stride", vert_stride, _vert_stride, NULL); 1026 string(file, ","); 1027 err |= control(file, "width", width, _width, NULL); 1028 string(file, ","); 1029 err |= control(file, "horiz_stride", horiz_stride, _horiz_stride, NULL); 1030 string(file, ">"); 1031 return err; 1032} 1033 1034static int 1035src_da1(FILE *file, 1036 const struct intel_device_info *devinfo, 1037 unsigned opcode, 1038 enum brw_reg_type type, unsigned _reg_file, 1039 unsigned _vert_stride, unsigned _width, unsigned _horiz_stride, 1040 unsigned reg_num, unsigned sub_reg_num, unsigned __abs, 1041 unsigned _negate) 1042{ 1043 int err = 0; 1044 1045 if (devinfo->ver >= 8 && is_logic_instruction(opcode)) 1046 err |= control(file, "bitnot", m_bitnot, _negate, NULL); 1047 else 1048 err |= control(file, "negate", m_negate, _negate, NULL); 1049 1050 err |= control(file, "abs", _abs, __abs, NULL); 1051 1052 err |= reg(file, _reg_file, reg_num); 1053 if (err == -1) 1054 return 0; 1055 if (sub_reg_num) { 1056 unsigned elem_size = brw_reg_type_to_size(type); 1057 format(file, ".%d", sub_reg_num / elem_size); /* use formal style like spec */ 1058 } 1059 src_align1_region(file, _vert_stride, _width, _horiz_stride); 1060 string(file, brw_reg_type_to_letters(type)); 1061 return err; 1062} 1063 1064static int 1065src_ia1(FILE *file, 1066 const struct intel_device_info *devinfo, 1067 unsigned opcode, 1068 enum brw_reg_type type, 1069 int _addr_imm, 1070 unsigned _addr_subreg_nr, 1071 unsigned _negate, 1072 unsigned __abs, 1073 unsigned _horiz_stride, unsigned _width, unsigned _vert_stride) 1074{ 1075 int err = 0; 1076 1077 if (devinfo->ver >= 8 && is_logic_instruction(opcode)) 1078 err |= control(file, "bitnot", m_bitnot, _negate, NULL); 1079 else 1080 err |= control(file, "negate", m_negate, _negate, NULL); 1081 1082 err |= control(file, "abs", _abs, __abs, NULL); 1083 1084 string(file, "g[a0"); 1085 if (_addr_subreg_nr) 1086 format(file, ".%d", _addr_subreg_nr); 1087 if (_addr_imm) 1088 format(file, " %d", _addr_imm); 1089 string(file, "]"); 1090 src_align1_region(file, _vert_stride, _width, _horiz_stride); 1091 string(file, brw_reg_type_to_letters(type)); 1092 return err; 1093} 1094 1095static int 1096src_swizzle(FILE *file, unsigned swiz) 1097{ 1098 unsigned x = BRW_GET_SWZ(swiz, BRW_CHANNEL_X); 1099 unsigned y = BRW_GET_SWZ(swiz, BRW_CHANNEL_Y); 1100 unsigned z = BRW_GET_SWZ(swiz, BRW_CHANNEL_Z); 1101 unsigned w = BRW_GET_SWZ(swiz, BRW_CHANNEL_W); 1102 int err = 0; 1103 1104 if (x == y && x == z && x == w) { 1105 string(file, "."); 1106 err |= control(file, "channel select", chan_sel, x, NULL); 1107 } else if (swiz != BRW_SWIZZLE_XYZW) { 1108 string(file, "."); 1109 err |= control(file, "channel select", chan_sel, x, NULL); 1110 err |= control(file, "channel select", chan_sel, y, NULL); 1111 err |= control(file, "channel select", chan_sel, z, NULL); 1112 err |= control(file, "channel select", chan_sel, w, NULL); 1113 } 1114 return err; 1115} 1116 1117static int 1118src_da16(FILE *file, 1119 const struct intel_device_info *devinfo, 1120 unsigned opcode, 1121 enum brw_reg_type type, 1122 unsigned _reg_file, 1123 unsigned _vert_stride, 1124 unsigned _reg_nr, 1125 unsigned _subreg_nr, 1126 unsigned __abs, 1127 unsigned _negate, 1128 unsigned swz_x, unsigned swz_y, unsigned swz_z, unsigned swz_w) 1129{ 1130 int err = 0; 1131 1132 if (devinfo->ver >= 8 && is_logic_instruction(opcode)) 1133 err |= control(file, "bitnot", m_bitnot, _negate, NULL); 1134 else 1135 err |= control(file, "negate", m_negate, _negate, NULL); 1136 1137 err |= control(file, "abs", _abs, __abs, NULL); 1138 1139 err |= reg(file, _reg_file, _reg_nr); 1140 if (err == -1) 1141 return 0; 1142 if (_subreg_nr) { 1143 unsigned elem_size = brw_reg_type_to_size(type); 1144 1145 /* bit4 for subreg number byte addressing. Make this same meaning as 1146 in da1 case, so output looks consistent. */ 1147 format(file, ".%d", 16 / elem_size); 1148 } 1149 string(file, "<"); 1150 err |= control(file, "vert stride", vert_stride, _vert_stride, NULL); 1151 string(file, ">"); 1152 err |= src_swizzle(file, BRW_SWIZZLE4(swz_x, swz_y, swz_z, swz_w)); 1153 string(file, brw_reg_type_to_letters(type)); 1154 return err; 1155} 1156 1157static enum brw_vertical_stride 1158vstride_from_align1_3src_vstride(const struct intel_device_info *devinfo, 1159 enum gfx10_align1_3src_vertical_stride vstride) 1160{ 1161 switch (vstride) { 1162 case BRW_ALIGN1_3SRC_VERTICAL_STRIDE_0: return BRW_VERTICAL_STRIDE_0; 1163 case BRW_ALIGN1_3SRC_VERTICAL_STRIDE_2: 1164 if (devinfo->ver >= 12) 1165 return BRW_VERTICAL_STRIDE_1; 1166 else 1167 return BRW_VERTICAL_STRIDE_2; 1168 case BRW_ALIGN1_3SRC_VERTICAL_STRIDE_4: return BRW_VERTICAL_STRIDE_4; 1169 case BRW_ALIGN1_3SRC_VERTICAL_STRIDE_8: return BRW_VERTICAL_STRIDE_8; 1170 default: 1171 unreachable("not reached"); 1172 } 1173} 1174 1175static enum brw_horizontal_stride 1176hstride_from_align1_3src_hstride(enum gfx10_align1_3src_src_horizontal_stride hstride) 1177{ 1178 switch (hstride) { 1179 case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_0: return BRW_HORIZONTAL_STRIDE_0; 1180 case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_1: return BRW_HORIZONTAL_STRIDE_1; 1181 case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_2: return BRW_HORIZONTAL_STRIDE_2; 1182 case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_4: return BRW_HORIZONTAL_STRIDE_4; 1183 default: 1184 unreachable("not reached"); 1185 } 1186} 1187 1188static enum brw_vertical_stride 1189vstride_from_align1_3src_hstride(enum gfx10_align1_3src_src_horizontal_stride hstride) 1190{ 1191 switch (hstride) { 1192 case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_0: return BRW_VERTICAL_STRIDE_0; 1193 case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_1: return BRW_VERTICAL_STRIDE_1; 1194 case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_2: return BRW_VERTICAL_STRIDE_2; 1195 case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_4: return BRW_VERTICAL_STRIDE_4; 1196 default: 1197 unreachable("not reached"); 1198 } 1199} 1200 1201/* From "GFX10 Regioning Rules for Align1 Ternary Operations" in the 1202 * "Register Region Restrictions" documentation 1203 */ 1204static enum brw_width 1205implied_width(enum brw_vertical_stride _vert_stride, 1206 enum brw_horizontal_stride _horiz_stride) 1207{ 1208 /* "1. Width is 1 when Vertical and Horizontal Strides are both zero." */ 1209 if (_vert_stride == BRW_VERTICAL_STRIDE_0 && 1210 _horiz_stride == BRW_HORIZONTAL_STRIDE_0) { 1211 return BRW_WIDTH_1; 1212 1213 /* "2. Width is equal to vertical stride when Horizontal Stride is zero." */ 1214 } else if (_horiz_stride == BRW_HORIZONTAL_STRIDE_0) { 1215 switch (_vert_stride) { 1216 case BRW_VERTICAL_STRIDE_2: return BRW_WIDTH_2; 1217 case BRW_VERTICAL_STRIDE_4: return BRW_WIDTH_4; 1218 case BRW_VERTICAL_STRIDE_8: return BRW_WIDTH_8; 1219 case BRW_VERTICAL_STRIDE_0: 1220 default: 1221 unreachable("not reached"); 1222 } 1223 1224 } else { 1225 /* FINISHME: Implement these: */ 1226 1227 /* "3. Width is equal to Vertical Stride/Horizontal Stride when both 1228 * Strides are non-zero. 1229 * 1230 * 4. Vertical Stride must not be zero if Horizontal Stride is non-zero. 1231 * This implies Vertical Stride is always greater than Horizontal 1232 * Stride." 1233 * 1234 * Given these statements and the knowledge that the stride and width 1235 * values are encoded in logarithmic form, we can perform the division 1236 * by just subtracting. 1237 */ 1238 return _vert_stride - _horiz_stride; 1239 } 1240} 1241 1242static int 1243src0_3src(FILE *file, const struct intel_device_info *devinfo, 1244 const brw_inst *inst) 1245{ 1246 int err = 0; 1247 unsigned reg_nr, subreg_nr; 1248 enum brw_reg_file _file; 1249 enum brw_reg_type type; 1250 enum brw_vertical_stride _vert_stride; 1251 enum brw_width _width; 1252 enum brw_horizontal_stride _horiz_stride; 1253 bool is_scalar_region; 1254 bool is_align1 = brw_inst_3src_access_mode(devinfo, inst) == BRW_ALIGN_1; 1255 1256 if (devinfo->ver < 10 && is_align1) 1257 return 0; 1258 1259 if (is_align1) { 1260 if (devinfo->ver >= 12 && !brw_inst_3src_a1_src0_is_imm(devinfo, inst)) { 1261 _file = brw_inst_3src_a1_src0_reg_file(devinfo, inst); 1262 } else if (brw_inst_3src_a1_src0_reg_file(devinfo, inst) == 1263 BRW_ALIGN1_3SRC_GENERAL_REGISTER_FILE) { 1264 _file = BRW_GENERAL_REGISTER_FILE; 1265 } else if (brw_inst_3src_a1_src0_type(devinfo, inst) == 1266 BRW_REGISTER_TYPE_NF) { 1267 _file = BRW_ARCHITECTURE_REGISTER_FILE; 1268 } else { 1269 _file = BRW_IMMEDIATE_VALUE; 1270 uint16_t imm_val = brw_inst_3src_a1_src0_imm(devinfo, inst); 1271 enum brw_reg_type type = brw_inst_3src_a1_src0_type(devinfo, inst); 1272 1273 if (type == BRW_REGISTER_TYPE_W) { 1274 format(file, "%dW", imm_val); 1275 } else if (type == BRW_REGISTER_TYPE_UW) { 1276 format(file, "0x%04xUW", imm_val); 1277 } else if (type == BRW_REGISTER_TYPE_HF) { 1278 format(file, "0x%04xHF", imm_val); 1279 } 1280 return 0; 1281 } 1282 1283 reg_nr = brw_inst_3src_src0_reg_nr(devinfo, inst); 1284 subreg_nr = brw_inst_3src_a1_src0_subreg_nr(devinfo, inst); 1285 type = brw_inst_3src_a1_src0_type(devinfo, inst); 1286 _vert_stride = vstride_from_align1_3src_vstride( 1287 devinfo, brw_inst_3src_a1_src0_vstride(devinfo, inst)); 1288 _horiz_stride = hstride_from_align1_3src_hstride( 1289 brw_inst_3src_a1_src0_hstride(devinfo, inst)); 1290 _width = implied_width(_vert_stride, _horiz_stride); 1291 } else { 1292 _file = BRW_GENERAL_REGISTER_FILE; 1293 reg_nr = brw_inst_3src_src0_reg_nr(devinfo, inst); 1294 subreg_nr = brw_inst_3src_a16_src0_subreg_nr(devinfo, inst) * 4; 1295 type = brw_inst_3src_a16_src_type(devinfo, inst); 1296 1297 if (brw_inst_3src_a16_src0_rep_ctrl(devinfo, inst)) { 1298 _vert_stride = BRW_VERTICAL_STRIDE_0; 1299 _width = BRW_WIDTH_1; 1300 _horiz_stride = BRW_HORIZONTAL_STRIDE_0; 1301 } else { 1302 _vert_stride = BRW_VERTICAL_STRIDE_4; 1303 _width = BRW_WIDTH_4; 1304 _horiz_stride = BRW_HORIZONTAL_STRIDE_1; 1305 } 1306 } 1307 is_scalar_region = _vert_stride == BRW_VERTICAL_STRIDE_0 && 1308 _width == BRW_WIDTH_1 && 1309 _horiz_stride == BRW_HORIZONTAL_STRIDE_0; 1310 1311 subreg_nr /= brw_reg_type_to_size(type); 1312 1313 err |= control(file, "negate", m_negate, 1314 brw_inst_3src_src0_negate(devinfo, inst), NULL); 1315 err |= control(file, "abs", _abs, brw_inst_3src_src0_abs(devinfo, inst), NULL); 1316 1317 err |= reg(file, _file, reg_nr); 1318 if (err == -1) 1319 return 0; 1320 if (subreg_nr || is_scalar_region) 1321 format(file, ".%d", subreg_nr); 1322 src_align1_region(file, _vert_stride, _width, _horiz_stride); 1323 if (!is_scalar_region && !is_align1) 1324 err |= src_swizzle(file, brw_inst_3src_a16_src0_swizzle(devinfo, inst)); 1325 string(file, brw_reg_type_to_letters(type)); 1326 return err; 1327} 1328 1329static int 1330src1_3src(FILE *file, const struct intel_device_info *devinfo, 1331 const brw_inst *inst) 1332{ 1333 int err = 0; 1334 unsigned reg_nr, subreg_nr; 1335 enum brw_reg_file _file; 1336 enum brw_reg_type type; 1337 enum brw_vertical_stride _vert_stride; 1338 enum brw_width _width; 1339 enum brw_horizontal_stride _horiz_stride; 1340 bool is_scalar_region; 1341 bool is_align1 = brw_inst_3src_access_mode(devinfo, inst) == BRW_ALIGN_1; 1342 1343 if (devinfo->ver < 10 && is_align1) 1344 return 0; 1345 1346 if (is_align1) { 1347 if (devinfo->ver >= 12) { 1348 _file = brw_inst_3src_a1_src1_reg_file(devinfo, inst); 1349 } else if (brw_inst_3src_a1_src1_reg_file(devinfo, inst) == 1350 BRW_ALIGN1_3SRC_GENERAL_REGISTER_FILE) { 1351 _file = BRW_GENERAL_REGISTER_FILE; 1352 } else { 1353 _file = BRW_ARCHITECTURE_REGISTER_FILE; 1354 } 1355 1356 reg_nr = brw_inst_3src_src1_reg_nr(devinfo, inst); 1357 subreg_nr = brw_inst_3src_a1_src1_subreg_nr(devinfo, inst); 1358 type = brw_inst_3src_a1_src1_type(devinfo, inst); 1359 1360 _vert_stride = vstride_from_align1_3src_vstride( 1361 devinfo, brw_inst_3src_a1_src1_vstride(devinfo, inst)); 1362 _horiz_stride = hstride_from_align1_3src_hstride( 1363 brw_inst_3src_a1_src1_hstride(devinfo, inst)); 1364 _width = implied_width(_vert_stride, _horiz_stride); 1365 } else { 1366 _file = BRW_GENERAL_REGISTER_FILE; 1367 reg_nr = brw_inst_3src_src1_reg_nr(devinfo, inst); 1368 subreg_nr = brw_inst_3src_a16_src1_subreg_nr(devinfo, inst) * 4; 1369 type = brw_inst_3src_a16_src_type(devinfo, inst); 1370 1371 if (brw_inst_3src_a16_src1_rep_ctrl(devinfo, inst)) { 1372 _vert_stride = BRW_VERTICAL_STRIDE_0; 1373 _width = BRW_WIDTH_1; 1374 _horiz_stride = BRW_HORIZONTAL_STRIDE_0; 1375 } else { 1376 _vert_stride = BRW_VERTICAL_STRIDE_4; 1377 _width = BRW_WIDTH_4; 1378 _horiz_stride = BRW_HORIZONTAL_STRIDE_1; 1379 } 1380 } 1381 is_scalar_region = _vert_stride == BRW_VERTICAL_STRIDE_0 && 1382 _width == BRW_WIDTH_1 && 1383 _horiz_stride == BRW_HORIZONTAL_STRIDE_0; 1384 1385 subreg_nr /= brw_reg_type_to_size(type); 1386 1387 err |= control(file, "negate", m_negate, 1388 brw_inst_3src_src1_negate(devinfo, inst), NULL); 1389 err |= control(file, "abs", _abs, brw_inst_3src_src1_abs(devinfo, inst), NULL); 1390 1391 err |= reg(file, _file, reg_nr); 1392 if (err == -1) 1393 return 0; 1394 if (subreg_nr || is_scalar_region) 1395 format(file, ".%d", subreg_nr); 1396 src_align1_region(file, _vert_stride, _width, _horiz_stride); 1397 if (!is_scalar_region && !is_align1) 1398 err |= src_swizzle(file, brw_inst_3src_a16_src1_swizzle(devinfo, inst)); 1399 string(file, brw_reg_type_to_letters(type)); 1400 return err; 1401} 1402 1403static int 1404src2_3src(FILE *file, const struct intel_device_info *devinfo, 1405 const brw_inst *inst) 1406{ 1407 int err = 0; 1408 unsigned reg_nr, subreg_nr; 1409 enum brw_reg_file _file; 1410 enum brw_reg_type type; 1411 enum brw_vertical_stride _vert_stride; 1412 enum brw_width _width; 1413 enum brw_horizontal_stride _horiz_stride; 1414 bool is_scalar_region; 1415 bool is_align1 = brw_inst_3src_access_mode(devinfo, inst) == BRW_ALIGN_1; 1416 1417 if (devinfo->ver < 10 && is_align1) 1418 return 0; 1419 1420 if (is_align1) { 1421 if (devinfo->ver >= 12 && !brw_inst_3src_a1_src2_is_imm(devinfo, inst)) { 1422 _file = brw_inst_3src_a1_src2_reg_file(devinfo, inst); 1423 } else if (brw_inst_3src_a1_src2_reg_file(devinfo, inst) == 1424 BRW_ALIGN1_3SRC_GENERAL_REGISTER_FILE) { 1425 _file = BRW_GENERAL_REGISTER_FILE; 1426 } else { 1427 _file = BRW_IMMEDIATE_VALUE; 1428 uint16_t imm_val = brw_inst_3src_a1_src2_imm(devinfo, inst); 1429 enum brw_reg_type type = brw_inst_3src_a1_src2_type(devinfo, inst); 1430 1431 if (type == BRW_REGISTER_TYPE_W) { 1432 format(file, "%dW", imm_val); 1433 } else if (type == BRW_REGISTER_TYPE_UW) { 1434 format(file, "0x%04xUW", imm_val); 1435 } else if (type == BRW_REGISTER_TYPE_HF) { 1436 format(file, "0x%04xHF", imm_val); 1437 } 1438 return 0; 1439 } 1440 1441 reg_nr = brw_inst_3src_src2_reg_nr(devinfo, inst); 1442 subreg_nr = brw_inst_3src_a1_src2_subreg_nr(devinfo, inst); 1443 type = brw_inst_3src_a1_src2_type(devinfo, inst); 1444 /* FINISHME: No vertical stride on src2. Is using the hstride in place 1445 * correct? Doesn't seem like it, since there's hstride=1 but 1446 * no vstride=1. 1447 */ 1448 _vert_stride = vstride_from_align1_3src_hstride( 1449 brw_inst_3src_a1_src2_hstride(devinfo, inst)); 1450 _horiz_stride = hstride_from_align1_3src_hstride( 1451 brw_inst_3src_a1_src2_hstride(devinfo, inst)); 1452 _width = implied_width(_vert_stride, _horiz_stride); 1453 } else { 1454 _file = BRW_GENERAL_REGISTER_FILE; 1455 reg_nr = brw_inst_3src_src2_reg_nr(devinfo, inst); 1456 subreg_nr = brw_inst_3src_a16_src2_subreg_nr(devinfo, inst) * 4; 1457 type = brw_inst_3src_a16_src_type(devinfo, inst); 1458 1459 if (brw_inst_3src_a16_src2_rep_ctrl(devinfo, inst)) { 1460 _vert_stride = BRW_VERTICAL_STRIDE_0; 1461 _width = BRW_WIDTH_1; 1462 _horiz_stride = BRW_HORIZONTAL_STRIDE_0; 1463 } else { 1464 _vert_stride = BRW_VERTICAL_STRIDE_4; 1465 _width = BRW_WIDTH_4; 1466 _horiz_stride = BRW_HORIZONTAL_STRIDE_1; 1467 } 1468 } 1469 is_scalar_region = _vert_stride == BRW_VERTICAL_STRIDE_0 && 1470 _width == BRW_WIDTH_1 && 1471 _horiz_stride == BRW_HORIZONTAL_STRIDE_0; 1472 1473 subreg_nr /= brw_reg_type_to_size(type); 1474 1475 err |= control(file, "negate", m_negate, 1476 brw_inst_3src_src2_negate(devinfo, inst), NULL); 1477 err |= control(file, "abs", _abs, brw_inst_3src_src2_abs(devinfo, inst), NULL); 1478 1479 err |= reg(file, _file, reg_nr); 1480 if (err == -1) 1481 return 0; 1482 if (subreg_nr || is_scalar_region) 1483 format(file, ".%d", subreg_nr); 1484 src_align1_region(file, _vert_stride, _width, _horiz_stride); 1485 if (!is_scalar_region && !is_align1) 1486 err |= src_swizzle(file, brw_inst_3src_a16_src2_swizzle(devinfo, inst)); 1487 string(file, brw_reg_type_to_letters(type)); 1488 return err; 1489} 1490 1491static int 1492imm(FILE *file, const struct intel_device_info *devinfo, enum brw_reg_type type, 1493 const brw_inst *inst) 1494{ 1495 switch (type) { 1496 case BRW_REGISTER_TYPE_UQ: 1497 format(file, "0x%016"PRIx64"UQ", brw_inst_imm_uq(devinfo, inst)); 1498 break; 1499 case BRW_REGISTER_TYPE_Q: 1500 format(file, "0x%016"PRIx64"Q", brw_inst_imm_uq(devinfo, inst)); 1501 break; 1502 case BRW_REGISTER_TYPE_UD: 1503 format(file, "0x%08xUD", brw_inst_imm_ud(devinfo, inst)); 1504 break; 1505 case BRW_REGISTER_TYPE_D: 1506 format(file, "%dD", brw_inst_imm_d(devinfo, inst)); 1507 break; 1508 case BRW_REGISTER_TYPE_UW: 1509 format(file, "0x%04xUW", (uint16_t) brw_inst_imm_ud(devinfo, inst)); 1510 break; 1511 case BRW_REGISTER_TYPE_W: 1512 format(file, "%dW", (int16_t) brw_inst_imm_d(devinfo, inst)); 1513 break; 1514 case BRW_REGISTER_TYPE_UV: 1515 format(file, "0x%08xUV", brw_inst_imm_ud(devinfo, inst)); 1516 break; 1517 case BRW_REGISTER_TYPE_VF: 1518 format(file, "0x%"PRIx64"VF", brw_inst_bits(inst, 127, 96)); 1519 pad(file, 48); 1520 format(file, "/* [%-gF, %-gF, %-gF, %-gF]VF */", 1521 brw_vf_to_float(brw_inst_imm_ud(devinfo, inst)), 1522 brw_vf_to_float(brw_inst_imm_ud(devinfo, inst) >> 8), 1523 brw_vf_to_float(brw_inst_imm_ud(devinfo, inst) >> 16), 1524 brw_vf_to_float(brw_inst_imm_ud(devinfo, inst) >> 24)); 1525 break; 1526 case BRW_REGISTER_TYPE_V: 1527 format(file, "0x%08xV", brw_inst_imm_ud(devinfo, inst)); 1528 break; 1529 case BRW_REGISTER_TYPE_F: 1530 /* The DIM instruction's src0 uses an F type but contains a 1531 * 64-bit immediate 1532 */ 1533 if (brw_inst_opcode(devinfo, inst) == BRW_OPCODE_DIM) { 1534 format(file, "0x%"PRIx64"F", brw_inst_bits(inst, 127, 64)); 1535 pad(file, 48); 1536 format(file, "/* %-gF */", brw_inst_imm_df(devinfo, inst)); 1537 } else { 1538 format(file, "0x%"PRIx64"F", brw_inst_bits(inst, 127, 96)); 1539 pad(file, 48); 1540 format(file, " /* %-gF */", brw_inst_imm_f(devinfo, inst)); 1541 } 1542 break; 1543 case BRW_REGISTER_TYPE_DF: 1544 format(file, "0x%016"PRIx64"DF", brw_inst_bits(inst, 127, 64)); 1545 pad(file, 48); 1546 format(file, "/* %-gDF */", brw_inst_imm_df(devinfo, inst)); 1547 break; 1548 case BRW_REGISTER_TYPE_HF: 1549 string(file, "Half Float IMM"); 1550 break; 1551 case BRW_REGISTER_TYPE_NF: 1552 case BRW_REGISTER_TYPE_UB: 1553 case BRW_REGISTER_TYPE_B: 1554 format(file, "*** invalid immediate type %d ", type); 1555 } 1556 return 0; 1557} 1558 1559static int 1560src_sends_da(FILE *file, 1561 const struct intel_device_info *devinfo, 1562 enum brw_reg_type type, 1563 enum brw_reg_file _reg_file, 1564 unsigned _reg_nr, 1565 unsigned _reg_subnr) 1566{ 1567 int err = 0; 1568 1569 err |= reg(file, _reg_file, _reg_nr); 1570 if (err == -1) 1571 return 0; 1572 if (_reg_subnr) 1573 format(file, ".1"); 1574 string(file, brw_reg_type_to_letters(type)); 1575 1576 return err; 1577} 1578 1579static int 1580src_sends_ia(FILE *file, 1581 const struct intel_device_info *devinfo, 1582 enum brw_reg_type type, 1583 int _addr_imm, 1584 unsigned _addr_subreg_nr) 1585{ 1586 string(file, "g[a0"); 1587 if (_addr_subreg_nr) 1588 format(file, ".1"); 1589 if (_addr_imm) 1590 format(file, " %d", _addr_imm); 1591 string(file, "]"); 1592 string(file, brw_reg_type_to_letters(type)); 1593 1594 return 0; 1595} 1596 1597static int 1598src_send_desc_ia(FILE *file, 1599 const struct intel_device_info *devinfo, 1600 unsigned _addr_subreg_nr) 1601{ 1602 string(file, "a0"); 1603 if (_addr_subreg_nr) 1604 format(file, ".%d", _addr_subreg_nr); 1605 format(file, "<0>UD"); 1606 1607 return 0; 1608} 1609 1610static int 1611src0(FILE *file, const struct intel_device_info *devinfo, const brw_inst *inst) 1612{ 1613 if (is_split_send(devinfo, brw_inst_opcode(devinfo, inst))) { 1614 if (devinfo->ver >= 12) { 1615 return src_sends_da(file, 1616 devinfo, 1617 BRW_REGISTER_TYPE_UD, 1618 brw_inst_send_src0_reg_file(devinfo, inst), 1619 brw_inst_src0_da_reg_nr(devinfo, inst), 1620 0); 1621 } else if (brw_inst_send_src0_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) { 1622 return src_sends_da(file, 1623 devinfo, 1624 BRW_REGISTER_TYPE_UD, 1625 BRW_GENERAL_REGISTER_FILE, 1626 brw_inst_src0_da_reg_nr(devinfo, inst), 1627 brw_inst_src0_da16_subreg_nr(devinfo, inst)); 1628 } else { 1629 return src_sends_ia(file, 1630 devinfo, 1631 BRW_REGISTER_TYPE_UD, 1632 brw_inst_send_src0_ia16_addr_imm(devinfo, inst), 1633 brw_inst_src0_ia_subreg_nr(devinfo, inst)); 1634 } 1635 } else if (brw_inst_src0_reg_file(devinfo, inst) == BRW_IMMEDIATE_VALUE) { 1636 return imm(file, devinfo, brw_inst_src0_type(devinfo, inst), inst); 1637 } else if (brw_inst_access_mode(devinfo, inst) == BRW_ALIGN_1) { 1638 if (brw_inst_src0_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) { 1639 return src_da1(file, 1640 devinfo, 1641 brw_inst_opcode(devinfo, inst), 1642 brw_inst_src0_type(devinfo, inst), 1643 brw_inst_src0_reg_file(devinfo, inst), 1644 brw_inst_src0_vstride(devinfo, inst), 1645 brw_inst_src0_width(devinfo, inst), 1646 brw_inst_src0_hstride(devinfo, inst), 1647 brw_inst_src0_da_reg_nr(devinfo, inst), 1648 brw_inst_src0_da1_subreg_nr(devinfo, inst), 1649 brw_inst_src0_abs(devinfo, inst), 1650 brw_inst_src0_negate(devinfo, inst)); 1651 } else { 1652 return src_ia1(file, 1653 devinfo, 1654 brw_inst_opcode(devinfo, inst), 1655 brw_inst_src0_type(devinfo, inst), 1656 brw_inst_src0_ia1_addr_imm(devinfo, inst), 1657 brw_inst_src0_ia_subreg_nr(devinfo, inst), 1658 brw_inst_src0_negate(devinfo, inst), 1659 brw_inst_src0_abs(devinfo, inst), 1660 brw_inst_src0_hstride(devinfo, inst), 1661 brw_inst_src0_width(devinfo, inst), 1662 brw_inst_src0_vstride(devinfo, inst)); 1663 } 1664 } else { 1665 if (brw_inst_src0_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) { 1666 return src_da16(file, 1667 devinfo, 1668 brw_inst_opcode(devinfo, inst), 1669 brw_inst_src0_type(devinfo, inst), 1670 brw_inst_src0_reg_file(devinfo, inst), 1671 brw_inst_src0_vstride(devinfo, inst), 1672 brw_inst_src0_da_reg_nr(devinfo, inst), 1673 brw_inst_src0_da16_subreg_nr(devinfo, inst), 1674 brw_inst_src0_abs(devinfo, inst), 1675 brw_inst_src0_negate(devinfo, inst), 1676 brw_inst_src0_da16_swiz_x(devinfo, inst), 1677 brw_inst_src0_da16_swiz_y(devinfo, inst), 1678 brw_inst_src0_da16_swiz_z(devinfo, inst), 1679 brw_inst_src0_da16_swiz_w(devinfo, inst)); 1680 } else { 1681 string(file, "Indirect align16 address mode not supported"); 1682 return 1; 1683 } 1684 } 1685} 1686 1687static int 1688src1(FILE *file, const struct intel_device_info *devinfo, const brw_inst *inst) 1689{ 1690 if (is_split_send(devinfo, brw_inst_opcode(devinfo, inst))) { 1691 return src_sends_da(file, 1692 devinfo, 1693 BRW_REGISTER_TYPE_UD, 1694 brw_inst_send_src1_reg_file(devinfo, inst), 1695 brw_inst_send_src1_reg_nr(devinfo, inst), 1696 0 /* subreg_nr */); 1697 } else if (brw_inst_src1_reg_file(devinfo, inst) == BRW_IMMEDIATE_VALUE) { 1698 return imm(file, devinfo, brw_inst_src1_type(devinfo, inst), inst); 1699 } else if (brw_inst_access_mode(devinfo, inst) == BRW_ALIGN_1) { 1700 if (brw_inst_src1_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) { 1701 return src_da1(file, 1702 devinfo, 1703 brw_inst_opcode(devinfo, inst), 1704 brw_inst_src1_type(devinfo, inst), 1705 brw_inst_src1_reg_file(devinfo, inst), 1706 brw_inst_src1_vstride(devinfo, inst), 1707 brw_inst_src1_width(devinfo, inst), 1708 brw_inst_src1_hstride(devinfo, inst), 1709 brw_inst_src1_da_reg_nr(devinfo, inst), 1710 brw_inst_src1_da1_subreg_nr(devinfo, inst), 1711 brw_inst_src1_abs(devinfo, inst), 1712 brw_inst_src1_negate(devinfo, inst)); 1713 } else { 1714 return src_ia1(file, 1715 devinfo, 1716 brw_inst_opcode(devinfo, inst), 1717 brw_inst_src1_type(devinfo, inst), 1718 brw_inst_src1_ia1_addr_imm(devinfo, inst), 1719 brw_inst_src1_ia_subreg_nr(devinfo, inst), 1720 brw_inst_src1_negate(devinfo, inst), 1721 brw_inst_src1_abs(devinfo, inst), 1722 brw_inst_src1_hstride(devinfo, inst), 1723 brw_inst_src1_width(devinfo, inst), 1724 brw_inst_src1_vstride(devinfo, inst)); 1725 } 1726 } else { 1727 if (brw_inst_src1_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) { 1728 return src_da16(file, 1729 devinfo, 1730 brw_inst_opcode(devinfo, inst), 1731 brw_inst_src1_type(devinfo, inst), 1732 brw_inst_src1_reg_file(devinfo, inst), 1733 brw_inst_src1_vstride(devinfo, inst), 1734 brw_inst_src1_da_reg_nr(devinfo, inst), 1735 brw_inst_src1_da16_subreg_nr(devinfo, inst), 1736 brw_inst_src1_abs(devinfo, inst), 1737 brw_inst_src1_negate(devinfo, inst), 1738 brw_inst_src1_da16_swiz_x(devinfo, inst), 1739 brw_inst_src1_da16_swiz_y(devinfo, inst), 1740 brw_inst_src1_da16_swiz_z(devinfo, inst), 1741 brw_inst_src1_da16_swiz_w(devinfo, inst)); 1742 } else { 1743 string(file, "Indirect align16 address mode not supported"); 1744 return 1; 1745 } 1746 } 1747} 1748 1749static int 1750qtr_ctrl(FILE *file, const struct intel_device_info *devinfo, 1751 const brw_inst *inst) 1752{ 1753 int qtr_ctl = brw_inst_qtr_control(devinfo, inst); 1754 int exec_size = 1 << brw_inst_exec_size(devinfo, inst); 1755 const unsigned nib_ctl = devinfo->ver < 7 ? 0 : 1756 brw_inst_nib_control(devinfo, inst); 1757 1758 if (exec_size < 8 || nib_ctl) { 1759 format(file, " %dN", qtr_ctl * 2 + nib_ctl + 1); 1760 } else if (exec_size == 8) { 1761 switch (qtr_ctl) { 1762 case 0: 1763 string(file, " 1Q"); 1764 break; 1765 case 1: 1766 string(file, " 2Q"); 1767 break; 1768 case 2: 1769 string(file, " 3Q"); 1770 break; 1771 case 3: 1772 string(file, " 4Q"); 1773 break; 1774 } 1775 } else if (exec_size == 16) { 1776 if (qtr_ctl < 2) 1777 string(file, " 1H"); 1778 else 1779 string(file, " 2H"); 1780 } 1781 return 0; 1782} 1783 1784static int 1785swsb(FILE *file, const struct intel_device_info *devinfo, const brw_inst *inst) 1786{ 1787 const enum opcode opcode = brw_inst_opcode(devinfo, inst); 1788 const uint8_t x = brw_inst_swsb(devinfo, inst); 1789 const struct tgl_swsb swsb = tgl_swsb_decode(devinfo, opcode, x); 1790 if (swsb.regdist) 1791 format(file, " %s@%d", 1792 (swsb.pipe == TGL_PIPE_FLOAT ? "F" : 1793 swsb.pipe == TGL_PIPE_INT ? "I" : 1794 swsb.pipe == TGL_PIPE_LONG ? "L" : 1795 swsb.pipe == TGL_PIPE_ALL ? "A" : "" ), 1796 swsb.regdist); 1797 if (swsb.mode) 1798 format(file, " $%d%s", swsb.sbid, 1799 (swsb.mode & TGL_SBID_SET ? "" : 1800 swsb.mode & TGL_SBID_DST ? ".dst" : ".src")); 1801 return 0; 1802} 1803 1804#ifdef DEBUG 1805static __attribute__((__unused__)) int 1806brw_disassemble_imm(const struct intel_device_info *devinfo, 1807 uint32_t dw3, uint32_t dw2, uint32_t dw1, uint32_t dw0) 1808{ 1809 brw_inst inst; 1810 inst.data[0] = (((uint64_t) dw1) << 32) | ((uint64_t) dw0); 1811 inst.data[1] = (((uint64_t) dw3) << 32) | ((uint64_t) dw2); 1812 return brw_disassemble_inst(stderr, devinfo, &inst, false, 0, NULL); 1813} 1814#endif 1815 1816static void 1817write_label(FILE *file, const struct intel_device_info *devinfo, 1818 const struct brw_label *root_label, 1819 int offset, int jump) 1820{ 1821 if (root_label != NULL) { 1822 int to_bytes_scale = sizeof(brw_inst) / brw_jump_scale(devinfo); 1823 const struct brw_label *label = 1824 brw_find_label(root_label, offset + jump * to_bytes_scale); 1825 if (label != NULL) { 1826 format(file, " LABEL%d", label->number); 1827 } 1828 } 1829} 1830 1831static void 1832lsc_disassemble_ex_desc(const struct intel_device_info *devinfo, 1833 uint32_t imm_desc, 1834 uint32_t imm_ex_desc, 1835 FILE *file) 1836{ 1837 const unsigned addr_type = lsc_msg_desc_addr_type(devinfo, imm_desc); 1838 switch (addr_type) { 1839 case LSC_ADDR_SURFTYPE_FLAT: 1840 format(file, "base_offset %u ", 1841 lsc_flat_ex_desc_base_offset(devinfo, imm_ex_desc)); 1842 break; 1843 case LSC_ADDR_SURFTYPE_BSS: 1844 case LSC_ADDR_SURFTYPE_SS: 1845 format(file, "surface_state_index %u ", 1846 lsc_bss_ex_desc_index(devinfo, imm_ex_desc)); 1847 break; 1848 case LSC_ADDR_SURFTYPE_BTI: 1849 format(file, "BTI %u ", 1850 lsc_bti_ex_desc_index(devinfo, imm_ex_desc)); 1851 format(file, "base_offset %u ", 1852 lsc_bti_ex_desc_base_offset(devinfo, imm_ex_desc)); 1853 break; 1854 default: 1855 format(file, "unsupported address surface type %d", addr_type); 1856 break; 1857 } 1858} 1859 1860static inline bool 1861brw_sfid_is_lsc(unsigned sfid) 1862{ 1863 switch (sfid) { 1864 case GFX12_SFID_UGM: 1865 case GFX12_SFID_SLM: 1866 case GFX12_SFID_TGM: 1867 return true; 1868 default: 1869 break; 1870 } 1871 1872 return false; 1873} 1874 1875int 1876brw_disassemble_inst(FILE *file, const struct intel_device_info *devinfo, 1877 const brw_inst *inst, bool is_compacted, 1878 int offset, const struct brw_label *root_label) 1879{ 1880 int err = 0; 1881 int space = 0; 1882 1883 const enum opcode opcode = brw_inst_opcode(devinfo, inst); 1884 const struct opcode_desc *desc = brw_opcode_desc(devinfo, opcode); 1885 1886 if (brw_inst_pred_control(devinfo, inst)) { 1887 string(file, "("); 1888 err |= control(file, "predicate inverse", pred_inv, 1889 brw_inst_pred_inv(devinfo, inst), NULL); 1890 format(file, "f%"PRIu64".%"PRIu64, 1891 devinfo->ver >= 7 ? brw_inst_flag_reg_nr(devinfo, inst) : 0, 1892 brw_inst_flag_subreg_nr(devinfo, inst)); 1893 if (brw_inst_access_mode(devinfo, inst) == BRW_ALIGN_1) { 1894 err |= control(file, "predicate control align1", pred_ctrl_align1, 1895 brw_inst_pred_control(devinfo, inst), NULL); 1896 } else { 1897 err |= control(file, "predicate control align16", pred_ctrl_align16, 1898 brw_inst_pred_control(devinfo, inst), NULL); 1899 } 1900 string(file, ") "); 1901 } 1902 1903 err |= print_opcode(file, devinfo, opcode); 1904 1905 if (!is_send(opcode)) 1906 err |= control(file, "saturate", saturate, brw_inst_saturate(devinfo, inst), 1907 NULL); 1908 1909 err |= control(file, "debug control", debug_ctrl, 1910 brw_inst_debug_control(devinfo, inst), NULL); 1911 1912 if (opcode == BRW_OPCODE_MATH) { 1913 string(file, " "); 1914 err |= control(file, "function", math_function, 1915 brw_inst_math_function(devinfo, inst), NULL); 1916 1917 } else if (opcode == BRW_OPCODE_SYNC) { 1918 string(file, " "); 1919 err |= control(file, "function", sync_function, 1920 brw_inst_cond_modifier(devinfo, inst), NULL); 1921 1922 } else if (!is_send(opcode)) { 1923 err |= control(file, "conditional modifier", conditional_modifier, 1924 brw_inst_cond_modifier(devinfo, inst), NULL); 1925 1926 /* If we're using the conditional modifier, print which flags reg is 1927 * used for it. Note that on gfx6+, the embedded-condition SEL and 1928 * control flow doesn't update flags. 1929 */ 1930 if (brw_inst_cond_modifier(devinfo, inst) && 1931 (devinfo->ver < 6 || (opcode != BRW_OPCODE_SEL && 1932 opcode != BRW_OPCODE_CSEL && 1933 opcode != BRW_OPCODE_IF && 1934 opcode != BRW_OPCODE_WHILE))) { 1935 format(file, ".f%"PRIu64".%"PRIu64, 1936 devinfo->ver >= 7 ? brw_inst_flag_reg_nr(devinfo, inst) : 0, 1937 brw_inst_flag_subreg_nr(devinfo, inst)); 1938 } 1939 } 1940 1941 if (opcode != BRW_OPCODE_NOP && opcode != BRW_OPCODE_NENOP) { 1942 string(file, "("); 1943 err |= control(file, "execution size", exec_size, 1944 brw_inst_exec_size(devinfo, inst), NULL); 1945 string(file, ")"); 1946 } 1947 1948 if (opcode == BRW_OPCODE_SEND && devinfo->ver < 6) 1949 format(file, " %"PRIu64, brw_inst_base_mrf(devinfo, inst)); 1950 1951 if (brw_has_uip(devinfo, opcode)) { 1952 /* Instructions that have UIP also have JIP. */ 1953 pad(file, 16); 1954 string(file, "JIP: "); 1955 write_label(file, devinfo, root_label, offset, brw_inst_jip(devinfo, inst)); 1956 1957 pad(file, 38); 1958 string(file, "UIP: "); 1959 write_label(file, devinfo, root_label, offset, brw_inst_uip(devinfo, inst)); 1960 } else if (brw_has_jip(devinfo, opcode)) { 1961 int jip; 1962 if (devinfo->ver >= 7) { 1963 jip = brw_inst_jip(devinfo, inst); 1964 } else { 1965 jip = brw_inst_gfx6_jump_count(devinfo, inst); 1966 } 1967 1968 pad(file, 16); 1969 string(file, "JIP: "); 1970 write_label(file, devinfo, root_label, offset, jip); 1971 } else if (devinfo->ver < 6 && (opcode == BRW_OPCODE_BREAK || 1972 opcode == BRW_OPCODE_CONTINUE || 1973 opcode == BRW_OPCODE_ELSE)) { 1974 pad(file, 16); 1975 format(file, "Jump: %d", brw_inst_gfx4_jump_count(devinfo, inst)); 1976 pad(file, 32); 1977 format(file, "Pop: %"PRIu64, brw_inst_gfx4_pop_count(devinfo, inst)); 1978 } else if (devinfo->ver < 6 && (opcode == BRW_OPCODE_IF || 1979 opcode == BRW_OPCODE_IFF || 1980 opcode == BRW_OPCODE_HALT || 1981 opcode == BRW_OPCODE_WHILE)) { 1982 pad(file, 16); 1983 format(file, "Jump: %d", brw_inst_gfx4_jump_count(devinfo, inst)); 1984 } else if (devinfo->ver < 6 && opcode == BRW_OPCODE_ENDIF) { 1985 pad(file, 16); 1986 format(file, "Pop: %"PRIu64, brw_inst_gfx4_pop_count(devinfo, inst)); 1987 } else if (opcode == BRW_OPCODE_JMPI) { 1988 pad(file, 16); 1989 err |= src1(file, devinfo, inst); 1990 } else if (desc && desc->nsrc == 3) { 1991 pad(file, 16); 1992 err |= dest_3src(file, devinfo, inst); 1993 1994 pad(file, 32); 1995 err |= src0_3src(file, devinfo, inst); 1996 1997 pad(file, 48); 1998 err |= src1_3src(file, devinfo, inst); 1999 2000 pad(file, 64); 2001 err |= src2_3src(file, devinfo, inst); 2002 } else if (desc) { 2003 if (desc->ndst > 0) { 2004 pad(file, 16); 2005 err |= dest(file, devinfo, inst); 2006 } 2007 2008 if (desc->nsrc > 0) { 2009 pad(file, 32); 2010 err |= src0(file, devinfo, inst); 2011 } 2012 2013 if (desc->nsrc > 1) { 2014 pad(file, 48); 2015 err |= src1(file, devinfo, inst); 2016 } 2017 } 2018 2019 if (is_send(opcode)) { 2020 enum brw_message_target sfid = brw_inst_sfid(devinfo, inst); 2021 2022 bool has_imm_desc = false, has_imm_ex_desc = false; 2023 uint32_t imm_desc = 0, imm_ex_desc = 0; 2024 if (is_split_send(devinfo, opcode)) { 2025 pad(file, 64); 2026 if (brw_inst_send_sel_reg32_desc(devinfo, inst)) { 2027 /* show the indirect descriptor source */ 2028 err |= src_send_desc_ia(file, devinfo, 0); 2029 } else { 2030 has_imm_desc = true; 2031 imm_desc = brw_inst_send_desc(devinfo, inst); 2032 fprintf(file, "0x%08"PRIx32, imm_desc); 2033 } 2034 2035 pad(file, 80); 2036 if (brw_inst_send_sel_reg32_ex_desc(devinfo, inst)) { 2037 /* show the indirect descriptor source */ 2038 err |= src_send_desc_ia(file, devinfo, 2039 brw_inst_send_ex_desc_ia_subreg_nr(devinfo, inst)); 2040 } else { 2041 has_imm_ex_desc = true; 2042 imm_ex_desc = brw_inst_sends_ex_desc(devinfo, inst); 2043 fprintf(file, "0x%08"PRIx32, imm_ex_desc); 2044 } 2045 } else { 2046 if (brw_inst_src1_reg_file(devinfo, inst) != BRW_IMMEDIATE_VALUE) { 2047 /* show the indirect descriptor source */ 2048 pad(file, 48); 2049 err |= src1(file, devinfo, inst); 2050 pad(file, 64); 2051 } else { 2052 has_imm_desc = true; 2053 imm_desc = brw_inst_send_desc(devinfo, inst); 2054 pad(file, 48); 2055 } 2056 2057 /* Print message descriptor as immediate source */ 2058 fprintf(file, "0x%08"PRIx64, inst->data[1] >> 32); 2059 } 2060 2061 newline(file); 2062 pad(file, 16); 2063 space = 0; 2064 2065 fprintf(file, " "); 2066 err |= control(file, "SFID", devinfo->ver >= 6 ? gfx6_sfid : gfx4_sfid, 2067 sfid, &space); 2068 string(file, " MsgDesc:"); 2069 2070 if (!has_imm_desc) { 2071 format(file, " indirect"); 2072 } else { 2073 bool unsupported = false; 2074 switch (sfid) { 2075 case BRW_SFID_MATH: 2076 err |= control(file, "math function", math_function, 2077 brw_inst_math_msg_function(devinfo, inst), &space); 2078 err |= control(file, "math saturate", math_saturate, 2079 brw_inst_math_msg_saturate(devinfo, inst), &space); 2080 err |= control(file, "math signed", math_signed, 2081 brw_inst_math_msg_signed_int(devinfo, inst), &space); 2082 err |= control(file, "math scalar", math_scalar, 2083 brw_inst_math_msg_data_type(devinfo, inst), &space); 2084 err |= control(file, "math precision", math_precision, 2085 brw_inst_math_msg_precision(devinfo, inst), &space); 2086 break; 2087 case BRW_SFID_SAMPLER: 2088 if (devinfo->ver >= 5) { 2089 err |= control(file, "sampler message", gfx5_sampler_msg_type, 2090 brw_sampler_desc_msg_type(devinfo, imm_desc), 2091 &space); 2092 err |= control(file, "sampler simd mode", gfx5_sampler_simd_mode, 2093 brw_sampler_desc_simd_mode(devinfo, imm_desc), 2094 &space); 2095 format(file, " Surface = %u Sampler = %u", 2096 brw_sampler_desc_binding_table_index(devinfo, imm_desc), 2097 brw_sampler_desc_sampler(devinfo, imm_desc)); 2098 } else { 2099 format(file, " (bti %u, sampler %u, msg_type %u, ", 2100 brw_sampler_desc_binding_table_index(devinfo, imm_desc), 2101 brw_sampler_desc_sampler(devinfo, imm_desc), 2102 brw_sampler_desc_msg_type(devinfo, imm_desc)); 2103 if (!devinfo->is_g4x) { 2104 err |= control(file, "sampler target format", 2105 sampler_target_format, 2106 brw_sampler_desc_return_format(devinfo, imm_desc), 2107 NULL); 2108 } 2109 string(file, ")"); 2110 } 2111 break; 2112 case GFX6_SFID_DATAPORT_SAMPLER_CACHE: 2113 case GFX6_SFID_DATAPORT_CONSTANT_CACHE: 2114 /* aka BRW_SFID_DATAPORT_READ on Gfx4-5 */ 2115 if (devinfo->ver >= 6) { 2116 format(file, " (bti %u, msg_ctrl %u, msg_type %u, write_commit %u)", 2117 brw_dp_desc_binding_table_index(devinfo, imm_desc), 2118 brw_dp_desc_msg_control(devinfo, imm_desc), 2119 brw_dp_desc_msg_type(devinfo, imm_desc), 2120 devinfo->ver >= 7 ? 0u : 2121 brw_dp_write_desc_write_commit(devinfo, imm_desc)); 2122 } else { 2123 bool is_965 = devinfo->ver == 4 && !devinfo->is_g4x; 2124 err |= control(file, "DP read message type", 2125 is_965 ? gfx4_dp_read_port_msg_type : 2126 g45_dp_read_port_msg_type, 2127 brw_dp_read_desc_msg_type(devinfo, imm_desc), 2128 &space); 2129 2130 format(file, " MsgCtrl = 0x%u", 2131 brw_dp_read_desc_msg_control(devinfo, imm_desc)); 2132 2133 format(file, " Surface = %u", 2134 brw_dp_desc_binding_table_index(devinfo, imm_desc)); 2135 } 2136 break; 2137 2138 case GFX6_SFID_DATAPORT_RENDER_CACHE: { 2139 /* aka BRW_SFID_DATAPORT_WRITE on Gfx4-5 */ 2140 unsigned msg_type = brw_fb_write_desc_msg_type(devinfo, imm_desc); 2141 2142 err |= control(file, "DP rc message type", 2143 dp_rc_msg_type(devinfo), msg_type, &space); 2144 2145 bool is_rt_write = msg_type == 2146 (devinfo->ver >= 6 ? GFX6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE 2147 : BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE); 2148 2149 if (is_rt_write) { 2150 err |= control(file, "RT message type", m_rt_write_subtype, 2151 brw_inst_rt_message_type(devinfo, inst), &space); 2152 if (devinfo->ver >= 6 && brw_inst_rt_slot_group(devinfo, inst)) 2153 string(file, " Hi"); 2154 if (brw_fb_write_desc_last_render_target(devinfo, imm_desc)) 2155 string(file, " LastRT"); 2156 if (devinfo->ver >= 10 && 2157 brw_fb_write_desc_coarse_write(devinfo, imm_desc)) 2158 string(file, " CoarseWrite"); 2159 if (devinfo->ver < 7 && 2160 brw_fb_write_desc_write_commit(devinfo, imm_desc)) 2161 string(file, " WriteCommit"); 2162 } else { 2163 format(file, " MsgCtrl = 0x%u", 2164 brw_fb_write_desc_msg_control(devinfo, imm_desc)); 2165 } 2166 2167 format(file, " Surface = %u", 2168 brw_fb_desc_binding_table_index(devinfo, imm_desc)); 2169 break; 2170 } 2171 2172 case BRW_SFID_URB: { 2173 unsigned opcode = brw_inst_urb_opcode(devinfo, inst); 2174 2175 format(file, " offset %"PRIu64, brw_inst_urb_global_offset(devinfo, inst)); 2176 2177 space = 1; 2178 2179 err |= control(file, "urb opcode", 2180 devinfo->ver >= 7 ? gfx7_urb_opcode 2181 : gfx5_urb_opcode, 2182 opcode, &space); 2183 2184 if (devinfo->ver >= 7 && 2185 brw_inst_urb_per_slot_offset(devinfo, inst)) { 2186 string(file, " per-slot"); 2187 } 2188 2189 if (opcode == GFX8_URB_OPCODE_SIMD8_WRITE || 2190 opcode == GFX8_URB_OPCODE_SIMD8_READ) { 2191 if (brw_inst_urb_channel_mask_present(devinfo, inst)) 2192 string(file, " masked"); 2193 } else if (opcode != GFX125_URB_OPCODE_FENCE) { 2194 err |= control(file, "urb swizzle", urb_swizzle, 2195 brw_inst_urb_swizzle_control(devinfo, inst), 2196 &space); 2197 } 2198 2199 if (devinfo->ver < 7) { 2200 err |= control(file, "urb allocate", urb_allocate, 2201 brw_inst_urb_allocate(devinfo, inst), &space); 2202 err |= control(file, "urb used", urb_used, 2203 brw_inst_urb_used(devinfo, inst), &space); 2204 } 2205 if (devinfo->ver < 8) { 2206 err |= control(file, "urb complete", urb_complete, 2207 brw_inst_urb_complete(devinfo, inst), &space); 2208 } 2209 break; 2210 } 2211 case BRW_SFID_THREAD_SPAWNER: 2212 break; 2213 2214 case BRW_SFID_MESSAGE_GATEWAY: 2215 format(file, " (%s)", 2216 gfx7_gateway_subfuncid[brw_inst_gateway_subfuncid(devinfo, inst)]); 2217 break; 2218 2219 case GFX12_SFID_SLM: 2220 case GFX12_SFID_TGM: 2221 case GFX12_SFID_UGM: { 2222 assert(devinfo->has_lsc); 2223 format(file, " ("); 2224 const enum lsc_opcode op = lsc_msg_desc_opcode(devinfo, imm_desc); 2225 err |= control(file, "operation", lsc_operation, 2226 op, &space); 2227 format(file, ","); 2228 err |= control(file, "addr_size", lsc_addr_size, 2229 lsc_msg_desc_addr_size(devinfo, imm_desc), 2230 &space); 2231 2232 if (op == LSC_OP_FENCE) { 2233 format(file, ","); 2234 err |= control(file, "scope", lsc_fence_scope, 2235 lsc_fence_msg_desc_scope(devinfo, imm_desc), 2236 &space); 2237 format(file, ","); 2238 err |= control(file, "flush_type", lsc_flush_type, 2239 lsc_fence_msg_desc_flush_type(devinfo, imm_desc), 2240 &space); 2241 format(file, ","); 2242 err |= control(file, "backup_mode_fence_routing", 2243 lsc_backup_fence_routing, 2244 lsc_fence_msg_desc_backup_routing(devinfo, imm_desc), 2245 &space); 2246 } else { 2247 format(file, ","); 2248 err |= control(file, "data_size", lsc_data_size, 2249 lsc_msg_desc_data_size(devinfo, imm_desc), 2250 &space); 2251 format(file, ","); 2252 if (lsc_opcode_has_cmask(op)) { 2253 err |= control(file, "component_mask", 2254 lsc_cmask_str, 2255 lsc_msg_desc_cmask(devinfo, imm_desc), 2256 &space); 2257 } else { 2258 err |= control(file, "vector_size", 2259 lsc_vect_size_str, 2260 lsc_msg_desc_vect_size(devinfo, imm_desc), 2261 &space); 2262 if (lsc_msg_desc_transpose(devinfo, imm_desc)) 2263 format(file, ", transpose"); 2264 } 2265 switch(op) { 2266 case LSC_OP_LOAD_CMASK: 2267 case LSC_OP_LOAD: 2268 format(file, ","); 2269 err |= control(file, "cache_load", 2270 lsc_cache_load, 2271 lsc_msg_desc_cache_ctrl(devinfo, imm_desc), 2272 &space); 2273 break; 2274 default: 2275 format(file, ","); 2276 err |= control(file, "cache_store", 2277 lsc_cache_store, 2278 lsc_msg_desc_cache_ctrl(devinfo, imm_desc), 2279 &space); 2280 break; 2281 } 2282 } 2283 format(file, " dst_len = %u,", lsc_msg_desc_dest_len(devinfo, imm_desc)); 2284 format(file, " src0_len = %u,", lsc_msg_desc_src0_len(devinfo, imm_desc)); 2285 format(file, " src1_len = %d", brw_message_ex_desc_ex_mlen(devinfo, imm_ex_desc)); 2286 err |= control(file, "address_type", lsc_addr_surface_type, 2287 lsc_msg_desc_addr_type(devinfo, imm_desc), &space); 2288 format(file, " )"); 2289 break; 2290 } 2291 2292 case GFX7_SFID_DATAPORT_DATA_CACHE: 2293 if (devinfo->ver >= 7) { 2294 format(file, " ("); 2295 space = 0; 2296 2297 err |= control(file, "DP DC0 message type", 2298 dp_dc0_msg_type_gfx7, 2299 brw_dp_desc_msg_type(devinfo, imm_desc), &space); 2300 2301 format(file, ", bti %u, ", 2302 brw_dp_desc_binding_table_index(devinfo, imm_desc)); 2303 2304 switch (brw_inst_dp_msg_type(devinfo, inst)) { 2305 case GFX7_DATAPORT_DC_UNTYPED_ATOMIC_OP: 2306 control(file, "atomic op", aop, 2307 brw_dp_desc_msg_control(devinfo, imm_desc) & 0xf, 2308 &space); 2309 break; 2310 case GFX7_DATAPORT_DC_OWORD_BLOCK_READ: 2311 case GFX7_DATAPORT_DC_OWORD_BLOCK_WRITE: { 2312 unsigned msg_ctrl = brw_dp_desc_msg_control(devinfo, imm_desc); 2313 assert(dp_oword_block_rw[msg_ctrl & 7]); 2314 format(file, "owords = %s, aligned = %d", 2315 dp_oword_block_rw[msg_ctrl & 7], (msg_ctrl >> 3) & 3); 2316 break; 2317 } 2318 default: 2319 format(file, "%u", 2320 brw_dp_desc_msg_control(devinfo, imm_desc)); 2321 } 2322 format(file, ")"); 2323 } else { 2324 unsupported = true; 2325 } 2326 break; 2327 2328 case HSW_SFID_DATAPORT_DATA_CACHE_1: { 2329 if (devinfo->ver >= 7) { 2330 format(file, " ("); 2331 space = 0; 2332 2333 unsigned msg_ctrl = brw_dp_desc_msg_control(devinfo, imm_desc); 2334 2335 err |= control(file, "DP DC1 message type", 2336 dp_dc1_msg_type_hsw, 2337 brw_dp_desc_msg_type(devinfo, imm_desc), &space); 2338 2339 format(file, ", Surface = %u, ", 2340 brw_dp_desc_binding_table_index(devinfo, imm_desc)); 2341 2342 switch (brw_inst_dp_msg_type(devinfo, inst)) { 2343 case HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP: 2344 case HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP: 2345 case HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP: 2346 format(file, "SIMD%d,", (msg_ctrl & (1 << 4)) ? 8 : 16); 2347 FALLTHROUGH; 2348 case HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP_SIMD4X2: 2349 case HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP_SIMD4X2: 2350 case HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP_SIMD4X2: 2351 case GFX8_DATAPORT_DC_PORT1_A64_UNTYPED_ATOMIC_OP: 2352 case GFX12_DATAPORT_DC_PORT1_A64_UNTYPED_ATOMIC_HALF_INT_OP: 2353 control(file, "atomic op", aop, msg_ctrl & 0xf, &space); 2354 break; 2355 case HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_READ: 2356 case HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_WRITE: 2357 case HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_READ: 2358 case HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_WRITE: 2359 case GFX8_DATAPORT_DC_PORT1_A64_UNTYPED_SURFACE_WRITE: 2360 case GFX8_DATAPORT_DC_PORT1_A64_UNTYPED_SURFACE_READ: { 2361 static const char *simd_modes[] = { "4x2", "16", "8" }; 2362 format(file, "SIMD%s, Mask = 0x%x", 2363 simd_modes[msg_ctrl >> 4], msg_ctrl & 0xf); 2364 break; 2365 } 2366 case GFX9_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_FLOAT_OP: 2367 case GFX9_DATAPORT_DC_PORT1_A64_UNTYPED_ATOMIC_FLOAT_OP: 2368 case GFX12_DATAPORT_DC_PORT1_A64_UNTYPED_ATOMIC_HALF_FLOAT_OP: 2369 format(file, "SIMD%d,", (msg_ctrl & (1 << 4)) ? 8 : 16); 2370 control(file, "atomic float op", aop_float, msg_ctrl & 0xf, 2371 &space); 2372 break; 2373 case GFX9_DATAPORT_DC_PORT1_A64_OWORD_BLOCK_WRITE: 2374 case GFX9_DATAPORT_DC_PORT1_A64_OWORD_BLOCK_READ: 2375 assert(dp_oword_block_rw[msg_ctrl & 7]); 2376 format(file, "owords = %s, aligned = %d", 2377 dp_oword_block_rw[msg_ctrl & 7], (msg_ctrl >> 3) & 3); 2378 break; 2379 default: 2380 format(file, "0x%x", msg_ctrl); 2381 } 2382 format(file, ")"); 2383 } else { 2384 unsupported = true; 2385 } 2386 break; 2387 } 2388 2389 case GFX7_SFID_PIXEL_INTERPOLATOR: 2390 if (devinfo->ver >= 7) { 2391 format(file, " (%s, %s, 0x%02"PRIx64")", 2392 brw_inst_pi_nopersp(devinfo, inst) ? "linear" : "persp", 2393 pixel_interpolator_msg_types[brw_inst_pi_message_type(devinfo, inst)], 2394 brw_inst_pi_message_data(devinfo, inst)); 2395 } else { 2396 unsupported = true; 2397 } 2398 break; 2399 2400 case GEN_RT_SFID_RAY_TRACE_ACCELERATOR: 2401 if (devinfo->has_ray_tracing) { 2402 format(file, " SIMD%d,", 2403 brw_rt_trace_ray_desc_exec_size(devinfo, imm_desc)); 2404 } else { 2405 unsupported = true; 2406 } 2407 break; 2408 2409 default: 2410 unsupported = true; 2411 break; 2412 } 2413 2414 if (unsupported) 2415 format(file, "unsupported shared function ID %d", sfid); 2416 2417 if (space) 2418 string(file, " "); 2419 } 2420 if (brw_sfid_is_lsc(sfid)) { 2421 lsc_disassemble_ex_desc(devinfo, imm_desc, imm_ex_desc, file); 2422 } else { 2423 if (has_imm_desc) 2424 format(file, "mlen %u", brw_message_desc_mlen(devinfo, imm_desc)); 2425 if (has_imm_ex_desc) { 2426 format(file, " ex_mlen %u", 2427 brw_message_ex_desc_ex_mlen(devinfo, imm_ex_desc)); 2428 } 2429 if (has_imm_desc) 2430 format(file, " rlen %u", brw_message_desc_rlen(devinfo, imm_desc)); 2431 } 2432 } 2433 pad(file, 64); 2434 if (opcode != BRW_OPCODE_NOP && opcode != BRW_OPCODE_NENOP) { 2435 string(file, "{"); 2436 space = 1; 2437 err |= control(file, "access mode", access_mode, 2438 brw_inst_access_mode(devinfo, inst), &space); 2439 if (devinfo->ver >= 6) { 2440 err |= control(file, "write enable control", wectrl, 2441 brw_inst_mask_control(devinfo, inst), &space); 2442 } else { 2443 err |= control(file, "mask control", mask_ctrl, 2444 brw_inst_mask_control(devinfo, inst), &space); 2445 } 2446 2447 if (devinfo->ver < 12) { 2448 err |= control(file, "dependency control", dep_ctrl, 2449 ((brw_inst_no_dd_check(devinfo, inst) << 1) | 2450 brw_inst_no_dd_clear(devinfo, inst)), &space); 2451 } 2452 2453 if (devinfo->ver >= 6) 2454 err |= qtr_ctrl(file, devinfo, inst); 2455 else { 2456 if (brw_inst_qtr_control(devinfo, inst) == BRW_COMPRESSION_COMPRESSED && 2457 desc && desc->ndst > 0 && 2458 brw_inst_dst_reg_file(devinfo, inst) == BRW_MESSAGE_REGISTER_FILE && 2459 brw_inst_dst_da_reg_nr(devinfo, inst) & BRW_MRF_COMPR4) { 2460 format(file, " compr4"); 2461 } else { 2462 err |= control(file, "compression control", compr_ctrl, 2463 brw_inst_qtr_control(devinfo, inst), &space); 2464 } 2465 } 2466 2467 if (devinfo->ver >= 12) 2468 err |= swsb(file, devinfo, inst); 2469 2470 err |= control(file, "compaction", cmpt_ctrl, is_compacted, &space); 2471 err |= control(file, "thread control", thread_ctrl, 2472 (devinfo->ver >= 12 ? brw_inst_atomic_control(devinfo, inst) : 2473 brw_inst_thread_control(devinfo, inst)), 2474 &space); 2475 if (has_branch_ctrl(devinfo, opcode)) { 2476 err |= control(file, "branch ctrl", branch_ctrl, 2477 brw_inst_branch_control(devinfo, inst), &space); 2478 } else if (devinfo->ver >= 6) { 2479 err |= control(file, "acc write control", accwr, 2480 brw_inst_acc_wr_control(devinfo, inst), &space); 2481 } 2482 if (is_send(opcode)) 2483 err |= control(file, "end of thread", end_of_thread, 2484 brw_inst_eot(devinfo, inst), &space); 2485 if (space) 2486 string(file, " "); 2487 string(file, "}"); 2488 } 2489 string(file, ";"); 2490 newline(file); 2491 return err; 2492} 2493