shader_recompiler: add SSA

This commit is contained in:
nmzik
2026-08-15 03:11:19 +02:00
parent bc2f077c37
commit b42380ced6
113 changed files with 40415 additions and 32616 deletions
@@ -0,0 +1,71 @@
#pragma once
#include "graphics/shader/recompiler/ir/Type.h"
#include <array>
#include <cstddef>
#include <string_view>
namespace Libs::Graphics::ShaderRecompiler::IR {
enum class Opcode {
#define IR_OPCODE(name, category, lowering, ...) name,
#include "graphics/shader/recompiler/ir/opcodes/ShaderIROpcodes.inc"
#undef IR_OPCODE
Count,
};
enum class OpcodeClass { General, Compare, Compare64 };
enum class LoweringClass {
Control,
Move,
Lane,
State,
Memory,
Attribute,
IntegerCompare,
Integer16Compare,
FloatCompare,
Conversion,
Integer16,
PackedInteger16,
PackedFloat16,
Float16,
Float,
U64Mask,
SimpleInteger,
ComposedInteger,
ExtendedInteger,
};
struct OpcodeInfo {
std::string_view name;
OpcodeClass opcode_class = OpcodeClass::General;
LoweringClass lowering_class = LoweringClass::Control;
};
inline constexpr OpcodeInfo OPCODE_INFO[] = {
#define IR_OPCODE(name, category, lowering, ...) \
{#name, OpcodeClass::category, LoweringClass::lowering},
#include "graphics/shader/recompiler/ir/opcodes/ShaderIROpcodes.inc"
#undef IR_OPCODE
};
static_assert(std::size(OPCODE_INFO) == static_cast<size_t>(Opcode::Count));
constexpr const OpcodeInfo& GetOpcodeInfo(Opcode opcode) {
return OPCODE_INFO[static_cast<size_t>(opcode)];
}
constexpr std::string_view OpcodeName(Opcode opcode) {
return GetOpcodeInfo(opcode).name;
}
constexpr bool IsCompareOpcode(Opcode opcode) {
return GetOpcodeInfo(opcode).opcode_class != OpcodeClass::General;
}
constexpr bool IsCompare64Opcode(Opcode opcode) {
return GetOpcodeInfo(opcode).opcode_class == OpcodeClass::Compare64;
}
} // namespace Libs::Graphics::ShaderRecompiler::IR
@@ -0,0 +1,528 @@
#include "common/assert.h"
#include "graphics/shader/recompiler/BufferFormat.h"
#include "graphics/shader/recompiler/ir/ShaderIR.h"
#include "graphics/shader/recompiler/ir/ShaderIRInternal.h"
#include <algorithm>
#include <fmt/format.h>
#include <utility>
namespace Libs::Graphics::ShaderRecompiler::IR {
namespace {
struct LowerMap {
Decoder::Opcode decoded = Decoder::Opcode::Unknown;
Opcode ir = Opcode::MoveU32;
};
constexpr LowerMap LOWER_OPS[] = {
{Decoder::Opcode::SMovB32, Opcode::MoveU32},
{Decoder::Opcode::SMovB64, Opcode::MoveU64},
{Decoder::Opcode::SWqmB64, Opcode::WqmB64},
{Decoder::Opcode::SMovkI32, Opcode::MoveU32},
{Decoder::Opcode::SAbsI32, Opcode::AbsI32},
{Decoder::Opcode::SBrevB32, Opcode::BitReverseU32},
{Decoder::Opcode::SBcnt1I32B32, Opcode::BitCountU32},
{Decoder::Opcode::SBcnt1I32B64, Opcode::BitCountU64},
{Decoder::Opcode::SFf1I32B32, Opcode::FindLsbU32},
{Decoder::Opcode::SFlbitI32B64, Opcode::FindMsbFromHighU64},
{Decoder::Opcode::SBitreplicateB64B32, Opcode::BitReplicateB64B32},
{Decoder::Opcode::SNotB32, Opcode::BitwiseNotU32},
{Decoder::Opcode::SNotB64, Opcode::BitwiseNotU64},
{Decoder::Opcode::SAddU32, Opcode::IAddU32},
{Decoder::Opcode::SSubU32, Opcode::ISubU32},
{Decoder::Opcode::SAddI32, Opcode::IAddU32},
{Decoder::Opcode::SSubI32, Opcode::ISubU32},
{Decoder::Opcode::SMinI32, Opcode::IMinI32},
{Decoder::Opcode::SMaxI32, Opcode::IMaxI32},
{Decoder::Opcode::SMinU32, Opcode::UMinU32},
{Decoder::Opcode::SMaxU32, Opcode::UMaxU32},
{Decoder::Opcode::SAndB32, Opcode::BitwiseAndU32},
{Decoder::Opcode::SAndB64, Opcode::BitwiseAndU64},
{Decoder::Opcode::SAndn2B32, Opcode::BitwiseAndNotU32},
{Decoder::Opcode::SAndn2B64, Opcode::BitwiseAndNotU64},
{Decoder::Opcode::SOrB32, Opcode::BitwiseOrU32},
{Decoder::Opcode::SOrB64, Opcode::BitwiseOrU64},
{Decoder::Opcode::SOrn2B32, Opcode::BitwiseOrNotU32},
{Decoder::Opcode::SOrn2B64, Opcode::BitwiseOrNotU64},
{Decoder::Opcode::SXorB32, Opcode::BitwiseXorU32},
{Decoder::Opcode::SXorB64, Opcode::BitwiseXorU64},
{Decoder::Opcode::SNandB32, Opcode::BitwiseNandU32},
{Decoder::Opcode::SNandB64, Opcode::BitwiseNandU64},
{Decoder::Opcode::SNorB32, Opcode::BitwiseNorU32},
{Decoder::Opcode::SNorB64, Opcode::BitwiseNorU64},
{Decoder::Opcode::SXnorB32, Opcode::BitwiseXnorU32},
{Decoder::Opcode::SXnorB64, Opcode::BitwiseXnorU64},
{Decoder::Opcode::SLshlB32, Opcode::ShiftLeftLogicalU32},
{Decoder::Opcode::SLshlB64, Opcode::ShiftLeftLogicalU64},
{Decoder::Opcode::SLshrB32, Opcode::ShiftRightLogicalU32},
{Decoder::Opcode::SLshrB64, Opcode::ShiftRightLogicalU64},
{Decoder::Opcode::SAshrI32, Opcode::ShiftRightArithmeticI32},
{Decoder::Opcode::SMulI32, Opcode::IMulU32},
{Decoder::Opcode::SMulHiU32, Opcode::UMulHighU32},
{Decoder::Opcode::SMulkI32, Opcode::IMulU32},
{Decoder::Opcode::SBfeU32, Opcode::BitFieldExtractU32},
{Decoder::Opcode::SBfeU64, Opcode::BitFieldExtractU64},
{Decoder::Opcode::SBfmB32, Opcode::BitFieldMaskU32},
{Decoder::Opcode::SBfmB64, Opcode::BitFieldMaskU64},
{Decoder::Opcode::SBitcmp0B32, Opcode::BitCompare0B32},
{Decoder::Opcode::SBitcmp1B32, Opcode::BitCompare1B32},
{Decoder::Opcode::SPackLlB32B16, Opcode::PackLowLowU16},
{Decoder::Opcode::SPackLhB32B16, Opcode::PackLowHighU16},
{Decoder::Opcode::SPackHhB32B16, Opcode::PackHighHighU16},
{Decoder::Opcode::SCmpEqI32, Opcode::CompareEqI32},
{Decoder::Opcode::SCmpLgI32, Opcode::CompareNeI32},
{Decoder::Opcode::SCmpGtI32, Opcode::CompareGtI32},
{Decoder::Opcode::SCmpGeI32, Opcode::CompareGeI32},
{Decoder::Opcode::SCmpLtI32, Opcode::CompareLtI32},
{Decoder::Opcode::SCmpLeI32, Opcode::CompareLeI32},
{Decoder::Opcode::SCmpEqU32, Opcode::CompareEqU32},
{Decoder::Opcode::SCmpLgU32, Opcode::CompareNeU32},
{Decoder::Opcode::SCmpGtU32, Opcode::CompareGtU32},
{Decoder::Opcode::SCmpGeU32, Opcode::CompareGeU32},
{Decoder::Opcode::SCmpLtU32, Opcode::CompareLtU32},
{Decoder::Opcode::SCmpLeU32, Opcode::CompareLeU32},
{Decoder::Opcode::SCmpEqU64, Opcode::CompareEqU64},
{Decoder::Opcode::SCmpLgU64, Opcode::CompareNeU64},
{Decoder::Opcode::VReadfirstlaneB32, Opcode::ReadFirstLaneU32},
{Decoder::Opcode::VReadlaneB32, Opcode::ReadLaneU32},
{Decoder::Opcode::VWritelaneB32, Opcode::WriteLaneU32},
{Decoder::Opcode::VPermlane16B32, Opcode::Permlane16B32},
{Decoder::Opcode::VPermlanex16B32, Opcode::Permlanex16B32},
{Decoder::Opcode::VCvtF32I32, Opcode::ConvertI32ToF32},
{Decoder::Opcode::VCvtF32U32, Opcode::ConvertU32ToF32},
{Decoder::Opcode::VCvtU32F32, Opcode::ConvertF32ToU32},
{Decoder::Opcode::VCvtI32F32, Opcode::ConvertF32ToI32},
{Decoder::Opcode::VCvtF16F32, Opcode::ConvertF32ToF16},
{Decoder::Opcode::VCvtF32F16, Opcode::ConvertF16ToF32},
{Decoder::Opcode::VCvtF16U16, Opcode::ConvertU16ToF16},
{Decoder::Opcode::VCvtU16F16, Opcode::ConvertF16ToU16},
{Decoder::Opcode::VCvtF16I16, Opcode::ConvertI16ToF16},
{Decoder::Opcode::VCvtI16F16, Opcode::ConvertF16ToI16},
{Decoder::Opcode::VCvtRpiI32F32, Opcode::ConvertRoundPlusInfF32ToI32},
{Decoder::Opcode::VCvtFlrI32F32, Opcode::ConvertFloorF32ToI32},
{Decoder::Opcode::VCvtOffF32I4, Opcode::ConvertI4ToOffsetF32},
{Decoder::Opcode::VRcpF32, Opcode::RcpF32},
{Decoder::Opcode::VRcpIflagF32, Opcode::RcpIflagF32},
{Decoder::Opcode::VFractF32, Opcode::FractF32},
{Decoder::Opcode::VTruncF32, Opcode::TruncF32},
{Decoder::Opcode::VCeilF32, Opcode::CeilF32},
{Decoder::Opcode::VRndneF32, Opcode::RoundEvenF32},
{Decoder::Opcode::VFloorF32, Opcode::FloorF32},
{Decoder::Opcode::VExpF32, Opcode::Exp2F32},
{Decoder::Opcode::VLogF32, Opcode::Log2F32},
{Decoder::Opcode::VRsqF32, Opcode::InverseSqrtF32},
{Decoder::Opcode::VSqrtF32, Opcode::SqrtF32},
{Decoder::Opcode::VRcpF16, Opcode::RcpF16},
{Decoder::Opcode::VSqrtF16, Opcode::SqrtF16},
{Decoder::Opcode::VRsqF16, Opcode::InverseSqrtF16},
{Decoder::Opcode::VLogF16, Opcode::Log2F16},
{Decoder::Opcode::VExpF16, Opcode::Exp2F16},
{Decoder::Opcode::VFloorF16, Opcode::FloorF16},
{Decoder::Opcode::VCeilF16, Opcode::CeilF16},
{Decoder::Opcode::VTruncF16, Opcode::TruncF16},
{Decoder::Opcode::VRndneF16, Opcode::RoundEvenF16},
{Decoder::Opcode::VSinF32, Opcode::SinF32},
{Decoder::Opcode::VCosF32, Opcode::CosF32},
{Decoder::Opcode::VNotB32, Opcode::BitwiseNotU32},
{Decoder::Opcode::VBfrevB32, Opcode::BitReverseU32},
{Decoder::Opcode::VFfblB32, Opcode::FindLsbU32},
{Decoder::Opcode::VFfbhU32, Opcode::FindMsbFromHighU32},
{Decoder::Opcode::VAddF32, Opcode::FAddF32},
{Decoder::Opcode::VSubF32, Opcode::FSubF32},
{Decoder::Opcode::VSubrevF32, Opcode::FSubF32},
{Decoder::Opcode::VMulF32, Opcode::FMulF32},
{Decoder::Opcode::VMacF32, Opcode::FMadF32},
{Decoder::Opcode::VMadmkF32, Opcode::FMadF32},
{Decoder::Opcode::VMadakF32, Opcode::FMadF32},
{Decoder::Opcode::VMinF32, Opcode::FMinF32},
{Decoder::Opcode::VMaxF32, Opcode::FMaxF32},
{Decoder::Opcode::VMinI32, Opcode::IMinI32},
{Decoder::Opcode::VMaxI32, Opcode::IMaxI32},
{Decoder::Opcode::VMadF32, Opcode::FMadF32},
{Decoder::Opcode::VMadI32I24, Opcode::IMadI24U32},
{Decoder::Opcode::VMadU32U24, Opcode::UMadU24U32},
{Decoder::Opcode::VCubeidF32, Opcode::CubeIdF32},
{Decoder::Opcode::VCubescF32, Opcode::CubeScF32},
{Decoder::Opcode::VCubetcF32, Opcode::CubeTcF32},
{Decoder::Opcode::VCubemaF32, Opcode::CubeMaF32},
{Decoder::Opcode::VFmaF32, Opcode::FMadF32},
{Decoder::Opcode::VBfeU32, Opcode::BitFieldExtract3U32},
{Decoder::Opcode::VBfeI32, Opcode::BitFieldExtract3I32},
{Decoder::Opcode::VBfiB32, Opcode::BitFieldInsertSelectU32},
{Decoder::Opcode::VAlignbitB32, Opcode::AlignBitU32},
{Decoder::Opcode::VMin3F32, Opcode::FMin3F32},
{Decoder::Opcode::VMin3I32, Opcode::IMin3I32},
{Decoder::Opcode::VMin3U32, Opcode::UMin3U32},
{Decoder::Opcode::VMin3F16, Opcode::Min3F16},
{Decoder::Opcode::VMax3F32, Opcode::FMax3F32},
{Decoder::Opcode::VMax3I32, Opcode::IMax3I32},
{Decoder::Opcode::VMax3U32, Opcode::UMax3U32},
{Decoder::Opcode::VMax3F16, Opcode::Max3F16},
{Decoder::Opcode::VMed3F32, Opcode::FMed3F32},
{Decoder::Opcode::VMed3I32, Opcode::IMed3I32},
{Decoder::Opcode::VMed3U32, Opcode::UMed3U32},
{Decoder::Opcode::VMed3F16, Opcode::Med3F16},
{Decoder::Opcode::VSadU32, Opcode::SadU32},
{Decoder::Opcode::VAdd3U32, Opcode::IAdd3U32},
{Decoder::Opcode::VLshlAddU32, Opcode::ShiftLeftAddU32},
{Decoder::Opcode::VAddLshlU32, Opcode::AddShiftLeftU32},
{Decoder::Opcode::VXadU32, Opcode::XorAddU32},
{Decoder::Opcode::VLshlOrB32, Opcode::ShiftLeftOrU32},
{Decoder::Opcode::VAndOrB32, Opcode::BitwiseAndOrU32},
{Decoder::Opcode::VOr3B32, Opcode::BitwiseOr3U32},
{Decoder::Opcode::VXor3B32, Opcode::BitwiseXor3U32},
{Decoder::Opcode::VAddNcU32, Opcode::IAddU32},
{Decoder::Opcode::VSubNcU32, Opcode::ISubU32},
{Decoder::Opcode::VSubrevNcU32, Opcode::ISubU32},
{Decoder::Opcode::VAddNcU16, Opcode::IAddU16},
{Decoder::Opcode::VSubNcU16, Opcode::ISubI16},
{Decoder::Opcode::VMaxU16, Opcode::UMaxU16},
{Decoder::Opcode::VMaxI16, Opcode::IMaxI16},
{Decoder::Opcode::VMinU16, Opcode::UMinU16},
{Decoder::Opcode::VMinI16, Opcode::IMinI16},
{Decoder::Opcode::VAddNcI16, Opcode::IAddU16},
{Decoder::Opcode::VSubNcI16, Opcode::ISubI16},
{Decoder::Opcode::VMulI32I24, Opcode::IMulI24U32},
{Decoder::Opcode::VMulU32U24, Opcode::UMulU24U32},
{Decoder::Opcode::VMulLoU32, Opcode::IMulU32},
{Decoder::Opcode::VMulHiU32, Opcode::UMulHighU32},
{Decoder::Opcode::VMulLoI32, Opcode::IMulU32},
{Decoder::Opcode::VMulHiI32, Opcode::SMulHighI32},
{Decoder::Opcode::VAddI32, Opcode::IAddU32},
{Decoder::Opcode::VSubI32, Opcode::ISubU32},
{Decoder::Opcode::VSubrevI32, Opcode::ISubU32},
{Decoder::Opcode::VBfmB32, Opcode::BitFieldMaskU32},
{Decoder::Opcode::VCvtPkrtzF16F32, Opcode::PackF32ToF16Rtz},
{Decoder::Opcode::VLdexpF32, Opcode::LdexpF32},
{Decoder::Opcode::VCvtPknormI16F32, Opcode::PackSnorm2x16F32},
{Decoder::Opcode::VCvtPknormU16F32, Opcode::PackUnorm2x16F32},
{Decoder::Opcode::VCvtPkU16U32, Opcode::PackU16U32},
{Decoder::Opcode::VCvtPkU8F32, Opcode::PackU8F32},
{Decoder::Opcode::VPackB32F16, Opcode::PackB32F16},
{Decoder::Opcode::VPkMadI16, Opcode::PackedMadI16},
{Decoder::Opcode::VPkMulLoU16, Opcode::PackedMulLoU16},
{Decoder::Opcode::VPkAddI16, Opcode::PackedAddI16},
{Decoder::Opcode::VPkSubI16, Opcode::PackedSubI16},
{Decoder::Opcode::VPkLshlrevB16, Opcode::PackedLshlrevB16},
{Decoder::Opcode::VPkLshrrevB16, Opcode::PackedLshrrevB16},
{Decoder::Opcode::VPkAshrrevI16, Opcode::PackedAshrrevI16},
{Decoder::Opcode::VPkMaxI16, Opcode::PackedMaxI16},
{Decoder::Opcode::VPkMinI16, Opcode::PackedMinI16},
{Decoder::Opcode::VPkMadU16, Opcode::PackedMadU16},
{Decoder::Opcode::VPkAddU16, Opcode::PackedAddU16},
{Decoder::Opcode::VPkSubU16, Opcode::PackedSubU16},
{Decoder::Opcode::VPkMaxU16, Opcode::PackedMaxU16},
{Decoder::Opcode::VPkMinU16, Opcode::PackedMinU16},
{Decoder::Opcode::VPkAddF16, Opcode::PackedAddF16},
{Decoder::Opcode::VPkMulF16, Opcode::PackedMulF16},
{Decoder::Opcode::VPkMinF16, Opcode::PackedMinF16},
{Decoder::Opcode::VPkMaxF16, Opcode::PackedMaxF16},
{Decoder::Opcode::VPkFmaF16, Opcode::PackedFmaF16},
{Decoder::Opcode::VPkFmacF16, Opcode::PackedFmaF16},
{Decoder::Opcode::VAddF16, Opcode::AddF16},
{Decoder::Opcode::VSubF16, Opcode::SubF16},
{Decoder::Opcode::VSubrevF16, Opcode::SubF16},
{Decoder::Opcode::VMulF16, Opcode::MulF16},
{Decoder::Opcode::VFmacF16, Opcode::FmaF16},
{Decoder::Opcode::VFmamkF16, Opcode::FmaF16},
{Decoder::Opcode::VFmaakF16, Opcode::FmaF16},
{Decoder::Opcode::VFmaF16, Opcode::FmaF16},
{Decoder::Opcode::VMadMixloF16, Opcode::MadMixF16},
{Decoder::Opcode::VMadMixhiF16, Opcode::MadMixF16},
{Decoder::Opcode::VAndB32, Opcode::BitwiseAndU32},
{Decoder::Opcode::VOrB32, Opcode::BitwiseOrU32},
{Decoder::Opcode::VXorB32, Opcode::BitwiseXorU32},
{Decoder::Opcode::VXnorB32, Opcode::BitwiseXnorU32},
{Decoder::Opcode::VBcntU32B32, Opcode::BitCountAddU32},
{Decoder::Opcode::VMbcntLoU32B32, Opcode::MaskedBitCountLowU32},
{Decoder::Opcode::VMbcntHiU32B32, Opcode::MaskedBitCountHighU32},
{Decoder::Opcode::VLshlB32, Opcode::ShiftLeftLogicalU32},
{Decoder::Opcode::VLshlrevB32, Opcode::ShiftLeftLogicalU32},
{Decoder::Opcode::VLshlrevB16, Opcode::ShiftLeftLogicalU16},
{Decoder::Opcode::VLshrB32, Opcode::ShiftRightLogicalU32},
{Decoder::Opcode::VLshrrevB32, Opcode::ShiftRightLogicalU32},
{Decoder::Opcode::VLshrrevB16, Opcode::ShiftRightLogicalU16},
{Decoder::Opcode::VAshrI32, Opcode::ShiftRightArithmeticI32},
{Decoder::Opcode::VAshrrevI32, Opcode::ShiftRightArithmeticI32},
{Decoder::Opcode::VAshrrevI16, Opcode::ShiftRightArithmeticI16},
{Decoder::Opcode::VMinU32, Opcode::UMinU32},
{Decoder::Opcode::VMaxU32, Opcode::UMaxU32},
{Decoder::Opcode::VMaxF16, Opcode::MaxF16},
{Decoder::Opcode::VMinF16, Opcode::MinF16},
{Decoder::Opcode::VCmpFF32, Opcode::CompareFalse},
{Decoder::Opcode::VCmpLtF32, Opcode::CompareLtF32},
{Decoder::Opcode::VCmpEqF32, Opcode::CompareEqF32},
{Decoder::Opcode::VCmpLeF32, Opcode::CompareLeF32},
{Decoder::Opcode::VCmpGtF32, Opcode::CompareGtF32},
{Decoder::Opcode::VCmpLgF32, Opcode::CompareNeF32},
{Decoder::Opcode::VCmpGeF32, Opcode::CompareGeF32},
{Decoder::Opcode::VCmpOF32, Opcode::CompareOrderedF32},
{Decoder::Opcode::VCmpUF32, Opcode::CompareUnorderedF32},
{Decoder::Opcode::VCmpNgeF32, Opcode::CompareUnordLtF32},
{Decoder::Opcode::VCmpNlgF32, Opcode::CompareUnordEqF32},
{Decoder::Opcode::VCmpNgtF32, Opcode::CompareUnordLeF32},
{Decoder::Opcode::VCmpNleF32, Opcode::CompareUnordGtF32},
{Decoder::Opcode::VCmpNeqF32, Opcode::CompareUnordNeF32},
{Decoder::Opcode::VCmpNltF32, Opcode::CompareUnordGeF32},
{Decoder::Opcode::VCmpTruF32, Opcode::CompareTrue},
{Decoder::Opcode::VCmpClassF32, Opcode::CompareClassF32},
{Decoder::Opcode::VCmpLtF16, Opcode::CompareLtF16},
{Decoder::Opcode::VCmpEqF16, Opcode::CompareEqF16},
{Decoder::Opcode::VCmpLeF16, Opcode::CompareLeF16},
{Decoder::Opcode::VCmpGtF16, Opcode::CompareGtF16},
{Decoder::Opcode::VCmpLgF16, Opcode::CompareNeF16},
{Decoder::Opcode::VCmpGeF16, Opcode::CompareGeF16},
{Decoder::Opcode::VCmpNeqF16, Opcode::CompareUnordNeF16},
{Decoder::Opcode::VCmpxLtF16, Opcode::CompareMaskLtF16},
{Decoder::Opcode::VCmpxEqF16, Opcode::CompareMaskEqF16},
{Decoder::Opcode::VCmpxLeF16, Opcode::CompareMaskLeF16},
{Decoder::Opcode::VCmpxGtF16, Opcode::CompareMaskGtF16},
{Decoder::Opcode::VCmpxGeF16, Opcode::CompareMaskGeF16},
{Decoder::Opcode::VCmpxNeqF16, Opcode::CompareMaskUnordNeF16},
{Decoder::Opcode::VCmpxNltF16, Opcode::CompareMaskUnordGeF16},
{Decoder::Opcode::VCmpxLtF32, Opcode::CompareMaskLtF32},
{Decoder::Opcode::VCmpxEqF32, Opcode::CompareMaskEqF32},
{Decoder::Opcode::VCmpxLeF32, Opcode::CompareMaskLeF32},
{Decoder::Opcode::VCmpxGtF32, Opcode::CompareMaskGtF32},
{Decoder::Opcode::VCmpxLgF32, Opcode::CompareMaskNeF32},
{Decoder::Opcode::VCmpxGeF32, Opcode::CompareMaskGeF32},
{Decoder::Opcode::VCmpxNgeF32, Opcode::CompareMaskUnordLtF32},
{Decoder::Opcode::VCmpxNlgF32, Opcode::CompareMaskUnordEqF32},
{Decoder::Opcode::VCmpxNgtF32, Opcode::CompareMaskUnordLeF32},
{Decoder::Opcode::VCmpxNleF32, Opcode::CompareMaskUnordGtF32},
{Decoder::Opcode::VCmpxNeqF32, Opcode::CompareMaskUnordNeF32},
{Decoder::Opcode::VCmpxNltF32, Opcode::CompareMaskUnordGeF32},
{Decoder::Opcode::VCmpFI32, Opcode::CompareFalse},
{Decoder::Opcode::VCmpLtI32, Opcode::CompareLtI32},
{Decoder::Opcode::VCmpEqI32, Opcode::CompareEqI32},
{Decoder::Opcode::VCmpLeI32, Opcode::CompareLeI32},
{Decoder::Opcode::VCmpGtI32, Opcode::CompareGtI32},
{Decoder::Opcode::VCmpNeI32, Opcode::CompareNeI32},
{Decoder::Opcode::VCmpGeI32, Opcode::CompareGeI32},
{Decoder::Opcode::VCmpTI32, Opcode::CompareTrue},
{Decoder::Opcode::VCmpLtI16, Opcode::CompareLtI16},
{Decoder::Opcode::VCmpEqI16, Opcode::CompareEqI16},
{Decoder::Opcode::VCmpLeI16, Opcode::CompareLeI16},
{Decoder::Opcode::VCmpGtI16, Opcode::CompareGtI16},
{Decoder::Opcode::VCmpNeI16, Opcode::CompareNeI16},
{Decoder::Opcode::VCmpGeI16, Opcode::CompareGeI16},
{Decoder::Opcode::VCmpxLtI32, Opcode::CompareMaskLtI32},
{Decoder::Opcode::VCmpxEqI32, Opcode::CompareMaskEqI32},
{Decoder::Opcode::VCmpxLeI32, Opcode::CompareMaskLeI32},
{Decoder::Opcode::VCmpxGtI32, Opcode::CompareMaskGtI32},
{Decoder::Opcode::VCmpxNeI32, Opcode::CompareMaskNeI32},
{Decoder::Opcode::VCmpxGeI32, Opcode::CompareMaskGeI32},
{Decoder::Opcode::VCmpLtU16, Opcode::CompareLtU16},
{Decoder::Opcode::VCmpEqU16, Opcode::CompareEqU16},
{Decoder::Opcode::VCmpLeU16, Opcode::CompareLeU16},
{Decoder::Opcode::VCmpGtU16, Opcode::CompareGtU16},
{Decoder::Opcode::VCmpNeU16, Opcode::CompareNeU16},
{Decoder::Opcode::VCmpGeU16, Opcode::CompareGeU16},
{Decoder::Opcode::VCmpFU32, Opcode::CompareFalse},
{Decoder::Opcode::VCmpLtU32, Opcode::CompareLtU32},
{Decoder::Opcode::VCmpEqU32, Opcode::CompareEqU32},
{Decoder::Opcode::VCmpLeU32, Opcode::CompareLeU32},
{Decoder::Opcode::VCmpGtU32, Opcode::CompareGtU32},
{Decoder::Opcode::VCmpNeU32, Opcode::CompareNeU32},
{Decoder::Opcode::VCmpGeU32, Opcode::CompareGeU32},
{Decoder::Opcode::VCmpTU32, Opcode::CompareTrue},
{Decoder::Opcode::VCmpEqI64, Opcode::CompareEqU64},
{Decoder::Opcode::VCmpNeU64, Opcode::CompareNeU64},
{Decoder::Opcode::VCmpxLtU32, Opcode::CompareMaskLtU32},
{Decoder::Opcode::VCmpxEqU32, Opcode::CompareMaskEqU32},
{Decoder::Opcode::VCmpxLeU32, Opcode::CompareMaskLeU32},
{Decoder::Opcode::VCmpxGtU32, Opcode::CompareMaskGtU32},
{Decoder::Opcode::VCmpxNeU32, Opcode::CompareMaskNeU32},
{Decoder::Opcode::VCmpxGeU32, Opcode::CompareMaskGeU32},
{Decoder::Opcode::SLoadDword, Opcode::SLoadDword},
{Decoder::Opcode::SBufferLoadDword, Opcode::SBufferLoadDword},
{Decoder::Opcode::BufferLoadDword, Opcode::BufferLoadDword},
{Decoder::Opcode::BufferLoadSbyte, Opcode::BufferLoadSbyte},
{Decoder::Opcode::BufferLoadSshort, Opcode::BufferLoadSshort},
{Decoder::Opcode::BufferStoreByte, Opcode::BufferStoreByte},
{Decoder::Opcode::BufferStoreShort, Opcode::BufferStoreShort},
{Decoder::Opcode::BufferStoreDword, Opcode::BufferStoreDword},
{Decoder::Opcode::BufferAtomicSwap, Opcode::AtomicSwapU32},
{Decoder::Opcode::BufferAtomicAdd, Opcode::AtomicAddU32},
{Decoder::Opcode::BufferAtomicSub, Opcode::AtomicSubU32},
{Decoder::Opcode::BufferAtomicSMin, Opcode::AtomicSMinI32},
{Decoder::Opcode::BufferAtomicUMin, Opcode::AtomicUMinU32},
{Decoder::Opcode::BufferAtomicSMax, Opcode::AtomicSMaxI32},
{Decoder::Opcode::BufferAtomicUMax, Opcode::AtomicUMaxU32},
{Decoder::Opcode::BufferAtomicAnd, Opcode::AtomicAndU32},
{Decoder::Opcode::BufferAtomicOr, Opcode::AtomicOrU32},
{Decoder::Opcode::BufferAtomicXor, Opcode::AtomicXorU32},
{Decoder::Opcode::BufferAtomicFMin, Opcode::AtomicFMinF32},
{Decoder::Opcode::BufferAtomicFMax, Opcode::AtomicFMaxF32},
{Decoder::Opcode::FlatLoadUbyte, Opcode::FlatLoadUbyte},
{Decoder::Opcode::FlatLoadSbyte, Opcode::FlatLoadSbyte},
{Decoder::Opcode::FlatLoadSshort, Opcode::FlatLoadSshort},
{Decoder::Opcode::FlatStoreByte, Opcode::FlatStoreByte},
{Decoder::Opcode::FlatStoreShort, Opcode::FlatStoreShort},
{Decoder::Opcode::FlatStoreDword, Opcode::FlatStoreDword},
{Decoder::Opcode::DsAddU32, Opcode::AtomicAddU32},
{Decoder::Opcode::DsAddRtnU32, Opcode::AtomicAddU32},
{Decoder::Opcode::DsSubU32, Opcode::AtomicSubU32},
{Decoder::Opcode::DsSubRtnU32, Opcode::AtomicSubU32},
{Decoder::Opcode::DsMinI32, Opcode::AtomicSMinI32},
{Decoder::Opcode::DsMinRtnI32, Opcode::AtomicSMinI32},
{Decoder::Opcode::DsMaxI32, Opcode::AtomicSMaxI32},
{Decoder::Opcode::DsMaxRtnI32, Opcode::AtomicSMaxI32},
{Decoder::Opcode::DsMinU32, Opcode::AtomicUMinU32},
{Decoder::Opcode::DsMinRtnU32, Opcode::AtomicUMinU32},
{Decoder::Opcode::DsMaxU32, Opcode::AtomicUMaxU32},
{Decoder::Opcode::DsMaxRtnU32, Opcode::AtomicUMaxU32},
{Decoder::Opcode::DsAndB32, Opcode::AtomicAndU32},
{Decoder::Opcode::DsAndRtnB32, Opcode::AtomicAndU32},
{Decoder::Opcode::DsOrB32, Opcode::AtomicOrU32},
{Decoder::Opcode::DsOrRtnB32, Opcode::AtomicOrU32},
{Decoder::Opcode::DsXorB32, Opcode::AtomicXorU32},
{Decoder::Opcode::DsXorRtnB32, Opcode::AtomicXorU32},
{Decoder::Opcode::DsWrxchgRtnB32, Opcode::AtomicSwapU32},
{Decoder::Opcode::DsReadSbyte, Opcode::DsReadSbyte},
{Decoder::Opcode::DsReadUbyte, Opcode::DsReadUbyte},
{Decoder::Opcode::DsReadSshort, Opcode::DsReadSshort},
{Decoder::Opcode::DsReadUshort, Opcode::DsReadUshort},
{Decoder::Opcode::DsRead2B32, Opcode::DsReadB32},
{Decoder::Opcode::DsReadB32, Opcode::DsReadB32},
{Decoder::Opcode::DsReadB64, Opcode::DsReadB32},
{Decoder::Opcode::DsRead2B64, Opcode::DsReadB32},
{Decoder::Opcode::DsRead2St64B64, Opcode::DsReadB32},
{Decoder::Opcode::DsReadB96, Opcode::DsReadB32},
{Decoder::Opcode::DsReadB128, Opcode::DsReadB32},
{Decoder::Opcode::DsWriteByte, Opcode::DsWriteByte},
{Decoder::Opcode::DsWriteShort, Opcode::DsWriteShort},
{Decoder::Opcode::DsWrite2B32, Opcode::DsWriteB32},
{Decoder::Opcode::DsWrite2St64B32, Opcode::DsWriteB32},
{Decoder::Opcode::DsWrite2B64, Opcode::DsWriteB32},
{Decoder::Opcode::DsWrite2St64B64, Opcode::DsWriteB32},
{Decoder::Opcode::DsWriteB32, Opcode::DsWriteB32},
{Decoder::Opcode::DsWriteB64, Opcode::DsWriteB32},
{Decoder::Opcode::DsWriteB96, Opcode::DsWriteB32},
{Decoder::Opcode::DsWriteB128, Opcode::DsWriteB32},
{Decoder::Opcode::DsMinF32, Opcode::DsMinF32},
{Decoder::Opcode::DsMaxF32, Opcode::DsMaxF32},
{Decoder::Opcode::DsConsume, Opcode::DsConsume},
{Decoder::Opcode::DsAppend, Opcode::DsAppend},
{Decoder::Opcode::DsWriteAddtidB32, Opcode::DsWriteAddtidB32},
{Decoder::Opcode::DsReadAddtidB32, Opcode::DsReadAddtidB32},
{Decoder::Opcode::ImageGetResinfo, Opcode::ImageGetResinfo},
{Decoder::Opcode::ImageGetLod, Opcode::ImageGetLod},
{Decoder::Opcode::ImageLoad, Opcode::ImageLoad},
{Decoder::Opcode::ImageLoadMip, Opcode::ImageLoad},
{Decoder::Opcode::ImageStore, Opcode::ImageStore},
{Decoder::Opcode::ImageStoreMip, Opcode::ImageStore},
{Decoder::Opcode::ImageAtomicAdd, Opcode::AtomicAddU32},
{Decoder::Opcode::ImageAtomicUMin, Opcode::AtomicUMinU32},
{Decoder::Opcode::ImageAtomicUMax, Opcode::AtomicUMaxU32},
{Decoder::Opcode::ImageAtomicAnd, Opcode::AtomicAndU32},
{Decoder::Opcode::ImageAtomicOr, Opcode::AtomicOrU32},
{Decoder::Opcode::ImageAtomicXor, Opcode::AtomicXorU32},
{Decoder::Opcode::ImageSample, Opcode::ImageSample},
{Decoder::Opcode::ImageGather4Lz, Opcode::ImageGather4},
{Decoder::Opcode::ImageGather4C, Opcode::ImageGather4},
{Decoder::Opcode::ImageGather4CLz, Opcode::ImageGather4},
{Decoder::Opcode::ImageGather4LzO, Opcode::ImageGather4},
{Decoder::Opcode::ImageGather4CO, Opcode::ImageGather4},
{Decoder::Opcode::ImageGather4CLzO, Opcode::ImageGather4},
{Decoder::Opcode::ImageGather4H, Opcode::ImageGather4},
};
} // namespace
void SetError(std::string* error, const char* message) {
if (error != nullptr) {
*error = message;
}
}
std::optional<Opcode> LookupIrOpcode(Decoder::Opcode opcode) {
for (const auto& op: LOWER_OPS) {
if (op.decoded == opcode) {
return op.ir;
}
}
return std::nullopt;
}
bool IsReversedBinary(Decoder::Opcode opcode) {
switch (opcode) {
case Decoder::Opcode::VSubrevF32:
case Decoder::Opcode::VSubrevF16:
case Decoder::Opcode::VSubrevNcU32:
case Decoder::Opcode::VLshlrevB32:
case Decoder::Opcode::VLshrrevB32:
case Decoder::Opcode::VAshrrevI32:
case Decoder::Opcode::VLshlrevB16:
case Decoder::Opcode::VLshrrevB16:
case Decoder::Opcode::VAshrrevI16:
case Decoder::Opcode::VSubrevI32: return true;
default: return false;
}
}
bool IsVectorCarryOutOpcode(Decoder::Opcode opcode) {
switch (opcode) {
case Decoder::Opcode::VAddI32:
case Decoder::Opcode::VSubI32:
case Decoder::Opcode::VSubrevI32: return true;
default: return false;
}
}
bool ScalarResultWritesSccNonZero(Decoder::Opcode opcode) {
switch (opcode) {
case Decoder::Opcode::SAbsI32:
case Decoder::Opcode::SBcnt1I32B32:
case Decoder::Opcode::SBcnt1I32B64:
case Decoder::Opcode::SAndB32:
case Decoder::Opcode::SAndn2B32:
case Decoder::Opcode::SOrB32:
case Decoder::Opcode::SOrn2B32:
case Decoder::Opcode::SXorB32:
case Decoder::Opcode::SNandB32:
case Decoder::Opcode::SNorB32:
case Decoder::Opcode::SXnorB32:
case Decoder::Opcode::SNotB32:
case Decoder::Opcode::SLshlB32:
case Decoder::Opcode::SLshrB32:
case Decoder::Opcode::SAshrI32:
case Decoder::Opcode::SBfeU32:
case Decoder::Opcode::SAndB64:
case Decoder::Opcode::SAndn2B64:
case Decoder::Opcode::SNotB64:
case Decoder::Opcode::SOrB64:
case Decoder::Opcode::SOrn2B64:
case Decoder::Opcode::SXorB64:
case Decoder::Opcode::SNandB64:
case Decoder::Opcode::SNorB64:
case Decoder::Opcode::SXnorB64:
case Decoder::Opcode::SLshlB64:
case Decoder::Opcode::SLshrB64:
case Decoder::Opcode::SBfeU64:
case Decoder::Opcode::SWqmB64: return true;
default: return false;
}
}
bool ScalarResultIs64Bit(Decoder::Opcode opcode) {
switch (opcode) {
case Decoder::Opcode::SAndB64:
case Decoder::Opcode::SAndn2B64:
case Decoder::Opcode::SNotB64:
case Decoder::Opcode::SOrB64:
case Decoder::Opcode::SOrn2B64:
case Decoder::Opcode::SXorB64:
case Decoder::Opcode::SNandB64:
case Decoder::Opcode::SNorB64:
case Decoder::Opcode::SXnorB64:
case Decoder::Opcode::SLshlB64:
case Decoder::Opcode::SLshrB64:
case Decoder::Opcode::SBfeU64:
case Decoder::Opcode::SWqmB64: return true;
default: return false;
}
}
} // namespace Libs::Graphics::ShaderRecompiler::IR
@@ -0,0 +1,343 @@
// Semantic operations produced by RDNA2 instruction lowering. The typed frontend consumes this
// baseline set before optimization and resource planning; it must not grow without decoder support.
IR_OPCODE(ControlNop, General, Control, Void)
IR_OPCODE(Waitcnt, General, Control, Void)
IR_OPCODE(Barrier, General, Control, Void)
IR_OPCODE(Sendmsg, General, Control, Void)
IR_OPCODE(TtraceData, General, Control, Void)
IR_OPCODE(InstPrefetch, General, Control, Void)
IR_OPCODE(MoveU32, General, Move)
IR_OPCODE(MoveF32Bits, General, Move)
IR_OPCODE(MoveRelDestU32, General, Lane)
IR_OPCODE(MoveRelSourceU32, General, Lane)
IR_OPCODE(MoveU64, General, Move)
IR_OPCODE(WqmB64, General, Move)
IR_OPCODE(SaveexecB32, General, State)
IR_OPCODE(SaveexecB64, General, State)
IR_OPCODE(ReadFirstLaneU32, General, Lane)
IR_OPCODE(ReadLaneU32, General, Lane)
IR_OPCODE(WriteLaneU32, General, Lane)
IR_OPCODE(Permlane16B32, General, Lane)
IR_OPCODE(Permlanex16B32, General, Lane)
IR_OPCODE(AbsI32, General, SimpleInteger)
IR_OPCODE(IAddU32, General, SimpleInteger)
IR_OPCODE(IAddCarryU32, General, State)
IR_OPCODE(ISubBorrowU32, General, State)
IR_OPCODE(ScalarAddCarryU32, General, State)
IR_OPCODE(ScalarSubBorrowU32, General, State)
IR_OPCODE(ScalarSubBorrowCarryU32, General, State)
IR_OPCODE(ScalarSignedAddOverflowI32, General, State)
IR_OPCODE(ScalarSignedSubOverflowI32, General, State)
IR_OPCODE(ScalarShiftLeftAddCarryU32, General, State)
IR_OPCODE(ISubU32, General, SimpleInteger)
IR_OPCODE(IMulU32, General, SimpleInteger)
IR_OPCODE(UMulHighU32, General, SimpleInteger)
IR_OPCODE(SMulHighI32, General, SimpleInteger)
IR_OPCODE(IMadI24U32, General, ExtendedInteger)
IR_OPCODE(UMadU24U32, General, ExtendedInteger)
IR_OPCODE(UMadU64U32, General, ExtendedInteger)
IR_OPCODE(SadU32, General, ExtendedInteger)
IR_OPCODE(IAdd3U32, General, ExtendedInteger)
IR_OPCODE(IMulI24U32, General, ExtendedInteger)
IR_OPCODE(UMulU24U32, General, ExtendedInteger)
IR_OPCODE(IMinI32, General, SimpleInteger)
IR_OPCODE(IMaxI32, General, SimpleInteger)
IR_OPCODE(IMin3I32, General, SimpleInteger)
IR_OPCODE(IMax3I32, General, SimpleInteger)
IR_OPCODE(IMed3I32, General, SimpleInteger)
IR_OPCODE(UMinU32, General, SimpleInteger)
IR_OPCODE(UMaxU32, General, SimpleInteger)
IR_OPCODE(UMin3U32, General, SimpleInteger)
IR_OPCODE(UMax3U32, General, SimpleInteger)
IR_OPCODE(UMed3U32, General, SimpleInteger)
IR_OPCODE(BitwiseAndU32, General, SimpleInteger)
IR_OPCODE(BitwiseAndU64, General, U64Mask)
IR_OPCODE(BitwiseAndNotU32, General, ComposedInteger)
IR_OPCODE(BitwiseAndNotU64, General, U64Mask)
IR_OPCODE(BitwiseOrU32, General, SimpleInteger)
IR_OPCODE(BitwiseOrU64, General, U64Mask)
IR_OPCODE(BitwiseOrNotU32, General, ComposedInteger)
IR_OPCODE(BitwiseOrNotU64, General, U64Mask)
IR_OPCODE(BitwiseAndOrU32, General, ComposedInteger)
IR_OPCODE(BitwiseOr3U32, General, ComposedInteger)
IR_OPCODE(BitwiseXorU32, General, SimpleInteger)
IR_OPCODE(BitwiseXorU64, General, U64Mask)
IR_OPCODE(BitwiseXor3U32, General, ComposedInteger)
IR_OPCODE(BitwiseNandU32, General, ComposedInteger)
IR_OPCODE(BitwiseNandU64, General, U64Mask)
IR_OPCODE(BitwiseNorU32, General, ComposedInteger)
IR_OPCODE(BitwiseNorU64, General, U64Mask)
IR_OPCODE(BitwiseXnorU32, General, ComposedInteger)
IR_OPCODE(BitwiseXnorU64, General, U64Mask)
IR_OPCODE(BitwiseNotU32, General, SimpleInteger)
IR_OPCODE(BitwiseNotU64, General, U64Mask)
IR_OPCODE(BitClearU32, General, ExtendedInteger)
IR_OPCODE(BitSetU32, General, ExtendedInteger)
IR_OPCODE(BitReverseU32, General, SimpleInteger)
IR_OPCODE(BitCountU32, General, SimpleInteger)
IR_OPCODE(BitCountU64, General, SimpleInteger)
IR_OPCODE(BitReplicateB64B32, General, ExtendedInteger)
IR_OPCODE(BitCountAddU32, General, ExtendedInteger)
IR_OPCODE(MaskedBitCountLowU32, General, ExtendedInteger)
IR_OPCODE(MaskedBitCountHighU32, General, ExtendedInteger)
IR_OPCODE(FindLsbU32, General, SimpleInteger)
IR_OPCODE(FindMsbFromHighU32, General, ComposedInteger)
IR_OPCODE(FindMsbFromHighU64, General, ComposedInteger)
IR_OPCODE(BitFieldMaskU32, General, ExtendedInteger)
IR_OPCODE(BitFieldMaskU64, General, ExtendedInteger)
IR_OPCODE(BitFieldExtractU32, General, ExtendedInteger)
IR_OPCODE(BitFieldExtractU64, General, ExtendedInteger)
IR_OPCODE(BitFieldExtract3U32, General, ExtendedInteger)
IR_OPCODE(BitFieldExtract3I32, General, ExtendedInteger)
IR_OPCODE(BitFieldInsertSelectU32, General, ExtendedInteger)
IR_OPCODE(BitCompare0B32, General, ExtendedInteger)
IR_OPCODE(BitCompare1B32, General, ExtendedInteger)
IR_OPCODE(AlignBitU32, General, ExtendedInteger)
IR_OPCODE(ShiftLeftAddU32, General, ExtendedInteger)
IR_OPCODE(AddShiftLeftU32, General, ExtendedInteger)
IR_OPCODE(XorAddU32, General, ExtendedInteger)
IR_OPCODE(ShiftLeftOrU32, General, ExtendedInteger)
IR_OPCODE(ShiftLeftLogicalU32, General, SimpleInteger)
IR_OPCODE(ShiftLeftLogicalU64, General, SimpleInteger)
IR_OPCODE(ShiftLeftLogicalU16, General, Integer16)
IR_OPCODE(ShiftRightLogicalU32, General, SimpleInteger)
IR_OPCODE(ShiftRightLogicalU64, General, SimpleInteger)
IR_OPCODE(ShiftRightLogicalU16, General, Integer16)
IR_OPCODE(ShiftRightArithmeticI32, General, SimpleInteger)
IR_OPCODE(ShiftRightArithmeticI16, General, Integer16)
IR_OPCODE(SelectU32, General, ExtendedInteger, U32, U1, U32, U32)
IR_OPCODE(SelectMaskU32, General, ExtendedInteger)
IR_OPCODE(SelectF32Bits, General, ExtendedInteger)
IR_OPCODE(SelectMaskF32Bits, General, ExtendedInteger)
IR_OPCODE(SelectU64, General, ExtendedInteger)
IR_OPCODE(PackLowLowU16, General, ExtendedInteger)
IR_OPCODE(PackLowHighU16, General, ExtendedInteger)
IR_OPCODE(PackHighHighU16, General, ExtendedInteger)
IR_OPCODE(CompareFalse, Compare, IntegerCompare)
IR_OPCODE(CompareTrue, Compare, IntegerCompare)
IR_OPCODE(CompareEqU32, Compare, IntegerCompare)
IR_OPCODE(CompareNeU32, Compare, IntegerCompare)
IR_OPCODE(CompareGtU32, Compare, IntegerCompare)
IR_OPCODE(CompareGeU32, Compare, IntegerCompare)
IR_OPCODE(CompareLtU32, Compare, IntegerCompare)
IR_OPCODE(CompareLeU32, Compare, IntegerCompare)
IR_OPCODE(CompareEqU64, Compare64, IntegerCompare)
IR_OPCODE(CompareNeU64, Compare64, IntegerCompare)
IR_OPCODE(CompareMaskEqU32, Compare, IntegerCompare)
IR_OPCODE(CompareMaskNeU32, Compare, IntegerCompare)
IR_OPCODE(CompareMaskGtU32, Compare, IntegerCompare)
IR_OPCODE(CompareMaskGeU32, Compare, IntegerCompare)
IR_OPCODE(CompareMaskLtU32, Compare, IntegerCompare)
IR_OPCODE(CompareMaskLeU32, Compare, IntegerCompare)
IR_OPCODE(CompareEqI32, Compare, IntegerCompare)
IR_OPCODE(CompareNeI32, Compare, IntegerCompare)
IR_OPCODE(CompareGtI32, Compare, IntegerCompare)
IR_OPCODE(CompareGeI32, Compare, IntegerCompare)
IR_OPCODE(CompareLtI32, Compare, IntegerCompare)
IR_OPCODE(CompareLeI32, Compare, IntegerCompare)
IR_OPCODE(CompareEqI16, Compare, Integer16Compare)
IR_OPCODE(CompareNeI16, Compare, Integer16Compare)
IR_OPCODE(CompareGtI16, Compare, Integer16Compare)
IR_OPCODE(CompareGeI16, Compare, Integer16Compare)
IR_OPCODE(CompareLtI16, Compare, Integer16Compare)
IR_OPCODE(CompareLeI16, Compare, Integer16Compare)
IR_OPCODE(CompareMaskEqI32, Compare, IntegerCompare)
IR_OPCODE(CompareMaskNeI32, Compare, IntegerCompare)
IR_OPCODE(CompareMaskGtI32, Compare, IntegerCompare)
IR_OPCODE(CompareMaskGeI32, Compare, IntegerCompare)
IR_OPCODE(CompareMaskLtI32, Compare, IntegerCompare)
IR_OPCODE(CompareMaskLeI32, Compare, IntegerCompare)
IR_OPCODE(CompareEqU16, Compare, Integer16Compare)
IR_OPCODE(CompareNeU16, Compare, Integer16Compare)
IR_OPCODE(CompareGtU16, Compare, Integer16Compare)
IR_OPCODE(CompareGeU16, Compare, Integer16Compare)
IR_OPCODE(CompareLtU16, Compare, Integer16Compare)
IR_OPCODE(CompareLeU16, Compare, Integer16Compare)
IR_OPCODE(CompareEqF32, Compare, FloatCompare)
IR_OPCODE(CompareNeF32, Compare, FloatCompare)
IR_OPCODE(CompareGtF32, Compare, FloatCompare)
IR_OPCODE(CompareGeF32, Compare, FloatCompare)
IR_OPCODE(CompareLtF32, Compare, FloatCompare)
IR_OPCODE(CompareLeF32, Compare, FloatCompare)
IR_OPCODE(CompareOrderedF32, Compare, FloatCompare)
IR_OPCODE(CompareUnorderedF32, Compare, FloatCompare)
IR_OPCODE(CompareUnordEqF32, Compare, FloatCompare)
IR_OPCODE(CompareUnordNeF32, Compare, FloatCompare)
IR_OPCODE(CompareUnordGtF32, Compare, FloatCompare)
IR_OPCODE(CompareUnordGeF32, Compare, FloatCompare)
IR_OPCODE(CompareUnordLtF32, Compare, FloatCompare)
IR_OPCODE(CompareUnordLeF32, Compare, FloatCompare)
IR_OPCODE(CompareClassF32, Compare, FloatCompare)
IR_OPCODE(CompareEqF16, Compare, FloatCompare)
IR_OPCODE(CompareNeF16, Compare, FloatCompare)
IR_OPCODE(CompareGtF16, Compare, FloatCompare)
IR_OPCODE(CompareGeF16, Compare, FloatCompare)
IR_OPCODE(CompareLtF16, Compare, FloatCompare)
IR_OPCODE(CompareLeF16, Compare, FloatCompare)
IR_OPCODE(CompareUnordNeF16, Compare, FloatCompare)
IR_OPCODE(CompareMaskEqF16, Compare, FloatCompare)
IR_OPCODE(CompareMaskNeF16, Compare, FloatCompare)
IR_OPCODE(CompareMaskGtF16, Compare, FloatCompare)
IR_OPCODE(CompareMaskGeF16, Compare, FloatCompare)
IR_OPCODE(CompareMaskLtF16, Compare, FloatCompare)
IR_OPCODE(CompareMaskLeF16, Compare, FloatCompare)
IR_OPCODE(CompareMaskUnordNeF16, Compare, FloatCompare)
IR_OPCODE(CompareMaskUnordGeF16, Compare, FloatCompare)
IR_OPCODE(CompareMaskEqF32, Compare, FloatCompare)
IR_OPCODE(CompareMaskNeF32, Compare, FloatCompare)
IR_OPCODE(CompareMaskGtF32, Compare, FloatCompare)
IR_OPCODE(CompareMaskGeF32, Compare, FloatCompare)
IR_OPCODE(CompareMaskLtF32, Compare, FloatCompare)
IR_OPCODE(CompareMaskLeF32, Compare, FloatCompare)
IR_OPCODE(CompareMaskUnordEqF32, Compare, FloatCompare)
IR_OPCODE(CompareMaskUnordNeF32, Compare, FloatCompare)
IR_OPCODE(CompareMaskUnordGtF32, Compare, FloatCompare)
IR_OPCODE(CompareMaskUnordGeF32, Compare, FloatCompare)
IR_OPCODE(CompareMaskUnordLtF32, Compare, FloatCompare)
IR_OPCODE(CompareMaskUnordLeF32, Compare, FloatCompare)
IR_OPCODE(ConvertByteU32ToF32, General, Conversion)
IR_OPCODE(ConvertU32ToF32, General, Conversion)
IR_OPCODE(ConvertI32ToF32, General, Conversion)
IR_OPCODE(ConvertF32ToU32, General, Conversion)
IR_OPCODE(ConvertF32ToI32, General, Conversion)
IR_OPCODE(ConvertF32ToF16, General, Conversion)
IR_OPCODE(ConvertF16ToF32, General, Conversion)
IR_OPCODE(ConvertU16ToF16, General, Conversion)
IR_OPCODE(ConvertF16ToU16, General, Conversion)
IR_OPCODE(ConvertI16ToF16, General, Conversion)
IR_OPCODE(ConvertF16ToI16, General, Conversion)
IR_OPCODE(ConvertRoundPlusInfF32ToI32, General, Conversion)
IR_OPCODE(ConvertFloorF32ToI32, General, Conversion)
IR_OPCODE(ConvertI4ToOffsetF32, General, Conversion)
IR_OPCODE(LdexpF32, General, Float)
IR_OPCODE(PackF32ToF16Rtz, General, Conversion)
IR_OPCODE(PackSnorm2x16F32, General, Conversion)
IR_OPCODE(PackUnorm2x16F32, General, Conversion)
IR_OPCODE(PackU16U32, General, ExtendedInteger)
IR_OPCODE(PackU8F32, General, Conversion)
IR_OPCODE(PackB32F16, General, Conversion)
IR_OPCODE(PackedMadI16, General, PackedInteger16)
IR_OPCODE(PackedMulLoU16, General, PackedInteger16)
IR_OPCODE(PackedAddI16, General, PackedInteger16)
IR_OPCODE(PackedSubI16, General, PackedInteger16)
IR_OPCODE(PackedLshlrevB16, General, PackedInteger16)
IR_OPCODE(PackedLshrrevB16, General, PackedInteger16)
IR_OPCODE(PackedAshrrevI16, General, PackedInteger16)
IR_OPCODE(PackedMaxI16, General, PackedInteger16)
IR_OPCODE(PackedMinI16, General, PackedInteger16)
IR_OPCODE(PackedMadU16, General, PackedInteger16)
IR_OPCODE(PackedAddU16, General, PackedInteger16)
IR_OPCODE(PackedSubU16, General, PackedInteger16)
IR_OPCODE(PackedMaxU16, General, PackedInteger16)
IR_OPCODE(PackedMinU16, General, PackedInteger16)
IR_OPCODE(PackedAddF16, General, PackedFloat16)
IR_OPCODE(PackedMulF16, General, PackedFloat16)
IR_OPCODE(PackedMinF16, General, PackedFloat16)
IR_OPCODE(PackedMaxF16, General, PackedFloat16)
IR_OPCODE(PackedFmaF16, General, PackedFloat16)
IR_OPCODE(AddF16, General, Float16)
IR_OPCODE(SubF16, General, Float16)
IR_OPCODE(MulF16, General, Float16)
IR_OPCODE(MinF16, General, Float16)
IR_OPCODE(MaxF16, General, Float16)
IR_OPCODE(FmaF16, General, Float16)
IR_OPCODE(MadMixF16, General, Float16)
IR_OPCODE(IAddU16, General, Integer16)
IR_OPCODE(ISubI16, General, Integer16)
IR_OPCODE(IMinI16, General, Integer16)
IR_OPCODE(IMaxI16, General, Integer16)
IR_OPCODE(UMinU16, General, Integer16)
IR_OPCODE(UMaxU16, General, Integer16)
IR_OPCODE(RcpF32, General, Float)
IR_OPCODE(RcpIflagF32, General, Float)
IR_OPCODE(FractF32, General, Float)
IR_OPCODE(TruncF32, General, Float)
IR_OPCODE(CeilF32, General, Float)
IR_OPCODE(RoundEvenF32, General, Float)
IR_OPCODE(FloorF32, General, Float)
IR_OPCODE(Exp2F32, General, Float)
IR_OPCODE(Log2F32, General, Float)
IR_OPCODE(InverseSqrtF32, General, Float)
IR_OPCODE(SqrtF32, General, Float)
IR_OPCODE(RcpF16, General, Float16)
IR_OPCODE(SqrtF16, General, Float16)
IR_OPCODE(InverseSqrtF16, General, Float16)
IR_OPCODE(Log2F16, General, Float16)
IR_OPCODE(Exp2F16, General, Float16)
IR_OPCODE(FloorF16, General, Float16)
IR_OPCODE(CeilF16, General, Float16)
IR_OPCODE(TruncF16, General, Float16)
IR_OPCODE(RoundEvenF16, General, Float16)
IR_OPCODE(SinF32, General, Float)
IR_OPCODE(CosF32, General, Float)
IR_OPCODE(CubeIdF32, General, Float)
IR_OPCODE(CubeScF32, General, Float)
IR_OPCODE(CubeTcF32, General, Float)
IR_OPCODE(CubeMaF32, General, Float)
IR_OPCODE(FAddF32, General, Float)
IR_OPCODE(FSubF32, General, Float)
IR_OPCODE(FMulF32, General, Float)
IR_OPCODE(FMinF32, General, Float)
IR_OPCODE(FMaxF32, General, Float)
IR_OPCODE(FMadF32, General, Float)
IR_OPCODE(Dot2AccF32F16, General, Float)
IR_OPCODE(FMin3F32, General, Float)
IR_OPCODE(FMax3F32, General, Float)
IR_OPCODE(FMed3F32, General, Float)
IR_OPCODE(Min3F16, General, Float16)
IR_OPCODE(Max3F16, General, Float16)
IR_OPCODE(Med3F16, General, Float16)
IR_OPCODE(LoadSrtDword, General, Memory)
IR_OPCODE(SLoadDword, General, Memory)
IR_OPCODE(SBufferLoadDword, General, Memory)
IR_OPCODE(BufferLoadUbyte, General, Memory)
IR_OPCODE(BufferLoadSbyte, General, Memory)
IR_OPCODE(BufferLoadUshort, General, Memory)
IR_OPCODE(BufferLoadSshort, General, Memory)
IR_OPCODE(BufferLoadDword, General, Memory)
IR_OPCODE(BufferStoreByte, General, Memory)
IR_OPCODE(BufferStoreShort, General, Memory)
IR_OPCODE(BufferStoreDword, General, Memory)
IR_OPCODE(AtomicSwapU32, General, Memory)
IR_OPCODE(AtomicAddU32, General, Memory)
IR_OPCODE(AtomicSubU32, General, Memory)
IR_OPCODE(AtomicSMinI32, General, Memory)
IR_OPCODE(AtomicUMinU32, General, Memory)
IR_OPCODE(AtomicSMaxI32, General, Memory)
IR_OPCODE(AtomicUMaxU32, General, Memory)
IR_OPCODE(AtomicAndU32, General, Memory)
IR_OPCODE(AtomicOrU32, General, Memory)
IR_OPCODE(AtomicXorU32, General, Memory)
IR_OPCODE(AtomicFMinF32, General, Memory)
IR_OPCODE(AtomicFMaxF32, General, Memory)
IR_OPCODE(FlatLoadUbyte, General, Memory)
IR_OPCODE(FlatLoadSbyte, General, Memory)
IR_OPCODE(FlatLoadUshort, General, Memory)
IR_OPCODE(FlatLoadSshort, General, Memory)
IR_OPCODE(FlatLoadDword, General, Memory)
IR_OPCODE(FlatStoreByte, General, Memory)
IR_OPCODE(FlatStoreShort, General, Memory)
IR_OPCODE(FlatStoreDword, General, Memory)
IR_OPCODE(DsReadUbyte, General, Memory)
IR_OPCODE(DsReadSbyte, General, Memory)
IR_OPCODE(DsReadUshort, General, Memory)
IR_OPCODE(DsReadSshort, General, Memory)
IR_OPCODE(DsReadB32, General, Memory)
IR_OPCODE(DsWriteByte, General, Memory)
IR_OPCODE(DsWriteShort, General, Memory)
IR_OPCODE(DsWriteB32, General, Memory)
IR_OPCODE(DsMinF32, General, Memory)
IR_OPCODE(DsMaxF32, General, Memory)
IR_OPCODE(DsSwizzleB32, General, Memory)
IR_OPCODE(DsConsume, General, Memory)
IR_OPCODE(DsAppend, General, Memory)
IR_OPCODE(DsWriteAddtidB32, General, Memory)
IR_OPCODE(DsReadAddtidB32, General, Memory)
IR_OPCODE(ImageGetResinfo, General, Memory)
IR_OPCODE(ImageGetLod, General, Memory)
IR_OPCODE(ImageLoad, General, Memory)
IR_OPCODE(ImageStore, General, Memory)
IR_OPCODE(ImageSample, General, Memory)
IR_OPCODE(ImageGather4, General, Memory)
IR_OPCODE(LoadInputF32, General, Attribute)
IR_OPCODE(Export, General, Attribute)
@@ -0,0 +1,144 @@
#include "graphics/shader/recompiler/ir/opcodes/ValueOpcodes.h"
#include <array>
namespace Libs::Graphics::ShaderRecompiler::IR {
namespace {
struct OpcodeMeta {
std::string_view name;
Type type = Type::Void;
std::array<Type, 16> args = {};
size_t num_args = 0;
};
template <typename... Args>
consteval OpcodeMeta MakeMeta(std::string_view name, Type type, Args... args) {
static_assert(sizeof...(Args) <= 16);
OpcodeMeta meta {.name = name, .type = type, .num_args = sizeof...(Args)};
meta.args.fill(Type::Void);
size_t index = 0;
((meta.args[index++] = args), ...);
return meta;
}
constexpr Type Void = Type::Void;
constexpr Type Opaque = Type::Opaque;
constexpr Type ScalarReg = Type::ScalarReg;
constexpr Type VectorReg = Type::VectorReg;
constexpr Type U1 = Type::U1;
constexpr Type U8 = Type::U8;
constexpr Type U16 = Type::U16;
constexpr Type U32 = Type::U32;
constexpr Type U64 = Type::U64;
constexpr Type F16 = Type::F16;
constexpr Type F32 = Type::F32;
constexpr Type U32x2 = Type::U32x2;
constexpr Type U32x4 = Type::U32x4;
constexpr Type F32x2 = Type::F32x2;
constexpr Type SrtResource = Type::SrtResource;
constexpr Type BufferResource = Type::BufferResource;
constexpr Type AddressResource = Type::AddressResource;
constexpr Type ImageResource = Type::ImageResource;
constexpr Type SamplerResource = Type::SamplerResource;
constexpr Type LdsResource = Type::LdsResource;
constexpr Type GdsResource = Type::GdsResource;
constexpr Type ImageAddress = Type::ImageAddress;
constexpr std::array<OpcodeMeta, static_cast<size_t>(ValueOpcode::Count)> MetaTable = {{
#define VALUE_OPCODE(name, ...) MakeMeta(#name __VA_OPT__(, ) __VA_ARGS__),
#include "graphics/shader/recompiler/ir/opcodes/ValueOpcodes.inc"
#undef VALUE_OPCODE
}};
} // namespace
Type TypeOf(ValueOpcode opcode) {
return MetaTable[static_cast<size_t>(opcode)].type;
}
size_t NumArgsOf(ValueOpcode opcode) {
return MetaTable[static_cast<size_t>(opcode)].num_args;
}
Type ArgTypeOf(ValueOpcode opcode, size_t index) {
const auto& meta = MetaTable[static_cast<size_t>(opcode)];
return meta.args.at(index);
}
std::string_view ValueOpcodeName(ValueOpcode opcode) {
return MetaTable[static_cast<size_t>(opcode)].name;
}
bool HasSideEffects(ValueOpcode opcode) {
switch (opcode) {
case ValueOpcode::Reference:
case ValueOpcode::ReferenceU32:
case ValueOpcode::Prologue:
case ValueOpcode::Epilogue:
case ValueOpcode::StoreAddressU8:
case ValueOpcode::StoreAddressU16:
case ValueOpcode::StoreAddressU32:
case ValueOpcode::StoreBufferU8:
case ValueOpcode::StoreBufferU16:
case ValueOpcode::StoreBufferU32:
case ValueOpcode::WriteSharedU8:
case ValueOpcode::WriteSharedU16:
case ValueOpcode::WriteSharedU32:
case ValueOpcode::WriteGdsU8:
case ValueOpcode::WriteGdsU16:
case ValueOpcode::WriteGdsU32:
case ValueOpcode::SharedAtomicFMin32:
case ValueOpcode::SharedAtomicFMax32:
case ValueOpcode::GdsAtomicFMin32:
case ValueOpcode::GdsAtomicFMax32:
case ValueOpcode::SharedAtomicSwap32:
case ValueOpcode::SharedAtomicIAdd32:
case ValueOpcode::SharedAtomicISub32:
case ValueOpcode::SharedAtomicSMin32:
case ValueOpcode::SharedAtomicUMin32:
case ValueOpcode::SharedAtomicSMax32:
case ValueOpcode::SharedAtomicUMax32:
case ValueOpcode::SharedAtomicAnd32:
case ValueOpcode::SharedAtomicOr32:
case ValueOpcode::SharedAtomicXor32:
case ValueOpcode::GdsAtomicSwap32:
case ValueOpcode::GdsAtomicIAdd32:
case ValueOpcode::GdsAtomicISub32:
case ValueOpcode::GdsAtomicSMin32:
case ValueOpcode::GdsAtomicUMin32:
case ValueOpcode::GdsAtomicSMax32:
case ValueOpcode::GdsAtomicUMax32:
case ValueOpcode::GdsAtomicAnd32:
case ValueOpcode::GdsAtomicOr32:
case ValueOpcode::GdsAtomicXor32:
case ValueOpcode::BufferAtomicSwap32:
case ValueOpcode::BufferAtomicIAdd32:
case ValueOpcode::BufferAtomicISub32:
case ValueOpcode::BufferAtomicSMin32:
case ValueOpcode::BufferAtomicUMin32:
case ValueOpcode::BufferAtomicSMax32:
case ValueOpcode::BufferAtomicUMax32:
case ValueOpcode::BufferAtomicAnd32:
case ValueOpcode::BufferAtomicOr32:
case ValueOpcode::BufferAtomicXor32:
case ValueOpcode::BufferAtomicFMin32:
case ValueOpcode::BufferAtomicFMax32:
case ValueOpcode::ImageAtomicIAdd32:
case ValueOpcode::ImageAtomicUMin32:
case ValueOpcode::ImageAtomicUMax32:
case ValueOpcode::ImageAtomicAnd32:
case ValueOpcode::ImageAtomicOr32:
case ValueOpcode::ImageAtomicXor32:
case ValueOpcode::DataAppend:
case ValueOpcode::DataConsume:
case ValueOpcode::GdsDataAppend:
case ValueOpcode::GdsDataConsume:
case ValueOpcode::ImageWrite:
case ValueOpcode::SetAttribute:
case ValueOpcode::Barrier: return true;
default: return false;
}
}
} // namespace Libs::Graphics::ShaderRecompiler::IR
@@ -0,0 +1,57 @@
#pragma once
#include "graphics/shader/recompiler/ir/Type.h"
#include <cstddef>
#include <cstdint>
#include <string_view>
#include <type_traits>
namespace Libs::Graphics::ShaderRecompiler::IR {
enum class ValueOpcode {
#define VALUE_OPCODE(name, ...) name,
#include "graphics/shader/recompiler/ir/opcodes/ValueOpcodes.inc"
#undef VALUE_OPCODE
Count,
};
struct DppMoveFlags {
uint16_t control = 0;
uint8_t row_mask = 0xf;
uint8_t bank_mask = 0xf;
bool fetch_inactive = false;
bool bound_control = false;
};
static_assert(sizeof(DppMoveFlags) <= sizeof(uint64_t));
static_assert(std::is_trivially_copyable_v<DppMoveFlags>);
struct PermlaneFlags {
bool x16 = false;
bool fetch_inactive = false;
bool bound_control = false;
};
static_assert(sizeof(PermlaneFlags) <= sizeof(uint64_t));
static_assert(std::is_trivially_copyable_v<PermlaneFlags>);
struct MemoryFlags {
uint32_t index = 0;
uint32_t pc = 0;
};
static_assert(sizeof(MemoryFlags) == sizeof(uint64_t));
static_assert(std::is_trivially_copyable_v<MemoryFlags>);
struct ExportFlags {
uint32_t index = 0;
uint32_t pc = 0;
};
static_assert(sizeof(ExportFlags) == sizeof(uint64_t));
static_assert(std::is_trivially_copyable_v<ExportFlags>);
[[nodiscard]] Type TypeOf(ValueOpcode opcode);
[[nodiscard]] Type ArgTypeOf(ValueOpcode opcode, size_t index);
[[nodiscard]] size_t NumArgsOf(ValueOpcode opcode);
[[nodiscard]] bool HasSideEffects(ValueOpcode opcode);
[[nodiscard]] std::string_view ValueOpcodeName(ValueOpcode opcode);
} // namespace Libs::Graphics::ShaderRecompiler::IR
@@ -0,0 +1,299 @@
// operation, result, arguments...
VALUE_OPCODE(Phi, Opaque)
VALUE_OPCODE(Identity, Opaque, Opaque)
VALUE_OPCODE(Void, Void)
VALUE_OPCODE(ConditionRef, U1, U1)
VALUE_OPCODE(Reference, Void, U1)
VALUE_OPCODE(ReferenceU32, Void, U32)
// Translation and register-state pseudo operations.
VALUE_OPCODE(Prologue, Void)
VALUE_OPCODE(Epilogue, Void)
VALUE_OPCODE(GetUserData, U32, ScalarReg)
VALUE_OPCODE(GetShaderBase, U64)
VALUE_OPCODE(GetBuiltin, U32, U32, U32)
VALUE_OPCODE(GetThreadBitScalarRegister, U1, ScalarReg)
VALUE_OPCODE(SetThreadBitScalarRegister, Void, ScalarReg, U1)
VALUE_OPCODE(GetScalarRegister, U32, ScalarReg)
VALUE_OPCODE(SetScalarRegister, Void, ScalarReg, U32)
VALUE_OPCODE(GetVectorRegister, U32, VectorReg)
VALUE_OPCODE(SetVectorRegister, Void, VectorReg, U32)
VALUE_OPCODE(GetGotoVariable, U1, U32)
VALUE_OPCODE(SetGotoVariable, Void, U32, U1)
VALUE_OPCODE(GetScc, U1)
VALUE_OPCODE(SetScc, Void, U1)
VALUE_OPCODE(GetExec, U1)
VALUE_OPCODE(SetExec, Void, U1)
VALUE_OPCODE(GetExecLo, U32)
VALUE_OPCODE(SetExecLo, Void, U32)
VALUE_OPCODE(GetExecHi, U32)
VALUE_OPCODE(SetExecHi, Void, U32)
VALUE_OPCODE(GetVcc, U1)
VALUE_OPCODE(SetVcc, Void, U1)
VALUE_OPCODE(GetVccLo, U32)
VALUE_OPCODE(SetVccLo, Void, U32)
VALUE_OPCODE(GetVccHi, U32)
VALUE_OPCODE(SetVccHi, Void, U32)
VALUE_OPCODE(GetM0, U32)
VALUE_OPCODE(SetM0, Void, U32)
VALUE_OPCODE(UndefU1, U1)
VALUE_OPCODE(UndefU8, U8)
VALUE_OPCODE(UndefU16, U16)
VALUE_OPCODE(UndefU32, U32)
VALUE_OPCODE(UndefU64, U64)
// Value construction and bit-preserving conversion.
VALUE_OPCODE(BitCastU16F16, U16, F16)
VALUE_OPCODE(BitCastF16U16, F16, U16)
VALUE_OPCODE(BitCastU32F32, U32, F32)
VALUE_OPCODE(BitCastF32U32, F32, U32)
VALUE_OPCODE(ConvertU16U32, U16, U32)
VALUE_OPCODE(ConvertU32U16, U32, U16)
VALUE_OPCODE(ConvertU8U32, U8, U32)
VALUE_OPCODE(ConvertU32U8, U32, U8)
VALUE_OPCODE(ConvertF32F16, F32, F16)
VALUE_OPCODE(ConvertF16F32, F16, F32)
VALUE_OPCODE(ConvertS32F32, U32, F32)
VALUE_OPCODE(ConvertU32F32, U32, F32)
VALUE_OPCODE(ConvertF32S32, F32, U32)
VALUE_OPCODE(ConvertF32U32, F32, U32)
VALUE_OPCODE(CompositeConstructU32x2, U32x2, U32, U32)
VALUE_OPCODE(CompositeConstructF32x2, F32x2, F32, F32)
VALUE_OPCODE(CompositeConstructU32x4, U32x4, U32, U32, U32, U32)
VALUE_OPCODE(CompositeExtractU32x2, U32, U32x2, U32)
VALUE_OPCODE(CompositeExtractU32x4, U32, U32x4, U32)
VALUE_OPCODE(PackUint2x32, U64, U32x2)
VALUE_OPCODE(UnpackUint2x32, U32x2, U64)
VALUE_OPCODE(PackHalf2x16, U32, F32x2)
VALUE_OPCODE(PackSnorm2x16, U32, F32x2)
VALUE_OPCODE(PackUnorm2x16, U32, F32x2)
VALUE_OPCODE(PackFloat2x16Rtz, U32, F32, F32)
// Source/destination modifiers made explicit by translation.
VALUE_OPCODE(FPAbs32, F32, F32)
VALUE_OPCODE(FPNeg32, F32, F32)
VALUE_OPCODE(FPSaturate32, F32, F32)
VALUE_OPCODE(BitFieldInsert, U32, U32, U32, U32, U32)
VALUE_OPCODE(BitFieldUExtract, U32, U32, U32, U32)
VALUE_OPCODE(BitFieldSExtract, U32, U32, U32, U32)
VALUE_OPCODE(DppMoveU32, U32, U32, U1)
VALUE_OPCODE(DppUpdateU32, U32, U32, U32, U1)
VALUE_OPCODE(WqmMask, U1, U1)
// Core value operations used to expand architectural side effects.
VALUE_OPCODE(SelectU1, U1, U1, U1, U1)
VALUE_OPCODE(SelectF32, F32, U1, F32, F32)
VALUE_OPCODE(IAdd32, U32, U32, U32)
VALUE_OPCODE(IAdd64, U64, U64, U64)
VALUE_OPCODE(IAddCarry32, U32x2, U32, U32)
VALUE_OPCODE(ISub32, U32, U32, U32)
VALUE_OPCODE(ISub64, U64, U64, U64)
VALUE_OPCODE(IMul32, U32, U32, U32)
VALUE_OPCODE(IMul64, U64, U64, U64)
VALUE_OPCODE(UDiv32, U32, U32, U32)
VALUE_OPCODE(SMulHi, U32, U32, U32)
VALUE_OPCODE(UMulHi, U32, U32, U32)
VALUE_OPCODE(IAbs32, U32, U32)
VALUE_OPCODE(ShiftLeftLogical32, U32, U32, U32)
VALUE_OPCODE(ShiftLeftLogical64, U64, U64, U32)
VALUE_OPCODE(ShiftRightLogical32, U32, U32, U32)
VALUE_OPCODE(ShiftRightLogical64, U64, U64, U32)
VALUE_OPCODE(ShiftRightArithmetic32, U32, U32, U32)
VALUE_OPCODE(ShiftRightArithmetic64, U64, U64, U32)
VALUE_OPCODE(BitwiseAnd32, U32, U32, U32)
VALUE_OPCODE(BitwiseAnd64, U64, U64, U64)
VALUE_OPCODE(BitwiseOr32, U32, U32, U32)
VALUE_OPCODE(BitwiseOr64, U64, U64, U64)
VALUE_OPCODE(BitwiseXor32, U32, U32, U32)
VALUE_OPCODE(BitwiseNot32, U32, U32)
VALUE_OPCODE(BitReverse32, U32, U32)
VALUE_OPCODE(BitCount32, U32, U32)
VALUE_OPCODE(BitCount64, U32, U64)
VALUE_OPCODE(FindUMsb32, U32, U32)
VALUE_OPCODE(FindUMsb64, U32, U64)
VALUE_OPCODE(FindSMsb32, U32, U32)
VALUE_OPCODE(FindILsb32, U32, U32)
VALUE_OPCODE(SMin32, U32, U32, U32)
VALUE_OPCODE(UMin32, U32, U32, U32)
VALUE_OPCODE(SMax32, U32, U32, U32)
VALUE_OPCODE(UMax32, U32, U32, U32)
VALUE_OPCODE(SMinTri32, U32, U32, U32, U32)
VALUE_OPCODE(UMinTri32, U32, U32, U32, U32)
VALUE_OPCODE(SMaxTri32, U32, U32, U32, U32)
VALUE_OPCODE(UMaxTri32, U32, U32, U32, U32)
VALUE_OPCODE(SMedTri32, U32, U32, U32, U32)
VALUE_OPCODE(UMedTri32, U32, U32, U32, U32)
VALUE_OPCODE(SLessThan32, U1, U32, U32)
VALUE_OPCODE(SLessThan64, U1, U64, U64)
VALUE_OPCODE(ULessThan32, U1, U32, U32)
VALUE_OPCODE(ULessThan64, U1, U64, U64)
VALUE_OPCODE(IEqual32, U1, U32, U32)
VALUE_OPCODE(IEqual64, U1, U64, U64)
VALUE_OPCODE(SLessThanEqual32, U1, U32, U32)
VALUE_OPCODE(SLessThanEqual64, U1, U64, U64)
VALUE_OPCODE(ULessThanEqual32, U1, U32, U32)
VALUE_OPCODE(ULessThanEqual64, U1, U64, U64)
VALUE_OPCODE(SGreaterThan32, U1, U32, U32)
VALUE_OPCODE(SGreaterThan64, U1, U64, U64)
VALUE_OPCODE(UGreaterThan32, U1, U32, U32)
VALUE_OPCODE(UGreaterThan64, U1, U64, U64)
VALUE_OPCODE(INotEqual32, U1, U32, U32)
VALUE_OPCODE(INotEqual64, U1, U64, U64)
VALUE_OPCODE(SGreaterThanEqual32, U1, U32, U32)
VALUE_OPCODE(SGreaterThanEqual64, U1, U64, U64)
VALUE_OPCODE(UGreaterThanEqual32, U1, U32, U32)
VALUE_OPCODE(UGreaterThanEqual64, U1, U64, U64)
VALUE_OPCODE(LogicalOr, U1, U1, U1)
VALUE_OPCODE(LogicalAnd, U1, U1, U1)
VALUE_OPCODE(LogicalXor, U1, U1, U1)
VALUE_OPCODE(LogicalNot, U1, U1)
VALUE_OPCODE(FPOrdEqual32, U1, F32, F32)
VALUE_OPCODE(FPUnordEqual32, U1, F32, F32)
VALUE_OPCODE(FPOrdNotEqual32, U1, F32, F32)
VALUE_OPCODE(FPUnordNotEqual32, U1, F32, F32)
VALUE_OPCODE(FPOrdLessThan32, U1, F32, F32)
VALUE_OPCODE(FPUnordLessThan32, U1, F32, F32)
VALUE_OPCODE(FPOrdGreaterThan32, U1, F32, F32)
VALUE_OPCODE(FPUnordGreaterThan32, U1, F32, F32)
VALUE_OPCODE(FPOrdLessThanEqual32, U1, F32, F32)
VALUE_OPCODE(FPUnordLessThanEqual32, U1, F32, F32)
VALUE_OPCODE(FPOrdGreaterThanEqual32, U1, F32, F32)
VALUE_OPCODE(FPUnordGreaterThanEqual32, U1, F32, F32)
VALUE_OPCODE(FPIsNan32, U1, F32)
VALUE_OPCODE(FPCmpClass32, U1, F32, U32)
VALUE_OPCODE(FPAdd32, F32, F32, F32)
VALUE_OPCODE(FPSub32, F32, F32, F32)
VALUE_OPCODE(FPFma32, F32, F32, F32, F32)
VALUE_OPCODE(FPMul32, F32, F32, F32)
VALUE_OPCODE(FPMin32, F32, F32, F32)
VALUE_OPCODE(FPMax32, F32, F32, F32)
VALUE_OPCODE(FPMinTri32, F32, F32, F32, F32)
VALUE_OPCODE(FPMaxTri32, F32, F32, F32, F32)
VALUE_OPCODE(FPMedTri32, F32, F32, F32, F32)
VALUE_OPCODE(FPRecip32, F32, F32)
VALUE_OPCODE(FPRecipIFlag32, F32, F32)
VALUE_OPCODE(FPRecipSqrt32, F32, F32)
VALUE_OPCODE(FPSqrt, F32, F32)
VALUE_OPCODE(FPSin, F32, F32)
VALUE_OPCODE(FPCos, F32, F32)
VALUE_OPCODE(FPExp2, F32, F32)
VALUE_OPCODE(FPLog2, F32, F32)
VALUE_OPCODE(FPLdexp, F32, F32, U32)
VALUE_OPCODE(FPRoundEven32, F32, F32)
VALUE_OPCODE(FPFloor32, F32, F32)
VALUE_OPCODE(FPCeil32, F32, F32)
VALUE_OPCODE(FPTrunc32, F32, F32)
VALUE_OPCODE(FPFract32, F32, F32)
VALUE_OPCODE(LaneId, U32)
VALUE_OPCODE(Ballot, U32x4, U1)
VALUE_OPCODE(ReadFirstLane, U32, U32, U1)
VALUE_OPCODE(ReadLane, U32, U32, U32)
VALUE_OPCODE(WriteLane, U32, U32, U32, U32)
VALUE_OPCODE(Permlane16U32, U32, U32, U32, U32, U1)
// Typed shader resources and memory operations. Descriptor state is represented by SSA values;
// dense bindings are assigned by resource tracking.
VALUE_OPCODE(GetSrtResource, SrtResource)
VALUE_OPCODE(GetBufferResource, BufferResource, U32, U32, U32, U32)
VALUE_OPCODE(GetAddressResource, AddressResource, U32, U32)
VALUE_OPCODE(GetImageResource, ImageResource, U32, U32, U32, U32, U32, U32, U32, U32)
VALUE_OPCODE(GetSamplerResource, SamplerResource, U32, U32, U32, U32)
VALUE_OPCODE(GetLdsResource, LdsResource)
VALUE_OPCODE(GetGdsResource, GdsResource)
VALUE_OPCODE(MakeImageAddress, ImageAddress, U32, U32, U32, U32, U32, U32, U32, U32, U32, U32, U32,
U32, U32)
VALUE_OPCODE(ReadConst, U32, SrtResource, U32)
VALUE_OPCODE(ReadConstBuffer, U32, BufferResource, U32)
VALUE_OPCODE(LoadAddressU8, U8, AddressResource, U32, U32, U1)
VALUE_OPCODE(LoadAddressU16, U16, AddressResource, U32, U32, U1)
VALUE_OPCODE(LoadAddressU32, U32, AddressResource, U32, U32, U1)
VALUE_OPCODE(StoreAddressU8, Void, AddressResource, U32, U32, U8, U1)
VALUE_OPCODE(StoreAddressU16, Void, AddressResource, U32, U32, U16, U1)
VALUE_OPCODE(StoreAddressU32, Void, AddressResource, U32, U32, U32, U1)
VALUE_OPCODE(LoadBufferU8, U8, BufferResource, U32, U32, U32, U1)
VALUE_OPCODE(LoadBufferU16, U16, BufferResource, U32, U32, U32, U1)
VALUE_OPCODE(LoadBufferU32, U32, BufferResource, U32, U32, U32, U1)
VALUE_OPCODE(StoreBufferU8, Void, BufferResource, U32, U32, U32, U8, U1)
VALUE_OPCODE(StoreBufferU16, Void, BufferResource, U32, U32, U32, U16, U1)
VALUE_OPCODE(StoreBufferU32, Void, BufferResource, U32, U32, U32, U32, U1)
VALUE_OPCODE(BufferAtomicSwap32, U32, BufferResource, U32, U32, U32, U32, U1)
VALUE_OPCODE(BufferAtomicIAdd32, U32, BufferResource, U32, U32, U32, U32, U1)
VALUE_OPCODE(BufferAtomicISub32, U32, BufferResource, U32, U32, U32, U32, U1)
VALUE_OPCODE(BufferAtomicSMin32, U32, BufferResource, U32, U32, U32, U32, U1)
VALUE_OPCODE(BufferAtomicUMin32, U32, BufferResource, U32, U32, U32, U32, U1)
VALUE_OPCODE(BufferAtomicSMax32, U32, BufferResource, U32, U32, U32, U32, U1)
VALUE_OPCODE(BufferAtomicUMax32, U32, BufferResource, U32, U32, U32, U32, U1)
VALUE_OPCODE(BufferAtomicAnd32, U32, BufferResource, U32, U32, U32, U32, U1)
VALUE_OPCODE(BufferAtomicOr32, U32, BufferResource, U32, U32, U32, U32, U1)
VALUE_OPCODE(BufferAtomicXor32, U32, BufferResource, U32, U32, U32, U32, U1)
VALUE_OPCODE(BufferAtomicFMin32, U32, BufferResource, U32, U32, U32, U32, U1)
VALUE_OPCODE(BufferAtomicFMax32, U32, BufferResource, U32, U32, U32, U32, U1)
VALUE_OPCODE(LoadSharedU8, U8, LdsResource, U32, U1)
VALUE_OPCODE(LoadSharedU16, U16, LdsResource, U32, U1)
VALUE_OPCODE(LoadSharedU32, U32, LdsResource, U32, U1)
VALUE_OPCODE(WriteSharedU8, Void, LdsResource, U32, U8, U1)
VALUE_OPCODE(WriteSharedU16, Void, LdsResource, U32, U16, U1)
VALUE_OPCODE(WriteSharedU32, Void, LdsResource, U32, U32, U1)
VALUE_OPCODE(LoadGdsU8, U8, GdsResource, U32, U1)
VALUE_OPCODE(LoadGdsU16, U16, GdsResource, U32, U1)
VALUE_OPCODE(LoadGdsU32, U32, GdsResource, U32, U1)
VALUE_OPCODE(WriteGdsU8, Void, GdsResource, U32, U8, U1)
VALUE_OPCODE(WriteGdsU16, Void, GdsResource, U32, U16, U1)
VALUE_OPCODE(WriteGdsU32, Void, GdsResource, U32, U32, U1)
VALUE_OPCODE(SharedAtomicFMin32, Void, LdsResource, U32, U32, U32, U1)
VALUE_OPCODE(SharedAtomicFMax32, Void, LdsResource, U32, U32, U32, U1)
VALUE_OPCODE(GdsAtomicFMin32, Void, GdsResource, U32, U32, U32, U1)
VALUE_OPCODE(GdsAtomicFMax32, Void, GdsResource, U32, U32, U32, U1)
VALUE_OPCODE(SharedAtomicSwap32, U32, LdsResource, U32, U32, U1)
VALUE_OPCODE(SharedAtomicIAdd32, U32, LdsResource, U32, U32, U1)
VALUE_OPCODE(SharedAtomicISub32, U32, LdsResource, U32, U32, U1)
VALUE_OPCODE(SharedAtomicSMin32, U32, LdsResource, U32, U32, U1)
VALUE_OPCODE(SharedAtomicUMin32, U32, LdsResource, U32, U32, U1)
VALUE_OPCODE(SharedAtomicSMax32, U32, LdsResource, U32, U32, U1)
VALUE_OPCODE(SharedAtomicUMax32, U32, LdsResource, U32, U32, U1)
VALUE_OPCODE(SharedAtomicAnd32, U32, LdsResource, U32, U32, U1)
VALUE_OPCODE(SharedAtomicOr32, U32, LdsResource, U32, U32, U1)
VALUE_OPCODE(SharedAtomicXor32, U32, LdsResource, U32, U32, U1)
VALUE_OPCODE(GdsAtomicSwap32, U32, GdsResource, U32, U32, U1)
VALUE_OPCODE(GdsAtomicIAdd32, U32, GdsResource, U32, U32, U1)
VALUE_OPCODE(GdsAtomicISub32, U32, GdsResource, U32, U32, U1)
VALUE_OPCODE(GdsAtomicSMin32, U32, GdsResource, U32, U32, U1)
VALUE_OPCODE(GdsAtomicUMin32, U32, GdsResource, U32, U32, U1)
VALUE_OPCODE(GdsAtomicSMax32, U32, GdsResource, U32, U32, U1)
VALUE_OPCODE(GdsAtomicUMax32, U32, GdsResource, U32, U32, U1)
VALUE_OPCODE(GdsAtomicAnd32, U32, GdsResource, U32, U32, U1)
VALUE_OPCODE(GdsAtomicOr32, U32, GdsResource, U32, U32, U1)
VALUE_OPCODE(GdsAtomicXor32, U32, GdsResource, U32, U32, U1)
VALUE_OPCODE(DataAppend, U32, LdsResource, U32, U1, U32, U32)
VALUE_OPCODE(DataConsume, U32, LdsResource, U32, U1, U32, U32)
VALUE_OPCODE(GdsDataAppend, U32, GdsResource, U32, U1, U32, U32)
VALUE_OPCODE(GdsDataConsume, U32, GdsResource, U32, U1, U32, U32)
VALUE_OPCODE(SwizzleU32, U32, U32, U32, U1)
VALUE_OPCODE(ImageQueryDimensions, U32x4, ImageResource, ImageAddress)
VALUE_OPCODE(ImageQueryLod, U32x4, ImageResource, SamplerResource, ImageAddress)
VALUE_OPCODE(ImageRead, U32x4, ImageResource, ImageAddress, U1)
VALUE_OPCODE(ImageWrite, Void, ImageResource, ImageAddress, U32x4, U1)
VALUE_OPCODE(ImageSampleRaw, U32x4, ImageResource, SamplerResource, ImageAddress)
VALUE_OPCODE(ImageGatherRaw, U32x4, ImageResource, SamplerResource, ImageAddress)
VALUE_OPCODE(ImageAtomicIAdd32, U32, ImageResource, ImageAddress, U32, U1)
VALUE_OPCODE(ImageAtomicUMin32, U32, ImageResource, ImageAddress, U32, U1)
VALUE_OPCODE(ImageAtomicUMax32, U32, ImageResource, ImageAddress, U32, U1)
VALUE_OPCODE(ImageAtomicAnd32, U32, ImageResource, ImageAddress, U32, U1)
VALUE_OPCODE(ImageAtomicOr32, U32, ImageResource, ImageAddress, U32, U1)
VALUE_OPCODE(ImageAtomicXor32, U32, ImageResource, ImageAddress, U32, U1)
VALUE_OPCODE(GetAttribute, U32, U32, U32)
VALUE_OPCODE(SetAttribute, Void, U32x4, U1)
VALUE_OPCODE(ControlNop, Void)
VALUE_OPCODE(Waitcnt, Void)
VALUE_OPCODE(Barrier, Void)
VALUE_OPCODE(Sendmsg, Void)
VALUE_OPCODE(TtraceData, Void)
VALUE_OPCODE(InstPrefetch, Void)
VALUE_OPCODE(SelectU32, U32, U1, U32, U32)