struct disasm_operand {
unsigned file:2;
- unsigned type:3;
+ unsigned type:4;
unsigned addr_mode:1;
unsigned reg:8;
};
struct disasm_inst {
- const struct ilo_dev_info *dev;
+ const struct ilo_dev *dev;
unsigned has_jip:1;
unsigned has_uip:1;
unsigned fc:4;
unsigned acc_wr_ctrl:1;
+ unsigned branch_ctrl:1;
+
unsigned cmpt_ctrl:1;
unsigned debug_ctrl:1;
unsigned saturate:1;
struct disasm_src_operand src1;
union {
struct disasm_src_operand src2;
- uint32_t imm32;
+ uint64_t imm64;
+
+ uint32_t ud;
+ int32_t d;
+ uint16_t uw;
+ int16_t w;
+ float f;
+
+ struct {
+ int16_t jip;
+ int16_t uip;
+ } ip16;
+
+ struct {
+ int32_t jip;
+ int32_t uip;
+ } ip32;
} u;
};
[GEN75_OPCODE_CALLA] = { "calla", 1 },
[GEN6_OPCODE_CALL] = { "call", 1 },
[GEN6_OPCODE_RETURN] = { "return", 1 },
+ [GEN8_OPCODE_GOTO] = { "goto", 1 },
[GEN6_OPCODE_WAIT] = { "wait", 1 },
[GEN6_OPCODE_SEND] = { "send", 1 },
[GEN6_OPCODE_SENDC] = { "sendc", 1 },
};
static void
-disasm_inst_decode_dw0_gen6(struct disasm_inst *inst, uint32_t dw0)
+disasm_inst_decode_dw0_opcode_gen6(struct disasm_inst *inst, uint32_t dw0)
{
+ ILO_DEV_ASSERT(inst->dev, 6, 8);
+
inst->opcode = GEN_EXTRACT(dw0, GEN6_INST_OPCODE);
switch (inst->opcode) {
case GEN6_OPCODE_IF:
inst->has_jip = true;
- inst->has_uip = (inst->dev->gen >= ILO_GEN(7));
+ inst->has_uip = (ilo_dev_gen(inst->dev) >= ILO_GEN(7));
+ break;
+ case GEN6_OPCODE_ELSE:
+ inst->has_jip = true;
+ inst->has_uip = (ilo_dev_gen(inst->dev) >= ILO_GEN(8));
break;
case GEN6_OPCODE_BREAK:
case GEN6_OPCODE_CONT:
case GEN6_OPCODE_JMPI:
case GEN7_OPCODE_BRD:
case GEN7_OPCODE_BRC:
- case GEN6_OPCODE_ELSE:
case GEN6_OPCODE_ENDIF:
case GEN6_OPCODE_CASE:
case GEN6_OPCODE_WHILE:
default:
break;
}
+}
+
+static void
+disasm_inst_decode_dw0_gen6(struct disasm_inst *inst, uint32_t dw0)
+{
+ ILO_DEV_ASSERT(inst->dev, 6, 8);
+
+ disasm_inst_decode_dw0_opcode_gen6(inst, dw0);
inst->access_mode = GEN_EXTRACT(dw0, GEN6_INST_ACCESSMODE);
- inst->mask_ctrl = GEN_EXTRACT(dw0, GEN6_INST_MASKCTRL);
- inst->dep_ctrl = GEN_EXTRACT(dw0, GEN6_INST_DEPCTRL);
+
+ if (ilo_dev_gen(inst->dev) >= ILO_GEN(8)) {
+ inst->dep_ctrl = GEN_EXTRACT(dw0, GEN8_INST_DEPCTRL);
+ inst->nib_ctrl = (bool) (dw0 & GEN8_INST_NIBCTRL);
+ } else {
+ inst->mask_ctrl = GEN_EXTRACT(dw0, GEN6_INST_MASKCTRL);
+ inst->dep_ctrl = GEN_EXTRACT(dw0, GEN6_INST_DEPCTRL);
+ }
+
inst->qtr_ctrl = GEN_EXTRACT(dw0, GEN6_INST_QTRCTRL);
inst->thread_ctrl = GEN_EXTRACT(dw0, GEN6_INST_THREADCTRL);
inst->pred_ctrl = GEN_EXTRACT(dw0, GEN6_INST_PREDCTRL);
break;
}
- inst->acc_wr_ctrl = (bool) (dw0 & GEN6_INST_ACCWRCTRL);
+ switch (inst->opcode) {
+ case GEN6_OPCODE_IF:
+ case GEN6_OPCODE_ELSE:
+ case GEN8_OPCODE_GOTO:
+ if (ilo_dev_gen(inst->dev) >= ILO_GEN(8)) {
+ inst->branch_ctrl = (bool) (dw0 & GEN8_INST_BRANCHCTRL);
+ break;
+ }
+ default:
+ inst->acc_wr_ctrl = (bool) (dw0 & GEN6_INST_ACCWRCTRL);
+ break;
+ }
+
inst->cmpt_ctrl = (bool) (dw0 & GEN6_INST_CMPTCTRL);
inst->debug_ctrl = (bool) (dw0 & GEN6_INST_DEBUGCTRL);
inst->saturate = (bool) (dw0 & GEN6_INST_SATURATE);
}
-static bool
-disasm_inst_jip_in_dw1_high_gen6(const struct disasm_inst *inst)
-{
- return (inst->dev->gen == ILO_GEN(6) && inst->has_jip && !inst->has_uip);
-}
-
static void
-disasm_inst_decode_dw1_gen6(struct disasm_inst *inst, uint32_t dw1)
+disasm_inst_decode_dw1_low_gen6(struct disasm_inst *inst, uint32_t dw1)
{
+ ILO_DEV_ASSERT(inst->dev, 6, 7.5);
+
inst->dst.base.file = GEN_EXTRACT(dw1, GEN6_INST_DST_FILE);
inst->dst.base.type = GEN_EXTRACT(dw1, GEN6_INST_DST_TYPE);
inst->src0.base.file = GEN_EXTRACT(dw1, GEN6_INST_SRC0_FILE);
inst->src1.base.file = GEN_EXTRACT(dw1, GEN6_INST_SRC1_FILE);
inst->src1.base.type = GEN_EXTRACT(dw1, GEN6_INST_SRC1_TYPE);
- if (inst->dev->gen >= ILO_GEN(7))
+ if (ilo_dev_gen(inst->dev) >= ILO_GEN(7))
inst->nib_ctrl = (bool) (dw1 & GEN7_INST_NIBCTRL);
+}
- if (disasm_inst_jip_in_dw1_high_gen6(inst)) {
- inst->u.imm32 = dw1 >> 16;
- return;
- }
+static void
+disasm_inst_decode_dw1_low_gen8(struct disasm_inst *inst, uint32_t dw1)
+{
+ ILO_DEV_ASSERT(inst->dev, 8, 8);
+
+ inst->flag_subreg = GEN_EXTRACT(dw1, GEN8_INST_FLAG_SUBREG);
+ inst->flag_reg = GEN_EXTRACT(dw1, GEN8_INST_FLAG_REG);
+ inst->mask_ctrl = GEN_EXTRACT(dw1, GEN8_INST_MASKCTRL);
+
+ inst->dst.base.file = GEN_EXTRACT(dw1, GEN8_INST_DST_FILE);
+ inst->dst.base.type = GEN_EXTRACT(dw1, GEN8_INST_DST_TYPE);
+ inst->src0.base.file = GEN_EXTRACT(dw1, GEN8_INST_SRC0_FILE);
+ inst->src0.base.type = GEN_EXTRACT(dw1, GEN8_INST_SRC0_TYPE);
+
+ inst->dst.base.addr_imm = GEN_EXTRACT(dw1, GEN8_INST_DST_ADDR_IMM_BIT9) <<
+ GEN8_INST_DST_ADDR_IMM_BIT9__SHR;
+}
+
+static void
+disasm_inst_decode_dw1_high_gen6(struct disasm_inst *inst, uint32_t dw1)
+{
+ ILO_DEV_ASSERT(inst->dev, 6, 8);
inst->dst.base.addr_mode = GEN_EXTRACT(dw1, GEN6_INST_DST_ADDRMODE);
GEN6_INST_DST_SUBREG_ALIGN16__SHR;
}
} else {
- inst->dst.base.addr_subreg = GEN_EXTRACT(dw1, GEN6_INST_DST_ADDR_SUBREG);
+ if (ilo_dev_gen(inst->dev) >= ILO_GEN(8)) {
+ inst->dst.base.addr_subreg =
+ GEN_EXTRACT(dw1, GEN8_INST_DST_ADDR_SUBREG);
- if (inst->access_mode == GEN6_ALIGN_1) {
- inst->dst.base.addr_imm = GEN_EXTRACT(dw1, GEN6_INST_DST_ADDR_IMM);
+ /* bit 9 is already set in disasm_inst_decode_dw1_low_gen8() */
+ if (inst->access_mode == GEN6_ALIGN_1) {
+ inst->dst.base.addr_imm |=
+ GEN_EXTRACT(dw1, GEN8_INST_DST_ADDR_IMM);
+ } else {
+ inst->dst.base.addr_imm |=
+ GEN_EXTRACT(dw1, GEN8_INST_DST_ADDR_IMM_ALIGN16) <<
+ GEN8_INST_DST_ADDR_IMM_ALIGN16__SHR;
+ }
} else {
- inst->dst.base.addr_imm = GEN_EXTRACT(dw1,
- GEN6_INST_DST_ADDR_IMM_ALIGN16) <<
- GEN6_INST_DST_ADDR_IMM_ALIGN16__SHR;
+ inst->dst.base.addr_subreg =
+ GEN_EXTRACT(dw1, GEN6_INST_DST_ADDR_SUBREG);
+
+ if (inst->access_mode == GEN6_ALIGN_1) {
+ inst->dst.base.addr_imm =
+ GEN_EXTRACT(dw1, GEN6_INST_DST_ADDR_IMM);
+ } else {
+ inst->dst.base.addr_imm =
+ GEN_EXTRACT(dw1, GEN6_INST_DST_ADDR_IMM_ALIGN16) <<
+ GEN6_INST_DST_ADDR_IMM_ALIGN16__SHR;
+ }
}
}
inst->dst.writemask = GEN_EXTRACT(dw1, GEN6_INST_DST_WRITEMASK);
}
+static void
+disasm_inst_decode_dw1_gen6(struct disasm_inst *inst, uint32_t dw1)
+{
+ ILO_DEV_ASSERT(inst->dev, 6, 8);
+
+ if (ilo_dev_gen(inst->dev) >= ILO_GEN(8))
+ disasm_inst_decode_dw1_low_gen8(inst, dw1);
+ else
+ disasm_inst_decode_dw1_low_gen6(inst, dw1);
+
+ if (ilo_dev_gen(inst->dev) == ILO_GEN(6) &&
+ inst->has_jip && !inst->has_uip)
+ inst->u.imm64 = dw1 >> 16;
+ else
+ disasm_inst_decode_dw1_high_gen6(inst, dw1);
+}
+
static void
disasm_inst_decode_dw2_dw3_gen6(struct disasm_inst *inst,
uint32_t dw2, uint32_t dw3)
{
- int count, i;
+ int imm_bits = 0, count, i;
- if (inst->dev->gen >= ILO_GEN(7))
- inst->flag_reg = GEN_EXTRACT(dw2, GEN7_INST_FLAG_REG);
+ ILO_DEV_ASSERT(inst->dev, 6, 8);
- inst->flag_subreg = GEN_EXTRACT(dw2, GEN6_INST_FLAG_SUBREG);
+ if (ilo_dev_gen(inst->dev) >= ILO_GEN(8)) {
+ /* how about real 64-bit immediates? */
+ if (inst->has_uip) {
+ imm_bits = 64;
+ inst->src1.base.file = GEN6_FILE_IMM;
+ inst->src1.base.type = GEN6_TYPE_D;
+ } else {
+ inst->src1.base.file = GEN_EXTRACT(dw2, GEN8_INST_SRC1_FILE);
+ inst->src1.base.type = GEN_EXTRACT(dw2, GEN8_INST_SRC1_TYPE);
- if (inst->src0.base.file == GEN6_FILE_IMM ||
- inst->src1.base.file == GEN6_FILE_IMM) {
- count = 1;
- if (!disasm_inst_jip_in_dw1_high_gen6(inst))
- inst->u.imm32 = dw3;
+ if (inst->src0.base.file == GEN6_FILE_IMM ||
+ inst->src1.base.file == GEN6_FILE_IMM)
+ imm_bits = 32;
+ }
} else {
+ if (ilo_dev_gen(inst->dev) >= ILO_GEN(7))
+ inst->flag_reg = GEN_EXTRACT(dw2, GEN7_INST_FLAG_REG);
+ inst->flag_subreg = GEN_EXTRACT(dw2, GEN6_INST_FLAG_SUBREG);
+
+ if (inst->src0.base.file == GEN6_FILE_IMM ||
+ inst->src1.base.file == GEN6_FILE_IMM)
+ imm_bits = 32;
+ }
+
+ switch (imm_bits) {
+ case 32:
+ inst->u.imm64 = dw3;
+ count = 1;
+ break;
+ case 64:
+ inst->u.imm64 = (uint64_t) dw2 << 32 | dw3;
+ count = 0;
+ break;
+ default:
count = 2;
+ break;
}
for (i = 0; i < count; i++) {
GEN6_INST_SRC_SUBREG_ALIGN16__SHR;
}
} else {
- src->base.addr_subreg = GEN_EXTRACT(dw, GEN6_INST_SRC_ADDR_SUBREG);
-
- if (inst->access_mode == GEN6_ALIGN_1) {
- src->base.addr_imm = GEN_EXTRACT(dw, GEN6_INST_SRC_ADDR_IMM);
+ if (ilo_dev_gen(inst->dev) >= ILO_GEN(8)) {
+ src->base.addr_subreg =
+ GEN_EXTRACT(dw, GEN8_INST_SRC_ADDR_SUBREG);
+
+ if (inst->access_mode == GEN6_ALIGN_1) {
+ src->base.addr_imm = GEN_EXTRACT(dw, GEN8_INST_SRC_ADDR_IMM);
+ } else {
+ src->base.addr_imm =
+ GEN_EXTRACT(dw, GEN8_INST_SRC_ADDR_IMM_ALIGN16) <<
+ GEN8_INST_SRC_ADDR_IMM_ALIGN16__SHR;
+ }
+
+ if (i == 0) {
+ inst->dst.base.addr_imm |= GEN_EXTRACT(dw,
+ GEN8_INST_SRC0_ADDR_IMM_BIT9) <<
+ GEN8_INST_SRC0_ADDR_IMM_BIT9__SHR;
+ } else {
+ inst->dst.base.addr_imm |= GEN_EXTRACT(dw,
+ GEN8_INST_SRC1_ADDR_IMM_BIT9) <<
+ GEN8_INST_SRC1_ADDR_IMM_BIT9__SHR;
+ }
} else {
- src->base.addr_imm =
- GEN_EXTRACT(dw, GEN6_INST_SRC_ADDR_IMM_ALIGN16) <<
- GEN6_INST_SRC_ADDR_IMM_ALIGN16__SHR;
+ src->base.addr_subreg =
+ GEN_EXTRACT(dw, GEN6_INST_SRC_ADDR_SUBREG);
+
+ if (inst->access_mode == GEN6_ALIGN_1) {
+ src->base.addr_imm = GEN_EXTRACT(dw, GEN6_INST_SRC_ADDR_IMM);
+ } else {
+ src->base.addr_imm =
+ GEN_EXTRACT(dw, GEN6_INST_SRC_ADDR_IMM_ALIGN16) <<
+ GEN6_INST_SRC_ADDR_IMM_ALIGN16__SHR;
+ }
}
}
static void
disasm_inst_decode_3src_dw1_gen6(struct disasm_inst *inst, uint32_t dw1)
{
- static unsigned type_mapping[4] = {
+ static const unsigned type_mapping[4] = {
[GEN7_TYPE_F_3SRC] = GEN6_TYPE_F,
[GEN7_TYPE_D_3SRC] = GEN6_TYPE_D,
[GEN7_TYPE_UD_3SRC] = GEN6_TYPE_UD,
[GEN7_TYPE_DF_3SRC] = GEN7_TYPE_DF,
};
+ ILO_DEV_ASSERT(inst->dev, 6, 7.5);
+
inst->flag_subreg = GEN_EXTRACT(dw1, GEN6_3SRC_FLAG_SUBREG);
- if (inst->dev->gen >= ILO_GEN(7)) {
+ if (ilo_dev_gen(inst->dev) >= ILO_GEN(7)) {
inst->nib_ctrl = (bool) (dw1 & GEN7_3SRC_NIBCTRL);
inst->flag_reg = GEN_EXTRACT(dw1, GEN7_3SRC_FLAG_REG);
inst->u.src2.absolute = (bool) (dw1 & GEN6_3SRC_SRC2_ABSOLUTE);
}
+static void
+disasm_inst_decode_3src_dw1_gen8(struct disasm_inst *inst, uint32_t dw1)
+{
+ static const unsigned type_mapping[8] = {
+ [GEN7_TYPE_F_3SRC] = GEN6_TYPE_F,
+ [GEN7_TYPE_D_3SRC] = GEN6_TYPE_D,
+ [GEN7_TYPE_UD_3SRC] = GEN6_TYPE_UD,
+ [GEN7_TYPE_DF_3SRC] = GEN7_TYPE_DF,
+ /* map unknown types to unknown types */
+ [0x4] = 0xf,
+ [0x5] = 0xf,
+ [0x6] = 0xf,
+ [0x7] = 0xf,
+ };
+
+ ILO_DEV_ASSERT(inst->dev, 8, 8);
+
+ inst->flag_subreg = GEN_EXTRACT(dw1, GEN8_3SRC_FLAG_SUBREG);
+ inst->flag_reg = GEN_EXTRACT(dw1, GEN8_3SRC_FLAG_REG);
+ inst->mask_ctrl = GEN_EXTRACT(dw1, GEN8_3SRC_MASKCTRL);
+ inst->src0.absolute = (bool) (dw1 & GEN8_3SRC_SRC0_ABSOLUTE);
+ inst->src0.negate = (bool) (dw1 & GEN8_3SRC_SRC0_NEGATE);
+ inst->src1.negate = (bool) (dw1 & GEN8_3SRC_SRC1_NEGATE);
+ inst->src1.absolute = (bool) (dw1 & GEN8_3SRC_SRC1_ABSOLUTE);
+ inst->u.src2.negate = (bool) (dw1 & GEN8_3SRC_SRC2_NEGATE);
+ inst->u.src2.absolute = (bool) (dw1 & GEN8_3SRC_SRC2_ABSOLUTE);
+
+ inst->src0.base.file = GEN6_FILE_GRF;
+ inst->src0.base.type = GEN_EXTRACT(dw1, GEN8_3SRC_SRC_TYPE);
+ inst->src0.base.type = type_mapping[inst->src0.base.type];
+
+ inst->src1.base.file = GEN6_FILE_GRF;
+ inst->src1.base.type = inst->src0.base.type;
+
+ inst->u.src2.base.file = GEN6_FILE_GRF;
+ inst->u.src2.base.type = inst->src0.base.type;
+
+ inst->dst.base.file = GEN6_FILE_GRF;
+ inst->dst.base.type = GEN_EXTRACT(dw1, GEN8_3SRC_DST_TYPE);
+ inst->dst.base.type = type_mapping[inst->dst.base.type];
+ inst->dst.base.addr_mode = GEN6_ADDRMODE_DIRECT;
+ inst->dst.horz_stride = GEN6_HORZSTRIDE_1;
+
+ inst->dst.writemask = GEN_EXTRACT(dw1, GEN6_3SRC_DST_WRITEMASK);
+ inst->dst.base.subreg = GEN_EXTRACT(dw1, GEN6_3SRC_DST_SUBREG) <<
+ GEN6_3SRC_DST_SUBREG__SHR;
+ inst->dst.base.reg = GEN_EXTRACT(dw1, GEN6_3SRC_DST_REG);
+}
+
static void
disasm_inst_decode_3src_dw2_dw3_gen6(struct disasm_inst *inst,
uint32_t dw2, uint32_t dw3)
const uint64_t qw = (uint64_t) dw3 << 32 | dw2;
int i;
+ ILO_DEV_ASSERT(inst->dev, 6, 8);
+
for (i = 0; i < 3; i++) {
struct disasm_src_operand *src = (i == 0) ? &inst->src0 :
(i == 1) ? &inst->src1 :
disasm_inst_decode_dw0_gen6(inst, dw[0]);
- switch (inst->opcode) {
- case GEN7_OPCODE_CSEL:
- case GEN7_OPCODE_BFE:
- case GEN7_OPCODE_BFI2:
- case GEN6_OPCODE_MAD:
- case GEN6_OPCODE_LRP:
- disasm_inst_decode_3src_dw1_gen6(inst, dw[1]);
+ if (disasm_opcode_table[inst->opcode].src_count == 3) {
+ if (ilo_dev_gen(inst->dev) >= ILO_GEN(8))
+ disasm_inst_decode_3src_dw1_gen8(inst, dw[1]);
+ else
+ disasm_inst_decode_3src_dw1_gen6(inst, dw[1]);
disasm_inst_decode_3src_dw2_dw3_gen6(inst, dw[2], dw[3]);
- break;
- default:
+ } else {
disasm_inst_decode_dw1_gen6(inst, dw[1]);
disasm_inst_decode_dw2_dw3_gen6(inst, dw[2], dw[3]);
- break;
}
}
case GEN6_MATH_INT_DIV: return "int_div";
case GEN6_MATH_INT_DIV_QUOTIENT: return "int_div_quotient";
case GEN6_MATH_INT_DIV_REMAINDER: return "int_div_remainder";
+ case GEN8_MATH_INVM: return "invm";
+ case GEN8_MATH_RSQRTM: return "rsqrtm";
default: return "BAD";
}
}
static const char *
disasm_inst_eot(const struct disasm_inst *inst)
{
+ const uint32_t mdesc = inst->u.ud;
+
if (inst->opcode == GEN6_OPCODE_SEND ||
inst->opcode == GEN6_OPCODE_SENDC)
- return (inst->u.imm32 & GEN6_MSG_EOT) ? " EOT" : "";
+ return (mdesc & GEN6_MSG_EOT) ? " EOT" : "";
else
return "";
}
case GEN6_TYPE_VF_IMM: return "VF";
case GEN6_TYPE_V_IMM: return "V";
case GEN6_TYPE_F: return "F";
+ case GEN8_TYPE_DF_IMM: return "DF";
+ case GEN8_TYPE_HF_IMM: return "HF";
default: return "BAD";
}
} else {
case GEN6_TYPE_B: return "B";
case GEN7_TYPE_DF: return "DF";
case GEN6_TYPE_F: return "F";
+ case GEN8_TYPE_UQ: return "UQ";
+ case GEN8_TYPE_Q: return "Q";
+ case GEN8_TYPE_HF: return "HF";
default: return "BAD";
}
}
static const char *
disasm_inst_negate(const struct disasm_inst *inst, bool negate)
{
+ if (ilo_dev_gen(inst->dev) >= ILO_GEN(8)) {
+ switch (inst->opcode) {
+ case GEN6_OPCODE_AND:
+ case GEN6_OPCODE_NOT:
+ case GEN6_OPCODE_OR:
+ case GEN6_OPCODE_XOR:
+ return (negate) ? "~" : "";
+ break;
+ default:
+ break;
+ }
+ }
+
return (negate) ? "-" : "";
}
return (absolute) ? "(abs)" : "";
}
+static const char *
+disasm_inst_mdesc_sampler_op(const struct disasm_inst *inst, int op)
+{
+ switch (op) {
+ case GEN6_MSG_SAMPLER_SAMPLE: return "sample";
+ case GEN6_MSG_SAMPLER_SAMPLE_B: return "sample_b";
+ case GEN6_MSG_SAMPLER_SAMPLE_L: return "sample_l";
+ case GEN6_MSG_SAMPLER_SAMPLE_C: return "sample_c";
+ case GEN6_MSG_SAMPLER_SAMPLE_D: return "sample_d";
+ case GEN6_MSG_SAMPLER_SAMPLE_B_C: return "sample_b_c";
+ case GEN6_MSG_SAMPLER_SAMPLE_L_C: return "sample_l_c";
+ case GEN6_MSG_SAMPLER_LD: return "ld";
+ case GEN6_MSG_SAMPLER_GATHER4: return "gather4";
+ case GEN6_MSG_SAMPLER_LOD: return "lod";
+ case GEN6_MSG_SAMPLER_RESINFO: return "resinfo";
+ case GEN6_MSG_SAMPLER_SAMPLEINFO: return "sampleinfo";
+ case GEN7_MSG_SAMPLER_GATHER4_C: return "gather4_c";
+ case GEN7_MSG_SAMPLER_GATHER4_PO: return "gather4_po";
+ case GEN7_MSG_SAMPLER_GATHER4_PO_C: return "gather4_po_c";
+ case GEN7_MSG_SAMPLER_SAMPLE_D_C: return "sample_d_c";
+ case GEN7_MSG_SAMPLER_SAMPLE_LZ: return "sample_lz";
+ case GEN7_MSG_SAMPLER_SAMPLE_C_LC: return "sample_c_lc";
+ case GEN7_MSG_SAMPLER_LD_LZ: return "ld_lz";
+ case GEN7_MSG_SAMPLER_LD_MCS: return "ld_mcs";
+ case GEN7_MSG_SAMPLER_LD2DMS: return "ld2dms";
+ case GEN7_MSG_SAMPLER_LD2DSS: return "ld2dss";
+ default: return "BAD";
+ }
+}
+
+static const char *
+disasm_inst_mdesc_sampler_simd(const struct disasm_inst *inst, int simd)
+{
+ switch (simd) {
+ case GEN6_MSG_SAMPLER_SIMD4X2: return "SIMD4x2";
+ case GEN6_MSG_SAMPLER_SIMD8: return "SIMD8";
+ case GEN6_MSG_SAMPLER_SIMD16: return "SIMD16";
+ case GEN6_MSG_SAMPLER_SIMD32_64: return "SIMD32";
+ default: return "BAD";
+ }
+}
+
+static const char *
+disasm_inst_mdesc_urb_op(const struct disasm_inst *inst, int op)
+{
+ if (ilo_dev_gen(inst->dev) >= ILO_GEN(7)) {
+ switch (op) {
+ case GEN7_MSG_URB_WRITE_HWORD: return "write HWord";
+ case GEN7_MSG_URB_WRITE_OWORD: return "write OWord";
+ case GEN7_MSG_URB_READ_HWORD: return "read HWord";
+ case GEN7_MSG_URB_READ_OWORD: return "read OWord";
+ case GEN7_MSG_URB_ATOMIC_MOV: return "atomic mov";
+ case GEN7_MSG_URB_ATOMIC_INC: return "atomic inc";
+ default: return "BAD";
+ }
+ } else {
+ switch (op) {
+ case GEN6_MSG_URB_WRITE: return "urb_write";
+ case GEN6_MSG_URB_FF_SYNC: return "ff_sync";
+ default: return "BAD";
+ }
+ }
+}
+
+static const char *
+disasm_inst_mdesc_dp_op_gen6(const struct disasm_inst *inst,
+ int sfid, int op)
+{
+ ILO_DEV_ASSERT(inst->dev, 6, 6);
+
+ switch (op) {
+ case GEN6_MSG_DP_OWORD_BLOCK_READ: return "OWORD block read";
+ case GEN6_MSG_DP_RT_UNORM_READ: return "RT UNORM read";
+ case GEN6_MSG_DP_OWORD_DUAL_BLOCK_READ: return "OWORD dual block read";
+ case GEN6_MSG_DP_MEDIA_BLOCK_READ: return "media block read";
+ case GEN6_MSG_DP_UNALIGNED_OWORD_BLOCK_READ: return "unaligned OWORD block read";
+ case GEN6_MSG_DP_DWORD_SCATTERED_READ: return "DWORD scattered read";
+ case GEN6_MSG_DP_DWORD_ATOMIC_WRITE: return "DWORD atomic write";
+ case GEN6_MSG_DP_OWORD_BLOCK_WRITE: return "OWORD block write";
+ case GEN6_MSG_DP_OWORD_DUAL_BLOCK_WRITE: return "OWORD dual block_write";
+ case GEN6_MSG_DP_MEDIA_BLOCK_WRITE: return "media block write";
+ case GEN6_MSG_DP_DWORD_SCATTERED_WRITE: return "DWORD scattered write";
+ case GEN6_MSG_DP_RT_WRITE: return "RT write";
+ case GEN6_MSG_DP_SVB_WRITE: return "SVB write";
+ case GEN6_MSG_DP_RT_UNORM_WRITE: return "RT UNORM write";
+ default: return "BAD";
+ }
+}
+
+static const char *
+disasm_inst_mdesc_dp_op_gen7(const struct disasm_inst *inst,
+ int sfid, int op)
+{
+ ILO_DEV_ASSERT(inst->dev, 7, 7);
+
+ switch (sfid) {
+ case GEN6_SFID_DP_SAMPLER:
+ switch (op) {
+ case GEN7_MSG_DP_SAMPLER_UNALIGNED_OWORD_BLOCK_READ: return "OWORD block read";
+ case GEN7_MSG_DP_SAMPLER_MEDIA_BLOCK_READ: return "media block read";
+ default: return "BAD";
+ }
+ case GEN6_SFID_DP_RC:
+ switch (op) {
+ case GEN7_MSG_DP_RC_MEDIA_BLOCK_READ: return "media block read";
+ case GEN7_MSG_DP_RC_TYPED_SURFACE_READ: return "typed surface read";
+ case GEN7_MSG_DP_RC_TYPED_ATOMIC_OP: return "typed atomic op";
+ case GEN7_MSG_DP_RC_MEMORY_FENCE: return "memory fence";
+ case GEN7_MSG_DP_RC_MEDIA_BLOCK_WRITE: return "media block write";
+ case GEN7_MSG_DP_RC_RT_WRITE: return "RT write";
+ case GEN7_MSG_DP_RC_TYPED_SURFACE_WRITE: return "typed surface write";
+ default: return "BAD";
+ }
+ case GEN6_SFID_DP_CC:
+ switch (op) {
+ case GEN7_MSG_DP_CC_OWORD_BLOCK_READ: return "OWROD block read";
+ case GEN7_MSG_DP_CC_UNALIGNED_OWORD_BLOCK_READ: return "unaligned OWORD block read";
+ case GEN7_MSG_DP_CC_OWORD_DUAL_BLOCK_READ: return "OWORD dual block read";
+ case GEN7_MSG_DP_CC_DWORD_SCATTERED_READ: return "DWORD scattered read";
+ default: return "BAD";
+ }
+ case GEN7_SFID_DP_DC0:
+ switch (op) {
+ case GEN7_MSG_DP_DC0_OWORD_BLOCK_READ: return "OWORD block read";
+ case GEN7_MSG_DP_DC0_UNALIGNED_OWORD_BLOCK_READ: return "unaligned OWORD block read";
+ case GEN7_MSG_DP_DC0_OWORD_DUAL_BLOCK_READ: return "OWORD dual block read";
+ case GEN7_MSG_DP_DC0_DWORD_SCATTERED_READ: return "DWORD scattered read";
+ case GEN7_MSG_DP_DC0_BYTE_SCATTERED_READ: return "BYTE scattered read";
+ case GEN7_MSG_DP_DC0_UNTYPED_SURFACE_READ: return "untyped surface read";
+ case GEN7_MSG_DP_DC0_UNTYPED_ATOMIC_OP: return "untyped atomic op";
+ case GEN7_MSG_DP_DC0_MEMORY_FENCE: return "memory fence";
+ case GEN7_MSG_DP_DC0_OWORD_BLOCK_WRITE: return "OWORD block write";
+ case GEN7_MSG_DP_DC0_OWORD_DUAL_BLOCK_WRITE: return "OWORD dual block write";
+ case GEN7_MSG_DP_DC0_DWORD_SCATTERED_WRITE: return "OWORD scattered write";
+ case GEN7_MSG_DP_DC0_BYTE_SCATTERED_WRITE: return "BYTE scattered write";
+ case GEN7_MSG_DP_DC0_UNTYPED_SURFACE_WRITE: return "untyped surface write";
+ default: return "BAD";
+ }
+ default: return "BAD";
+ }
+}
+
+static const char *
+disasm_inst_mdesc_dp_op_gen75(const struct disasm_inst *inst,
+ int sfid, int op)
+{
+ ILO_DEV_ASSERT(inst->dev, 7.5, 8);
+
+ switch (sfid) {
+ case GEN6_SFID_DP_SAMPLER:
+ switch (op) {
+ case GEN75_MSG_DP_SAMPLER_READ_SURFACE_INFO: return "read surface info";
+ case GEN75_MSG_DP_SAMPLER_UNALIGNED_OWORD_BLOCK_READ: return "unaligned OWORD block read";
+ case GEN75_MSG_DP_SAMPLER_MEDIA_BLOCK_READ: return "media block read";
+ default: return "BAD";
+ }
+
+ case GEN6_SFID_DP_RC:
+ switch (op) {
+ case GEN75_MSG_DP_RC_MEDIA_BLOCK_READ: return "media block read";
+ case GEN75_MSG_DP_RC_MEMORY_FENCE: return "memory fence";
+ case GEN75_MSG_DP_RC_MEDIA_BLOCK_WRITE: return "media block write";
+ case GEN75_MSG_DP_RC_RT_WRITE: return "RT write";
+ default: return "BAD";
+ }
+ case GEN6_SFID_DP_CC:
+ switch (op) {
+ case GEN75_MSG_DP_CC_OWORD_BLOCK_READ: return "OWROD block read";
+ case GEN75_MSG_DP_CC_UNALIGNED_OWORD_BLOCK_READ: return "unaligned OWORD block read";
+ case GEN75_MSG_DP_CC_OWORD_DUAL_BLOCK_READ: return "OWORD dual block read";
+ case GEN75_MSG_DP_CC_DWORD_SCATTERED_READ: return "DWORD scattered read";
+ default: return "BAD";
+ }
+ case GEN7_SFID_DP_DC0:
+ switch (op) {
+ case GEN75_MSG_DP_DC0_OWORD_BLOCK_READ: return "OWORD block read";
+ case GEN75_MSG_DP_DC0_UNALIGNED_OWORD_BLOCK_READ: return "unaligned OWORD block read";
+ case GEN75_MSG_DP_DC0_OWORD_DUAL_BLOCK_READ: return "OWORD dual block read";
+ case GEN75_MSG_DP_DC0_DWORD_SCATTERED_READ: return "DWORD scattered read";
+ case GEN75_MSG_DP_DC0_BYTE_SCATTERED_READ: return "BYTE scattered read";
+ case GEN75_MSG_DP_DC0_MEMORY_FENCE: return "memory fence";
+ case GEN75_MSG_DP_DC0_OWORD_BLOCK_WRITE: return "OWORD block write";
+ case GEN75_MSG_DP_DC0_OWORD_DUAL_BLOCK_WRITE: return "OWORD dual block write";
+ case GEN75_MSG_DP_DC0_DWORD_SCATTERED_WRITE: return "OWORD scattered write";
+ case GEN75_MSG_DP_DC0_BYTE_SCATTERED_WRITE: return "BYTE scattered write";
+ default: return "BAD";
+ }
+ case GEN75_SFID_DP_DC1:
+ switch (op) {
+ case GEN75_MSG_DP_DC1_UNTYPED_SURFACE_READ: return "untyped surface read";
+ case GEN75_MSG_DP_DC1_UNTYPED_ATOMIC_OP: return "DC untyped atomic op";
+ case GEN75_MSG_DP_DC1_UNTYPED_ATOMIC_OP_SIMD4X2: return "DC untyped 4x2 atomic op";
+ case GEN75_MSG_DP_DC1_MEDIA_BLOCK_READ: return "DC media block read";
+ case GEN75_MSG_DP_DC1_TYPED_SURFACE_READ: return "DC typed surface read";
+ case GEN75_MSG_DP_DC1_TYPED_ATOMIC_OP: return "DC typed atomic";
+ case GEN75_MSG_DP_DC1_TYPED_ATOMIC_OP_SIMD4X2: return "DC typed 4x2 atomic op";
+ case GEN75_MSG_DP_DC1_UNTYPED_SURFACE_WRITE: return "DC untyped surface write";
+ case GEN75_MSG_DP_DC1_MEDIA_BLOCK_WRITE: return "DC media block write";
+ case GEN75_MSG_DP_DC1_ATOMIC_COUNTER_OP: return "DC atomic counter op";
+ case GEN75_MSG_DP_DC1_ATOMIC_COUNTER_OP_SIMD4X2: return "DC 4x2 atomic counter op";
+ case GEN75_MSG_DP_DC1_TYPED_SURFACE_WRITE: return "DC typed surface write";
+ default: return "BAD";
+ }
+ default: return "BAD";
+ }
+}
+
+static const char *
+disasm_inst_mdesc_dp_op(const struct disasm_inst *inst, int sfid, int op)
+{
+ switch (ilo_dev_gen(inst->dev)) {
+ case ILO_GEN(8):
+ case ILO_GEN(7.5): return disasm_inst_mdesc_dp_op_gen75(inst, sfid, op);
+ case ILO_GEN(7): return disasm_inst_mdesc_dp_op_gen7(inst, sfid, op);
+ case ILO_GEN(6): return disasm_inst_mdesc_dp_op_gen6(inst, sfid, op);
+ default: return "BAD";
+ }
+}
+
+static const char *
+disasm_inst_mdesc_dp_untyped_surface_simd_mode(const struct disasm_inst *inst,
+ uint32_t mdesc)
+{
+ switch (mdesc & GEN7_MSG_DP_UNTYPED_MODE__MASK) {
+ case GEN7_MSG_DP_UNTYPED_MODE_SIMD4X2: return "SIMD4x2";
+ case GEN7_MSG_DP_UNTYPED_MODE_SIMD16: return "SIMD16";
+ case GEN7_MSG_DP_UNTYPED_MODE_SIMD8: return "SIMD8";
+ default: return "BAD";
+ }
+}
+
+static const char *
+disasm_inst_mdesc_dp_rt_write_simd_mode(const struct disasm_inst *inst,
+ uint32_t mdesc)
+{
+ switch (mdesc & GEN6_MSG_DP_RT_MODE__MASK) {
+ case GEN6_MSG_DP_RT_MODE_SIMD16: return "SIMD16";
+ case GEN6_MSG_DP_RT_MODE_SIMD16_REPDATA: return "SIMD16/RepData";
+ case GEN6_MSG_DP_RT_MODE_SIMD8_DUALSRC_LO: return "SIMD8/DualSrcLow";
+ case GEN6_MSG_DP_RT_MODE_SIMD8_DUALSRC_HI: return "SIMD8/DualSrcHigh";
+ case GEN6_MSG_DP_RT_MODE_SIMD8_LO: return "SIMD8";
+ case GEN6_MSG_DP_RT_MODE_SIMD8_IMAGE_WR: return "SIMD8/ImageWrite";
+ default: return "BAD";
+ }
+}
+
static bool
disasm_inst_is_null(const struct disasm_inst *inst,
const struct disasm_operand *operand)
if (operand->file == GEN6_FILE_IMM) {
switch (operand->type) {
case GEN6_TYPE_UD:
- disasm_printer_add(printer, "0x%08xUD", inst->u.imm32);
+ disasm_printer_add(printer, "0x%08xUD", inst->u.ud);
break;
case GEN6_TYPE_D:
- disasm_printer_add(printer, "%dD", inst->u.imm32);
+ disasm_printer_add(printer, "%dD", inst->u.d);
break;
case GEN6_TYPE_UW:
- disasm_printer_add(printer, "0x%04xUW", (uint16_t) inst->u.imm32);
+ disasm_printer_add(printer, "0x%04xUW", inst->u.uw);
break;
case GEN6_TYPE_W:
- disasm_printer_add(printer, "%dW", (int16_t) inst->u.imm32);
+ disasm_printer_add(printer, "%dW", inst->u.w);
break;
case GEN6_TYPE_UV_IMM:
- disasm_printer_add(printer, "0x%08xUV", inst->u.imm32);
+ disasm_printer_add(printer, "0x%08xUV", inst->u.ud);
break;
case GEN6_TYPE_VF_IMM:
disasm_printer_add(printer, "Vector Float");
break;
case GEN6_TYPE_V_IMM:
- disasm_printer_add(printer, "0x%08xV", inst->u.imm32);
+ disasm_printer_add(printer, "0x%08xV", inst->u.ud);
break;
case GEN6_TYPE_F:
- disasm_printer_add(printer, "%-gF", uif(inst->u.imm32));
+ disasm_printer_add(printer, "%-gF", uif(inst->u.f));
break;
default:
disasm_printer_add(printer, "BAD");
{
int op, simd;
- if (inst->dev->gen >= ILO_GEN(7)) {
+ if (ilo_dev_gen(inst->dev) >= ILO_GEN(7)) {
op = GEN_EXTRACT(mdesc, GEN7_MSG_SAMPLER_OP);
simd = GEN_EXTRACT(mdesc, GEN7_MSG_SAMPLER_SIMD);
- } {
+ } else {
op = GEN_EXTRACT(mdesc, GEN6_MSG_SAMPLER_OP);
simd = GEN_EXTRACT(mdesc, GEN6_MSG_SAMPLER_SIMD);
}
- disasm_printer_add(printer, " (%d, %d, %d, %d)",
- GEN_EXTRACT(mdesc, GEN6_MSG_SAMPLER_SURFACE),
+ disasm_printer_add(printer,
+ "%s %s samp %d surf %d",
+ disasm_inst_mdesc_sampler_op(inst, op),
+ disasm_inst_mdesc_sampler_simd(inst, simd),
GEN_EXTRACT(mdesc, GEN6_MSG_SAMPLER_INDEX),
- op, simd);
+ GEN_EXTRACT(mdesc, GEN6_MSG_SAMPLER_SURFACE));
}
static void
const struct disasm_inst *inst,
uint32_t mdesc)
{
- const char *op;
- int offset;
+ int op, offset;
bool interleaved, complete, allocate, used;
- if (inst->dev->gen >= ILO_GEN(7)) {
- switch (GEN_EXTRACT(mdesc, GEN7_MSG_URB_OP)) {
- case GEN7_MSG_URB_WRITE_HWORD: op = "write HWord"; break;
- case GEN7_MSG_URB_WRITE_OWORD: op = "write OWord"; break;
- case GEN7_MSG_URB_READ_HWORD: op = "read HWord"; break;
- case GEN7_MSG_URB_READ_OWORD: op = "read OWord"; break;
- case GEN7_MSG_URB_ATOMIC_MOV: op = "atomic mov"; break;
- case GEN7_MSG_URB_ATOMIC_INC: op = "atomic inc"; break;
- default: op = "BAD"; break;
- }
-
+ if (ilo_dev_gen(inst->dev) >= ILO_GEN(7)) {
+ op = GEN_EXTRACT(mdesc, GEN7_MSG_URB_OP);
offset = GEN_EXTRACT(mdesc, GEN7_MSG_URB_GLOBAL_OFFSET);
interleaved = mdesc & GEN7_MSG_URB_INTERLEAVED;
- complete = mdesc & GEN7_MSG_URB_COMPLETE;
+
+ complete = (ilo_dev_gen(inst->dev) >= ILO_GEN(8)) ?
+ false : (mdesc & GEN7_MSG_URB_COMPLETE);
allocate = false;
used = false;
} else {
- switch (GEN_EXTRACT(mdesc, GEN6_MSG_URB_OP)) {
- case GEN6_MSG_URB_WRITE: op = "urb_write"; break;
- case GEN6_MSG_URB_FF_SYNC: op = "ff_sync"; break;
- default: op = "BAD"; break;
- }
-
+ op = GEN_EXTRACT(mdesc, GEN6_MSG_URB_OP);
offset = GEN_EXTRACT(mdesc, GEN6_MSG_URB_OFFSET);
interleaved = mdesc & GEN6_MSG_URB_INTERLEAVED;
complete = mdesc & GEN6_MSG_URB_COMPLETE;
used = mdesc & GEN6_MSG_URB_USED;
}
- disasm_printer_add(printer, " %d %s%s%s%s%s", offset, op,
+ disasm_printer_add(printer, "%s offset %d%s%s%s%s",
+ disasm_inst_mdesc_urb_op(inst, op),
+ offset,
(interleaved) ? " interleave" : "",
(allocate) ? " allocate" : "",
(used) ? " used" : "",
(complete) ? " complete" : "");
}
+static void
+disasm_printer_add_mdesc_spawner(struct disasm_printer *printer,
+ const struct disasm_inst *inst,
+ uint32_t mdesc)
+{
+ const char *requester, *op;
+
+ switch (mdesc & GEN6_MSG_TS_REQUESTER_TYPE__MASK) {
+ case GEN6_MSG_TS_REQUESTER_TYPE_ROOT: requester = "root"; break;
+ case GEN6_MSG_TS_REQUESTER_TYPE_CHILD: requester = "child"; break;
+ default: requester = "BAD"; break;
+ }
+
+ switch (mdesc & GEN6_MSG_TS_OPCODE__MASK) {
+ case GEN6_MSG_TS_OPCODE_DEREF:
+ op = (mdesc & GEN6_MSG_TS_RESOURCE_SELECT_NO_DEREF) ?
+ "no deref" : "deref";
+ break;
+ case GEN6_MSG_TS_OPCODE_SPAWN:
+ op = (mdesc & GEN6_MSG_TS_RESOURCE_SELECT_ROOT) ?
+ "spawn root" : "spawn child";
+ break;
+ default:
+ op = "BAD";
+ break;
+ }
+
+ disasm_printer_add(printer, "%s thread %s", requester, op);
+}
+
static void
disasm_printer_add_mdesc_dp_sampler(struct disasm_printer *printer,
const struct disasm_inst *inst,
uint32_t mdesc)
{
- const int op = (inst->dev->gen >= ILO_GEN(7)) ?
+ const int op = (ilo_dev_gen(inst->dev) >= ILO_GEN(7)) ?
GEN_EXTRACT(mdesc, GEN7_MSG_DP_OP) : GEN_EXTRACT(mdesc, GEN6_MSG_DP_OP);
- const bool write_commit = (inst->dev->gen == ILO_GEN(6)) ?
+ const bool write_commit = (ilo_dev_gen(inst->dev) == ILO_GEN(6)) ?
(mdesc & GEN6_MSG_DP_SEND_WRITE_COMMIT) : 0;
- disasm_printer_add(printer, " (%d, %d, %d, %d)",
- GEN_EXTRACT(mdesc, GEN6_MSG_DP_SURFACE),
+ disasm_printer_add(printer, "%s block size %d commit %d surf %d",
+ disasm_inst_mdesc_dp_op(inst, GEN6_SFID_DP_SAMPLER, op),
GEN_EXTRACT(mdesc, GEN6_MSG_DP_OWORD_BLOCK_SIZE),
- op, write_commit);
+ write_commit,
+ GEN_EXTRACT(mdesc, GEN6_MSG_DP_SURFACE));
+}
+
+static void
+disasm_printer_add_mdesc_dp_dc0(struct disasm_printer *printer,
+ const struct disasm_inst *inst,
+ uint32_t mdesc)
+{
+ const int op = GEN_EXTRACT(mdesc, GEN7_MSG_DP_OP);
+
+ ILO_DEV_ASSERT(inst->dev, 7, 7.5);
+
+ if (ilo_dev_gen(inst->dev) >= ILO_GEN(7.5)) {
+ disasm_printer_add(printer, "%s ctrl 0x%x surf %d",
+ disasm_inst_mdesc_dp_op(inst, GEN7_SFID_DP_DC0, op),
+ GEN_EXTRACT(mdesc, GEN6_MSG_DP_CTRL),
+ GEN_EXTRACT(mdesc, GEN6_MSG_DP_SURFACE));
+ } else {
+ switch (op) {
+ case GEN7_MSG_DP_DC0_UNTYPED_SURFACE_READ:
+ case GEN7_MSG_DP_DC0_UNTYPED_SURFACE_WRITE:
+ disasm_printer_add(printer, "%s %s mask 0x%x surf %d",
+ disasm_inst_mdesc_dp_op(inst, GEN7_SFID_DP_DC0, op),
+ disasm_inst_mdesc_dp_untyped_surface_simd_mode(inst, mdesc),
+ GEN_EXTRACT(mdesc, GEN7_MSG_DP_UNTYPED_MASK),
+ GEN_EXTRACT(mdesc, GEN6_MSG_DP_SURFACE));
+ break;
+ default:
+ disasm_printer_add(printer, "%s ctrl 0x%x surf %d",
+ disasm_inst_mdesc_dp_op(inst, GEN7_SFID_DP_DC0, op),
+ GEN_EXTRACT(mdesc, GEN6_MSG_DP_CTRL),
+ GEN_EXTRACT(mdesc, GEN6_MSG_DP_SURFACE));
+ break;
+ }
+ }
+}
+
+static void
+disasm_printer_add_mdesc_dp_dc1(struct disasm_printer *printer,
+ const struct disasm_inst *inst,
+ uint32_t mdesc)
+{
+ const int op = GEN_EXTRACT(mdesc, GEN7_MSG_DP_OP);
+
+ ILO_DEV_ASSERT(inst->dev, 7.5, 7.5);
+
+ switch (op) {
+ case GEN75_MSG_DP_DC1_UNTYPED_SURFACE_READ:
+ case GEN75_MSG_DP_DC1_UNTYPED_SURFACE_WRITE:
+ disasm_printer_add(printer, "%s %s mask 0x%x surf %d",
+ disasm_inst_mdesc_dp_op(inst, GEN75_SFID_DP_DC1, op),
+ disasm_inst_mdesc_dp_untyped_surface_simd_mode(inst, mdesc),
+ GEN_EXTRACT(mdesc, GEN7_MSG_DP_UNTYPED_MASK),
+ GEN_EXTRACT(mdesc, GEN6_MSG_DP_SURFACE));
+ break;
+ default:
+ disasm_printer_add(printer, "%s ctrl 0x%x surf %d",
+ disasm_inst_mdesc_dp_op(inst, GEN75_SFID_DP_DC1, op),
+ GEN_EXTRACT(mdesc, GEN6_MSG_DP_CTRL),
+ GEN_EXTRACT(mdesc, GEN6_MSG_DP_SURFACE));
+ break;
+ }
}
static void
const struct disasm_inst *inst,
uint32_t mdesc)
{
- const int op = (inst->dev->gen >= ILO_GEN(7)) ?
+ const int op = (ilo_dev_gen(inst->dev) >= ILO_GEN(7)) ?
GEN_EXTRACT(mdesc, GEN7_MSG_DP_OP) : GEN_EXTRACT(mdesc, GEN6_MSG_DP_OP);
- const char *str;
bool is_rt_write;
- if (inst->dev->gen >= ILO_GEN(7.5)) {
- switch (op) {
- case GEN75_MSG_DP_RC_MEDIA_BLOCK_READ: str = "media block read"; break;
- case GEN75_MSG_DP_RC_MEMORY_FENCE: str = "memory fence"; break;
- case GEN75_MSG_DP_RC_MEDIA_BLOCK_WRITE: str = "media block write"; break;
- case GEN75_MSG_DP_RC_RT_WRITE: str = "RT write"; break;
- default: str = "BAD"; break;
- }
-
+ if (ilo_dev_gen(inst->dev) >= ILO_GEN(7.5))
is_rt_write = (op == GEN75_MSG_DP_RC_RT_WRITE);
- } else if (inst->dev->gen >= ILO_GEN(7)) {
- switch (op) {
- case GEN7_MSG_DP_RC_MEDIA_BLOCK_READ: str = "media block read"; break;
- case GEN7_MSG_DP_RC_TYPED_SURFACE_READ: str = "typed surface read"; break;
- case GEN7_MSG_DP_RC_TYPED_ATOMIC_OP: str = "typed atomic op"; break;
- case GEN7_MSG_DP_RC_MEMORY_FENCE: str = "memory fence"; break;
- case GEN7_MSG_DP_RC_MEDIA_BLOCK_WRITE: str = "media block write"; break;
- case GEN7_MSG_DP_RC_RT_WRITE: str = "RT write"; break;
- case GEN7_MSG_DP_RC_TYPED_SURFACE_WRITE: str = "typed surface write"; break;
- default: str = "BAD"; break;
- }
-
+ else if (ilo_dev_gen(inst->dev) >= ILO_GEN(7))
is_rt_write = (op == GEN7_MSG_DP_RC_RT_WRITE);
- } else {
- switch (op) {
- case GEN6_MSG_DP_OWORD_BLOCK_READ: str = "OWORD block read"; break;
- case GEN6_MSG_DP_RT_UNORM_READ: str = "RT UNORM read"; break;
- case GEN6_MSG_DP_OWORD_DUAL_BLOCK_READ: str = "OWORD dual block read"; break;
- case GEN6_MSG_DP_MEDIA_BLOCK_READ: str = "media block read"; break;
- case GEN6_MSG_DP_UNALIGNED_OWORD_BLOCK_READ: str = "unaligned OWORD block read"; break;
- case GEN6_MSG_DP_DWORD_SCATTERED_READ: str = "DWORD scattered read"; break;
- case GEN6_MSG_DP_DWORD_ATOMIC_WRITE: str = "DWORD atomic write"; break;
- case GEN6_MSG_DP_OWORD_BLOCK_WRITE: str = "OWORD block write"; break;
- case GEN6_MSG_DP_OWORD_DUAL_BLOCK_WRITE: str = "OWORD dual block_write"; break;
- case GEN6_MSG_DP_MEDIA_BLOCK_WRITE: str = "media block write"; break;
- case GEN6_MSG_DP_DWORD_SCATTERED_WRITE: str = "DWORD scattered write"; break;
- case GEN6_MSG_DP_RT_WRITE: str = "RT write"; break;
- case GEN6_MSG_DP_SVB_WRITE: str = "SVB write"; break;
- case GEN6_MSG_DP_RT_UNORM_WRITE: str = "RT UNORM write"; break;
- default: str = "BAD"; break;
- }
-
+ else
is_rt_write = (op == GEN6_MSG_DP_RT_WRITE);
- }
- disasm_printer_add(printer, " %s", str);
+ disasm_printer_add(printer, "%s",
+ disasm_inst_mdesc_dp_op(inst, GEN6_SFID_DP_RC, op));
if (is_rt_write) {
- switch (mdesc & GEN6_MSG_DP_RT_MODE__MASK) {
- case GEN6_MSG_DP_RT_MODE_SIMD16: str = "SIMD16"; break;
- case GEN6_MSG_DP_RT_MODE_SIMD16_REPDATA: str = "SIMD16/RepData"; break;
- case GEN6_MSG_DP_RT_MODE_SIMD8_DUALSRC_LO: str = "SIMD8/DualSrcLow"; break;
- case GEN6_MSG_DP_RT_MODE_SIMD8_DUALSRC_HI: str = "SIMD8/DualSrcHigh"; break;
- case GEN6_MSG_DP_RT_MODE_SIMD8_LO: str = "SIMD8"; break;
- case GEN6_MSG_DP_RT_MODE_SIMD8_IMAGE_WR: str = "SIMD8/ImageWrite"; break;
- default: str = "BAD"; break;
- }
-
- disasm_printer_add(printer, " %s%s%s%s", str,
- (mdesc & GEN6_MSG_DP_SLOTGRP_HI) ? " Hi" : "",
+ disasm_printer_add(printer, " %s%s%s%s",
+ disasm_inst_mdesc_dp_rt_write_simd_mode(inst, mdesc),
+ (mdesc & GEN6_MSG_DP_RT_SLOTGRP_HI) ? " Hi" : "",
(mdesc & GEN6_MSG_DP_RT_LAST) ? " LastRT" : "",
- (inst->dev->gen == ILO_GEN(6) &&
+ (ilo_dev_gen(inst->dev) == ILO_GEN(6) &&
(mdesc & GEN6_MSG_DP_SEND_WRITE_COMMIT)) ? " WriteCommit" : "");
}
- disasm_printer_add(printer, " Surface = %d",
+ disasm_printer_add(printer, " surf %d",
GEN_EXTRACT(mdesc, GEN6_MSG_DP_SURFACE));
}
disasm_printer_add_mdesc(struct disasm_printer *printer,
const struct disasm_inst *inst)
{
- const uint32_t mdesc = inst->u.imm32;
+ const uint32_t mdesc = inst->u.ud;
assert(inst->opcode == GEN6_OPCODE_SEND ||
inst->opcode == GEN6_OPCODE_SENDC);
assert(inst->src1.base.file == GEN6_FILE_IMM);
- disasm_printer_add(printer, " %s", disasm_inst_sfid(inst));
+ disasm_printer_add(printer, " %s (", disasm_inst_sfid(inst));
switch (inst->sfid) {
case GEN6_SFID_SAMPLER:
case GEN6_SFID_URB:
disasm_printer_add_mdesc_urb(printer, inst, mdesc);
break;
- case GEN6_SFID_DP_CC:
+ case GEN6_SFID_SPAWNER:
+ disasm_printer_add_mdesc_spawner(printer, inst, mdesc);
+ break;
case GEN7_SFID_DP_DC0:
- case GEN7_SFID_PI:
+ disasm_printer_add_mdesc_dp_dc0(printer, inst, mdesc);
+ break;
case GEN75_SFID_DP_DC1:
+ disasm_printer_add_mdesc_dp_dc1(printer, inst, mdesc);
+ break;
+ case GEN6_SFID_DP_CC:
+ case GEN7_SFID_PI:
default:
break;
}
- disasm_printer_add(printer, " mlen %d rlen %d",
+ disasm_printer_add(printer, ") mlen %d rlen %d",
GEN_EXTRACT(mdesc, GEN6_MSG_MLEN),
GEN_EXTRACT(mdesc, GEN6_MSG_RLEN));
}
if (inst->has_jip || inst->has_uip) {
if (inst->has_jip) {
+ const int32_t jip = (ilo_dev_gen(inst->dev) >= ILO_GEN(8)) ?
+ inst->u.ip32.jip : inst->u.ip16.jip;
+
disasm_printer_column(printer, col++);
- disasm_printer_add(printer, "JIP: %d", (int16_t) inst->u.imm32);
+ disasm_printer_add(printer, "JIP: %d", jip);
}
if (inst->has_uip) {
+ const int32_t uip = (ilo_dev_gen(inst->dev) >= ILO_GEN(8)) ?
+ inst->u.ip32.uip : inst->u.ip16.uip;
+
disasm_printer_column(printer, col++);
- disasm_printer_add(printer, "UIP: %d",
- (int16_t) (inst->u.imm32 >> 16));
+ disasm_printer_add(printer, "UIP: %d", uip);
}
} else {
const int src_count = disasm_opcode_table[inst->opcode].src_count;
- const struct disasm_src_operand *src[3];
- int i;
-
- /* get src operands */
- switch (src_count) {
- case 3:
- src[2] = &inst->u.src2;
- case 2:
- src[1] = &inst->src1;
- case 1:
- src[0] = &inst->src0;
- case 0:
- default:
- break;
- }
if (src_count) {
+ const struct disasm_src_operand *src[3] = {
+ &inst->src0, &inst->src1, &inst->u.src2
+ };
+ int i;
+
disasm_printer_column(printer, col++);
disasm_printer_add_dst(printer, inst, &inst->dst);
ilo_printf("%s\n", disasm_printer_get_string(printer));
}
+static void
+disasm_uncompact_3src(const struct ilo_dev *dev,
+ uint64_t compact, uint32_t *dw)
+{
+ const struct toy_compaction_table *tbl =
+ toy_compiler_get_compaction_table(dev);
+ uint32_t src[3], tmp;
+ uint64_t tmp64;
+
+ ILO_DEV_ASSERT(dev, 8, 8);
+
+ tmp = GEN_EXTRACT(compact, GEN8_COMPACT_3SRC_OPCODE);
+ dw[0] = GEN_SHIFT32(tmp, GEN6_INST_OPCODE);
+
+ /* ControlIndex */
+ tmp = GEN_EXTRACT(compact, GEN8_COMPACT_3SRC_CONTROL_INDEX);
+ tmp = tbl->control_3src[tmp];
+
+ dw[0] |= (tmp & 0x1fffff) << GEN6_INST_ACCESSMODE__SHIFT;
+ dw[1] = (tmp >> 21) & ((ilo_dev_gen(dev) >= ILO_GEN(9)) ? 0x1f : 0x7);
+
+ /* SourceIndex */
+ tmp = GEN_EXTRACT(compact, GEN8_COMPACT_3SRC_SOURCE_INDEX);
+ tmp64 = tbl->source_3src[tmp];
+
+ dw[1] |= (tmp64 & 0x7ffff) << 5;
+ src[0] = ((tmp64 >> 19) & 0xff) << 1;
+ src[1] = ((tmp64 >> 27) & 0xff) << 1;
+ src[2] = ((tmp64 >> 35) & 0xff) << 1;
+ if (ilo_dev_gen(dev) >= ILO_GEN(9)) {
+ src[0] |= ((tmp64 >> 43) & 0x3) << 19;
+ src[1] |= ((tmp64 >> 45) & 0x3) << 19;
+ src[2] |= ((tmp64 >> 47) & 0x3) << 19;
+ } else {
+ src[0] |= ((tmp64 >> 43) & 0x1) << 19;
+ src[1] |= ((tmp64 >> 44) & 0x1) << 19;
+ src[2] |= ((tmp64 >> 45) & 0x1) << 19;
+ }
+
+ tmp = GEN_EXTRACT(compact, GEN8_COMPACT_3SRC_DST_REG);
+ dw[1] |= GEN_SHIFT32(tmp, GEN6_3SRC_DST_REG);
+
+ if (compact & GEN8_COMPACT_3SRC_SRC0_REPCTRL)
+ src[0] |= GEN6_3SRC_SRC_REPCTRL;
+
+ assert(compact & GEN8_COMPACT_3SRC_CMPTCTRL);
+
+ if (compact & GEN8_COMPACT_3SRC_DEBUGCTRL)
+ dw[0] |= GEN6_INST_DEBUGCTRL;
+ if (compact & GEN8_COMPACT_3SRC_SATURATE)
+ dw[0] |= GEN6_INST_SATURATE;
+
+ if (compact & GEN8_COMPACT_3SRC_SRC1_REPCTRL)
+ src[1] |= GEN6_3SRC_SRC_REPCTRL;
+ if (compact & GEN8_COMPACT_3SRC_SRC2_REPCTRL)
+ src[2] |= GEN6_3SRC_SRC_REPCTRL;
+
+ tmp = GEN_EXTRACT(compact, GEN8_COMPACT_3SRC_SRC0_SUBREG);
+ src[0] |= GEN_SHIFT32(tmp, GEN6_3SRC_SRC_SUBREG);
+ tmp = GEN_EXTRACT(compact, GEN8_COMPACT_3SRC_SRC1_SUBREG);
+ src[1] |= GEN_SHIFT32(tmp, GEN6_3SRC_SRC_SUBREG);
+ tmp = GEN_EXTRACT(compact, GEN8_COMPACT_3SRC_SRC2_SUBREG);
+ src[2] |= GEN_SHIFT32(tmp, GEN6_3SRC_SRC_SUBREG);
+
+ tmp = GEN_EXTRACT(compact, GEN8_COMPACT_3SRC_SRC0_REG);
+ src[0] |= GEN_SHIFT32(tmp, GEN6_3SRC_SRC_REG);
+ tmp = GEN_EXTRACT(compact, GEN8_COMPACT_3SRC_SRC1_REG);
+ src[1] |= GEN_SHIFT32(tmp, GEN6_3SRC_SRC_REG);
+ tmp = GEN_EXTRACT(compact, GEN8_COMPACT_3SRC_SRC2_REG);
+ src[2] |= GEN_SHIFT32(tmp, GEN6_3SRC_SRC_REG);
+
+ tmp64 = (uint64_t) src[2] << 42 |
+ (uint64_t) src[1] << 21 |
+ (uint64_t) src[0];
+ dw[2] = (uint32_t) tmp64;
+ dw[3] = (uint32_t) (tmp64 >> 32);
+}
+
+static void
+disasm_uncompact(const struct ilo_dev *dev,
+ uint64_t compact, uint32_t *dw)
+{
+ const struct toy_compaction_table *tbl =
+ toy_compiler_get_compaction_table(dev);
+ bool src_is_imm;
+ uint32_t tmp;
+
+ ILO_DEV_ASSERT(dev, 6, 8);
+
+ tmp = GEN_EXTRACT(compact, GEN6_COMPACT_OPCODE);
+ if (disasm_opcode_table[tmp].src_count == 3) {
+ disasm_uncompact_3src(dev, compact, dw);
+ return;
+ }
+
+ memset(dw, 0, sizeof(*dw) * 4);
+
+ dw[0] |= GEN_SHIFT32(tmp, GEN6_INST_OPCODE);
+
+ if (ilo_dev_gen(dev) >= ILO_GEN(7) && (compact & GEN6_COMPACT_DEBUGCTRL))
+ dw[0] |= GEN6_INST_DEBUGCTRL;
+
+ /* ControlIndex */
+ tmp = GEN_EXTRACT(compact, GEN6_COMPACT_CONTROL_INDEX);
+ tmp = tbl->control[tmp];
+
+ dw[0] |= (tmp & 0xffff) << GEN6_INST_ACCESSMODE__SHIFT;
+ if (tmp & 0x10000)
+ dw[0] |= GEN6_INST_SATURATE;
+
+ if (ilo_dev_gen(dev) >= ILO_GEN(7))
+ dw[2] |= (tmp >> 17) << GEN6_INST_FLAG_SUBREG__SHIFT;
+
+ /* DataTypeIndex */
+ tmp = GEN_EXTRACT(compact, GEN6_COMPACT_DATATYPE_INDEX);
+ tmp = tbl->datatype[tmp];
+
+ dw[1] |= (tmp & 0x7fff) << GEN6_INST_DST_FILE__SHIFT;
+ dw[1] |= (tmp >> 15) << GEN6_INST_DST_HORZSTRIDE__SHIFT;
+
+ /* SubRegIndex */
+ tmp = GEN_EXTRACT(compact, GEN6_COMPACT_SUBREG_INDEX);
+ tmp = tbl->subreg[tmp];
+
+ dw[1] |= (tmp & 0x1f) << 16;
+ dw[2] |= ((tmp >> 5) & 0x1f);
+ dw[3] |= ((tmp >> 10) & 0x1f);
+
+ if (compact & GEN6_COMPACT_ACCWRCTRL)
+ dw[0] |= GEN6_INST_ACCWRCTRL;
+
+ tmp = GEN_EXTRACT(compact, GEN6_COMPACT_CONDMODIFIER);
+ dw[0] |= GEN_SHIFT32(tmp, GEN6_INST_CONDMODIFIER);
+
+ if (ilo_dev_gen(dev) == ILO_GEN(6)) {
+ tmp = GEN_EXTRACT(compact, GEN6_COMPACT_FLAG_SUBREG);
+ dw[2] |= GEN_SHIFT32(compact, GEN6_INST_FLAG_SUBREG);
+ }
+
+ assert(compact & GEN6_COMPACT_CMPTCTRL);
+
+ /* Src0Index */
+ tmp = GEN_EXTRACT(compact, GEN6_COMPACT_SRC0_INDEX);
+ tmp = tbl->src[tmp];
+ dw[2] |= tmp << 13;
+
+ src_is_imm = (GEN_EXTRACT(dw[1], GEN6_INST_SRC0_FILE) == GEN6_FILE_IMM) ||
+ (GEN_EXTRACT(dw[1], GEN6_INST_SRC1_FILE) == GEN6_FILE_IMM);
+
+ /* Src1Index */
+ tmp = GEN_EXTRACT(compact, GEN6_COMPACT_SRC1_INDEX);
+ if (src_is_imm) {
+ if (tmp & 0x10)
+ tmp |= 0xfffff0;
+ dw[3] |= tmp << 8;
+ } else {
+ tmp = tbl->src[tmp];
+ dw[3] |= tmp << 13;
+ }
+
+ tmp = GEN_EXTRACT(compact, GEN6_COMPACT_DST_REG);
+ dw[1] |= GEN_SHIFT32(tmp, GEN6_INST_DST_REG);
+
+ tmp = GEN_EXTRACT(compact, GEN6_COMPACT_SRC0_REG);
+ dw[2] |= GEN_SHIFT32(tmp, GEN6_INST_SRC_REG);
+
+ tmp = GEN_EXTRACT(compact, GEN6_COMPACT_SRC1_REG);
+ if (src_is_imm)
+ dw[3] |= tmp;
+ else
+ dw[3] |= GEN_SHIFT32(tmp, GEN6_INST_SRC_REG);
+}
+
void
-toy_compiler_disassemble(const struct ilo_dev_info *dev,
+toy_compiler_disassemble(const struct ilo_dev *dev,
const void *kernel, int size,
bool dump_hex)
{
break;
if (compacted) {
- /* no compaction support yet */
- memset(temp, 0, sizeof(temp));
+ const uint64_t compact = (uint64_t) dw[1] << 32 | dw[0];
+ disasm_uncompact(dev, compact, temp);
dw = temp;
}