
#include "disasm-internal.h"

UNUSED static const char *enum_hint[] = {
    [1] = "",
    [2] = "cache",
    [3] = "discard",
};
UNUSED static const char *enum_interpolation[] = {
    [0] = "",
    [1] = "sample",
    [2] = "centroid",
    [3] = "sample",
};
UNUSED static const char *enum_coherent[] = {
    [0] = "",
    [1] = "coherent1",
    [2] = "coherent2",
    [3] = "coherent",
};
UNUSED static const char *enum_atomic[] = {
    [0] = "add",
    [1] = "sub",
    [2] = "xchg",
    [3] = "cmpxchg",
    [4] = "umin",
    [5] = "imin",
    [6] = "umax",
    [7] = "imax",
    [8] = "and",
    [9] = "or",
    [10] = "xor",
};
UNUSED static const char *enum_sr[] = {
    [0] = "threadgroup_in_grid_x",
    [1] = "threadgroup_in_grid_y",
    [2] = "threadgroup_in_grid_z",
    [4] = "threads_per_threadgroup_x",
    [5] = "threads_per_threadgroup_y",
    [6] = "threads_per_threadgroup_z",
    [8] = "dispatch_threads_per_threadgroup_x",
    [9] = "dispatch_threads_per_threadgroup_y",
    [10] = "dispatch_threads_per_threadgroup_z",
    [12] = "threadgroup_width",
    [13] = "threadgroup_height",
    [14] = "samples_log2",
    [20] = "core_index",
    [21] = "vm_slot",
    [48] = "thread_in_threadgroup_x",
    [49] = "thread_in_threadgroup_y",
    [50] = "thread_in_threadgroup_z",
    [51] = "thread_index_in_threadgroup",
    [52] = "thread_index_in_simdgroup",
    [53] = "simdgroup_index_in_threadgroup",
    [56] = "active_thread_index_in_quadgroup",
    [57] = "total_active_threads_in_quadgroup",
    [58] = "active_thread_index_in_simdgroup",
    [59] = "total_active_threads_in_simdgroup",
    [60] = "internal_coverage_mask",
    [62] = "backfacing",
    [63] = "is_active_thread",
    [80] = "thread_in_grid_x",
    [81] = "thread_in_grid_y",
    [82] = "thread_in_grid_z",
    [124] = "input_sample_mask",
    [144] = "helper_op",
    [146] = "helper_arg_l",
    [147] = "helper_arg_h",
};
UNUSED static const char *enum_round[] = {
    [0] = "rtz",
    [1] = "rte",
};
UNUSED static const char *enum_group[] = {
    [0] = "a",
    [1] = "b",
};
UNUSED static const char *enum_shift[] = {
    [0] = "",
    [1] = "lsl 1",
    [2] = "lsl 2",
    [3] = "lsl 3",
    [4] = "lsl 4",
};
UNUSED static const char *enum_ext[] = {
    [0] = "sx",
    [1] = "zx",
};
UNUSED static const char *enum_icond[] = {
    [0] = "ieq",
    [1] = "ult",
    [2] = "ugt",
    [4] = "seq",
    [5] = "slt",
    [6] = "sgt",
    [8] = "ine",
    [9] = "ugte",
    [10] = "ulte",
    [12] = "nseq",
    [13] = "sgte",
    [14] = "slte",
};
UNUSED static const char *enum_fcond[] = {
    [0] = "feq",
    [1] = "flt",
    [2] = "fgt",
    [3] = "fltn",
    [5] = "fgte",
    [6] = "flte",
    [7] = "fgtn",
    [8] = "fneq",
    [9] = "fnlt",
    [10] = "fngt",
    [11] = "fnltn",
    [13] = "fngte",
    [14] = "fnlte",
    [15] = "fngtn",
};
UNUSED static const char *enum_mask[] = {
    [0] = "none",
    [1] = "x",
    [2] = "y",
    [3] = "xy",
    [4] = "z",
    [5] = "xz",
    [6] = "yz",
    [7] = "xyz",
    [8] = "w",
    [9] = "xw",
    [10] = "yw",
    [11] = "xyw",
    [12] = "zw",
    [13] = "xzw",
    [14] = "yzw",
    [15] = "xyzw",
};
UNUSED static const char *enum_format[] = {
    [0] = "i8",
    [1] = "i16",
    [2] = "i32",
    [3] = "f16",
    [4] = "u8norm",
    [5] = "s8norm",
    [6] = "u16norm",
    [7] = "s16norm",
    [8] = "rgb10a2",
    [10] = "srgba8",
    [12] = "rg11b10f",
    [13] = "rgb9e5",
    [14] = "rg11b10f_rtz",
    [15] = "rgb9e5_rtz",
};
UNUSED static const char *enum_dim[] = {
    [0] = "1d",
    [1] = "1d_array",
    [2] = "2d",
    [3] = "2d_array",
    [4] = "2d_ms",
    [5] = "3d",
    [6] = "cube",
    [7] = "cube_array",
    [8] = "2d_ms_array",
};
UNUSED static const char *enum_gather[] = {
    [0] = "",
    [1] = "gather_r",
    [3] = "gather_g",
    [5] = "gather_b",
    [7] = "gather_a",
};
UNUSED static const char *enum_lod_type[] = {
    [0] = "auto_lod",
    [1] = "auto_lod_bias",
    [2] = "lod_min",
    [4] = "lod_grad",
    [5] = "auto_lod_bias",
    [6] = "lod_min",
    [9] = "auto_lod_bias_min",
    [12] = "lod_grad_min",
    [13] = "auto_lod_bias_min",
};
UNUSED static const char *enum_quad[] = {
    [0] = "quad",
    [1] = "",
};
UNUSED static const char *enum_shuffle_op[] = {
    [0] = "",
    [1] = "xor",
    [2] = "up",
    [3] = "down",
};
UNUSED static const char *enum_subop[] = {
    [0] = "and",
    [1] = "fadd",
    [2] = "or",
    [3] = "fmul",
    [4] = "xor",
    [5] = "fmin",
    [7] = "fmax",
    [16] = "iadd",
    [20] = "smin",
    [22] = "smax",
    [28] = "umin",
    [30] = "umax",
};

static void
print_diter(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x0ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 1, 8, 0) << 0,
          .size32 = bits(r, 0, 1, 0),
          .count = (bits(r, 9, 2, 0)) ?: 4,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for diter", v);
       ctx->error = true;
   }
}

static void
print_dldcf(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x600ull) == 0x200ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 1, 8, 0) << 0,
          .size32 = bits(r, 0, 1, 0),
          .count = 3,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for dldcf", v);
       ctx->error = true;
   }
}

static void
print_dalu(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x0ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 2, 8, 0) << 0,
          .cache = bits(r, 0, 1, 0),
          .size32 = bits(r, 1, 1, 0),
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for dalu", v);
       ctx->error = true;
   }
}

static void
print_dhalf(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x2ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 2, 8, 0) << 0,
          .cache = bits(r, 0, 1, 0),
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for dhalf", v);
       ctx->error = true;
   }
}

static void
print_dalu64(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x6ull) == 0x6ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 3, 7, 0) << 1,
          .cache = bits(r, 0, 1, 0),
          .size64 = 1,
          .optional = source,
       });
   } else if ((v & 0x6ull) == 0x2ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 3, 7, 0) << 1,
          .cache = bits(r, 0, 1, 0),
          .size32 = 1,
          .optional = source,
       });
   } else if ((v & 0x2ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 2, 8, 0) << 0,
          .cache = bits(r, 0, 1, 0),
          .size16 = 1,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for dalu64", v);
       ctx->error = true;
   }
}

static void
print_ts(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x0ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_TS,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for ts", v);
       ctx->error = true;
   }
}

static void
print_ss(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x0ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_SS,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for ss", v);
       ctx->error = true;
   }
}

static void
print_uniform_dest(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0xf0001ull) == 0xf0000ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_UNIFORM,
          .value = bits(r, 0, 16, 0) << 0,
          .size64 = 1,
          .optional = source,
       });
   } else if ((v & 0xf0001ull) == 0x30000ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_UNIFORM,
          .value = bits(r, 0, 16, 0) << 0,
          .size32 = 1,
          .optional = source,
       });
   } else if ((v & 0xf0000ull) == 0xf0000ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_UNIFORM,
          .value = bits(r, 0, 16, 0) << 0,
          .count = 4,
          .optional = source,
       });
   } else if ((v & 0xf0000ull) == 0x70000ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_UNIFORM,
          .value = bits(r, 0, 16, 0) << 0,
          .count = 3,
          .optional = source,
       });
   } else if ((v & 0xf0000ull) == 0x30000ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_UNIFORM,
          .value = bits(r, 0, 16, 0) << 0,
          .count = 2,
          .optional = source,
       });
   } else if ((v & 0xf0000ull) == 0x10000ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_UNIFORM,
          .value = bits(r, 0, 16, 0) << 0,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for uniform_dest", v);
       ctx->error = true;
   }
}

static void
print_uniform_src(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0xf01ull) == 0xf00ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .size64 = 1,
          .optional = source,
       });
   } else if ((v & 0xf01ull) == 0x300ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .size32 = 1,
          .optional = source,
       });
   } else if ((v & 0xf00ull) == 0xf00ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .count = 4,
          .optional = source,
       });
   } else if ((v & 0xf00ull) == 0x700ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .count = 3,
          .optional = source,
       });
   } else if ((v & 0xf00ull) == 0x300ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .count = 2,
          .optional = source,
       });
   } else if ((v & 0xf00ull) == 0x100ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for uniform_src", v);
       ctx->error = true;
   }
}

static void
print_coord(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x200ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .lu = bits(r, 8, 1, 0),
          .size32 = 1,
          .optional = source,
       });
   } else if ((v & 0x200ull) == 0x200ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .lu = bits(r, 8, 1, 0),
          .size16 = 1,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for coord", v);
       ctx->error = true;
   }
}

