aco: use v_interp_p2_f16 opsel

Reviewed-by: Rhys Perry <pendingchaos02@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28435>
This commit is contained in:
Georg Lehmann
2024-04-06 11:07:37 +02:00
committed by Marge Bot
parent d15ca421c4
commit e2cb9c57a2
6 changed files with 20 additions and 4 deletions
+6 -1
View File
@@ -369,7 +369,8 @@ emit_vintrp_instruction(asm_context& ctx, std::vector<uint32_t>& out, Instructio
if (instr->opcode == aco_opcode::v_interp_p1ll_f16 ||
instr->opcode == aco_opcode::v_interp_p1lv_f16 ||
instr->opcode == aco_opcode::v_interp_p2_legacy_f16 ||
instr->opcode == aco_opcode::v_interp_p2_f16) {
instr->opcode == aco_opcode::v_interp_p2_f16 ||
instr->opcode == aco_opcode::v_interp_p2_hi_f16) {
if (ctx.gfx_level == GFX8 || ctx.gfx_level == GFX9) {
encoding = (0b110100 << 26);
} else if (ctx.gfx_level >= GFX10) {
@@ -378,7 +379,10 @@ emit_vintrp_instruction(asm_context& ctx, std::vector<uint32_t>& out, Instructio
unreachable("Unknown gfx_level.");
}
unsigned opsel = instr->opcode == aco_opcode::v_interp_p2_hi_f16 ? 0x8 : 0;
encoding |= opcode << 16;
encoding |= opsel << 11;
encoding |= reg(ctx, instr->definitions[0], 8);
out.push_back(encoding);
@@ -388,6 +392,7 @@ emit_vintrp_instruction(asm_context& ctx, std::vector<uint32_t>& out, Instructio
encoding |= interp.high_16bits << 8;
encoding |= reg(ctx, instr->operands[0]) << 9;
if (instr->opcode == aco_opcode::v_interp_p2_f16 ||
instr->opcode == aco_opcode::v_interp_p2_hi_f16 ||
instr->opcode == aco_opcode::v_interp_p2_legacy_f16 ||
instr->opcode == aco_opcode::v_interp_p1lv_f16) {
encoding |= reg(ctx, instr->operands[2]) << 18;
+1
View File
@@ -595,6 +595,7 @@ instr_is_16bit(amd_gfx_level gfx_level, aco_opcode op)
case aco_opcode::v_fma_legacy_f16:
case aco_opcode::v_div_fixup_legacy_f16: return false;
case aco_opcode::v_interp_p2_f16:
case aco_opcode::v_interp_p2_hi_f16:
case aco_opcode::v_fma_mixlo_f16:
case aco_opcode::v_fma_mixhi_f16:
/* VOP2 */
+4
View File
@@ -1205,6 +1205,7 @@ VOP3 = {
("v_interp_p1lv_f16", True, True, dst(1), src(1, M0, 1), op(gfx8=0x275, gfx10=0x343, gfx11=-1)),
("v_interp_p2_legacy_f16", True, True, dst(1), src(1, M0, 1), op(gfx8=0x276, gfx10=-1)),
("v_interp_p2_f16", True, True, dst(1), src(1, M0, 1), op(gfx9=0x277, gfx10=0x35a, gfx11=-1)),
("v_interp_p2_hi_f16", True, True, dst(1), src(1, M0, 1), op(gfx9=0x277, gfx10=0x35a, gfx11=-1)),
("v_ldexp_f32", False, True, dst(1), src(1, 1), op(0x12b, gfx8=0x288, gfx10=0x362, gfx11=0x31c)),
("v_readlane_b32_e64", False, False, dst(1), src(1, 1), op(gfx8=0x289, gfx10=0x360)),
("v_writelane_b32_e64", False, False, dst(1), src(1, 1, 1), op(gfx8=0x28a, gfx10=0x361)),
@@ -1862,6 +1863,9 @@ for ver in Opcode._fields:
# v_mac_legacy_f32 is replaced with v_fmac_legacy_f32 on GFX10.3
if ver == 'gfx10' and names == set(['v_mac_legacy_f32', 'v_fmac_legacy_f32']):
continue
# These are the same opcodes, but hi uses opsel
if names == set(['v_interp_p2_f16', 'v_interp_p2_hi_f16']):
continue
print('%s and %s share the same opcode number (%s)' % (op_to_name[key], inst.name, ver))
sys.exit(1)
+1
View File
@@ -623,6 +623,7 @@ can_apply_sgprs(opt_ctx& ctx, aco_ptr<Instruction>& instr)
instr->opcode != aco_opcode::v_interp_p1lv_f16 &&
instr->opcode != aco_opcode::v_interp_p2_legacy_f16 &&
instr->opcode != aco_opcode::v_interp_p2_f16 &&
instr->opcode != aco_opcode::v_interp_p2_hi_f16 &&
instr->opcode != aco_opcode::v_interp_p10_f32_inreg &&
instr->opcode != aco_opcode::v_interp_p2_f32_inreg &&
instr->opcode != aco_opcode::v_interp_p10_f16_f32_inreg &&
+4 -1
View File
@@ -617,7 +617,7 @@ get_subdword_definition_info(Program* program, const aco_ptr<Instruction>& instr
return std::make_pair(4, rc.size() * 4u);
}
if (instr->isVALU() || instr->isVINTRP()) {
if (instr->isVALU()) {
assert(rc.bytes() <= 2);
if (can_use_SDWA(gfx_level, instr, false))
@@ -636,6 +636,7 @@ get_subdword_definition_info(Program* program, const aco_ptr<Instruction>& instr
}
switch (instr->opcode) {
case aco_opcode::v_interp_p2_f16: return std::make_pair(2u, 2u);
/* D16 loads with _hi version */
case aco_opcode::ds_read_u8_d16:
case aco_opcode::ds_read_i8_d16:
@@ -715,6 +716,8 @@ add_subdword_definition(Program* program, aco_ptr<Instruction>& instr, PhysReg r
if (reg.byte() == 0)
return;
else if (instr->opcode == aco_opcode::v_interp_p2_f16)
instr->opcode = aco_opcode::v_interp_p2_hi_f16;
else if (instr->opcode == aco_opcode::buffer_load_ubyte_d16)
instr->opcode = aco_opcode::buffer_load_ubyte_d16_hi;
else if (instr->opcode == aco_opcode::buffer_load_sbyte_d16)
+4 -2
View File
@@ -195,7 +195,8 @@ validate_ir(Program* program)
if (instr->opcode == aco_opcode::v_interp_p1ll_f16 ||
instr->opcode == aco_opcode::v_interp_p1lv_f16 ||
instr->opcode == aco_opcode::v_interp_p2_legacy_f16 ||
instr->opcode == aco_opcode::v_interp_p2_f16) {
instr->opcode == aco_opcode::v_interp_p2_f16 ||
instr->opcode == aco_opcode::v_interp_p2_hi_f16) {
/* v_interp_*_fp16 are considered VINTRP by the compiler but
* they are emitted as VOP3.
*/
@@ -1067,6 +1068,7 @@ validate_subdword_definition(amd_gfx_level gfx_level, const aco_ptr<Instruction>
return true;
switch (instr->opcode) {
case aco_opcode::v_interp_p2_hi_f16:
case aco_opcode::v_fma_mixhi_f16:
case aco_opcode::buffer_load_ubyte_d16_hi:
case aco_opcode::buffer_load_sbyte_d16_hi:
@@ -1094,7 +1096,7 @@ get_subdword_bytes_written(Program* program, const aco_ptr<Instruction>& instr,
if (instr->isPseudo())
return gfx_level >= GFX8 ? def.bytes() : def.size() * 4u;
if (instr->isVALU()) {
if (instr->isVALU() || instr->isVINTRP()) {
assert(def.bytes() <= 2);
if (instr->isSDWA())
return instr->sdwa().dst_sel.size();