Home | History | Annotate | Download | only in i965
      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_context.h"
     28 #include "brw_defines.h"
     29 #include "brw_reg.h"
     30 #include "brw_inst.h"
     31 #include "brw_eu.h"
     32 
     33 static bool
     34 has_jip(const struct gen_device_info *devinfo, enum opcode opcode)
     35 {
     36    if (devinfo->gen < 6)
     37       return false;
     38 
     39    return opcode == BRW_OPCODE_IF ||
     40           opcode == BRW_OPCODE_ELSE ||
     41           opcode == BRW_OPCODE_ENDIF ||
     42           opcode == BRW_OPCODE_WHILE ||
     43           opcode == BRW_OPCODE_BREAK ||
     44           opcode == BRW_OPCODE_CONTINUE ||
     45           opcode == BRW_OPCODE_HALT;
     46 }
     47 
     48 static bool
     49 has_uip(const struct gen_device_info *devinfo, enum opcode opcode)
     50 {
     51    if (devinfo->gen < 6)
     52       return false;
     53 
     54    return (devinfo->gen >= 7 && opcode == BRW_OPCODE_IF) ||
     55           (devinfo->gen >= 8 && opcode == BRW_OPCODE_ELSE) ||
     56           opcode == BRW_OPCODE_BREAK ||
     57           opcode == BRW_OPCODE_CONTINUE ||
     58           opcode == BRW_OPCODE_HALT;
     59 }
     60 
     61 static bool
     62 has_branch_ctrl(const struct gen_device_info *devinfo, enum opcode opcode)
     63 {
     64    if (devinfo->gen < 8)
     65       return false;
     66 
     67    return opcode == BRW_OPCODE_IF ||
     68           opcode == BRW_OPCODE_ELSE;
     69           /* opcode == BRW_OPCODE_GOTO; */
     70 }
     71 
     72 static bool
     73 is_logic_instruction(unsigned opcode)
     74 {
     75    return opcode == BRW_OPCODE_AND ||
     76           opcode == BRW_OPCODE_NOT ||
     77           opcode == BRW_OPCODE_OR ||
     78           opcode == BRW_OPCODE_XOR;
     79 }
     80 
     81 const char *const conditional_modifier[16] = {
     82    [BRW_CONDITIONAL_NONE] = "",
     83    [BRW_CONDITIONAL_Z]    = ".z",
     84    [BRW_CONDITIONAL_NZ]   = ".nz",
     85    [BRW_CONDITIONAL_G]    = ".g",
     86    [BRW_CONDITIONAL_GE]   = ".ge",
     87    [BRW_CONDITIONAL_L]    = ".l",
     88    [BRW_CONDITIONAL_LE]   = ".le",
     89    [BRW_CONDITIONAL_R]    = ".r",
     90    [BRW_CONDITIONAL_O]    = ".o",
     91    [BRW_CONDITIONAL_U]    = ".u",
     92 };
     93 
     94 static const char *const m_negate[2] = {
     95    [0] = "",
     96    [1] = "-",
     97 };
     98 
     99 static const char *const _abs[2] = {
    100    [0] = "",
    101    [1] = "(abs)",
    102 };
    103 
    104 static const char *const m_bitnot[2] = { "", "~" };
    105 
    106 static const char *const vert_stride[16] = {
    107    [0] = "0",
    108    [1] = "1",
    109    [2] = "2",
    110    [3] = "4",
    111    [4] = "8",
    112    [5] = "16",
    113    [6] = "32",
    114    [15] = "VxH",
    115 };
    116 
    117 static const char *const width[8] = {
    118    [0] = "1",
    119    [1] = "2",
    120    [2] = "4",
    121    [3] = "8",
    122    [4] = "16",
    123 };
    124 
    125 static const char *const horiz_stride[4] = {
    126    [0] = "0",
    127    [1] = "1",
    128    [2] = "2",
    129    [3] = "4"
    130 };
    131 
    132 static const char *const chan_sel[4] = {
    133    [0] = "x",
    134    [1] = "y",
    135    [2] = "z",
    136    [3] = "w",
    137 };
    138 
    139 static const char *const debug_ctrl[2] = {
    140    [0] = "",
    141    [1] = ".breakpoint"
    142 };
    143 
    144 static const char *const saturate[2] = {
    145    [0] = "",
    146    [1] = ".sat"
    147 };
    148 
    149 static const char *const cmpt_ctrl[2] = {
    150    [0] = "",
    151    [1] = "compacted"
    152 };
    153 
    154 static const char *const accwr[2] = {
    155    [0] = "",
    156    [1] = "AccWrEnable"
    157 };
    158 
    159 static const char *const branch_ctrl[2] = {
    160    [0] = "",
    161    [1] = "BranchCtrl"
    162 };
    163 
    164 static const char *const wectrl[2] = {
    165    [0] = "",
    166    [1] = "WE_all"
    167 };
    168 
    169 static const char *const exec_size[8] = {
    170    [0] = "1",
    171    [1] = "2",
    172    [2] = "4",
    173    [3] = "8",
    174    [4] = "16",
    175    [5] = "32"
    176 };
    177 
    178 static const char *const pred_inv[2] = {
    179    [0] = "+",
    180    [1] = "-"
    181 };
    182 
    183 const char *const pred_ctrl_align16[16] = {
    184    [1] = "",
    185    [2] = ".x",
    186    [3] = ".y",
    187    [4] = ".z",
    188    [5] = ".w",
    189    [6] = ".any4h",
    190    [7] = ".all4h",
    191 };
    192 
    193 static const char *const pred_ctrl_align1[16] = {
    194    [BRW_PREDICATE_NORMAL]        = "",
    195    [BRW_PREDICATE_ALIGN1_ANYV]   = ".anyv",
    196    [BRW_PREDICATE_ALIGN1_ALLV]   = ".allv",
    197    [BRW_PREDICATE_ALIGN1_ANY2H]  = ".any2h",
    198    [BRW_PREDICATE_ALIGN1_ALL2H]  = ".all2h",
    199    [BRW_PREDICATE_ALIGN1_ANY4H]  = ".any4h",
    200    [BRW_PREDICATE_ALIGN1_ALL4H]  = ".all4h",
    201    [BRW_PREDICATE_ALIGN1_ANY8H]  = ".any8h",
    202    [BRW_PREDICATE_ALIGN1_ALL8H]  = ".all8h",
    203    [BRW_PREDICATE_ALIGN1_ANY16H] = ".any16h",
    204    [BRW_PREDICATE_ALIGN1_ALL16H] = ".all16h",
    205    [BRW_PREDICATE_ALIGN1_ANY32H] = ".any32h",
    206    [BRW_PREDICATE_ALIGN1_ALL32H] = ".all32h",
    207 };
    208 
    209 static const char *const thread_ctrl[4] = {
    210    [BRW_THREAD_NORMAL] = "",
    211    [BRW_THREAD_ATOMIC] = "atomic",
    212    [BRW_THREAD_SWITCH] = "switch",
    213 };
    214 
    215 static const char *const compr_ctrl[4] = {
    216    [0] = "",
    217    [1] = "sechalf",
    218    [2] = "compr",
    219    [3] = "compr4",
    220 };
    221 
    222 static const char *const dep_ctrl[4] = {
    223    [0] = "",
    224    [1] = "NoDDClr",
    225    [2] = "NoDDChk",
    226    [3] = "NoDDClr,NoDDChk",
    227 };
    228 
    229 static const char *const mask_ctrl[4] = {
    230    [0] = "",
    231    [1] = "nomask",
    232 };
    233 
    234 static const char *const access_mode[2] = {
    235    [0] = "align1",
    236    [1] = "align16",
    237 };
    238 
    239 static const char * const reg_encoding[] = {
    240    [BRW_HW_REG_TYPE_UD]          = "UD",
    241    [BRW_HW_REG_TYPE_D]           = "D",
    242    [BRW_HW_REG_TYPE_UW]          = "UW",
    243    [BRW_HW_REG_TYPE_W]           = "W",
    244    [BRW_HW_REG_NON_IMM_TYPE_UB]  = "UB",
    245    [BRW_HW_REG_NON_IMM_TYPE_B]   = "B",
    246    [GEN7_HW_REG_NON_IMM_TYPE_DF] = "DF",
    247    [BRW_HW_REG_TYPE_F]           = "F",
    248    [GEN8_HW_REG_TYPE_UQ]         = "UQ",
    249    [GEN8_HW_REG_TYPE_Q]          = "Q",
    250    [GEN8_HW_REG_NON_IMM_TYPE_HF] = "HF",
    251 };
    252 
    253 static const char *const three_source_reg_encoding[] = {
    254    [BRW_3SRC_TYPE_F]  = "F",
    255    [BRW_3SRC_TYPE_D]  = "D",
    256    [BRW_3SRC_TYPE_UD] = "UD",
    257    [BRW_3SRC_TYPE_DF] = "DF",
    258 };
    259 
    260 const int reg_type_size[] = {
    261    [BRW_HW_REG_TYPE_UD]          = 4,
    262    [BRW_HW_REG_TYPE_D]           = 4,
    263    [BRW_HW_REG_TYPE_UW]          = 2,
    264    [BRW_HW_REG_TYPE_W]           = 2,
    265    [BRW_HW_REG_NON_IMM_TYPE_UB]  = 1,
    266    [BRW_HW_REG_NON_IMM_TYPE_B]   = 1,
    267    [GEN7_HW_REG_NON_IMM_TYPE_DF] = 8,
    268    [BRW_HW_REG_TYPE_F]           = 4,
    269    [GEN8_HW_REG_TYPE_UQ]         = 8,
    270    [GEN8_HW_REG_TYPE_Q]          = 8,
    271    [GEN8_HW_REG_NON_IMM_TYPE_HF] = 2,
    272 };
    273 
    274 static const char *const reg_file[4] = {
    275    [0] = "A",
    276    [1] = "g",
    277    [2] = "m",
    278    [3] = "imm",
    279 };
    280 
    281 static const char *const writemask[16] = {
    282    [0x0] = ".",
    283    [0x1] = ".x",
    284    [0x2] = ".y",
    285    [0x3] = ".xy",
    286    [0x4] = ".z",
    287    [0x5] = ".xz",
    288    [0x6] = ".yz",
    289    [0x7] = ".xyz",
    290    [0x8] = ".w",
    291    [0x9] = ".xw",
    292    [0xa] = ".yw",
    293    [0xb] = ".xyw",
    294    [0xc] = ".zw",
    295    [0xd] = ".xzw",
    296    [0xe] = ".yzw",
    297    [0xf] = "",
    298 };
    299 
    300 static const char *const end_of_thread[2] = {
    301    [0] = "",
    302    [1] = "EOT"
    303 };
    304 
    305 /* SFIDs on Gen4-5 */
    306 static const char *const gen4_sfid[16] = {
    307    [BRW_SFID_NULL]            = "null",
    308    [BRW_SFID_MATH]            = "math",
    309    [BRW_SFID_SAMPLER]         = "sampler",
    310    [BRW_SFID_MESSAGE_GATEWAY] = "gateway",
    311    [BRW_SFID_DATAPORT_READ]   = "read",
    312    [BRW_SFID_DATAPORT_WRITE]  = "write",
    313    [BRW_SFID_URB]             = "urb",
    314    [BRW_SFID_THREAD_SPAWNER]  = "thread_spawner",
    315    [BRW_SFID_VME]             = "vme",
    316 };
    317 
    318 static const char *const gen6_sfid[16] = {
    319    [BRW_SFID_NULL]                     = "null",
    320    [BRW_SFID_MATH]                     = "math",
    321    [BRW_SFID_SAMPLER]                  = "sampler",
    322    [BRW_SFID_MESSAGE_GATEWAY]          = "gateway",
    323    [BRW_SFID_URB]                      = "urb",
    324    [BRW_SFID_THREAD_SPAWNER]           = "thread_spawner",
    325    [GEN6_SFID_DATAPORT_SAMPLER_CACHE]  = "sampler",
    326    [GEN6_SFID_DATAPORT_RENDER_CACHE]   = "render",
    327    [GEN6_SFID_DATAPORT_CONSTANT_CACHE] = "const",
    328    [GEN7_SFID_DATAPORT_DATA_CACHE]     = "data",
    329    [GEN7_SFID_PIXEL_INTERPOLATOR]      = "pixel interp",
    330    [HSW_SFID_DATAPORT_DATA_CACHE_1]    = "dp data 1",
    331    [HSW_SFID_CRE]                      = "cre",
    332 };
    333 
    334 static const char *const gen7_gateway_subfuncid[8] = {
    335    [BRW_MESSAGE_GATEWAY_SFID_OPEN_GATEWAY] = "open",
    336    [BRW_MESSAGE_GATEWAY_SFID_CLOSE_GATEWAY] = "close",
    337    [BRW_MESSAGE_GATEWAY_SFID_FORWARD_MSG] = "forward msg",
    338    [BRW_MESSAGE_GATEWAY_SFID_GET_TIMESTAMP] = "get timestamp",
    339    [BRW_MESSAGE_GATEWAY_SFID_BARRIER_MSG] = "barrier msg",
    340    [BRW_MESSAGE_GATEWAY_SFID_UPDATE_GATEWAY_STATE] = "update state",
    341    [BRW_MESSAGE_GATEWAY_SFID_MMIO_READ_WRITE] = "mmio read/write",
    342 };
    343 
    344 static const char *const gen4_dp_read_port_msg_type[4] = {
    345    [0b00] = "OWord Block Read",
    346    [0b01] = "OWord Dual Block Read",
    347    [0b10] = "Media Block Read",
    348    [0b11] = "DWord Scattered Read",
    349 };
    350 
    351 static const char *const g45_dp_read_port_msg_type[8] = {
    352    [0b000] = "OWord Block Read",
    353    [0b010] = "OWord Dual Block Read",
    354    [0b100] = "Media Block Read",
    355    [0b110] = "DWord Scattered Read",
    356    [0b001] = "Render Target UNORM Read",
    357    [0b011] = "AVC Loop Filter Read",
    358 };
    359 
    360 static const char *const dp_write_port_msg_type[8] = {
    361    [0b000] = "OWord block write",
    362    [0b001] = "OWord dual block write",
    363    [0b010] = "media block write",
    364    [0b011] = "DWord scattered write",
    365    [0b100] = "RT write",
    366    [0b101] = "streamed VB write",
    367    [0b110] = "RT UNORM write", /* G45+ */
    368    [0b111] = "flush render cache",
    369 };
    370 
    371 static const char *const dp_rc_msg_type_gen6[16] = {
    372    [BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ] = "OWORD block read",
    373    [GEN6_DATAPORT_READ_MESSAGE_RENDER_UNORM_READ] = "RT UNORM read",
    374    [GEN6_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ] = "OWORD dual block read",
    375    [GEN6_DATAPORT_READ_MESSAGE_MEDIA_BLOCK_READ] = "media block read",
    376    [GEN6_DATAPORT_READ_MESSAGE_OWORD_UNALIGN_BLOCK_READ] =
    377       "OWORD unaligned block read",
    378    [GEN6_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ] = "DWORD scattered read",
    379    [GEN6_DATAPORT_WRITE_MESSAGE_DWORD_ATOMIC_WRITE] = "DWORD atomic write",
    380    [GEN6_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE] = "OWORD block write",
    381    [GEN6_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE] =
    382       "OWORD dual block write",
    383    [GEN6_DATAPORT_WRITE_MESSAGE_MEDIA_BLOCK_WRITE] = "media block write",
    384    [GEN6_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE] =
    385       "DWORD scattered write",
    386    [GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE] = "RT write",
    387    [GEN6_DATAPORT_WRITE_MESSAGE_STREAMED_VB_WRITE] = "streamed VB write",
    388    [GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_UNORM_WRITE] = "RT UNORM write",
    389 };
    390 
    391 static const char *const dp_rc_msg_type_gen7[16] = {
    392    [GEN7_DATAPORT_RC_MEDIA_BLOCK_READ] = "media block read",
    393    [GEN7_DATAPORT_RC_TYPED_SURFACE_READ] = "typed surface read",
    394    [GEN7_DATAPORT_RC_TYPED_ATOMIC_OP] = "typed atomic op",
    395    [GEN7_DATAPORT_RC_MEMORY_FENCE] = "memory fence",
    396    [GEN7_DATAPORT_RC_MEDIA_BLOCK_WRITE] = "media block write",
    397    [GEN7_DATAPORT_RC_RENDER_TARGET_WRITE] = "RT write",
    398    [GEN7_DATAPORT_RC_TYPED_SURFACE_WRITE] = "typed surface write"
    399 };
    400 
    401 static const char *const dp_rc_msg_type_gen9[16] = {
    402    [GEN9_DATAPORT_RC_RENDER_TARGET_WRITE] = "RT write",
    403    [GEN9_DATAPORT_RC_RENDER_TARGET_READ] = "RT read"
    404 };
    405 
    406 static const char *const *
    407 dp_rc_msg_type(const struct gen_device_info *devinfo)
    408 {
    409    return (devinfo->gen >= 9 ? dp_rc_msg_type_gen9 :
    410            devinfo->gen >= 7 ? dp_rc_msg_type_gen7 :
    411            devinfo->gen >= 6 ? dp_rc_msg_type_gen6 :
    412            dp_write_port_msg_type);
    413 }
    414 
    415 static const char *const m_rt_write_subtype[] = {
    416    [0b000] = "SIMD16",
    417    [0b001] = "SIMD16/RepData",
    418    [0b010] = "SIMD8/DualSrcLow",
    419    [0b011] = "SIMD8/DualSrcHigh",
    420    [0b100] = "SIMD8",
    421    [0b101] = "SIMD8/ImageWrite",   /* Gen6+ */
    422    [0b111] = "SIMD16/RepData-111", /* no idea how this is different than 1 */
    423 };
    424 
    425 static const char *const dp_dc0_msg_type_gen7[16] = {
    426    [GEN7_DATAPORT_DC_OWORD_BLOCK_READ] = "DC OWORD block read",
    427    [GEN7_DATAPORT_DC_UNALIGNED_OWORD_BLOCK_READ] =
    428       "DC unaligned OWORD block read",
    429    [GEN7_DATAPORT_DC_OWORD_DUAL_BLOCK_READ] = "DC OWORD dual block read",
    430    [GEN7_DATAPORT_DC_DWORD_SCATTERED_READ] = "DC DWORD scattered read",
    431    [GEN7_DATAPORT_DC_BYTE_SCATTERED_READ] = "DC byte scattered read",
    432    [GEN7_DATAPORT_DC_UNTYPED_SURFACE_READ] = "DC untyped surface read",
    433    [GEN7_DATAPORT_DC_UNTYPED_ATOMIC_OP] = "DC untyped atomic",
    434    [GEN7_DATAPORT_DC_MEMORY_FENCE] = "DC mfence",
    435    [GEN7_DATAPORT_DC_OWORD_BLOCK_WRITE] = "DC OWORD block write",
    436    [GEN7_DATAPORT_DC_OWORD_DUAL_BLOCK_WRITE] = "DC OWORD dual block write",
    437    [GEN7_DATAPORT_DC_DWORD_SCATTERED_WRITE] = "DC DWORD scatterd write",
    438    [GEN7_DATAPORT_DC_BYTE_SCATTERED_WRITE] = "DC byte scattered write",
    439    [GEN7_DATAPORT_DC_UNTYPED_SURFACE_WRITE] = "DC untyped surface write",
    440 };
    441 
    442 static const char *const dp_dc1_msg_type_hsw[16] = {
    443    [HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_READ] = "untyped surface read",
    444    [HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP] = "DC untyped atomic op",
    445    [HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP_SIMD4X2] =
    446       "DC untyped 4x2 atomic op",
    447    [HSW_DATAPORT_DC_PORT1_MEDIA_BLOCK_READ] = "DC media block read",
    448    [HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_READ] = "DC typed surface read",
    449    [HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP] = "DC typed atomic",
    450    [HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP_SIMD4X2] = "DC typed 4x2 atomic op",
    451    [HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_WRITE] = "DC untyped surface write",
    452    [HSW_DATAPORT_DC_PORT1_MEDIA_BLOCK_WRITE] = "DC media block write",
    453    [HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP] = "DC atomic counter op",
    454    [HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP_SIMD4X2] =
    455       "DC 4x2 atomic counter op",
    456    [HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_WRITE] = "DC typed surface write",
    457 };
    458 
    459 static const char *const aop[16] = {
    460    [BRW_AOP_AND]    = "and",
    461    [BRW_AOP_OR]     = "or",
    462    [BRW_AOP_XOR]    = "xor",
    463    [BRW_AOP_MOV]    = "mov",
    464    [BRW_AOP_INC]    = "inc",
    465    [BRW_AOP_DEC]    = "dec",
    466    [BRW_AOP_ADD]    = "add",
    467    [BRW_AOP_SUB]    = "sub",
    468    [BRW_AOP_REVSUB] = "revsub",
    469    [BRW_AOP_IMAX]   = "imax",
    470    [BRW_AOP_IMIN]   = "imin",
    471    [BRW_AOP_UMAX]   = "umax",
    472    [BRW_AOP_UMIN]   = "umin",
    473    [BRW_AOP_CMPWR]  = "cmpwr",
    474    [BRW_AOP_PREDEC] = "predec",
    475 };
    476 
    477 static const char * const pixel_interpolator_msg_types[4] = {
    478     [GEN7_PIXEL_INTERPOLATOR_LOC_SHARED_OFFSET] = "per_message_offset",
    479     [GEN7_PIXEL_INTERPOLATOR_LOC_SAMPLE] = "sample_position",
    480     [GEN7_PIXEL_INTERPOLATOR_LOC_CENTROID] = "centroid",
    481     [GEN7_PIXEL_INTERPOLATOR_LOC_PER_SLOT_OFFSET] = "per_slot_offset",
    482 };
    483 
    484 static const char *const math_function[16] = {
    485    [BRW_MATH_FUNCTION_INV]    = "inv",
    486    [BRW_MATH_FUNCTION_LOG]    = "log",
    487    [BRW_MATH_FUNCTION_EXP]    = "exp",
    488    [BRW_MATH_FUNCTION_SQRT]   = "sqrt",
    489    [BRW_MATH_FUNCTION_RSQ]    = "rsq",
    490    [BRW_MATH_FUNCTION_SIN]    = "sin",
    491    [BRW_MATH_FUNCTION_COS]    = "cos",
    492    [BRW_MATH_FUNCTION_SINCOS] = "sincos",
    493    [BRW_MATH_FUNCTION_FDIV]   = "fdiv",
    494    [BRW_MATH_FUNCTION_POW]    = "pow",
    495    [BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER] = "intdivmod",
    496    [BRW_MATH_FUNCTION_INT_DIV_QUOTIENT]  = "intdiv",
    497    [BRW_MATH_FUNCTION_INT_DIV_REMAINDER] = "intmod",
    498    [GEN8_MATH_FUNCTION_INVM]  = "invm",
    499    [GEN8_MATH_FUNCTION_RSQRTM] = "rsqrtm",
    500 };
    501 
    502 static const char *const math_saturate[2] = {
    503    [0] = "",
    504    [1] = "sat"
    505 };
    506 
    507 static const char *const math_signed[2] = {
    508    [0] = "",
    509    [1] = "signed"
    510 };
    511 
    512 static const char *const math_scalar[2] = {
    513    [0] = "",
    514    [1] = "scalar"
    515 };
    516 
    517 static const char *const math_precision[2] = {
    518    [0] = "",
    519    [1] = "partial_precision"
    520 };
    521 
    522 static const char *const gen5_urb_opcode[] = {
    523    [0] = "urb_write",
    524    [1] = "ff_sync",
    525 };
    526 
    527 static const char *const gen7_urb_opcode[] = {
    528    [BRW_URB_OPCODE_WRITE_HWORD] = "write HWord",
    529    [BRW_URB_OPCODE_WRITE_OWORD] = "write OWord",
    530    [BRW_URB_OPCODE_READ_HWORD] = "read HWord",
    531    [BRW_URB_OPCODE_READ_OWORD] = "read OWord",
    532    [GEN7_URB_OPCODE_ATOMIC_MOV] = "atomic mov",  /* Gen7+ */
    533    [GEN7_URB_OPCODE_ATOMIC_INC] = "atomic inc",  /* Gen7+ */
    534    [GEN8_URB_OPCODE_ATOMIC_ADD] = "atomic add",  /* Gen8+ */
    535    [GEN8_URB_OPCODE_SIMD8_WRITE] = "SIMD8 write", /* Gen8+ */
    536    [GEN8_URB_OPCODE_SIMD8_READ] = "SIMD8 read",  /* Gen8+ */
    537    /* [9-15] - reserved */
    538 };
    539 
    540 static const char *const urb_swizzle[4] = {
    541    [BRW_URB_SWIZZLE_NONE]       = "",
    542    [BRW_URB_SWIZZLE_INTERLEAVE] = "interleave",
    543    [BRW_URB_SWIZZLE_TRANSPOSE]  = "transpose",
    544 };
    545 
    546 static const char *const urb_allocate[2] = {
    547    [0] = "",
    548    [1] = "allocate"
    549 };
    550 
    551 static const char *const urb_used[2] = {
    552    [0] = "",
    553    [1] = "used"
    554 };
    555 
    556 static const char *const urb_complete[2] = {
    557    [0] = "",
    558    [1] = "complete"
    559 };
    560 
    561 static const char *const gen5_sampler_msg_type[] = {
    562    [GEN5_SAMPLER_MESSAGE_SAMPLE]              = "sample",
    563    [GEN5_SAMPLER_MESSAGE_SAMPLE_BIAS]         = "sample_b",
    564    [GEN5_SAMPLER_MESSAGE_SAMPLE_LOD]          = "sample_l",
    565    [GEN5_SAMPLER_MESSAGE_SAMPLE_COMPARE]      = "sample_c",
    566    [GEN5_SAMPLER_MESSAGE_SAMPLE_DERIVS]       = "sample_d",
    567    [GEN5_SAMPLER_MESSAGE_SAMPLE_BIAS_COMPARE] = "sample_b_c",
    568    [GEN5_SAMPLER_MESSAGE_SAMPLE_LOD_COMPARE]  = "sample_l_c",
    569    [GEN5_SAMPLER_MESSAGE_SAMPLE_LD]           = "ld",
    570    [GEN7_SAMPLER_MESSAGE_SAMPLE_GATHER4]      = "gather4",
    571    [GEN5_SAMPLER_MESSAGE_LOD]                 = "lod",
    572    [GEN5_SAMPLER_MESSAGE_SAMPLE_RESINFO]      = "resinfo",
    573    [GEN6_SAMPLER_MESSAGE_SAMPLE_SAMPLEINFO]   = "sampleinfo",
    574    [GEN7_SAMPLER_MESSAGE_SAMPLE_GATHER4_C]    = "gather4_c",
    575    [GEN7_SAMPLER_MESSAGE_SAMPLE_GATHER4_PO]   = "gather4_po",
    576    [GEN7_SAMPLER_MESSAGE_SAMPLE_GATHER4_PO_C] = "gather4_po_c",
    577    [HSW_SAMPLER_MESSAGE_SAMPLE_DERIV_COMPARE] = "sample_d_c",
    578    [GEN9_SAMPLER_MESSAGE_SAMPLE_LZ]           = "sample_lz",
    579    [GEN9_SAMPLER_MESSAGE_SAMPLE_C_LZ]         = "sample_c_lz",
    580    [GEN9_SAMPLER_MESSAGE_SAMPLE_LD_LZ]        = "ld_lz",
    581    [GEN9_SAMPLER_MESSAGE_SAMPLE_LD2DMS_W]     = "ld2dms_w",
    582    [GEN7_SAMPLER_MESSAGE_SAMPLE_LD_MCS]       = "ld_mcs",
    583    [GEN7_SAMPLER_MESSAGE_SAMPLE_LD2DMS]       = "ld2dms",
    584    [GEN7_SAMPLER_MESSAGE_SAMPLE_LD2DSS]       = "ld2dss",
    585 };
    586 
    587 static const char *const gen5_sampler_simd_mode[4] = {
    588    [BRW_SAMPLER_SIMD_MODE_SIMD4X2]   = "SIMD4x2",
    589    [BRW_SAMPLER_SIMD_MODE_SIMD8]     = "SIMD8",
    590    [BRW_SAMPLER_SIMD_MODE_SIMD16]    = "SIMD16",
    591    [BRW_SAMPLER_SIMD_MODE_SIMD32_64] = "SIMD32/64",
    592 };
    593 
    594 static const char *const sampler_target_format[4] = {
    595    [0] = "F",
    596    [2] = "UD",
    597    [3] = "D"
    598 };
    599 
    600 
    601 static int column;
    602 
    603 static int
    604 string(FILE *file, const char *string)
    605 {
    606    fputs(string, file);
    607    column += strlen(string);
    608    return 0;
    609 }
    610 
    611 static int
    612 format(FILE *f, const char *format, ...) PRINTFLIKE(2, 3);
    613 
    614 static int
    615 format(FILE *f, const char *format, ...)
    616 {
    617    char buf[1024];
    618    va_list args;
    619    va_start(args, format);
    620 
    621    vsnprintf(buf, sizeof(buf) - 1, format, args);
    622    va_end(args);
    623    string(f, buf);
    624    return 0;
    625 }
    626 
    627 static int
    628 newline(FILE *f)
    629 {
    630    putc('\n', f);
    631    column = 0;
    632    return 0;
    633 }
    634 
    635 static int
    636 pad(FILE *f, int c)
    637 {
    638    do
    639       string(f, " ");
    640    while (column < c);
    641    return 0;
    642 }
    643 
    644 static int
    645 control(FILE *file, const char *name, const char *const ctrl[],
    646         unsigned id, int *space)
    647 {
    648    if (!ctrl[id]) {
    649       fprintf(file, "*** invalid %s value %d ", name, id);
    650       return 1;
    651    }
    652    if (ctrl[id][0]) {
    653       if (space && *space)
    654          string(file, " ");
    655       string(file, ctrl[id]);
    656       if (space)
    657          *space = 1;
    658    }
    659    return 0;
    660 }
    661 
    662 static int
    663 print_opcode(FILE *file, const struct gen_device_info *devinfo,
    664              enum opcode id)
    665 {
    666    const struct opcode_desc *desc = brw_opcode_desc(devinfo, id);
    667    if (!desc) {
    668       format(file, "*** invalid opcode value %d ", id);
    669       return 1;
    670    }
    671    string(file, desc->name);
    672    return 0;
    673 }
    674 
    675 static int
    676 reg(FILE *file, unsigned _reg_file, unsigned _reg_nr)
    677 {
    678    int err = 0;
    679 
    680    /* Clear the Compr4 instruction compression bit. */
    681    if (_reg_file == BRW_MESSAGE_REGISTER_FILE)
    682       _reg_nr &= ~BRW_MRF_COMPR4;
    683 
    684    if (_reg_file == BRW_ARCHITECTURE_REGISTER_FILE) {
    685       switch (_reg_nr & 0xf0) {
    686       case BRW_ARF_NULL:
    687          string(file, "null");
    688          break;
    689       case BRW_ARF_ADDRESS:
    690          format(file, "a%d", _reg_nr & 0x0f);
    691          break;
    692       case BRW_ARF_ACCUMULATOR:
    693          format(file, "acc%d", _reg_nr & 0x0f);
    694          break;
    695       case BRW_ARF_FLAG:
    696          format(file, "f%d", _reg_nr & 0x0f);
    697          break;
    698       case BRW_ARF_MASK:
    699          format(file, "mask%d", _reg_nr & 0x0f);
    700          break;
    701       case BRW_ARF_MASK_STACK:
    702          format(file, "msd%d", _reg_nr & 0x0f);
    703          break;
    704       case BRW_ARF_STATE:
    705          format(file, "sr%d", _reg_nr & 0x0f);
    706          break;
    707       case BRW_ARF_CONTROL:
    708          format(file, "cr%d", _reg_nr & 0x0f);
    709          break;
    710       case BRW_ARF_NOTIFICATION_COUNT:
    711          format(file, "n%d", _reg_nr & 0x0f);
    712          break;
    713       case BRW_ARF_IP:
    714          string(file, "ip");
    715          return -1;
    716          break;
    717       case BRW_ARF_TDR:
    718          format(file, "tdr0");
    719          return -1;
    720       case BRW_ARF_TIMESTAMP:
    721          format(file, "tm%d", _reg_nr & 0x0f);
    722          break;
    723       default:
    724          format(file, "ARF%d", _reg_nr);
    725          break;
    726       }
    727    } else {
    728       err |= control(file, "src reg file", reg_file, _reg_file, NULL);
    729       format(file, "%d", _reg_nr);
    730    }
    731    return err;
    732 }
    733 
    734 static int
    735 dest(FILE *file, const struct gen_device_info *devinfo, brw_inst *inst)
    736 {
    737    int err = 0;
    738 
    739    if (brw_inst_access_mode(devinfo, inst) == BRW_ALIGN_1) {
    740       if (brw_inst_dst_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
    741          err |= reg(file, brw_inst_dst_reg_file(devinfo, inst),
    742                     brw_inst_dst_da_reg_nr(devinfo, inst));
    743          if (err == -1)
    744             return 0;
    745          if (brw_inst_dst_da1_subreg_nr(devinfo, inst))
    746             format(file, ".%"PRIu64, brw_inst_dst_da1_subreg_nr(devinfo, inst) /
    747                    reg_type_size[brw_inst_dst_reg_type(devinfo, inst)]);
    748          string(file, "<");
    749          err |= control(file, "horiz stride", horiz_stride,
    750                         brw_inst_dst_hstride(devinfo, inst), NULL);
    751          string(file, ">");
    752          err |= control(file, "dest reg encoding", reg_encoding,
    753                         brw_inst_dst_reg_type(devinfo, inst), NULL);
    754       } else {
    755          string(file, "g[a0");
    756          if (brw_inst_dst_ia_subreg_nr(devinfo, inst))
    757             format(file, ".%"PRIu64, brw_inst_dst_ia_subreg_nr(devinfo, inst) /
    758                    reg_type_size[brw_inst_dst_reg_type(devinfo, inst)]);
    759          if (brw_inst_dst_ia1_addr_imm(devinfo, inst))
    760             format(file, " %d", brw_inst_dst_ia1_addr_imm(devinfo, inst));
    761          string(file, "]<");
    762          err |= control(file, "horiz stride", horiz_stride,
    763                         brw_inst_dst_hstride(devinfo, inst), NULL);
    764          string(file, ">");
    765          err |= control(file, "dest reg encoding", reg_encoding,
    766                         brw_inst_dst_reg_type(devinfo, inst), NULL);
    767       }
    768    } else {
    769       if (brw_inst_dst_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
    770          err |= reg(file, brw_inst_dst_reg_file(devinfo, inst),
    771                     brw_inst_dst_da_reg_nr(devinfo, inst));
    772          if (err == -1)
    773             return 0;
    774          if (brw_inst_dst_da16_subreg_nr(devinfo, inst))
    775             format(file, ".%u", 16 /
    776                    reg_type_size[brw_inst_dst_reg_type(devinfo, inst)]);
    777          string(file, "<1>");
    778          err |= control(file, "writemask", writemask,
    779                         brw_inst_da16_writemask(devinfo, inst), NULL);
    780          err |= control(file, "dest reg encoding", reg_encoding,
    781                         brw_inst_dst_reg_type(devinfo, inst), NULL);
    782       } else {
    783          err = 1;
    784          string(file, "Indirect align16 address mode not supported");
    785       }
    786    }
    787 
    788    return 0;
    789 }
    790 
    791 static int
    792 dest_3src(FILE *file, const struct gen_device_info *devinfo, brw_inst *inst)
    793 {
    794    int err = 0;
    795    uint32_t reg_file;
    796 
    797    if (devinfo->gen == 6 && brw_inst_3src_dst_reg_file(devinfo, inst))
    798       reg_file = BRW_MESSAGE_REGISTER_FILE;
    799    else
    800       reg_file = BRW_GENERAL_REGISTER_FILE;
    801 
    802    err |= reg(file, reg_file, brw_inst_3src_dst_reg_nr(devinfo, inst));
    803    if (err == -1)
    804       return 0;
    805    if (brw_inst_3src_dst_subreg_nr(devinfo, inst))
    806       format(file, ".%"PRIu64, brw_inst_3src_dst_subreg_nr(devinfo, inst));
    807    string(file, "<1>");
    808    err |= control(file, "writemask", writemask,
    809                   brw_inst_3src_dst_writemask(devinfo, inst), NULL);
    810    err |= control(file, "dest reg encoding", three_source_reg_encoding,
    811                   brw_inst_3src_dst_type(devinfo, inst), NULL);
    812 
    813    return 0;
    814 }
    815 
    816 static int
    817 src_align1_region(FILE *file,
    818                   unsigned _vert_stride, unsigned _width,
    819                   unsigned _horiz_stride)
    820 {
    821    int err = 0;
    822    string(file, "<");
    823    err |= control(file, "vert stride", vert_stride, _vert_stride, NULL);
    824    string(file, ",");
    825    err |= control(file, "width", width, _width, NULL);
    826    string(file, ",");
    827    err |= control(file, "horiz_stride", horiz_stride, _horiz_stride, NULL);
    828    string(file, ">");
    829    return err;
    830 }
    831 
    832 static int
    833 src_da1(FILE *file,
    834         const struct gen_device_info *devinfo,
    835         unsigned opcode,
    836         unsigned type, unsigned _reg_file,
    837         unsigned _vert_stride, unsigned _width, unsigned _horiz_stride,
    838         unsigned reg_num, unsigned sub_reg_num, unsigned __abs,
    839         unsigned _negate)
    840 {
    841    int err = 0;
    842 
    843    if (devinfo->gen >= 8 && is_logic_instruction(opcode))
    844       err |= control(file, "bitnot", m_bitnot, _negate, NULL);
    845    else
    846       err |= control(file, "negate", m_negate, _negate, NULL);
    847 
    848    err |= control(file, "abs", _abs, __abs, NULL);
    849 
    850    err |= reg(file, _reg_file, reg_num);
    851    if (err == -1)
    852       return 0;
    853    if (sub_reg_num)
    854       format(file, ".%d", sub_reg_num / reg_type_size[type]);   /* use formal style like spec */
    855    src_align1_region(file, _vert_stride, _width, _horiz_stride);
    856    err |= control(file, "src reg encoding", reg_encoding, type, NULL);
    857    return err;
    858 }
    859 
    860 static int
    861 src_ia1(FILE *file,
    862         const struct gen_device_info *devinfo,
    863         unsigned opcode,
    864         unsigned type,
    865         unsigned _reg_file,
    866         int _addr_imm,
    867         unsigned _addr_subreg_nr,
    868         unsigned _negate,
    869         unsigned __abs,
    870         unsigned _horiz_stride, unsigned _width, unsigned _vert_stride)
    871 {
    872    int err = 0;
    873 
    874    if (devinfo->gen >= 8 && is_logic_instruction(opcode))
    875       err |= control(file, "bitnot", m_bitnot, _negate, NULL);
    876    else
    877       err |= control(file, "negate", m_negate, _negate, NULL);
    878 
    879    err |= control(file, "abs", _abs, __abs, NULL);
    880 
    881    string(file, "g[a0");
    882    if (_addr_subreg_nr)
    883       format(file, ".%d", _addr_subreg_nr);
    884    if (_addr_imm)
    885       format(file, " %d", _addr_imm);
    886    string(file, "]");
    887    src_align1_region(file, _vert_stride, _width, _horiz_stride);
    888    err |= control(file, "src reg encoding", reg_encoding, type, NULL);
    889    return err;
    890 }
    891 
    892 static int
    893 src_swizzle(FILE *file, unsigned swiz)
    894 {
    895    unsigned x = BRW_GET_SWZ(swiz, BRW_CHANNEL_X);
    896    unsigned y = BRW_GET_SWZ(swiz, BRW_CHANNEL_Y);
    897    unsigned z = BRW_GET_SWZ(swiz, BRW_CHANNEL_Z);
    898    unsigned w = BRW_GET_SWZ(swiz, BRW_CHANNEL_W);
    899    int err = 0;
    900 
    901    if (x == y && x == z && x == w) {
    902       string(file, ".");
    903       err |= control(file, "channel select", chan_sel, x, NULL);
    904    } else if (swiz != BRW_SWIZZLE_XYZW) {
    905       string(file, ".");
    906       err |= control(file, "channel select", chan_sel, x, NULL);
    907       err |= control(file, "channel select", chan_sel, y, NULL);
    908       err |= control(file, "channel select", chan_sel, z, NULL);
    909       err |= control(file, "channel select", chan_sel, w, NULL);
    910    }
    911    return err;
    912 }
    913 
    914 static int
    915 src_da16(FILE *file,
    916          const struct gen_device_info *devinfo,
    917          unsigned opcode,
    918          unsigned _reg_type,
    919          unsigned _reg_file,
    920          unsigned _vert_stride,
    921          unsigned _reg_nr,
    922          unsigned _subreg_nr,
    923          unsigned __abs,
    924          unsigned _negate,
    925          unsigned swz_x, unsigned swz_y, unsigned swz_z, unsigned swz_w)
    926 {
    927    int err = 0;
    928 
    929    if (devinfo->gen >= 8 && is_logic_instruction(opcode))
    930       err |= control(file, "bitnot", m_bitnot, _negate, NULL);
    931    else
    932       err |= control(file, "negate", m_negate, _negate, NULL);
    933 
    934    err |= control(file, "abs", _abs, __abs, NULL);
    935 
    936    err |= reg(file, _reg_file, _reg_nr);
    937    if (err == -1)
    938       return 0;
    939    if (_subreg_nr)
    940       /* bit4 for subreg number byte addressing. Make this same meaning as
    941          in da1 case, so output looks consistent. */
    942       format(file, ".%d", 16 / reg_type_size[_reg_type]);
    943    string(file, "<");
    944    err |= control(file, "vert stride", vert_stride, _vert_stride, NULL);
    945    string(file, ">");
    946    err |= src_swizzle(file, BRW_SWIZZLE4(swz_x, swz_y, swz_z, swz_w));
    947    err |= control(file, "src da16 reg type", reg_encoding, _reg_type, NULL);
    948    return err;
    949 }
    950 
    951 static int
    952 src0_3src(FILE *file, const struct gen_device_info *devinfo, brw_inst *inst)
    953 {
    954    int err = 0;
    955    unsigned src0_subreg_nr = brw_inst_3src_src0_subreg_nr(devinfo, inst);
    956 
    957    err |= control(file, "negate", m_negate,
    958                   brw_inst_3src_src0_negate(devinfo, inst), NULL);
    959    err |= control(file, "abs", _abs, brw_inst_3src_src0_abs(devinfo, inst), NULL);
    960 
    961    err |= reg(file, BRW_GENERAL_REGISTER_FILE,
    962               brw_inst_3src_src0_reg_nr(devinfo, inst));
    963    if (err == -1)
    964       return 0;
    965    if (src0_subreg_nr || brw_inst_3src_src0_rep_ctrl(devinfo, inst))
    966       format(file, ".%d", src0_subreg_nr);
    967    if (brw_inst_3src_src0_rep_ctrl(devinfo, inst))
    968       string(file, "<0,1,0>");
    969    else {
    970       string(file, "<4,4,1>");
    971       err |= src_swizzle(file, brw_inst_3src_src0_swizzle(devinfo, inst));
    972    }
    973    err |= control(file, "src da16 reg type", three_source_reg_encoding,
    974                   brw_inst_3src_src_type(devinfo, inst), NULL);
    975    return err;
    976 }
    977 
    978 static int
    979 src1_3src(FILE *file, const struct gen_device_info *devinfo, brw_inst *inst)
    980 {
    981    int err = 0;
    982    unsigned src1_subreg_nr = brw_inst_3src_src1_subreg_nr(devinfo, inst);
    983 
    984    err |= control(file, "negate", m_negate,
    985                   brw_inst_3src_src1_negate(devinfo, inst), NULL);
    986    err |= control(file, "abs", _abs, brw_inst_3src_src1_abs(devinfo, inst), NULL);
    987 
    988    err |= reg(file, BRW_GENERAL_REGISTER_FILE,
    989               brw_inst_3src_src1_reg_nr(devinfo, inst));
    990    if (err == -1)
    991       return 0;
    992    if (src1_subreg_nr || brw_inst_3src_src1_rep_ctrl(devinfo, inst))
    993       format(file, ".%d", src1_subreg_nr);
    994    if (brw_inst_3src_src1_rep_ctrl(devinfo, inst))
    995       string(file, "<0,1,0>");
    996    else {
    997       string(file, "<4,4,1>");
    998       err |= src_swizzle(file, brw_inst_3src_src1_swizzle(devinfo, inst));
    999    }
   1000    err |= control(file, "src da16 reg type", three_source_reg_encoding,
   1001                   brw_inst_3src_src_type(devinfo, inst), NULL);
   1002    return err;
   1003 }
   1004 
   1005 
   1006 static int
   1007 src2_3src(FILE *file, const struct gen_device_info *devinfo, brw_inst *inst)
   1008 {
   1009    int err = 0;
   1010    unsigned src2_subreg_nr = brw_inst_3src_src2_subreg_nr(devinfo, inst);
   1011 
   1012    err |= control(file, "negate", m_negate,
   1013                   brw_inst_3src_src2_negate(devinfo, inst), NULL);
   1014    err |= control(file, "abs", _abs, brw_inst_3src_src2_abs(devinfo, inst), NULL);
   1015 
   1016    err |= reg(file, BRW_GENERAL_REGISTER_FILE,
   1017               brw_inst_3src_src2_reg_nr(devinfo, inst));
   1018    if (err == -1)
   1019       return 0;
   1020    if (src2_subreg_nr || brw_inst_3src_src2_rep_ctrl(devinfo, inst))
   1021       format(file, ".%d", src2_subreg_nr);
   1022    if (brw_inst_3src_src2_rep_ctrl(devinfo, inst))
   1023       string(file, "<0,1,0>");
   1024    else {
   1025       string(file, "<4,4,1>");
   1026       err |= src_swizzle(file, brw_inst_3src_src2_swizzle(devinfo, inst));
   1027    }
   1028    err |= control(file, "src da16 reg type", three_source_reg_encoding,
   1029                   brw_inst_3src_src_type(devinfo, inst), NULL);
   1030    return err;
   1031 }
   1032 
   1033 static int
   1034 imm(FILE *file, const struct gen_device_info *devinfo, unsigned type, brw_inst *inst)
   1035 {
   1036    switch (type) {
   1037    case BRW_HW_REG_TYPE_UD:
   1038       format(file, "0x%08xUD", brw_inst_imm_ud(devinfo, inst));
   1039       break;
   1040    case BRW_HW_REG_TYPE_D:
   1041       format(file, "%dD", brw_inst_imm_d(devinfo, inst));
   1042       break;
   1043    case BRW_HW_REG_TYPE_UW:
   1044       format(file, "0x%04xUW", (uint16_t) brw_inst_imm_ud(devinfo, inst));
   1045       break;
   1046    case BRW_HW_REG_TYPE_W:
   1047       format(file, "%dW", (int16_t) brw_inst_imm_d(devinfo, inst));
   1048       break;
   1049    case BRW_HW_REG_IMM_TYPE_UV:
   1050       format(file, "0x%08xUV", brw_inst_imm_ud(devinfo, inst));
   1051       break;
   1052    case BRW_HW_REG_IMM_TYPE_VF:
   1053       format(file, "[%-gF, %-gF, %-gF, %-gF]VF",
   1054              brw_vf_to_float(brw_inst_imm_ud(devinfo, inst)),
   1055              brw_vf_to_float(brw_inst_imm_ud(devinfo, inst) >> 8),
   1056              brw_vf_to_float(brw_inst_imm_ud(devinfo, inst) >> 16),
   1057              brw_vf_to_float(brw_inst_imm_ud(devinfo, inst) >> 24));
   1058       break;
   1059    case BRW_HW_REG_IMM_TYPE_V:
   1060       format(file, "0x%08xV", brw_inst_imm_ud(devinfo, inst));
   1061       break;
   1062    case BRW_HW_REG_TYPE_F:
   1063       format(file, "%-gF", brw_inst_imm_f(devinfo, inst));
   1064       break;
   1065    case GEN8_HW_REG_IMM_TYPE_DF:
   1066       format(file, "%-gDF", brw_inst_imm_df(devinfo, inst));
   1067       break;
   1068    case GEN8_HW_REG_IMM_TYPE_HF:
   1069       string(file, "Half Float IMM");
   1070       break;
   1071    }
   1072    return 0;
   1073 }
   1074 
   1075 static int
   1076 src0(FILE *file, const struct gen_device_info *devinfo, brw_inst *inst)
   1077 {
   1078    if (brw_inst_src0_reg_file(devinfo, inst) == BRW_IMMEDIATE_VALUE) {
   1079       return imm(file, devinfo, brw_inst_src0_reg_type(devinfo, inst), inst);
   1080    } else if (brw_inst_access_mode(devinfo, inst) == BRW_ALIGN_1) {
   1081       if (brw_inst_src0_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
   1082          return src_da1(file,
   1083                         devinfo,
   1084                         brw_inst_opcode(devinfo, inst),
   1085                         brw_inst_src0_reg_type(devinfo, inst),
   1086                         brw_inst_src0_reg_file(devinfo, inst),
   1087                         brw_inst_src0_vstride(devinfo, inst),
   1088                         brw_inst_src0_width(devinfo, inst),
   1089                         brw_inst_src0_hstride(devinfo, inst),
   1090                         brw_inst_src0_da_reg_nr(devinfo, inst),
   1091                         brw_inst_src0_da1_subreg_nr(devinfo, inst),
   1092                         brw_inst_src0_abs(devinfo, inst),
   1093                         brw_inst_src0_negate(devinfo, inst));
   1094       } else {
   1095          return src_ia1(file,
   1096                         devinfo,
   1097                         brw_inst_opcode(devinfo, inst),
   1098                         brw_inst_src0_reg_type(devinfo, inst),
   1099                         brw_inst_src0_reg_file(devinfo, inst),
   1100                         brw_inst_src0_ia1_addr_imm(devinfo, inst),
   1101                         brw_inst_src0_ia_subreg_nr(devinfo, inst),
   1102                         brw_inst_src0_negate(devinfo, inst),
   1103                         brw_inst_src0_abs(devinfo, inst),
   1104                         brw_inst_src0_hstride(devinfo, inst),
   1105                         brw_inst_src0_width(devinfo, inst),
   1106                         brw_inst_src0_vstride(devinfo, inst));
   1107       }
   1108    } else {
   1109       if (brw_inst_src0_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
   1110          return src_da16(file,
   1111                          devinfo,
   1112                          brw_inst_opcode(devinfo, inst),
   1113                          brw_inst_src0_reg_type(devinfo, inst),
   1114                          brw_inst_src0_reg_file(devinfo, inst),
   1115                          brw_inst_src0_vstride(devinfo, inst),
   1116                          brw_inst_src0_da_reg_nr(devinfo, inst),
   1117                          brw_inst_src0_da16_subreg_nr(devinfo, inst),
   1118                          brw_inst_src0_abs(devinfo, inst),
   1119                          brw_inst_src0_negate(devinfo, inst),
   1120                          brw_inst_src0_da16_swiz_x(devinfo, inst),
   1121                          brw_inst_src0_da16_swiz_y(devinfo, inst),
   1122                          brw_inst_src0_da16_swiz_z(devinfo, inst),
   1123                          brw_inst_src0_da16_swiz_w(devinfo, inst));
   1124       } else {
   1125          string(file, "Indirect align16 address mode not supported");
   1126          return 1;
   1127       }
   1128    }
   1129 }
   1130 
   1131 static int
   1132 src1(FILE *file, const struct gen_device_info *devinfo, brw_inst *inst)
   1133 {
   1134    if (brw_inst_src1_reg_file(devinfo, inst) == BRW_IMMEDIATE_VALUE) {
   1135       return imm(file, devinfo, brw_inst_src1_reg_type(devinfo, inst), inst);
   1136    } else if (brw_inst_access_mode(devinfo, inst) == BRW_ALIGN_1) {
   1137       if (brw_inst_src1_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
   1138          return src_da1(file,
   1139                         devinfo,
   1140                         brw_inst_opcode(devinfo, inst),
   1141                         brw_inst_src1_reg_type(devinfo, inst),
   1142                         brw_inst_src1_reg_file(devinfo, inst),
   1143                         brw_inst_src1_vstride(devinfo, inst),
   1144                         brw_inst_src1_width(devinfo, inst),
   1145                         brw_inst_src1_hstride(devinfo, inst),
   1146                         brw_inst_src1_da_reg_nr(devinfo, inst),
   1147                         brw_inst_src1_da1_subreg_nr(devinfo, inst),
   1148                         brw_inst_src1_abs(devinfo, inst),
   1149                         brw_inst_src1_negate(devinfo, inst));
   1150       } else {
   1151          return src_ia1(file,
   1152                         devinfo,
   1153                         brw_inst_opcode(devinfo, inst),
   1154                         brw_inst_src1_reg_type(devinfo, inst),
   1155                         brw_inst_src1_reg_file(devinfo, inst),
   1156                         brw_inst_src1_ia1_addr_imm(devinfo, inst),
   1157                         brw_inst_src1_ia_subreg_nr(devinfo, inst),
   1158                         brw_inst_src1_negate(devinfo, inst),
   1159                         brw_inst_src1_abs(devinfo, inst),
   1160                         brw_inst_src1_hstride(devinfo, inst),
   1161                         brw_inst_src1_width(devinfo, inst),
   1162                         brw_inst_src1_vstride(devinfo, inst));
   1163       }
   1164    } else {
   1165       if (brw_inst_src1_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
   1166          return src_da16(file,
   1167                          devinfo,
   1168                          brw_inst_opcode(devinfo, inst),
   1169                          brw_inst_src1_reg_type(devinfo, inst),
   1170                          brw_inst_src1_reg_file(devinfo, inst),
   1171                          brw_inst_src1_vstride(devinfo, inst),
   1172                          brw_inst_src1_da_reg_nr(devinfo, inst),
   1173                          brw_inst_src1_da16_subreg_nr(devinfo, inst),
   1174                          brw_inst_src1_abs(devinfo, inst),
   1175                          brw_inst_src1_negate(devinfo, inst),
   1176                          brw_inst_src1_da16_swiz_x(devinfo, inst),
   1177                          brw_inst_src1_da16_swiz_y(devinfo, inst),
   1178                          brw_inst_src1_da16_swiz_z(devinfo, inst),
   1179                          brw_inst_src1_da16_swiz_w(devinfo, inst));
   1180       } else {
   1181          string(file, "Indirect align16 address mode not supported");
   1182          return 1;
   1183       }
   1184    }
   1185 }
   1186 
   1187 static int
   1188 qtr_ctrl(FILE *file, const struct gen_device_info *devinfo, brw_inst *inst)
   1189 {
   1190    int qtr_ctl = brw_inst_qtr_control(devinfo, inst);
   1191    int exec_size = 1 << brw_inst_exec_size(devinfo, inst);
   1192 
   1193    if (exec_size < 8) {
   1194       const unsigned nib_ctl = devinfo->gen < 7 ? 0 :
   1195                                brw_inst_nib_control(devinfo, inst);
   1196       format(file, " %dN", qtr_ctl * 2 + nib_ctl + 1);
   1197    } else if (exec_size == 8) {
   1198       switch (qtr_ctl) {
   1199       case 0:
   1200          string(file, " 1Q");
   1201          break;
   1202       case 1:
   1203          string(file, " 2Q");
   1204          break;
   1205       case 2:
   1206          string(file, " 3Q");
   1207          break;
   1208       case 3:
   1209          string(file, " 4Q");
   1210          break;
   1211       }
   1212    } else if (exec_size == 16) {
   1213       if (qtr_ctl < 2)
   1214          string(file, " 1H");
   1215       else
   1216          string(file, " 2H");
   1217    }
   1218    return 0;
   1219 }
   1220 
   1221 #ifdef DEBUG
   1222 static __attribute__((__unused__)) int
   1223 brw_disassemble_imm(const struct gen_device_info *devinfo,
   1224                     uint32_t dw3, uint32_t dw2, uint32_t dw1, uint32_t dw0)
   1225 {
   1226    brw_inst inst;
   1227    inst.data[0] = (((uint64_t) dw1) << 32) | ((uint64_t) dw0);
   1228    inst.data[1] = (((uint64_t) dw3) << 32) | ((uint64_t) dw2);
   1229    return brw_disassemble_inst(stderr, devinfo, &inst, false);
   1230 }
   1231 #endif
   1232 
   1233 int
   1234 brw_disassemble_inst(FILE *file, const struct gen_device_info *devinfo,
   1235                      brw_inst *inst, bool is_compacted)
   1236 {
   1237    int err = 0;
   1238    int space = 0;
   1239 
   1240    const enum opcode opcode = brw_inst_opcode(devinfo, inst);
   1241    const struct opcode_desc *desc = brw_opcode_desc(devinfo, opcode);
   1242 
   1243    if (brw_inst_pred_control(devinfo, inst)) {
   1244       string(file, "(");
   1245       err |= control(file, "predicate inverse", pred_inv,
   1246                      brw_inst_pred_inv(devinfo, inst), NULL);
   1247       format(file, "f%"PRIu64, devinfo->gen >= 7 ? brw_inst_flag_reg_nr(devinfo, inst) : 0);
   1248       if (brw_inst_flag_subreg_nr(devinfo, inst))
   1249          format(file, ".%"PRIu64, brw_inst_flag_subreg_nr(devinfo, inst));
   1250       if (brw_inst_access_mode(devinfo, inst) == BRW_ALIGN_1) {
   1251          err |= control(file, "predicate control align1", pred_ctrl_align1,
   1252                         brw_inst_pred_control(devinfo, inst), NULL);
   1253       } else {
   1254          err |= control(file, "predicate control align16", pred_ctrl_align16,
   1255                         brw_inst_pred_control(devinfo, inst), NULL);
   1256       }
   1257       string(file, ") ");
   1258    }
   1259 
   1260    err |= print_opcode(file, devinfo, opcode);
   1261    err |= control(file, "saturate", saturate, brw_inst_saturate(devinfo, inst),
   1262                   NULL);
   1263 
   1264    err |= control(file, "debug control", debug_ctrl,
   1265                   brw_inst_debug_control(devinfo, inst), NULL);
   1266 
   1267    if (opcode == BRW_OPCODE_MATH) {
   1268       string(file, " ");
   1269       err |= control(file, "function", math_function,
   1270                      brw_inst_math_function(devinfo, inst), NULL);
   1271    } else if (opcode != BRW_OPCODE_SEND && opcode != BRW_OPCODE_SENDC) {
   1272       err |= control(file, "conditional modifier", conditional_modifier,
   1273                      brw_inst_cond_modifier(devinfo, inst), NULL);
   1274 
   1275       /* If we're using the conditional modifier, print which flags reg is
   1276        * used for it.  Note that on gen6+, the embedded-condition SEL and
   1277        * control flow doesn't update flags.
   1278        */
   1279       if (brw_inst_cond_modifier(devinfo, inst) &&
   1280           (devinfo->gen < 6 || (opcode != BRW_OPCODE_SEL &&
   1281                             opcode != BRW_OPCODE_IF &&
   1282                             opcode != BRW_OPCODE_WHILE))) {
   1283          format(file, ".f%"PRIu64,
   1284                 devinfo->gen >= 7 ? brw_inst_flag_reg_nr(devinfo, inst) : 0);
   1285          if (brw_inst_flag_subreg_nr(devinfo, inst))
   1286             format(file, ".%"PRIu64, brw_inst_flag_subreg_nr(devinfo, inst));
   1287       }
   1288    }
   1289 
   1290    if (opcode != BRW_OPCODE_NOP && opcode != BRW_OPCODE_NENOP) {
   1291       string(file, "(");
   1292       err |= control(file, "execution size", exec_size,
   1293                      brw_inst_exec_size(devinfo, inst), NULL);
   1294       string(file, ")");
   1295    }
   1296 
   1297    if (opcode == BRW_OPCODE_SEND && devinfo->gen < 6)
   1298       format(file, " %"PRIu64, brw_inst_base_mrf(devinfo, inst));
   1299 
   1300    if (has_uip(devinfo, opcode)) {
   1301       /* Instructions that have UIP also have JIP. */
   1302       pad(file, 16);
   1303       format(file, "JIP: %d", brw_inst_jip(devinfo, inst));
   1304       pad(file, 32);
   1305       format(file, "UIP: %d", brw_inst_uip(devinfo, inst));
   1306    } else if (has_jip(devinfo, opcode)) {
   1307       pad(file, 16);
   1308       if (devinfo->gen >= 7) {
   1309          format(file, "JIP: %d", brw_inst_jip(devinfo, inst));
   1310       } else {
   1311          format(file, "JIP: %d", brw_inst_gen6_jump_count(devinfo, inst));
   1312       }
   1313    } else if (devinfo->gen < 6 && (opcode == BRW_OPCODE_BREAK ||
   1314                                opcode == BRW_OPCODE_CONTINUE ||
   1315                                opcode == BRW_OPCODE_ELSE)) {
   1316       pad(file, 16);
   1317       format(file, "Jump: %d", brw_inst_gen4_jump_count(devinfo, inst));
   1318       pad(file, 32);
   1319       format(file, "Pop: %"PRIu64, brw_inst_gen4_pop_count(devinfo, inst));
   1320    } else if (devinfo->gen < 6 && (opcode == BRW_OPCODE_IF ||
   1321                                opcode == BRW_OPCODE_IFF ||
   1322                                opcode == BRW_OPCODE_HALT)) {
   1323       pad(file, 16);
   1324       format(file, "Jump: %d", brw_inst_gen4_jump_count(devinfo, inst));
   1325    } else if (devinfo->gen < 6 && opcode == BRW_OPCODE_ENDIF) {
   1326       pad(file, 16);
   1327       format(file, "Pop: %"PRIu64, brw_inst_gen4_pop_count(devinfo, inst));
   1328    } else if (opcode == BRW_OPCODE_JMPI) {
   1329       pad(file, 16);
   1330       err |= src1(file, devinfo, inst);
   1331    } else if (desc && desc->nsrc == 3) {
   1332       pad(file, 16);
   1333       err |= dest_3src(file, devinfo, inst);
   1334 
   1335       pad(file, 32);
   1336       err |= src0_3src(file, devinfo, inst);
   1337 
   1338       pad(file, 48);
   1339       err |= src1_3src(file, devinfo, inst);
   1340 
   1341       pad(file, 64);
   1342       err |= src2_3src(file, devinfo, inst);
   1343    } else if (desc) {
   1344       if (desc->ndst > 0) {
   1345          pad(file, 16);
   1346          err |= dest(file, devinfo, inst);
   1347       }
   1348 
   1349       if (desc->nsrc > 0) {
   1350          pad(file, 32);
   1351          err |= src0(file, devinfo, inst);
   1352       }
   1353 
   1354       if (desc->nsrc > 1) {
   1355          pad(file, 48);
   1356          err |= src1(file, devinfo, inst);
   1357       }
   1358    }
   1359 
   1360    if (opcode == BRW_OPCODE_SEND || opcode == BRW_OPCODE_SENDC) {
   1361       enum brw_message_target sfid = brw_inst_sfid(devinfo, inst);
   1362 
   1363       if (brw_inst_src1_reg_file(devinfo, inst) != BRW_IMMEDIATE_VALUE) {
   1364          /* show the indirect descriptor source */
   1365          pad(file, 48);
   1366          err |= src1(file, devinfo, inst);
   1367       }
   1368 
   1369       newline(file);
   1370       pad(file, 16);
   1371       space = 0;
   1372 
   1373       fprintf(file, "            ");
   1374       err |= control(file, "SFID", devinfo->gen >= 6 ? gen6_sfid : gen4_sfid,
   1375                      sfid, &space);
   1376 
   1377 
   1378       if (brw_inst_src1_reg_file(devinfo, inst) != BRW_IMMEDIATE_VALUE) {
   1379          format(file, " indirect");
   1380       } else {
   1381          switch (sfid) {
   1382          case BRW_SFID_MATH:
   1383             err |= control(file, "math function", math_function,
   1384                            brw_inst_math_msg_function(devinfo, inst), &space);
   1385             err |= control(file, "math saturate", math_saturate,
   1386                            brw_inst_math_msg_saturate(devinfo, inst), &space);
   1387             err |= control(file, "math signed", math_signed,
   1388                            brw_inst_math_msg_signed_int(devinfo, inst), &space);
   1389             err |= control(file, "math scalar", math_scalar,
   1390                            brw_inst_math_msg_data_type(devinfo, inst), &space);
   1391             err |= control(file, "math precision", math_precision,
   1392                            brw_inst_math_msg_precision(devinfo, inst), &space);
   1393             break;
   1394          case BRW_SFID_SAMPLER:
   1395             if (devinfo->gen >= 5) {
   1396                err |= control(file, "sampler message", gen5_sampler_msg_type,
   1397                               brw_inst_sampler_msg_type(devinfo, inst), &space);
   1398                err |= control(file, "sampler simd mode", gen5_sampler_simd_mode,
   1399                               brw_inst_sampler_simd_mode(devinfo, inst), &space);
   1400                format(file, " Surface = %"PRIu64" Sampler = %"PRIu64,
   1401                       brw_inst_binding_table_index(devinfo, inst),
   1402                       brw_inst_sampler(devinfo, inst));
   1403             } else {
   1404                format(file, " (%"PRIu64", %"PRIu64", %"PRIu64", ",
   1405                       brw_inst_binding_table_index(devinfo, inst),
   1406                       brw_inst_sampler(devinfo, inst),
   1407                       brw_inst_sampler_msg_type(devinfo, inst));
   1408                if (!devinfo->is_g4x) {
   1409                   err |= control(file, "sampler target format",
   1410                                  sampler_target_format,
   1411                                  brw_inst_sampler_return_format(devinfo, inst), NULL);
   1412                }
   1413                string(file, ")");
   1414             }
   1415             break;
   1416          case GEN6_SFID_DATAPORT_SAMPLER_CACHE:
   1417          case GEN6_SFID_DATAPORT_CONSTANT_CACHE:
   1418             /* aka BRW_SFID_DATAPORT_READ on Gen4-5 */
   1419             if (devinfo->gen >= 6) {
   1420                format(file, " (%"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64")",
   1421                       brw_inst_binding_table_index(devinfo, inst),
   1422                       brw_inst_dp_msg_control(devinfo, inst),
   1423                       brw_inst_dp_msg_type(devinfo, inst),
   1424                       devinfo->gen >= 7 ? 0 : brw_inst_dp_write_commit(devinfo, inst));
   1425             } else {
   1426                bool is_965 = devinfo->gen == 4 && !devinfo->is_g4x;
   1427                err |= control(file, "DP read message type",
   1428                               is_965 ? gen4_dp_read_port_msg_type :
   1429                                        g45_dp_read_port_msg_type,
   1430                               brw_inst_dp_read_msg_type(devinfo, inst),
   1431                               &space);
   1432 
   1433                format(file, " MsgCtrl = 0x%"PRIx64,
   1434                       brw_inst_dp_read_msg_control(devinfo, inst));
   1435 
   1436                format(file, " Surface = %"PRIu64, brw_inst_binding_table_index(devinfo, inst));
   1437             }
   1438             break;
   1439 
   1440          case GEN6_SFID_DATAPORT_RENDER_CACHE: {
   1441             /* aka BRW_SFID_DATAPORT_WRITE on Gen4-5 */
   1442             unsigned msg_type = brw_inst_dp_write_msg_type(devinfo, inst);
   1443 
   1444             err |= control(file, "DP rc message type",
   1445                            dp_rc_msg_type(devinfo), msg_type, &space);
   1446 
   1447             bool is_rt_write = msg_type ==
   1448                (devinfo->gen >= 6 ? GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE
   1449                                   : BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE);
   1450 
   1451             if (is_rt_write) {
   1452                err |= control(file, "RT message type", m_rt_write_subtype,
   1453                               brw_inst_rt_message_type(devinfo, inst), &space);
   1454                if (devinfo->gen >= 6 && brw_inst_rt_slot_group(devinfo, inst))
   1455                   string(file, " Hi");
   1456                if (brw_inst_rt_last(devinfo, inst))
   1457                   string(file, " LastRT");
   1458                if (devinfo->gen < 7 && brw_inst_dp_write_commit(devinfo, inst))
   1459                   string(file, " WriteCommit");
   1460             } else {
   1461                format(file, " MsgCtrl = 0x%"PRIx64,
   1462                       brw_inst_dp_write_msg_control(devinfo, inst));
   1463             }
   1464 
   1465             format(file, " Surface = %"PRIu64, brw_inst_binding_table_index(devinfo, inst));
   1466             break;
   1467          }
   1468 
   1469          case BRW_SFID_URB: {
   1470             unsigned opcode = brw_inst_urb_opcode(devinfo, inst);
   1471 
   1472             format(file, " %"PRIu64, brw_inst_urb_global_offset(devinfo, inst));
   1473 
   1474             space = 1;
   1475 
   1476             err |= control(file, "urb opcode",
   1477                            devinfo->gen >= 7 ? gen7_urb_opcode
   1478                                              : gen5_urb_opcode,
   1479                            opcode, &space);
   1480 
   1481             if (devinfo->gen >= 7 &&
   1482                 brw_inst_urb_per_slot_offset(devinfo, inst)) {
   1483                string(file, " per-slot");
   1484             }
   1485 
   1486             if (opcode == GEN8_URB_OPCODE_SIMD8_WRITE ||
   1487                 opcode == GEN8_URB_OPCODE_SIMD8_READ) {
   1488                if (brw_inst_urb_channel_mask_present(devinfo, inst))
   1489                   string(file, " masked");
   1490             } else {
   1491                err |= control(file, "urb swizzle", urb_swizzle,
   1492                               brw_inst_urb_swizzle_control(devinfo, inst),
   1493                               &space);
   1494             }
   1495 
   1496             if (devinfo->gen < 7) {
   1497                err |= control(file, "urb allocate", urb_allocate,
   1498                               brw_inst_urb_allocate(devinfo, inst), &space);
   1499                err |= control(file, "urb used", urb_used,
   1500                               brw_inst_urb_used(devinfo, inst), &space);
   1501             }
   1502             if (devinfo->gen < 8) {
   1503                err |= control(file, "urb complete", urb_complete,
   1504                               brw_inst_urb_complete(devinfo, inst), &space);
   1505             }
   1506             break;
   1507          }
   1508          case BRW_SFID_THREAD_SPAWNER:
   1509             break;
   1510 
   1511          case BRW_SFID_MESSAGE_GATEWAY:
   1512             format(file, " (%s)",
   1513                    gen7_gateway_subfuncid[brw_inst_gateway_subfuncid(devinfo, inst)]);
   1514             break;
   1515 
   1516          case GEN7_SFID_DATAPORT_DATA_CACHE:
   1517             if (devinfo->gen >= 7) {
   1518                format(file, " (");
   1519 
   1520                err |= control(file, "DP DC0 message type",
   1521                               dp_dc0_msg_type_gen7,
   1522                               brw_inst_dp_msg_type(devinfo, inst), &space);
   1523 
   1524                format(file, ", %"PRIu64", ", brw_inst_binding_table_index(devinfo, inst));
   1525 
   1526                switch (brw_inst_dp_msg_type(devinfo, inst)) {
   1527                case GEN7_DATAPORT_DC_UNTYPED_ATOMIC_OP:
   1528                   control(file, "atomic op", aop,
   1529                           brw_inst_imm_ud(devinfo, inst) >> 8 & 0xf, &space);
   1530                   break;
   1531                default:
   1532                   format(file, "%"PRIu64, brw_inst_dp_msg_control(devinfo, inst));
   1533                }
   1534                format(file, ")");
   1535                break;
   1536             }
   1537             /* FALLTHROUGH */
   1538 
   1539          case HSW_SFID_DATAPORT_DATA_CACHE_1: {
   1540             if (devinfo->gen >= 7) {
   1541                format(file, " (");
   1542 
   1543                unsigned msg_ctrl = brw_inst_dp_msg_control(devinfo, inst);
   1544 
   1545                err |= control(file, "DP DC1 message type",
   1546                               dp_dc1_msg_type_hsw,
   1547                               brw_inst_dp_msg_type(devinfo, inst), &space);
   1548 
   1549                format(file, ", Surface = %"PRIu64", ",
   1550                       brw_inst_binding_table_index(devinfo, inst));
   1551 
   1552                switch (brw_inst_dp_msg_type(devinfo, inst)) {
   1553                case HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP:
   1554                case HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP:
   1555                case HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP:
   1556                   format(file, "SIMD%d,", (msg_ctrl & (1 << 4)) ? 8 : 16);
   1557                   /* fallthrough */
   1558                case HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP_SIMD4X2:
   1559                case HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP_SIMD4X2:
   1560                case HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP_SIMD4X2:
   1561                   control(file, "atomic op", aop, msg_ctrl & 0xf, &space);
   1562                   break;
   1563                case HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_READ:
   1564                case HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_WRITE:
   1565                case HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_READ:
   1566                case HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_WRITE: {
   1567                   static const char *simd_modes[] = { "4x2", "16", "8" };
   1568                   format(file, "SIMD%s, Mask = 0x%x",
   1569                          simd_modes[msg_ctrl >> 4], msg_ctrl & 0xf);
   1570                   break;
   1571                }
   1572                default:
   1573                   format(file, "0x%x", msg_ctrl);
   1574                }
   1575                format(file, ")");
   1576                break;
   1577             }
   1578             /* FALLTHROUGH */
   1579          }
   1580 
   1581          case GEN7_SFID_PIXEL_INTERPOLATOR:
   1582             if (devinfo->gen >= 7) {
   1583                format(file, " (%s, %s, 0x%02"PRIx64")",
   1584                       brw_inst_pi_nopersp(devinfo, inst) ? "linear" : "persp",
   1585                       pixel_interpolator_msg_types[brw_inst_pi_message_type(devinfo, inst)],
   1586                       brw_inst_pi_message_data(devinfo, inst));
   1587                break;
   1588             }
   1589             /* FALLTHROUGH */
   1590 
   1591          default:
   1592             format(file, "unsupported shared function ID %d", sfid);
   1593             break;
   1594          }
   1595 
   1596          if (space)
   1597             string(file, " ");
   1598          format(file, "mlen %"PRIu64, brw_inst_mlen(devinfo, inst));
   1599          format(file, " rlen %"PRIu64, brw_inst_rlen(devinfo, inst));
   1600       }
   1601    }
   1602    pad(file, 64);
   1603    if (opcode != BRW_OPCODE_NOP && opcode != BRW_OPCODE_NENOP) {
   1604       string(file, "{");
   1605       space = 1;
   1606       err |= control(file, "access mode", access_mode,
   1607                      brw_inst_access_mode(devinfo, inst), &space);
   1608       if (devinfo->gen >= 6) {
   1609          err |= control(file, "write enable control", wectrl,
   1610                         brw_inst_mask_control(devinfo, inst), &space);
   1611       } else {
   1612          err |= control(file, "mask control", mask_ctrl,
   1613                         brw_inst_mask_control(devinfo, inst), &space);
   1614       }
   1615       err |= control(file, "dependency control", dep_ctrl,
   1616                      ((brw_inst_no_dd_check(devinfo, inst) << 1) |
   1617                       brw_inst_no_dd_clear(devinfo, inst)), &space);
   1618 
   1619       if (devinfo->gen >= 6)
   1620          err |= qtr_ctrl(file, devinfo, inst);
   1621       else {
   1622          if (brw_inst_qtr_control(devinfo, inst) == BRW_COMPRESSION_COMPRESSED &&
   1623              desc && desc->ndst > 0 &&
   1624              brw_inst_dst_reg_file(devinfo, inst) == BRW_MESSAGE_REGISTER_FILE &&
   1625              brw_inst_dst_da_reg_nr(devinfo, inst) & BRW_MRF_COMPR4) {
   1626             format(file, " compr4");
   1627          } else {
   1628             err |= control(file, "compression control", compr_ctrl,
   1629                            brw_inst_qtr_control(devinfo, inst), &space);
   1630          }
   1631       }
   1632 
   1633       err |= control(file, "compaction", cmpt_ctrl, is_compacted, &space);
   1634       err |= control(file, "thread control", thread_ctrl,
   1635                      brw_inst_thread_control(devinfo, inst), &space);
   1636       if (has_branch_ctrl(devinfo, opcode)) {
   1637          err |= control(file, "branch ctrl", branch_ctrl,
   1638                         brw_inst_branch_control(devinfo, inst), &space);
   1639       } else if (devinfo->gen >= 6) {
   1640          err |= control(file, "acc write control", accwr,
   1641                         brw_inst_acc_wr_control(devinfo, inst), &space);
   1642       }
   1643       if (opcode == BRW_OPCODE_SEND || opcode == BRW_OPCODE_SENDC)
   1644          err |= control(file, "end of thread", end_of_thread,
   1645                         brw_inst_eot(devinfo, inst), &space);
   1646       if (space)
   1647          string(file, " ");
   1648       string(file, "}");
   1649    }
   1650    string(file, ";");
   1651    newline(file);
   1652    return err;
   1653 }
   1654