static void
print_lod(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0xfffull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_IMM,
          .value = bits(r, 0, 1, 0) << 0,
          .optional = source,
       });
   } else if ((v & 0xf00ull) == 0x400ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .size32 = 1,
          .count = 2,
          .optional = source,
       });
   } else if ((v & 0xf00ull) == 0xc00ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .size16 = 1,
          .count = 5,
          .optional = source,
       });
   } else if ((v & 0xf00ull) == 0x200ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_UNIFORM,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else if ((v & 0xf00ull) == 0x100ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_UNIFORM,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else if ((v & 0xf00ull) == 0x900ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_UNIFORM,
          .value = bits(r, 0, 8, 0) << 0,
          .count = 2,
          .optional = source,
       });
   } else if ((v & 0xf00ull) == 0xd00ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .count = 2,
          .optional = source,
       });
   } else if ((v & 0xf00ull) == 0x600ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else if ((v & 0xf00ull) == 0x500ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for lod", v);
       ctx->error = true;
   }
}

static void
print_ureg64(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x0ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_UNIFORM,
          .value = bits(r, 0, 8, 0) << 1,
          .size64 = 1,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for ureg64", v);
       ctx->error = true;
   }
}

static void
print_ureg64_shift2(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x0ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_UNIFORM,
          .value = bits(r, 0, 7, 0) << 2,
          .size64 = 1,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for ureg64_shift2", v);
       ctx->error = true;
   }
}

static void
print_exreg16(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x0ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for exreg16", v);
       ctx->error = true;
   }
}

static void
print_exreg32(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x0ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 1,
          .size32 = 1,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for exreg32", v);
       ctx->error = true;
   }
}

static void
print_heap_offs(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x80000000ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 9, 0) << 0,
          .size32 = 1,
          .optional = source,
       });
   } else if ((v & 0x80000000ull) == 0x80000000ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_IMM,
          .value = bits(r, 0, 31, 0) << 0,
          .size32 = 1,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for heap_offs", v);
       ctx->error = true;
   }
}

static void
print_atomic_dest(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x100ull) == 0x100ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .size32 = 1,
          .optional = source,
       });
   } else if ((v & 0x1ffull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for atomic_dest", v);
       ctx->error = true;
   }
}

static void
print_local_atomic_dest(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x300ull) == 0x300ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .size32 = 1,
          .optional = source,
       });
   } else if ((v & 0x1ffull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for local_atomic_dest", v);
       ctx->error = true;
   }
}

static void
print_atomic_source(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0xf00ull) == 0x300ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .count = 2,
          .size32 = 1,
          .optional = source,
       });
   } else if ((v & 0x0ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .count = 1,
          .size32 = 1,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for atomic_source", v);
       ctx->error = true;
   }
}

static void
print_memory(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x0ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .size32 = bits(r, 8, 1, 0),
          .count = util_bitcount(bits(r, 9, 4, 0)),
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for memory", v);
       ctx->error = true;
   }
}

static void
print_uvs(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x100ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else if ((v & 0x100ull) == 0x100ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_IMM,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for uvs", v);
       ctx->error = true;
   }
}

static void
print_cf(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x100ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_CF,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else if ((v & 0x100ull) == 0x100ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for cf", v);
       ctx->error = true;
   }
}

static void
print_cfperspective(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x0ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_CF,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for cfperspective", v);
       ctx->error = true;
   }
}

static void
print_itersample(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x300ull) == 0x300ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else if ((v & 0x300ull) == 0x100ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_IMM,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else if ((v & 0x1ffull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for itersample", v);
       ctx->error = true;
   }
}

static void
print_pbesource(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x100ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .size16 = 1,
          .count = 4,
          .optional = source,
       });
   } else if ((v & 0x100ull) == 0x100ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .size32 = 1,
          .count = 4,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for pbesource", v);
       ctx->error = true;
   }
}

static void
print_membase(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x101ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 1, 7, 0) << 1,
          .size64 = 1,
          .optional = source,
       });
   } else if ((v & 0x101ull) == 0x100ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_UNIFORM,
          .value = bits(r, 1, 7, 0) << 1,
          .size64 = 1,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for membase", v);
       ctx->error = true;
   }
}

static void
print_localmembase(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x300ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else if ((v & 0x3ffull) == 0x200ull) {
       _print_operand(ctx, (struct operand_desc){
          .optional = source,
       });
   } else if ((v & 0x100ull) == 0x100ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_UNIFORM,
          .value = bits(r, 0, 8, 0) | bits(r, 9, 1, 8) << 0,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for localmembase", v);
       ctx->error = true;
   }
}

static void
print_memindex(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x1ff01ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 1, 7, 0) << 1,
          .sx = bits(r, 17, 1, 0) ^ 1,
          .size32 = 1,
          .optional = source,
       });
   } else if ((v & 0x30000ull) == 0x10000ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_IMM,
          .value = util_sign_extend(bits(r, 0, 16, 0) << 0, 16),
          .optional = source,
       });
   } else if ((v & 0x30000ull) == 0x30000ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_IMM,
          .value = bits(r, 0, 16, 0) << 0,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for memindex", v);
       ctx->error = true;
   }
}

static void
print_localmemindex(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x1ff00ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else if ((v & 0x10000ull) == 0x10000ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_IMM,
          .value = util_sign_extend(bits(r, 0, 16, 0) << 0, 16),
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for localmemindex", v);
       ctx->error = true;
   }
}

static void
print_cmpsel(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x1c0ull) == 0x100ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_IMM,
          .value = bits(r, 0, 6, 0) | bits(r, 9, 2, 6) << 0,
          .optional = source,
       });
   } else if ((v & 0x100ull) == 0x0ull) {
       if (bits(r, 6, 2, 0) == 0) {
          fprintf(ctx->fp, "# missing hint");
       }

       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 6, 0) | bits(r, 9, 2, 6) << 0,
          .hint = bits(r, 6, 2, 0),
          .size32 = bits(r, 11, 1, 0),
          .optional = source,
       });
   } else if ((v & 0x180ull) == 0x180ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_UNIFORM,
          .value = bits(r, 0, 6, 0) | bits(r, 9, 2, 6) | bits(r, 6, 1, 8) << 0,
          .size32 = bits(r, 11, 1, 0),
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for cmpsel", v);
       ctx->error = true;
   }
}

static void
print_alu(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x3c0ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_IMM,
          .value = bits(r, 0, 6, 0) | bits(r, 10, 2, 6) << 0,
          .optional = source,
       });
   } else if ((v & 0x300ull) == 0x100ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_UNIFORM,
          .value = bits(r, 0, 6, 0) | bits(r, 10, 2, 6) | bits(r, 6, 1, 8) << 0,
          .size32 = bits(r, 7, 1, 0),
          .optional = source,
       });
   } else if ((v & 0x100ull) == 0x0ull) {
       if (bits(r, 6, 2, 0) == 0) {
          fprintf(ctx->fp, "# missing hint");
       }

       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 6, 0) | bits(r, 10, 2, 6) << 0,
          .hint = bits(r, 6, 2, 0),
          .size32 = bits(r, 9, 1, 0),
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for alu", v);
       ctx->error = true;
   }
}

static void
print_mul(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x3c0ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_IMM,
          .value = bits(r, 0, 6, 0) | bits(r, 11, 2, 6) << 0,
          .sx = bits(r, 10, 1, 0),
          .optional = source,
       });
   } else if ((v & 0x300ull) == 0x100ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_UNIFORM,
          .value = bits(r, 0, 6, 0) | bits(r, 11, 2, 6) | bits(r, 6, 1, 8) << 0,
          .sx = bits(r, 10, 1, 0),
          .size32 = bits(r, 7, 1, 0),
          .optional = source,
       });
   } else if ((v & 0x100ull) == 0x0ull) {
       if (bits(r, 6, 2, 0) == 0) {
          fprintf(ctx->fp, "# missing hint");
       }

       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 6, 0) | bits(r, 11, 2, 6) << 0,
          .sx = bits(r, 10, 1, 0),
          .hint = bits(r, 6, 2, 0),
          .size32 = bits(r, 9, 1, 0),
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for mul", v);
       ctx->error = true;
   }
}

static void
print_add(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x3c0ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_IMM,
          .value = bits(r, 0, 6, 0) | bits(r, 11, 2, 6) << 0,
          .sx = bits(r, 10, 1, 0),
          .optional = source,
       });
   } else if ((v & 0x300ull) == 0x100ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_UNIFORM,
          .value = bits(r, 0, 6, 0) | bits(r, 11, 2, 6) | bits(r, 6, 1, 8) << 0,
          .sx = bits(r, 10, 1, 0),
          .size32 = bits(r, 7, 1, 0),
          .optional = source,
       });
   } else if ((v & 0x0ull) == 0x0ull) {
       if (bits(r, 6, 2, 0) == 0) {
          fprintf(ctx->fp, "# missing hint");
       }

       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 6, 0) | bits(r, 11, 2, 6) << 0,
          .sx = bits(r, 10, 1, 0),
          .hint = bits(r, 6, 2, 0),
          .size64 = bits(r, 8, 1, 0),
          .size32 = bits(r, 9, 1, 0),
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for add", v);
       ctx->error = true;
   }
}

static void
print_float(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x3c0ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_FIMM,
          .value = bits(r, 0, 6, 0) | bits(r, 12, 2, 6) << 0,
          .abs = bits(r, 10, 1, 0),
          .neg = bits(r, 11, 1, 0),
          .optional = source,
       });
   } else if ((v & 0x300ull) == 0x100ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_UNIFORM,
          .value = bits(r, 0, 6, 0) | bits(r, 12, 2, 6) | bits(r, 6, 1, 8) << 0,
          .abs = bits(r, 10, 1, 0),
          .neg = bits(r, 11, 1, 0),
          .size32 = bits(r, 7, 1, 0),
          .optional = source,
       });
   } else if ((v & 0x100ull) == 0x0ull) {
       if (bits(r, 6, 2, 0) == 0) {
          fprintf(ctx->fp, "# missing hint");
       }

       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 6, 0) | bits(r, 12, 2, 6) << 0,
          .abs = bits(r, 10, 1, 0),
          .neg = bits(r, 11, 1, 0),
          .hint = bits(r, 6, 2, 0),
          .size32 = bits(r, 9, 1, 0),
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for float", v);
       ctx->error = true;
   }
}

