};
struct disasm_inst {
- const struct ilo_dev_info *dev;
+ const struct ilo_dev *dev;
unsigned has_jip:1;
unsigned has_uip: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;
};
};
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);
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);
break;
}
- if (ilo_dev_gen(inst->dev) >= ILO_GEN(8)) {
- switch (inst->opcode) {
- case GEN6_OPCODE_IF:
- case GEN6_OPCODE_ELSE:
- case GEN8_OPCODE_GOTO:
+ 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;
}
- } else {
+ default:
inst->acc_wr_ctrl = (bool) (dw0 & GEN6_INST_ACCWRCTRL);
+ break;
}
inst->cmpt_ctrl = (bool) (dw0 & GEN6_INST_CMPTCTRL);
inst->saturate = (bool) (dw0 & GEN6_INST_SATURATE);
}
-static bool
-disasm_inst_jip_in_dw1_high_gen6(const struct disasm_inst *inst)
+static void
+disasm_inst_decode_dw1_low_gen6(struct disasm_inst *inst, uint32_t dw1)
{
- return (ilo_dev_gen(inst->dev) == ILO_GEN(6) &&
- inst->has_jip && !inst->has_uip);
+ 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->src0.base.type = GEN_EXTRACT(dw1, GEN6_INST_SRC0_TYPE);
+ inst->src1.base.file = GEN_EXTRACT(dw1, GEN6_INST_SRC1_FILE);
+ inst->src1.base.type = GEN_EXTRACT(dw1, GEN6_INST_SRC1_TYPE);
+
+ if (ilo_dev_gen(inst->dev) >= ILO_GEN(7))
+ inst->nib_ctrl = (bool) (dw1 & GEN7_INST_NIBCTRL);
}
static void
-disasm_inst_decode_dw1_gen6(struct disasm_inst *inst, uint32_t dw1)
+disasm_inst_decode_dw1_low_gen8(struct disasm_inst *inst, uint32_t dw1)
{
- ILO_DEV_ASSERT(inst->dev, 6, 8);
+ ILO_DEV_ASSERT(inst->dev, 8, 8);
- if (ilo_dev_gen(inst->dev) >= ILO_GEN(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);
- } else {
- 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->src0.base.type = GEN_EXTRACT(dw1, GEN6_INST_SRC0_TYPE);
- inst->src1.base.file = GEN_EXTRACT(dw1, GEN6_INST_SRC1_FILE);
- inst->src1.base.type = GEN_EXTRACT(dw1, GEN6_INST_SRC1_TYPE);
+ 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);
- if (ilo_dev_gen(inst->dev) >= ILO_GEN(7))
- inst->nib_ctrl = (bool) (dw1 & GEN7_INST_NIBCTRL);
- }
+ 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);
- if (disasm_inst_jip_in_dw1_high_gen6(inst)) {
- inst->u.imm32 = dw1 >> 16;
- return;
- }
+ 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);
inst->dst.base.addr_subreg =
GEN_EXTRACT(dw1, GEN8_INST_DST_ADDR_SUBREG);
+ /* bit 9 is already set in disasm_inst_decode_dw1_low_gen8() */
if (inst->access_mode == GEN6_ALIGN_1) {
- inst->dst.base.addr_imm =
+ 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) <<
+ inst->dst.base.addr_imm |=
+ GEN_EXTRACT(dw1, GEN8_INST_DST_ADDR_IMM_ALIGN16) <<
GEN8_INST_DST_ADDR_IMM_ALIGN16__SHR;
}
-
- inst->dst.base.addr_imm |= GEN_EXTRACT(dw1,
- GEN8_INST_DST_ADDR_IMM_BIT9) <<
- GEN8_INST_DST_ADDR_IMM_BIT9__SHR;
} else {
inst->dst.base.addr_subreg =
GEN_EXTRACT(dw1, GEN6_INST_DST_ADDR_SUBREG);
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) <<
+ 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;
ILO_DEV_ASSERT(inst->dev, 6, 8);
if (ilo_dev_gen(inst->dev) >= ILO_GEN(8)) {
- inst->src1.base.file = GEN_EXTRACT(dw2, GEN8_INST_SRC1_FILE);
- inst->src1.base.type = GEN_EXTRACT(dw2, GEN8_INST_SRC1_TYPE);
+ /* 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)
+ 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;
}
- if (inst->src0.base.file == GEN6_FILE_IMM ||
- inst->src1.base.file == GEN6_FILE_IMM) {
+ switch (imm_bits) {
+ case 32:
+ inst->u.imm64 = dw3;
count = 1;
- if (!disasm_inst_jip_in_dw1_high_gen6(inst))
- inst->u.imm32 = dw3;
- } else {
+ break;
+ case 64:
+ inst->u.imm64 = (uint64_t) dw2 << 32 | dw3;
+ count = 0;
+ break;
+ default:
count = 2;
+ break;
}
for (i = 0; i < count; i++) {
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 "";
}
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");
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);
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;
}
static void
-disasm_uncompact_3src(const struct ilo_dev_info *dev,
+disasm_uncompact_3src(const struct ilo_dev *dev,
uint64_t compact, uint32_t *dw)
{
const struct toy_compaction_table *tbl =
}
static void
-disasm_uncompact(const struct ilo_dev_info *dev,
+disasm_uncompact(const struct ilo_dev *dev,
uint64_t compact, uint32_t *dw)
{
const struct toy_compaction_table *tbl =
}
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)
{