shader: handle disabled RDNA2 traps

This commit is contained in:
nmzik
2026-08-15 05:02:31 +02:00
parent 00bd19194a
commit 09fec6815f
5 changed files with 53 additions and 19 deletions
@@ -74,7 +74,8 @@ constexpr OpcodeMap SOPP_OPS[] = {
{0x04u, Opcode::SCbranchScc0}, {0x05u, Opcode::SCbranchScc1}, {0x06u, Opcode::SCbranchVccz},
{0x07u, Opcode::SCbranchVccnz}, {0x08u, Opcode::SCbranchExecz}, {0x09u, Opcode::SCbranchExecnz},
{0x0au, Opcode::SBarrier}, {0x0cu, Opcode::SWaitcnt}, {0x0eu, Opcode::SSleep},
{0x10u, Opcode::SSendmsg}, {0x16u, Opcode::STtraceData}, {0x20u, Opcode::SInstPrefetch},
{0x10u, Opcode::SSendmsg}, {0x12u, Opcode::STrap}, {0x16u, Opcode::STtraceData},
{0x20u, Opcode::SInstPrefetch},
};
static_assert(Detail::HasUniqueEncodings(SOP1_OPS));
static_assert(Detail::HasUniqueEncodings(SOP2_OPS));
@@ -257,15 +258,18 @@ bool DecodeSopp(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
inst.opcode_id = opcode;
inst.opcode = Detail::LookupOpcode(SOPP_OPS, opcode);
inst.src0.kind = OperandKind::LiteralConstant;
inst.src0.value = simm;
inst.src0.signed_val = static_cast<int16_t>(simm);
inst.src_count = (inst.opcode == Opcode::SNop || inst.opcode == Opcode::SWaitcnt ||
inst.opcode == Opcode::SSleep || inst.opcode == Opcode::SSendmsg ||
inst.opcode == Opcode::STtraceData || inst.opcode == Opcode::SInstPrefetch)
? 1
: 0;
inst.branch_offset = static_cast<int32_t>(static_cast<int16_t>(simm)) * 4;
inst.branch_target = pc + 4u + static_cast<uint32_t>(inst.branch_offset);
inst.src0.value = inst.opcode == Opcode::STrap ? simm & 0xffu : simm;
inst.src0.signed_val = inst.opcode == Opcode::STrap
? static_cast<int32_t>(inst.src0.value)
: static_cast<int32_t>(static_cast<int16_t>(simm));
inst.src_count = (inst.opcode == Opcode::SNop || inst.opcode == Opcode::SWaitcnt ||
inst.opcode == Opcode::SSleep || inst.opcode == Opcode::SSendmsg ||
inst.opcode == Opcode::STrap || inst.opcode == Opcode::STtraceData ||
inst.opcode == Opcode::SInstPrefetch)
? 1
: 0;
inst.branch_offset = static_cast<int32_t>(static_cast<int16_t>(simm)) * 4;
inst.branch_target = pc + 4u + static_cast<uint32_t>(inst.branch_offset);
SetRawWords(inst, code, word_index, 1);
if (inst.opcode == Opcode::Unsupported) {
@@ -937,6 +937,7 @@ std::string OpcodeToString(Opcode opcode) {
case Opcode::SSendmsg: return "s_sendmsg";
case Opcode::SSetregB32: return "s_setreg_b32";
case Opcode::SSleep: return "s_sleep";
case Opcode::STrap: return "s_trap";
case Opcode::STtraceData: return "s_ttracedata";
case Opcode::SInstPrefetch: return "s_inst_prefetch";
case Opcode::SEndpgm: return "s_endpgm";
@@ -1039,6 +1040,7 @@ std::string InstructionToString(const Instruction& inst) {
case Opcode::SNop:
case Opcode::SWaitcnt:
case Opcode::SSleep:
case Opcode::STrap:
case Opcode::SSendmsg:
case Opcode::STtraceData:
case Opcode::SInstPrefetch:
@@ -537,6 +537,7 @@ enum class Opcode {
SSendmsg,
SSetregB32,
SSleep,
STrap,
STtraceData,
SInstPrefetch,
SEndpgm,
@@ -1000,6 +1000,9 @@ bool LowerControlInstruction(const Decoder::Instruction& decoded, BasicBlock& bl
case Decoder::Opcode::SSetregB32:
case Decoder::Opcode::SSleep:
return LowerControlMarker(decoded, block, Opcode::ControlNop, true, error);
case Decoder::Opcode::STrap:
// RDNA2 converts S_TRAP to a NOP when the unmodeled trap state is disabled.
return LowerControlMarker(decoded, block, Opcode::ControlNop, true, error);
case Decoder::Opcode::STtraceData:
return LowerControlMarker(decoded, block, Opcode::TtraceData, true, error);
case Decoder::Opcode::SInstPrefetch:
@@ -1076,6 +1079,7 @@ bool IsControlOpcode(Decoder::Opcode opcode) {
case Decoder::Opcode::SSendmsg:
case Decoder::Opcode::SSetregB32:
case Decoder::Opcode::SSleep:
case Decoder::Opcode::STrap:
case Decoder::Opcode::STtraceData:
case Decoder::Opcode::SInstPrefetch: return true;
default: return false;