static void
print_half(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x7c0ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_FIMM,
          .value = bits(r, 0, 6, 0) | bits(r, 11, 2, 6) << 0,
          .abs = bits(r, 9, 1, 0),
          .neg = bits(r, 10, 1, 0),
          .optional = source,
       });
   } else if ((v & 0x180ull) == 0x100ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_UNIFORM,
          .value = bits(r, 0, 6, 0) | bits(r, 11, 2, 6) | bits(r, 6, 1, 8) << 0,
          .abs = bits(r, 9, 1, 0),
          .neg = bits(r, 10, 1, 0),
          .optional = source,
       });
   } else if ((v & 0x100ull) == 0x0ull) {
       if (bits(r, 6, 2, 0) == 0) {
          fprintf(ctx->fp, "# missing hint");
       }

       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 6, 0) | bits(r, 11, 2, 6) << 0,
          .abs = bits(r, 9, 1, 0),
          .neg = bits(r, 10, 1, 0),
          .hint = bits(r, 6, 2, 0),
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for half", v);
       ctx->error = true;
   }
}

static void
print_discard(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x100ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else if ((v & 0x100ull) == 0x100ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_IMM,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for discard", v);
       ctx->error = true;
   }
}

static void
print_samples(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x100ull) == 0x100ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else if ((v & 0x100ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_IMM,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for samples", v);
       ctx->error = true;
   }
}

static void
print_tilecoord(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x100ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_IMM,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else if ((v & 0x100ull) == 0x100ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .count = 2,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for tilecoord", v);
       ctx->error = true;
   }
}

static void
print_zs(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x3ffull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .optional = source,
       });
   } else if ((v & 0x300ull) == 0x100ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .size32 = 1,
          .optional = source,
       });
   } else if ((v & 0x300ull) == 0x200ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else if ((v & 0x300ull) == 0x300ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .count = 3,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for zs", v);
       ctx->error = true;
   }
}

static void
print_heap(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x3full) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .optional = source,
       });
   } else if ((v & 0x20ull) == 0x20ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_UNIFORM,
          .value = bits(r, 0, 5, 0) << 2,
          .size64 = 1,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for heap", v);
       ctx->error = true;
   }
}

static void
print_texture(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x300ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_TS,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else if ((v & 0x300ull) == 0x100ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else if ((v & 0x300ull) == 0x200ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_IMM,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else if ((v & 0x300ull) == 0x300ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .size32 = 1,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for texture", v);
       ctx->error = true;
   }
}

static void
print_sampler(struct disasm_ctx *ctx, BITSET_WORD *orig, uint64_t v, bool source)
{
   BITSET_WORD r[] = { v, v >> 32 };
   if ((v & 0x100ull) == 0x0ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_SS,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else if ((v & 0x100ull) == 0x100ull) {
       _print_operand(ctx, (struct operand_desc){
          .kind = KIND_REG,
          .value = bits(r, 0, 8, 0) << 0,
          .optional = source,
       });
   } else {
       fprintf(ctx->fp, "# XXX: Invalid value 0x%"PRIx64" for sampler", v);
       ctx->error = true;
   }
}


static void
print_ldimm16(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_immediate(ctx, false, bits(r, 16, 16, 0));
}

static void
print_ldimm32(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 60, 2, 8), false);
   print_immediate(ctx, false, bits(r, 16, 32, 0));
}

static void
print_mfsr(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 28, 2, 8), false);
   print_enum(ctx, enum_sr, bits(r, 16, 6, 0) | bits(r, 26, 2, 6));
}

static void
print_iadd(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu64(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_add(ctx, r, bits(r, 16, 11, 0) | bits(r, 42, 2, 11), true);
   print_add(ctx, r, bits(r, 28, 11, 0) | bits(r, 40, 2, 11), true);
   print_enum(ctx, enum_shift, bits(r, 39, 1, 0) | bits(r, 52, 2, 1));
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_isub(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu64(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_add(ctx, r, bits(r, 16, 11, 0) | bits(r, 42, 2, 11), true);
   print_add(ctx, r, bits(r, 28, 11, 0) | bits(r, 40, 2, 11), true);
   print_enum(ctx, enum_shift, bits(r, 39, 1, 0) | bits(r, 52, 2, 1));
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_imul(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu64(ctx, r, bits(r, 7, 8, 0) | bits(r, 60, 2, 8), false);
   print_mul(ctx, r, bits(r, 16, 11, 0) | bits(r, 58, 2, 11), true);
   print_mul(ctx, r, bits(r, 28, 11, 0) | bits(r, 56, 2, 11), true);
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_imadd(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu64(ctx, r, bits(r, 7, 8, 0) | bits(r, 60, 2, 8), false);
   print_mul(ctx, r, bits(r, 16, 11, 0) | bits(r, 58, 2, 11), true);
   print_mul(ctx, r, bits(r, 28, 11, 0) | bits(r, 56, 2, 11), true);
   print_add(ctx, r, bits(r, 40, 11, 0) | bits(r, 54, 2, 11), true);
   print_enum(ctx, enum_shift, bits(r, 39, 1, 0) | bits(r, 52, 2, 1));
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_imsub(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu64(ctx, r, bits(r, 7, 8, 0) | bits(r, 60, 2, 8), false);
   print_mul(ctx, r, bits(r, 16, 11, 0) | bits(r, 58, 2, 11), true);
   print_mul(ctx, r, bits(r, 28, 11, 0) | bits(r, 56, 2, 11), true);
   print_add(ctx, r, bits(r, 40, 11, 0) | bits(r, 54, 2, 11), true);
   print_enum(ctx, enum_shift, bits(r, 39, 1, 0) | bits(r, 52, 2, 1));
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_u8_to_f(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
   print_enum(ctx, enum_round, bits(r, 26, 2, 0));
}

static void
print_s8_to_f(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
   print_enum(ctx, enum_round, bits(r, 26, 2, 0));
}

static void
print_f_to_u16(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
   print_enum(ctx, enum_round, bits(r, 26, 2, 0));
}

static void
print_f_to_s16(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
   print_enum(ctx, enum_round, bits(r, 26, 2, 0));
}

static void
print_u16_to_f(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
   print_enum(ctx, enum_round, bits(r, 26, 2, 0));
}

static void
print_s16_to_f(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
   print_enum(ctx, enum_round, bits(r, 26, 2, 0));
}

static void
print_f_to_u32(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
   print_enum(ctx, enum_round, bits(r, 26, 2, 0));
}

static void
print_f_to_s32(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
   print_enum(ctx, enum_round, bits(r, 26, 2, 0));
}

static void
print_u32_to_f(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
   print_enum(ctx, enum_round, bits(r, 26, 2, 0));
}

static void
print_s32_to_f(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
   print_enum(ctx, enum_round, bits(r, 26, 2, 0));
}

static void
print_shl(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 60, 2, 8), false);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 56, 2, 10), true);
   print_alu(ctx, r, bits(r, 40, 10, 0) | bits(r, 54, 2, 10), true);
}

static void
print_shr(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 60, 2, 8), false);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 56, 2, 10), true);
   print_alu(ctx, r, bits(r, 40, 10, 0) | bits(r, 54, 2, 10), true);
}

static void
print_bfi(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 60, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 58, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 56, 2, 10), true);
   print_alu(ctx, r, bits(r, 40, 10, 0) | bits(r, 54, 2, 10), true);
   print_immediate(ctx, false, bits(r, 38, 2, 0) | bits(r, 50, 2, 2) | bits(r, 63, 1, 4));
}

static void
print_bfeil(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 60, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 58, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 56, 2, 10), true);
   print_alu(ctx, r, bits(r, 40, 10, 0) | bits(r, 54, 2, 10), true);
   print_immediate(ctx, false, bits(r, 38, 2, 0) | bits(r, 50, 2, 2) | bits(r, 63, 1, 4));
}

static void
print_extr(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 60, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 58, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 56, 2, 10), true);
   print_alu(ctx, r, bits(r, 40, 10, 0) | bits(r, 54, 2, 10), true);
   print_immediate(ctx, false, bits(r, 38, 2, 0) | bits(r, 50, 2, 2) | bits(r, 63, 1, 4));
}

static void
print_shlhi(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 60, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 58, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 56, 2, 10), true);
   print_alu(ctx, r, bits(r, 40, 10, 0) | bits(r, 54, 2, 10), true);
   print_immediate(ctx, false, bits(r, 38, 2, 0) | bits(r, 50, 2, 2) | bits(r, 63, 1, 4));
}

static void
print_shrhi(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 60, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 58, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 56, 2, 10), true);
   print_alu(ctx, r, bits(r, 40, 10, 0) | bits(r, 54, 2, 10), true);
   print_immediate(ctx, false, bits(r, 38, 2, 0) | bits(r, 50, 2, 2) | bits(r, 63, 1, 4));
}

static void
print_asr(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 60, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 58, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 56, 2, 10), true);
   print_alu(ctx, r, bits(r, 40, 10, 0) | bits(r, 54, 2, 10), true);
   print_immediate(ctx, false, bits(r, 38, 2, 0) | bits(r, 50, 2, 2) | bits(r, 63, 1, 4));
}

static void
print_asrh(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 60, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 58, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 56, 2, 10), true);
   print_alu(ctx, r, bits(r, 40, 10, 0) | bits(r, 54, 2, 10), true);
   print_immediate(ctx, false, bits(r, 38, 2, 0) | bits(r, 50, 2, 2) | bits(r, 63, 1, 4));
}

