shader: use ISA-style decoder opcode names

This commit is contained in:
nmzik committed 2026-08-18 03:53:45 +02:00
1 parent 4220a747cb
commit 377fb8f50a
15 files changed
+3294 -3755

No files matched your search

@@ -227,19 +227,19 @@ uint32_t DecodedDstSize(const Decoder::Instruction& inst) {
} }
uint32_t EmbeddedFetchDstSize(const Decoder::Instruction& inst) { uint32_t EmbeddedFetchDstSize(const Decoder::Instruction& inst) {
return inst.opcode == Decoder::Opcode::VMadU64U32 ? 2u : DecodedDstSize(inst); return inst.opcode == Decoder::Opcode::V_MAD_U64_U32 ? 2u : DecodedDstSize(inst);
} }
bool EmbeddedFetchHasBranch(Decoder::Opcode opcode) { bool EmbeddedFetchHasBranch(Decoder::Opcode opcode) {
switch (opcode) { switch (opcode) {
case Decoder::Opcode::SSetpcB64: case Decoder::Opcode::S_SETPC_B64:
case Decoder::Opcode::SBranch: case Decoder::Opcode::S_BRANCH:
case Decoder::Opcode::SCbranchScc0: case Decoder::Opcode::S_CBRANCH_SCC0:
case Decoder::Opcode::SCbranchScc1: case Decoder::Opcode::S_CBRANCH_SCC1:
case Decoder::Opcode::SCbranchVccz: case Decoder::Opcode::S_CBRANCH_VCCZ:
case Decoder::Opcode::SCbranchVccnz: case Decoder::Opcode::S_CBRANCH_VCCNZ:
case Decoder::Opcode::SCbranchExecz: case Decoder::Opcode::S_CBRANCH_EXECZ:
case Decoder::Opcode::SCbranchExecnz: return true; case Decoder::Opcode::S_CBRANCH_EXECNZ: return true;
default: return false; default: return false;
} }
} }
@@ -288,32 +288,32 @@ bool TryDecodedSmemOffset(const std::array<EmbeddedFetchSgprInfo, 108>& sgprs,
bool IsEmbeddedFetchSLoad(const Decoder::Instruction& inst) { bool IsEmbeddedFetchSLoad(const Decoder::Instruction& inst) {
switch (inst.opcode) { switch (inst.opcode) {
case Decoder::Opcode::SLoadDword: case Decoder::Opcode::S_LOAD_DWORD:
case Decoder::Opcode::SLoadDwordx2: case Decoder::Opcode::S_LOAD_DWORDX2:
case Decoder::Opcode::SLoadDwordx4: case Decoder::Opcode::S_LOAD_DWORDX4:
case Decoder::Opcode::SLoadDwordx8: case Decoder::Opcode::S_LOAD_DWORDX8:
case Decoder::Opcode::SLoadDwordx16: return true; case Decoder::Opcode::S_LOAD_DWORDX16: return true;
default: return false; default: return false;
} }
} }
bool IsEmbeddedFetchBufferLoad(const Decoder::Instruction& inst) { bool IsEmbeddedFetchBufferLoad(const Decoder::Instruction& inst) {
switch (inst.opcode) { switch (inst.opcode) {
case Decoder::Opcode::BufferLoadFormatX: case Decoder::Opcode::BUFFER_LOAD_FORMAT_X:
case Decoder::Opcode::BufferLoadFormatXy: case Decoder::Opcode::BUFFER_LOAD_FORMAT_XY:
case Decoder::Opcode::BufferLoadFormatXyz: case Decoder::Opcode::BUFFER_LOAD_FORMAT_XYZ:
case Decoder::Opcode::BufferLoadFormatXyzw: return true; case Decoder::Opcode::BUFFER_LOAD_FORMAT_XYZW: return true;
default: return false; default: return false;
} }
} }
bool IsEmbeddedFetchAttribPropagationAlu(const Decoder::Instruction& inst) { bool IsEmbeddedFetchAttribPropagationAlu(const Decoder::Instruction& inst) {
switch (inst.opcode) { switch (inst.opcode) {
case Decoder::Opcode::SBfeU32: case Decoder::Opcode::S_BFE_U32:
case Decoder::Opcode::SAndB32: case Decoder::Opcode::S_AND_B32:
case Decoder::Opcode::SAddI32: case Decoder::Opcode::S_ADD_I32:
case Decoder::Opcode::SAddU32: case Decoder::Opcode::S_ADD_U32:
case Decoder::Opcode::SLshlB32: return true; case Decoder::Opcode::S_LSHL_B32: return true;
default: return false; default: return false;
} }
} }
@@ -373,10 +373,11 @@ EmbeddedFetchData DetectEmbeddedVertexFetch(const Decoder::Program& decoded
uint32_t sad_zero = 0; uint32_t sad_zero = 0;
const bool vertex_offset_add = const bool vertex_offset_add =
vertex_index_accumulator && IsDecodedSgpr(inst.src0) && vertex_index_accumulator && IsDecodedSgpr(inst.src0) &&
((inst.opcode == Decoder::Opcode::VAddI32 && IsDecodedVgpr(inst.src1) && ((inst.opcode == Decoder::Opcode::V_ADD_I32 && IsDecodedVgpr(inst.src1) &&
inst.src1.reg == inst.dst.reg) || inst.src1.reg == inst.dst.reg) ||
(user_data_base == 8 && inst.dst.reg == 5 && inst.opcode == Decoder::Opcode::VSadU32 && (user_data_base == 8 && inst.dst.reg == 5 &&
IsDecodedVgpr(inst.src2) && inst.src2.reg == inst.dst.reg && inst.opcode == Decoder::Opcode::V_SAD_U32 && IsDecodedVgpr(inst.src2) &&
inst.src2.reg == inst.dst.reg &&
TryDecodedOperandConstant(sgprs, inst.src1, sad_zero) && sad_zero == 0)); TryDecodedOperandConstant(sgprs, inst.src1, sad_zero) && sad_zero == 0));
if (data.loads.empty() && vertex_offset_add) { if (data.loads.empty() && vertex_offset_add) {
const auto reg = DecodedSgprReg(inst.src0); const auto reg = DecodedSgprReg(inst.src0);
@@ -389,7 +390,7 @@ EmbeddedFetchData DetectEmbeddedVertexFetch(const Decoder::Program& decoded
} }
} }
switch (inst.opcode) { switch (inst.opcode) {
case Decoder::Opcode::VWritelaneB32: { case Decoder::Opcode::V_WRITELANE_B32: {
uint32_t lane = 0; uint32_t lane = 0;
if (IsDecodedVgpr(inst.dst) && inst.dst.reg < vgprs.size()) { if (IsDecodedVgpr(inst.dst) && inst.dst.reg < vgprs.size()) {
vgprs[inst.dst.reg] = {}; vgprs[inst.dst.reg] = {};
@@ -405,7 +406,7 @@ EmbeddedFetchData DetectEmbeddedVertexFetch(const Decoder::Program& decoded
} }
break; break;
} }
case Decoder::Opcode::VReadlaneB32: { case Decoder::Opcode::V_READLANE_B32: {
uint32_t lane = 0; uint32_t lane = 0;
if (track_vector_lanes && IsDecodedSgpr(inst.dst) && if (track_vector_lanes && IsDecodedSgpr(inst.dst) &&
DecodedSgprReg(inst.dst) < sgprs.size() && IsDecodedVgpr(inst.src0) && DecodedSgprReg(inst.dst) < sgprs.size() && IsDecodedVgpr(inst.src0) &&
@@ -419,7 +420,7 @@ EmbeddedFetchData DetectEmbeddedVertexFetch(const Decoder::Program& decoded
} }
break; break;
} }
case Decoder::Opcode::SMovB32: case Decoder::Opcode::S_MOV_B32:
if (IsDecodedSgpr(inst.dst) && IsDecodedSgpr(inst.src0) && if (IsDecodedSgpr(inst.dst) && IsDecodedSgpr(inst.src0) &&
DecodedSgprReg(inst.src0) < sgprs.size()) { DecodedSgprReg(inst.src0) < sgprs.size()) {
sgprs[DecodedSgprReg(inst.dst)] = sgprs[DecodedSgprReg(inst.src0)]; sgprs[DecodedSgprReg(inst.dst)] = sgprs[DecodedSgprReg(inst.src0)];
@@ -435,7 +436,7 @@ EmbeddedFetchData DetectEmbeddedVertexFetch(const Decoder::Program& decoded
} }
} }
break; break;
case Decoder::Opcode::SMovkI32: case Decoder::Opcode::S_MOVK_I32:
if (IsDecodedSgpr(inst.dst)) { if (IsDecodedSgpr(inst.dst)) {
auto& dst = sgprs[DecodedSgprReg(inst.dst)]; auto& dst = sgprs[DecodedSgprReg(inst.dst)];
dst.type = EmbeddedFetchValueType::Constant; dst.type = EmbeddedFetchValueType::Constant;
@@ -496,7 +497,7 @@ EmbeddedFetchData DetectEmbeddedVertexFetch(const Decoder::Program& decoded
} else { } else {
ClearEmbeddedFetchSgprs(sgprs, inst.dst, DecodedDstSize(inst)); ClearEmbeddedFetchSgprs(sgprs, inst.dst, DecodedDstSize(inst));
} }
} else if (inst.opcode == Decoder::Opcode::VCndmaskB32) { } else if (inst.opcode == Decoder::Opcode::V_CNDMASK_B32) {
if (IsDecodedVgpr(inst.dst) && inst.dst.reg < vgprs.size()) { if (IsDecodedVgpr(inst.dst) && inst.dst.reg < vgprs.size()) {
ClearEmbeddedFetchVectorLanes(&vector_lanes, inst.dst.reg); ClearEmbeddedFetchVectorLanes(&vector_lanes, inst.dst.reg);
} }
@@ -518,11 +519,11 @@ EmbeddedFetchData DetectEmbeddedVertexFetch(const Decoder::Program& decoded
auto& dst = sgprs[DecodedSgprReg(inst.dst)]; auto& dst = sgprs[DecodedSgprReg(inst.dst)];
dst.type = EmbeddedFetchValueType::Constant; dst.type = EmbeddedFetchValueType::Constant;
switch (inst.opcode) { switch (inst.opcode) {
case Decoder::Opcode::SAndB32: dst.value = src0 & src1; break; case Decoder::Opcode::S_AND_B32: dst.value = src0 & src1; break;
case Decoder::Opcode::SLshlB32: case Decoder::Opcode::S_LSHL_B32:
dst.value = src0 << (src1 & 31u); dst.value = src0 << (src1 & 31u);
break; break;
case Decoder::Opcode::SBfeU32: case Decoder::Opcode::S_BFE_U32:
dst.value = src0 >> (src1 & 31u); dst.value = src0 >> (src1 & 31u);
break; break;
default: dst.value = src0 + src1; break; default: dst.value = src0 + src1; break;
@@ -551,9 +552,9 @@ EmbeddedFetchData DetectEmbeddedVertexFetch(const Decoder::Program& decoded
} }
break; break;
} }
if (inst.opcode == Decoder::Opcode::VMovreldB32) { if (inst.opcode == Decoder::Opcode::V_MOVRELD_B32) {
vector_lanes.clear(); vector_lanes.clear();
} else if (inst.opcode != Decoder::Opcode::VWritelaneB32 && IsDecodedVgpr(inst.dst)) { } else if (inst.opcode != Decoder::Opcode::V_WRITELANE_B32 && IsDecodedVgpr(inst.dst)) {
for (uint32_t i = 0; i < EmbeddedFetchDstSize(inst) && inst.dst.reg + i < vgprs.size(); for (uint32_t i = 0; i < EmbeddedFetchDstSize(inst) && inst.dst.reg + i < vgprs.size();
i++) { i++) {
ClearEmbeddedFetchVectorLanes(&vector_lanes, inst.dst.reg + i); ClearEmbeddedFetchVectorLanes(&vector_lanes, inst.dst.reg + i);
@@ -52,17 +52,17 @@ uint32_t ProgramEndPc(const Decoder::Program& program) {
} }
bool IsUnconditionalBranch(Opcode opcode) { bool IsUnconditionalBranch(Opcode opcode) {
return opcode == Opcode::SBranch; return opcode == Opcode::S_BRANCH;
} }
bool IsConditionalBranch(Opcode opcode) { bool IsConditionalBranch(Opcode opcode) {
switch (opcode) { switch (opcode) {
case Opcode::SCbranchScc0: case Opcode::S_CBRANCH_SCC0:
case Opcode::SCbranchScc1: case Opcode::S_CBRANCH_SCC1:
case Opcode::SCbranchVccz: case Opcode::S_CBRANCH_VCCZ:
case Opcode::SCbranchVccnz: case Opcode::S_CBRANCH_VCCNZ:
case Opcode::SCbranchExecz: case Opcode::S_CBRANCH_EXECZ:
case Opcode::SCbranchExecnz: return true; case Opcode::S_CBRANCH_EXECNZ: return true;
default: return false; default: return false;
} }
} }
@@ -73,13 +73,13 @@ bool IsBranch(Opcode opcode) {
BranchCondition ConditionForOpcode(Opcode opcode) { BranchCondition ConditionForOpcode(Opcode opcode) {
switch (opcode) { switch (opcode) {
case Opcode::SBranch: return BranchCondition::Always; case Opcode::S_BRANCH: return BranchCondition::Always;
case Opcode::SCbranchScc0: return BranchCondition::SccZero; case Opcode::S_CBRANCH_SCC0: return BranchCondition::SccZero;
case Opcode::SCbranchScc1: return BranchCondition::SccNonZero; case Opcode::S_CBRANCH_SCC1: return BranchCondition::SccNonZero;
case Opcode::SCbranchVccz: return BranchCondition::VccZero; case Opcode::S_CBRANCH_VCCZ: return BranchCondition::VccZero;
case Opcode::SCbranchVccnz: return BranchCondition::VccNonZero; case Opcode::S_CBRANCH_VCCNZ: return BranchCondition::VccNonZero;
case Opcode::SCbranchExecz: return BranchCondition::ExecZero; case Opcode::S_CBRANCH_EXECZ: return BranchCondition::ExecZero;
case Opcode::SCbranchExecnz: return BranchCondition::ExecNonZero; case Opcode::S_CBRANCH_EXECNZ: return BranchCondition::ExecNonZero;
default: return BranchCondition::Unknown; default: return BranchCondition::Unknown;
} }
} }
@@ -161,7 +161,7 @@ bool FindPreviousGetpc(const Decoder::Program& program, uint32_t before_index, u
for (uint32_t i = before_index; i > 0; i--) { for (uint32_t i = before_index; i > 0; i--) {
const uint32_t candidate_index = i - 1u; const uint32_t candidate_index = i - 1u;
const auto& candidate = program.instructions[candidate_index]; const auto& candidate = program.instructions[candidate_index];
if (candidate.opcode == Opcode::SGetpcB64 && IsScalarCode(candidate.dst, dst_code)) { if (candidate.opcode == Opcode::S_GETPC_B64 && IsScalarCode(candidate.dst, dst_code)) {
if (index != nullptr) { if (index != nullptr) {
*index = candidate_index; *index = candidate_index;
} }
@@ -186,9 +186,9 @@ bool ResolvePcRelativeBase(const Decoder::Program& program, uint32_t before_inde
continue; continue;
} }
const bool adds = const bool adds =
candidate.opcode == Opcode::SAddU32 || candidate.opcode == Opcode::SAddI32; candidate.opcode == Opcode::S_ADD_U32 || candidate.opcode == Opcode::S_ADD_I32;
const bool subs = const bool subs =
candidate.opcode == Opcode::SSubU32 || candidate.opcode == Opcode::SSubI32; candidate.opcode == Opcode::S_SUB_U32 || candidate.opcode == Opcode::S_SUB_I32;
if (!adds && !subs) { if (!adds && !subs) {
return false; return false;
} }
@@ -217,7 +217,7 @@ bool ResolvePcRelativeBase(const Decoder::Program& program, uint32_t before_inde
const auto& high = program.instructions[candidate_index + 1u]; const auto& high = program.instructions[candidate_index + 1u];
const Decoder::Operand* high_other = nullptr; const Decoder::Operand* high_other = nullptr;
uint32_t zero = 0; uint32_t zero = 0;
if (high.opcode != (adds ? Opcode::SAddcU32 : Opcode::SSubbU32) || if (high.opcode != (adds ? Opcode::S_ADDC_U32 : Opcode::S_SUBB_U32) ||
!IsScalarCode(high.dst, base_code + 1u)) { !IsScalarCode(high.dst, base_code + 1u)) {
return false; return false;
} }
@@ -288,7 +288,7 @@ bool ResolveJumpTableEntryCount(const Decoder::Program& program, uint32_t before
if (!InstructionWritesScalarCode(shift, byte_offset_code)) { if (!InstructionWritesScalarCode(shift, byte_offset_code)) {
continue; continue;
} }
if (shift.opcode != Opcode::SLshlB32 || !IsScalarCode(shift.dst, byte_offset_code)) { if (shift.opcode != Opcode::S_LSHL_B32 || !IsScalarCode(shift.dst, byte_offset_code)) {
return false; return false;
} }
@@ -307,7 +307,7 @@ bool ResolveJumpTableEntryCount(const Decoder::Program& program, uint32_t before
if (!InstructionWritesScalarCode(clamp, index_code)) { if (!InstructionWritesScalarCode(clamp, index_code)) {
continue; continue;
} }
if (clamp.opcode != Opcode::SMinU32 || !IsScalarCode(clamp.dst, index_code)) { if (clamp.opcode != Opcode::S_MIN_U32 || !IsScalarCode(clamp.dst, index_code)) {
return false; return false;
} }
@@ -350,7 +350,7 @@ bool ResolveSetpcJumpTable(const Decoder::Program& program, uint32_t setpc_index
const auto& setpc = program.instructions[setpc_index]; const auto& setpc = program.instructions[setpc_index];
uint32_t pc_reg = 0; uint32_t pc_reg = 0;
if (setpc.opcode != Opcode::SSetpcB64 || !ScalarOperandCode(setpc.src0, pc_reg) || if (setpc.opcode != Opcode::S_SETPC_B64 || !ScalarOperandCode(setpc.src0, pc_reg) ||
setpc.src0.kind != Decoder::OperandKind::Sgpr) { setpc.src0.kind != Decoder::OperandKind::Sgpr) {
return false; return false;
} }
@@ -358,9 +358,9 @@ bool ResolveSetpcJumpTable(const Decoder::Program& program, uint32_t setpc_index
const auto& getpc = program.instructions[setpc_index - 3u]; const auto& getpc = program.instructions[setpc_index - 3u];
const auto& add = program.instructions[setpc_index - 2u]; const auto& add = program.instructions[setpc_index - 2u];
const auto& addc = program.instructions[setpc_index - 1u]; const auto& addc = program.instructions[setpc_index - 1u];
if (getpc.opcode != Opcode::SGetpcB64 || !IsScalarCode(getpc.dst, pc_reg) || if (getpc.opcode != Opcode::S_GETPC_B64 || !IsScalarCode(getpc.dst, pc_reg) ||
add.opcode != Opcode::SAddU32 || !IsScalarCode(add.dst, pc_reg) || add.opcode != Opcode::S_ADD_U32 || !IsScalarCode(add.dst, pc_reg) ||
addc.opcode != Opcode::SAddcU32 || !IsScalarCode(addc.dst, pc_reg + 1u)) { addc.opcode != Opcode::S_ADDC_U32 || !IsScalarCode(addc.dst, pc_reg + 1u)) {
return false; return false;
} }
@@ -377,7 +377,7 @@ bool ResolveSetpcJumpTable(const Decoder::Program& program, uint32_t setpc_index
} }
uint32_t load_index = 0; uint32_t load_index = 0;
if (!FindPreviousScalarLoad(program, setpc_index - 3u, offset_low_code, Opcode::SLoadDwordx2, if (!FindPreviousScalarLoad(program, setpc_index - 3u, offset_low_code, Opcode::S_LOAD_DWORDX2,
&load_index)) { &load_index)) {
return false; return false;
} }
@@ -447,7 +447,7 @@ bool ResolveSetpcDwordJumpTable(const Decoder::Program& program, uint32_t setpc_
const auto& setpc = program.instructions[setpc_index]; const auto& setpc = program.instructions[setpc_index];
uint32_t pc_reg = 0; uint32_t pc_reg = 0;
if (setpc.opcode != Opcode::SSetpcB64 || setpc.src0.kind != Decoder::OperandKind::Sgpr || if (setpc.opcode != Opcode::S_SETPC_B64 || setpc.src0.kind != Decoder::OperandKind::Sgpr ||
!ScalarOperandCode(setpc.src0, pc_reg)) { !ScalarOperandCode(setpc.src0, pc_reg)) {
return false; return false;
} }
@@ -455,16 +455,16 @@ bool ResolveSetpcDwordJumpTable(const Decoder::Program& program, uint32_t setpc_
const auto& high_sub = program.instructions[setpc_index - 1u]; const auto& high_sub = program.instructions[setpc_index - 1u];
uint32_t offset_code = 0; uint32_t offset_code = 0;
uint32_t zero = 0; uint32_t zero = 0;
if (low_sub.opcode != Opcode::SSubU32 || !IsScalarCode(low_sub.dst, pc_reg) || if (low_sub.opcode != Opcode::S_SUB_U32 || !IsScalarCode(low_sub.dst, pc_reg) ||
!IsScalarCode(low_sub.src0, pc_reg) || !ScalarOperandCode(low_sub.src1, offset_code) || !IsScalarCode(low_sub.src0, pc_reg) || !ScalarOperandCode(low_sub.src1, offset_code) ||
high_sub.opcode != Opcode::SSubbU32 || !IsScalarCode(high_sub.dst, pc_reg + 1u) || high_sub.opcode != Opcode::S_SUBB_U32 || !IsScalarCode(high_sub.dst, pc_reg + 1u) ||
!IsScalarCode(high_sub.src0, pc_reg + 1u) || !IsImmediate(high_sub.src1, zero) || !IsScalarCode(high_sub.src0, pc_reg + 1u) || !IsImmediate(high_sub.src1, zero) ||
zero != 0u || offset_code == pc_reg || offset_code == pc_reg + 1u) { zero != 0u || offset_code == pc_reg || offset_code == pc_reg + 1u) {
return false; return false;
} }
uint32_t load_index = 0; uint32_t load_index = 0;
if (!FindPreviousScalarLoad(program, setpc_index - 2u, offset_code, Opcode::SLoadDword, if (!FindPreviousScalarLoad(program, setpc_index - 2u, offset_code, Opcode::S_LOAD_DWORD,
&load_index)) { &load_index)) {
return false; return false;
} }
@@ -531,7 +531,7 @@ bool ResolveSetpcTarget(const Decoder::Program& program, uint32_t setpc_index, u
} }
const auto& setpc = program.instructions[setpc_index]; const auto& setpc = program.instructions[setpc_index];
if (setpc.opcode != Opcode::SSetpcB64 || setpc.src0.kind != Decoder::OperandKind::Sgpr) { if (setpc.opcode != Opcode::S_SETPC_B64 || setpc.src0.kind != Decoder::OperandKind::Sgpr) {
return false; return false;
} }
@@ -539,12 +539,12 @@ bool ResolveSetpcTarget(const Decoder::Program& program, uint32_t setpc_index, u
if (setpc_index >= 2u) { if (setpc_index >= 2u) {
const auto& arith = program.instructions[setpc_index - 1u]; const auto& arith = program.instructions[setpc_index - 1u];
const auto& getpc = program.instructions[setpc_index - 2u]; const auto& getpc = program.instructions[setpc_index - 2u];
if (getpc.opcode == Opcode::SGetpcB64 && getpc.dst.kind == Decoder::OperandKind::Sgpr && if (getpc.opcode == Opcode::S_GETPC_B64 && getpc.dst.kind == Decoder::OperandKind::Sgpr &&
getpc.dst.reg == pc_reg && arith.dst.kind == Decoder::OperandKind::Sgpr && getpc.dst.reg == pc_reg && arith.dst.kind == Decoder::OperandKind::Sgpr &&
arith.dst.reg == pc_reg) { arith.dst.reg == pc_reg) {
uint32_t imm = 0; uint32_t imm = 0;
bool adds = arith.opcode == Opcode::SAddU32 || arith.opcode == Opcode::SAddI32; bool adds = arith.opcode == Opcode::S_ADD_U32 || arith.opcode == Opcode::S_ADD_I32;
bool subs = arith.opcode == Opcode::SSubU32 || arith.opcode == Opcode::SSubI32; bool subs = arith.opcode == Opcode::S_SUB_U32 || arith.opcode == Opcode::S_SUB_I32;
if ((adds || subs) && if ((adds || subs) &&
(IsRegister(arith.src0, Decoder::OperandKind::Sgpr, pc_reg) || (IsRegister(arith.src0, Decoder::OperandKind::Sgpr, pc_reg) ||
IsRegister(arith.src1, Decoder::OperandKind::Sgpr, pc_reg)) && IsRegister(arith.src1, Decoder::OperandKind::Sgpr, pc_reg)) &&
@@ -558,7 +558,7 @@ bool ResolveSetpcTarget(const Decoder::Program& program, uint32_t setpc_index, u
if (setpc_index >= 1u) { if (setpc_index >= 1u) {
const auto& getpc = program.instructions[setpc_index - 1u]; const auto& getpc = program.instructions[setpc_index - 1u];
if (getpc.opcode == Opcode::SGetpcB64 && getpc.dst.kind == Decoder::OperandKind::Sgpr && if (getpc.opcode == Opcode::S_GETPC_B64 && getpc.dst.kind == Decoder::OperandKind::Sgpr &&
getpc.dst.reg == pc_reg) { getpc.dst.reg == pc_reg) {
target = InstructionEndPc(getpc); target = InstructionEndPc(getpc);
return true; return true;
@@ -1619,7 +1619,7 @@ bool BuildGraph(const Decoder::Program& program, Graph& graph, std::string* erro
std::set<uint32_t> instruction_pcs; std::set<uint32_t> instruction_pcs;
for (const auto& inst: program.instructions) { for (const auto& inst: program.instructions) {
instruction_pcs.insert(inst.pc); instruction_pcs.insert(inst.pc);
if (inst.opcode == Opcode::Unsupported) { if (inst.opcode == Opcode::UNSUPPORTED) {
SetFailure(graph, FailureKind::UnsupportedInstruction, UINT32_MAX, SetFailure(graph, FailureKind::UnsupportedInstruction, UINT32_MAX,
fmt::format("unsupported decoded instruction in CFG at pc 0x{:08x}: {}", fmt::format("unsupported decoded instruction in CFG at pc 0x{:08x}: {}",
inst.pc, Decoder::InstructionToString(inst).c_str()), inst.pc, Decoder::InstructionToString(inst).c_str()),
@@ -1649,7 +1649,7 @@ bool BuildGraph(const Decoder::Program& program, Graph& graph, std::string* erro
if (next_pc <= end_pc) { if (next_pc <= end_pc) {
labels.insert(next_pc); labels.insert(next_pc);
} }
} else if (inst.opcode == Opcode::SSetpcB64) { } else if (inst.opcode == Opcode::S_SETPC_B64) {
SetpcTargetInfo target_info; SetpcTargetInfo target_info;
if (!ResolveSetpcTargets(program, i, target_info)) { if (!ResolveSetpcTargets(program, i, target_info)) {
SetFailure(graph, FailureKind::InvalidBranchTarget, UINT32_MAX, SetFailure(graph, FailureKind::InvalidBranchTarget, UINT32_MAX,
@@ -1675,7 +1675,7 @@ bool BuildGraph(const Decoder::Program& program, Graph& graph, std::string* erro
if (next_pc <= end_pc) { if (next_pc <= end_pc) {
labels.insert(next_pc); labels.insert(next_pc);
} }
} else if (inst.opcode == Opcode::SEndpgm) { } else if (inst.opcode == Opcode::S_ENDPGM) {
labels.insert(next_pc); labels.insert(next_pc);
} }
} }
@@ -1725,11 +1725,11 @@ bool BuildGraph(const Decoder::Program& program, Graph& graph, std::string* erro
const auto& last = program.instructions[block.inst_end - 1u]; const auto& last = program.instructions[block.inst_end - 1u];
const auto next_pc = InstructionEndPc(last); const auto next_pc = InstructionEndPc(last);
if (last.opcode == Opcode::SEndpgm) { if (last.opcode == Opcode::S_ENDPGM) {
block.terminator.kind = TerminatorKind::Branch; block.terminator.kind = TerminatorKind::Branch;
block.terminator.condition = BranchCondition::Always; block.terminator.condition = BranchCondition::Always;
block.terminator.true_block = pc_to_block.at(end_pc); block.terminator.true_block = pc_to_block.at(end_pc);
} else if (last.opcode == Opcode::SSetpcB64) { } else if (last.opcode == Opcode::S_SETPC_B64) {
const auto& target_info = setpc_targets.at(last.pc); const auto& target_info = setpc_targets.at(last.pc);
if (target_info.indirect) { if (target_info.indirect) {
block.terminator.kind = TerminatorKind::IndirectBranch; block.terminator.kind = TerminatorKind::IndirectBranch;
@@ -14,7 +14,7 @@ void DecodeExp(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index,
inst.word_count = 2; inst.word_count = 2;
inst.family = Family::EXP; inst.family = Family::EXP;
inst.opcode_id = target; inst.opcode_id = target;
inst.opcode = Opcode::Exp; inst.opcode = Opcode::EXP;
inst.exp.target = target; inst.exp.target = target;
inst.exp.en = en; inst.exp.en = en;
inst.exp.compr = ((word0 >> 10u) & 1u) != 0; inst.exp.compr = ((word0 >> 10u) & 1u) != 0;
@@ -17,7 +17,7 @@ struct MimgSampleInfo {
struct MimgGatherInfo { struct MimgGatherInfo {
uint32_t encoding = 0; uint32_t encoding = 0;
const char* name = nullptr; const char* name = nullptr;
Opcode decoded = Opcode::Unsupported; Opcode decoded = Opcode::UNSUPPORTED;
uint32_t flags = 0; uint32_t flags = 0;
uint32_t address_components = 3; uint32_t address_components = 3;
}; };
@@ -25,7 +25,7 @@ struct MimgGatherInfo {
struct MimgAtomicInfo { struct MimgAtomicInfo {
uint32_t encoding = 0; uint32_t encoding = 0;
const char* name = nullptr; const char* name = nullptr;
Opcode decoded = Opcode::Unsupported; Opcode decoded = Opcode::UNSUPPORTED;
}; };
constexpr ImageDimension DecodeImageDimension(uint32_t dim) { constexpr ImageDimension DecodeImageDimension(uint32_t dim) {
@@ -178,26 +178,26 @@ constexpr MimgSampleInfo MIMG_SAMPLE_OPCODE_LIST[] = {
}; };
constexpr MimgGatherInfo MIMG_GATHER_OPCODE_LIST[] = { constexpr MimgGatherInfo MIMG_GATHER_OPCODE_LIST[] = {
{0x47u, "image_gather4_lz", Opcode::ImageGather4Lz, ImageSampleFlagLevelZero, 2u}, {0x47u, "image_gather4_lz", Opcode::IMAGE_GATHER4_LZ, ImageSampleFlagLevelZero, 2u},
{0x48u, "image_gather4_c", Opcode::ImageGather4C, ImageSampleFlagCompare, 3u}, {0x48u, "image_gather4_c", Opcode::IMAGE_GATHER4_C, ImageSampleFlagCompare, 3u},
{0x4fu, "image_gather4_c_lz", Opcode::ImageGather4CLz, {0x4fu, "image_gather4_c_lz", Opcode::IMAGE_GATHER4_C_LZ,
ImageSampleFlagCompare | ImageSampleFlagLevelZero, 3u}, ImageSampleFlagCompare | ImageSampleFlagLevelZero, 3u},
{0x57u, "image_gather4_lz_o", Opcode::ImageGather4LzO, {0x57u, "image_gather4_lz_o", Opcode::IMAGE_GATHER4_LZ_O,
ImageSampleFlagLevelZero | ImageSampleFlagOffset, 3u}, ImageSampleFlagLevelZero | ImageSampleFlagOffset, 3u},
{0x58u, "image_gather4_c_o", Opcode::ImageGather4CO, {0x58u, "image_gather4_c_o", Opcode::IMAGE_GATHER4_C_O,
ImageSampleFlagCompare | ImageSampleFlagOffset, 4u}, ImageSampleFlagCompare | ImageSampleFlagOffset, 4u},
{0x5fu, "image_gather4_c_lz_o", Opcode::ImageGather4CLzO, {0x5fu, "image_gather4_c_lz_o", Opcode::IMAGE_GATHER4_C_LZ_O,
ImageSampleFlagCompare | ImageSampleFlagLevelZero | ImageSampleFlagOffset, 4u}, ImageSampleFlagCompare | ImageSampleFlagLevelZero | ImageSampleFlagOffset, 4u},
{0x61u, "image_gather4h", Opcode::ImageGather4H, ImageSampleFlagGatherHorizontal, 2u}, {0x61u, "image_gather4h", Opcode::IMAGE_GATHER4H, ImageSampleFlagGatherHorizontal, 2u},
}; };
constexpr MimgAtomicInfo MIMG_ATOMIC_OPCODE_LIST[] = { constexpr MimgAtomicInfo MIMG_ATOMIC_OPCODE_LIST[] = {
{0x11u, "image_atomic_add", Opcode::ImageAtomicAdd}, {0x11u, "image_atomic_add", Opcode::IMAGE_ATOMIC_ADD},
{0x15u, "image_atomic_umin", Opcode::ImageAtomicUMin}, {0x15u, "image_atomic_umin", Opcode::IMAGE_ATOMIC_UMIN},
{0x17u, "image_atomic_umax", Opcode::ImageAtomicUMax}, {0x17u, "image_atomic_umax", Opcode::IMAGE_ATOMIC_UMAX},
{0x18u, "image_atomic_and", Opcode::ImageAtomicAnd}, {0x18u, "image_atomic_and", Opcode::IMAGE_ATOMIC_AND},
{0x19u, "image_atomic_or", Opcode::ImageAtomicOr}, {0x19u, "image_atomic_or", Opcode::IMAGE_ATOMIC_OR},
{0x1au, "image_atomic_xor", Opcode::ImageAtomicXor}, {0x1au, "image_atomic_xor", Opcode::IMAGE_ATOMIC_XOR},
}; };
constexpr auto MIMG_SAMPLE_OPS = Detail::MakeOpcodeTable<0x100>(MIMG_SAMPLE_OPCODE_LIST); constexpr auto MIMG_SAMPLE_OPS = Detail::MakeOpcodeTable<0x100>(MIMG_SAMPLE_OPCODE_LIST);
@@ -219,7 +219,7 @@ const MimgAtomicInfo* LookupAtomic(uint32_t opcode) {
Opcode DecodeMimgOpcode(uint32_t opcode, const MimgSampleInfo* sample, const MimgGatherInfo* gather, Opcode DecodeMimgOpcode(uint32_t opcode, const MimgSampleInfo* sample, const MimgGatherInfo* gather,
const MimgAtomicInfo* atomic) { const MimgAtomicInfo* atomic) {
if (sample != nullptr) { if (sample != nullptr) {
return Opcode::ImageSample; return Opcode::IMAGE_SAMPLE;
} }
if (gather != nullptr) { if (gather != nullptr) {
return gather->decoded; return gather->decoded;
@@ -229,13 +229,13 @@ Opcode DecodeMimgOpcode(uint32_t opcode, const MimgSampleInfo* sample, const Mim
} }
switch (opcode) { switch (opcode) {
case 0x00u: return Opcode::ImageLoad; case 0x00u: return Opcode::IMAGE_LOAD;
case 0x01u: return Opcode::ImageLoadMip; case 0x01u: return Opcode::IMAGE_LOAD_MIP;
case 0x08u: return Opcode::ImageStore; case 0x08u: return Opcode::IMAGE_STORE;
case 0x09u: return Opcode::ImageStoreMip; case 0x09u: return Opcode::IMAGE_STORE_MIP;
case 0x0eu: return Opcode::ImageGetResinfo; case 0x0eu: return Opcode::IMAGE_GET_RESINFO;
case 0x60u: return Opcode::ImageGetLod; case 0x60u: return Opcode::IMAGE_GET_LOD;
default: return Opcode::Unsupported; default: return Opcode::UNSUPPORTED;
} }
} }
@@ -327,7 +327,7 @@ void DecodeMimg(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
DecodeMimgAddressComponents(opcode, dimension, sample, gather, atomic); DecodeMimgAddressComponents(opcode, dimension, sample, gather, atomic);
SetRawWords(inst, code, word_index, word_count); SetRawWords(inst, code, word_index, word_count);
if (inst.opcode == Opcode::Unsupported) { if (inst.opcode == Opcode::UNSUPPORTED) {
SetUnsupported(inst, Family::MIMG, opcode, "MIMG opcode is not implemented"); SetUnsupported(inst, Family::MIMG, opcode, "MIMG opcode is not implemented");
} }
if (gather != nullptr && !IsSingleDmaskBit(inst.dmask)) { if (gather != nullptr && !IsSingleDmaskBit(inst.dmask)) {
@@ -7,7 +7,7 @@ namespace {
struct MemoryOpcodeInfo { struct MemoryOpcodeInfo {
uint32_t encoding = 0; uint32_t encoding = 0;
Opcode decoded = Opcode::Unsupported; Opcode decoded = Opcode::UNSUPPORTED;
uint32_t data_dwords = 1; uint32_t data_dwords = 1;
uint32_t data_bits = 32; uint32_t data_bits = 32;
bool data_signed = false; bool data_signed = false;
@@ -16,96 +16,96 @@ struct MemoryOpcodeInfo {
}; };
constexpr MemoryOpcodeInfo SMEM_OPCODE_LIST[] = { constexpr MemoryOpcodeInfo SMEM_OPCODE_LIST[] = {
{0x00u, Opcode::SLoadDword, 1, 32}, {0x01u, Opcode::SLoadDwordx2, 2, 32}, {0x00u, Opcode::S_LOAD_DWORD, 1, 32}, {0x01u, Opcode::S_LOAD_DWORDX2, 2, 32},
{0x02u, Opcode::SLoadDwordx4, 4, 32}, {0x03u, Opcode::SLoadDwordx8, 8, 32}, {0x02u, Opcode::S_LOAD_DWORDX4, 4, 32}, {0x03u, Opcode::S_LOAD_DWORDX8, 8, 32},
{0x04u, Opcode::SLoadDwordx16, 16, 32}, {0x08u, Opcode::SBufferLoadDword, 1, 32}, {0x04u, Opcode::S_LOAD_DWORDX16, 16, 32}, {0x08u, Opcode::S_BUFFER_LOAD_DWORD, 1, 32},
{0x09u, Opcode::SBufferLoadDwordx2, 2, 32}, {0x0au, Opcode::SBufferLoadDwordx4, 4, 32}, {0x09u, Opcode::S_BUFFER_LOAD_DWORDX2, 2, 32}, {0x0au, Opcode::S_BUFFER_LOAD_DWORDX4, 4, 32},
{0x0bu, Opcode::SBufferLoadDwordx8, 8, 32}, {0x0cu, Opcode::SBufferLoadDwordx16, 16, 32}, {0x0bu, Opcode::S_BUFFER_LOAD_DWORDX8, 8, 32}, {0x0cu, Opcode::S_BUFFER_LOAD_DWORDX16, 16, 32},
}; };
constexpr MemoryOpcodeInfo MUBUF_OPCODE_LIST[] = { constexpr MemoryOpcodeInfo MUBUF_OPCODE_LIST[] = {
{0x00u, Opcode::BufferLoadFormatX, 1, 32, false, false, true}, {0x00u, Opcode::BUFFER_LOAD_FORMAT_X, 1, 32, false, false, true},
{0x01u, Opcode::BufferLoadFormatXy, 2, 32, false, false, true}, {0x01u, Opcode::BUFFER_LOAD_FORMAT_XY, 2, 32, false, false, true},
{0x02u, Opcode::BufferLoadFormatXyz, 3, 32, false, false, true}, {0x02u, Opcode::BUFFER_LOAD_FORMAT_XYZ, 3, 32, false, false, true},
{0x03u, Opcode::BufferLoadFormatXyzw, 4, 32, false, false, true}, {0x03u, Opcode::BUFFER_LOAD_FORMAT_XYZW, 4, 32, false, false, true},
{0x04u, Opcode::BufferStoreFormatX, 1, 32, false, false, true}, {0x04u, Opcode::BUFFER_STORE_FORMAT_X, 1, 32, false, false, true},
{0x05u, Opcode::BufferStoreFormatXy, 2, 32, false, false, true}, {0x05u, Opcode::BUFFER_STORE_FORMAT_XY, 2, 32, false, false, true},
{0x06u, Opcode::BufferStoreFormatXyz, 3, 32, false, false, true}, {0x06u, Opcode::BUFFER_STORE_FORMAT_XYZ, 3, 32, false, false, true},
{0x07u, Opcode::BufferStoreFormatXyzw, 4, 32, false, false, true}, {0x07u, Opcode::BUFFER_STORE_FORMAT_XYZW, 4, 32, false, false, true},
{0x08u, Opcode::BufferLoadUbyte, 1, 8}, {0x08u, Opcode::BUFFER_LOAD_UBYTE, 1, 8},
{0x09u, Opcode::BufferLoadSbyte, 1, 8, true}, {0x09u, Opcode::BUFFER_LOAD_SBYTE, 1, 8, true},
{0x0au, Opcode::BufferLoadUshort, 1, 16}, {0x0au, Opcode::BUFFER_LOAD_USHORT, 1, 16},
{0x0bu, Opcode::BufferLoadSshort, 1, 16, true}, {0x0bu, Opcode::BUFFER_LOAD_SSHORT, 1, 16, true},
{0x0cu, Opcode::BufferLoadDword, 1, 32}, {0x0cu, Opcode::BUFFER_LOAD_DWORD, 1, 32},
{0x0du, Opcode::BufferLoadDwordx2, 2, 32}, {0x0du, Opcode::BUFFER_LOAD_DWORDX2, 2, 32},
{0x0eu, Opcode::BufferLoadDwordx4, 4, 32}, {0x0eu, Opcode::BUFFER_LOAD_DWORDX4, 4, 32},
{0x0fu, Opcode::BufferLoadDwordx3, 3, 32}, {0x0fu, Opcode::BUFFER_LOAD_DWORDX3, 3, 32},
{0x18u, Opcode::BufferStoreByte, 1, 8}, {0x18u, Opcode::BUFFER_STORE_BYTE, 1, 8},
{0x1au, Opcode::BufferStoreShort, 1, 16}, {0x1au, Opcode::BUFFER_STORE_SHORT, 1, 16},
{0x1cu, Opcode::BufferStoreDword, 1, 32}, {0x1cu, Opcode::BUFFER_STORE_DWORD, 1, 32},
{0x1du, Opcode::BufferStoreDwordx2, 2, 32}, {0x1du, Opcode::BUFFER_STORE_DWORDX2, 2, 32},
{0x1eu, Opcode::BufferStoreDwordx4, 4, 32}, {0x1eu, Opcode::BUFFER_STORE_DWORDX4, 4, 32},
{0x1fu, Opcode::BufferStoreDwordx3, 3, 32}, {0x1fu, Opcode::BUFFER_STORE_DWORDX3, 3, 32},
{0x30u, Opcode::BufferAtomicSwap, 1, 32}, {0x30u, Opcode::BUFFER_ATOMIC_SWAP, 1, 32},
{0x32u, Opcode::BufferAtomicAdd, 1, 32}, {0x32u, Opcode::BUFFER_ATOMIC_ADD, 1, 32},
{0x33u, Opcode::BufferAtomicSub, 1, 32}, {0x33u, Opcode::BUFFER_ATOMIC_SUB, 1, 32},
{0x35u, Opcode::BufferAtomicSMin, 1, 32}, {0x35u, Opcode::BUFFER_ATOMIC_SMIN, 1, 32},
{0x36u, Opcode::BufferAtomicUMin, 1, 32}, {0x36u, Opcode::BUFFER_ATOMIC_UMIN, 1, 32},
{0x37u, Opcode::BufferAtomicSMax, 1, 32}, {0x37u, Opcode::BUFFER_ATOMIC_SMAX, 1, 32},
{0x38u, Opcode::BufferAtomicUMax, 1, 32}, {0x38u, Opcode::BUFFER_ATOMIC_UMAX, 1, 32},
{0x39u, Opcode::BufferAtomicAnd, 1, 32}, {0x39u, Opcode::BUFFER_ATOMIC_AND, 1, 32},
{0x3au, Opcode::BufferAtomicOr, 1, 32}, {0x3au, Opcode::BUFFER_ATOMIC_OR, 1, 32},
{0x3bu, Opcode::BufferAtomicXor, 1, 32}, {0x3bu, Opcode::BUFFER_ATOMIC_XOR, 1, 32},
{0x3fu, Opcode::BufferAtomicFMin, 1, 32}, {0x3fu, Opcode::BUFFER_ATOMIC_FMIN, 1, 32},
{0x40u, Opcode::BufferAtomicFMax, 1, 32}, {0x40u, Opcode::BUFFER_ATOMIC_FMAX, 1, 32},
}; };
constexpr MemoryOpcodeInfo MTBUF_OPCODE_LIST[] = { constexpr MemoryOpcodeInfo MTBUF_OPCODE_LIST[] = {
{0x00u, Opcode::TBufferLoadFormatX, 1, 32, false, true, true}, {0x00u, Opcode::TBUFFER_LOAD_FORMAT_X, 1, 32, false, true, true},
{0x01u, Opcode::TBufferLoadFormatXy, 2, 32, false, true, true}, {0x01u, Opcode::TBUFFER_LOAD_FORMAT_XY, 2, 32, false, true, true},
{0x02u, Opcode::TBufferLoadFormatXyz, 3, 32, false, true, true}, {0x02u, Opcode::TBUFFER_LOAD_FORMAT_XYZ, 3, 32, false, true, true},
{0x03u, Opcode::TBufferLoadFormatXyzw, 4, 32, false, true, true}, {0x03u, Opcode::TBUFFER_LOAD_FORMAT_XYZW, 4, 32, false, true, true},
{0x04u, Opcode::TBufferStoreFormatX, 1, 32, false, true, true}, {0x04u, Opcode::TBUFFER_STORE_FORMAT_X, 1, 32, false, true, true},
{0x05u, Opcode::TBufferStoreFormatXy, 2, 32, false, true, true}, {0x05u, Opcode::TBUFFER_STORE_FORMAT_XY, 2, 32, false, true, true},
{0x06u, Opcode::TBufferStoreFormatXyz, 3, 32, false, true, true}, {0x06u, Opcode::TBUFFER_STORE_FORMAT_XYZ, 3, 32, false, true, true},
{0x07u, Opcode::TBufferStoreFormatXyzw, 4, 32, false, true, true}, {0x07u, Opcode::TBUFFER_STORE_FORMAT_XYZW, 4, 32, false, true, true},
}; };
constexpr MemoryOpcodeInfo FLAT_OPCODE_LIST[] = { constexpr MemoryOpcodeInfo FLAT_OPCODE_LIST[] = {
{0x08u, Opcode::FlatLoadUbyte, 1, 8}, {0x09u, Opcode::FlatLoadSbyte, 1, 8, true}, {0x08u, Opcode::FLAT_LOAD_UBYTE, 1, 8}, {0x09u, Opcode::FLAT_LOAD_SBYTE, 1, 8, true},
{0x0au, Opcode::FlatLoadUshort, 1, 16}, {0x0bu, Opcode::FlatLoadSshort, 1, 16, true}, {0x0au, Opcode::FLAT_LOAD_USHORT, 1, 16}, {0x0bu, Opcode::FLAT_LOAD_SSHORT, 1, 16, true},
{0x0cu, Opcode::FlatLoadDword, 1, 32}, {0x0du, Opcode::FlatLoadDwordx2, 2, 32}, {0x0cu, Opcode::FLAT_LOAD_DWORD, 1, 32}, {0x0du, Opcode::FLAT_LOAD_DWORDX2, 2, 32},
{0x0eu, Opcode::FlatLoadDwordx4, 4, 32}, {0x0fu, Opcode::FlatLoadDwordx3, 3, 32}, {0x0eu, Opcode::FLAT_LOAD_DWORDX4, 4, 32}, {0x0fu, Opcode::FLAT_LOAD_DWORDX3, 3, 32},
{0x18u, Opcode::FlatStoreByte, 1, 8}, {0x1au, Opcode::FlatStoreShort, 1, 16}, {0x18u, Opcode::FLAT_STORE_BYTE, 1, 8}, {0x1au, Opcode::FLAT_STORE_SHORT, 1, 16},
{0x1cu, Opcode::FlatStoreDword, 1, 32}, {0x1du, Opcode::FlatStoreDwordx2, 2, 32}, {0x1cu, Opcode::FLAT_STORE_DWORD, 1, 32}, {0x1du, Opcode::FLAT_STORE_DWORDX2, 2, 32},
{0x1eu, Opcode::FlatStoreDwordx4, 4, 32}, {0x1fu, Opcode::FlatStoreDwordx3, 3, 32}, {0x1eu, Opcode::FLAT_STORE_DWORDX4, 4, 32}, {0x1fu, Opcode::FLAT_STORE_DWORDX3, 3, 32},
}; };
constexpr MemoryOpcodeInfo DS_OPCODE_LIST[] = { constexpr MemoryOpcodeInfo DS_OPCODE_LIST[] = {
{0x00u, Opcode::DsAddU32, 1, 32}, {0x01u, Opcode::DsSubU32, 1, 32}, {0x00u, Opcode::DS_ADD_U32, 1, 32}, {0x01u, Opcode::DS_SUB_U32, 1, 32},
{0x05u, Opcode::DsMinI32, 1, 32}, {0x06u, Opcode::DsMaxI32, 1, 32}, {0x05u, Opcode::DS_MIN_I32, 1, 32}, {0x06u, Opcode::DS_MAX_I32, 1, 32},
{0x07u, Opcode::DsMinU32, 1, 32}, {0x08u, Opcode::DsMaxU32, 1, 32}, {0x07u, Opcode::DS_MIN_U32, 1, 32}, {0x08u, Opcode::DS_MAX_U32, 1, 32},
{0x09u, Opcode::DsAndB32, 1, 32}, {0x0au, Opcode::DsOrB32, 1, 32}, {0x09u, Opcode::DS_AND_B32, 1, 32}, {0x0au, Opcode::DS_OR_B32, 1, 32},
{0x0bu, Opcode::DsXorB32, 1, 32}, {0x0du, Opcode::DsWriteB32, 1, 32}, {0x0bu, Opcode::DS_XOR_B32, 1, 32}, {0x0du, Opcode::DS_WRITE_B32, 1, 32},
{0x0eu, Opcode::DsWrite2B32, 2, 32}, {0x0fu, Opcode::DsWrite2St64B32, 2, 32}, {0x0eu, Opcode::DS_WRITE2_B32, 2, 32}, {0x0fu, Opcode::DS_WRITE2ST64_B32, 2, 32},
{0x12u, Opcode::DsMinF32, 1, 32}, {0x13u, Opcode::DsMaxF32, 1, 32}, {0x12u, Opcode::DS_MIN_F32, 1, 32}, {0x13u, Opcode::DS_MAX_F32, 1, 32},
{0x1eu, Opcode::DsWriteByte, 1, 8}, {0x1fu, Opcode::DsWriteShort, 1, 16}, {0x1eu, Opcode::DS_WRITE_B8, 1, 8}, {0x1fu, Opcode::DS_WRITE_B16, 1, 16},
{0x20u, Opcode::DsAddRtnU32, 1, 32}, {0x21u, Opcode::DsSubRtnU32, 1, 32}, {0x20u, Opcode::DS_ADD_RTN_U32, 1, 32}, {0x21u, Opcode::DS_SUB_RTN_U32, 1, 32},
{0x25u, Opcode::DsMinRtnI32, 1, 32}, {0x26u, Opcode::DsMaxRtnI32, 1, 32}, {0x25u, Opcode::DS_MIN_RTN_I32, 1, 32}, {0x26u, Opcode::DS_MAX_RTN_I32, 1, 32},
{0x27u, Opcode::DsMinRtnU32, 1, 32}, {0x28u, Opcode::DsMaxRtnU32, 1, 32}, {0x27u, Opcode::DS_MIN_RTN_U32, 1, 32}, {0x28u, Opcode::DS_MAX_RTN_U32, 1, 32},
{0x29u, Opcode::DsAndRtnB32, 1, 32}, {0x2au, Opcode::DsOrRtnB32, 1, 32}, {0x29u, Opcode::DS_AND_RTN_B32, 1, 32}, {0x2au, Opcode::DS_OR_RTN_B32, 1, 32},
{0x2bu, Opcode::DsXorRtnB32, 1, 32}, {0x2du, Opcode::DsWrxchgRtnB32, 1, 32}, {0x2bu, Opcode::DS_XOR_RTN_B32, 1, 32}, {0x2du, Opcode::DS_WRXCHG_RTN_B32, 1, 32},
{0x35u, Opcode::DsSwizzleB32, 1, 32}, {0x36u, Opcode::DsReadB32, 1, 32}, {0x35u, Opcode::DS_SWIZZLE_B32, 1, 32}, {0x36u, Opcode::DS_READ_B32, 1, 32},
{0x37u, Opcode::DsRead2B32, 2, 32}, {0x38u, Opcode::DsRead2B32, 2, 32}, {0x37u, Opcode::DS_READ2_B32, 2, 32}, {0x38u, Opcode::DS_READ2_B32, 2, 32},
{0x39u, Opcode::DsReadSbyte, 1, 8, true}, {0x3au, Opcode::DsReadUbyte, 1, 8}, {0x39u, Opcode::DS_READ_I8, 1, 8, true}, {0x3au, Opcode::DS_READ_U8, 1, 8},
{0x3bu, Opcode::DsReadSshort, 1, 16, true}, {0x3cu, Opcode::DsReadUshort, 1, 16}, {0x3bu, Opcode::DS_READ_I16, 1, 16, true}, {0x3cu, Opcode::DS_READ_U16, 1, 16},
{0x3du, Opcode::DsConsume, 1, 32}, {0x3eu, Opcode::DsAppend, 1, 32}, {0x3du, Opcode::DS_CONSUME, 1, 32}, {0x3eu, Opcode::DS_APPEND, 1, 32},
{0x4du, Opcode::DsWriteB64, 2, 32}, {0x4eu, Opcode::DsWrite2B64, 4, 32}, {0x4du, Opcode::DS_WRITE_B64, 2, 32}, {0x4eu, Opcode::DS_WRITE2_B64, 4, 32},
{0x4fu, Opcode::DsWrite2St64B64, 4, 32}, {0x76u, Opcode::DsReadB64, 2, 32}, {0x4fu, Opcode::DS_WRITE2ST64_B64, 4, 32}, {0x76u, Opcode::DS_READ_B64, 2, 32},
{0x77u, Opcode::DsRead2B64, 4, 32}, {0x78u, Opcode::DsRead2St64B64, 4, 32}, {0x77u, Opcode::DS_READ2_B64, 4, 32}, {0x78u, Opcode::DS_READ2ST64_B64, 4, 32},
{0xb0u, Opcode::DsWriteAddtidB32, 1, 32}, {0xb1u, Opcode::DsReadAddtidB32, 1, 32}, {0xb0u, Opcode::DS_WRITE_ADDTID_B32, 1, 32}, {0xb1u, Opcode::DS_READ_ADDTID_B32, 1, 32},
{0xdeu, Opcode::DsWriteB96, 3, 32}, {0xdfu, Opcode::DsWriteB128, 4, 32}, {0xdeu, Opcode::DS_WRITE_B96, 3, 32}, {0xdfu, Opcode::DS_WRITE_B128, 4, 32},
{0xfeu, Opcode::DsReadB96, 3, 32}, {0xffu, Opcode::DsReadB128, 4, 32}, {0xfeu, Opcode::DS_READ_B96, 3, 32}, {0xffu, Opcode::DS_READ_B128, 4, 32},
}; };
constexpr auto SMEM_OPS = Detail::MakeOpcodeTable<0x100>(SMEM_OPCODE_LIST); constexpr auto SMEM_OPS = Detail::MakeOpcodeTable<0x100>(SMEM_OPCODE_LIST);
@@ -125,13 +125,13 @@ uint32_t SignExtendU32(uint32_t value, uint32_t bits) {
void MarkMemoryUnsupported(Instruction& inst, Family family, uint32_t opcode, const char* reason) { void MarkMemoryUnsupported(Instruction& inst, Family family, uint32_t opcode, const char* reason) {
inst.family = family; inst.family = family;
inst.opcode_id = opcode; inst.opcode_id = opcode;
inst.opcode = Opcode::Unsupported; inst.opcode = Opcode::UNSUPPORTED;
SetUnsupported(inst, family, opcode, reason); SetUnsupported(inst, family, opcode, reason);
} }
void ApplyMemoryInfo(Instruction& inst, const MemoryOpcodeInfo* info) { void ApplyMemoryInfo(Instruction& inst, const MemoryOpcodeInfo* info) {
if (info == nullptr) { if (info == nullptr) {
inst.opcode = Opcode::Unsupported; inst.opcode = Opcode::UNSUPPORTED;
return; return;
} }
inst.opcode = info->decoded; inst.opcode = info->decoded;
@@ -144,68 +144,68 @@ void ApplyMemoryInfo(Instruction& inst, const MemoryOpcodeInfo* info) {
bool IsDsWriteOpcode(Opcode opcode) { bool IsDsWriteOpcode(Opcode opcode) {
switch (opcode) { switch (opcode) {
case Opcode::DsWriteByte: case Opcode::DS_WRITE_B8:
case Opcode::DsWriteShort: case Opcode::DS_WRITE_B16:
case Opcode::DsWrite2B32: case Opcode::DS_WRITE2_B32:
case Opcode::DsWrite2St64B32: case Opcode::DS_WRITE2ST64_B32:
case Opcode::DsWrite2B64: case Opcode::DS_WRITE2_B64:
case Opcode::DsWrite2St64B64: case Opcode::DS_WRITE2ST64_B64:
case Opcode::DsWriteB32: case Opcode::DS_WRITE_B32:
case Opcode::DsWriteB64: case Opcode::DS_WRITE_B64:
case Opcode::DsWriteB96: case Opcode::DS_WRITE_B96:
case Opcode::DsWriteB128: return true; case Opcode::DS_WRITE_B128: return true;
default: return false; default: return false;
} }
} }
bool IsDsAtomicOpcode(Opcode opcode) { bool IsDsAtomicOpcode(Opcode opcode) {
switch (opcode) { switch (opcode) {
case Opcode::DsAddU32: case Opcode::DS_ADD_U32:
case Opcode::DsAddRtnU32: case Opcode::DS_ADD_RTN_U32:
case Opcode::DsSubU32: case Opcode::DS_SUB_U32:
case Opcode::DsSubRtnU32: case Opcode::DS_SUB_RTN_U32:
case Opcode::DsMinI32: case Opcode::DS_MIN_I32:
case Opcode::DsMinRtnI32: case Opcode::DS_MIN_RTN_I32:
case Opcode::DsMaxI32: case Opcode::DS_MAX_I32:
case Opcode::DsMaxRtnI32: case Opcode::DS_MAX_RTN_I32:
case Opcode::DsMinU32: case Opcode::DS_MIN_U32:
case Opcode::DsMinRtnU32: case Opcode::DS_MIN_RTN_U32:
case Opcode::DsMaxU32: case Opcode::DS_MAX_U32:
case Opcode::DsMaxRtnU32: case Opcode::DS_MAX_RTN_U32:
case Opcode::DsAndB32: case Opcode::DS_AND_B32:
case Opcode::DsAndRtnB32: case Opcode::DS_AND_RTN_B32:
case Opcode::DsOrB32: case Opcode::DS_OR_B32:
case Opcode::DsOrRtnB32: case Opcode::DS_OR_RTN_B32:
case Opcode::DsXorB32: case Opcode::DS_XOR_B32:
case Opcode::DsXorRtnB32: case Opcode::DS_XOR_RTN_B32:
case Opcode::DsWrxchgRtnB32: return true; case Opcode::DS_WRXCHG_RTN_B32: return true;
default: return false; default: return false;
} }
} }
uint32_t DsSourceCount(Opcode opcode) { uint32_t DsSourceCount(Opcode opcode) {
switch (opcode) { switch (opcode) {
case Opcode::DsWrite2B32: case Opcode::DS_WRITE2_B32:
case Opcode::DsWrite2St64B32: case Opcode::DS_WRITE2ST64_B32:
case Opcode::DsWrite2B64: case Opcode::DS_WRITE2_B64:
case Opcode::DsWrite2St64B64: case Opcode::DS_WRITE2ST64_B64:
case Opcode::DsMinF32: case Opcode::DS_MIN_F32:
case Opcode::DsMaxF32: return 3u; case Opcode::DS_MAX_F32: return 3u;
case Opcode::DsReadAddtidB32: case Opcode::DS_READ_ADDTID_B32:
case Opcode::DsConsume: case Opcode::DS_CONSUME:
case Opcode::DsAppend: return 0u; case Opcode::DS_APPEND: return 0u;
default: return IsDsWriteOpcode(opcode) || IsDsAtomicOpcode(opcode) ? 2u : 1u; default: return IsDsWriteOpcode(opcode) || IsDsAtomicOpcode(opcode) ? 2u : 1u;
} }
} }
bool IsFlatStoreOpcode(Opcode opcode) { bool IsFlatStoreOpcode(Opcode opcode) {
switch (opcode) { switch (opcode) {
case Opcode::FlatStoreByte: case Opcode::FLAT_STORE_BYTE:
case Opcode::FlatStoreShort: case Opcode::FLAT_STORE_SHORT:
case Opcode::FlatStoreDword: case Opcode::FLAT_STORE_DWORD:
case Opcode::FlatStoreDwordx2: case Opcode::FLAT_STORE_DWORDX2:
case Opcode::FlatStoreDwordx3: case Opcode::FLAT_STORE_DWORDX3:
case Opcode::FlatStoreDwordx4: return true; case Opcode::FLAT_STORE_DWORDX4: return true;
default: return false; default: return false;
} }
} }
@@ -231,7 +231,7 @@ void DecodeSmem(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
const auto* info = Detail::FindOpcode(SMEM_OPS, opcode); const auto* info = Detail::FindOpcode(SMEM_OPS, opcode);
ApplyMemoryInfo(inst, info); ApplyMemoryInfo(inst, info);
SetRawWords(inst, code, word_index, 2); SetRawWords(inst, code, word_index, 2);
if (inst.opcode == Opcode::Unsupported) { if (inst.opcode == Opcode::UNSUPPORTED) {
MarkMemoryUnsupported(inst, Family::SMEM, opcode, "SMEM opcode is not implemented"); MarkMemoryUnsupported(inst, Family::SMEM, opcode, "SMEM opcode is not implemented");
} }
@@ -266,7 +266,7 @@ void DecodeMubuf(uint32_t pc, std::span<const uint32_t> code, uint32_t word_inde
const auto* info = Detail::FindOpcode(MUBUF_OPS, opcode); const auto* info = Detail::FindOpcode(MUBUF_OPS, opcode);
ApplyMemoryInfo(inst, info); ApplyMemoryInfo(inst, info);
SetRawWords(inst, code, word_index, 2); SetRawWords(inst, code, word_index, 2);
if (inst.opcode == Opcode::Unsupported) { if (inst.opcode == Opcode::UNSUPPORTED) {
MarkMemoryUnsupported(inst, Family::MUBUF, opcode, "MUBUF opcode is not implemented"); MarkMemoryUnsupported(inst, Family::MUBUF, opcode, "MUBUF opcode is not implemented");
} }
@@ -304,7 +304,7 @@ void DecodeMtbuf(uint32_t pc, std::span<const uint32_t> code, uint32_t word_inde
const auto* info = Detail::FindOpcode(MTBUF_OPS, opcode); const auto* info = Detail::FindOpcode(MTBUF_OPS, opcode);
ApplyMemoryInfo(inst, info); ApplyMemoryInfo(inst, info);
SetRawWords(inst, code, word_index, 2); SetRawWords(inst, code, word_index, 2);
if (inst.opcode == Opcode::Unsupported) { if (inst.opcode == Opcode::UNSUPPORTED) {
MarkMemoryUnsupported(inst, Family::MTBUF, opcode, "MTBUF opcode is not implemented"); MarkMemoryUnsupported(inst, Family::MTBUF, opcode, "MTBUF opcode is not implemented");
} }
@@ -346,7 +346,7 @@ void DecodeFlat(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
SetUnsupported(inst, Family::FLAT, opcode, "FLAT modifiers or segment are not implemented"); SetUnsupported(inst, Family::FLAT, opcode, "FLAT modifiers or segment are not implemented");
return; return;
} }
if (inst.opcode == Opcode::Unsupported) { if (inst.opcode == Opcode::UNSUPPORTED) {
MarkMemoryUnsupported(inst, Family::FLAT, opcode, "FLAT opcode is not implemented"); MarkMemoryUnsupported(inst, Family::FLAT, opcode, "FLAT opcode is not implemented");
return; return;
} }
@@ -384,35 +384,36 @@ void DecodeDs(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index,
const auto* info = Detail::FindOpcode(DS_OPS, opcode); const auto* info = Detail::FindOpcode(DS_OPS, opcode);
ApplyMemoryInfo(inst, info); ApplyMemoryInfo(inst, info);
SetRawWords(inst, code, word_index, 2); SetRawWords(inst, code, word_index, 2);
if (inst.opcode == Opcode::Unsupported) { if (inst.opcode == Opcode::UNSUPPORTED) {
MarkMemoryUnsupported(inst, Family::DS, opcode, "DS opcode is not implemented"); MarkMemoryUnsupported(inst, Family::DS, opcode, "DS opcode is not implemented");
} }
if (inst.opcode == Opcode::DsSwizzleB32 && inst.offset >= 0xe000u) { if (inst.opcode == Opcode::DS_SWIZZLE_B32 && inst.offset >= 0xe000u) {
SetUnsupported(inst, Family::DS, opcode, "DS swizzle FFT mode is not implemented"); SetUnsupported(inst, Family::DS, opcode, "DS swizzle FFT mode is not implemented");
} }
if (inst.gds && if (inst.gds &&
(inst.opcode == Opcode::DsSwizzleB32 || inst.opcode == Opcode::DsWriteAddtidB32 || (inst.opcode == Opcode::DS_SWIZZLE_B32 || inst.opcode == Opcode::DS_WRITE_ADDTID_B32 ||
inst.opcode == Opcode::DsReadAddtidB32)) { inst.opcode == Opcode::DS_READ_ADDTID_B32)) {
SetUnsupported(inst, Family::DS, opcode, "DS swizzle/addtid is available only for LDS"); SetUnsupported(inst, Family::DS, opcode, "DS swizzle/addtid is available only for LDS");
} }
if (inst.opcode == Opcode::DsWriteAddtidB32 && data1 != 0u) { if (inst.opcode == Opcode::DS_WRITE_ADDTID_B32 && data1 != 0u) {
SetUnsupported(inst, Family::DS, opcode, SetUnsupported(inst, Family::DS, opcode,
"DS write addtid data1 operand is not implemented"); "DS write addtid data1 operand is not implemented");
} }
if (inst.opcode == Opcode::DsReadAddtidB32 && (data0 != 0u || data1 != 0u)) { if (inst.opcode == Opcode::DS_READ_ADDTID_B32 && (data0 != 0u || data1 != 0u)) {
SetUnsupported(inst, Family::DS, opcode, SetUnsupported(inst, Family::DS, opcode,
"DS read addtid data operands are not implemented"); "DS read addtid data operands are not implemented");
} }
if (inst.opcode == Opcode::DsWrite2B32 || opcode == 0x37u) { if (inst.opcode == Opcode::DS_WRITE2_B32 || opcode == 0x37u) {
inst.offset = offset0 * 4u; inst.offset = offset0 * 4u;
inst.secondary_offset = offset1 * 4u; inst.secondary_offset = offset1 * 4u;
} else if (inst.opcode == Opcode::DsWrite2St64B32 || opcode == 0x38u) { } else if (inst.opcode == Opcode::DS_WRITE2ST64_B32 || opcode == 0x38u) {
inst.offset = offset0 * 256u; inst.offset = offset0 * 256u;
inst.secondary_offset = offset1 * 256u; inst.secondary_offset = offset1 * 256u;
} else if (inst.opcode == Opcode::DsWrite2B64 || inst.opcode == Opcode::DsRead2B64) { } else if (inst.opcode == Opcode::DS_WRITE2_B64 || inst.opcode == Opcode::DS_READ2_B64) {
inst.offset = offset0 * 8u; inst.offset = offset0 * 8u;
inst.secondary_offset = offset1 * 8u; inst.secondary_offset = offset1 * 8u;
} else if (inst.opcode == Opcode::DsWrite2St64B64 || inst.opcode == Opcode::DsRead2St64B64) { } else if (inst.opcode == Opcode::DS_WRITE2ST64_B64 ||
inst.opcode == Opcode::DS_READ2ST64_B64) {
inst.offset = offset0 * 512u; inst.offset = offset0 * 512u;
inst.secondary_offset = offset1 * 512u; inst.secondary_offset = offset1 * 512u;
} }
@@ -11,7 +11,7 @@ namespace Libs::Graphics::ShaderRecompiler::Decoder::Detail {
struct OpcodeMap { struct OpcodeMap {
uint32_t encoding = 0; uint32_t encoding = 0;
Opcode decoded = Opcode::Unknown; Opcode decoded = Opcode::UNKNOWN;
}; };
template <typename Entry, size_t EncodingCount, size_t EntryCount> template <typename Entry, size_t EncodingCount, size_t EntryCount>
@@ -48,7 +48,7 @@ template <typename Entry, size_t EncodingCount, size_t EntryCount>
constexpr Opcode LookupOpcode(const OpcodeTable<Entry, EncodingCount, EntryCount>& table, constexpr Opcode LookupOpcode(const OpcodeTable<Entry, EncodingCount, EntryCount>& table,
uint32_t encoding) { uint32_t encoding) {
const auto* entry = FindOpcode(table, encoding); const auto* entry = FindOpcode(table, encoding);
return entry != nullptr ? entry->decoded : Opcode::Unsupported; return entry != nullptr ? entry->decoded : Opcode::UNSUPPORTED;
} }
} // namespace Libs::Graphics::ShaderRecompiler::Decoder::Detail } // namespace Libs::Graphics::ShaderRecompiler::Decoder::Detail
@@ -8,67 +8,94 @@ namespace {
using Detail::OpcodeMap; using Detail::OpcodeMap;
constexpr OpcodeMap SOP2_OPCODE_LIST[] = { constexpr OpcodeMap SOP2_OPCODE_LIST[] = {
{0x00u, Opcode::SAddU32}, {0x01u, Opcode::SSubU32}, {0x02u, Opcode::SAddI32}, {0x00u, Opcode::S_ADD_U32}, {0x01u, Opcode::S_SUB_U32},
{0x03u, Opcode::SSubI32}, {0x04u, Opcode::SAddcU32}, {0x05u, Opcode::SSubbU32}, {0x02u, Opcode::S_ADD_I32}, {0x03u, Opcode::S_SUB_I32},
{0x06u, Opcode::SMinI32}, {0x07u, Opcode::SMinU32}, {0x08u, Opcode::SMaxI32}, {0x04u, Opcode::S_ADDC_U32}, {0x05u, Opcode::S_SUBB_U32},
{0x09u, Opcode::SMaxU32}, {0x0au, Opcode::SCselectB32}, {0x0bu, Opcode::SCselectB64}, {0x06u, Opcode::S_MIN_I32}, {0x07u, Opcode::S_MIN_U32},
{0x0eu, Opcode::SAndB32}, {0x0fu, Opcode::SAndB64}, {0x10u, Opcode::SOrB32}, {0x08u, Opcode::S_MAX_I32}, {0x09u, Opcode::S_MAX_U32},
{0x11u, Opcode::SOrB64}, {0x12u, Opcode::SXorB32}, {0x13u, Opcode::SXorB64}, {0x0au, Opcode::S_CSELECT_B32}, {0x0bu, Opcode::S_CSELECT_B64},
{0x14u, Opcode::SAndn2B32}, {0x15u, Opcode::SAndn2B64}, {0x16u, Opcode::SOrn2B32}, {0x0eu, Opcode::S_AND_B32}, {0x0fu, Opcode::S_AND_B64},
{0x17u, Opcode::SOrn2B64}, {0x18u, Opcode::SNandB32}, {0x19u, Opcode::SNandB64}, {0x10u, Opcode::S_OR_B32}, {0x11u, Opcode::S_OR_B64},
{0x1au, Opcode::SNorB32}, {0x1bu, Opcode::SNorB64}, {0x1cu, Opcode::SXnorB32}, {0x12u, Opcode::S_XOR_B32}, {0x13u, Opcode::S_XOR_B64},
{0x1du, Opcode::SXnorB64}, {0x1eu, Opcode::SLshlB32}, {0x1fu, Opcode::SLshlB64}, {0x14u, Opcode::S_ANDN2_B32}, {0x15u, Opcode::S_ANDN2_B64},
{0x20u, Opcode::SLshrB32}, {0x21u, Opcode::SLshrB64}, {0x22u, Opcode::SAshrI32}, {0x16u, Opcode::S_ORN2_B32}, {0x17u, Opcode::S_ORN2_B64},
{0x24u, Opcode::SBfmB32}, {0x25u, Opcode::SBfmB64}, {0x26u, Opcode::SMulI32}, {0x18u, Opcode::S_NAND_B32}, {0x19u, Opcode::S_NAND_B64},
{0x27u, Opcode::SBfeU32}, {0x28u, Opcode::SBfeI32}, {0x29u, Opcode::SBfeU64}, {0x1au, Opcode::S_NOR_B32}, {0x1bu, Opcode::S_NOR_B64},
{0x2eu, Opcode::SLshl1AddU32}, {0x2fu, Opcode::SLshl2AddU32}, {0x30u, Opcode::SLshl3AddU32}, {0x1cu, Opcode::S_XNOR_B32}, {0x1du, Opcode::S_XNOR_B64},
{0x31u, Opcode::SLshl4AddU32}, {0x32u, Opcode::SPackLlB32B16}, {0x33u, Opcode::SPackLhB32B16}, {0x1eu, Opcode::S_LSHL_B32}, {0x1fu, Opcode::S_LSHL_B64},
{0x34u, Opcode::SPackHhB32B16}, {0x35u, Opcode::SMulHiU32}, {0x20u, Opcode::S_LSHR_B32}, {0x21u, Opcode::S_LSHR_B64},
{0x22u, Opcode::S_ASHR_I32}, {0x24u, Opcode::S_BFM_B32},
{0x25u, Opcode::S_BFM_B64}, {0x26u, Opcode::S_MUL_I32},
{0x27u, Opcode::S_BFE_U32}, {0x28u, Opcode::S_BFE_I32},
{0x29u, Opcode::S_BFE_U64}, {0x2eu, Opcode::S_LSHL1_ADD_U32},
{0x2fu, Opcode::S_LSHL2_ADD_U32}, {0x30u, Opcode::S_LSHL3_ADD_U32},
{0x31u, Opcode::S_LSHL4_ADD_U32}, {0x32u, Opcode::S_PACK_LL_B32_B16},
{0x33u, Opcode::S_PACK_LH_B32_B16}, {0x34u, Opcode::S_PACK_HH_B32_B16},
{0x35u, Opcode::S_MUL_HI_U32},
}; };
constexpr OpcodeMap SOP1_OPCODE_LIST[] = { constexpr OpcodeMap SOP1_OPCODE_LIST[] = {
{0x03u, Opcode::SMovB32}, {0x04u, Opcode::SMovB64}, {0x03u, Opcode::S_MOV_B32},
{0x07u, Opcode::SNotB32}, {0x08u, Opcode::SNotB64}, {0x04u, Opcode::S_MOV_B64},
{0x0au, Opcode::SWqmB64}, {0x0bu, Opcode::SBrevB32}, {0x07u, Opcode::S_NOT_B32},
{0x0fu, Opcode::SBcnt1I32B32}, {0x10u, Opcode::SBcnt1I32B64}, {0x08u, Opcode::S_NOT_B64},
{0x13u, Opcode::SFf1I32B32}, {0x14u, Opcode::SFf1I32B64}, {0x0au, Opcode::S_WQM_B64},
{0x16u, Opcode::SFlbitI32B64}, {0x1bu, Opcode::SBitset0B32}, {0x0bu, Opcode::S_BREV_B32},
{0x1du, Opcode::SBitset1B32}, {0x1fu, Opcode::SGetpcB64}, {0x0fu, Opcode::S_BCNT1_I32_B32},
{0x20u, Opcode::SSetpcB64}, {0x24u, Opcode::SAndSaveexecB64}, {0x10u, Opcode::S_BCNT1_I32_B64},
{0x28u, Opcode::SOrn2SaveexecB64}, {0x34u, Opcode::SAbsI32}, {0x13u, Opcode::S_FF1_I32_B32},
{0x37u, Opcode::SAndn1SaveexecB64}, {0x3bu, Opcode::SBitreplicateB64B32}, {0x14u, Opcode::S_FF1_I32_B64},
{0x3cu, Opcode::SAndSaveexecB32}, {0x44u, Opcode::SAndn1SaveexecB32}, {0x16u, Opcode::S_FLBIT_I32_B64},
{0x1bu, Opcode::S_BITSET0_B32},
{0x1du, Opcode::S_BITSET1_B32},
{0x1fu, Opcode::S_GETPC_B64},
{0x20u, Opcode::S_SETPC_B64},
{0x24u, Opcode::S_AND_SAVEEXEC_B64},
{0x28u, Opcode::S_ORN2_SAVEEXEC_B64},
{0x34u, Opcode::S_ABS_I32},
{0x37u, Opcode::S_ANDN1_SAVEEXEC_B64},
{0x3bu, Opcode::S_BITREPLICATE_B64_B32},
{0x3cu, Opcode::S_AND_SAVEEXEC_B32},
{0x44u, Opcode::S_ANDN1_SAVEEXEC_B32},
}; };
constexpr OpcodeMap SOPC_OPCODE_LIST[] = { constexpr OpcodeMap SOPC_OPCODE_LIST[] = {
{0x00u, Opcode::SCmpEqI32}, {0x01u, Opcode::SCmpLgI32}, {0x02u, Opcode::SCmpGtI32}, {0x00u, Opcode::S_CMP_EQ_I32}, {0x01u, Opcode::S_CMP_LG_I32}, {0x02u, Opcode::S_CMP_GT_I32},
{0x03u, Opcode::SCmpGeI32}, {0x04u, Opcode::SCmpLtI32}, {0x05u, Opcode::SCmpLeI32}, {0x03u, Opcode::S_CMP_GE_I32}, {0x04u, Opcode::S_CMP_LT_I32}, {0x05u, Opcode::S_CMP_LE_I32},
{0x06u, Opcode::SCmpEqU32}, {0x07u, Opcode::SCmpLgU32}, {0x08u, Opcode::SCmpGtU32}, {0x06u, Opcode::S_CMP_EQ_U32}, {0x07u, Opcode::S_CMP_LG_U32}, {0x08u, Opcode::S_CMP_GT_U32},
{0x09u, Opcode::SCmpGeU32}, {0x0au, Opcode::SCmpLtU32}, {0x0bu, Opcode::SCmpLeU32}, {0x09u, Opcode::S_CMP_GE_U32}, {0x0au, Opcode::S_CMP_LT_U32}, {0x0bu, Opcode::S_CMP_LE_U32},
{0x0cu, Opcode::SBitcmp0B32}, {0x0du, Opcode::SBitcmp1B32}, {0x12u, Opcode::SCmpEqU64}, {0x0cu, Opcode::S_BITCMP0_B32}, {0x0du, Opcode::S_BITCMP1_B32}, {0x12u, Opcode::S_CMP_EQ_U64},
{0x13u, Opcode::SCmpLgU64}, {0x13u, Opcode::S_CMP_LG_U64},
}; };
constexpr OpcodeMap SOPK_OPCODE_LIST[] = { constexpr OpcodeMap SOPK_OPCODE_LIST[] = {
{0x00u, Opcode::SMovkI32}, {0x03u, Opcode::SCmpEqI32}, {0x04u, Opcode::SCmpLgI32}, {0x00u, Opcode::S_MOVK_I32}, {0x03u, Opcode::S_CMP_EQ_I32}, {0x04u, Opcode::S_CMP_LG_I32},
{0x05u, Opcode::SCmpGtI32}, {0x06u, Opcode::SCmpGeI32}, {0x07u, Opcode::SCmpLtI32}, {0x05u, Opcode::S_CMP_GT_I32}, {0x06u, Opcode::S_CMP_GE_I32}, {0x07u, Opcode::S_CMP_LT_I32},
{0x08u, Opcode::SCmpLeI32}, {0x09u, Opcode::SCmpEqU32}, {0x0au, Opcode::SCmpLgU32}, {0x08u, Opcode::S_CMP_LE_I32}, {0x09u, Opcode::S_CMP_EQ_U32}, {0x0au, Opcode::S_CMP_LG_U32},
{0x0bu, Opcode::SCmpGtU32}, {0x0cu, Opcode::SCmpGeU32}, {0x0du, Opcode::SCmpLtU32}, {0x0bu, Opcode::S_CMP_GT_U32}, {0x0cu, Opcode::S_CMP_GE_U32}, {0x0du, Opcode::S_CMP_LT_U32},
{0x0eu, Opcode::SCmpLeU32}, {0x0fu, Opcode::SAddI32}, {0x10u, Opcode::SMulkI32}, {0x0eu, Opcode::S_CMP_LE_U32}, {0x0fu, Opcode::S_ADD_I32}, {0x10u, Opcode::S_MULK_I32},
{0x13u, Opcode::SSetregB32}, {0x17u, Opcode::SWaitcnt}, {0x18u, Opcode::SWaitcnt}, {0x13u, Opcode::S_SETREG_B32}, {0x17u, Opcode::S_WAITCNT}, {0x18u, Opcode::S_WAITCNT},
{0x19u, Opcode::SWaitcnt}, {0x1au, Opcode::SWaitcnt}, {0x19u, Opcode::S_WAITCNT}, {0x1au, Opcode::S_WAITCNT},
}; };
constexpr OpcodeMap SOPP_OPCODE_LIST[] = { constexpr OpcodeMap SOPP_OPCODE_LIST[] = {
{0x00u, Opcode::SNop}, {0x01u, Opcode::SEndpgm}, {0x00u, Opcode::S_NOP},
{0x02u, Opcode::SBranch}, {0x04u, Opcode::SCbranchScc0}, {0x01u, Opcode::S_ENDPGM},
{0x05u, Opcode::SCbranchScc1}, {0x06u, Opcode::SCbranchVccz}, {0x02u, Opcode::S_BRANCH},
{0x07u, Opcode::SCbranchVccnz}, {0x08u, Opcode::SCbranchExecz}, {0x04u, Opcode::S_CBRANCH_SCC0},
{0x09u, Opcode::SCbranchExecnz}, {0x0au, Opcode::SBarrier}, {0x05u, Opcode::S_CBRANCH_SCC1},
{0x0cu, Opcode::SWaitcnt}, {0x0eu, Opcode::SSleep}, {0x06u, Opcode::S_CBRANCH_VCCZ},
{0x10u, Opcode::SSendmsg}, {0x12u, Opcode::STrap}, {0x07u, Opcode::S_CBRANCH_VCCNZ},
{0x16u, Opcode::STtraceData}, {0x20u, Opcode::SInstPrefetch}, {0x08u, Opcode::S_CBRANCH_EXECZ},
{0x23u, Opcode::SWaitcntDepctr}, {0x09u, Opcode::S_CBRANCH_EXECNZ},
{0x0au, Opcode::S_BARRIER},
{0x0cu, Opcode::S_WAITCNT},
{0x0eu, Opcode::S_SLEEP},
{0x10u, Opcode::S_SENDMSG},
{0x12u, Opcode::S_TRAP},
{0x16u, Opcode::S_TTRACEDATA},
{0x20u, Opcode::S_INST_PREFETCH},
{0x23u, Opcode::S_WAITCNT_DEPCTR},
}; };
constexpr auto SOP1_OPS = Detail::MakeOpcodeTable<0x100>(SOP1_OPCODE_LIST); constexpr auto SOP1_OPS = Detail::MakeOpcodeTable<0x100>(SOP1_OPCODE_LIST);
@@ -104,16 +131,16 @@ bool DecodeSop1(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
inst.opcode = Detail::LookupOpcode(SOP1_OPS, opcode); inst.opcode = Detail::LookupOpcode(SOP1_OPS, opcode);
SetRawWords(inst, code, word_index, 1); SetRawWords(inst, code, word_index, 1);
if (inst.opcode == Opcode::Unsupported) { if (inst.opcode == Opcode::UNSUPPORTED) {
SetUnsupported(inst, Family::SOP1, opcode, "SOP1 opcode is not implemented"); SetUnsupported(inst, Family::SOP1, opcode, "SOP1 opcode is not implemented");
return true; return true;
} }
switch (inst.opcode) { switch (inst.opcode) {
case Opcode::SGetpcB64: case Opcode::S_GETPC_B64:
inst.src_count = 0; inst.src_count = 0;
return DecodeScalarDestination(sdst, pc, inst.dst, error); return DecodeScalarDestination(sdst, pc, inst.dst, error);
case Opcode::SSetpcB64: case Opcode::S_SETPC_B64:
inst.src_count = 1; inst.src_count = 1;
inst.dst.kind = OperandKind::Null; inst.dst.kind = OperandKind::Null;
if (!DecodeScalarSource(ssrc0, pc, inst.src0, error)) { if (!DecodeScalarSource(ssrc0, pc, inst.src0, error)) {
@@ -148,7 +175,7 @@ bool DecodeSop2(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
inst.opcode = Detail::LookupOpcode(SOP2_OPS, opcode); inst.opcode = Detail::LookupOpcode(SOP2_OPS, opcode);
SetRawWords(inst, code, word_index, 1); SetRawWords(inst, code, word_index, 1);
if (inst.opcode == Opcode::Unsupported) { if (inst.opcode == Opcode::UNSUPPORTED) {
SetUnsupported(inst, Family::SOP2, opcode, "SOP2 opcode is not implemented"); SetUnsupported(inst, Family::SOP2, opcode, "SOP2 opcode is not implemented");
return true; return true;
} }
@@ -177,14 +204,14 @@ bool DecodeSopk(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
inst.src_count = 1; inst.src_count = 1;
SetRawWords(inst, code, word_index, 1); SetRawWords(inst, code, word_index, 1);
if (inst.opcode == Opcode::Unsupported) { if (inst.opcode == Opcode::UNSUPPORTED) {
SetUnsupported(inst, Family::SOPK, opcode, "SOPK opcode is not implemented"); SetUnsupported(inst, Family::SOPK, opcode, "SOPK opcode is not implemented");
return true; return true;
} }
switch (inst.opcode) { switch (inst.opcode) {
case Opcode::SMovkI32: return DecodeScalarDestination(sdst, pc, inst.dst, error); case Opcode::S_MOVK_I32: return DecodeScalarDestination(sdst, pc, inst.dst, error);
case Opcode::SWaitcnt: { case Opcode::S_WAITCNT: {
const uint32_t waitcnt = word & 0xffffu; const uint32_t waitcnt = word & 0xffffu;
inst.dst.kind = OperandKind::Null; inst.dst.kind = OperandKind::Null;
inst.src0.signed_val = static_cast<int32_t>(waitcnt); inst.src0.signed_val = static_cast<int32_t>(waitcnt);
@@ -192,7 +219,7 @@ bool DecodeSopk(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
inst.src_count = 1; inst.src_count = 1;
return true; return true;
} }
case Opcode::SSetregB32: case Opcode::S_SETREG_B32:
inst.dst.kind = OperandKind::Null; inst.dst.kind = OperandKind::Null;
inst.src1.kind = OperandKind::LiteralConstant; inst.src1.kind = OperandKind::LiteralConstant;
inst.src1.value = word & 0xffffu; inst.src1.value = word & 0xffffu;
@@ -206,7 +233,7 @@ bool DecodeSopk(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
if (!DecodeScalarSource(sdst, pc, inst.src0, error)) { if (!DecodeScalarSource(sdst, pc, inst.src0, error)) {
return false; return false;
} }
if (inst.opcode == Opcode::SAddI32 || inst.opcode == Opcode::SMulkI32) { if (inst.opcode == Opcode::S_ADD_I32 || inst.opcode == Opcode::S_MULK_I32) {
inst.src_count = 2; inst.src_count = 2;
return DecodeScalarDestination(sdst, pc, inst.dst, error); return DecodeScalarDestination(sdst, pc, inst.dst, error);
} }
@@ -231,7 +258,7 @@ bool DecodeSopc(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
inst.dst.kind = OperandKind::Scc; inst.dst.kind = OperandKind::Scc;
SetRawWords(inst, code, word_index, 1); SetRawWords(inst, code, word_index, 1);
if (inst.opcode == Opcode::Unsupported) { if (inst.opcode == Opcode::UNSUPPORTED) {
SetUnsupported(inst, Family::SOPC, opcode, "SOPC opcode is not implemented"); SetUnsupported(inst, Family::SOPC, opcode, "SOPC opcode is not implemented");
return true; return true;
} }
@@ -251,21 +278,21 @@ void DecodeSopp(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
inst.opcode_id = opcode; inst.opcode_id = opcode;
inst.opcode = Detail::LookupOpcode(SOPP_OPS, opcode); inst.opcode = Detail::LookupOpcode(SOPP_OPS, opcode);
inst.src0.kind = OperandKind::LiteralConstant; inst.src0.kind = OperandKind::LiteralConstant;
inst.src0.value = inst.opcode == Opcode::STrap ? simm & 0xffu : simm; inst.src0.value = inst.opcode == Opcode::S_TRAP ? simm & 0xffu : simm;
inst.src0.signed_val = inst.opcode == Opcode::STrap inst.src0.signed_val = inst.opcode == Opcode::S_TRAP
? static_cast<int32_t>(inst.src0.value) ? static_cast<int32_t>(inst.src0.value)
: static_cast<int32_t>(static_cast<int16_t>(simm)); : static_cast<int32_t>(static_cast<int16_t>(simm));
inst.src_count = (inst.opcode == Opcode::SNop || inst.opcode == Opcode::SWaitcnt || inst.src_count = (inst.opcode == Opcode::S_NOP || inst.opcode == Opcode::S_WAITCNT ||
inst.opcode == Opcode::SWaitcntDepctr || inst.opcode == Opcode::SSleep || inst.opcode == Opcode::S_WAITCNT_DEPCTR || inst.opcode == Opcode::S_SLEEP ||
inst.opcode == Opcode::SSendmsg || inst.opcode == Opcode::STrap || inst.opcode == Opcode::S_SENDMSG || inst.opcode == Opcode::S_TRAP ||
inst.opcode == Opcode::STtraceData || inst.opcode == Opcode::SInstPrefetch) inst.opcode == Opcode::S_TTRACEDATA || inst.opcode == Opcode::S_INST_PREFETCH)
? 1 ? 1
: 0; : 0;
inst.branch_offset = static_cast<int32_t>(static_cast<int16_t>(simm)) * 4; 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.branch_target = pc + 4u + static_cast<uint32_t>(inst.branch_offset);
SetRawWords(inst, code, word_index, 1); SetRawWords(inst, code, word_index, 1);
if (inst.opcode == Opcode::Unsupported) { if (inst.opcode == Opcode::UNSUPPORTED) {
SetUnsupported(inst, Family::SOPP, opcode, "SOPP control-flow opcode is not implemented"); SetUnsupported(inst, Family::SOPP, opcode, "SOPP control-flow opcode is not implemented");
} }
} }
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+97 -94
View File
@@ -71,10 +71,10 @@ bool AppendScalarResultSccNonZero(const Decoder::Instruction& decoded, BasicBloc
uint32_t VectorByteConvertIndex(Decoder::Opcode opcode) { uint32_t VectorByteConvertIndex(Decoder::Opcode opcode) {
switch (opcode) { switch (opcode) {
case Decoder::Opcode::VCvtF32Ubyte0: return 0; case Decoder::Opcode::V_CVT_F32_UBYTE0: return 0;
case Decoder::Opcode::VCvtF32Ubyte1: return 1; case Decoder::Opcode::V_CVT_F32_UBYTE1: return 1;
case Decoder::Opcode::VCvtF32Ubyte2: return 2; case Decoder::Opcode::V_CVT_F32_UBYTE2: return 2;
case Decoder::Opcode::VCvtF32Ubyte3: return 3; case Decoder::Opcode::V_CVT_F32_UBYTE3: return 3;
default: return 0xffffffffu; default: return 0xffffffffu;
} }
} }
@@ -228,8 +228,8 @@ MemoryInfo MemoryInfoFromDecoded(const Decoder::Instruction& decoded, ResourceKi
mem.data_signed = decoded.data_signed; mem.data_signed = decoded.data_signed;
mem.typed = decoded.typed; mem.typed = decoded.typed;
mem.formatted = decoded.formatted; mem.formatted = decoded.formatted;
mem.image_has_mip = decoded.opcode == Decoder::Opcode::ImageLoadMip || mem.image_has_mip = decoded.opcode == Decoder::Opcode::IMAGE_LOAD_MIP ||
decoded.opcode == Decoder::Opcode::ImageStoreMip; decoded.opcode == Decoder::Opcode::IMAGE_STORE_MIP;
mem.glc = decoded.glc; mem.glc = decoded.glc;
mem.slc = decoded.slc; mem.slc = decoded.slc;
mem.idxen = decoded.idxen; mem.idxen = decoded.idxen;
@@ -451,10 +451,10 @@ bool LowerScalarSelect64(const Decoder::Instruction& decoded, BasicBlock& block,
uint32_t ScalarShiftLeftAddAmount(Decoder::Opcode opcode) { uint32_t ScalarShiftLeftAddAmount(Decoder::Opcode opcode) {
switch (opcode) { switch (opcode) {
case Decoder::Opcode::SLshl1AddU32: return 1; case Decoder::Opcode::S_LSHL1_ADD_U32: return 1;
case Decoder::Opcode::SLshl2AddU32: return 2; case Decoder::Opcode::S_LSHL2_ADD_U32: return 2;
case Decoder::Opcode::SLshl3AddU32: return 3; case Decoder::Opcode::S_LSHL3_ADD_U32: return 3;
case Decoder::Opcode::SLshl4AddU32: return 4; case Decoder::Opcode::S_LSHL4_ADD_U32: return 4;
default: return 0; default: return 0;
} }
} }
@@ -484,20 +484,20 @@ bool LowerScalarShiftLeftAdd(const Decoder::Instruction& decoded, BasicBlock& bl
Opcode ScalarMinMaxSccCompareOpcode(Decoder::Opcode opcode) { Opcode ScalarMinMaxSccCompareOpcode(Decoder::Opcode opcode) {
switch (opcode) { switch (opcode) {
case Decoder::Opcode::SMinI32: return Opcode::CompareLtI32; case Decoder::Opcode::S_MIN_I32: return Opcode::CompareLtI32;
case Decoder::Opcode::SMaxI32: return Opcode::CompareGtI32; case Decoder::Opcode::S_MAX_I32: return Opcode::CompareGtI32;
case Decoder::Opcode::SMinU32: return Opcode::CompareLtU32; case Decoder::Opcode::S_MIN_U32: return Opcode::CompareLtU32;
case Decoder::Opcode::SMaxU32: return Opcode::CompareGtU32; case Decoder::Opcode::S_MAX_U32: return Opcode::CompareGtU32;
default: return Opcode::CompareFalse; default: return Opcode::CompareFalse;
} }
} }
bool IsScalarMinMaxOpcode(Decoder::Opcode opcode) { bool IsScalarMinMaxOpcode(Decoder::Opcode opcode) {
switch (opcode) { switch (opcode) {
case Decoder::Opcode::SMinI32: case Decoder::Opcode::S_MIN_I32:
case Decoder::Opcode::SMaxI32: case Decoder::Opcode::S_MAX_I32:
case Decoder::Opcode::SMinU32: case Decoder::Opcode::S_MIN_U32:
case Decoder::Opcode::SMaxU32: return true; case Decoder::Opcode::S_MAX_U32: return true;
default: return false; default: return false;
} }
} }
@@ -507,7 +507,7 @@ bool ResolveIrOpcode(Decoder::Opcode decoded, Opcode& lowered, std::string* erro
if (!opcode.has_value()) { if (!opcode.has_value()) {
if (error != nullptr) { if (error != nullptr) {
*error = fmt::format("decoded opcode has no IR lowering: {}", *error = fmt::format("decoded opcode has no IR lowering: {}",
Decoder::OpcodeToString(decoded)); magic_enum::enum_name(decoded));
} }
return false; return false;
} }
@@ -763,17 +763,19 @@ bool LowerVectorCarryOut(const Decoder::Instruction& decoded, BasicBlock& block,
Instruction inst; Instruction inst;
inst.pc = decoded.pc; inst.pc = decoded.pc;
inst.op = inst.op =
decoded.opcode == Decoder::Opcode::VAddI32 ? Opcode::IAddCarryU32 : Opcode::ISubBorrowU32; decoded.opcode == Decoder::Opcode::V_ADD_I32 ? Opcode::IAddCarryU32 : Opcode::ISubBorrowU32;
inst.src_count = decoded.opcode == Decoder::Opcode::VAddI32 ? 3u : 2u; inst.src_count = decoded.opcode == Decoder::Opcode::V_ADD_I32 ? 3u : 2u;
const auto& src0 = decoded.opcode == Decoder::Opcode::VSubrevI32 ? decoded.src1 : decoded.src0; const auto& src0 =
const auto& src1 = decoded.opcode == Decoder::Opcode::VSubrevI32 ? decoded.src0 : decoded.src1; decoded.opcode == Decoder::Opcode::V_SUBREV_I32 ? decoded.src1 : decoded.src0;
const auto& src1 =
decoded.opcode == Decoder::Opcode::V_SUBREV_I32 ? decoded.src0 : decoded.src1;
if (!LowerRegisterOperand(decoded.dst, inst.dst, error) || if (!LowerRegisterOperand(decoded.dst, inst.dst, error) ||
!LowerRegisterOperand(decoded.dst2, inst.dst2, error) || !LowerRegisterOperand(decoded.dst2, inst.dst2, error) ||
!LowerSourceOperand(src0, inst.src[0], error) || !LowerSourceOperand(src0, inst.src[0], error) ||
!LowerSourceOperand(src1, inst.src[1], error)) { !LowerSourceOperand(src1, inst.src[1], error)) {
return false; return false;
} }
if (decoded.opcode == Decoder::Opcode::VAddI32) { if (decoded.opcode == Decoder::Opcode::V_ADD_I32) {
inst.src[2] = MakeImmediateU32(0); inst.src[2] = MakeImmediateU32(0);
} }
block.instructions.push_back(inst); block.instructions.push_back(inst);
@@ -892,7 +894,7 @@ bool LowerVInterpP1F32(const Decoder::Instruction& decoded, BasicBlock& block) {
bool LowerVInterpLoadF32(const Decoder::Instruction& decoded, BasicBlock& block, bool LowerVInterpLoadF32(const Decoder::Instruction& decoded, BasicBlock& block,
std::string* error) { std::string* error) {
if (decoded.opcode == Decoder::Opcode::VInterpMovF32 && decoded.src0.value != 2u) { if (decoded.opcode == Decoder::Opcode::V_INTERP_MOV_F32 && decoded.src0.value != 2u) {
if (error != nullptr) { if (error != nullptr) {
*error = fmt::format("v_interp_mov_f32 mode {} is not implemented at pc 0x{:08x}", *error = fmt::format("v_interp_mov_f32 mode {} is not implemented at pc 0x{:08x}",
decoded.src0.value, decoded.pc); decoded.src0.value, decoded.pc);
@@ -989,29 +991,29 @@ bool LowerControlMarker(const Decoder::Instruction& decoded, BasicBlock& block,
bool LowerControlInstruction(const Decoder::Instruction& decoded, BasicBlock& block, bool LowerControlInstruction(const Decoder::Instruction& decoded, BasicBlock& block,
std::string* error) { std::string* error) {
switch (decoded.opcode) { switch (decoded.opcode) {
case Decoder::Opcode::SNop: case Decoder::Opcode::S_NOP:
return LowerControlMarker(decoded, block, Opcode::ControlNop, true, error); return LowerControlMarker(decoded, block, Opcode::ControlNop, true, error);
case Decoder::Opcode::SWaitcnt: case Decoder::Opcode::S_WAITCNT:
case Decoder::Opcode::SWaitcntDepctr: case Decoder::Opcode::S_WAITCNT_DEPCTR:
return LowerControlMarker(decoded, block, Opcode::Waitcnt, true, error); return LowerControlMarker(decoded, block, Opcode::Waitcnt, true, error);
case Decoder::Opcode::SBarrier: case Decoder::Opcode::S_BARRIER:
return LowerControlMarker(decoded, block, Opcode::Barrier, false, error); return LowerControlMarker(decoded, block, Opcode::Barrier, false, error);
case Decoder::Opcode::SSendmsg: case Decoder::Opcode::S_SENDMSG:
return LowerControlMarker(decoded, block, Opcode::Sendmsg, true, error); return LowerControlMarker(decoded, block, Opcode::Sendmsg, true, error);
case Decoder::Opcode::SSetregB32: case Decoder::Opcode::S_SETREG_B32:
case Decoder::Opcode::SSleep: case Decoder::Opcode::S_SLEEP:
return LowerControlMarker(decoded, block, Opcode::ControlNop, true, error); return LowerControlMarker(decoded, block, Opcode::ControlNop, true, error);
case Decoder::Opcode::STrap: case Decoder::Opcode::S_TRAP:
// RDNA2 converts S_TRAP to a NOP when the unmodeled trap state is disabled. // RDNA2 converts S_TRAP to a NOP when the unmodeled trap state is disabled.
return LowerControlMarker(decoded, block, Opcode::ControlNop, true, error); return LowerControlMarker(decoded, block, Opcode::ControlNop, true, error);
case Decoder::Opcode::STtraceData: case Decoder::Opcode::S_TTRACEDATA:
return LowerControlMarker(decoded, block, Opcode::TtraceData, true, error); return LowerControlMarker(decoded, block, Opcode::TtraceData, true, error);
case Decoder::Opcode::SInstPrefetch: case Decoder::Opcode::S_INST_PREFETCH:
return LowerControlMarker(decoded, block, Opcode::InstPrefetch, true, error); return LowerControlMarker(decoded, block, Opcode::InstPrefetch, true, error);
default: default:
if (error != nullptr) { if (error != nullptr) {
*error = fmt::format("control opcode has no specialized IR lowering: {}", *error = fmt::format("control opcode has no specialized IR lowering: {}",
Decoder::OpcodeToString(decoded.opcode)); magic_enum::enum_name(decoded.opcode));
} }
return false; return false;
} }
@@ -1036,20 +1038,20 @@ bool LowerScalarGetpcB64(const Decoder::Instruction& decoded, BasicBlock& block,
bool IsScalarSaveexecOpcode(Decoder::Opcode opcode) { bool IsScalarSaveexecOpcode(Decoder::Opcode opcode) {
switch (opcode) { switch (opcode) {
case Decoder::Opcode::SAndSaveexecB32: case Decoder::Opcode::S_AND_SAVEEXEC_B32:
case Decoder::Opcode::SAndn1SaveexecB32: case Decoder::Opcode::S_ANDN1_SAVEEXEC_B32:
case Decoder::Opcode::SAndSaveexecB64: case Decoder::Opcode::S_AND_SAVEEXEC_B64:
case Decoder::Opcode::SOrn2SaveexecB64: case Decoder::Opcode::S_ORN2_SAVEEXEC_B64:
case Decoder::Opcode::SAndn1SaveexecB64: return true; case Decoder::Opcode::S_ANDN1_SAVEEXEC_B64: return true;
default: return false; default: return false;
} }
} }
SaveexecMode ScalarSaveexecMode(Decoder::Opcode opcode) { SaveexecMode ScalarSaveexecMode(Decoder::Opcode opcode) {
switch (opcode) { switch (opcode) {
case Decoder::Opcode::SOrn2SaveexecB64: return SaveexecMode::Orn2; case Decoder::Opcode::S_ORN2_SAVEEXEC_B64: return SaveexecMode::Orn2;
case Decoder::Opcode::SAndn1SaveexecB32: case Decoder::Opcode::S_ANDN1_SAVEEXEC_B32:
case Decoder::Opcode::SAndn1SaveexecB64: return SaveexecMode::Andn1; case Decoder::Opcode::S_ANDN1_SAVEEXEC_B64: return SaveexecMode::Andn1;
default: return SaveexecMode::And; default: return SaveexecMode::And;
} }
} }
@@ -1058,8 +1060,8 @@ bool LowerScalarSaveexec(const Decoder::Instruction& decoded, BasicBlock& block,
std::string* error) { std::string* error) {
Instruction inst; Instruction inst;
inst.pc = decoded.pc; inst.pc = decoded.pc;
inst.op = (decoded.opcode == Decoder::Opcode::SAndSaveexecB32 || inst.op = (decoded.opcode == Decoder::Opcode::S_AND_SAVEEXEC_B32 ||
decoded.opcode == Decoder::Opcode::SAndn1SaveexecB32) decoded.opcode == Decoder::Opcode::S_ANDN1_SAVEEXEC_B32)
? Opcode::SaveexecB32 ? Opcode::SaveexecB32
: Opcode::SaveexecB64; : Opcode::SaveexecB64;
inst.saveexec_mode = ScalarSaveexecMode(decoded.opcode); inst.saveexec_mode = ScalarSaveexecMode(decoded.opcode);
@@ -1074,31 +1076,31 @@ bool LowerScalarSaveexec(const Decoder::Instruction& decoded, BasicBlock& block,
bool IsControlOpcode(Decoder::Opcode opcode) { bool IsControlOpcode(Decoder::Opcode opcode) {
switch (opcode) { switch (opcode) {
case Decoder::Opcode::SNop: case Decoder::Opcode::S_NOP:
case Decoder::Opcode::SWaitcnt: case Decoder::Opcode::S_WAITCNT:
case Decoder::Opcode::SWaitcntDepctr: case Decoder::Opcode::S_WAITCNT_DEPCTR:
case Decoder::Opcode::SBarrier: case Decoder::Opcode::S_BARRIER:
case Decoder::Opcode::SSendmsg: case Decoder::Opcode::S_SENDMSG:
case Decoder::Opcode::SSetregB32: case Decoder::Opcode::S_SETREG_B32:
case Decoder::Opcode::SSleep: case Decoder::Opcode::S_SLEEP:
case Decoder::Opcode::STrap: case Decoder::Opcode::S_TRAP:
case Decoder::Opcode::STtraceData: case Decoder::Opcode::S_TTRACEDATA:
case Decoder::Opcode::SInstPrefetch: return true; case Decoder::Opcode::S_INST_PREFETCH: return true;
default: return false; default: return false;
} }
} }
bool IsTerminatorOpcode(Decoder::Opcode opcode) { bool IsTerminatorOpcode(Decoder::Opcode opcode) {
switch (opcode) { switch (opcode) {
case Decoder::Opcode::SEndpgm: case Decoder::Opcode::S_ENDPGM:
case Decoder::Opcode::SBranch: case Decoder::Opcode::S_BRANCH:
case Decoder::Opcode::SCbranchScc0: case Decoder::Opcode::S_CBRANCH_SCC0:
case Decoder::Opcode::SCbranchScc1: case Decoder::Opcode::S_CBRANCH_SCC1:
case Decoder::Opcode::SCbranchVccz: case Decoder::Opcode::S_CBRANCH_VCCZ:
case Decoder::Opcode::SCbranchVccnz: case Decoder::Opcode::S_CBRANCH_VCCNZ:
case Decoder::Opcode::SCbranchExecz: case Decoder::Opcode::S_CBRANCH_EXECZ:
case Decoder::Opcode::SCbranchExecnz: case Decoder::Opcode::S_CBRANCH_EXECNZ:
case Decoder::Opcode::SSetpcB64: return true; case Decoder::Opcode::S_SETPC_B64: return true;
default: return false; default: return false;
} }
} }
@@ -1120,43 +1122,44 @@ bool IsMemoryFamily(Decoder::Family family) {
bool LowerDecodedInstruction(const Decoder::Instruction& inst, BasicBlock& block, bool LowerDecodedInstruction(const Decoder::Instruction& inst, BasicBlock& block,
std::string* error) { std::string* error) {
switch (inst.opcode) { switch (inst.opcode) {
case Decoder::Opcode::Unsupported: case Decoder::Opcode::UNSUPPORTED:
if (error != nullptr) { if (error != nullptr) {
*error = fmt::format("unsupported decoded instruction: {}", *error = fmt::format("unsupported decoded instruction: {}",
Decoder::InstructionToString(inst).c_str()); Decoder::InstructionToString(inst).c_str());
} }
return false; return false;
case Decoder::Opcode::SGetpcB64: return LowerScalarGetpcB64(inst, block, error); case Decoder::Opcode::S_GETPC_B64: return LowerScalarGetpcB64(inst, block, error);
case Decoder::Opcode::VNop: return true; case Decoder::Opcode::V_NOP: return true;
case Decoder::Opcode::Exp: return LowerExportInstruction(inst, block, error); case Decoder::Opcode::EXP: return LowerExportInstruction(inst, block, error);
case Decoder::Opcode::SCselectB32: return LowerScalarSelect(inst, block, error); case Decoder::Opcode::S_CSELECT_B32: return LowerScalarSelect(inst, block, error);
case Decoder::Opcode::SCselectB64: return LowerScalarSelect64(inst, block, error); case Decoder::Opcode::S_CSELECT_B64: return LowerScalarSelect64(inst, block, error);
case Decoder::Opcode::SAddU32: return LowerScalarAddCarry(inst, block, false, error); case Decoder::Opcode::S_ADD_U32: return LowerScalarAddCarry(inst, block, false, error);
case Decoder::Opcode::SAddcU32: return LowerScalarAddCarry(inst, block, true, error); case Decoder::Opcode::S_ADDC_U32: return LowerScalarAddCarry(inst, block, true, error);
case Decoder::Opcode::SSubbU32: return LowerScalarSubBorrowCarry(inst, block, error); case Decoder::Opcode::S_SUBB_U32: return LowerScalarSubBorrowCarry(inst, block, error);
case Decoder::Opcode::SSubU32: case Decoder::Opcode::S_SUB_U32:
return LowerScalarBinaryScc(inst, block, Opcode::ScalarSubBorrowU32, error); return LowerScalarBinaryScc(inst, block, Opcode::ScalarSubBorrowU32, error);
case Decoder::Opcode::SBitset0B32: return LowerScalarBitset0B32(inst, block, error); case Decoder::Opcode::S_BITSET0_B32: return LowerScalarBitset0B32(inst, block, error);
case Decoder::Opcode::SBitset1B32: return LowerScalarBitset1B32(inst, block, error); case Decoder::Opcode::S_BITSET1_B32: return LowerScalarBitset1B32(inst, block, error);
case Decoder::Opcode::SAddI32: case Decoder::Opcode::S_ADD_I32:
return LowerScalarBinaryScc(inst, block, Opcode::ScalarSignedAddOverflowI32, error); return LowerScalarBinaryScc(inst, block, Opcode::ScalarSignedAddOverflowI32, error);
case Decoder::Opcode::SSubI32: case Decoder::Opcode::S_SUB_I32:
return LowerScalarBinaryScc(inst, block, Opcode::ScalarSignedSubOverflowI32, error); return LowerScalarBinaryScc(inst, block, Opcode::ScalarSignedSubOverflowI32, error);
case Decoder::Opcode::VCndmaskB32: return LowerVectorCndmask(inst, block, error); case Decoder::Opcode::V_CNDMASK_B32: return LowerVectorCndmask(inst, block, error);
case Decoder::Opcode::VMovB32: return LowerVectorMoveB32(inst, block, error); case Decoder::Opcode::V_MOV_B32: return LowerVectorMoveB32(inst, block, error);
case Decoder::Opcode::VMovreldB32: return LowerVectorMoveRelDestination(inst, block, error); case Decoder::Opcode::V_MOVRELD_B32:
case Decoder::Opcode::VMovrelsB32: return LowerVectorMoveRelSource(inst, block, error); return LowerVectorMoveRelDestination(inst, block, error);
case Decoder::Opcode::VAddcU32: return LowerVectorAddCarry(inst, block, error); case Decoder::Opcode::V_MOVRELS_B32: return LowerVectorMoveRelSource(inst, block, error);
case Decoder::Opcode::VSubrevCoCiU32: case Decoder::Opcode::V_ADDC_U32: return LowerVectorAddCarry(inst, block, error);
case Decoder::Opcode::V_SUBREV_CO_CI_U32:
return LowerVectorSubrevBorrowCarry(inst, block, error); return LowerVectorSubrevBorrowCarry(inst, block, error);
case Decoder::Opcode::VMadU64U32: return LowerVectorMadU64U32(inst, block, error); case Decoder::Opcode::V_MAD_U64_U32: return LowerVectorMadU64U32(inst, block, error);
case Decoder::Opcode::VMacF32: return LowerVectorMacF32(inst, block, error); case Decoder::Opcode::V_MAC_F32: return LowerVectorMacF32(inst, block, error);
case Decoder::Opcode::VPkFmacF16: return LowerVectorPkFmacF16(inst, block, error); case Decoder::Opcode::V_PK_FMAC_F16: return LowerVectorPkFmacF16(inst, block, error);
case Decoder::Opcode::VFmacF16: return LowerVectorFmacF16(inst, block, error); case Decoder::Opcode::V_FMAC_F16: return LowerVectorFmacF16(inst, block, error);
case Decoder::Opcode::VDot2cF32F16: return LowerVectorDot2cF32F16(inst, block, error); case Decoder::Opcode::V_DOT2C_F32_F16: return LowerVectorDot2cF32F16(inst, block, error);
case Decoder::Opcode::VInterpP1F32: return LowerVInterpP1F32(inst, block); case Decoder::Opcode::V_INTERP_P1_F32: return LowerVInterpP1F32(inst, block);
case Decoder::Opcode::VInterpP2F32: case Decoder::Opcode::V_INTERP_P2_F32:
case Decoder::Opcode::VInterpMovF32: return LowerVInterpLoadF32(inst, block, error); case Decoder::Opcode::V_INTERP_MOV_F32: return LowerVInterpLoadF32(inst, block, error);
default: break; default: break;
} }
@@ -1177,7 +1180,7 @@ bool LowerDecodedInstruction(const Decoder::Instruction& inst, BasicBlock& block
if (IsMemoryFamily(inst.family)) { if (IsMemoryFamily(inst.family)) {
if (error != nullptr) { if (error != nullptr) {
*error = fmt::format("decoded memory-family opcode has no specialized IR lowering: {}", *error = fmt::format("decoded memory-family opcode has no specialized IR lowering: {}",
Decoder::OpcodeToString(inst.opcode)); magic_enum::enum_name(inst.opcode));
} }
return false; return false;
} }
@@ -60,17 +60,17 @@ Opcode DsWriteOpcode(uint32_t data_bits) {
Opcode LoweredImageOpcode(Decoder::Opcode opcode) { Opcode LoweredImageOpcode(Decoder::Opcode opcode) {
switch (opcode) { switch (opcode) {
case Decoder::Opcode::ImageGetResinfo: return Opcode::ImageGetResinfo; case Decoder::Opcode::IMAGE_GET_RESINFO: return Opcode::ImageGetResinfo;
case Decoder::Opcode::ImageGetLod: return Opcode::ImageGetLod; case Decoder::Opcode::IMAGE_GET_LOD: return Opcode::ImageGetLod;
case Decoder::Opcode::ImageLoad: case Decoder::Opcode::IMAGE_LOAD:
case Decoder::Opcode::ImageLoadMip: return Opcode::ImageLoad; case Decoder::Opcode::IMAGE_LOAD_MIP: return Opcode::ImageLoad;
case Decoder::Opcode::ImageGather4Lz: case Decoder::Opcode::IMAGE_GATHER4_LZ:
case Decoder::Opcode::ImageGather4C: case Decoder::Opcode::IMAGE_GATHER4_C:
case Decoder::Opcode::ImageGather4CLz: case Decoder::Opcode::IMAGE_GATHER4_C_LZ:
case Decoder::Opcode::ImageGather4LzO: case Decoder::Opcode::IMAGE_GATHER4_LZ_O:
case Decoder::Opcode::ImageGather4CO: case Decoder::Opcode::IMAGE_GATHER4_C_O:
case Decoder::Opcode::ImageGather4CLzO: case Decoder::Opcode::IMAGE_GATHER4_C_LZ_O:
case Decoder::Opcode::ImageGather4H: return Opcode::ImageGather4; case Decoder::Opcode::IMAGE_GATHER4H: return Opcode::ImageGather4;
default: return Opcode::ImageSample; default: return Opcode::ImageSample;
} }
} }
@@ -334,12 +334,12 @@ bool LowerDsAppendConsume(const Decoder::Instruction& decoded, BasicBlock& block
Opcode ImageAtomicIrOpcode(Decoder::Opcode opcode) { Opcode ImageAtomicIrOpcode(Decoder::Opcode opcode) {
switch (opcode) { switch (opcode) {
case Decoder::Opcode::ImageAtomicAdd: return Opcode::AtomicAddU32; case Decoder::Opcode::IMAGE_ATOMIC_ADD: return Opcode::AtomicAddU32;
case Decoder::Opcode::ImageAtomicUMin: return Opcode::AtomicUMinU32; case Decoder::Opcode::IMAGE_ATOMIC_UMIN: return Opcode::AtomicUMinU32;
case Decoder::Opcode::ImageAtomicUMax: return Opcode::AtomicUMaxU32; case Decoder::Opcode::IMAGE_ATOMIC_UMAX: return Opcode::AtomicUMaxU32;
case Decoder::Opcode::ImageAtomicAnd: return Opcode::AtomicAndU32; case Decoder::Opcode::IMAGE_ATOMIC_AND: return Opcode::AtomicAndU32;
case Decoder::Opcode::ImageAtomicOr: return Opcode::AtomicOrU32; case Decoder::Opcode::IMAGE_ATOMIC_OR: return Opcode::AtomicOrU32;
case Decoder::Opcode::ImageAtomicXor: return Opcode::AtomicXorU32; case Decoder::Opcode::IMAGE_ATOMIC_XOR: return Opcode::AtomicXorU32;
default: return Opcode::AtomicAddU32; default: return Opcode::AtomicAddU32;
} }
} }
@@ -477,8 +477,8 @@ bool LowerImageOperation(const Decoder::Instruction& decoded, BasicBlock& block,
std::string* error) { std::string* error) {
Instruction inst; Instruction inst;
inst.pc = decoded.pc; inst.pc = decoded.pc;
if (decoded.opcode == Decoder::Opcode::ImageStore || if (decoded.opcode == Decoder::Opcode::IMAGE_STORE ||
decoded.opcode == Decoder::Opcode::ImageStoreMip) { decoded.opcode == Decoder::Opcode::IMAGE_STORE_MIP) {
inst.op = Opcode::ImageStore; inst.op = Opcode::ImageStore;
inst.src_count = 2; inst.src_count = 2;
inst.memory = MemoryInfoFromDecoded(decoded, ResourceKind::StorageImage); inst.memory = MemoryInfoFromDecoded(decoded, ResourceKind::StorageImage);
@@ -508,181 +508,184 @@ bool LowerImageOperation(const Decoder::Instruction& decoded, BasicBlock& block,
bool LowerMemoryInstruction(const Decoder::Instruction& decoded, BasicBlock& block, bool LowerMemoryInstruction(const Decoder::Instruction& decoded, BasicBlock& block,
std::string* error) { std::string* error) {
switch (decoded.opcode) { switch (decoded.opcode) {
case Decoder::Opcode::SLoadDword: case Decoder::Opcode::S_LOAD_DWORD:
case Decoder::Opcode::SLoadDwordx2: case Decoder::Opcode::S_LOAD_DWORDX2:
case Decoder::Opcode::SLoadDwordx4: case Decoder::Opcode::S_LOAD_DWORDX4:
case Decoder::Opcode::SLoadDwordx8: case Decoder::Opcode::S_LOAD_DWORDX8:
case Decoder::Opcode::SLoadDwordx16: case Decoder::Opcode::S_LOAD_DWORDX16:
return LowerScalarMemoryLoadDword(decoded, block, Opcode::SLoadDword, error); return LowerScalarMemoryLoadDword(decoded, block, Opcode::SLoadDword, error);
case Decoder::Opcode::SBufferLoadDword: case Decoder::Opcode::S_BUFFER_LOAD_DWORD:
case Decoder::Opcode::SBufferLoadDwordx2: case Decoder::Opcode::S_BUFFER_LOAD_DWORDX2:
case Decoder::Opcode::SBufferLoadDwordx4: case Decoder::Opcode::S_BUFFER_LOAD_DWORDX4:
case Decoder::Opcode::SBufferLoadDwordx8: case Decoder::Opcode::S_BUFFER_LOAD_DWORDX8:
case Decoder::Opcode::SBufferLoadDwordx16: case Decoder::Opcode::S_BUFFER_LOAD_DWORDX16:
return LowerScalarMemoryLoadDword(decoded, block, Opcode::SBufferLoadDword, error); return LowerScalarMemoryLoadDword(decoded, block, Opcode::SBufferLoadDword, error);
case Decoder::Opcode::BufferLoadUbyte: case Decoder::Opcode::BUFFER_LOAD_UBYTE:
case Decoder::Opcode::BufferLoadSbyte: case Decoder::Opcode::BUFFER_LOAD_SBYTE:
case Decoder::Opcode::BufferLoadUshort: case Decoder::Opcode::BUFFER_LOAD_USHORT:
case Decoder::Opcode::BufferLoadSshort: case Decoder::Opcode::BUFFER_LOAD_SSHORT:
case Decoder::Opcode::BufferLoadDword: case Decoder::Opcode::BUFFER_LOAD_DWORD:
case Decoder::Opcode::BufferLoadDwordx2: case Decoder::Opcode::BUFFER_LOAD_DWORDX2:
case Decoder::Opcode::BufferLoadDwordx3: case Decoder::Opcode::BUFFER_LOAD_DWORDX3:
case Decoder::Opcode::BufferLoadDwordx4: case Decoder::Opcode::BUFFER_LOAD_DWORDX4:
case Decoder::Opcode::BufferLoadFormatX: case Decoder::Opcode::BUFFER_LOAD_FORMAT_X:
case Decoder::Opcode::BufferLoadFormatXy: case Decoder::Opcode::BUFFER_LOAD_FORMAT_XY:
case Decoder::Opcode::BufferLoadFormatXyz: case Decoder::Opcode::BUFFER_LOAD_FORMAT_XYZ:
case Decoder::Opcode::BufferLoadFormatXyzw: case Decoder::Opcode::BUFFER_LOAD_FORMAT_XYZW:
case Decoder::Opcode::TBufferLoadFormatX: case Decoder::Opcode::TBUFFER_LOAD_FORMAT_X:
case Decoder::Opcode::TBufferLoadFormatXy: case Decoder::Opcode::TBUFFER_LOAD_FORMAT_XY:
case Decoder::Opcode::TBufferLoadFormatXyz: case Decoder::Opcode::TBUFFER_LOAD_FORMAT_XYZ:
case Decoder::Opcode::TBufferLoadFormatXyzw: return LowerBufferLoad(decoded, block, error); case Decoder::Opcode::TBUFFER_LOAD_FORMAT_XYZW:
case Decoder::Opcode::BufferStoreDword: return LowerBufferLoad(decoded, block, error);
case Decoder::Opcode::BufferStoreDwordx2: case Decoder::Opcode::BUFFER_STORE_DWORD:
case Decoder::Opcode::BufferStoreDwordx3: case Decoder::Opcode::BUFFER_STORE_DWORDX2:
case Decoder::Opcode::BufferStoreDwordx4: case Decoder::Opcode::BUFFER_STORE_DWORDX3:
case Decoder::Opcode::BufferStoreByte: case Decoder::Opcode::BUFFER_STORE_DWORDX4:
case Decoder::Opcode::BufferStoreShort: case Decoder::Opcode::BUFFER_STORE_BYTE:
case Decoder::Opcode::BufferStoreFormatX: case Decoder::Opcode::BUFFER_STORE_SHORT:
case Decoder::Opcode::BufferStoreFormatXy: case Decoder::Opcode::BUFFER_STORE_FORMAT_X:
case Decoder::Opcode::BufferStoreFormatXyz: case Decoder::Opcode::BUFFER_STORE_FORMAT_XY:
case Decoder::Opcode::BufferStoreFormatXyzw: case Decoder::Opcode::BUFFER_STORE_FORMAT_XYZ:
case Decoder::Opcode::TBufferStoreFormatX: case Decoder::Opcode::BUFFER_STORE_FORMAT_XYZW:
case Decoder::Opcode::TBufferStoreFormatXy: case Decoder::Opcode::TBUFFER_STORE_FORMAT_X:
case Decoder::Opcode::TBufferStoreFormatXyz: case Decoder::Opcode::TBUFFER_STORE_FORMAT_XY:
case Decoder::Opcode::TBufferStoreFormatXyzw: case Decoder::Opcode::TBUFFER_STORE_FORMAT_XYZ:
case Decoder::Opcode::TBUFFER_STORE_FORMAT_XYZW:
return LowerBufferStore(decoded, block, error); return LowerBufferStore(decoded, block, error);
case Decoder::Opcode::BufferAtomicSwap: case Decoder::Opcode::BUFFER_ATOMIC_SWAP:
return LowerBufferAtomicDword(decoded, block, Opcode::AtomicSwapU32, error); return LowerBufferAtomicDword(decoded, block, Opcode::AtomicSwapU32, error);
case Decoder::Opcode::BufferAtomicAdd: case Decoder::Opcode::BUFFER_ATOMIC_ADD:
return LowerBufferAtomicDword(decoded, block, Opcode::AtomicAddU32, error); return LowerBufferAtomicDword(decoded, block, Opcode::AtomicAddU32, error);
case Decoder::Opcode::BufferAtomicSub: case Decoder::Opcode::BUFFER_ATOMIC_SUB:
return LowerBufferAtomicDword(decoded, block, Opcode::AtomicSubU32, error); return LowerBufferAtomicDword(decoded, block, Opcode::AtomicSubU32, error);
case Decoder::Opcode::BufferAtomicSMin: case Decoder::Opcode::BUFFER_ATOMIC_SMIN:
return LowerBufferAtomicDword(decoded, block, Opcode::AtomicSMinI32, error); return LowerBufferAtomicDword(decoded, block, Opcode::AtomicSMinI32, error);
case Decoder::Opcode::BufferAtomicUMin: case Decoder::Opcode::BUFFER_ATOMIC_UMIN:
return LowerBufferAtomicDword(decoded, block, Opcode::AtomicUMinU32, error); return LowerBufferAtomicDword(decoded, block, Opcode::AtomicUMinU32, error);
case Decoder::Opcode::BufferAtomicSMax: case Decoder::Opcode::BUFFER_ATOMIC_SMAX:
return LowerBufferAtomicDword(decoded, block, Opcode::AtomicSMaxI32, error); return LowerBufferAtomicDword(decoded, block, Opcode::AtomicSMaxI32, error);
case Decoder::Opcode::BufferAtomicUMax: case Decoder::Opcode::BUFFER_ATOMIC_UMAX:
return LowerBufferAtomicDword(decoded, block, Opcode::AtomicUMaxU32, error); return LowerBufferAtomicDword(decoded, block, Opcode::AtomicUMaxU32, error);
case Decoder::Opcode::BufferAtomicAnd: case Decoder::Opcode::BUFFER_ATOMIC_AND:
return LowerBufferAtomicDword(decoded, block, Opcode::AtomicAndU32, error); return LowerBufferAtomicDword(decoded, block, Opcode::AtomicAndU32, error);
case Decoder::Opcode::BufferAtomicOr: case Decoder::Opcode::BUFFER_ATOMIC_OR:
return LowerBufferAtomicDword(decoded, block, Opcode::AtomicOrU32, error); return LowerBufferAtomicDword(decoded, block, Opcode::AtomicOrU32, error);
case Decoder::Opcode::BufferAtomicXor: case Decoder::Opcode::BUFFER_ATOMIC_XOR:
return LowerBufferAtomicDword(decoded, block, Opcode::AtomicXorU32, error); return LowerBufferAtomicDword(decoded, block, Opcode::AtomicXorU32, error);
case Decoder::Opcode::BufferAtomicFMin: case Decoder::Opcode::BUFFER_ATOMIC_FMIN:
return LowerBufferAtomicDword(decoded, block, Opcode::AtomicFMinF32, error); return LowerBufferAtomicDword(decoded, block, Opcode::AtomicFMinF32, error);
case Decoder::Opcode::BufferAtomicFMax: case Decoder::Opcode::BUFFER_ATOMIC_FMAX:
return LowerBufferAtomicDword(decoded, block, Opcode::AtomicFMaxF32, error); return LowerBufferAtomicDword(decoded, block, Opcode::AtomicFMaxF32, error);
case Decoder::Opcode::FlatLoadUbyte: case Decoder::Opcode::FLAT_LOAD_UBYTE:
case Decoder::Opcode::FlatLoadSbyte: case Decoder::Opcode::FLAT_LOAD_SBYTE:
case Decoder::Opcode::FlatLoadUshort: case Decoder::Opcode::FLAT_LOAD_USHORT:
case Decoder::Opcode::FlatLoadSshort: case Decoder::Opcode::FLAT_LOAD_SSHORT:
case Decoder::Opcode::FlatLoadDword: case Decoder::Opcode::FLAT_LOAD_DWORD:
case Decoder::Opcode::FlatLoadDwordx2: case Decoder::Opcode::FLAT_LOAD_DWORDX2:
case Decoder::Opcode::FlatLoadDwordx3: case Decoder::Opcode::FLAT_LOAD_DWORDX3:
case Decoder::Opcode::FlatLoadDwordx4: return LowerFlatLoad(decoded, block, error); case Decoder::Opcode::FLAT_LOAD_DWORDX4: return LowerFlatLoad(decoded, block, error);
case Decoder::Opcode::FlatStoreByte: case Decoder::Opcode::FLAT_STORE_BYTE:
case Decoder::Opcode::FlatStoreShort: case Decoder::Opcode::FLAT_STORE_SHORT:
case Decoder::Opcode::FlatStoreDword: case Decoder::Opcode::FLAT_STORE_DWORD:
case Decoder::Opcode::FlatStoreDwordx2: case Decoder::Opcode::FLAT_STORE_DWORDX2:
case Decoder::Opcode::FlatStoreDwordx3: case Decoder::Opcode::FLAT_STORE_DWORDX3:
case Decoder::Opcode::FlatStoreDwordx4: return LowerFlatStore(decoded, block, error); case Decoder::Opcode::FLAT_STORE_DWORDX4: return LowerFlatStore(decoded, block, error);
case Decoder::Opcode::DsAddU32: case Decoder::Opcode::DS_ADD_U32:
return LowerDsAtomicU32(decoded, block, Opcode::AtomicAddU32, false, error); return LowerDsAtomicU32(decoded, block, Opcode::AtomicAddU32, false, error);
case Decoder::Opcode::DsAddRtnU32: case Decoder::Opcode::DS_ADD_RTN_U32:
return LowerDsAtomicU32(decoded, block, Opcode::AtomicAddU32, true, error); return LowerDsAtomicU32(decoded, block, Opcode::AtomicAddU32, true, error);
case Decoder::Opcode::DsSubU32: case Decoder::Opcode::DS_SUB_U32:
return LowerDsAtomicU32(decoded, block, Opcode::AtomicSubU32, false, error); return LowerDsAtomicU32(decoded, block, Opcode::AtomicSubU32, false, error);
case Decoder::Opcode::DsSubRtnU32: case Decoder::Opcode::DS_SUB_RTN_U32:
return LowerDsAtomicU32(decoded, block, Opcode::AtomicSubU32, true, error); return LowerDsAtomicU32(decoded, block, Opcode::AtomicSubU32, true, error);
case Decoder::Opcode::DsMinI32: case Decoder::Opcode::DS_MIN_I32:
return LowerDsAtomicU32(decoded, block, Opcode::AtomicSMinI32, false, error); return LowerDsAtomicU32(decoded, block, Opcode::AtomicSMinI32, false, error);
case Decoder::Opcode::DsMinRtnI32: case Decoder::Opcode::DS_MIN_RTN_I32:
return LowerDsAtomicU32(decoded, block, Opcode::AtomicSMinI32, true, error); return LowerDsAtomicU32(decoded, block, Opcode::AtomicSMinI32, true, error);
case Decoder::Opcode::DsMaxI32: case Decoder::Opcode::DS_MAX_I32:
return LowerDsAtomicU32(decoded, block, Opcode::AtomicSMaxI32, false, error); return LowerDsAtomicU32(decoded, block, Opcode::AtomicSMaxI32, false, error);
case Decoder::Opcode::DsMaxRtnI32: case Decoder::Opcode::DS_MAX_RTN_I32:
return LowerDsAtomicU32(decoded, block, Opcode::AtomicSMaxI32, true, error); return LowerDsAtomicU32(decoded, block, Opcode::AtomicSMaxI32, true, error);
case Decoder::Opcode::DsMinU32: case Decoder::Opcode::DS_MIN_U32:
return LowerDsAtomicU32(decoded, block, Opcode::AtomicUMinU32, false, error); return LowerDsAtomicU32(decoded, block, Opcode::AtomicUMinU32, false, error);
case Decoder::Opcode::DsMinRtnU32: case Decoder::Opcode::DS_MIN_RTN_U32:
return LowerDsAtomicU32(decoded, block, Opcode::AtomicUMinU32, true, error); return LowerDsAtomicU32(decoded, block, Opcode::AtomicUMinU32, true, error);
case Decoder::Opcode::DsMaxU32: case Decoder::Opcode::DS_MAX_U32:
return LowerDsAtomicU32(decoded, block, Opcode::AtomicUMaxU32, false, error); return LowerDsAtomicU32(decoded, block, Opcode::AtomicUMaxU32, false, error);
case Decoder::Opcode::DsMaxRtnU32: case Decoder::Opcode::DS_MAX_RTN_U32:
return LowerDsAtomicU32(decoded, block, Opcode::AtomicUMaxU32, true, error); return LowerDsAtomicU32(decoded, block, Opcode::AtomicUMaxU32, true, error);
case Decoder::Opcode::DsAndB32: case Decoder::Opcode::DS_AND_B32:
return LowerDsAtomicU32(decoded, block, Opcode::AtomicAndU32, false, error); return LowerDsAtomicU32(decoded, block, Opcode::AtomicAndU32, false, error);
case Decoder::Opcode::DsAndRtnB32: case Decoder::Opcode::DS_AND_RTN_B32:
return LowerDsAtomicU32(decoded, block, Opcode::AtomicAndU32, true, error); return LowerDsAtomicU32(decoded, block, Opcode::AtomicAndU32, true, error);
case Decoder::Opcode::DsOrB32: case Decoder::Opcode::DS_OR_B32:
return LowerDsAtomicU32(decoded, block, Opcode::AtomicOrU32, false, error); return LowerDsAtomicU32(decoded, block, Opcode::AtomicOrU32, false, error);
case Decoder::Opcode::DsOrRtnB32: case Decoder::Opcode::DS_OR_RTN_B32:
return LowerDsAtomicU32(decoded, block, Opcode::AtomicOrU32, true, error); return LowerDsAtomicU32(decoded, block, Opcode::AtomicOrU32, true, error);
case Decoder::Opcode::DsXorB32: case Decoder::Opcode::DS_XOR_B32:
return LowerDsAtomicU32(decoded, block, Opcode::AtomicXorU32, false, error); return LowerDsAtomicU32(decoded, block, Opcode::AtomicXorU32, false, error);
case Decoder::Opcode::DsXorRtnB32: case Decoder::Opcode::DS_XOR_RTN_B32:
return LowerDsAtomicU32(decoded, block, Opcode::AtomicXorU32, true, error); return LowerDsAtomicU32(decoded, block, Opcode::AtomicXorU32, true, error);
case Decoder::Opcode::DsWrxchgRtnB32: case Decoder::Opcode::DS_WRXCHG_RTN_B32:
return LowerDsAtomicU32(decoded, block, Opcode::AtomicSwapU32, true, error); return LowerDsAtomicU32(decoded, block, Opcode::AtomicSwapU32, true, error);
case Decoder::Opcode::DsMinF32: case Decoder::Opcode::DS_MIN_F32:
return LowerDsFloatMinMaxF32(decoded, block, Opcode::DsMinF32, error); return LowerDsFloatMinMaxF32(decoded, block, Opcode::DsMinF32, error);
case Decoder::Opcode::DsMaxF32: case Decoder::Opcode::DS_MAX_F32:
return LowerDsFloatMinMaxF32(decoded, block, Opcode::DsMaxF32, error); return LowerDsFloatMinMaxF32(decoded, block, Opcode::DsMaxF32, error);
case Decoder::Opcode::DsSwizzleB32: return LowerDsSwizzleB32(decoded, block, error); case Decoder::Opcode::DS_SWIZZLE_B32: return LowerDsSwizzleB32(decoded, block, error);
case Decoder::Opcode::DsConsume: case Decoder::Opcode::DS_CONSUME:
return LowerDsAppendConsume(decoded, block, Opcode::DsConsume, error); return LowerDsAppendConsume(decoded, block, Opcode::DsConsume, error);
case Decoder::Opcode::DsAppend: case Decoder::Opcode::DS_APPEND:
return LowerDsAppendConsume(decoded, block, Opcode::DsAppend, error); return LowerDsAppendConsume(decoded, block, Opcode::DsAppend, error);
case Decoder::Opcode::DsWriteAddtidB32: return LowerDsWriteAddtidB32(decoded, block, error); case Decoder::Opcode::DS_WRITE_ADDTID_B32:
case Decoder::Opcode::DsReadAddtidB32: return LowerDsReadAddtidB32(decoded, block, error); return LowerDsWriteAddtidB32(decoded, block, error);
case Decoder::Opcode::DsRead2B32: return LowerDsRead2(decoded, block, 1, error); case Decoder::Opcode::DS_READ_ADDTID_B32:
case Decoder::Opcode::DsRead2B64: return LowerDsReadAddtidB32(decoded, block, error);
case Decoder::Opcode::DsRead2St64B64: return LowerDsRead2(decoded, block, 2, error); case Decoder::Opcode::DS_READ2_B32: return LowerDsRead2(decoded, block, 1, error);
case Decoder::Opcode::DsReadSbyte: case Decoder::Opcode::DS_READ2_B64:
case Decoder::Opcode::DsReadUbyte: case Decoder::Opcode::DS_READ2ST64_B64: return LowerDsRead2(decoded, block, 2, error);
case Decoder::Opcode::DsReadSshort: case Decoder::Opcode::DS_READ_I8:
case Decoder::Opcode::DsReadUshort: case Decoder::Opcode::DS_READ_U8:
case Decoder::Opcode::DsReadB32: case Decoder::Opcode::DS_READ_I16:
case Decoder::Opcode::DsReadB64: case Decoder::Opcode::DS_READ_U16:
case Decoder::Opcode::DsReadB96: case Decoder::Opcode::DS_READ_B32:
case Decoder::Opcode::DsReadB128: return LowerDsRead(decoded, block, error); case Decoder::Opcode::DS_READ_B64:
case Decoder::Opcode::DsWrite2B32: case Decoder::Opcode::DS_READ_B96:
case Decoder::Opcode::DsWrite2St64B32: return LowerDsWrite2(decoded, block, 1, error); case Decoder::Opcode::DS_READ_B128: return LowerDsRead(decoded, block, error);
case Decoder::Opcode::DsWrite2B64: case Decoder::Opcode::DS_WRITE2_B32:
case Decoder::Opcode::DsWrite2St64B64: return LowerDsWrite2(decoded, block, 2, error); case Decoder::Opcode::DS_WRITE2ST64_B32: return LowerDsWrite2(decoded, block, 1, error);
case Decoder::Opcode::DsWriteByte: case Decoder::Opcode::DS_WRITE2_B64:
case Decoder::Opcode::DsWriteShort: case Decoder::Opcode::DS_WRITE2ST64_B64: return LowerDsWrite2(decoded, block, 2, error);
case Decoder::Opcode::DsWriteB32: case Decoder::Opcode::DS_WRITE_B8:
case Decoder::Opcode::DsWriteB64: case Decoder::Opcode::DS_WRITE_B16:
case Decoder::Opcode::DsWriteB96: case Decoder::Opcode::DS_WRITE_B32:
case Decoder::Opcode::DsWriteB128: return LowerDsWrite(decoded, block, error); case Decoder::Opcode::DS_WRITE_B64:
case Decoder::Opcode::ImageGetResinfo: case Decoder::Opcode::DS_WRITE_B96:
case Decoder::Opcode::ImageGetLod: case Decoder::Opcode::DS_WRITE_B128: return LowerDsWrite(decoded, block, error);
case Decoder::Opcode::ImageLoad: case Decoder::Opcode::IMAGE_GET_RESINFO:
case Decoder::Opcode::ImageLoadMip: case Decoder::Opcode::IMAGE_GET_LOD:
case Decoder::Opcode::ImageStore: case Decoder::Opcode::IMAGE_LOAD:
case Decoder::Opcode::ImageStoreMip: case Decoder::Opcode::IMAGE_LOAD_MIP:
case Decoder::Opcode::ImageGather4Lz: case Decoder::Opcode::IMAGE_STORE:
case Decoder::Opcode::ImageGather4C: case Decoder::Opcode::IMAGE_STORE_MIP:
case Decoder::Opcode::ImageGather4CLz: case Decoder::Opcode::IMAGE_GATHER4_LZ:
case Decoder::Opcode::ImageGather4LzO: case Decoder::Opcode::IMAGE_GATHER4_C:
case Decoder::Opcode::ImageGather4CO: case Decoder::Opcode::IMAGE_GATHER4_C_LZ:
case Decoder::Opcode::ImageGather4CLzO: case Decoder::Opcode::IMAGE_GATHER4_LZ_O:
case Decoder::Opcode::ImageGather4H: case Decoder::Opcode::IMAGE_GATHER4_C_O:
case Decoder::Opcode::ImageSample: return LowerImageOperation(decoded, block, error); case Decoder::Opcode::IMAGE_GATHER4_C_LZ_O:
case Decoder::Opcode::ImageAtomicAdd: case Decoder::Opcode::IMAGE_GATHER4H:
case Decoder::Opcode::ImageAtomicUMin: case Decoder::Opcode::IMAGE_SAMPLE: return LowerImageOperation(decoded, block, error);
case Decoder::Opcode::ImageAtomicUMax: case Decoder::Opcode::IMAGE_ATOMIC_ADD:
case Decoder::Opcode::ImageAtomicAnd: case Decoder::Opcode::IMAGE_ATOMIC_UMIN:
case Decoder::Opcode::ImageAtomicOr: case Decoder::Opcode::IMAGE_ATOMIC_UMAX:
case Decoder::Opcode::ImageAtomicXor: return LowerImageAtomicU32(decoded, block, error); case Decoder::Opcode::IMAGE_ATOMIC_AND:
case Decoder::Opcode::IMAGE_ATOMIC_OR:
case Decoder::Opcode::IMAGE_ATOMIC_XOR: return LowerImageAtomicU32(decoded, block, error);
default: default:
if (error != nullptr) { if (error != nullptr) {
*error = fmt::format("memory opcode has no specialized IR lowering: {}", *error = fmt::format("memory opcode has no specialized IR lowering: {}",
Decoder::OpcodeToString(decoded.opcode)); magic_enum::enum_name(decoded.opcode));
} }
return false; return false;
} }
@@ -690,139 +693,139 @@ bool LowerMemoryInstruction(const Decoder::Instruction& decoded, BasicBlock& blo
bool IsMemoryOpcode(Decoder::Opcode opcode) { bool IsMemoryOpcode(Decoder::Opcode opcode) {
switch (opcode) { switch (opcode) {
case Decoder::Opcode::SLoadDword: case Decoder::Opcode::S_LOAD_DWORD:
case Decoder::Opcode::SLoadDwordx2: case Decoder::Opcode::S_LOAD_DWORDX2:
case Decoder::Opcode::SLoadDwordx4: case Decoder::Opcode::S_LOAD_DWORDX4:
case Decoder::Opcode::SLoadDwordx8: case Decoder::Opcode::S_LOAD_DWORDX8:
case Decoder::Opcode::SLoadDwordx16: case Decoder::Opcode::S_LOAD_DWORDX16:
case Decoder::Opcode::SBufferLoadDword: case Decoder::Opcode::S_BUFFER_LOAD_DWORD:
case Decoder::Opcode::SBufferLoadDwordx2: case Decoder::Opcode::S_BUFFER_LOAD_DWORDX2:
case Decoder::Opcode::SBufferLoadDwordx4: case Decoder::Opcode::S_BUFFER_LOAD_DWORDX4:
case Decoder::Opcode::SBufferLoadDwordx8: case Decoder::Opcode::S_BUFFER_LOAD_DWORDX8:
case Decoder::Opcode::SBufferLoadDwordx16: case Decoder::Opcode::S_BUFFER_LOAD_DWORDX16:
case Decoder::Opcode::BufferLoadUbyte: case Decoder::Opcode::BUFFER_LOAD_UBYTE:
case Decoder::Opcode::BufferLoadSbyte: case Decoder::Opcode::BUFFER_LOAD_SBYTE:
case Decoder::Opcode::BufferLoadUshort: case Decoder::Opcode::BUFFER_LOAD_USHORT:
case Decoder::Opcode::BufferLoadSshort: case Decoder::Opcode::BUFFER_LOAD_SSHORT:
case Decoder::Opcode::BufferLoadDword: case Decoder::Opcode::BUFFER_LOAD_DWORD:
case Decoder::Opcode::BufferLoadDwordx2: case Decoder::Opcode::BUFFER_LOAD_DWORDX2:
case Decoder::Opcode::BufferLoadDwordx3: case Decoder::Opcode::BUFFER_LOAD_DWORDX3:
case Decoder::Opcode::BufferLoadDwordx4: case Decoder::Opcode::BUFFER_LOAD_DWORDX4:
case Decoder::Opcode::BufferLoadFormatX: case Decoder::Opcode::BUFFER_LOAD_FORMAT_X:
case Decoder::Opcode::BufferLoadFormatXy: case Decoder::Opcode::BUFFER_LOAD_FORMAT_XY:
case Decoder::Opcode::BufferLoadFormatXyz: case Decoder::Opcode::BUFFER_LOAD_FORMAT_XYZ:
case Decoder::Opcode::BufferLoadFormatXyzw: case Decoder::Opcode::BUFFER_LOAD_FORMAT_XYZW:
case Decoder::Opcode::TBufferLoadFormatX: case Decoder::Opcode::TBUFFER_LOAD_FORMAT_X:
case Decoder::Opcode::TBufferLoadFormatXy: case Decoder::Opcode::TBUFFER_LOAD_FORMAT_XY:
case Decoder::Opcode::TBufferLoadFormatXyz: case Decoder::Opcode::TBUFFER_LOAD_FORMAT_XYZ:
case Decoder::Opcode::TBufferLoadFormatXyzw: case Decoder::Opcode::TBUFFER_LOAD_FORMAT_XYZW:
case Decoder::Opcode::BufferStoreDword: case Decoder::Opcode::BUFFER_STORE_DWORD:
case Decoder::Opcode::BufferStoreDwordx2: case Decoder::Opcode::BUFFER_STORE_DWORDX2:
case Decoder::Opcode::BufferStoreDwordx3: case Decoder::Opcode::BUFFER_STORE_DWORDX3:
case Decoder::Opcode::BufferStoreDwordx4: case Decoder::Opcode::BUFFER_STORE_DWORDX4:
case Decoder::Opcode::BufferStoreByte: case Decoder::Opcode::BUFFER_STORE_BYTE:
case Decoder::Opcode::BufferStoreShort: case Decoder::Opcode::BUFFER_STORE_SHORT:
case Decoder::Opcode::BufferStoreFormatX: case Decoder::Opcode::BUFFER_STORE_FORMAT_X:
case Decoder::Opcode::BufferStoreFormatXy: case Decoder::Opcode::BUFFER_STORE_FORMAT_XY:
case Decoder::Opcode::BufferStoreFormatXyz: case Decoder::Opcode::BUFFER_STORE_FORMAT_XYZ:
case Decoder::Opcode::BufferStoreFormatXyzw: case Decoder::Opcode::BUFFER_STORE_FORMAT_XYZW:
case Decoder::Opcode::TBufferStoreFormatX: case Decoder::Opcode::TBUFFER_STORE_FORMAT_X:
case Decoder::Opcode::TBufferStoreFormatXy: case Decoder::Opcode::TBUFFER_STORE_FORMAT_XY:
case Decoder::Opcode::TBufferStoreFormatXyz: case Decoder::Opcode::TBUFFER_STORE_FORMAT_XYZ:
case Decoder::Opcode::TBufferStoreFormatXyzw: case Decoder::Opcode::TBUFFER_STORE_FORMAT_XYZW:
case Decoder::Opcode::BufferAtomicSwap: case Decoder::Opcode::BUFFER_ATOMIC_SWAP:
case Decoder::Opcode::BufferAtomicAdd: case Decoder::Opcode::BUFFER_ATOMIC_ADD:
case Decoder::Opcode::BufferAtomicSub: case Decoder::Opcode::BUFFER_ATOMIC_SUB:
case Decoder::Opcode::BufferAtomicSMin: case Decoder::Opcode::BUFFER_ATOMIC_SMIN:
case Decoder::Opcode::BufferAtomicUMin: case Decoder::Opcode::BUFFER_ATOMIC_UMIN:
case Decoder::Opcode::BufferAtomicSMax: case Decoder::Opcode::BUFFER_ATOMIC_SMAX:
case Decoder::Opcode::BufferAtomicUMax: case Decoder::Opcode::BUFFER_ATOMIC_UMAX:
case Decoder::Opcode::BufferAtomicAnd: case Decoder::Opcode::BUFFER_ATOMIC_AND:
case Decoder::Opcode::BufferAtomicOr: case Decoder::Opcode::BUFFER_ATOMIC_OR:
case Decoder::Opcode::BufferAtomicXor: case Decoder::Opcode::BUFFER_ATOMIC_XOR:
case Decoder::Opcode::BufferAtomicFMin: case Decoder::Opcode::BUFFER_ATOMIC_FMIN:
case Decoder::Opcode::BufferAtomicFMax: case Decoder::Opcode::BUFFER_ATOMIC_FMAX:
case Decoder::Opcode::FlatLoadUbyte: case Decoder::Opcode::FLAT_LOAD_UBYTE:
case Decoder::Opcode::FlatLoadSbyte: case Decoder::Opcode::FLAT_LOAD_SBYTE:
case Decoder::Opcode::FlatLoadUshort: case Decoder::Opcode::FLAT_LOAD_USHORT:
case Decoder::Opcode::FlatLoadSshort: case Decoder::Opcode::FLAT_LOAD_SSHORT:
case Decoder::Opcode::FlatLoadDword: case Decoder::Opcode::FLAT_LOAD_DWORD:
case Decoder::Opcode::FlatLoadDwordx2: case Decoder::Opcode::FLAT_LOAD_DWORDX2:
case Decoder::Opcode::FlatLoadDwordx3: case Decoder::Opcode::FLAT_LOAD_DWORDX3:
case Decoder::Opcode::FlatLoadDwordx4: case Decoder::Opcode::FLAT_LOAD_DWORDX4:
case Decoder::Opcode::FlatStoreByte: case Decoder::Opcode::FLAT_STORE_BYTE:
case Decoder::Opcode::FlatStoreShort: case Decoder::Opcode::FLAT_STORE_SHORT:
case Decoder::Opcode::FlatStoreDword: case Decoder::Opcode::FLAT_STORE_DWORD:
case Decoder::Opcode::FlatStoreDwordx2: case Decoder::Opcode::FLAT_STORE_DWORDX2:
case Decoder::Opcode::FlatStoreDwordx3: case Decoder::Opcode::FLAT_STORE_DWORDX3:
case Decoder::Opcode::FlatStoreDwordx4: case Decoder::Opcode::FLAT_STORE_DWORDX4:
case Decoder::Opcode::DsAddU32: case Decoder::Opcode::DS_ADD_U32:
case Decoder::Opcode::DsAddRtnU32: case Decoder::Opcode::DS_ADD_RTN_U32:
case Decoder::Opcode::DsSubU32: case Decoder::Opcode::DS_SUB_U32:
case Decoder::Opcode::DsSubRtnU32: case Decoder::Opcode::DS_SUB_RTN_U32:
case Decoder::Opcode::DsMinI32: case Decoder::Opcode::DS_MIN_I32:
case Decoder::Opcode::DsMinRtnI32: case Decoder::Opcode::DS_MIN_RTN_I32:
case Decoder::Opcode::DsMaxI32: case Decoder::Opcode::DS_MAX_I32:
case Decoder::Opcode::DsMaxRtnI32: case Decoder::Opcode::DS_MAX_RTN_I32:
case Decoder::Opcode::DsMinU32: case Decoder::Opcode::DS_MIN_U32:
case Decoder::Opcode::DsMinRtnU32: case Decoder::Opcode::DS_MIN_RTN_U32:
case Decoder::Opcode::DsMaxU32: case Decoder::Opcode::DS_MAX_U32:
case Decoder::Opcode::DsMaxRtnU32: case Decoder::Opcode::DS_MAX_RTN_U32:
case Decoder::Opcode::DsAndB32: case Decoder::Opcode::DS_AND_B32:
case Decoder::Opcode::DsAndRtnB32: case Decoder::Opcode::DS_AND_RTN_B32:
case Decoder::Opcode::DsOrB32: case Decoder::Opcode::DS_OR_B32:
case Decoder::Opcode::DsOrRtnB32: case Decoder::Opcode::DS_OR_RTN_B32:
case Decoder::Opcode::DsXorB32: case Decoder::Opcode::DS_XOR_B32:
case Decoder::Opcode::DsXorRtnB32: case Decoder::Opcode::DS_XOR_RTN_B32:
case Decoder::Opcode::DsWrxchgRtnB32: case Decoder::Opcode::DS_WRXCHG_RTN_B32:
case Decoder::Opcode::DsMinF32: case Decoder::Opcode::DS_MIN_F32:
case Decoder::Opcode::DsMaxF32: case Decoder::Opcode::DS_MAX_F32:
case Decoder::Opcode::DsSwizzleB32: case Decoder::Opcode::DS_SWIZZLE_B32:
case Decoder::Opcode::DsConsume: case Decoder::Opcode::DS_CONSUME:
case Decoder::Opcode::DsAppend: case Decoder::Opcode::DS_APPEND:
case Decoder::Opcode::DsReadSbyte: case Decoder::Opcode::DS_READ_I8:
case Decoder::Opcode::DsReadUbyte: case Decoder::Opcode::DS_READ_U8:
case Decoder::Opcode::DsReadSshort: case Decoder::Opcode::DS_READ_I16:
case Decoder::Opcode::DsReadUshort: case Decoder::Opcode::DS_READ_U16:
case Decoder::Opcode::DsRead2B32: case Decoder::Opcode::DS_READ2_B32:
case Decoder::Opcode::DsReadB32: case Decoder::Opcode::DS_READ_B32:
case Decoder::Opcode::DsReadB64: case Decoder::Opcode::DS_READ_B64:
case Decoder::Opcode::DsRead2B64: case Decoder::Opcode::DS_READ2_B64:
case Decoder::Opcode::DsRead2St64B64: case Decoder::Opcode::DS_READ2ST64_B64:
case Decoder::Opcode::DsReadB96: case Decoder::Opcode::DS_READ_B96:
case Decoder::Opcode::DsReadB128: case Decoder::Opcode::DS_READ_B128:
case Decoder::Opcode::DsWriteByte: case Decoder::Opcode::DS_WRITE_B8:
case Decoder::Opcode::DsWriteShort: case Decoder::Opcode::DS_WRITE_B16:
case Decoder::Opcode::DsWrite2B32: case Decoder::Opcode::DS_WRITE2_B32:
case Decoder::Opcode::DsWrite2St64B32: case Decoder::Opcode::DS_WRITE2ST64_B32:
case Decoder::Opcode::DsWrite2B64: case Decoder::Opcode::DS_WRITE2_B64:
case Decoder::Opcode::DsWrite2St64B64: case Decoder::Opcode::DS_WRITE2ST64_B64:
case Decoder::Opcode::DsWriteB32: case Decoder::Opcode::DS_WRITE_B32:
case Decoder::Opcode::DsWriteB64: case Decoder::Opcode::DS_WRITE_B64:
case Decoder::Opcode::DsWriteB96: case Decoder::Opcode::DS_WRITE_B96:
case Decoder::Opcode::DsWriteB128: case Decoder::Opcode::DS_WRITE_B128:
case Decoder::Opcode::DsWriteAddtidB32: case Decoder::Opcode::DS_WRITE_ADDTID_B32:
case Decoder::Opcode::DsReadAddtidB32: case Decoder::Opcode::DS_READ_ADDTID_B32:
case Decoder::Opcode::ImageGetResinfo: case Decoder::Opcode::IMAGE_GET_RESINFO:
case Decoder::Opcode::ImageGetLod: case Decoder::Opcode::IMAGE_GET_LOD:
case Decoder::Opcode::ImageLoad: case Decoder::Opcode::IMAGE_LOAD:
case Decoder::Opcode::ImageLoadMip: case Decoder::Opcode::IMAGE_LOAD_MIP:
case Decoder::Opcode::ImageStore: case Decoder::Opcode::IMAGE_STORE:
case Decoder::Opcode::ImageStoreMip: case Decoder::Opcode::IMAGE_STORE_MIP:
case Decoder::Opcode::ImageAtomicAdd: case Decoder::Opcode::IMAGE_ATOMIC_ADD:
case Decoder::Opcode::ImageAtomicUMin: case Decoder::Opcode::IMAGE_ATOMIC_UMIN:
case Decoder::Opcode::ImageAtomicUMax: case Decoder::Opcode::IMAGE_ATOMIC_UMAX:
case Decoder::Opcode::ImageAtomicAnd: case Decoder::Opcode::IMAGE_ATOMIC_AND:
case Decoder::Opcode::ImageAtomicOr: case Decoder::Opcode::IMAGE_ATOMIC_OR:
case Decoder::Opcode::ImageAtomicXor: case Decoder::Opcode::IMAGE_ATOMIC_XOR:
case Decoder::Opcode::ImageGather4Lz: case Decoder::Opcode::IMAGE_GATHER4_LZ:
case Decoder::Opcode::ImageGather4C: case Decoder::Opcode::IMAGE_GATHER4_C:
case Decoder::Opcode::ImageGather4CLz: case Decoder::Opcode::IMAGE_GATHER4_C_LZ:
case Decoder::Opcode::ImageGather4LzO: case Decoder::Opcode::IMAGE_GATHER4_LZ_O:
case Decoder::Opcode::ImageGather4CO: case Decoder::Opcode::IMAGE_GATHER4_C_O:
case Decoder::Opcode::ImageGather4CLzO: case Decoder::Opcode::IMAGE_GATHER4_C_LZ_O:
case Decoder::Opcode::ImageGather4H: case Decoder::Opcode::IMAGE_GATHER4H:
case Decoder::Opcode::ImageSample: return true; case Decoder::Opcode::IMAGE_SAMPLE: return true;
default: return false; default: return false;
} }
} }
@@ -11,430 +11,430 @@ namespace Libs::Graphics::ShaderRecompiler::IR {
namespace { namespace {
struct LowerMap { struct LowerMap {
Decoder::Opcode decoded = Decoder::Opcode::Unknown; Decoder::Opcode decoded = Decoder::Opcode::UNKNOWN;
Opcode ir = Opcode::MoveU32; Opcode ir = Opcode::MoveU32;
}; };
constexpr LowerMap LOWER_OPS[] = { constexpr LowerMap LOWER_OPS[] = {
{Decoder::Opcode::SMovB32, Opcode::MoveU32}, {Decoder::Opcode::S_MOV_B32, Opcode::MoveU32},
{Decoder::Opcode::SMovB64, Opcode::MoveU64}, {Decoder::Opcode::S_MOV_B64, Opcode::MoveU64},
{Decoder::Opcode::SWqmB64, Opcode::WqmB64}, {Decoder::Opcode::S_WQM_B64, Opcode::WqmB64},
{Decoder::Opcode::SMovkI32, Opcode::MoveU32}, {Decoder::Opcode::S_MOVK_I32, Opcode::MoveU32},
{Decoder::Opcode::SAbsI32, Opcode::AbsI32}, {Decoder::Opcode::S_ABS_I32, Opcode::AbsI32},
{Decoder::Opcode::SBrevB32, Opcode::BitReverseU32}, {Decoder::Opcode::S_BREV_B32, Opcode::BitReverseU32},
{Decoder::Opcode::SBcnt1I32B32, Opcode::BitCountU32}, {Decoder::Opcode::S_BCNT1_I32_B32, Opcode::BitCountU32},
{Decoder::Opcode::SBcnt1I32B64, Opcode::BitCountU64}, {Decoder::Opcode::S_BCNT1_I32_B64, Opcode::BitCountU64},
{Decoder::Opcode::SFf1I32B32, Opcode::FindLsbU32}, {Decoder::Opcode::S_FF1_I32_B32, Opcode::FindLsbU32},
{Decoder::Opcode::SFf1I32B64, Opcode::FindLsbU64}, {Decoder::Opcode::S_FF1_I32_B64, Opcode::FindLsbU64},
{Decoder::Opcode::SFlbitI32B64, Opcode::FindMsbFromHighU64}, {Decoder::Opcode::S_FLBIT_I32_B64, Opcode::FindMsbFromHighU64},
{Decoder::Opcode::SBitreplicateB64B32, Opcode::BitReplicateB64B32}, {Decoder::Opcode::S_BITREPLICATE_B64_B32, Opcode::BitReplicateB64B32},
{Decoder::Opcode::SNotB32, Opcode::BitwiseNotU32}, {Decoder::Opcode::S_NOT_B32, Opcode::BitwiseNotU32},
{Decoder::Opcode::SNotB64, Opcode::BitwiseNotU64}, {Decoder::Opcode::S_NOT_B64, Opcode::BitwiseNotU64},
{Decoder::Opcode::SAddU32, Opcode::IAddU32}, {Decoder::Opcode::S_ADD_U32, Opcode::IAddU32},
{Decoder::Opcode::SSubU32, Opcode::ISubU32}, {Decoder::Opcode::S_SUB_U32, Opcode::ISubU32},
{Decoder::Opcode::SAddI32, Opcode::IAddU32}, {Decoder::Opcode::S_ADD_I32, Opcode::IAddU32},
{Decoder::Opcode::SSubI32, Opcode::ISubU32}, {Decoder::Opcode::S_SUB_I32, Opcode::ISubU32},
{Decoder::Opcode::SMinI32, Opcode::IMinI32}, {Decoder::Opcode::S_MIN_I32, Opcode::IMinI32},
{Decoder::Opcode::SMaxI32, Opcode::IMaxI32}, {Decoder::Opcode::S_MAX_I32, Opcode::IMaxI32},
{Decoder::Opcode::SMinU32, Opcode::UMinU32}, {Decoder::Opcode::S_MIN_U32, Opcode::UMinU32},
{Decoder::Opcode::SMaxU32, Opcode::UMaxU32}, {Decoder::Opcode::S_MAX_U32, Opcode::UMaxU32},
{Decoder::Opcode::SAndB32, Opcode::BitwiseAndU32}, {Decoder::Opcode::S_AND_B32, Opcode::BitwiseAndU32},
{Decoder::Opcode::SAndB64, Opcode::BitwiseAndU64}, {Decoder::Opcode::S_AND_B64, Opcode::BitwiseAndU64},
{Decoder::Opcode::SAndn2B32, Opcode::BitwiseAndNotU32}, {Decoder::Opcode::S_ANDN2_B32, Opcode::BitwiseAndNotU32},
{Decoder::Opcode::SAndn2B64, Opcode::BitwiseAndNotU64}, {Decoder::Opcode::S_ANDN2_B64, Opcode::BitwiseAndNotU64},
{Decoder::Opcode::SOrB32, Opcode::BitwiseOrU32}, {Decoder::Opcode::S_OR_B32, Opcode::BitwiseOrU32},
{Decoder::Opcode::SOrB64, Opcode::BitwiseOrU64}, {Decoder::Opcode::S_OR_B64, Opcode::BitwiseOrU64},
{Decoder::Opcode::SOrn2B32, Opcode::BitwiseOrNotU32}, {Decoder::Opcode::S_ORN2_B32, Opcode::BitwiseOrNotU32},
{Decoder::Opcode::SOrn2B64, Opcode::BitwiseOrNotU64}, {Decoder::Opcode::S_ORN2_B64, Opcode::BitwiseOrNotU64},
{Decoder::Opcode::SXorB32, Opcode::BitwiseXorU32}, {Decoder::Opcode::S_XOR_B32, Opcode::BitwiseXorU32},
{Decoder::Opcode::SXorB64, Opcode::BitwiseXorU64}, {Decoder::Opcode::S_XOR_B64, Opcode::BitwiseXorU64},
{Decoder::Opcode::SNandB32, Opcode::BitwiseNandU32}, {Decoder::Opcode::S_NAND_B32, Opcode::BitwiseNandU32},
{Decoder::Opcode::SNandB64, Opcode::BitwiseNandU64}, {Decoder::Opcode::S_NAND_B64, Opcode::BitwiseNandU64},
{Decoder::Opcode::SNorB32, Opcode::BitwiseNorU32}, {Decoder::Opcode::S_NOR_B32, Opcode::BitwiseNorU32},
{Decoder::Opcode::SNorB64, Opcode::BitwiseNorU64}, {Decoder::Opcode::S_NOR_B64, Opcode::BitwiseNorU64},
{Decoder::Opcode::SXnorB32, Opcode::BitwiseXnorU32}, {Decoder::Opcode::S_XNOR_B32, Opcode::BitwiseXnorU32},
{Decoder::Opcode::SXnorB64, Opcode::BitwiseXnorU64}, {Decoder::Opcode::S_XNOR_B64, Opcode::BitwiseXnorU64},
{Decoder::Opcode::SLshlB32, Opcode::ShiftLeftLogicalU32}, {Decoder::Opcode::S_LSHL_B32, Opcode::ShiftLeftLogicalU32},
{Decoder::Opcode::SLshlB64, Opcode::ShiftLeftLogicalU64}, {Decoder::Opcode::S_LSHL_B64, Opcode::ShiftLeftLogicalU64},
{Decoder::Opcode::SLshrB32, Opcode::ShiftRightLogicalU32}, {Decoder::Opcode::S_LSHR_B32, Opcode::ShiftRightLogicalU32},
{Decoder::Opcode::SLshrB64, Opcode::ShiftRightLogicalU64}, {Decoder::Opcode::S_LSHR_B64, Opcode::ShiftRightLogicalU64},
{Decoder::Opcode::SAshrI32, Opcode::ShiftRightArithmeticI32}, {Decoder::Opcode::S_ASHR_I32, Opcode::ShiftRightArithmeticI32},
{Decoder::Opcode::SMulI32, Opcode::IMulU32}, {Decoder::Opcode::S_MUL_I32, Opcode::IMulU32},
{Decoder::Opcode::SMulHiU32, Opcode::UMulHighU32}, {Decoder::Opcode::S_MUL_HI_U32, Opcode::UMulHighU32},
{Decoder::Opcode::SMulkI32, Opcode::IMulU32}, {Decoder::Opcode::S_MULK_I32, Opcode::IMulU32},
{Decoder::Opcode::SBfeU32, Opcode::BitFieldExtractU32}, {Decoder::Opcode::S_BFE_U32, Opcode::BitFieldExtractU32},
{Decoder::Opcode::SBfeI32, Opcode::BitFieldExtractI32}, {Decoder::Opcode::S_BFE_I32, Opcode::BitFieldExtractI32},
{Decoder::Opcode::SBfeU64, Opcode::BitFieldExtractU64}, {Decoder::Opcode::S_BFE_U64, Opcode::BitFieldExtractU64},
{Decoder::Opcode::SBfmB32, Opcode::BitFieldMaskU32}, {Decoder::Opcode::S_BFM_B32, Opcode::BitFieldMaskU32},
{Decoder::Opcode::SBfmB64, Opcode::BitFieldMaskU64}, {Decoder::Opcode::S_BFM_B64, Opcode::BitFieldMaskU64},
{Decoder::Opcode::SBitcmp0B32, Opcode::BitCompare0B32}, {Decoder::Opcode::S_BITCMP0_B32, Opcode::BitCompare0B32},
{Decoder::Opcode::SBitcmp1B32, Opcode::BitCompare1B32}, {Decoder::Opcode::S_BITCMP1_B32, Opcode::BitCompare1B32},
{Decoder::Opcode::SPackLlB32B16, Opcode::PackLowLowU16}, {Decoder::Opcode::S_PACK_LL_B32_B16, Opcode::PackLowLowU16},
{Decoder::Opcode::SPackLhB32B16, Opcode::PackLowHighU16}, {Decoder::Opcode::S_PACK_LH_B32_B16, Opcode::PackLowHighU16},
{Decoder::Opcode::SPackHhB32B16, Opcode::PackHighHighU16}, {Decoder::Opcode::S_PACK_HH_B32_B16, Opcode::PackHighHighU16},
{Decoder::Opcode::SCmpEqI32, Opcode::CompareEqI32}, {Decoder::Opcode::S_CMP_EQ_I32, Opcode::CompareEqI32},
{Decoder::Opcode::SCmpLgI32, Opcode::CompareNeI32}, {Decoder::Opcode::S_CMP_LG_I32, Opcode::CompareNeI32},
{Decoder::Opcode::SCmpGtI32, Opcode::CompareGtI32}, {Decoder::Opcode::S_CMP_GT_I32, Opcode::CompareGtI32},
{Decoder::Opcode::SCmpGeI32, Opcode::CompareGeI32}, {Decoder::Opcode::S_CMP_GE_I32, Opcode::CompareGeI32},
{Decoder::Opcode::SCmpLtI32, Opcode::CompareLtI32}, {Decoder::Opcode::S_CMP_LT_I32, Opcode::CompareLtI32},
{Decoder::Opcode::SCmpLeI32, Opcode::CompareLeI32}, {Decoder::Opcode::S_CMP_LE_I32, Opcode::CompareLeI32},
{Decoder::Opcode::SCmpEqU32, Opcode::CompareEqU32}, {Decoder::Opcode::S_CMP_EQ_U32, Opcode::CompareEqU32},
{Decoder::Opcode::SCmpLgU32, Opcode::CompareNeU32}, {Decoder::Opcode::S_CMP_LG_U32, Opcode::CompareNeU32},
{Decoder::Opcode::SCmpGtU32, Opcode::CompareGtU32}, {Decoder::Opcode::S_CMP_GT_U32, Opcode::CompareGtU32},
{Decoder::Opcode::SCmpGeU32, Opcode::CompareGeU32}, {Decoder::Opcode::S_CMP_GE_U32, Opcode::CompareGeU32},
{Decoder::Opcode::SCmpLtU32, Opcode::CompareLtU32}, {Decoder::Opcode::S_CMP_LT_U32, Opcode::CompareLtU32},
{Decoder::Opcode::SCmpLeU32, Opcode::CompareLeU32}, {Decoder::Opcode::S_CMP_LE_U32, Opcode::CompareLeU32},
{Decoder::Opcode::SCmpEqU64, Opcode::CompareEqU64}, {Decoder::Opcode::S_CMP_EQ_U64, Opcode::CompareEqU64},
{Decoder::Opcode::SCmpLgU64, Opcode::CompareNeU64}, {Decoder::Opcode::S_CMP_LG_U64, Opcode::CompareNeU64},
{Decoder::Opcode::VReadfirstlaneB32, Opcode::ReadFirstLaneU32}, {Decoder::Opcode::V_READFIRSTLANE_B32, Opcode::ReadFirstLaneU32},
{Decoder::Opcode::VReadlaneB32, Opcode::ReadLaneU32}, {Decoder::Opcode::V_READLANE_B32, Opcode::ReadLaneU32},
{Decoder::Opcode::VWritelaneB32, Opcode::WriteLaneU32}, {Decoder::Opcode::V_WRITELANE_B32, Opcode::WriteLaneU32},
{Decoder::Opcode::VPermlane16B32, Opcode::Permlane16B32}, {Decoder::Opcode::V_PERMLANE16_B32, Opcode::Permlane16B32},
{Decoder::Opcode::VPermlanex16B32, Opcode::Permlanex16B32}, {Decoder::Opcode::V_PERMLANEX16_B32, Opcode::Permlanex16B32},
{Decoder::Opcode::VCvtF32I32, Opcode::ConvertI32ToF32}, {Decoder::Opcode::V_CVT_F32_I32, Opcode::ConvertI32ToF32},
{Decoder::Opcode::VCvtF32U32, Opcode::ConvertU32ToF32}, {Decoder::Opcode::V_CVT_F32_U32, Opcode::ConvertU32ToF32},
{Decoder::Opcode::VCvtU32F32, Opcode::ConvertF32ToU32}, {Decoder::Opcode::V_CVT_U32_F32, Opcode::ConvertF32ToU32},
{Decoder::Opcode::VCvtI32F32, Opcode::ConvertF32ToI32}, {Decoder::Opcode::V_CVT_I32_F32, Opcode::ConvertF32ToI32},
{Decoder::Opcode::VCvtF16F32, Opcode::ConvertF32ToF16}, {Decoder::Opcode::V_CVT_F16_F32, Opcode::ConvertF32ToF16},
{Decoder::Opcode::VCvtF32F16, Opcode::ConvertF16ToF32}, {Decoder::Opcode::V_CVT_F32_F16, Opcode::ConvertF16ToF32},
{Decoder::Opcode::VCvtF16U16, Opcode::ConvertU16ToF16}, {Decoder::Opcode::V_CVT_F16_U16, Opcode::ConvertU16ToF16},
{Decoder::Opcode::VCvtU16F16, Opcode::ConvertF16ToU16}, {Decoder::Opcode::V_CVT_U16_F16, Opcode::ConvertF16ToU16},
{Decoder::Opcode::VCvtF16I16, Opcode::ConvertI16ToF16}, {Decoder::Opcode::V_CVT_F16_I16, Opcode::ConvertI16ToF16},
{Decoder::Opcode::VCvtI16F16, Opcode::ConvertF16ToI16}, {Decoder::Opcode::V_CVT_I16_F16, Opcode::ConvertF16ToI16},
{Decoder::Opcode::VCvtRpiI32F32, Opcode::ConvertRoundPlusInfF32ToI32}, {Decoder::Opcode::V_CVT_RPI_I32_F32, Opcode::ConvertRoundPlusInfF32ToI32},
{Decoder::Opcode::VCvtFlrI32F32, Opcode::ConvertFloorF32ToI32}, {Decoder::Opcode::V_CVT_FLR_I32_F32, Opcode::ConvertFloorF32ToI32},
{Decoder::Opcode::VFrexpExpI32F32, Opcode::FrexpExpI32F32}, {Decoder::Opcode::V_FREXP_EXP_I32_F32, Opcode::FrexpExpI32F32},
{Decoder::Opcode::VFrexpMantF32, Opcode::FrexpMantF32}, {Decoder::Opcode::V_FREXP_MANT_F32, Opcode::FrexpMantF32},
{Decoder::Opcode::VCvtOffF32I4, Opcode::ConvertI4ToOffsetF32}, {Decoder::Opcode::V_CVT_OFF_F32_I4, Opcode::ConvertI4ToOffsetF32},
{Decoder::Opcode::VRcpF32, Opcode::RcpF32}, {Decoder::Opcode::V_RCP_F32, Opcode::RcpF32},
{Decoder::Opcode::VRcpIflagF32, Opcode::RcpIflagF32}, {Decoder::Opcode::V_RCP_IFLAG_F32, Opcode::RcpIflagF32},
{Decoder::Opcode::VFractF32, Opcode::FractF32}, {Decoder::Opcode::V_FRACT_F32, Opcode::FractF32},
{Decoder::Opcode::VTruncF32, Opcode::TruncF32}, {Decoder::Opcode::V_TRUNC_F32, Opcode::TruncF32},
{Decoder::Opcode::VCeilF32, Opcode::CeilF32}, {Decoder::Opcode::V_CEIL_F32, Opcode::CeilF32},
{Decoder::Opcode::VRndneF32, Opcode::RoundEvenF32}, {Decoder::Opcode::V_RNDNE_F32, Opcode::RoundEvenF32},
{Decoder::Opcode::VFloorF32, Opcode::FloorF32}, {Decoder::Opcode::V_FLOOR_F32, Opcode::FloorF32},
{Decoder::Opcode::VExpF32, Opcode::Exp2F32}, {Decoder::Opcode::V_EXP_F32, Opcode::Exp2F32},
{Decoder::Opcode::VLogF32, Opcode::Log2F32}, {Decoder::Opcode::V_LOG_F32, Opcode::Log2F32},
{Decoder::Opcode::VRsqF32, Opcode::InverseSqrtF32}, {Decoder::Opcode::V_RSQ_F32, Opcode::InverseSqrtF32},
{Decoder::Opcode::VSqrtF32, Opcode::SqrtF32}, {Decoder::Opcode::V_SQRT_F32, Opcode::SqrtF32},
{Decoder::Opcode::VRcpF16, Opcode::RcpF16}, {Decoder::Opcode::V_RCP_F16, Opcode::RcpF16},
{Decoder::Opcode::VSqrtF16, Opcode::SqrtF16}, {Decoder::Opcode::V_SQRT_F16, Opcode::SqrtF16},
{Decoder::Opcode::VRsqF16, Opcode::InverseSqrtF16}, {Decoder::Opcode::V_RSQ_F16, Opcode::InverseSqrtF16},
{Decoder::Opcode::VLogF16, Opcode::Log2F16}, {Decoder::Opcode::V_LOG_F16, Opcode::Log2F16},
{Decoder::Opcode::VExpF16, Opcode::Exp2F16}, {Decoder::Opcode::V_EXP_F16, Opcode::Exp2F16},
{Decoder::Opcode::VFloorF16, Opcode::FloorF16}, {Decoder::Opcode::V_FLOOR_F16, Opcode::FloorF16},
{Decoder::Opcode::VCeilF16, Opcode::CeilF16}, {Decoder::Opcode::V_CEIL_F16, Opcode::CeilF16},
{Decoder::Opcode::VTruncF16, Opcode::TruncF16}, {Decoder::Opcode::V_TRUNC_F16, Opcode::TruncF16},
{Decoder::Opcode::VRndneF16, Opcode::RoundEvenF16}, {Decoder::Opcode::V_RNDNE_F16, Opcode::RoundEvenF16},
{Decoder::Opcode::VSinF32, Opcode::SinF32}, {Decoder::Opcode::V_SIN_F32, Opcode::SinF32},
{Decoder::Opcode::VCosF32, Opcode::CosF32}, {Decoder::Opcode::V_COS_F32, Opcode::CosF32},
{Decoder::Opcode::VNotB32, Opcode::BitwiseNotU32}, {Decoder::Opcode::V_NOT_B32, Opcode::BitwiseNotU32},
{Decoder::Opcode::VBfrevB32, Opcode::BitReverseU32}, {Decoder::Opcode::V_BFREV_B32, Opcode::BitReverseU32},
{Decoder::Opcode::VFfblB32, Opcode::FindLsbU32}, {Decoder::Opcode::V_FFBL_B32, Opcode::FindLsbU32},
{Decoder::Opcode::VFfbhU32, Opcode::FindMsbFromHighU32}, {Decoder::Opcode::V_FFBH_U32, Opcode::FindMsbFromHighU32},
{Decoder::Opcode::VAddF32, Opcode::FAddF32}, {Decoder::Opcode::V_ADD_F32, Opcode::FAddF32},
{Decoder::Opcode::VSubF32, Opcode::FSubF32}, {Decoder::Opcode::V_SUB_F32, Opcode::FSubF32},
{Decoder::Opcode::VSubrevF32, Opcode::FSubF32}, {Decoder::Opcode::V_SUBREV_F32, Opcode::FSubF32},
{Decoder::Opcode::VMulF32, Opcode::FMulF32}, {Decoder::Opcode::V_MUL_F32, Opcode::FMulF32},
{Decoder::Opcode::VMacF32, Opcode::FMadF32}, {Decoder::Opcode::V_MAC_F32, Opcode::FMadF32},
{Decoder::Opcode::VMadmkF32, Opcode::FMadF32}, {Decoder::Opcode::V_MADMK_F32, Opcode::FMadF32},
{Decoder::Opcode::VMadakF32, Opcode::FMadF32}, {Decoder::Opcode::V_MADAK_F32, Opcode::FMadF32},
{Decoder::Opcode::VMinF32, Opcode::FMinF32}, {Decoder::Opcode::V_MIN_F32, Opcode::FMinF32},
{Decoder::Opcode::VMaxF32, Opcode::FMaxF32}, {Decoder::Opcode::V_MAX_F32, Opcode::FMaxF32},
{Decoder::Opcode::VMinI32, Opcode::IMinI32}, {Decoder::Opcode::V_MIN_I32, Opcode::IMinI32},
{Decoder::Opcode::VMaxI32, Opcode::IMaxI32}, {Decoder::Opcode::V_MAX_I32, Opcode::IMaxI32},
{Decoder::Opcode::VMadF32, Opcode::FMadF32}, {Decoder::Opcode::V_MAD_F32, Opcode::FMadF32},
{Decoder::Opcode::VMadI32I24, Opcode::IMadI24U32}, {Decoder::Opcode::V_MAD_I32_I24, Opcode::IMadI24U32},
{Decoder::Opcode::VMadU32U24, Opcode::UMadU24U32}, {Decoder::Opcode::V_MAD_U32_U24, Opcode::UMadU24U32},
{Decoder::Opcode::VCubeidF32, Opcode::CubeIdF32}, {Decoder::Opcode::V_CUBEID_F32, Opcode::CubeIdF32},
{Decoder::Opcode::VCubescF32, Opcode::CubeScF32}, {Decoder::Opcode::V_CUBESC_F32, Opcode::CubeScF32},
{Decoder::Opcode::VCubetcF32, Opcode::CubeTcF32}, {Decoder::Opcode::V_CUBETC_F32, Opcode::CubeTcF32},
{Decoder::Opcode::VCubemaF32, Opcode::CubeMaF32}, {Decoder::Opcode::V_CUBEMA_F32, Opcode::CubeMaF32},
{Decoder::Opcode::VFmaF32, Opcode::FMadF32}, {Decoder::Opcode::V_FMA_F32, Opcode::FMadF32},
{Decoder::Opcode::VBfeU32, Opcode::BitFieldExtract3U32}, {Decoder::Opcode::V_BFE_U32, Opcode::BitFieldExtract3U32},
{Decoder::Opcode::VBfeI32, Opcode::BitFieldExtract3I32}, {Decoder::Opcode::V_BFE_I32, Opcode::BitFieldExtract3I32},
{Decoder::Opcode::VBfiB32, Opcode::BitFieldInsertSelectU32}, {Decoder::Opcode::V_BFI_B32, Opcode::BitFieldInsertSelectU32},
{Decoder::Opcode::VAlignbitB32, Opcode::AlignBitU32}, {Decoder::Opcode::V_ALIGNBIT_B32, Opcode::AlignBitU32},
{Decoder::Opcode::VAlignbyteB32, Opcode::AlignByteU32}, {Decoder::Opcode::V_ALIGNBYTE_B32, Opcode::AlignByteU32},
{Decoder::Opcode::VMin3F32, Opcode::FMin3F32}, {Decoder::Opcode::V_MIN3_F32, Opcode::FMin3F32},
{Decoder::Opcode::VMin3I32, Opcode::IMin3I32}, {Decoder::Opcode::V_MIN3_I32, Opcode::IMin3I32},
{Decoder::Opcode::VMin3U32, Opcode::UMin3U32}, {Decoder::Opcode::V_MIN3_U32, Opcode::UMin3U32},
{Decoder::Opcode::VMin3F16, Opcode::Min3F16}, {Decoder::Opcode::V_MIN3_F16, Opcode::Min3F16},
{Decoder::Opcode::VMax3F32, Opcode::FMax3F32}, {Decoder::Opcode::V_MAX3_F32, Opcode::FMax3F32},
{Decoder::Opcode::VMax3I32, Opcode::IMax3I32}, {Decoder::Opcode::V_MAX3_I32, Opcode::IMax3I32},
{Decoder::Opcode::VMax3U32, Opcode::UMax3U32}, {Decoder::Opcode::V_MAX3_U32, Opcode::UMax3U32},
{Decoder::Opcode::VMax3F16, Opcode::Max3F16}, {Decoder::Opcode::V_MAX3_F16, Opcode::Max3F16},
{Decoder::Opcode::VMed3F32, Opcode::FMed3F32}, {Decoder::Opcode::V_MED3_F32, Opcode::FMed3F32},
{Decoder::Opcode::VMed3I32, Opcode::IMed3I32}, {Decoder::Opcode::V_MED3_I32, Opcode::IMed3I32},
{Decoder::Opcode::VMed3U32, Opcode::UMed3U32}, {Decoder::Opcode::V_MED3_U32, Opcode::UMed3U32},
{Decoder::Opcode::VMed3F16, Opcode::Med3F16}, {Decoder::Opcode::V_MED3_F16, Opcode::Med3F16},
{Decoder::Opcode::VMed3I16, Opcode::IMed3I16}, {Decoder::Opcode::V_MED3_I16, Opcode::IMed3I16},
{Decoder::Opcode::VSadU32, Opcode::SadU32}, {Decoder::Opcode::V_SAD_U32, Opcode::SadU32},
{Decoder::Opcode::VAdd3U32, Opcode::IAdd3U32}, {Decoder::Opcode::V_ADD3_U32, Opcode::IAdd3U32},
{Decoder::Opcode::VLshlAddU32, Opcode::ShiftLeftAddU32}, {Decoder::Opcode::V_LSHL_ADD_U32, Opcode::ShiftLeftAddU32},
{Decoder::Opcode::VAddLshlU32, Opcode::AddShiftLeftU32}, {Decoder::Opcode::V_ADD_LSHL_U32, Opcode::AddShiftLeftU32},
{Decoder::Opcode::VXadU32, Opcode::XorAddU32}, {Decoder::Opcode::V_XAD_U32, Opcode::XorAddU32},
{Decoder::Opcode::VLshlOrB32, Opcode::ShiftLeftOrU32}, {Decoder::Opcode::V_LSHL_OR_B32, Opcode::ShiftLeftOrU32},
{Decoder::Opcode::VAndOrB32, Opcode::BitwiseAndOrU32}, {Decoder::Opcode::V_AND_OR_B32, Opcode::BitwiseAndOrU32},
{Decoder::Opcode::VOr3B32, Opcode::BitwiseOr3U32}, {Decoder::Opcode::V_OR3_B32, Opcode::BitwiseOr3U32},
{Decoder::Opcode::VXor3B32, Opcode::BitwiseXor3U32}, {Decoder::Opcode::V_XOR3_B32, Opcode::BitwiseXor3U32},
{Decoder::Opcode::VAddNcU32, Opcode::IAddU32}, {Decoder::Opcode::V_ADD_NC_U32, Opcode::IAddU32},
{Decoder::Opcode::VSubNcU32, Opcode::ISubU32}, {Decoder::Opcode::V_SUB_NC_U32, Opcode::ISubU32},
{Decoder::Opcode::VSubrevNcU32, Opcode::ISubU32}, {Decoder::Opcode::V_SUBREV_NC_U32, Opcode::ISubU32},
{Decoder::Opcode::VAddNcU16, Opcode::IAddU16}, {Decoder::Opcode::V_ADD_NC_U16, Opcode::IAddU16},
{Decoder::Opcode::VSubNcU16, Opcode::ISubI16}, {Decoder::Opcode::V_SUB_NC_U16, Opcode::ISubI16},
{Decoder::Opcode::VMaxU16, Opcode::UMaxU16}, {Decoder::Opcode::V_MAX_U16, Opcode::UMaxU16},
{Decoder::Opcode::VMaxI16, Opcode::IMaxI16}, {Decoder::Opcode::V_MAX_I16, Opcode::IMaxI16},
{Decoder::Opcode::VMinU16, Opcode::UMinU16}, {Decoder::Opcode::V_MIN_U16, Opcode::UMinU16},
{Decoder::Opcode::VMinI16, Opcode::IMinI16}, {Decoder::Opcode::V_MIN_I16, Opcode::IMinI16},
{Decoder::Opcode::VAddNcI16, Opcode::IAddU16}, {Decoder::Opcode::V_ADD_NC_I16, Opcode::IAddU16},
{Decoder::Opcode::VSubNcI16, Opcode::ISubI16}, {Decoder::Opcode::V_SUB_NC_I16, Opcode::ISubI16},
{Decoder::Opcode::VMulI32I24, Opcode::IMulI24U32}, {Decoder::Opcode::V_MUL_I32_I24, Opcode::IMulI24U32},
{Decoder::Opcode::VMulU32U24, Opcode::UMulU24U32}, {Decoder::Opcode::V_MUL_U32_U24, Opcode::UMulU24U32},
{Decoder::Opcode::VMulLoU32, Opcode::IMulU32}, {Decoder::Opcode::V_MUL_LO_U32, Opcode::IMulU32},
{Decoder::Opcode::VMulHiU32, Opcode::UMulHighU32}, {Decoder::Opcode::V_MUL_HI_U32, Opcode::UMulHighU32},
{Decoder::Opcode::VMulLoI32, Opcode::IMulU32}, {Decoder::Opcode::V_MUL_LO_I32, Opcode::IMulU32},
{Decoder::Opcode::VMulHiI32, Opcode::SMulHighI32}, {Decoder::Opcode::V_MUL_HI_I32, Opcode::SMulHighI32},
{Decoder::Opcode::VAddI32, Opcode::IAddU32}, {Decoder::Opcode::V_ADD_I32, Opcode::IAddU32},
{Decoder::Opcode::VSubI32, Opcode::ISubU32}, {Decoder::Opcode::V_SUB_I32, Opcode::ISubU32},
{Decoder::Opcode::VSubrevI32, Opcode::ISubU32}, {Decoder::Opcode::V_SUBREV_I32, Opcode::ISubU32},
{Decoder::Opcode::VBfmB32, Opcode::BitFieldMaskU32}, {Decoder::Opcode::V_BFM_B32, Opcode::BitFieldMaskU32},
{Decoder::Opcode::VCvtPkrtzF16F32, Opcode::PackF32ToF16Rtz}, {Decoder::Opcode::V_CVT_PKRTZ_F16_F32, Opcode::PackF32ToF16Rtz},
{Decoder::Opcode::VLdexpF32, Opcode::LdexpF32}, {Decoder::Opcode::V_LDEXP_F32, Opcode::LdexpF32},
{Decoder::Opcode::VCvtPknormI16F32, Opcode::PackSnorm2x16F32}, {Decoder::Opcode::V_CVT_PKNORM_I16_F32, Opcode::PackSnorm2x16F32},
{Decoder::Opcode::VCvtPknormU16F32, Opcode::PackUnorm2x16F32}, {Decoder::Opcode::V_CVT_PKNORM_U16_F32, Opcode::PackUnorm2x16F32},
{Decoder::Opcode::VCvtPkU16U32, Opcode::PackU16U32}, {Decoder::Opcode::V_CVT_PK_U16_U32, Opcode::PackU16U32},
{Decoder::Opcode::VCvtPkI16I32, Opcode::PackU16U32}, {Decoder::Opcode::V_CVT_PK_I16_I32, Opcode::PackU16U32},
{Decoder::Opcode::VCvtPkU8F32, Opcode::PackU8F32}, {Decoder::Opcode::V_CVT_PK_U8_F32, Opcode::PackU8F32},
{Decoder::Opcode::VPackB32F16, Opcode::PackB32F16}, {Decoder::Opcode::V_PACK_B32_F16, Opcode::PackB32F16},
{Decoder::Opcode::VPkMadI16, Opcode::PackedMadI16}, {Decoder::Opcode::V_PK_MAD_I16, Opcode::PackedMadI16},
{Decoder::Opcode::VPkMulLoU16, Opcode::PackedMulLoU16}, {Decoder::Opcode::V_PK_MUL_LO_U16, Opcode::PackedMulLoU16},
{Decoder::Opcode::VPkAddI16, Opcode::PackedAddI16}, {Decoder::Opcode::V_PK_ADD_I16, Opcode::PackedAddI16},
{Decoder::Opcode::VPkSubI16, Opcode::PackedSubI16}, {Decoder::Opcode::V_PK_SUB_I16, Opcode::PackedSubI16},
{Decoder::Opcode::VPkLshlrevB16, Opcode::PackedLshlrevB16}, {Decoder::Opcode::V_PK_LSHLREV_B16, Opcode::PackedLshlrevB16},
{Decoder::Opcode::VPkLshrrevB16, Opcode::PackedLshrrevB16}, {Decoder::Opcode::V_PK_LSHRREV_B16, Opcode::PackedLshrrevB16},
{Decoder::Opcode::VPkAshrrevI16, Opcode::PackedAshrrevI16}, {Decoder::Opcode::V_PK_ASHRREV_I16, Opcode::PackedAshrrevI16},
{Decoder::Opcode::VPkMaxI16, Opcode::PackedMaxI16}, {Decoder::Opcode::V_PK_MAX_I16, Opcode::PackedMaxI16},
{Decoder::Opcode::VPkMinI16, Opcode::PackedMinI16}, {Decoder::Opcode::V_PK_MIN_I16, Opcode::PackedMinI16},
{Decoder::Opcode::VPkMadU16, Opcode::PackedMadU16}, {Decoder::Opcode::V_PK_MAD_U16, Opcode::PackedMadU16},
{Decoder::Opcode::VPkAddU16, Opcode::PackedAddU16}, {Decoder::Opcode::V_PK_ADD_U16, Opcode::PackedAddU16},
{Decoder::Opcode::VPkSubU16, Opcode::PackedSubU16}, {Decoder::Opcode::V_PK_SUB_U16, Opcode::PackedSubU16},
{Decoder::Opcode::VPkMaxU16, Opcode::PackedMaxU16}, {Decoder::Opcode::V_PK_MAX_U16, Opcode::PackedMaxU16},
{Decoder::Opcode::VPkMinU16, Opcode::PackedMinU16}, {Decoder::Opcode::V_PK_MIN_U16, Opcode::PackedMinU16},
{Decoder::Opcode::VPkAddF16, Opcode::PackedAddF16}, {Decoder::Opcode::V_PK_ADD_F16, Opcode::PackedAddF16},
{Decoder::Opcode::VPkMulF16, Opcode::PackedMulF16}, {Decoder::Opcode::V_PK_MUL_F16, Opcode::PackedMulF16},
{Decoder::Opcode::VPkMinF16, Opcode::PackedMinF16}, {Decoder::Opcode::V_PK_MIN_F16, Opcode::PackedMinF16},
{Decoder::Opcode::VPkMaxF16, Opcode::PackedMaxF16}, {Decoder::Opcode::V_PK_MAX_F16, Opcode::PackedMaxF16},
{Decoder::Opcode::VPkFmaF16, Opcode::PackedFmaF16}, {Decoder::Opcode::V_PK_FMA_F16, Opcode::PackedFmaF16},
{Decoder::Opcode::VPkFmacF16, Opcode::PackedFmaF16}, {Decoder::Opcode::V_PK_FMAC_F16, Opcode::PackedFmaF16},
{Decoder::Opcode::VAddF16, Opcode::AddF16}, {Decoder::Opcode::V_ADD_F16, Opcode::AddF16},
{Decoder::Opcode::VSubF16, Opcode::SubF16}, {Decoder::Opcode::V_SUB_F16, Opcode::SubF16},
{Decoder::Opcode::VSubrevF16, Opcode::SubF16}, {Decoder::Opcode::V_SUBREV_F16, Opcode::SubF16},
{Decoder::Opcode::VMulF16, Opcode::MulF16}, {Decoder::Opcode::V_MUL_F16, Opcode::MulF16},
{Decoder::Opcode::VFmacF16, Opcode::FmaF16}, {Decoder::Opcode::V_FMAC_F16, Opcode::FmaF16},
{Decoder::Opcode::VFmamkF16, Opcode::FmaF16}, {Decoder::Opcode::V_FMAMK_F16, Opcode::FmaF16},
{Decoder::Opcode::VFmaakF16, Opcode::FmaF16}, {Decoder::Opcode::V_FMAAK_F16, Opcode::FmaF16},
{Decoder::Opcode::VFmaF16, Opcode::FmaF16}, {Decoder::Opcode::V_FMA_F16, Opcode::FmaF16},
{Decoder::Opcode::VMadMixloF16, Opcode::MadMixF16}, {Decoder::Opcode::V_MAD_MIXLO_F16, Opcode::MadMixF16},
{Decoder::Opcode::VMadMixhiF16, Opcode::MadMixF16}, {Decoder::Opcode::V_MAD_MIXHI_F16, Opcode::MadMixF16},
{Decoder::Opcode::VAndB32, Opcode::BitwiseAndU32}, {Decoder::Opcode::V_AND_B32, Opcode::BitwiseAndU32},
{Decoder::Opcode::VOrB32, Opcode::BitwiseOrU32}, {Decoder::Opcode::V_OR_B32, Opcode::BitwiseOrU32},
{Decoder::Opcode::VXorB32, Opcode::BitwiseXorU32}, {Decoder::Opcode::V_XOR_B32, Opcode::BitwiseXorU32},
{Decoder::Opcode::VXnorB32, Opcode::BitwiseXnorU32}, {Decoder::Opcode::V_XNOR_B32, Opcode::BitwiseXnorU32},
{Decoder::Opcode::VBcntU32B32, Opcode::BitCountAddU32}, {Decoder::Opcode::V_BCNT_U32_B32, Opcode::BitCountAddU32},
{Decoder::Opcode::VMbcntLoU32B32, Opcode::MaskedBitCountLowU32}, {Decoder::Opcode::V_MBCNT_LO_U32_B32, Opcode::MaskedBitCountLowU32},
{Decoder::Opcode::VMbcntHiU32B32, Opcode::MaskedBitCountHighU32}, {Decoder::Opcode::V_MBCNT_HI_U32_B32, Opcode::MaskedBitCountHighU32},
{Decoder::Opcode::VLshlB32, Opcode::ShiftLeftLogicalU32}, {Decoder::Opcode::V_LSHL_B32, Opcode::ShiftLeftLogicalU32},
{Decoder::Opcode::VLshlrevB32, Opcode::ShiftLeftLogicalU32}, {Decoder::Opcode::V_LSHLREV_B32, Opcode::ShiftLeftLogicalU32},
{Decoder::Opcode::VLshlrevB16, Opcode::ShiftLeftLogicalU16}, {Decoder::Opcode::V_LSHLREV_B16, Opcode::ShiftLeftLogicalU16},
{Decoder::Opcode::VLshrB32, Opcode::ShiftRightLogicalU32}, {Decoder::Opcode::V_LSHR_B32, Opcode::ShiftRightLogicalU32},
{Decoder::Opcode::VLshrrevB32, Opcode::ShiftRightLogicalU32}, {Decoder::Opcode::V_LSHRREV_B32, Opcode::ShiftRightLogicalU32},
{Decoder::Opcode::VLshrrevB16, Opcode::ShiftRightLogicalU16}, {Decoder::Opcode::V_LSHRREV_B16, Opcode::ShiftRightLogicalU16},
{Decoder::Opcode::VAshrI32, Opcode::ShiftRightArithmeticI32}, {Decoder::Opcode::V_ASHR_I32, Opcode::ShiftRightArithmeticI32},
{Decoder::Opcode::VAshrrevI32, Opcode::ShiftRightArithmeticI32}, {Decoder::Opcode::V_ASHRREV_I32, Opcode::ShiftRightArithmeticI32},
{Decoder::Opcode::VAshrrevI16, Opcode::ShiftRightArithmeticI16}, {Decoder::Opcode::V_ASHRREV_I16, Opcode::ShiftRightArithmeticI16},
{Decoder::Opcode::VMinU32, Opcode::UMinU32}, {Decoder::Opcode::V_MIN_U32, Opcode::UMinU32},
{Decoder::Opcode::VMaxU32, Opcode::UMaxU32}, {Decoder::Opcode::V_MAX_U32, Opcode::UMaxU32},
{Decoder::Opcode::VMaxF16, Opcode::MaxF16}, {Decoder::Opcode::V_MAX_F16, Opcode::MaxF16},
{Decoder::Opcode::VMinF16, Opcode::MinF16}, {Decoder::Opcode::V_MIN_F16, Opcode::MinF16},
{Decoder::Opcode::VCmpFF32, Opcode::CompareFalse}, {Decoder::Opcode::V_CMP_F_F32, Opcode::CompareFalse},
{Decoder::Opcode::VCmpLtF32, Opcode::CompareLtF32}, {Decoder::Opcode::V_CMP_LT_F32, Opcode::CompareLtF32},
{Decoder::Opcode::VCmpEqF32, Opcode::CompareEqF32}, {Decoder::Opcode::V_CMP_EQ_F32, Opcode::CompareEqF32},
{Decoder::Opcode::VCmpLeF32, Opcode::CompareLeF32}, {Decoder::Opcode::V_CMP_LE_F32, Opcode::CompareLeF32},
{Decoder::Opcode::VCmpGtF32, Opcode::CompareGtF32}, {Decoder::Opcode::V_CMP_GT_F32, Opcode::CompareGtF32},
{Decoder::Opcode::VCmpLgF32, Opcode::CompareNeF32}, {Decoder::Opcode::V_CMP_LG_F32, Opcode::CompareNeF32},
{Decoder::Opcode::VCmpGeF32, Opcode::CompareGeF32}, {Decoder::Opcode::V_CMP_GE_F32, Opcode::CompareGeF32},
{Decoder::Opcode::VCmpOF32, Opcode::CompareOrderedF32}, {Decoder::Opcode::V_CMP_O_F32, Opcode::CompareOrderedF32},
{Decoder::Opcode::VCmpUF32, Opcode::CompareUnorderedF32}, {Decoder::Opcode::V_CMP_U_F32, Opcode::CompareUnorderedF32},
{Decoder::Opcode::VCmpNgeF32, Opcode::CompareUnordLtF32}, {Decoder::Opcode::V_CMP_NGE_F32, Opcode::CompareUnordLtF32},
{Decoder::Opcode::VCmpNlgF32, Opcode::CompareUnordEqF32}, {Decoder::Opcode::V_CMP_NLG_F32, Opcode::CompareUnordEqF32},
{Decoder::Opcode::VCmpNgtF32, Opcode::CompareUnordLeF32}, {Decoder::Opcode::V_CMP_NGT_F32, Opcode::CompareUnordLeF32},
{Decoder::Opcode::VCmpNleF32, Opcode::CompareUnordGtF32}, {Decoder::Opcode::V_CMP_NLE_F32, Opcode::CompareUnordGtF32},
{Decoder::Opcode::VCmpNeqF32, Opcode::CompareUnordNeF32}, {Decoder::Opcode::V_CMP_NEQ_F32, Opcode::CompareUnordNeF32},
{Decoder::Opcode::VCmpNltF32, Opcode::CompareUnordGeF32}, {Decoder::Opcode::V_CMP_NLT_F32, Opcode::CompareUnordGeF32},
{Decoder::Opcode::VCmpTruF32, Opcode::CompareTrue}, {Decoder::Opcode::V_CMP_TRU_F32, Opcode::CompareTrue},
{Decoder::Opcode::VCmpClassF32, Opcode::CompareClassF32}, {Decoder::Opcode::V_CMP_CLASS_F32, Opcode::CompareClassF32},
{Decoder::Opcode::VCmpLtF16, Opcode::CompareLtF16}, {Decoder::Opcode::V_CMP_LT_F16, Opcode::CompareLtF16},
{Decoder::Opcode::VCmpEqF16, Opcode::CompareEqF16}, {Decoder::Opcode::V_CMP_EQ_F16, Opcode::CompareEqF16},
{Decoder::Opcode::VCmpLeF16, Opcode::CompareLeF16}, {Decoder::Opcode::V_CMP_LE_F16, Opcode::CompareLeF16},
{Decoder::Opcode::VCmpGtF16, Opcode::CompareGtF16}, {Decoder::Opcode::V_CMP_GT_F16, Opcode::CompareGtF16},
{Decoder::Opcode::VCmpLgF16, Opcode::CompareNeF16}, {Decoder::Opcode::V_CMP_LG_F16, Opcode::CompareNeF16},
{Decoder::Opcode::VCmpGeF16, Opcode::CompareGeF16}, {Decoder::Opcode::V_CMP_GE_F16, Opcode::CompareGeF16},
{Decoder::Opcode::VCmpNeqF16, Opcode::CompareUnordNeF16}, {Decoder::Opcode::V_CMP_NEQ_F16, Opcode::CompareUnordNeF16},
{Decoder::Opcode::VCmpxLtF16, Opcode::CompareMaskLtF16}, {Decoder::Opcode::V_CMPX_LT_F16, Opcode::CompareMaskLtF16},
{Decoder::Opcode::VCmpxEqF16, Opcode::CompareMaskEqF16}, {Decoder::Opcode::V_CMPX_EQ_F16, Opcode::CompareMaskEqF16},
{Decoder::Opcode::VCmpxLeF16, Opcode::CompareMaskLeF16}, {Decoder::Opcode::V_CMPX_LE_F16, Opcode::CompareMaskLeF16},
{Decoder::Opcode::VCmpxGtF16, Opcode::CompareMaskGtF16}, {Decoder::Opcode::V_CMPX_GT_F16, Opcode::CompareMaskGtF16},
{Decoder::Opcode::VCmpxGeF16, Opcode::CompareMaskGeF16}, {Decoder::Opcode::V_CMPX_GE_F16, Opcode::CompareMaskGeF16},
{Decoder::Opcode::VCmpxNeqF16, Opcode::CompareMaskUnordNeF16}, {Decoder::Opcode::V_CMPX_NEQ_F16, Opcode::CompareMaskUnordNeF16},
{Decoder::Opcode::VCmpxNltF16, Opcode::CompareMaskUnordGeF16}, {Decoder::Opcode::V_CMPX_NLT_F16, Opcode::CompareMaskUnordGeF16},
{Decoder::Opcode::VCmpxLtF32, Opcode::CompareMaskLtF32}, {Decoder::Opcode::V_CMPX_LT_F32, Opcode::CompareMaskLtF32},
{Decoder::Opcode::VCmpxEqF32, Opcode::CompareMaskEqF32}, {Decoder::Opcode::V_CMPX_EQ_F32, Opcode::CompareMaskEqF32},
{Decoder::Opcode::VCmpxLeF32, Opcode::CompareMaskLeF32}, {Decoder::Opcode::V_CMPX_LE_F32, Opcode::CompareMaskLeF32},
{Decoder::Opcode::VCmpxGtF32, Opcode::CompareMaskGtF32}, {Decoder::Opcode::V_CMPX_GT_F32, Opcode::CompareMaskGtF32},
{Decoder::Opcode::VCmpxLgF32, Opcode::CompareMaskNeF32}, {Decoder::Opcode::V_CMPX_LG_F32, Opcode::CompareMaskNeF32},
{Decoder::Opcode::VCmpxGeF32, Opcode::CompareMaskGeF32}, {Decoder::Opcode::V_CMPX_GE_F32, Opcode::CompareMaskGeF32},
{Decoder::Opcode::VCmpxNgeF32, Opcode::CompareMaskUnordLtF32}, {Decoder::Opcode::V_CMPX_NGE_F32, Opcode::CompareMaskUnordLtF32},
{Decoder::Opcode::VCmpxNlgF32, Opcode::CompareMaskUnordEqF32}, {Decoder::Opcode::V_CMPX_NLG_F32, Opcode::CompareMaskUnordEqF32},
{Decoder::Opcode::VCmpxNgtF32, Opcode::CompareMaskUnordLeF32}, {Decoder::Opcode::V_CMPX_NGT_F32, Opcode::CompareMaskUnordLeF32},
{Decoder::Opcode::VCmpxNleF32, Opcode::CompareMaskUnordGtF32}, {Decoder::Opcode::V_CMPX_NLE_F32, Opcode::CompareMaskUnordGtF32},
{Decoder::Opcode::VCmpxNeqF32, Opcode::CompareMaskUnordNeF32}, {Decoder::Opcode::V_CMPX_NEQ_F32, Opcode::CompareMaskUnordNeF32},
{Decoder::Opcode::VCmpxNltF32, Opcode::CompareMaskUnordGeF32}, {Decoder::Opcode::V_CMPX_NLT_F32, Opcode::CompareMaskUnordGeF32},
{Decoder::Opcode::VCmpFI32, Opcode::CompareFalse}, {Decoder::Opcode::V_CMP_F_I32, Opcode::CompareFalse},
{Decoder::Opcode::VCmpLtI32, Opcode::CompareLtI32}, {Decoder::Opcode::V_CMP_LT_I32, Opcode::CompareLtI32},
{Decoder::Opcode::VCmpEqI32, Opcode::CompareEqI32}, {Decoder::Opcode::V_CMP_EQ_I32, Opcode::CompareEqI32},
{Decoder::Opcode::VCmpLeI32, Opcode::CompareLeI32}, {Decoder::Opcode::V_CMP_LE_I32, Opcode::CompareLeI32},
{Decoder::Opcode::VCmpGtI32, Opcode::CompareGtI32}, {Decoder::Opcode::V_CMP_GT_I32, Opcode::CompareGtI32},
{Decoder::Opcode::VCmpNeI32, Opcode::CompareNeI32}, {Decoder::Opcode::V_CMP_NE_I32, Opcode::CompareNeI32},
{Decoder::Opcode::VCmpGeI32, Opcode::CompareGeI32}, {Decoder::Opcode::V_CMP_GE_I32, Opcode::CompareGeI32},
{Decoder::Opcode::VCmpTI32, Opcode::CompareTrue}, {Decoder::Opcode::V_CMP_T_I32, Opcode::CompareTrue},
{Decoder::Opcode::VCmpLtI16, Opcode::CompareLtI16}, {Decoder::Opcode::V_CMP_LT_I16, Opcode::CompareLtI16},
{Decoder::Opcode::VCmpEqI16, Opcode::CompareEqI16}, {Decoder::Opcode::V_CMP_EQ_I16, Opcode::CompareEqI16},
{Decoder::Opcode::VCmpLeI16, Opcode::CompareLeI16}, {Decoder::Opcode::V_CMP_LE_I16, Opcode::CompareLeI16},
{Decoder::Opcode::VCmpGtI16, Opcode::CompareGtI16}, {Decoder::Opcode::V_CMP_GT_I16, Opcode::CompareGtI16},
{Decoder::Opcode::VCmpNeI16, Opcode::CompareNeI16}, {Decoder::Opcode::V_CMP_NE_I16, Opcode::CompareNeI16},
{Decoder::Opcode::VCmpGeI16, Opcode::CompareGeI16}, {Decoder::Opcode::V_CMP_GE_I16, Opcode::CompareGeI16},
{Decoder::Opcode::VCmpxLtI32, Opcode::CompareMaskLtI32}, {Decoder::Opcode::V_CMPX_LT_I32, Opcode::CompareMaskLtI32},
{Decoder::Opcode::VCmpxEqI32, Opcode::CompareMaskEqI32}, {Decoder::Opcode::V_CMPX_EQ_I32, Opcode::CompareMaskEqI32},
{Decoder::Opcode::VCmpxLeI32, Opcode::CompareMaskLeI32}, {Decoder::Opcode::V_CMPX_LE_I32, Opcode::CompareMaskLeI32},
{Decoder::Opcode::VCmpxGtI32, Opcode::CompareMaskGtI32}, {Decoder::Opcode::V_CMPX_GT_I32, Opcode::CompareMaskGtI32},
{Decoder::Opcode::VCmpxNeI32, Opcode::CompareMaskNeI32}, {Decoder::Opcode::V_CMPX_NE_I32, Opcode::CompareMaskNeI32},
{Decoder::Opcode::VCmpxGeI32, Opcode::CompareMaskGeI32}, {Decoder::Opcode::V_CMPX_GE_I32, Opcode::CompareMaskGeI32},
{Decoder::Opcode::VCmpLtU16, Opcode::CompareLtU16}, {Decoder::Opcode::V_CMP_LT_U16, Opcode::CompareLtU16},
{Decoder::Opcode::VCmpEqU16, Opcode::CompareEqU16}, {Decoder::Opcode::V_CMP_EQ_U16, Opcode::CompareEqU16},
{Decoder::Opcode::VCmpLeU16, Opcode::CompareLeU16}, {Decoder::Opcode::V_CMP_LE_U16, Opcode::CompareLeU16},
{Decoder::Opcode::VCmpGtU16, Opcode::CompareGtU16}, {Decoder::Opcode::V_CMP_GT_U16, Opcode::CompareGtU16},
{Decoder::Opcode::VCmpNeU16, Opcode::CompareNeU16}, {Decoder::Opcode::V_CMP_NE_U16, Opcode::CompareNeU16},
{Decoder::Opcode::VCmpGeU16, Opcode::CompareGeU16}, {Decoder::Opcode::V_CMP_GE_U16, Opcode::CompareGeU16},
{Decoder::Opcode::VCmpFU32, Opcode::CompareFalse}, {Decoder::Opcode::V_CMP_F_U32, Opcode::CompareFalse},
{Decoder::Opcode::VCmpLtU32, Opcode::CompareLtU32}, {Decoder::Opcode::V_CMP_LT_U32, Opcode::CompareLtU32},
{Decoder::Opcode::VCmpEqU32, Opcode::CompareEqU32}, {Decoder::Opcode::V_CMP_EQ_U32, Opcode::CompareEqU32},
{Decoder::Opcode::VCmpLeU32, Opcode::CompareLeU32}, {Decoder::Opcode::V_CMP_LE_U32, Opcode::CompareLeU32},
{Decoder::Opcode::VCmpGtU32, Opcode::CompareGtU32}, {Decoder::Opcode::V_CMP_GT_U32, Opcode::CompareGtU32},
{Decoder::Opcode::VCmpNeU32, Opcode::CompareNeU32}, {Decoder::Opcode::V_CMP_NE_U32, Opcode::CompareNeU32},
{Decoder::Opcode::VCmpGeU32, Opcode::CompareGeU32}, {Decoder::Opcode::V_CMP_GE_U32, Opcode::CompareGeU32},
{Decoder::Opcode::VCmpTU32, Opcode::CompareTrue}, {Decoder::Opcode::V_CMP_T_U32, Opcode::CompareTrue},
{Decoder::Opcode::VCmpEqI64, Opcode::CompareEqU64}, {Decoder::Opcode::V_CMP_EQ_I64, Opcode::CompareEqU64},
{Decoder::Opcode::VCmpGtU64, Opcode::CompareGtU64}, {Decoder::Opcode::V_CMP_GT_U64, Opcode::CompareGtU64},
{Decoder::Opcode::VCmpNeU64, Opcode::CompareNeU64}, {Decoder::Opcode::V_CMP_NE_U64, Opcode::CompareNeU64},
{Decoder::Opcode::VCmpxLtU32, Opcode::CompareMaskLtU32}, {Decoder::Opcode::V_CMPX_LT_U32, Opcode::CompareMaskLtU32},
{Decoder::Opcode::VCmpxEqU32, Opcode::CompareMaskEqU32}, {Decoder::Opcode::V_CMPX_EQ_U32, Opcode::CompareMaskEqU32},
{Decoder::Opcode::VCmpxLeU32, Opcode::CompareMaskLeU32}, {Decoder::Opcode::V_CMPX_LE_U32, Opcode::CompareMaskLeU32},
{Decoder::Opcode::VCmpxGtU32, Opcode::CompareMaskGtU32}, {Decoder::Opcode::V_CMPX_GT_U32, Opcode::CompareMaskGtU32},
{Decoder::Opcode::VCmpxNeU32, Opcode::CompareMaskNeU32}, {Decoder::Opcode::V_CMPX_NE_U32, Opcode::CompareMaskNeU32},
{Decoder::Opcode::VCmpxGeU32, Opcode::CompareMaskGeU32}, {Decoder::Opcode::V_CMPX_GE_U32, Opcode::CompareMaskGeU32},
{Decoder::Opcode::SLoadDword, Opcode::SLoadDword}, {Decoder::Opcode::S_LOAD_DWORD, Opcode::SLoadDword},
{Decoder::Opcode::SBufferLoadDword, Opcode::SBufferLoadDword}, {Decoder::Opcode::S_BUFFER_LOAD_DWORD, Opcode::SBufferLoadDword},
{Decoder::Opcode::BufferLoadDword, Opcode::BufferLoadDword}, {Decoder::Opcode::BUFFER_LOAD_DWORD, Opcode::BufferLoadDword},
{Decoder::Opcode::BufferLoadSbyte, Opcode::BufferLoadSbyte}, {Decoder::Opcode::BUFFER_LOAD_SBYTE, Opcode::BufferLoadSbyte},
{Decoder::Opcode::BufferLoadSshort, Opcode::BufferLoadSshort}, {Decoder::Opcode::BUFFER_LOAD_SSHORT, Opcode::BufferLoadSshort},
{Decoder::Opcode::BufferStoreByte, Opcode::BufferStoreByte}, {Decoder::Opcode::BUFFER_STORE_BYTE, Opcode::BufferStoreByte},
{Decoder::Opcode::BufferStoreShort, Opcode::BufferStoreShort}, {Decoder::Opcode::BUFFER_STORE_SHORT, Opcode::BufferStoreShort},
{Decoder::Opcode::BufferStoreDword, Opcode::BufferStoreDword}, {Decoder::Opcode::BUFFER_STORE_DWORD, Opcode::BufferStoreDword},
{Decoder::Opcode::BufferAtomicSwap, Opcode::AtomicSwapU32}, {Decoder::Opcode::BUFFER_ATOMIC_SWAP, Opcode::AtomicSwapU32},
{Decoder::Opcode::BufferAtomicAdd, Opcode::AtomicAddU32}, {Decoder::Opcode::BUFFER_ATOMIC_ADD, Opcode::AtomicAddU32},
{Decoder::Opcode::BufferAtomicSub, Opcode::AtomicSubU32}, {Decoder::Opcode::BUFFER_ATOMIC_SUB, Opcode::AtomicSubU32},
{Decoder::Opcode::BufferAtomicSMin, Opcode::AtomicSMinI32}, {Decoder::Opcode::BUFFER_ATOMIC_SMIN, Opcode::AtomicSMinI32},
{Decoder::Opcode::BufferAtomicUMin, Opcode::AtomicUMinU32}, {Decoder::Opcode::BUFFER_ATOMIC_UMIN, Opcode::AtomicUMinU32},
{Decoder::Opcode::BufferAtomicSMax, Opcode::AtomicSMaxI32}, {Decoder::Opcode::BUFFER_ATOMIC_SMAX, Opcode::AtomicSMaxI32},
{Decoder::Opcode::BufferAtomicUMax, Opcode::AtomicUMaxU32}, {Decoder::Opcode::BUFFER_ATOMIC_UMAX, Opcode::AtomicUMaxU32},
{Decoder::Opcode::BufferAtomicAnd, Opcode::AtomicAndU32}, {Decoder::Opcode::BUFFER_ATOMIC_AND, Opcode::AtomicAndU32},
{Decoder::Opcode::BufferAtomicOr, Opcode::AtomicOrU32}, {Decoder::Opcode::BUFFER_ATOMIC_OR, Opcode::AtomicOrU32},
{Decoder::Opcode::BufferAtomicXor, Opcode::AtomicXorU32}, {Decoder::Opcode::BUFFER_ATOMIC_XOR, Opcode::AtomicXorU32},
{Decoder::Opcode::BufferAtomicFMin, Opcode::AtomicFMinF32}, {Decoder::Opcode::BUFFER_ATOMIC_FMIN, Opcode::AtomicFMinF32},
{Decoder::Opcode::BufferAtomicFMax, Opcode::AtomicFMaxF32}, {Decoder::Opcode::BUFFER_ATOMIC_FMAX, Opcode::AtomicFMaxF32},
{Decoder::Opcode::FlatLoadUbyte, Opcode::FlatLoadUbyte}, {Decoder::Opcode::FLAT_LOAD_UBYTE, Opcode::FlatLoadUbyte},
{Decoder::Opcode::FlatLoadSbyte, Opcode::FlatLoadSbyte}, {Decoder::Opcode::FLAT_LOAD_SBYTE, Opcode::FlatLoadSbyte},
{Decoder::Opcode::FlatLoadSshort, Opcode::FlatLoadSshort}, {Decoder::Opcode::FLAT_LOAD_SSHORT, Opcode::FlatLoadSshort},
{Decoder::Opcode::FlatStoreByte, Opcode::FlatStoreByte}, {Decoder::Opcode::FLAT_STORE_BYTE, Opcode::FlatStoreByte},
{Decoder::Opcode::FlatStoreShort, Opcode::FlatStoreShort}, {Decoder::Opcode::FLAT_STORE_SHORT, Opcode::FlatStoreShort},
{Decoder::Opcode::FlatStoreDword, Opcode::FlatStoreDword}, {Decoder::Opcode::FLAT_STORE_DWORD, Opcode::FlatStoreDword},
{Decoder::Opcode::DsAddU32, Opcode::AtomicAddU32}, {Decoder::Opcode::DS_ADD_U32, Opcode::AtomicAddU32},
{Decoder::Opcode::DsAddRtnU32, Opcode::AtomicAddU32}, {Decoder::Opcode::DS_ADD_RTN_U32, Opcode::AtomicAddU32},
{Decoder::Opcode::DsSubU32, Opcode::AtomicSubU32}, {Decoder::Opcode::DS_SUB_U32, Opcode::AtomicSubU32},
{Decoder::Opcode::DsSubRtnU32, Opcode::AtomicSubU32}, {Decoder::Opcode::DS_SUB_RTN_U32, Opcode::AtomicSubU32},
{Decoder::Opcode::DsMinI32, Opcode::AtomicSMinI32}, {Decoder::Opcode::DS_MIN_I32, Opcode::AtomicSMinI32},
{Decoder::Opcode::DsMinRtnI32, Opcode::AtomicSMinI32}, {Decoder::Opcode::DS_MIN_RTN_I32, Opcode::AtomicSMinI32},
{Decoder::Opcode::DsMaxI32, Opcode::AtomicSMaxI32}, {Decoder::Opcode::DS_MAX_I32, Opcode::AtomicSMaxI32},
{Decoder::Opcode::DsMaxRtnI32, Opcode::AtomicSMaxI32}, {Decoder::Opcode::DS_MAX_RTN_I32, Opcode::AtomicSMaxI32},
{Decoder::Opcode::DsMinU32, Opcode::AtomicUMinU32}, {Decoder::Opcode::DS_MIN_U32, Opcode::AtomicUMinU32},
{Decoder::Opcode::DsMinRtnU32, Opcode::AtomicUMinU32}, {Decoder::Opcode::DS_MIN_RTN_U32, Opcode::AtomicUMinU32},
{Decoder::Opcode::DsMaxU32, Opcode::AtomicUMaxU32}, {Decoder::Opcode::DS_MAX_U32, Opcode::AtomicUMaxU32},
{Decoder::Opcode::DsMaxRtnU32, Opcode::AtomicUMaxU32}, {Decoder::Opcode::DS_MAX_RTN_U32, Opcode::AtomicUMaxU32},
{Decoder::Opcode::DsAndB32, Opcode::AtomicAndU32}, {Decoder::Opcode::DS_AND_B32, Opcode::AtomicAndU32},
{Decoder::Opcode::DsAndRtnB32, Opcode::AtomicAndU32}, {Decoder::Opcode::DS_AND_RTN_B32, Opcode::AtomicAndU32},
{Decoder::Opcode::DsOrB32, Opcode::AtomicOrU32}, {Decoder::Opcode::DS_OR_B32, Opcode::AtomicOrU32},
{Decoder::Opcode::DsOrRtnB32, Opcode::AtomicOrU32}, {Decoder::Opcode::DS_OR_RTN_B32, Opcode::AtomicOrU32},
{Decoder::Opcode::DsXorB32, Opcode::AtomicXorU32}, {Decoder::Opcode::DS_XOR_B32, Opcode::AtomicXorU32},
{Decoder::Opcode::DsXorRtnB32, Opcode::AtomicXorU32}, {Decoder::Opcode::DS_XOR_RTN_B32, Opcode::AtomicXorU32},
{Decoder::Opcode::DsWrxchgRtnB32, Opcode::AtomicSwapU32}, {Decoder::Opcode::DS_WRXCHG_RTN_B32, Opcode::AtomicSwapU32},
{Decoder::Opcode::DsReadSbyte, Opcode::DsReadSbyte}, {Decoder::Opcode::DS_READ_I8, Opcode::DsReadSbyte},
{Decoder::Opcode::DsReadUbyte, Opcode::DsReadUbyte}, {Decoder::Opcode::DS_READ_U8, Opcode::DsReadUbyte},
{Decoder::Opcode::DsReadSshort, Opcode::DsReadSshort}, {Decoder::Opcode::DS_READ_I16, Opcode::DsReadSshort},
{Decoder::Opcode::DsReadUshort, Opcode::DsReadUshort}, {Decoder::Opcode::DS_READ_U16, Opcode::DsReadUshort},
{Decoder::Opcode::DsRead2B32, Opcode::DsReadB32}, {Decoder::Opcode::DS_READ2_B32, Opcode::DsReadB32},
{Decoder::Opcode::DsReadB32, Opcode::DsReadB32}, {Decoder::Opcode::DS_READ_B32, Opcode::DsReadB32},
{Decoder::Opcode::DsReadB64, Opcode::DsReadB32}, {Decoder::Opcode::DS_READ_B64, Opcode::DsReadB32},
{Decoder::Opcode::DsRead2B64, Opcode::DsReadB32}, {Decoder::Opcode::DS_READ2_B64, Opcode::DsReadB32},
{Decoder::Opcode::DsRead2St64B64, Opcode::DsReadB32}, {Decoder::Opcode::DS_READ2ST64_B64, Opcode::DsReadB32},
{Decoder::Opcode::DsReadB96, Opcode::DsReadB32}, {Decoder::Opcode::DS_READ_B96, Opcode::DsReadB32},
{Decoder::Opcode::DsReadB128, Opcode::DsReadB32}, {Decoder::Opcode::DS_READ_B128, Opcode::DsReadB32},
{Decoder::Opcode::DsWriteByte, Opcode::DsWriteByte}, {Decoder::Opcode::DS_WRITE_B8, Opcode::DsWriteByte},
{Decoder::Opcode::DsWriteShort, Opcode::DsWriteShort}, {Decoder::Opcode::DS_WRITE_B16, Opcode::DsWriteShort},
{Decoder::Opcode::DsWrite2B32, Opcode::DsWriteB32}, {Decoder::Opcode::DS_WRITE2_B32, Opcode::DsWriteB32},
{Decoder::Opcode::DsWrite2St64B32, Opcode::DsWriteB32}, {Decoder::Opcode::DS_WRITE2ST64_B32, Opcode::DsWriteB32},
{Decoder::Opcode::DsWrite2B64, Opcode::DsWriteB32}, {Decoder::Opcode::DS_WRITE2_B64, Opcode::DsWriteB32},
{Decoder::Opcode::DsWrite2St64B64, Opcode::DsWriteB32}, {Decoder::Opcode::DS_WRITE2ST64_B64, Opcode::DsWriteB32},
{Decoder::Opcode::DsWriteB32, Opcode::DsWriteB32}, {Decoder::Opcode::DS_WRITE_B32, Opcode::DsWriteB32},
{Decoder::Opcode::DsWriteB64, Opcode::DsWriteB32}, {Decoder::Opcode::DS_WRITE_B64, Opcode::DsWriteB32},
{Decoder::Opcode::DsWriteB96, Opcode::DsWriteB32}, {Decoder::Opcode::DS_WRITE_B96, Opcode::DsWriteB32},
{Decoder::Opcode::DsWriteB128, Opcode::DsWriteB32}, {Decoder::Opcode::DS_WRITE_B128, Opcode::DsWriteB32},
{Decoder::Opcode::DsMinF32, Opcode::DsMinF32}, {Decoder::Opcode::DS_MIN_F32, Opcode::DsMinF32},
{Decoder::Opcode::DsMaxF32, Opcode::DsMaxF32}, {Decoder::Opcode::DS_MAX_F32, Opcode::DsMaxF32},
{Decoder::Opcode::DsConsume, Opcode::DsConsume}, {Decoder::Opcode::DS_CONSUME, Opcode::DsConsume},
{Decoder::Opcode::DsAppend, Opcode::DsAppend}, {Decoder::Opcode::DS_APPEND, Opcode::DsAppend},
{Decoder::Opcode::DsWriteAddtidB32, Opcode::DsWriteAddtidB32}, {Decoder::Opcode::DS_WRITE_ADDTID_B32, Opcode::DsWriteAddtidB32},
{Decoder::Opcode::DsReadAddtidB32, Opcode::DsReadAddtidB32}, {Decoder::Opcode::DS_READ_ADDTID_B32, Opcode::DsReadAddtidB32},
{Decoder::Opcode::ImageGetResinfo, Opcode::ImageGetResinfo}, {Decoder::Opcode::IMAGE_GET_RESINFO, Opcode::ImageGetResinfo},
{Decoder::Opcode::ImageGetLod, Opcode::ImageGetLod}, {Decoder::Opcode::IMAGE_GET_LOD, Opcode::ImageGetLod},
{Decoder::Opcode::ImageLoad, Opcode::ImageLoad}, {Decoder::Opcode::IMAGE_LOAD, Opcode::ImageLoad},
{Decoder::Opcode::ImageLoadMip, Opcode::ImageLoad}, {Decoder::Opcode::IMAGE_LOAD_MIP, Opcode::ImageLoad},
{Decoder::Opcode::ImageStore, Opcode::ImageStore}, {Decoder::Opcode::IMAGE_STORE, Opcode::ImageStore},
{Decoder::Opcode::ImageStoreMip, Opcode::ImageStore}, {Decoder::Opcode::IMAGE_STORE_MIP, Opcode::ImageStore},
{Decoder::Opcode::ImageAtomicAdd, Opcode::AtomicAddU32}, {Decoder::Opcode::IMAGE_ATOMIC_ADD, Opcode::AtomicAddU32},
{Decoder::Opcode::ImageAtomicUMin, Opcode::AtomicUMinU32}, {Decoder::Opcode::IMAGE_ATOMIC_UMIN, Opcode::AtomicUMinU32},
{Decoder::Opcode::ImageAtomicUMax, Opcode::AtomicUMaxU32}, {Decoder::Opcode::IMAGE_ATOMIC_UMAX, Opcode::AtomicUMaxU32},
{Decoder::Opcode::ImageAtomicAnd, Opcode::AtomicAndU32}, {Decoder::Opcode::IMAGE_ATOMIC_AND, Opcode::AtomicAndU32},
{Decoder::Opcode::ImageAtomicOr, Opcode::AtomicOrU32}, {Decoder::Opcode::IMAGE_ATOMIC_OR, Opcode::AtomicOrU32},
{Decoder::Opcode::ImageAtomicXor, Opcode::AtomicXorU32}, {Decoder::Opcode::IMAGE_ATOMIC_XOR, Opcode::AtomicXorU32},
{Decoder::Opcode::ImageSample, Opcode::ImageSample}, {Decoder::Opcode::IMAGE_SAMPLE, Opcode::ImageSample},
{Decoder::Opcode::ImageGather4Lz, Opcode::ImageGather4}, {Decoder::Opcode::IMAGE_GATHER4_LZ, Opcode::ImageGather4},
{Decoder::Opcode::ImageGather4C, Opcode::ImageGather4}, {Decoder::Opcode::IMAGE_GATHER4_C, Opcode::ImageGather4},
{Decoder::Opcode::ImageGather4CLz, Opcode::ImageGather4}, {Decoder::Opcode::IMAGE_GATHER4_C_LZ, Opcode::ImageGather4},
{Decoder::Opcode::ImageGather4LzO, Opcode::ImageGather4}, {Decoder::Opcode::IMAGE_GATHER4_LZ_O, Opcode::ImageGather4},
{Decoder::Opcode::ImageGather4CO, Opcode::ImageGather4}, {Decoder::Opcode::IMAGE_GATHER4_C_O, Opcode::ImageGather4},
{Decoder::Opcode::ImageGather4CLzO, Opcode::ImageGather4}, {Decoder::Opcode::IMAGE_GATHER4_C_LZ_O, Opcode::ImageGather4},
{Decoder::Opcode::ImageGather4H, Opcode::ImageGather4}, {Decoder::Opcode::IMAGE_GATHER4H, Opcode::ImageGather4},
}; };
} // namespace } // namespace
@@ -456,80 +456,80 @@ std::optional<Opcode> LookupIrOpcode(Decoder::Opcode opcode) {
bool IsReversedBinary(Decoder::Opcode opcode) { bool IsReversedBinary(Decoder::Opcode opcode) {
switch (opcode) { switch (opcode) {
case Decoder::Opcode::VSubrevF32: case Decoder::Opcode::V_SUBREV_F32:
case Decoder::Opcode::VSubrevF16: case Decoder::Opcode::V_SUBREV_F16:
case Decoder::Opcode::VSubrevNcU32: case Decoder::Opcode::V_SUBREV_NC_U32:
case Decoder::Opcode::VLshlrevB32: case Decoder::Opcode::V_LSHLREV_B32:
case Decoder::Opcode::VLshrrevB32: case Decoder::Opcode::V_LSHRREV_B32:
case Decoder::Opcode::VAshrrevI32: case Decoder::Opcode::V_ASHRREV_I32:
case Decoder::Opcode::VLshlrevB16: case Decoder::Opcode::V_LSHLREV_B16:
case Decoder::Opcode::VLshrrevB16: case Decoder::Opcode::V_LSHRREV_B16:
case Decoder::Opcode::VAshrrevI16: case Decoder::Opcode::V_ASHRREV_I16:
case Decoder::Opcode::VSubrevI32: return true; case Decoder::Opcode::V_SUBREV_I32: return true;
default: return false; default: return false;
} }
} }
bool IsVectorCarryOutOpcode(Decoder::Opcode opcode) { bool IsVectorCarryOutOpcode(Decoder::Opcode opcode) {
switch (opcode) { switch (opcode) {
case Decoder::Opcode::VAddI32: case Decoder::Opcode::V_ADD_I32:
case Decoder::Opcode::VSubI32: case Decoder::Opcode::V_SUB_I32:
case Decoder::Opcode::VSubrevI32: return true; case Decoder::Opcode::V_SUBREV_I32: return true;
default: return false; default: return false;
} }
} }
bool ScalarResultWritesSccNonZero(Decoder::Opcode opcode) { bool ScalarResultWritesSccNonZero(Decoder::Opcode opcode) {
switch (opcode) { switch (opcode) {
case Decoder::Opcode::SAbsI32: case Decoder::Opcode::S_ABS_I32:
case Decoder::Opcode::SBcnt1I32B32: case Decoder::Opcode::S_BCNT1_I32_B32:
case Decoder::Opcode::SBcnt1I32B64: case Decoder::Opcode::S_BCNT1_I32_B64:
case Decoder::Opcode::SAndB32: case Decoder::Opcode::S_AND_B32:
case Decoder::Opcode::SAndn2B32: case Decoder::Opcode::S_ANDN2_B32:
case Decoder::Opcode::SOrB32: case Decoder::Opcode::S_OR_B32:
case Decoder::Opcode::SOrn2B32: case Decoder::Opcode::S_ORN2_B32:
case Decoder::Opcode::SXorB32: case Decoder::Opcode::S_XOR_B32:
case Decoder::Opcode::SNandB32: case Decoder::Opcode::S_NAND_B32:
case Decoder::Opcode::SNorB32: case Decoder::Opcode::S_NOR_B32:
case Decoder::Opcode::SXnorB32: case Decoder::Opcode::S_XNOR_B32:
case Decoder::Opcode::SNotB32: case Decoder::Opcode::S_NOT_B32:
case Decoder::Opcode::SLshlB32: case Decoder::Opcode::S_LSHL_B32:
case Decoder::Opcode::SLshrB32: case Decoder::Opcode::S_LSHR_B32:
case Decoder::Opcode::SAshrI32: case Decoder::Opcode::S_ASHR_I32:
case Decoder::Opcode::SBfeU32: case Decoder::Opcode::S_BFE_U32:
case Decoder::Opcode::SBfeI32: case Decoder::Opcode::S_BFE_I32:
case Decoder::Opcode::SAndB64: case Decoder::Opcode::S_AND_B64:
case Decoder::Opcode::SAndn2B64: case Decoder::Opcode::S_ANDN2_B64:
case Decoder::Opcode::SNotB64: case Decoder::Opcode::S_NOT_B64:
case Decoder::Opcode::SOrB64: case Decoder::Opcode::S_OR_B64:
case Decoder::Opcode::SOrn2B64: case Decoder::Opcode::S_ORN2_B64:
case Decoder::Opcode::SXorB64: case Decoder::Opcode::S_XOR_B64:
case Decoder::Opcode::SNandB64: case Decoder::Opcode::S_NAND_B64:
case Decoder::Opcode::SNorB64: case Decoder::Opcode::S_NOR_B64:
case Decoder::Opcode::SXnorB64: case Decoder::Opcode::S_XNOR_B64:
case Decoder::Opcode::SLshlB64: case Decoder::Opcode::S_LSHL_B64:
case Decoder::Opcode::SLshrB64: case Decoder::Opcode::S_LSHR_B64:
case Decoder::Opcode::SBfeU64: case Decoder::Opcode::S_BFE_U64:
case Decoder::Opcode::SWqmB64: return true; case Decoder::Opcode::S_WQM_B64: return true;
default: return false; default: return false;
} }
} }
bool ScalarResultIs64Bit(Decoder::Opcode opcode) { bool ScalarResultIs64Bit(Decoder::Opcode opcode) {
switch (opcode) { switch (opcode) {
case Decoder::Opcode::SAndB64: case Decoder::Opcode::S_AND_B64:
case Decoder::Opcode::SAndn2B64: case Decoder::Opcode::S_ANDN2_B64:
case Decoder::Opcode::SNotB64: case Decoder::Opcode::S_NOT_B64:
case Decoder::Opcode::SOrB64: case Decoder::Opcode::S_OR_B64:
case Decoder::Opcode::SOrn2B64: case Decoder::Opcode::S_ORN2_B64:
case Decoder::Opcode::SXorB64: case Decoder::Opcode::S_XOR_B64:
case Decoder::Opcode::SNandB64: case Decoder::Opcode::S_NAND_B64:
case Decoder::Opcode::SNorB64: case Decoder::Opcode::S_NOR_B64:
case Decoder::Opcode::SXnorB64: case Decoder::Opcode::S_XNOR_B64:
case Decoder::Opcode::SLshlB64: case Decoder::Opcode::S_LSHL_B64:
case Decoder::Opcode::SLshrB64: case Decoder::Opcode::S_LSHR_B64:
case Decoder::Opcode::SBfeU64: case Decoder::Opcode::S_BFE_U64:
case Decoder::Opcode::SWqmB64: return true; case Decoder::Opcode::S_WQM_B64: return true;
default: return false; default: return false;
} }
} }
File diff suppressed because it is too large. Load diff
+18 -19
View File
@@ -1050,11 +1050,11 @@ void TestNewShaderRecompilerSMovB32() {
Check(!result.spirv.empty(), "new shader recompiler produced no SPIR-V"); Check(!result.spirv.empty(), "new shader recompiler produced no SPIR-V");
Check(result.spirv.front() == 0x07230203u, Check(result.spirv.front() == 0x07230203u,
"new shader recompiler did not emit SPIR-V binary"); "new shader recompiler did not emit SPIR-V binary");
Check(Common::ContainsStr(result.decoded_dump, "s_mov_b32 s0, 1"), Check(Common::ContainsStr(result.decoded_dump, "S_MOV_B32 s0, 1"),
"new decoder did not decode inline S_MOV_B32 operand"); "new decoder did not decode inline S_MOV_B32 operand");
Check(Common::ContainsStr(result.decoded_dump, "s_mov_b32 s1, 0x12345678"), Check(Common::ContainsStr(result.decoded_dump, "S_MOV_B32 s1, 0x12345678"),
"new decoder did not decode literal S_MOV_B32 operand"); "new decoder did not decode literal S_MOV_B32 operand");
Check(Common::ContainsStr(result.decoded_dump, "s_mov_b32 s2, s1"), Check(Common::ContainsStr(result.decoded_dump, "S_MOV_B32 s2, s1"),
"new decoder did not decode register S_MOV_B32 operand"); "new decoder did not decode register S_MOV_B32 operand");
Check(Common::ContainsStr(result.ir_dump, "StoreBufferU32") && Check(Common::ContainsStr(result.ir_dump, "StoreBufferU32") &&
Common::ContainsStr(result.ir_dump, "0x00000001") && Common::ContainsStr(result.ir_dump, "0x00000001") &&
@@ -2844,9 +2844,8 @@ void TestNewShaderRecompilerCapturedVop1SdwaByteConvert() {
std::string error; std::string error;
Check(ShaderRecompiler::TryRecompile(shader, options, result, &error), Check(ShaderRecompiler::TryRecompile(shader, options, result, &error),
error.c_str()); error.c_str());
Check(Common::ContainsStr( Check(Common::ContainsStr(result.decoded_dump,
result.decoded_dump, "V_CVT_F32_UBYTE0 v4, v9.sdwa(sel=4,sext=0)"),
"v_cvt_f32_ubyte0 v4, v9.sdwa(sel=4,sext=0)"),
"captured V_CVT_F32_UBYTE0 SDWA instruction was not decoded"); "captured V_CVT_F32_UBYTE0 SDWA instruction was not decoded");
size_t extracts = 0; size_t extracts = 0;
@@ -3458,7 +3457,7 @@ void TestNewShaderDecoderArchitecture() {
std::string error; std::string error;
Check(DecodeInstruction(offset_code, 1u, direct, &error), error.c_str()); Check(DecodeInstruction(offset_code, 1u, direct, &error), error.c_str());
Check(direct.pc == 4u && direct.family == Family::VOP1 && Check(direct.pc == 4u && direct.family == Family::VOP1 &&
direct.opcode == Opcode::VMovB32 && direct.dst.reg == 2u && direct.opcode == Opcode::V_MOV_B32 && direct.dst.reg == 2u &&
direct.src0.reg == 3u, direct.src0.reg == 3u,
"single-instruction decoder failed at a nonzero offset"); "single-instruction decoder failed at a nonzero offset");
@@ -3489,7 +3488,7 @@ void TestNewShaderDecoderArchitecture() {
Check(DecodeInstruction(scalar_signed_bfe, 0u, signed_bfe, &error), Check(DecodeInstruction(scalar_signed_bfe, 0u, signed_bfe, &error),
error.c_str()); error.c_str());
Check(signed_bfe.family == Family::SOP2 && Check(signed_bfe.family == Family::SOP2 &&
signed_bfe.opcode == Opcode::SBfeI32 && signed_bfe.opcode == Opcode::S_BFE_I32 &&
signed_bfe.word_count == 2u && signed_bfe.word_count == 2u &&
signed_bfe.dst.kind == OperandKind::VccLo && signed_bfe.dst.kind == OperandKind::VccLo &&
signed_bfe.src0.reg == 20u && signed_bfe.src1.value == 0x0004001cu, signed_bfe.src0.reg == 20u && signed_bfe.src1.value == 0x0004001cu,
@@ -3503,7 +3502,7 @@ void TestNewShaderDecoderArchitecture() {
Check(DecodeInstruction(vop2_sdwa_partial_dst, 0u, sdwa_add, &error), Check(DecodeInstruction(vop2_sdwa_partial_dst, 0u, sdwa_add, &error),
error.c_str()); error.c_str());
Check(sdwa_add.family == Family::VOP2 && Check(sdwa_add.family == Family::VOP2 &&
sdwa_add.opcode == Opcode::VAddNcU32 && sdwa_add.word_count == 2u && sdwa_add.opcode == Opcode::V_ADD_NC_U32 && sdwa_add.word_count == 2u &&
sdwa_add.dst.reg == 4u && sdwa_add.dst.sdwa_sel == 5u && sdwa_add.dst.reg == 4u && sdwa_add.dst.sdwa_sel == 5u &&
sdwa_add.dst.sdwa_dst_unused == 2u && sdwa_add.dst.sdwa_dst_unused == 2u &&
sdwa_add.src0.kind == OperandKind::VccLo && sdwa_add.src0.kind == OperandKind::VccLo &&
@@ -3524,13 +3523,13 @@ void TestNewShaderDecoderArchitecture() {
EncodeDs1(2, 0, 1)}; EncodeDs1(2, 0, 1)};
Instruction ds; Instruction ds;
Check(DecodeInstruction(ds_code, 0u, ds, &error), error.c_str()); Check(DecodeInstruction(ds_code, 0u, ds, &error), error.c_str());
Check(ds.opcode == Opcode::DsReadB32 && ds.gds, Check(ds.opcode == Opcode::DS_READ_B32 && ds.gds,
"DS decoder lost the GFX10 opcode or GDS fields"); "DS decoder lost the GFX10 opcode or GDS fields");
const uint32_t boot_ds[] = {0xd8d4c480u, 0x45000045u}; const uint32_t boot_ds[] = {0xd8d4c480u, 0x45000045u};
Instruction boot; Instruction boot;
Check(DecodeInstruction(boot_ds, 0u, boot, &error), error.c_str()); Check(DecodeInstruction(boot_ds, 0u, boot, &error), error.c_str());
Check(boot.opcode == Opcode::DsSwizzleB32 && boot.offset == 0xc480u, Check(boot.opcode == Opcode::DS_SWIZZLE_B32 && boot.offset == 0xc480u,
"DS decoder rejected a captured boot-shader instruction"); "DS decoder rejected a captured boot-shader instruction");
constexpr uint32_t packed_source_selectors[][2] = { constexpr uint32_t packed_source_selectors[][2] = {
@@ -3565,7 +3564,7 @@ void TestNewShaderRecompilerRejectsDppOn64BitCompares() {
Check(program.instructions.size() == 2u, Check(program.instructions.size() == 2u,
"64-bit VOPC DPP decode did not consume its modifier word"); "64-bit VOPC DPP decode did not consume its modifier word");
const auto &compare = program.instructions.front(); const auto &compare = program.instructions.front();
Check(compare.opcode == ShaderRecompiler::Decoder::Opcode::Unsupported, Check(compare.opcode == ShaderRecompiler::Decoder::Opcode::UNSUPPORTED,
"64-bit VOPC illegally accepted a DPP modifier"); "64-bit VOPC illegally accepted a DPP modifier");
Check(Common::ContainsStr(compare.unsupported_reason, Check(Common::ContainsStr(compare.unsupported_reason,
"VOPC DPP modifier is not supported for opcode"), "VOPC DPP modifier is not supported for opcode"),
@@ -3578,7 +3577,7 @@ void TestNewShaderRecompilerIrLookupMissFailsExplicitly() {
ShaderRecompiler::Decoder::Instruction missing; ShaderRecompiler::Decoder::Instruction missing;
missing.pc = 0u; missing.pc = 0u;
missing.family = ShaderRecompiler::Decoder::Family::VOP1; missing.family = ShaderRecompiler::Decoder::Family::VOP1;
missing.opcode = ShaderRecompiler::Decoder::Opcode::Unknown; missing.opcode = ShaderRecompiler::Decoder::Opcode::UNKNOWN;
decoded.instructions.push_back(missing); decoded.instructions.push_back(missing);
ShaderRecompiler::CFG::Graph cfg; ShaderRecompiler::CFG::Graph cfg;
@@ -3600,7 +3599,7 @@ void TestNewShaderRecompilerIrLookupMissFailsExplicitly() {
decoded.instructions.front().family = decoded.instructions.front().family =
ShaderRecompiler::Decoder::Family::MUBUF; ShaderRecompiler::Decoder::Family::MUBUF;
decoded.instructions.front().opcode = decoded.instructions.front().opcode =
ShaderRecompiler::Decoder::Opcode::VAddNcU32; ShaderRecompiler::Decoder::Opcode::V_ADD_NC_U32;
error.clear(); error.clear();
Check(!ShaderRecompiler::IR::LowerProgram(decoded, cfg, ShaderType::Compute, Check(!ShaderRecompiler::IR::LowerProgram(decoded, cfg, ShaderType::Compute,
64u, ir, &error), 64u, ir, &error),
@@ -3650,8 +3649,8 @@ void TestNewShaderRecompilerMemoryFamilyLowering() {
"new decoder did not decode SMEM scalar-buffer dword load"); "new decoder did not decode SMEM scalar-buffer dword load");
Check(Common::ContainsStr(result.decoded_dump, "s_buffer_load_dword s1, s8"), Check(Common::ContainsStr(result.decoded_dump, "s_buffer_load_dword s1, s8"),
"SMEM scalar-buffer SBASE was not decoded as an SGPR-pair index"); "SMEM scalar-buffer SBASE was not decoded as an SGPR-pair index");
Check(Common::ContainsStr(result.decoded_dump, "buffer_load_dword"), Check(Common::ContainsStr(result.decoded_dump, "buffer_load_dword"),
"new decoder did not decode MUBUF dword load"); "new decoder did not decode MUBUF dword load");
Check(Common::ContainsStr(result.decoded_dump, "buffer_store_dword"), Check(Common::ContainsStr(result.decoded_dump, "buffer_store_dword"),
"new decoder did not decode MUBUF dword store"); "new decoder did not decode MUBUF dword store");
Check(Common::ContainsStr(result.decoded_dump, "ds_read_b32"), Check(Common::ContainsStr(result.decoded_dump, "ds_read_b32"),
@@ -6225,7 +6224,7 @@ void TestNewShaderRecompilerCfgPostEndTargetMergePS() {
error.c_str()); error.c_str());
} }
Check(ok, "post-end target PS shader failed to compile"); Check(ok, "post-end target PS shader failed to compile");
Check(Common::ContainsStr(result.decoded_dump, "0x0000000c: s_mov_b32"), Check(Common::ContainsStr(result.decoded_dump, "0x0000000c: S_MOV_B32"),
"post-end branch target was not decoded"); "post-end branch target was not decoded");
Check(Common::ContainsStr(result.ir_dump, "mode=structured"), Check(Common::ContainsStr(result.ir_dump, "mode=structured"),
"post-end terminal branch should stay on structured path"); "post-end terminal branch should stay on structured path");
@@ -7366,7 +7365,7 @@ void TestNewShaderRecompilerBufferLoadsGuardedByExec() {
std::string error; std::string error;
Check(ShaderRecompiler::TryRecompile(shader, options, result, &error), Check(ShaderRecompiler::TryRecompile(shader, options, result, &error),
error.c_str()); error.c_str());
Check(Common::ContainsStr(result.decoded_dump, "buffer_load_dword"), Check(Common::ContainsStr(result.decoded_dump, "BUFFER_LOAD_DWORD"),
"buffer load guard regression did not decode MUBUF load"); "buffer load guard regression did not decode MUBUF load");
CheckSpirvBinaryValidates(result.spirv); CheckSpirvBinaryValidates(result.spirv);
@@ -7407,7 +7406,7 @@ void TestNewShaderRecompilerBufferAtomicsGuardedByBounds() {
std::string error; std::string error;
Check(ShaderRecompiler::TryRecompile(shader, options, result, &error), Check(ShaderRecompiler::TryRecompile(shader, options, result, &error),
error.c_str()); error.c_str());
Check(Common::ContainsStr(result.decoded_dump, "buffer_atomic_add"), Check(Common::ContainsStr(result.decoded_dump, "BUFFER_ATOMIC_ADD"),
"buffer atomic bounds regression did not decode MUBUF atomic"); "buffer atomic bounds regression did not decode MUBUF atomic");
CheckSpirvBinaryValidates(result.spirv); CheckSpirvBinaryValidates(result.spirv);