Parse Data Parallel Primitive (#4331)

This commit is contained in:
Marcin Mikołajczyk 2026-04-28 21:53:13 +02:00 committed by GitHub
parent 09c20d4636
commit 7755e98a2f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 88 additions and 0 deletions

View File

@ -133,6 +133,7 @@ GcnInst GcnDecodeContext::decodeInstruction(GcnCodeSlice& code) {
if (encodingLen == sizeof(u32)) {
decodeLiteralConstant(encoding, code);
decodeSubDwordAddressing(encoding, code);
decodeDataParallelPrimitive(encoding, code);
}
repairOperandType();
@ -505,6 +506,41 @@ void GcnDecodeContext::decodeSubDwordAddressing(InstEncoding encoding, GcnCodeSl
}
}
void GcnDecodeContext::decodeDataParallelPrimitive(InstEncoding encoding, GcnCodeSlice& code) {
// Find if the instruction contains DPP
if (m_instruction.src[0].field == OperandField::Dpp) {
m_instruction.src[0].code = code.readu32();
m_instruction.length += sizeof(u32);
Dpp dpp = *reinterpret_cast<Dpp*>(&m_instruction.src[0].code);
m_instruction.src[0].field = OperandField::VectorGPR;
m_instruction.src[0].code = dpp.src0;
if (dpp.src0_abs) {
m_instruction.src[0].input_modifier.abs = true;
}
if (dpp.src0_neg) {
m_instruction.src[0].input_modifier.neg = true;
}
if (dpp.src1_abs) {
m_instruction.src[1].input_modifier.abs = true;
}
if (dpp.src1_neg) {
m_instruction.src[1].input_modifier.neg = true;
}
auto op = dpp.GetOperation();
LOG_ERROR(
Render_Recompiler,
"unhandled DPP operation: {} ({:#x}), value {}, bc {}, row_mask {:#b}, bank_mask {:#b}",
magic_enum::enum_name(op.op), u32(op.op), op.value, bool(dpp.bc), u8(dpp.row_mask),
u8(dpp.bank_mask));
m_instruction.src[0].dpp = op;
}
}
void GcnDecodeContext::decodeInstructionSOP1(u32 hexInstruction) {
u32 ssrc0 = bit::extract(hexInstruction, 7, 0);
u32 op = bit::extract(hexInstruction, 15, 8);

View File

@ -71,6 +71,7 @@ private:
void decodeInstruction64(InstEncoding encoding, GcnCodeSlice& code);
void decodeLiteralConstant(InstEncoding encoding, GcnCodeSlice& code);
void decodeSubDwordAddressing(InstEncoding encoding, GcnCodeSlice& code);
void decodeDataParallelPrimitive(InstEncoding encoding, GcnCodeSlice& code);
// 32 bits encodings
void decodeInstructionSOP1(uint32_t hexInstruction);

View File

@ -60,6 +60,23 @@ enum class SdwaDstUnused : u32 {
Invalid = 3,
};
enum class DppCtrl : u16 {
DppQuadPerm = 0,
DppRowShl = 0x101,
DppRowShr = 0x111,
DppRowRor = 0x121,
DppRowMirror = 0x140,
DppRowHalfMirror = 0x141,
};
struct DppOperation {
DppCtrl op;
u16 value;
bool bc;
u8 row_mask;
u8 bank_mask;
};
struct InstOperand {
OperandField field = OperandField::Undefined;
ScalarType type = ScalarType::Undefined;
@ -69,6 +86,7 @@ struct InstOperand {
OperandSelection op_sel = {};
SdwaDstUnused sdwa_dst = SdwaDstUnused::Invalid;
SdwaSelector sdwa_sel = SdwaSelector::Invalid;
std::optional<DppOperation> dpp = {};
u32 code = 0xFFFFFFFF;
};
@ -286,6 +304,39 @@ union Sdwa {
SdwaVop12 vop12;
};
struct Dpp {
u32 src0 : 8;
u32 dpp_ctrl : 9;
u32 : 1;
u32 fi : 1;
u32 bc : 1;
u32 src0_neg : 1;
u32 src0_abs : 1;
u32 src1_neg : 1;
u32 src1_abs : 1;
u32 bank_mask : 4;
u32 row_mask : 4;
DppOperation GetOperation() const {
if (dpp_ctrl >= u32(DppCtrl::DppQuadPerm) && dpp_ctrl < 0x100) {
return {DppCtrl::DppQuadPerm, u16(dpp_ctrl & 0xFF), bool(bc), u8(row_mask),
u8(bank_mask)};
} else if (dpp_ctrl >= u32(DppCtrl::DppRowShl) && dpp_ctrl < 0x110) {
return {DppCtrl::DppRowShl, u16(dpp_ctrl & 0xF), bool(bc), u8(row_mask), u8(bank_mask)};
} else if (dpp_ctrl >= u32(DppCtrl::DppRowShr) && dpp_ctrl < 0x120) {
return {DppCtrl::DppRowShr, u16(dpp_ctrl & 0xF), bool(bc), u8(row_mask), u8(bank_mask)};
} else if (dpp_ctrl >= u32(DppCtrl::DppRowRor) && dpp_ctrl < 0x130) {
return {DppCtrl::DppRowRor, u16(dpp_ctrl & 0xF), bool(bc), u8(row_mask), u8(bank_mask)};
} else if (dpp_ctrl == u32(DppCtrl::DppRowMirror)) {
return {DppCtrl::DppRowMirror, 0, bool(bc), u8(row_mask), u8(bank_mask)};
} else if (dpp_ctrl == u32(DppCtrl::DppRowHalfMirror)) {
return {DppCtrl::DppRowHalfMirror, 0, bool(bc), u8(row_mask), u8(bank_mask)};
} else {
UNREACHABLE_MSG("malformed dpp_ctrl");
}
}
};
struct GcnInst {
Opcode opcode;
InstEncoding encoding;