static void
print_ffma(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 60, 2, 8), false);
   print_float(ctx, r, bits(r, 16, 12, 0) | bits(r, 58, 2, 12), true);
   print_float(ctx, r, bits(r, 28, 12, 0) | bits(r, 56, 2, 12), true);
   print_float(ctx, r, bits(r, 40, 12, 0) | bits(r, 54, 2, 12), true);
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_hfma(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dhalf(ctx, r, bits(r, 7, 8, 0) | bits(r, 60, 2, 8), false);
   print_half(ctx, r, bits(r, 16, 11, 0) | bits(r, 58, 2, 11), true);
   print_half(ctx, r, bits(r, 28, 11, 0) | bits(r, 56, 2, 11), true);
   print_half(ctx, r, bits(r, 40, 11, 0) | bits(r, 54, 2, 11), true);
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_fadd(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_float(ctx, r, bits(r, 16, 12, 0) | bits(r, 42, 2, 12), true);
   print_float(ctx, r, bits(r, 28, 12, 0) | bits(r, 40, 2, 12), true);
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_fmul(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_float(ctx, r, bits(r, 16, 12, 0) | bits(r, 42, 2, 12), true);
   print_float(ctx, r, bits(r, 28, 12, 0) | bits(r, 40, 2, 12), true);
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_hadd(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dhalf(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_half(ctx, r, bits(r, 16, 11, 0) | bits(r, 42, 2, 11), true);
   print_half(ctx, r, bits(r, 28, 11, 0) | bits(r, 40, 2, 11), true);
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_hmul(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dhalf(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_half(ctx, r, bits(r, 16, 11, 0) | bits(r, 42, 2, 11), true);
   print_half(ctx, r, bits(r, 28, 11, 0) | bits(r, 40, 2, 11), true);
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_not_a(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
}

static void
print_mov(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
}

static void
print_not(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
}

static void
print_mov_a(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
}

static void
print_zero(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
}

static void
print_and(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
}

static void
print_andn1(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
}

static void
print_andn2(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
}

static void
print_xor(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
}

static void
print_or(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
}

static void
print_nor(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
}

static void
print_xnor(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
}

static void
print_orn1(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
}

static void
print_orn2(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
}

static void
print_nand(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
}

static void
print_one(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
}

static void
print_bitrev(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
}

static void
print_popcnt(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
}

static void
print_ffs(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
}

static void
print_intl(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
}

static void
print_floor(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_float(ctx, r, bits(r, 16, 12, 0) | bits(r, 42, 2, 12), true);
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_rsqrts(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_float(ctx, r, bits(r, 16, 12, 0) | bits(r, 42, 2, 12), true);
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_rcp(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_float(ctx, r, bits(r, 16, 12, 0) | bits(r, 42, 2, 12), true);
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_rsqrt(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_float(ctx, r, bits(r, 16, 12, 0) | bits(r, 42, 2, 12), true);
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_sinr(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_float(ctx, r, bits(r, 16, 12, 0) | bits(r, 42, 2, 12), true);
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_dfdx(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_float(ctx, r, bits(r, 16, 12, 0) | bits(r, 42, 2, 12), true);
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_dfdy(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_float(ctx, r, bits(r, 16, 12, 0) | bits(r, 42, 2, 12), true);
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_sinc(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_float(ctx, r, bits(r, 16, 12, 0) | bits(r, 42, 2, 12), true);
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_log2(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_float(ctx, r, bits(r, 16, 12, 0) | bits(r, 42, 2, 12), true);
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_exp2(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_float(ctx, r, bits(r, 16, 12, 0) | bits(r, 42, 2, 12), true);
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_ceil(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_float(ctx, r, bits(r, 16, 12, 0) | bits(r, 42, 2, 12), true);
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_trunc(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_float(ctx, r, bits(r, 16, 12, 0) | bits(r, 42, 2, 12), true);
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_rint(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_float(ctx, r, bits(r, 16, 12, 0) | bits(r, 42, 2, 12), true);
   print_modifier(ctx, "sat", bits(r, 6, 1, 0));
}

static void
print_jmp_incomplete(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_immediate(ctx, false, bits(r, 16, 8, 0));
}

static void
print_ret(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_exreg32(ctx, r, bits(r, 9, 7, 0), true);
}

static void
print_call_reg(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_exreg32(ctx, r, bits(r, 9, 7, 0), true);
}

static void
print_jmp_any(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_immediate(ctx, true, bits(r, 16, 32, 0));
}

static void
print_call(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_immediate(ctx, true, bits(r, 16, 32, 0));
}

static void
print_jmp_none(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_immediate(ctx, true, bits(r, 16, 32, 0));
}

static void
print_pop_exec(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_immediate(ctx, false, bits(r, 11, 2, 0));
   print_modifier(ctx, "cache", bits(r, 7, 1, 0));
}

static void
print_if_icmp(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
   print_immediate(ctx, false, bits(r, 11, 2, 0));
   print_modifier(ctx, "cache", bits(r, 7, 1, 0));
   print_enum(ctx, enum_icond, bits(r, 13, 3, 0) | bits(r, 8, 1, 3));
}

static void
print_else_icmp(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
   print_immediate(ctx, false, bits(r, 11, 2, 0));
   print_modifier(ctx, "cache", bits(r, 7, 1, 0));
   print_enum(ctx, enum_icond, bits(r, 13, 3, 0) | bits(r, 8, 1, 3));
}

static void
print_while_icmp(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
   print_immediate(ctx, false, bits(r, 11, 2, 0));
   print_modifier(ctx, "cache", bits(r, 7, 1, 0));
   print_enum(ctx, enum_icond, bits(r, 13, 3, 0) | bits(r, 8, 1, 3));
}

static void
print_update_exec(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_modifier(ctx, "cache", bits(r, 7, 1, 0));
}

static void
print_if_fcmp(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_float(ctx, r, bits(r, 16, 12, 0) | bits(r, 42, 2, 12), true);
   print_float(ctx, r, bits(r, 28, 12, 0) | bits(r, 40, 2, 12), true);
   print_immediate(ctx, false, bits(r, 11, 2, 0));
   print_modifier(ctx, "cache", bits(r, 7, 1, 0));
   print_enum(ctx, enum_fcond, bits(r, 13, 3, 0) | bits(r, 8, 1, 3));
}

static void
print_else_fcmp(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_float(ctx, r, bits(r, 16, 12, 0) | bits(r, 42, 2, 12), true);
   print_float(ctx, r, bits(r, 28, 12, 0) | bits(r, 40, 2, 12), true);
   print_immediate(ctx, false, bits(r, 11, 2, 0));
   print_modifier(ctx, "cache", bits(r, 7, 1, 0));
   print_enum(ctx, enum_fcond, bits(r, 13, 3, 0) | bits(r, 8, 1, 3));
}

static void
print_while_fcmp(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_float(ctx, r, bits(r, 16, 12, 0) | bits(r, 42, 2, 12), true);
   print_float(ctx, r, bits(r, 28, 12, 0) | bits(r, 40, 2, 12), true);
   print_immediate(ctx, false, bits(r, 11, 2, 0));
   print_modifier(ctx, "cache", bits(r, 7, 1, 0));
   print_enum(ctx, enum_fcond, bits(r, 13, 3, 0) | bits(r, 8, 1, 3));
}

static void
print_icsel(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 76, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 74, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 72, 2, 10), true);
   print_cmpsel(ctx, r, bits(r, 40, 9, 0) | bits(r, 70, 2, 9) | bits(r, 8, 1, 11), true);
   print_cmpsel(ctx, r, bits(r, 52, 9, 0) | bits(r, 68, 2, 9) | bits(r, 8, 1, 11), true);
   print_enum(ctx, enum_icond, bits(r, 61, 3, 0));
}

static void
print_fcsel(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 76, 2, 8), false);
   print_float(ctx, r, bits(r, 16, 12, 0) | bits(r, 74, 2, 12), true);
   print_float(ctx, r, bits(r, 28, 12, 0) | bits(r, 72, 2, 12), true);
   print_cmpsel(ctx, r, bits(r, 40, 9, 0) | bits(r, 70, 2, 9) | bits(r, 8, 1, 11), true);
   print_cmpsel(ctx, r, bits(r, 52, 9, 0) | bits(r, 68, 2, 9) | bits(r, 8, 1, 11), true);
   print_enum(ctx, enum_fcond, bits(r, 61, 3, 0));
}

static void
print_ballot(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
}

static void
print_icmp_ballot(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
   print_enum(ctx, enum_quad, bits(r, 48, 1, 0));
   print_enum(ctx, enum_icond, bits(r, 61, 3, 0) | bits(r, 47, 1, 3));
}

static void
print_fcmp_ballot(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_float(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
   print_float(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
   print_enum(ctx, enum_quad, bits(r, 48, 1, 0));
   print_enum(ctx, enum_icond, bits(r, 61, 3, 0) | bits(r, 47, 1, 3));
}

static void
print_shuffle(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
   print_alu(ctx, r, bits(r, 28, 10, 0) | bits(r, 40, 2, 10), true);
   print_enum(ctx, enum_quad, bits(r, 26, 1, 0));
   print_modifier(ctx, "rotate", bits(r, 47, 1, 0));
   print_enum(ctx, enum_shuffle_op, bits(r, 38, 2, 0));
}

static void
print_pixwait(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_immediate(ctx, false, bits(r, 8, 10, 0));
   print_immediate(ctx, false, bits(r, 22, 2, 0));
}

static void
print_pixrel(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_immediate(ctx, false, bits(r, 8, 10, 0));
   print_immediate(ctx, false, bits(r, 22, 2, 0));
}

static void
print_wait(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_enum(ctx, enum_group, bits(r, 8, 1, 0));
}

static void
print_st_var(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_exreg32(ctx, r, bits(r, 10, 5, 0) | bits(r, 24, 2, 5), true);
   print_uvs(ctx, r, bits(r, 16, 6, 0) | bits(r, 26, 2, 6) | bits(r, 23, 1, 8), true);
   print_modifier(ctx, "last", bits(r, 7, 1, 0));
}

static void
print_load(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_memory(ctx, r, bits(r, 10, 6, 0) | bits(r, 40, 2, 6) | bits(r, 49, 1, 8) | bits(r, 52, 4, 9), false);
   print_membase(ctx, r, bits(r, 16, 4, 0) | bits(r, 36, 4, 4) | bits(r, 27, 1, 8), true);
   print_memindex(ctx, r, bits(r, 20, 4, 0) | bits(r, 32, 4, 4) | bits(r, 56, 8, 8) | bits(r, 24, 1, 16) | bits(r, 25, 1, 17), true);
   print_enum(ctx, enum_shift, bits(r, 42, 2, 0));
   print_enum(ctx, enum_format, bits(r, 7, 3, 0) | bits(r, 48, 1, 3));
   print_enum(ctx, enum_mask, bits(r, 52, 4, 0));
   print_enum(ctx, enum_coherent, bits(r, 44, 2, 0));
   print_enum(ctx, enum_group, bits(r, 30, 1, 0));
}

static void
print_atomic(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_atomic_dest(ctx, r, bits(r, 10, 6, 0) | bits(r, 40, 2, 6) | bits(r, 47, 1, 8), false);
   print_atomic_source(ctx, r, bits(r, 48, 8, 0) | bits(r, 6, 4, 8), true);
   print_membase(ctx, r, bits(r, 16, 4, 0) | bits(r, 36, 4, 4) | bits(r, 27, 1, 8), true);
   print_memindex(ctx, r, bits(r, 20, 4, 0) | bits(r, 32, 4, 4) | bits(r, 56, 8, 8) | bits(r, 24, 1, 16) | bits(r, 25, 1, 17), true);
   print_enum(ctx, enum_atomic, bits(r, 6, 4, 0));
   print_enum(ctx, enum_coherent, bits(r, 44, 2, 0));
   print_enum(ctx, enum_group, bits(r, 30, 1, 0));
}

static void
print_latomic(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_local_atomic_dest(ctx, r, bits(r, 9, 6, 0) | bits(r, 60, 2, 6) | bits(r, 38, 1, 8) | bits(r, 8, 1, 9), false);
   print_atomic_source(ctx, r, bits(r, 64, 8, 0) | bits(r, 24, 4, 8), true);
   print_localmembase(ctx, r, bits(r, 16, 6, 0) | bits(r, 58, 2, 6) | bits(r, 22, 2, 8), true);
   print_localmemindex(ctx, r, bits(r, 28, 6, 0) | bits(r, 48, 10, 6) | bits(r, 34, 1, 16), true);
   print_enum(ctx, enum_atomic, bits(r, 24, 4, 0));
}

static void
print_stack_load(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_memory(ctx, r, bits(r, 10, 6, 0) | bits(r, 40, 2, 6) | bits(r, 49, 1, 8) | bits(r, 52, 4, 9), false);
   print_memindex(ctx, r, bits(r, 20, 4, 0) | bits(r, 32, 4, 4) | bits(r, 56, 8, 8) | bits(r, 24, 1, 16) | bits(r, 25, 1, 17), true);
   print_enum(ctx, enum_shift, bits(r, 42, 2, 0));
   print_enum(ctx, enum_format, bits(r, 8, 2, 0) | bits(r, 50, 2, 2));
   print_enum(ctx, enum_mask, bits(r, 52, 4, 0));
   print_enum(ctx, enum_group, bits(r, 30, 1, 0));
}

static void
print_stack_adjust(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_memindex(ctx, r, bits(r, 20, 4, 0) | bits(r, 32, 4, 4) | bits(r, 56, 8, 8) | bits(r, 24, 1, 16) | bits(r, 25, 1, 17), true);
}

static void
print_stack_store(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_memory(ctx, r, bits(r, 10, 6, 0) | bits(r, 40, 2, 6) | bits(r, 49, 1, 8) | bits(r, 52, 4, 9), true);
   print_memindex(ctx, r, bits(r, 20, 4, 0) | bits(r, 32, 4, 4) | bits(r, 56, 8, 8) | bits(r, 24, 1, 16) | bits(r, 25, 1, 17), true);
   print_enum(ctx, enum_shift, bits(r, 42, 2, 0));
   print_enum(ctx, enum_format, bits(r, 8, 2, 0) | bits(r, 50, 2, 2));
   print_enum(ctx, enum_mask, bits(r, 52, 4, 0));
   print_enum(ctx, enum_group, bits(r, 30, 1, 0));
}

static void
print_uniform_store(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_uniform_dest(ctx, r, bits(r, 20, 4, 0) | bits(r, 32, 4, 4) | bits(r, 56, 8, 8) | bits(r, 52, 4, 16), false);
   print_uniform_src(ctx, r, bits(r, 10, 6, 0) | bits(r, 40, 2, 6) | bits(r, 52, 4, 8), true);
}

static void
print_uniform_store_unk(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_memory(ctx, r, bits(r, 10, 6, 0) | bits(r, 40, 2, 6) | bits(r, 49, 1, 8) | bits(r, 52, 4, 9), true);
   print_memindex(ctx, r, bits(r, 20, 4, 0) | bits(r, 32, 4, 4) | bits(r, 56, 8, 8) | bits(r, 24, 1, 16) | bits(r, 25, 1, 17), true);
   print_enum(ctx, enum_shift, bits(r, 42, 2, 0));
   print_enum(ctx, enum_format, bits(r, 7, 3, 0) | bits(r, 48, 1, 3));
   print_enum(ctx, enum_mask, bits(r, 52, 4, 0));
   print_enum(ctx, enum_group, bits(r, 30, 1, 0));
}

static void
print_tex_state_store(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_ts(ctx, r, bits(r, 8, 7, 0), false);
   print_ureg64_shift2(ctx, r, bits(r, 59, 5, 0), true);
   print_heap_offs(ctx, r, bits(r, 26, 31, 0) | bits(r, 58, 1, 31), true);
   print_enum(ctx, enum_group, bits(r, 16, 1, 0));
}

static void
print_sampler_state_store(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_ss(ctx, r, bits(r, 8, 7, 0), false);
   print_ureg64_shift2(ctx, r, bits(r, 59, 5, 0), true);
   print_heap_offs(ctx, r, bits(r, 26, 31, 0) | bits(r, 58, 1, 31), true);
   print_enum(ctx, enum_group, bits(r, 16, 1, 0));
}

static void
print_store(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_memory(ctx, r, bits(r, 10, 6, 0) | bits(r, 40, 2, 6) | bits(r, 49, 1, 8) | bits(r, 52, 4, 9), true);
   print_membase(ctx, r, bits(r, 16, 4, 0) | bits(r, 36, 4, 4) | bits(r, 27, 1, 8), true);
   print_memindex(ctx, r, bits(r, 20, 4, 0) | bits(r, 32, 4, 4) | bits(r, 56, 8, 8) | bits(r, 24, 1, 16) | bits(r, 25, 1, 17), true);
   print_enum(ctx, enum_shift, bits(r, 42, 2, 0));
   print_enum(ctx, enum_format, bits(r, 7, 3, 0) | bits(r, 48, 1, 3));
   print_enum(ctx, enum_mask, bits(r, 52, 4, 0));
   print_enum(ctx, enum_coherent, bits(r, 44, 2, 0));
   print_enum(ctx, enum_group, bits(r, 30, 1, 0));
}

static void
print_lload(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_memory(ctx, r, bits(r, 9, 6, 0) | bits(r, 60, 2, 6) | bits(r, 8, 1, 8) | bits(r, 36, 4, 9), false);
   print_localmembase(ctx, r, bits(r, 16, 6, 0) | bits(r, 58, 2, 6) | bits(r, 22, 2, 8), true);
   print_localmemindex(ctx, r, bits(r, 28, 6, 0) | bits(r, 48, 10, 6) | bits(r, 34, 1, 16), true);
   print_enum(ctx, enum_format, bits(r, 24, 4, 0));
   print_enum(ctx, enum_mask, bits(r, 36, 4, 0));
}

static void
print_lstore(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_memory(ctx, r, bits(r, 9, 6, 0) | bits(r, 60, 2, 6) | bits(r, 8, 1, 8) | bits(r, 36, 4, 9), true);
   print_localmembase(ctx, r, bits(r, 16, 6, 0) | bits(r, 58, 2, 6) | bits(r, 22, 2, 8), true);
   print_localmemindex(ctx, r, bits(r, 28, 6, 0) | bits(r, 48, 10, 6) | bits(r, 34, 1, 16), true);
   print_enum(ctx, enum_format, bits(r, 24, 4, 0));
   print_enum(ctx, enum_mask, bits(r, 36, 4, 0));
}

static void
print_doorbell(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_immediate(ctx, false, bits(r, 8, 8, 0));
}

static void
print_jmp_if_skipping_doorbell(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_immediate(ctx, false, bits(r, 16, 8, 0));
}

static void
print_unmap(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_exreg32(ctx, r, bits(r, 11, 5, 0) | bits(r, 40, 2, 5), true);
   print_immediate(ctx, false, bits(r, 36, 1, 0));
   print_immediate(ctx, false, bits(r, 20, 4, 0) | bits(r, 32, 4, 4) | bits(r, 56, 8, 8));
}

static void
print_map(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_exreg32(ctx, r, bits(r, 11, 5, 0) | bits(r, 40, 2, 5), true);
   print_immediate(ctx, false, bits(r, 36, 1, 0));
   print_immediate(ctx, false, bits(r, 20, 4, 0) | bits(r, 32, 4, 4) | bits(r, 56, 8, 8));
}

static void
print_quad(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
   print_modifier(ctx, "prefix", bits(r, 30, 1, 0));
   print_enum(ctx, enum_subop, bits(r, 28, 1, 0) | bits(r, 38, 3, 1) | bits(r, 47, 1, 4));
}

static void
print_simd(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dalu(ctx, r, bits(r, 7, 8, 0) | bits(r, 44, 2, 8), false);
   print_alu(ctx, r, bits(r, 16, 10, 0) | bits(r, 42, 2, 10), true);
   print_modifier(ctx, "prefix", bits(r, 30, 1, 0));
   print_enum(ctx, enum_subop, bits(r, 28, 1, 0) | bits(r, 38, 3, 1) | bits(r, 47, 1, 4));
}

static void
print_ld_tile(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_memory(ctx, r, bits(r, 9, 6, 0) | bits(r, 60, 2, 6) | bits(r, 8, 1, 8) | bits(r, 36, 4, 9), false);
   print_tilecoord(ctx, r, bits(r, 16, 6, 0) | bits(r, 58, 2, 6) | bits(r, 55, 1, 8), true);
   print_samples(ctx, r, bits(r, 42, 6, 0) | bits(r, 56, 2, 6) | bits(r, 22, 1, 8), true);
   print_immediate(ctx, false, bits(r, 28, 7, 0) | bits(r, 40, 2, 7));
   print_enum(ctx, enum_format, bits(r, 24, 4, 0));
   print_enum(ctx, enum_mask, bits(r, 36, 4, 0));
}

static void
print_st_tile(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_memory(ctx, r, bits(r, 9, 6, 0) | bits(r, 60, 2, 6) | bits(r, 8, 1, 8) | bits(r, 36, 4, 9), true);
   print_tilecoord(ctx, r, bits(r, 16, 6, 0) | bits(r, 58, 2, 6) | bits(r, 55, 1, 8), true);
   print_samples(ctx, r, bits(r, 42, 6, 0) | bits(r, 56, 2, 6) | bits(r, 22, 1, 8), true);
   print_immediate(ctx, false, bits(r, 28, 7, 0) | bits(r, 40, 2, 7));
   print_modifier(ctx, "explicit_coords", bits(r, 35, 1, 0));
   print_enum(ctx, enum_format, bits(r, 24, 4, 0));
   print_enum(ctx, enum_mask, bits(r, 36, 4, 0));
}

static void
print_sample_mask(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_discard(ctx, r, bits(r, 9, 6, 0) | bits(r, 24, 2, 6) | bits(r, 8, 1, 8), true);
   print_discard(ctx, r, bits(r, 16, 6, 0) | bits(r, 26, 2, 6) | bits(r, 23, 1, 8), true);
}

static void
print_zs_emit(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_discard(ctx, r, bits(r, 9, 6, 0) | bits(r, 24, 2, 6) | bits(r, 8, 1, 8), true);
   print_zs(ctx, r, bits(r, 16, 6, 0) | bits(r, 26, 2, 6) | bits(r, 29, 1, 8) | bits(r, 30, 1, 9), true);
}

static void
print_iter(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_diter(ctx, r, bits(r, 8, 7, 0) | bits(r, 56, 2, 7) | bits(r, 30, 2, 9), false);
   print_cf(ctx, r, bits(r, 16, 6, 0) | bits(r, 58, 2, 6) | bits(r, 23, 1, 8), true);
   print_itersample(ctx, r, bits(r, 32, 8, 0) | bits(r, 48, 2, 8), true);
   print_modifier(ctx, "fwd", bits(r, 22, 1, 0));
   print_modifier(ctx, "elide", bits(r, 46, 1, 0));
   print_enum(ctx, enum_interpolation, bits(r, 48, 2, 0));
   print_modifier(ctx, "kill", bits(r, 52, 1, 0));
}

static void
print_iterproj(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_diter(ctx, r, bits(r, 8, 7, 0) | bits(r, 56, 2, 7) | bits(r, 30, 2, 9), false);
   print_cf(ctx, r, bits(r, 16, 6, 0) | bits(r, 58, 2, 6) | bits(r, 23, 1, 8), true);
   print_cfperspective(ctx, r, bits(r, 24, 6, 0) | bits(r, 60, 2, 6), true);
   print_itersample(ctx, r, bits(r, 32, 8, 0) | bits(r, 48, 2, 8), true);
   print_modifier(ctx, "fwd", bits(r, 22, 1, 0));
   print_modifier(ctx, "elide", bits(r, 46, 1, 0));
   print_enum(ctx, enum_interpolation, bits(r, 48, 2, 0));
   print_modifier(ctx, "kill", bits(r, 52, 1, 0));
}

static void
print_ldcf(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_dldcf(ctx, r, bits(r, 8, 7, 0) | bits(r, 56, 2, 7) | bits(r, 30, 2, 9), false);
   print_cf(ctx, r, bits(r, 16, 6, 0) | bits(r, 58, 2, 6) | bits(r, 23, 1, 8), true);
   print_itersample(ctx, r, bits(r, 32, 8, 0) | bits(r, 48, 2, 8), true);
}

static void
print_smpf(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_memory(ctx, r, bits(r, 9, 6, 0) | bits(r, 72, 2, 6) | bits(r, 8, 1, 8) | bits(r, 48, 4, 9), false);
   print_heap(ctx, r, bits(r, 64, 5, 0) | bits(r, 39, 1, 5), true);
   print_texture(ctx, r, bits(r, 32, 6, 0) | bits(r, 78, 2, 6) | bits(r, 38, 2, 8), true);
   print_sampler(ctx, r, bits(r, 56, 6, 0) | bits(r, 92, 2, 6) | bits(r, 62, 1, 8), true);
   print_coord(ctx, r, bits(r, 16, 6, 0) | bits(r, 74, 2, 6) | bits(r, 22, 1, 8) | bits(r, 47, 1, 9), true);
   print_lod(ctx, r, bits(r, 24, 6, 0) | bits(r, 76, 2, 6) | bits(r, 52, 4, 8), true);
   print_zs(ctx, r, bits(r, 80, 6, 0) | bits(r, 94, 2, 6) | bits(r, 23, 1, 8) | bits(r, 91, 1, 9), true);
   print_modifier(ctx, "shadow", bits(r, 23, 1, 0));
   print_modifier(ctx, "query_lod", bits(r, 31, 1, 0));
   print_modifier(ctx, "rw", bits(r, 43, 1, 0));
   print_modifier(ctx, "coherent", bits(r, 44, 1, 0));
   print_modifier(ctx, "sparse", bits(r, 70, 1, 0));
   print_modifier(ctx, "kill", bits(r, 69, 1, 0));
   print_enum(ctx, enum_dim, bits(r, 40, 3, 0) | bits(r, 71, 1, 3));
   print_enum(ctx, enum_mask, bits(r, 48, 4, 0));
   print_enum(ctx, enum_lod_type, bits(r, 52, 4, 0));
   print_enum(ctx, enum_gather, bits(r, 87, 4, 0));
   print_enum(ctx, enum_group, bits(r, 63, 1, 0));
}

static void
print_smpi(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_memory(ctx, r, bits(r, 9, 6, 0) | bits(r, 72, 2, 6) | bits(r, 8, 1, 8) | bits(r, 48, 4, 9), false);
   print_heap(ctx, r, bits(r, 64, 5, 0) | bits(r, 39, 1, 5), true);
   print_texture(ctx, r, bits(r, 32, 6, 0) | bits(r, 78, 2, 6) | bits(r, 38, 2, 8), true);
   print_sampler(ctx, r, bits(r, 56, 6, 0) | bits(r, 92, 2, 6) | bits(r, 62, 1, 8), true);
   print_coord(ctx, r, bits(r, 16, 6, 0) | bits(r, 74, 2, 6) | bits(r, 22, 1, 8) | bits(r, 47, 1, 9), true);
   print_lod(ctx, r, bits(r, 24, 6, 0) | bits(r, 76, 2, 6) | bits(r, 52, 4, 8), true);
   print_zs(ctx, r, bits(r, 80, 6, 0) | bits(r, 94, 2, 6) | bits(r, 23, 1, 8) | bits(r, 91, 1, 9), true);
   print_modifier(ctx, "shadow", bits(r, 23, 1, 0));
   print_modifier(ctx, "query_lod", bits(r, 31, 1, 0));
   print_modifier(ctx, "rw", bits(r, 43, 1, 0));
   print_modifier(ctx, "coherent", bits(r, 44, 1, 0));
   print_modifier(ctx, "sparse", bits(r, 70, 1, 0));
   print_modifier(ctx, "kill", bits(r, 69, 1, 0));
   print_enum(ctx, enum_dim, bits(r, 40, 3, 0) | bits(r, 71, 1, 3));
   print_enum(ctx, enum_mask, bits(r, 48, 4, 0));
   print_enum(ctx, enum_lod_type, bits(r, 52, 4, 0));
   print_enum(ctx, enum_gather, bits(r, 87, 4, 0));
   print_enum(ctx, enum_group, bits(r, 63, 1, 0));
}

static void
print_imgw(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_pbesource(ctx, r, bits(r, 9, 6, 0) | bits(r, 56, 2, 6) | bits(r, 8, 1, 8), true);
   print_heap(ctx, r, bits(r, 48, 5, 0) | bits(r, 39, 1, 5), true);
   print_texture(ctx, r, bits(r, 32, 6, 0) | bits(r, 62, 2, 6) | bits(r, 38, 2, 8), true);
   print_coord(ctx, r, bits(r, 16, 6, 0) | bits(r, 58, 2, 6) | bits(r, 22, 1, 8) | bits(r, 47, 1, 9), true);
   print_uvs(ctx, r, bits(r, 24, 6, 0) | bits(r, 60, 2, 6) | bits(r, 31, 1, 8), true);
   print_enum(ctx, enum_dim, bits(r, 40, 3, 0) | bits(r, 55, 1, 3));
   print_modifier(ctx, "rtz", bits(r, 53, 1, 0));
   print_enum(ctx, enum_coherent, bits(r, 44, 2, 0));
}

static void
print_imgwblk(struct disasm_ctx *ctx, BITSET_WORD *r)
{
   print_exreg16(ctx, r, bits(r, 9, 6, 0) | bits(r, 56, 2, 6), true);
   print_heap(ctx, r, bits(r, 48, 5, 0) | bits(r, 39, 1, 5), true);
   print_texture(ctx, r, bits(r, 32, 6, 0) | bits(r, 62, 2, 6) | bits(r, 38, 2, 8), true);
   print_coord(ctx, r, bits(r, 16, 6, 0) | bits(r, 58, 2, 6) | bits(r, 22, 1, 8) | bits(r, 47, 1, 9), true);
   print_uvs(ctx, r, bits(r, 24, 6, 0) | bits(r, 60, 2, 6) | bits(r, 31, 1, 8), true);
   print_modifier(ctx, "explicit_coords", bits(r, 23, 1, 0));
   print_enum(ctx, enum_dim, bits(r, 40, 3, 0) | bits(r, 55, 1, 3));
   print_enum(ctx, enum_format, bits(r, 8, 1, 0) | bits(r, 64, 3, 1));
   print_modifier(ctx, "rtz", bits(r, 53, 1, 0));
}

struct disasm_spec decodings[] = {
    { "ldimm   ", print_ldimm16, 15, 4, 6, {0x17f}, {0x62}, {0xffffffff, 0x3000} },
    { "ldimm   ", print_ldimm32, 15, 6, 8, {0x17f}, {0x162}, {0xffffffff, 0x3000ffff} },
    { "mov     ", print_mfsr, 0, 4, 4, {0x807f}, {0x72}, {0x3c3fffff} },
    { "iadd    ", print_iadd, 0, 8, 8, {0x800803f}, {0xe}, {0xffffffff, 0x303fff} },
    { "isub    ", print_isub, 0, 8, 8, {0x800803f}, {0x800000e}, {0xffffffff, 0x303fff} },
    { "imul    ", print_imul, 0, 8, 8, {0x800803f, 0xf7ff80}, {0x1e}, {0xffffffff, 0x3ff7ffff} },
    { "imadd   ", print_imadd, 0, 8, 8, {0x800803f}, {0x1e}, {0xffffffff, 0x3ff7ffff} },
    { "imsub   ", print_imsub, 0, 8, 8, {0x800803f}, {0x800001e}, {0xffffffff, 0x3ff7ffff} },
    { "u8_to_f ", print_u8_to_f, 0, 6, 6, {0x3ff807f, 0xcc0}, {0x803e}, {0xffffffff, 0x3fff} },
    { "s8_to_f ", print_s8_to_f, 0, 6, 6, {0x3ff807f, 0xcc0}, {0x1803e}, {0xffffffff, 0x3fff} },
    { "f_to_u16", print_f_to_u16, 0, 6, 6, {0x3ff807f, 0xcc0}, {0x4803e}, {0xffffffff, 0x3fff} },
    { "f_to_s16", print_f_to_s16, 0, 6, 6, {0x3ff807f, 0xcc0}, {0x5803e}, {0xffffffff, 0x3fff} },
    { "u16_to_f", print_u16_to_f, 0, 6, 6, {0x3ff807f, 0xcc0}, {0x6803e}, {0xffffffff, 0x3fff} },
    { "s16_to_f", print_s16_to_f, 0, 6, 6, {0x3ff807f, 0xcc0}, {0x7803e}, {0xffffffff, 0x3fff} },
    { "f_to_u32", print_f_to_u32, 0, 6, 6, {0x3ff807f, 0xcc0}, {0x8803e}, {0xffffffff, 0x3fff} },
    { "f_to_s32", print_f_to_s32, 0, 6, 6, {0x3ff807f, 0xcc0}, {0x9803e}, {0xffffffff, 0x3fff} },
    { "u32_to_f", print_u32_to_f, 0, 6, 6, {0x3ff807f, 0xcc0}, {0xa803e}, {0xffffffff, 0x3fff} },
    { "s32_to_f", print_s32_to_f, 0, 6, 6, {0x3ff807f, 0xcc0}, {0xb803e}, {0xffffffff, 0x3fff} },
    { "shl     ", print_shl, 0, 8, 8, {0xfff807f, 0x8c0c00c0}, {0x2e}, {0xffffffff, 0xbfcfffff} },
    { "shr     ", print_shr, 0, 8, 8, {0xfff807f, 0x8c0c00c0}, {0x802e}, {0xffffffff, 0xbfcfffff} },
    { "bfi     ", print_bfi, 0, 8, 8, {0xc00807f}, {0x2e}, {0xffffffff, 0xbfcfffff} },
    { "bfeil   ", print_bfeil, 0, 8, 8, {0xc00807f}, {0x802e}, {0xffffffff, 0xbfcfffff} },
    { "extr    ", print_extr, 0, 8, 8, {0xc00807f}, {0x400002e}, {0xffffffff, 0xbfcfffff} },
    { "shlhi   ", print_shlhi, 0, 8, 8, {0xc00807f}, {0x800002e}, {0xffffffff, 0xbfcfffff} },
    { "shrhi   ", print_shrhi, 0, 8, 8, {0xc00807f}, {0x800802e}, {0xffffffff, 0xbfcfffff} },
    { "asr     ", print_asr, 0, 8, 8, {0xc00807f}, {0x400802e}, {0xffffffff, 0xbfcfffff} },
    { "asrh    ", print_asrh, 0, 8, 8, {0xc00807f}, {0xc00802e}, {0xffffffff, 0xbfcfffff} },
    { "ffma    ", print_ffma, 15, 6, 8, {0x3f}, {0x3a}, {0xffffffff, 0x3fcfffff} },
    { "hfma    ", print_hfma, 15, 6, 8, {0x3f}, {0x36}, {0xf7ffffff, 0x3fc7ff7f} },
    { "fadd    ", print_fadd, 15, 4, 6, {0x3f}, {0x2a}, {0xffffffff, 0x3fff} },
    { "fmul    ", print_fmul, 15, 4, 6, {0x3f}, {0x1a}, {0xffffffff, 0x3fff} },
    { "hadd    ", print_hadd, 15, 4, 6, {0x3f}, {0x26}, {0xf7ffffff, 0x3f7f} },
    { "hmul    ", print_hmul, 15, 4, 6, {0x3f}, {0x16}, {0xf7ffffff, 0x3f7f} },
    { "not_a   ", print_not_a, 0, 6, 6, {0xfc00807f, 0x3ff}, {0x7e, 0xc0}, {0xffffffff, 0x3fff} },
    { "mov     ", print_mov, 0, 6, 6, {0xfc00807f, 0x3ff}, {0x800007e, 0x80}, {0xffffffff, 0x3fff} },
    { "not     ", print_not, 0, 6, 6, {0xfc00807f, 0x3ff}, {0x400007e, 0x40}, {0xffffffff, 0x3fff} },
    { "mov_a   ", print_mov_a, 0, 6, 6, {0xfc00807f, 0x3ff}, {0xc00007e}, {0xffffffff, 0x3fff} },
    { "zero    ", print_zero, 0, 6, 6, {0xc00807f, 0xc0}, {0x7e}, {0xffffffff, 0x3fff} },
    { "and     ", print_and, 0, 6, 6, {0xc00807f, 0xc0}, {0x7e, 0x80}, {0xffffffff, 0x3fff} },
    { "andn1   ", print_andn1, 0, 6, 6, {0xc00807f, 0xc0}, {0x7e, 0x40}, {0xffffffff, 0x3fff} },
    { "andn2   ", print_andn2, 0, 6, 6, {0xc00807f, 0xc0}, {0x800007e}, {0xffffffff, 0x3fff} },
    { "xor     ", print_xor, 0, 6, 6, {0xc00807f, 0xc0}, {0x800007e, 0x40}, {0xffffffff, 0x3fff} },
    { "or      ", print_or, 0, 6, 6, {0xc00807f, 0xc0}, {0x800007e, 0xc0}, {0xffffffff, 0x3fff} },
    { "nor     ", print_nor, 0, 6, 6, {0xc00807f, 0xc0}, {0x400007e}, {0xffffffff, 0x3fff} },
    { "xnor    ", print_xnor, 0, 6, 6, {0xc00807f, 0xc0}, {0x400007e, 0x80}, {0xffffffff, 0x3fff} },
    { "orn1    ", print_orn1, 0, 6, 6, {0xc00807f, 0xc0}, {0x400007e, 0xc0}, {0xffffffff, 0x3fff} },
    { "orn2    ", print_orn2, 0, 6, 6, {0xc00807f, 0xc0}, {0xc00007e, 0x80}, {0xffffffff, 0x3fff} },
    { "nand    ", print_nand, 0, 6, 6, {0xc00807f, 0xc0}, {0xc00007e, 0x40}, {0xffffffff, 0x3fff} },
    { "one     ", print_one, 0, 6, 6, {0xc00807f, 0xc0}, {0xc00007e, 0xc0}, {0xffffffff, 0x3fff} },
    { "bitrev  ", print_bitrev, 0, 6, 6, {0xfc00807f, 0xff}, {0x400003e}, {0xffffffff, 0x3cff} },
    { "popcnt  ", print_popcnt, 0, 6, 6, {0xfc00807f, 0xff}, {0x800003e}, {0xffffffff, 0x3cff} },
    { "ffs     ", print_ffs, 0, 6, 6, {0xfc00807f, 0xff}, {0xc00003e}, {0xffffffff, 0x3cff} },
    { "intl    ", print_intl, 0, 6, 6, {0xc00807f, 0xc0}, {0x3e}, {0xffffffff, 0x3fff} },
    { "floor   ", print_floor, 15, 4, 6, {0xf000003f, 0x3ff}, {0xa}, {0xffffffff, 0x3fff} },
    { "rsqrts  ", print_rsqrts, 15, 4, 6, {0xf000003f, 0x3ff}, {0x1000000a}, {0xffffffff, 0x3fff} },
    { "rcp     ", print_rcp, 15, 4, 6, {0xf000003f, 0x3ff}, {0x8000000a}, {0xffffffff, 0x3fff} },
    { "rsqrt   ", print_rsqrt, 15, 4, 6, {0xf000003f, 0x3ff}, {0x9000000a}, {0xffffffff, 0x3fff} },
    { "sinr    ", print_sinr, 15, 4, 6, {0xf000003f, 0x3ff}, {0xa000000a}, {0xffffffff, 0x3fff} },
    { "dfdx    ", print_dfdx, 15, 4, 6, {0xf000003f, 0x3ff}, {0x4000000a}, {0xffffffff, 0x3fff} },
    { "dfdy    ", print_dfdy, 15, 4, 6, {0xf000003f, 0x3ff}, {0x6000000a}, {0xffffffff, 0x3fff} },
    { "sinc    ", print_sinc, 15, 4, 6, {0xf000003f, 0x3ff}, {0xe000000a}, {0xffffffff, 0x3fff} },
    { "log2    ", print_log2, 15, 4, 6, {0xf000003f, 0x3ff}, {0xc000000a}, {0xffffffff, 0x3fff} },
    { "exp2    ", print_exp2, 15, 4, 6, {0xf000003f, 0x3ff}, {0xd000000a}, {0xffffffff, 0x3fff} },
    { "ceil    ", print_ceil, 15, 4, 6, {0xf000003f, 0x3ff}, {0xa, 0x1}, {0xffffffff, 0x3fff} },
    { "trunc   ", print_trunc, 15, 4, 6, {0xf000003f, 0x3ff}, {0xa, 0x2}, {0xffffffff, 0x3fff} },
    { "rint    ", print_rint, 15, 4, 6, {0xf000003f, 0x3ff}, {0xa, 0x3}, {0xffffffff, 0x3fff} },
    { "stop", NULL, 0, 2, 2, {0xffff}, {0x88}, {0xffff} },
    { "trap", NULL, 0, 2, 2, {0xffff}, {0x8}, {0xffff} },
    { "jmp_incomplete", print_jmp_incomplete, 0, 4, 4, {0xff00ffff}, {0x0}, {0xffffffff} },
    { "ret     ", print_ret, 0, 2, 2, {0x7f}, {0x14}, {0xfe7f} },
    { "call    ", print_call_reg, 0, 2, 2, {0x7f}, {0x4}, {0xfe7f} },
    { "jmp_any ", print_jmp_any, 0, 6, 6, {0xffff}, {0xc000}, {0xffffffff, 0xffff} },
    { "call    ", print_call, 0, 6, 6, {0xffff}, {0xc010}, {0xffffffff, 0xffff} },
    { "jmp_none", print_jmp_none, 0, 6, 6, {0xffff}, {0xc020}, {0xffffffff, 0xffff} },
    { "pop_exec", print_pop_exec, 0, 6, 6, {0xffffe67f, 0xffff}, {0x652}, {0xfffffeff, 0xffff} },
    { "if      ", print_if_icmp, 0, 6, 6, {0xc00067f, 0x30c0}, {0x52}, {0xffffffff, 0x3fff} },
    { "else    ", print_else_icmp, 0, 6, 6, {0xc00067f, 0x30c0}, {0x252}, {0xffffffff, 0x3fff} },
    { "while   ", print_while_icmp, 0, 6, 6, {0xc00067f, 0x30c0}, {0x452}, {0xffffffff, 0x3fff} },
    { "update_exec", print_update_exec, 0, 6, 6, {0xffffff7f, 0x3fff}, {0x42}, {0xffffffff, 0x3fff} },
    { "if      ", print_if_fcmp, 0, 6, 6, {0x67f, 0x3000}, {0x42}, {0xffffffff, 0x3fff} },
    { "else    ", print_else_fcmp, 0, 6, 6, {0x67f, 0x3000}, {0x242}, {0xffffffff, 0x3fff} },
    { "while   ", print_while_fcmp, 0, 6, 6, {0x67f, 0x3000}, {0x442}, {0xffffffff, 0x3fff} },
    { "csel    ", print_icsel, 15, 8, 10, {0x7f}, {0x12}, {0xf3ffffff, 0xfff1ff3f, 0x3ff0} },
    { "csel    ", print_fcsel, 15, 8, 10, {0x7f}, {0x2}, {0xffffffff, 0xfff1ffff, 0x3ff0} },
    { "ballot  ", print_ballot, 0, 8, 8, {0xf3ff007f, 0xffff803f}, {0x10032, 0x18000}, {0xf3ff7fff, 0xffffb03f} },
    { "ballot  ", print_icmp_ballot, 0, 8, 8, {0x7f, 0x1ffe0000}, {0x32}, {0xf3ff7fff, 0xffffbf3f} },
    { "ballot  ", print_fcmp_ballot, 0, 8, 8, {0x7f, 0x1ffe0000}, {0x22}, {0xf3ff7fff, 0xffffbf3f} },
    { "shuffle ", print_shuffle, 0, 6, 6, {0x800807f}, {0x6f}, {0xffffffff, 0xbfff} },
    { "pixwait ", print_pixwait, 0, 4, 4, {0xff}, {0x48}, {0xc3ffff} },
    { "pixrel  ", print_pixrel, 0, 4, 4, {0xff}, {0x58}, {0xc3ffff} },
    { "wait    ", print_wait, 0, 2, 2, {0xff}, {0x38}, {0x1ff} },
    { "no_var", NULL, 0, 4, 4, {0x804003ff}, {0x80000051}, {0x804003ff} },
    { "st_var  ", print_st_var, 0, 4, 4, {0x8040037f}, {0x80000011}, {0x8fff7fff} },
    { "load    ", print_load, 47, 6, 8, {0x400007f, 0x4000}, {0x4000005, 0x4000}, {0x4fffffff, 0xfff3ffff} },
    { "atomic  ", print_atomic, 0, 8, 8, {0x8400003f, 0x4000}, {0x84000015, 0x4000}, {0xcfffffff, 0xfffff3ff} },
    { "latomic ", print_latomic, 15, 6, 10, {0x3f, 0x8010}, {0x19, 0x8010}, {0xffffff3f, 0x3fff8057, 0xff} },
    { "stack_load", print_stack_load, 47, 6, 8, {0x40000ff, 0x7070}, {0x4000035, 0x4000}, {0x47f0ffff, 0xfffeff7f} },
    { "stack_adjust", print_stack_adjust, 47, 6, 8, {0x40100ff, 0x7070}, {0x40100b5, 0x20}, {0x7f100ff, 0xff00f07f} },
    { "stack_store", print_stack_store, 47, 6, 8, {0x40000ff, 0x7070}, {0x40000b5, 0x4000}, {0x47f0ffff, 0xfffeff7f} },
    { "mov     ", print_uniform_store, 47, 6, 8, {0x7f0f03ff, 0xd0cf0}, {0x3d0000c5}, {0x7fffffff, 0xfffd8fff} },
    { "uniform_store_unk", print_uniform_store_unk, 47, 6, 8, {0x3c0f007f, 0xc00f0}, {0x3c000045}, {0x7fffffff, 0xffff8fff} },
    { "load    ", print_tex_state_store, 0, 8, 8, {0x1000ff}, {0x1000ed}, {0xfc117fff, 0xfdffffff} },
    { "load    ", print_sampler_state_store, 0, 8, 8, {0x1000ff}, {0x1000ad}, {0xfc117fff, 0xfdffffff} },
    { "store   ", print_store, 47, 6, 8, {0x400007f, 0x4000}, {0x4000045, 0x4000}, {0x4fffffff, 0xfff3ffff} },
    { "lload   ", print_lload, 15, 6, 8, {0x7f}, {0x69}, {0xffffff7f, 0x3fff00f7} },
    { "lstore  ", print_lstore, 15, 6, 8, {0x7f}, {0x29}, {0xffffff7f, 0x3fff00f7} },
    { "barrier", NULL, 0, 2, 2, {0xff}, {0x68}, {0xff} },
    { "doorbell", print_doorbell, 0, 2, 2, {0xff}, {0x28}, {0xffff} },
    { "jmp_if_skipping_doorbell", print_jmp_if_skipping_doorbell, 0, 4, 4, {0xff00ffff}, {0x20}, {0xffffffff} },
    { "unmap   ", print_unmap, 0, 8, 8, {0xff0f07ff, 0xfffce0}, {0x5000075, 0x10c000}, {0xffffffff, 0xffffffff} },
    { "map     ", print_map, 0, 8, 8, {0xff0f07ff, 0xfffce0}, {0x5010075, 0x10c000}, {0xffffffff, 0xffffffff} },
    { "memory_barrier", NULL, 0, 2, 2, {0xffff}, {0x96f5}, {0xffff} },
    { "image_barrier_1", NULL, 0, 2, 2, {0xffff}, {0xaaf5}, {0xffff} },
    { "image_barrier_2", NULL, 0, 2, 2, {0xffff}, {0xaef5}, {0xffff} },
    { "image_barrier_3", NULL, 0, 2, 2, {0xffff}, {0xa9f5}, {0xffff} },
    { "image_barrier_4", NULL, 0, 2, 2, {0xffff}, {0xadf5}, {0xffff} },
    { "flush_memory_to_texture", NULL, 0, 2, 2, {0xffff}, {0x40f5}, {0xffff} },
    { "memory_barrier_2", NULL, 0, 2, 2, {0xffff}, {0x9af5}, {0xffff} },
    { "memory_barrier_3", NULL, 0, 2, 2, {0xffff}, {0x99f5}, {0xffff} },
    { "unknown_barrier_1", NULL, 0, 2, 2, {0xffff}, {0x33f5}, {0xffff} },
    { "unknown_barrier_2", NULL, 0, 2, 2, {0xffff}, {0x3f5}, {0xffff} },
    { "device_barrier_1", NULL, 0, 2, 2, {0xffff}, {0x9df5}, {0xffff} },
    { "device_barrier_2", NULL, 0, 2, 2, {0xffff}, {0x9ef5}, {0xffff} },
    { "quad    ", print_quad, 0, 6, 6, {0xac00807f, 0x23f}, {0x806f}, {0xffffffff, 0xbfff} },
    { "simd    ", print_simd, 0, 6, 6, {0xac00807f, 0x23f}, {0x2000806f}, {0xffffffff, 0xbfff} },
    { "ld_tile ", print_ld_tile, 15, 8, 10, {0x7f, 0x8}, {0x49, 0x8}, {0xff7fff7f, 0x3f80ffff} },
    { "st_tile ", print_st_tile, 15, 8, 10, {0x7f}, {0x9}, {0xff7fff7f, 0x3f80ffff} },
    { "sample_mask", print_sample_mask, 0, 4, 4, {0x80ff}, {0xc1}, {0xfbfffff} },
    { "zs_emit ", print_zs_emit, 0, 4, 4, {0xc080ff}, {0x41}, {0x6fffffff} },
    { "iter    ", print_iter, 15, 4, 8, {0xff}, {0x21}, {0xc0ffffff, 0xf1340ff} },
    { "iter    ", print_iterproj, 15, 4, 8, {0xff}, {0x61}, {0xffffffff, 0x3f1340ff} },
    { "ldcf    ", print_ldcf, 15, 4, 8, {0xff}, {0xa1}, {0xc0bfffff, 0xf0300ff} },
    { "smpf    ", print_smpf, 15, 8, 12, {0xff, 0x6000}, {0x31, 0x6000}, {0xbfffffff, 0xffffffff, 0xffbfffff} },
    { "smpi    ", print_smpi, 15, 8, 12, {0xff, 0x6000}, {0x71, 0x6000}, {0xbfffffff, 0xffffffff, 0xffbfffff} },
    { "imgw    ", print_imgw, 15, 6, 8, {0x8000ff, 0x4800}, {0x8000f1, 0x4800}, {0xbfffffff, 0xffbfffff} },
    { "imgwblk ", print_imgwblk, 15, 6, 10, {0xff, 0x4800, 0x3ff8}, {0xb1, 0x4800, 0x8}, {0xbfffffff, 0xffbfcfff, 0x3fff} },
};

signed
agx2_disassemble_instr(BITSET_WORD *code, FILE *fp, unsigned offset, bool verbose)
{
  return _disassemble_instr(code, fp, decodings, ARRAY_SIZE(decodings), offset, verbose);
}
