Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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