diff --git a/src/amd/compiler/aco_assembler.cpp b/src/amd/compiler/aco_assembler.cpp index 1500984a121..e54082df9e5 100644 --- a/src/amd/compiler/aco_assembler.cpp +++ b/src/amd/compiler/aco_assembler.cpp @@ -80,6 +80,21 @@ get_mimg_nsa_dwords(const Instruction* instr) return 0; } +unsigned +get_vopd_opy_start(const Instruction* instr) +{ + switch (instr->opcode) { + case aco_opcode::v_dual_fmac_f32: + case aco_opcode::v_dual_fmaak_f32: + case aco_opcode::v_dual_fmamk_f32: + case aco_opcode::v_dual_cndmask_b32: + case aco_opcode::v_dual_dot2acc_f32_f16: + case aco_opcode::v_dual_dot2acc_f32_bf16: return 3; + case aco_opcode::v_dual_mov_b32: return 1; + default: return 2; + } +} + uint32_t reg(asm_context& ctx, PhysReg reg) { @@ -478,16 +493,7 @@ emit_instruction(asm_context& ctx, std::vector& out, Instruction* inst encoding |= opcode << 22; out.push_back(encoding); - unsigned opy_start = instr->opcode == aco_opcode::v_dual_mov_b32 ? 1 : 2; - switch (instr->opcode) { - case aco_opcode::v_dual_fmac_f32: - case aco_opcode::v_dual_fmaak_f32: - case aco_opcode::v_dual_fmamk_f32: - case aco_opcode::v_dual_cndmask_b32: - case aco_opcode::v_dual_dot2acc_f32_f16: - case aco_opcode::v_dual_dot2acc_f32_bf16: opy_start = 3; break; - default: break; - } + unsigned opy_start = get_vopd_opy_start(instr); encoding = reg(ctx, instr->operands[opy_start]); if (vopd.opy != aco_opcode::v_dual_mov_b32) diff --git a/src/amd/compiler/aco_ir.h b/src/amd/compiler/aco_ir.h index bd9bb19a5ac..184b4605da9 100644 --- a/src/amd/compiler/aco_ir.h +++ b/src/amd/compiler/aco_ir.h @@ -1828,6 +1828,8 @@ uint32_t get_reduction_identity(ReduceOp op, unsigned idx); unsigned get_mimg_nsa_dwords(const Instruction* instr); +unsigned get_vopd_opy_start(const Instruction* instr); + unsigned get_operand_size(aco_ptr& instr, unsigned index); bool should_form_clause(const Instruction* a, const Instruction* b); diff --git a/src/amd/compiler/aco_print_ir.cpp b/src/amd/compiler/aco_print_ir.cpp index 5a7ae9d94b9..971fdba5006 100644 --- a/src/amd/compiler/aco_print_ir.cpp +++ b/src/amd/compiler/aco_print_ir.cpp @@ -443,12 +443,6 @@ print_instr_format_specific(enum amd_gfx_level gfx_level, const Instruction* ins fprintf(output, " attr%d.%c", vintrp.attribute, "xyzw"[vintrp.component]); break; } - case Format::VOPD: { - const VOPD_instruction& vopd = instr->vopd(); - // TODO: beautify - fprintf(output, " %s", instr_info.name[(int)vopd.opy]); - break; - } case Format::DS: { const DS_instruction& ds = instr->ds(); if (ds.offset0) @@ -754,10 +748,44 @@ print_instr_format_specific(enum amd_gfx_level gfx_level, const Instruction* ins } } +void +print_vopd_instr(enum amd_gfx_level gfx_level, const Instruction* instr, FILE* output, + unsigned flags) +{ + unsigned opy_start = get_vopd_opy_start(instr); + + if (!instr->definitions.empty()) { + print_definition(&instr->definitions[0], output, flags); + fprintf(output, " = "); + } + fprintf(output, "%s", instr_info.name[(int)instr->opcode]); + for (unsigned i = 0; i < MIN2(instr->operands.size(), opy_start); ++i) { + fprintf(output, i ? ", " : " "); + aco_print_operand(&instr->operands[i], output, flags); + } + + fprintf(output, " ::"); + + if (instr->definitions.size() > 1) { + print_definition(&instr->definitions[1], output, flags); + fprintf(output, " = "); + } + fprintf(output, "%s", instr_info.name[(int)instr->vopd().opy]); + for (unsigned i = opy_start; i < instr->operands.size(); ++i) { + fprintf(output, i > opy_start ? ", " : " "); + aco_print_operand(&instr->operands[i], output, flags); + } +} + void aco_print_instr(enum amd_gfx_level gfx_level, const Instruction* instr, FILE* output, unsigned flags) { + if (instr->isVOPD()) { + print_vopd_instr(gfx_level, instr, output, flags); + return; + } + if (!instr->definitions.empty()) { for (unsigned i = 0; i < instr->definitions.size(); ++i) { print_definition(&instr->definitions[i], output, flags);