i965: Add support for compacting 3-src instructions on Gen8.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
Matt Turner 2014-06-15 11:29:22 -07:00
parent fb1db6753f
commit 31eed95b22
1 changed files with 185 additions and 0 deletions

View File

@ -611,6 +611,97 @@ set_src1_index(struct brw_context *brw, brw_compact_inst *dst, brw_inst *src,
return true;
}
static bool
set_3src_control_index(struct brw_context *brw, brw_compact_inst *dst, brw_inst *src)
{
assert(brw->gen >= 8);
uint32_t uncompacted = /* 24b/BDW; 26b/CHV */
(brw_inst_bits(src, 34, 32) << 21) | /* 3b */
(brw_inst_bits(src, 28, 8)); /* 21b */
if (brw->is_cherryview)
uncompacted |= brw_inst_bits(src, 36, 35) << 24; /* 2b */
for (int i = 0; i < ARRAY_SIZE(gen8_3src_control_index_table); i++) {
if (gen8_3src_control_index_table[i] == uncompacted) {
brw_compact_inst_set_3src_control_index(dst, i);
return true;
}
}
return false;
}
static bool
set_3src_source_index(struct brw_context *brw, brw_compact_inst *dst, brw_inst *src)
{
assert(brw->gen >= 8);
uint64_t uncompacted = /* 46b/BDW; 49b/CHV */
(brw_inst_bits(src, 83, 83) << 43) | /* 1b */
(brw_inst_bits(src, 114, 107) << 35) | /* 8b */
(brw_inst_bits(src, 93, 86) << 27) | /* 8b */
(brw_inst_bits(src, 72, 65) << 19) | /* 8b */
(brw_inst_bits(src, 55, 37)); /* 19b */
if (brw->is_cherryview) {
uncompacted |=
(brw_inst_bits(src, 126, 125) << 47) | /* 2b */
(brw_inst_bits(src, 105, 104) << 45) | /* 2b */
(brw_inst_bits(src, 84, 84) << 44); /* 1b */
} else {
uncompacted |=
(brw_inst_bits(src, 125, 125) << 45) | /* 1b */
(brw_inst_bits(src, 104, 104) << 44); /* 1b */
}
for (int i = 0; i < ARRAY_SIZE(gen8_3src_source_index_table); i++) {
if (gen8_3src_source_index_table[i] == uncompacted) {
brw_compact_inst_set_3src_source_index(dst, i);
return true;
}
}
return false;
}
static bool
brw_try_compact_3src_instruction(struct brw_context *brw, brw_compact_inst *dst,
brw_inst *src)
{
assert(brw->gen >= 8);
#define compact(field) \
brw_compact_inst_set_3src_##field(dst, brw_inst_3src_##field(brw, src))
compact(opcode);
if (!set_3src_control_index(brw, dst, src))
return false;
if (!set_3src_source_index(brw, dst, src))
return false;
compact(dst_reg_nr);
compact(src0_rep_ctrl);
brw_compact_inst_set_3src_cmpt_control(dst, true);
compact(debug_control);
compact(saturate);
compact(src1_rep_ctrl);
compact(src2_rep_ctrl);
compact(src0_reg_nr);
compact(src1_reg_nr);
compact(src2_reg_nr);
compact(src0_subreg_nr);
compact(src1_subreg_nr);
compact(src2_subreg_nr);
#undef compact
return true;
}
/* Compacted instructions have 12-bits for immediate sources, and a 13th bit
* that's replicated through the high 20 bits.
*
@ -627,6 +718,13 @@ is_compactable_immediate(unsigned imm)
return imm == 0 || imm == 0xfffff000;
}
/* Returns whether an opcode takes three sources. */
static bool
is_3src(uint32_t op)
{
return opcode_descs[op].nsrc == 3;
}
/**
* Tries to compact instruction src into dst.
*
@ -651,6 +749,16 @@ brw_try_compact_instruction(struct brw_context *brw, brw_compact_inst *dst,
return false;
}
if (brw->gen >= 8 && is_3src(brw_inst_opcode(brw, src))) {
memset(&temp, 0, sizeof(temp));
if (brw_try_compact_3src_instruction(brw, &temp, src)) {
*dst = temp;
return true;
} else {
return false;
}
}
bool is_immediate =
brw_inst_src0_reg_file(brw, src) == BRW_IMMEDIATE_VALUE ||
brw_inst_src1_reg_file(brw, src) == BRW_IMMEDIATE_VALUE;
@ -767,12 +875,89 @@ set_uncompacted_src1(struct brw_context *brw, brw_inst *dst,
}
}
static void
set_uncompacted_3src_control_index(struct brw_context *brw, brw_inst *dst,
brw_compact_inst *src)
{
assert(brw->gen >= 8);
uint32_t compacted = brw_compact_inst_3src_control_index(src);
uint32_t uncompacted = gen8_3src_control_index_table[compacted];
brw_inst_set_bits(dst, 34, 32, (uncompacted >> 21) & 0x7);
brw_inst_set_bits(dst, 28, 8, (uncompacted >> 0) & 0x1fffff);
if (brw->is_cherryview)
brw_inst_set_bits(dst, 36, 35, (uncompacted >> 24) & 0x3);
}
static void
set_uncompacted_3src_source_index(struct brw_context *brw, brw_inst *dst,
brw_compact_inst *src)
{
assert(brw->gen >= 8);
uint32_t compacted = brw_compact_inst_3src_source_index(src);
uint64_t uncompacted = gen8_3src_source_index_table[compacted];
brw_inst_set_bits(dst, 83, 83, (uncompacted >> 43) & 0x1);
brw_inst_set_bits(dst, 114, 107, (uncompacted >> 35) & 0xff);
brw_inst_set_bits(dst, 93, 86, (uncompacted >> 27) & 0xff);
brw_inst_set_bits(dst, 72, 65, (uncompacted >> 19) & 0xff);
brw_inst_set_bits(dst, 55, 37, (uncompacted >> 0) & 0x7ffff);
if (brw->is_cherryview) {
brw_inst_set_bits(dst, 126, 125, (uncompacted >> 47) & 0x3);
brw_inst_set_bits(dst, 105, 104, (uncompacted >> 45) & 0x3);
brw_inst_set_bits(dst, 84, 84, (uncompacted >> 44) & 0x1);
} else {
brw_inst_set_bits(dst, 125, 125, (uncompacted >> 45) & 0x1);
brw_inst_set_bits(dst, 104, 104, (uncompacted >> 44) & 0x1);
}
}
static void
brw_uncompact_3src_instruction(struct brw_context *brw, brw_inst *dst,
brw_compact_inst *src)
{
assert(brw->gen >= 8);
#define uncompact(field) \
brw_inst_set_3src_##field(brw, dst, brw_compact_inst_3src_##field(src))
uncompact(opcode);
set_uncompacted_3src_control_index(brw, dst, src);
set_uncompacted_3src_source_index(brw, dst, src);
uncompact(dst_reg_nr);
uncompact(src0_rep_ctrl);
brw_inst_set_3src_cmpt_control(brw, dst, false);
uncompact(debug_control);
uncompact(saturate);
uncompact(src1_rep_ctrl);
uncompact(src2_rep_ctrl);
uncompact(src0_reg_nr);
uncompact(src1_reg_nr);
uncompact(src2_reg_nr);
uncompact(src0_subreg_nr);
uncompact(src1_subreg_nr);
uncompact(src2_subreg_nr);
#undef uncompact
}
void
brw_uncompact_instruction(struct brw_context *brw, brw_inst *dst,
brw_compact_inst *src)
{
memset(dst, 0, sizeof(*dst));
if (brw->gen >= 8 && is_3src(brw_compact_inst_3src_opcode(src))) {
brw_uncompact_3src_instruction(brw, dst, src);
return;
}
brw_inst_set_opcode(brw, dst, brw_compact_inst_opcode(src));
brw_inst_set_debug_control(brw, dst, brw_compact_inst_debug_control(src));