mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-29 08:41:20 +00:00
Initial commit
This commit is contained in:
commit
147188b143
427 files changed
+205923
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,57 @@
|
||||
#ifndef EMULATOR_SRC_GRAPHICS_SHADER_RECOMPILER_SHADERIR_SHADERIRINTERNAL_H_
|
||||
#define EMULATOR_SRC_GRAPHICS_SHADER_RECOMPILER_SHADERIR_SHADERIRINTERNAL_H_
|
||||
|
||||
#include "graphics/shader/recompiler/ShaderIR.h"
|
||||
|
||||
namespace Libs::Graphics::ShaderRecompiler::IR {
|
||||
|
||||
void SetError(std::string* error, const char* message);
|
||||
|
||||
Opcode LookupIrOpcode(Decoder::Opcode opcode);
|
||||
bool IsImplemented(Decoder::Opcode opcode);
|
||||
bool IsReversedBinary(Decoder::Opcode opcode);
|
||||
bool IsVectorCarryOutOpcode(Decoder::Opcode opcode);
|
||||
bool ScalarResultWritesSccNonZero(Decoder::Opcode opcode);
|
||||
bool ScalarResultIs64Bit(Decoder::Opcode opcode);
|
||||
|
||||
Operand MakeSccOperand();
|
||||
Operand MakeImmediateU32(uint32_t value);
|
||||
Operand MakePcRelativeU32(uint32_t value);
|
||||
bool AppendScalarResultSccNonZero(const Decoder::Instruction& decoded, BasicBlock* block,
|
||||
std::string* error);
|
||||
uint32_t VectorByteConvertIndex(Decoder::Opcode opcode);
|
||||
void CopyOperandModifiers(const Decoder::Operand& decoded, Operand& operand);
|
||||
bool LowerRegisterOperand(const Decoder::Operand& decoded, Operand* operand,
|
||||
std::string* error);
|
||||
bool LowerSourceOperand(const Decoder::Operand& decoded, Operand* operand, std::string* error);
|
||||
void ApplyDppDestinationMask(const Decoder::Instruction& decoded, Operand& dst);
|
||||
uint32_t ResourceIndexFromOperand(const Decoder::Operand& operand);
|
||||
MemoryInfo MemoryInfoFromDecoded(const Decoder::Instruction& decoded, ResourceKind kind);
|
||||
uint32_t RawScalarLoadBase(const Decoder::Operand& operand);
|
||||
void ClearRegisterOffsetModifiers(Decoder::Operand& operand);
|
||||
bool TryGetScalarDestinationCode(const Decoder::Operand& operand, uint32_t& code);
|
||||
bool TryOffsetScalarDestination(const Decoder::Operand& operand, uint32_t index,
|
||||
Decoder::Operand* result);
|
||||
Decoder::Operand OffsetDecodedRegister(const Decoder::Operand& operand, uint32_t index);
|
||||
MemoryInfo OffsetMemoryInfo(const Decoder::Instruction& decoded, ResourceKind kind,
|
||||
uint32_t dword_index);
|
||||
uint32_t TypedBufferComponentOffsetBytes(const Decoder::Instruction& decoded,
|
||||
uint32_t component_index);
|
||||
uint32_t TypedBufferFormatComponentCount(const Decoder::Instruction& decoded);
|
||||
bool LowerMoveImmediateU32(uint32_t pc, const Decoder::Operand& dst, uint32_t value,
|
||||
BasicBlock* block, std::string* error);
|
||||
MemoryInfo OffsetBufferMemoryInfo(const Decoder::Instruction& decoded,
|
||||
uint32_t component_index);
|
||||
MemoryInfo ByteOffsetMemoryInfo(const Decoder::Instruction& decoded, ResourceKind kind,
|
||||
uint32_t byte_offset);
|
||||
ResourceKind FlatSegmentResourceKind(uint32_t segment);
|
||||
const Decoder::Operand& DecodedSourceAt(const Decoder::Instruction& decoded, uint32_t index);
|
||||
Decoder::Operand M0Operand();
|
||||
|
||||
bool IsMemoryOpcode(Decoder::Opcode opcode);
|
||||
bool LowerMemoryInstruction(const Decoder::Instruction& decoded, BasicBlock* block,
|
||||
std::string* error);
|
||||
|
||||
} // namespace Libs::Graphics::ShaderRecompiler::IR
|
||||
|
||||
#endif // EMULATOR_SRC_GRAPHICS_SHADER_RECOMPILER_SHADERIR_SHADERIRINTERNAL_H_
|
||||
@@ -0,0 +1,559 @@
|
||||
#include "graphics/shader/recompiler/ShaderIR.h"
|
||||
|
||||
#include "graphics/shader/recompiler/shaderIR/ShaderIRInternal.h"
|
||||
#include "common/assert.h"
|
||||
#include "graphics/shader/recompiler/BufferFormat.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <fmt/format.h>
|
||||
#include <utility>
|
||||
|
||||
namespace Libs::Graphics::ShaderRecompiler::IR {
|
||||
|
||||
std::string RegisterToString(Register reg) {
|
||||
switch (reg.file) {
|
||||
case RegisterFile::Scalar: return fmt::format("s{}", reg.index);
|
||||
case RegisterFile::Vector: return fmt::format("v{}", reg.index);
|
||||
case RegisterFile::Vcc:
|
||||
return reg.index == 0 ? std::string("vcc_lo") : std::string("vcc_hi");
|
||||
case RegisterFile::Exec:
|
||||
return reg.index == 0 ? std::string("exec_lo") : std::string("exec_hi");
|
||||
case RegisterFile::Scc:
|
||||
if (reg.index == static_cast<uint32_t>(Decoder::OperandKind::Scc)) {
|
||||
return "scc";
|
||||
}
|
||||
if (reg.index == static_cast<uint32_t>(Decoder::OperandKind::VccZ)) {
|
||||
return "vccz";
|
||||
}
|
||||
if (reg.index == static_cast<uint32_t>(Decoder::OperandKind::ExecZ)) {
|
||||
return "execz";
|
||||
}
|
||||
return fmt::format("scc_like_{}", reg.index);
|
||||
case RegisterFile::M0: return "m0";
|
||||
default: return "unknown_reg";
|
||||
}
|
||||
}
|
||||
|
||||
std::string OperandToString(const Operand& operand) {
|
||||
std::string text;
|
||||
switch (operand.kind) {
|
||||
case OperandKind::Register: text = RegisterToString(operand.reg); break;
|
||||
case OperandKind::ImmediateU32: text = fmt::format("0x{:08x}", operand.imm); break;
|
||||
case OperandKind::PcRelativeU32: text = fmt::format("pc_rel(0x{:08x})", operand.imm); break;
|
||||
case OperandKind::Null: text = "null"; break;
|
||||
default: text = "unknown"; break;
|
||||
}
|
||||
if (operand.sdwa_sel != 6 || operand.sdwa_sext) {
|
||||
text += fmt::format(".sdwa(sel={},sext={})", operand.sdwa_sel, operand.sdwa_sext ? 1u : 0u);
|
||||
}
|
||||
if (operand.absolute) {
|
||||
text += ".abs";
|
||||
}
|
||||
if (operand.negate) {
|
||||
text += ".neg";
|
||||
}
|
||||
if (operand.op_sel || operand.op_sel_hi || operand.negate_hi) {
|
||||
text += fmt::format(".opsel(lo={},hi={},neghi={})", operand.op_sel ? 1u : 0u,
|
||||
operand.op_sel_hi ? 1u : 0u, operand.negate_hi ? 1u : 0u);
|
||||
}
|
||||
if (operand.omod != 0) {
|
||||
text += fmt::format(".omod({})", operand.omod);
|
||||
}
|
||||
if (operand.clamp) {
|
||||
text += ".clamp";
|
||||
}
|
||||
if (operand.dpp) {
|
||||
text += fmt::format(".dpp(ctrl=0x{:x},fi={},bc={})", operand.dpp_ctrl,
|
||||
operand.dpp_fetch_inactive ? 1u : 0u, operand.dpp_bound_ctrl ? 1u : 0u);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
std::string ResourceKindToString(ResourceKind kind) {
|
||||
switch (kind) {
|
||||
case ResourceKind::ScalarBuffer: return "scalar_buffer";
|
||||
case ResourceKind::Buffer: return "buffer";
|
||||
case ResourceKind::Flat: return "flat";
|
||||
case ResourceKind::Global: return "global";
|
||||
case ResourceKind::Scratch: return "scratch";
|
||||
case ResourceKind::Lds: return "lds";
|
||||
case ResourceKind::Gds: return "gds";
|
||||
case ResourceKind::Image: return "image";
|
||||
case ResourceKind::ImageUint: return "image_uint";
|
||||
case ResourceKind::StorageImage: return "storage_image";
|
||||
case ResourceKind::StorageImageUint: return "storage_image_uint";
|
||||
case ResourceKind::Sampler: return "sampler";
|
||||
default: return "none";
|
||||
}
|
||||
}
|
||||
|
||||
const char* ImageDimensionToString(Decoder::ImageDimension dimension) {
|
||||
switch (dimension) {
|
||||
case Decoder::ImageDimension::Dim2D: return "2d";
|
||||
case Decoder::ImageDimension::Dim3D: return "3d";
|
||||
case Decoder::ImageDimension::Dim2DArray: return "2d_array";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
std::string MemoryInfoToString(const MemoryInfo& mem) {
|
||||
if (mem.kind == ResourceKind::None) {
|
||||
return "";
|
||||
}
|
||||
std::string text = fmt::format(
|
||||
" ; {} resource={} sampler={} offset={} offset2={} dmask=0x{:x} data_dwords={} "
|
||||
"data_bits={} component={}/{} dfmt={} nfmt={} signed={} typed={} formatted={} segment={} "
|
||||
"glc={} slc={} idxen={} offen={} image_flags=0x{:x} image_dim={} image_addr={} "
|
||||
"image_mip={}",
|
||||
ResourceKindToString(mem.kind).c_str(), mem.resource, mem.sampler, mem.offset,
|
||||
mem.secondary_offset, mem.dmask, mem.data_dwords, mem.data_bits, mem.component_index,
|
||||
mem.component_count, mem.data_format, mem.number_format, mem.data_signed ? 1u : 0u,
|
||||
mem.typed ? 1u : 0u, mem.formatted ? 1u : 0u, mem.memory_segment, mem.glc ? 1u : 0u,
|
||||
mem.slc ? 1u : 0u, mem.idxen ? 1u : 0u, mem.offen ? 1u : 0u, mem.image_sample_flags,
|
||||
ImageDimensionToString(mem.image_dimension), mem.image_address_components,
|
||||
mem.image_has_mip ? 1u : 0u);
|
||||
if (mem.image_nsa_dwords != 0) {
|
||||
text += fmt::format(" image_nsa_dwords={} image_nsa_addr=", mem.image_nsa_dwords);
|
||||
const auto count =
|
||||
std::min<uint32_t>(mem.image_nsa_dwords * 4u, Decoder::MaxImageNsaAddressComponents);
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
if (i != 0) {
|
||||
text += ",";
|
||||
}
|
||||
text += fmt::format("{}", mem.image_nsa_addr[i]);
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
std::string ExportInfoToString(const ExportInfo& exp) {
|
||||
return fmt::format(" ; target={} index={} raw=0x{:02x} en=0x{:x} done={} compr={} vm={}",
|
||||
ExportTargetKindToString(exp.kind).c_str(), exp.index, exp.target, exp.en,
|
||||
exp.done ? 1u : 0u, exp.compr ? 1u : 0u, exp.vm ? 1u : 0u);
|
||||
}
|
||||
|
||||
std::string InputInfoToString(Opcode op, const InputInfo& input) {
|
||||
if (op != Opcode::LoadInputF32) {
|
||||
return "";
|
||||
}
|
||||
return fmt::format(" ; input_attr={} input_chan={}", input.attr, input.chan);
|
||||
}
|
||||
|
||||
std::string TerminatorToString(const CFG::Terminator& term) {
|
||||
return fmt::format(
|
||||
"term={} cond={} true={} false={} merge={} continue={} loop={} indirect_sgpr={} "
|
||||
"indirect_selector={} indirect_targets={} selector_values={}",
|
||||
static_cast<uint32_t>(term.kind), CFG::BranchConditionToString(term.condition).c_str(),
|
||||
term.true_block, term.false_block, term.merge_block, term.continue_block,
|
||||
term.loop_header ? 1u : 0u, term.indirect_pc_sgpr, term.indirect_selector_code,
|
||||
static_cast<uint32_t>(term.indirect_targets.size()),
|
||||
static_cast<uint32_t>(term.indirect_selector_values.size()));
|
||||
}
|
||||
|
||||
std::string ExportSourcesToString(const Instruction& inst) {
|
||||
std::string text;
|
||||
for (uint32_t i = 0; i < inst.src_count && i < 4u; i++) {
|
||||
text += i == 0 ? " " : ", ";
|
||||
text += OperandToString(inst.src[i]);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
std::string InstructionToString(const Instruction& inst) {
|
||||
std::string text = fmt::format("0x{:08x}: ", inst.pc);
|
||||
if (inst.op == Opcode::Export) {
|
||||
text += "Export";
|
||||
text += ExportSourcesToString(inst);
|
||||
text += ExportInfoToString(inst.export_info);
|
||||
return text;
|
||||
}
|
||||
switch (inst.op) {
|
||||
case Opcode::ControlNop: text += "ControlNop"; break;
|
||||
case Opcode::Waitcnt: text += "Waitcnt"; break;
|
||||
case Opcode::Barrier: text += "Barrier"; break;
|
||||
case Opcode::Sendmsg: text += "Sendmsg"; break;
|
||||
case Opcode::TtraceData: text += "TtraceData"; break;
|
||||
case Opcode::InstPrefetch: text += "InstPrefetch"; break;
|
||||
case Opcode::MoveU32: text += "MoveU32"; break;
|
||||
case Opcode::MoveF32Bits: text += "MoveF32Bits"; break;
|
||||
case Opcode::MoveRelDestU32: text += "MoveRelDestU32"; break;
|
||||
case Opcode::MoveRelSourceU32: text += "MoveRelSourceU32"; break;
|
||||
case Opcode::MoveU64: text += "MoveU64"; break;
|
||||
case Opcode::WqmB64: text += "WqmB64"; break;
|
||||
case Opcode::SaveexecB32: text += "SaveexecB32"; break;
|
||||
case Opcode::SaveexecB64: text += "SaveexecB64"; break;
|
||||
case Opcode::ReadFirstLaneU32: text += "ReadFirstLaneU32"; break;
|
||||
case Opcode::ReadLaneU32: text += "ReadLaneU32"; break;
|
||||
case Opcode::WriteLaneU32: text += "WriteLaneU32"; break;
|
||||
case Opcode::Permlane16B32: text += "Permlane16B32"; break;
|
||||
case Opcode::Permlanex16B32: text += "Permlanex16B32"; break;
|
||||
case Opcode::AbsI32: text += "AbsI32"; break;
|
||||
case Opcode::IAddU32: text += "IAddU32"; break;
|
||||
case Opcode::IAddCarryU32: text += "IAddCarryU32"; break;
|
||||
case Opcode::ISubBorrowU32: text += "ISubBorrowU32"; break;
|
||||
case Opcode::ScalarAddCarryU32: text += "ScalarAddCarryU32"; break;
|
||||
case Opcode::ScalarSubBorrowU32: text += "ScalarSubBorrowU32"; break;
|
||||
case Opcode::ScalarSubBorrowCarryU32: text += "ScalarSubBorrowCarryU32"; break;
|
||||
case Opcode::ScalarSignedAddOverflowI32: text += "ScalarSignedAddOverflowI32"; break;
|
||||
case Opcode::ScalarSignedSubOverflowI32: text += "ScalarSignedSubOverflowI32"; break;
|
||||
case Opcode::ScalarShiftLeftAddCarryU32: text += "ScalarShiftLeftAddCarryU32"; break;
|
||||
case Opcode::ISubU32: text += "ISubU32"; break;
|
||||
case Opcode::IMulU32: text += "IMulU32"; break;
|
||||
case Opcode::UMulHighU32: text += "UMulHighU32"; break;
|
||||
case Opcode::SMulHighI32: text += "SMulHighI32"; break;
|
||||
case Opcode::IMadI24U32: text += "IMadI24U32"; break;
|
||||
case Opcode::UMadU24U32: text += "UMadU24U32"; break;
|
||||
case Opcode::UMadU64U32: text += "UMadU64U32"; break;
|
||||
case Opcode::SadU32: text += "SadU32"; break;
|
||||
case Opcode::IAdd3U32: text += "IAdd3U32"; break;
|
||||
case Opcode::IMulI24U32: text += "IMulI24U32"; break;
|
||||
case Opcode::UMulU24U32: text += "UMulU24U32"; break;
|
||||
case Opcode::IMinI32: text += "IMinI32"; break;
|
||||
case Opcode::IMaxI32: text += "IMaxI32"; break;
|
||||
case Opcode::IMin3I32: text += "IMin3I32"; break;
|
||||
case Opcode::IMax3I32: text += "IMax3I32"; break;
|
||||
case Opcode::IMed3I32: text += "IMed3I32"; break;
|
||||
case Opcode::UMinU32: text += "UMinU32"; break;
|
||||
case Opcode::UMaxU32: text += "UMaxU32"; break;
|
||||
case Opcode::UMin3U32: text += "UMin3U32"; break;
|
||||
case Opcode::UMax3U32: text += "UMax3U32"; break;
|
||||
case Opcode::UMed3U32: text += "UMed3U32"; break;
|
||||
case Opcode::BitwiseAndU32: text += "BitwiseAndU32"; break;
|
||||
case Opcode::BitwiseAndU64: text += "BitwiseAndU64"; break;
|
||||
case Opcode::BitwiseAndNotU32: text += "BitwiseAndNotU32"; break;
|
||||
case Opcode::BitwiseAndNotU64: text += "BitwiseAndNotU64"; break;
|
||||
case Opcode::BitwiseOrU32: text += "BitwiseOrU32"; break;
|
||||
case Opcode::BitwiseOrU64: text += "BitwiseOrU64"; break;
|
||||
case Opcode::BitwiseOrNotU32: text += "BitwiseOrNotU32"; break;
|
||||
case Opcode::BitwiseOrNotU64: text += "BitwiseOrNotU64"; break;
|
||||
case Opcode::BitwiseAndOrU32: text += "BitwiseAndOrU32"; break;
|
||||
case Opcode::BitwiseOr3U32: text += "BitwiseOr3U32"; break;
|
||||
case Opcode::BitwiseXorU32: text += "BitwiseXorU32"; break;
|
||||
case Opcode::BitwiseXorU64: text += "BitwiseXorU64"; break;
|
||||
case Opcode::BitwiseXor3U32: text += "BitwiseXor3U32"; break;
|
||||
case Opcode::BitwiseNandU32: text += "BitwiseNandU32"; break;
|
||||
case Opcode::BitwiseNandU64: text += "BitwiseNandU64"; break;
|
||||
case Opcode::BitwiseNorU32: text += "BitwiseNorU32"; break;
|
||||
case Opcode::BitwiseNorU64: text += "BitwiseNorU64"; break;
|
||||
case Opcode::BitwiseXnorU32: text += "BitwiseXnorU32"; break;
|
||||
case Opcode::BitwiseXnorU64: text += "BitwiseXnorU64"; break;
|
||||
case Opcode::BitwiseNotU32: text += "BitwiseNotU32"; break;
|
||||
case Opcode::BitwiseNotU64: text += "BitwiseNotU64"; break;
|
||||
case Opcode::BitClearU32: text += "BitClearU32"; break;
|
||||
case Opcode::BitSetU32: text += "BitSetU32"; break;
|
||||
case Opcode::BitReverseU32: text += "BitReverseU32"; break;
|
||||
case Opcode::BitCountU32: text += "BitCountU32"; break;
|
||||
case Opcode::BitCountU64: text += "BitCountU64"; break;
|
||||
case Opcode::BitReplicateB64B32: text += "BitReplicateB64B32"; break;
|
||||
case Opcode::BitCountAddU32: text += "BitCountAddU32"; break;
|
||||
case Opcode::MaskedBitCountLowU32: text += "MaskedBitCountLowU32"; break;
|
||||
case Opcode::MaskedBitCountHighU32: text += "MaskedBitCountHighU32"; break;
|
||||
case Opcode::FindLsbU32: text += "FindLsbU32"; break;
|
||||
case Opcode::FindMsbFromHighU32: text += "FindMsbFromHighU32"; break;
|
||||
case Opcode::FindMsbFromHighU64: text += "FindMsbFromHighU64"; break;
|
||||
case Opcode::BitFieldMaskU32: text += "BitFieldMaskU32"; break;
|
||||
case Opcode::BitFieldMaskU64: text += "BitFieldMaskU64"; break;
|
||||
case Opcode::BitFieldExtractU32: text += "BitFieldExtractU32"; break;
|
||||
case Opcode::BitFieldExtractU64: text += "BitFieldExtractU64"; break;
|
||||
case Opcode::BitFieldExtract3U32: text += "BitFieldExtract3U32"; break;
|
||||
case Opcode::BitFieldExtract3I32: text += "BitFieldExtract3I32"; break;
|
||||
case Opcode::BitFieldInsertSelectU32: text += "BitFieldInsertSelectU32"; break;
|
||||
case Opcode::BitCompare0B32: text += "BitCompare0B32"; break;
|
||||
case Opcode::BitCompare1B32: text += "BitCompare1B32"; break;
|
||||
case Opcode::AlignBitU32: text += "AlignBitU32"; break;
|
||||
case Opcode::ShiftLeftAddU32: text += "ShiftLeftAddU32"; break;
|
||||
case Opcode::AddShiftLeftU32: text += "AddShiftLeftU32"; break;
|
||||
case Opcode::XorAddU32: text += "XorAddU32"; break;
|
||||
case Opcode::ShiftLeftOrU32: text += "ShiftLeftOrU32"; break;
|
||||
case Opcode::ShiftLeftLogicalU32: text += "ShiftLeftLogicalU32"; break;
|
||||
case Opcode::ShiftLeftLogicalU64: text += "ShiftLeftLogicalU64"; break;
|
||||
case Opcode::ShiftLeftLogicalU16: text += "ShiftLeftLogicalU16"; break;
|
||||
case Opcode::ShiftRightLogicalU32: text += "ShiftRightLogicalU32"; break;
|
||||
case Opcode::ShiftRightLogicalU64: text += "ShiftRightLogicalU64"; break;
|
||||
case Opcode::ShiftRightLogicalU16: text += "ShiftRightLogicalU16"; break;
|
||||
case Opcode::ShiftRightArithmeticI32: text += "ShiftRightArithmeticI32"; break;
|
||||
case Opcode::ShiftRightArithmeticI16: text += "ShiftRightArithmeticI16"; break;
|
||||
case Opcode::SelectU32: text += "SelectU32"; break;
|
||||
case Opcode::SelectMaskU32: text += "SelectMaskU32"; break;
|
||||
case Opcode::SelectF32Bits: text += "SelectF32Bits"; break;
|
||||
case Opcode::SelectMaskF32Bits: text += "SelectMaskF32Bits"; break;
|
||||
case Opcode::SelectU64: text += "SelectU64"; break;
|
||||
case Opcode::PackLowLowU16: text += "PackLowLowU16"; break;
|
||||
case Opcode::PackLowHighU16: text += "PackLowHighU16"; break;
|
||||
case Opcode::PackHighHighU16: text += "PackHighHighU16"; break;
|
||||
case Opcode::CompareFalse: text += "CompareFalse"; break;
|
||||
case Opcode::CompareTrue: text += "CompareTrue"; break;
|
||||
case Opcode::CompareEqU32: text += "CompareEqU32"; break;
|
||||
case Opcode::CompareNeU32: text += "CompareNeU32"; break;
|
||||
case Opcode::CompareGtU32: text += "CompareGtU32"; break;
|
||||
case Opcode::CompareGeU32: text += "CompareGeU32"; break;
|
||||
case Opcode::CompareLtU32: text += "CompareLtU32"; break;
|
||||
case Opcode::CompareLeU32: text += "CompareLeU32"; break;
|
||||
case Opcode::CompareNeU64: text += "CompareNeU64"; break;
|
||||
case Opcode::CompareMaskEqU32: text += "CompareMaskEqU32"; break;
|
||||
case Opcode::CompareMaskNeU32: text += "CompareMaskNeU32"; break;
|
||||
case Opcode::CompareMaskGtU32: text += "CompareMaskGtU32"; break;
|
||||
case Opcode::CompareMaskGeU32: text += "CompareMaskGeU32"; break;
|
||||
case Opcode::CompareMaskLtU32: text += "CompareMaskLtU32"; break;
|
||||
case Opcode::CompareMaskLeU32: text += "CompareMaskLeU32"; break;
|
||||
case Opcode::CompareEqI32: text += "CompareEqI32"; break;
|
||||
case Opcode::CompareNeI32: text += "CompareNeI32"; break;
|
||||
case Opcode::CompareGtI32: text += "CompareGtI32"; break;
|
||||
case Opcode::CompareGeI32: text += "CompareGeI32"; break;
|
||||
case Opcode::CompareLtI32: text += "CompareLtI32"; break;
|
||||
case Opcode::CompareLeI32: text += "CompareLeI32"; break;
|
||||
case Opcode::CompareEqI16: text += "CompareEqI16"; break;
|
||||
case Opcode::CompareNeI16: text += "CompareNeI16"; break;
|
||||
case Opcode::CompareGtI16: text += "CompareGtI16"; break;
|
||||
case Opcode::CompareGeI16: text += "CompareGeI16"; break;
|
||||
case Opcode::CompareLtI16: text += "CompareLtI16"; break;
|
||||
case Opcode::CompareLeI16: text += "CompareLeI16"; break;
|
||||
case Opcode::CompareMaskEqI32: text += "CompareMaskEqI32"; break;
|
||||
case Opcode::CompareMaskNeI32: text += "CompareMaskNeI32"; break;
|
||||
case Opcode::CompareMaskGtI32: text += "CompareMaskGtI32"; break;
|
||||
case Opcode::CompareMaskGeI32: text += "CompareMaskGeI32"; break;
|
||||
case Opcode::CompareMaskLtI32: text += "CompareMaskLtI32"; break;
|
||||
case Opcode::CompareMaskLeI32: text += "CompareMaskLeI32"; break;
|
||||
case Opcode::CompareEqU16: text += "CompareEqU16"; break;
|
||||
case Opcode::CompareNeU16: text += "CompareNeU16"; break;
|
||||
case Opcode::CompareGtU16: text += "CompareGtU16"; break;
|
||||
case Opcode::CompareGeU16: text += "CompareGeU16"; break;
|
||||
case Opcode::CompareLtU16: text += "CompareLtU16"; break;
|
||||
case Opcode::CompareLeU16: text += "CompareLeU16"; break;
|
||||
case Opcode::CompareEqF32: text += "CompareEqF32"; break;
|
||||
case Opcode::CompareNeF32: text += "CompareNeF32"; break;
|
||||
case Opcode::CompareGtF32: text += "CompareGtF32"; break;
|
||||
case Opcode::CompareGeF32: text += "CompareGeF32"; break;
|
||||
case Opcode::CompareLtF32: text += "CompareLtF32"; break;
|
||||
case Opcode::CompareLeF32: text += "CompareLeF32"; break;
|
||||
case Opcode::CompareOrderedF32: text += "CompareOrderedF32"; break;
|
||||
case Opcode::CompareUnorderedF32: text += "CompareUnorderedF32"; break;
|
||||
case Opcode::CompareUnordEqF32: text += "CompareUnordEqF32"; break;
|
||||
case Opcode::CompareUnordNeF32: text += "CompareUnordNeF32"; break;
|
||||
case Opcode::CompareUnordGtF32: text += "CompareUnordGtF32"; break;
|
||||
case Opcode::CompareUnordGeF32: text += "CompareUnordGeF32"; break;
|
||||
case Opcode::CompareUnordLtF32: text += "CompareUnordLtF32"; break;
|
||||
case Opcode::CompareUnordLeF32: text += "CompareUnordLeF32"; break;
|
||||
case Opcode::CompareClassF32: text += "CompareClassF32"; break;
|
||||
case Opcode::CompareEqF16: text += "CompareEqF16"; break;
|
||||
case Opcode::CompareNeF16: text += "CompareNeF16"; break;
|
||||
case Opcode::CompareGtF16: text += "CompareGtF16"; break;
|
||||
case Opcode::CompareGeF16: text += "CompareGeF16"; break;
|
||||
case Opcode::CompareLtF16: text += "CompareLtF16"; break;
|
||||
case Opcode::CompareLeF16: text += "CompareLeF16"; break;
|
||||
case Opcode::CompareUnordNeF16: text += "CompareUnordNeF16"; break;
|
||||
case Opcode::CompareMaskEqF16: text += "CompareMaskEqF16"; break;
|
||||
case Opcode::CompareMaskNeF16: text += "CompareMaskNeF16"; break;
|
||||
case Opcode::CompareMaskGtF16: text += "CompareMaskGtF16"; break;
|
||||
case Opcode::CompareMaskGeF16: text += "CompareMaskGeF16"; break;
|
||||
case Opcode::CompareMaskLtF16: text += "CompareMaskLtF16"; break;
|
||||
case Opcode::CompareMaskLeF16: text += "CompareMaskLeF16"; break;
|
||||
case Opcode::CompareMaskUnordNeF16: text += "CompareMaskUnordNeF16"; break;
|
||||
case Opcode::CompareMaskUnordGeF16: text += "CompareMaskUnordGeF16"; break;
|
||||
case Opcode::CompareMaskEqF32: text += "CompareMaskEqF32"; break;
|
||||
case Opcode::CompareMaskNeF32: text += "CompareMaskNeF32"; break;
|
||||
case Opcode::CompareMaskGtF32: text += "CompareMaskGtF32"; break;
|
||||
case Opcode::CompareMaskGeF32: text += "CompareMaskGeF32"; break;
|
||||
case Opcode::CompareMaskLtF32: text += "CompareMaskLtF32"; break;
|
||||
case Opcode::CompareMaskLeF32: text += "CompareMaskLeF32"; break;
|
||||
case Opcode::CompareMaskUnordEqF32: text += "CompareMaskUnordEqF32"; break;
|
||||
case Opcode::CompareMaskUnordNeF32: text += "CompareMaskUnordNeF32"; break;
|
||||
case Opcode::CompareMaskUnordGtF32: text += "CompareMaskUnordGtF32"; break;
|
||||
case Opcode::CompareMaskUnordGeF32: text += "CompareMaskUnordGeF32"; break;
|
||||
case Opcode::CompareMaskUnordLtF32: text += "CompareMaskUnordLtF32"; break;
|
||||
case Opcode::CompareMaskUnordLeF32: text += "CompareMaskUnordLeF32"; break;
|
||||
case Opcode::ConvertByteU32ToF32: text += "ConvertByteU32ToF32"; break;
|
||||
case Opcode::ConvertU32ToF32: text += "ConvertU32ToF32"; break;
|
||||
case Opcode::ConvertI32ToF32: text += "ConvertI32ToF32"; break;
|
||||
case Opcode::ConvertF32ToU32: text += "ConvertF32ToU32"; break;
|
||||
case Opcode::ConvertF32ToI32: text += "ConvertF32ToI32"; break;
|
||||
case Opcode::ConvertF32ToF16: text += "ConvertF32ToF16"; break;
|
||||
case Opcode::ConvertF16ToF32: text += "ConvertF16ToF32"; break;
|
||||
case Opcode::ConvertU16ToF16: text += "ConvertU16ToF16"; break;
|
||||
case Opcode::ConvertF16ToU16: text += "ConvertF16ToU16"; break;
|
||||
case Opcode::ConvertI16ToF16: text += "ConvertI16ToF16"; break;
|
||||
case Opcode::ConvertF16ToI16: text += "ConvertF16ToI16"; break;
|
||||
case Opcode::ConvertRoundPlusInfF32ToI32: text += "ConvertRoundPlusInfF32ToI32"; break;
|
||||
case Opcode::ConvertFloorF32ToI32: text += "ConvertFloorF32ToI32"; break;
|
||||
case Opcode::ConvertI4ToOffsetF32: text += "ConvertI4ToOffsetF32"; break;
|
||||
case Opcode::LdexpF32: text += "LdexpF32"; break;
|
||||
case Opcode::PackF32ToF16Rtz: text += "PackF32ToF16Rtz"; break;
|
||||
case Opcode::PackSnorm2x16F32: text += "PackSnorm2x16F32"; break;
|
||||
case Opcode::PackUnorm2x16F32: text += "PackUnorm2x16F32"; break;
|
||||
case Opcode::PackU16U32: text += "PackU16U32"; break;
|
||||
case Opcode::PackU8F32: text += "PackU8F32"; break;
|
||||
case Opcode::PackB32F16: text += "PackB32F16"; break;
|
||||
case Opcode::PackedMadI16: text += "PackedMadI16"; break;
|
||||
case Opcode::PackedMulLoU16: text += "PackedMulLoU16"; break;
|
||||
case Opcode::PackedAddI16: text += "PackedAddI16"; break;
|
||||
case Opcode::PackedSubI16: text += "PackedSubI16"; break;
|
||||
case Opcode::PackedLshlrevB16: text += "PackedLshlrevB16"; break;
|
||||
case Opcode::PackedLshrrevB16: text += "PackedLshrrevB16"; break;
|
||||
case Opcode::PackedAshrrevI16: text += "PackedAshrrevI16"; break;
|
||||
case Opcode::PackedMaxI16: text += "PackedMaxI16"; break;
|
||||
case Opcode::PackedMinI16: text += "PackedMinI16"; break;
|
||||
case Opcode::PackedMadU16: text += "PackedMadU16"; break;
|
||||
case Opcode::PackedAddU16: text += "PackedAddU16"; break;
|
||||
case Opcode::PackedSubU16: text += "PackedSubU16"; break;
|
||||
case Opcode::PackedMaxU16: text += "PackedMaxU16"; break;
|
||||
case Opcode::PackedMinU16: text += "PackedMinU16"; break;
|
||||
case Opcode::PackedAddF16: text += "PackedAddF16"; break;
|
||||
case Opcode::PackedMulF16: text += "PackedMulF16"; break;
|
||||
case Opcode::PackedMinF16: text += "PackedMinF16"; break;
|
||||
case Opcode::PackedMaxF16: text += "PackedMaxF16"; break;
|
||||
case Opcode::PackedFmaF16: text += "PackedFmaF16"; break;
|
||||
case Opcode::AddF16: text += "AddF16"; break;
|
||||
case Opcode::SubF16: text += "SubF16"; break;
|
||||
case Opcode::MulF16: text += "MulF16"; break;
|
||||
case Opcode::MinF16: text += "MinF16"; break;
|
||||
case Opcode::MaxF16: text += "MaxF16"; break;
|
||||
case Opcode::FmaF16: text += "FmaF16"; break;
|
||||
case Opcode::MadMixF16: text += "MadMixF16"; break;
|
||||
case Opcode::IAddU16: text += "IAddU16"; break;
|
||||
case Opcode::ISubI16: text += "ISubI16"; break;
|
||||
case Opcode::IMinI16: text += "IMinI16"; break;
|
||||
case Opcode::IMaxI16: text += "IMaxI16"; break;
|
||||
case Opcode::UMinU16: text += "UMinU16"; break;
|
||||
case Opcode::UMaxU16: text += "UMaxU16"; break;
|
||||
case Opcode::RcpF32: text += "RcpF32"; break;
|
||||
case Opcode::FractF32: text += "FractF32"; break;
|
||||
case Opcode::TruncF32: text += "TruncF32"; break;
|
||||
case Opcode::CeilF32: text += "CeilF32"; break;
|
||||
case Opcode::RoundEvenF32: text += "RoundEvenF32"; break;
|
||||
case Opcode::FloorF32: text += "FloorF32"; break;
|
||||
case Opcode::Exp2F32: text += "Exp2F32"; break;
|
||||
case Opcode::Log2F32: text += "Log2F32"; break;
|
||||
case Opcode::InverseSqrtF32: text += "InverseSqrtF32"; break;
|
||||
case Opcode::SqrtF32: text += "SqrtF32"; break;
|
||||
case Opcode::RcpF16: text += "RcpF16"; break;
|
||||
case Opcode::SqrtF16: text += "SqrtF16"; break;
|
||||
case Opcode::InverseSqrtF16: text += "InverseSqrtF16"; break;
|
||||
case Opcode::Log2F16: text += "Log2F16"; break;
|
||||
case Opcode::Exp2F16: text += "Exp2F16"; break;
|
||||
case Opcode::FloorF16: text += "FloorF16"; break;
|
||||
case Opcode::CeilF16: text += "CeilF16"; break;
|
||||
case Opcode::TruncF16: text += "TruncF16"; break;
|
||||
case Opcode::RoundEvenF16: text += "RoundEvenF16"; break;
|
||||
case Opcode::SinF32: text += "SinF32"; break;
|
||||
case Opcode::CosF32: text += "CosF32"; break;
|
||||
case Opcode::CubeIdF32: text += "CubeIdF32"; break;
|
||||
case Opcode::CubeScF32: text += "CubeScF32"; break;
|
||||
case Opcode::CubeTcF32: text += "CubeTcF32"; break;
|
||||
case Opcode::CubeMaF32: text += "CubeMaF32"; break;
|
||||
case Opcode::FAddF32: text += "FAddF32"; break;
|
||||
case Opcode::FSubF32: text += "FSubF32"; break;
|
||||
case Opcode::FMulF32: text += "FMulF32"; break;
|
||||
case Opcode::FMinF32: text += "FMinF32"; break;
|
||||
case Opcode::FMaxF32: text += "FMaxF32"; break;
|
||||
case Opcode::FMadF32: text += "FMadF32"; break;
|
||||
case Opcode::Dot2AccF32F16: text += "Dot2AccF32F16"; break;
|
||||
case Opcode::FMin3F32: text += "FMin3F32"; break;
|
||||
case Opcode::FMax3F32: text += "FMax3F32"; break;
|
||||
case Opcode::FMed3F32: text += "FMed3F32"; break;
|
||||
case Opcode::Min3F16: text += "Min3F16"; break;
|
||||
case Opcode::Max3F16: text += "Max3F16"; break;
|
||||
case Opcode::Med3F16: text += "Med3F16"; break;
|
||||
case Opcode::LoadSrtDword: text += "LoadSrtDword"; break;
|
||||
case Opcode::SLoadDword: text += "SLoadDword"; break;
|
||||
case Opcode::SBufferLoadDword: text += "SBufferLoadDword"; break;
|
||||
case Opcode::BufferLoadUbyte: text += "BufferLoadUbyte"; break;
|
||||
case Opcode::BufferLoadSbyte: text += "BufferLoadSbyte"; break;
|
||||
case Opcode::BufferLoadUshort: text += "BufferLoadUshort"; break;
|
||||
case Opcode::BufferLoadSshort: text += "BufferLoadSshort"; break;
|
||||
case Opcode::BufferLoadDword: text += "BufferLoadDword"; break;
|
||||
case Opcode::BufferStoreByte: text += "BufferStoreByte"; break;
|
||||
case Opcode::BufferStoreShort: text += "BufferStoreShort"; break;
|
||||
case Opcode::BufferStoreDword: text += "BufferStoreDword"; break;
|
||||
case Opcode::AtomicSwapU32: text += "AtomicSwapU32"; break;
|
||||
case Opcode::AtomicAddU32: text += "AtomicAddU32"; break;
|
||||
case Opcode::AtomicSubU32: text += "AtomicSubU32"; break;
|
||||
case Opcode::AtomicSMinI32: text += "AtomicSMinI32"; break;
|
||||
case Opcode::AtomicUMinU32: text += "AtomicUMinU32"; break;
|
||||
case Opcode::AtomicSMaxI32: text += "AtomicSMaxI32"; break;
|
||||
case Opcode::AtomicUMaxU32: text += "AtomicUMaxU32"; break;
|
||||
case Opcode::AtomicAndU32: text += "AtomicAndU32"; break;
|
||||
case Opcode::AtomicOrU32: text += "AtomicOrU32"; break;
|
||||
case Opcode::AtomicXorU32: text += "AtomicXorU32"; break;
|
||||
case Opcode::FlatLoadUbyte: text += "FlatLoadUbyte"; break;
|
||||
case Opcode::FlatLoadSbyte: text += "FlatLoadSbyte"; break;
|
||||
case Opcode::FlatLoadUshort: text += "FlatLoadUshort"; break;
|
||||
case Opcode::FlatLoadSshort: text += "FlatLoadSshort"; break;
|
||||
case Opcode::FlatLoadDword: text += "FlatLoadDword"; break;
|
||||
case Opcode::FlatStoreByte: text += "FlatStoreByte"; break;
|
||||
case Opcode::FlatStoreShort: text += "FlatStoreShort"; break;
|
||||
case Opcode::FlatStoreDword: text += "FlatStoreDword"; break;
|
||||
case Opcode::DsReadUbyte: text += "DsReadUbyte"; break;
|
||||
case Opcode::DsReadSbyte: text += "DsReadSbyte"; break;
|
||||
case Opcode::DsReadUshort: text += "DsReadUshort"; break;
|
||||
case Opcode::DsReadSshort: text += "DsReadSshort"; break;
|
||||
case Opcode::DsReadB32: text += "DsReadB32"; break;
|
||||
case Opcode::DsWriteByte: text += "DsWriteByte"; break;
|
||||
case Opcode::DsWriteShort: text += "DsWriteShort"; break;
|
||||
case Opcode::DsWriteB32: text += "DsWriteB32"; break;
|
||||
case Opcode::DsMinF32: text += "DsMinF32"; break;
|
||||
case Opcode::DsMaxF32: text += "DsMaxF32"; break;
|
||||
case Opcode::DsSwizzleB32: text += "DsSwizzleB32"; break;
|
||||
case Opcode::DsConsume: text += "DsConsume"; break;
|
||||
case Opcode::DsAppend: text += "DsAppend"; break;
|
||||
case Opcode::DsWriteAddtidB32: text += "DsWriteAddtidB32"; break;
|
||||
case Opcode::DsReadAddtidB32: text += "DsReadAddtidB32"; break;
|
||||
case Opcode::ImageGetResinfo: text += "ImageGetResinfo"; break;
|
||||
case Opcode::ImageGetLod: text += "ImageGetLod"; break;
|
||||
case Opcode::ImageLoad: text += "ImageLoad"; break;
|
||||
case Opcode::ImageStore: text += "ImageStore"; break;
|
||||
case Opcode::ImageSample: text += "ImageSample"; break;
|
||||
case Opcode::ImageGather4: text += "ImageGather4"; break;
|
||||
case Opcode::LoadInputF32: text += "LoadInputF32"; break;
|
||||
case Opcode::Export: text += "Export"; break;
|
||||
}
|
||||
text += " ";
|
||||
text += OperandToString(inst.dst);
|
||||
if (inst.dst2.kind != OperandKind::Null) {
|
||||
text += ", ";
|
||||
text += OperandToString(inst.dst2);
|
||||
}
|
||||
for (uint32_t i = 0; i < inst.src_count; i++) {
|
||||
text += i == 0 ? ", " : ", ";
|
||||
text += OperandToString(inst.src[i]);
|
||||
}
|
||||
text += MemoryInfoToString(inst.memory);
|
||||
text += InputInfoToString(inst.op, inst.input_info);
|
||||
return text;
|
||||
}
|
||||
|
||||
std::string ExportTargetKindToString(ExportTargetKind kind) {
|
||||
switch (kind) {
|
||||
case ExportTargetKind::Null: return "null";
|
||||
case ExportTargetKind::Position: return "position";
|
||||
case ExportTargetKind::Primitive: return "primitive";
|
||||
case ExportTargetKind::Parameter: return "parameter";
|
||||
case ExportTargetKind::Mrt: return "mrt";
|
||||
case ExportTargetKind::MrtZ: return "mrtz";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
std::string ProgramToString(const Program& program) {
|
||||
std::string text;
|
||||
text += fmt::format("mode={} masks={} fallback={} reason={}\n",
|
||||
program.dispatcher_fallback ? "dispatcher" : "structured",
|
||||
program.lane_mask_mode == ShaderLaneMaskMode::NativeWave ? "native-wave"
|
||||
: "per-invocation",
|
||||
CFG::FailureKindToString(program.cfg_failure_kind).c_str(),
|
||||
program.fallback_reason.c_str());
|
||||
for (const auto& block: program.blocks) {
|
||||
text += fmt::format("block_{} pc=0x{:08x} end=0x{:08x} preds={} succs={} {}\n", block.id,
|
||||
block.start_pc, block.end_pc,
|
||||
static_cast<uint32_t>(block.predecessors.size()),
|
||||
static_cast<uint32_t>(block.successors.size()),
|
||||
TerminatorToString(block.terminator).c_str());
|
||||
for (const auto& inst: block.instructions) {
|
||||
text += " ";
|
||||
text += InstructionToString(inst);
|
||||
text += "\n";
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
} // namespace Libs::Graphics::ShaderRecompiler::IR
|
||||
@@ -0,0 +1,788 @@
|
||||
#include "graphics/shader/recompiler/ShaderIR.h"
|
||||
|
||||
#include "graphics/shader/recompiler/shaderIR/ShaderIRInternal.h"
|
||||
#include "common/assert.h"
|
||||
#include "graphics/shader/recompiler/BufferFormat.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <fmt/format.h>
|
||||
#include <utility>
|
||||
|
||||
namespace Libs::Graphics::ShaderRecompiler::IR {
|
||||
namespace {
|
||||
|
||||
bool LowerScalarBufferLoadDword(const Decoder::Instruction& decoded, BasicBlock* block, Opcode op,
|
||||
std::string* error) {
|
||||
for (uint32_t i = 0; i < decoded.data_dwords; i++) {
|
||||
Instruction inst;
|
||||
inst.pc = decoded.pc;
|
||||
inst.op = op;
|
||||
inst.src_count = 1;
|
||||
inst.memory = OffsetMemoryInfo(decoded, ResourceKind::ScalarBuffer, i);
|
||||
// Raw s_load uses a two-SGPR pointer base; s_buffer_load uses a four-SGPR
|
||||
// descriptor resource index.
|
||||
inst.memory.resource = op == Opcode::SLoadDword ? RawScalarLoadBase(decoded.src0)
|
||||
: ResourceIndexFromOperand(decoded.src0);
|
||||
if (!LowerRegisterOperand(OffsetDecodedRegister(decoded.dst, i), &inst.dst, error) ||
|
||||
!LowerSourceOperand(decoded.src1, &inst.src[0], error)) {
|
||||
return false;
|
||||
}
|
||||
block->instructions.push_back(inst);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LowerBufferAddressSources(const Decoder::Instruction& decoded, Instruction* inst,
|
||||
uint32_t first_src, std::string* error) {
|
||||
uint32_t src = first_src;
|
||||
if (decoded.idxen) {
|
||||
if (!LowerSourceOperand(decoded.src0, &inst->src[src++], error)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (decoded.offen) {
|
||||
const auto offset_source =
|
||||
decoded.idxen ? OffsetDecodedRegister(decoded.src0, 1) : decoded.src0;
|
||||
if (!LowerSourceOperand(offset_source, &inst->src[src++], error)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!LowerSourceOperand(decoded.src2, &inst->src[src++], error)) {
|
||||
return false;
|
||||
}
|
||||
inst->src_count = src;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LowerBufferLoad(const Decoder::Instruction& decoded, BasicBlock* block, std::string* error) {
|
||||
const auto ir_op =
|
||||
decoded.data_bits == 8u
|
||||
? (decoded.data_signed ? Opcode::BufferLoadSbyte : Opcode::BufferLoadUbyte)
|
||||
: decoded.data_bits == 16u
|
||||
? (decoded.data_signed ? Opcode::BufferLoadSshort : Opcode::BufferLoadUshort)
|
||||
: Opcode::BufferLoadDword;
|
||||
const auto count = decoded.data_bits == 32u ? decoded.data_dwords : 1u;
|
||||
const auto typed_format_components = TypedBufferFormatComponentCount(decoded);
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
if (i >= typed_format_components) {
|
||||
if (!LowerMoveImmediateU32(decoded.pc, OffsetDecodedRegister(decoded.dst, i), 0, block,
|
||||
error)) {
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
Instruction inst;
|
||||
inst.pc = decoded.pc;
|
||||
inst.op = ir_op;
|
||||
inst.memory = OffsetBufferMemoryInfo(decoded, i);
|
||||
if (!LowerRegisterOperand(OffsetDecodedRegister(decoded.dst, i), &inst.dst, error) ||
|
||||
!LowerBufferAddressSources(decoded, &inst, 0, error)) {
|
||||
return false;
|
||||
}
|
||||
block->instructions.push_back(inst);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LowerBufferStore(const Decoder::Instruction& decoded, BasicBlock* block, std::string* error) {
|
||||
const auto ir_op = decoded.data_bits == 8u ? Opcode::BufferStoreByte
|
||||
: decoded.data_bits == 16u ? Opcode::BufferStoreShort
|
||||
: Opcode::BufferStoreDword;
|
||||
auto count = decoded.data_bits == 32u ? decoded.data_dwords : 1u;
|
||||
if (decoded.data_bits == 32u) {
|
||||
const auto typed_format_components = TypedBufferFormatComponentCount(decoded);
|
||||
if (typed_format_components < count) {
|
||||
count = typed_format_components;
|
||||
}
|
||||
}
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
Instruction inst;
|
||||
inst.pc = decoded.pc;
|
||||
inst.op = ir_op;
|
||||
inst.memory = OffsetBufferMemoryInfo(decoded, i);
|
||||
inst.dst.kind = OperandKind::Null;
|
||||
if (!LowerSourceOperand(OffsetDecodedRegister(decoded.dst, i), &inst.src[0], error) ||
|
||||
!LowerBufferAddressSources(decoded, &inst, 1, error)) {
|
||||
return false;
|
||||
}
|
||||
block->instructions.push_back(inst);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LowerBufferAtomicDword(const Decoder::Instruction& decoded, BasicBlock* block, Opcode op,
|
||||
std::string* error) {
|
||||
Instruction inst;
|
||||
inst.pc = decoded.pc;
|
||||
inst.op = op;
|
||||
inst.memory = MemoryInfoFromDecoded(decoded, ResourceKind::Buffer);
|
||||
inst.dst.kind = OperandKind::Null;
|
||||
if ((decoded.glc && !LowerRegisterOperand(decoded.dst, &inst.dst, error)) ||
|
||||
!LowerSourceOperand(decoded.dst, &inst.src[0], error) ||
|
||||
!LowerBufferAddressSources(decoded, &inst, 1, error)) {
|
||||
return false;
|
||||
}
|
||||
block->instructions.push_back(inst);
|
||||
return true;
|
||||
}
|
||||
|
||||
ResourceKind DsMemoryKind(const Decoder::Instruction& decoded) {
|
||||
return decoded.gds ? ResourceKind::Gds : ResourceKind::Lds;
|
||||
}
|
||||
|
||||
bool LowerDsRead(const Decoder::Instruction& decoded, BasicBlock* block, std::string* error) {
|
||||
const auto ir_op = decoded.data_bits == 8u
|
||||
? (decoded.data_signed ? Opcode::DsReadSbyte : Opcode::DsReadUbyte)
|
||||
: decoded.data_bits == 16u
|
||||
? (decoded.data_signed ? Opcode::DsReadSshort : Opcode::DsReadUshort)
|
||||
: Opcode::DsReadB32;
|
||||
const auto count = decoded.data_bits == 32u ? decoded.data_dwords : 1u;
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
Instruction inst;
|
||||
inst.pc = decoded.pc;
|
||||
inst.op = ir_op;
|
||||
inst.src_count = 1;
|
||||
inst.memory = OffsetMemoryInfo(decoded, DsMemoryKind(decoded), i);
|
||||
if (!LowerRegisterOperand(OffsetDecodedRegister(decoded.dst, i), &inst.dst, error) ||
|
||||
!LowerSourceOperand(decoded.src0, &inst.src[0], error)) {
|
||||
return false;
|
||||
}
|
||||
block->instructions.push_back(inst);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LowerDsRead2(const Decoder::Instruction& decoded, BasicBlock* block, uint32_t dwords_per_read,
|
||||
std::string* error) {
|
||||
const uint32_t offsets[] = {decoded.offset, decoded.secondary_offset};
|
||||
for (uint32_t read = 0; read < 2u; read++) {
|
||||
for (uint32_t dword = 0; dword < dwords_per_read; dword++) {
|
||||
const auto index = read * dwords_per_read + dword;
|
||||
Instruction inst;
|
||||
inst.pc = decoded.pc;
|
||||
inst.op = Opcode::DsReadB32;
|
||||
inst.src_count = 1;
|
||||
inst.memory =
|
||||
ByteOffsetMemoryInfo(decoded, DsMemoryKind(decoded), offsets[read] + dword * 4u);
|
||||
if (!LowerRegisterOperand(OffsetDecodedRegister(decoded.dst, index), &inst.dst,
|
||||
error) ||
|
||||
!LowerSourceOperand(decoded.src0, &inst.src[0], error)) {
|
||||
return false;
|
||||
}
|
||||
block->instructions.push_back(inst);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LowerDsAtomicU32(const Decoder::Instruction& decoded, BasicBlock* block, Opcode op,
|
||||
bool return_old, std::string* error) {
|
||||
Instruction inst;
|
||||
inst.pc = decoded.pc;
|
||||
inst.op = op;
|
||||
inst.src_count = 2;
|
||||
inst.memory = MemoryInfoFromDecoded(decoded, DsMemoryKind(decoded));
|
||||
inst.dst.kind = return_old ? OperandKind::Register : OperandKind::Null;
|
||||
if ((return_old && !LowerRegisterOperand(decoded.dst, &inst.dst, error)) ||
|
||||
!LowerSourceOperand(decoded.src1, &inst.src[0], error) ||
|
||||
!LowerSourceOperand(decoded.src0, &inst.src[1], error)) {
|
||||
return false;
|
||||
}
|
||||
block->instructions.push_back(inst);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LowerDsSwizzleB32(const Decoder::Instruction& decoded, BasicBlock* block, std::string* error) {
|
||||
Instruction inst;
|
||||
inst.pc = decoded.pc;
|
||||
inst.op = Opcode::DsSwizzleB32;
|
||||
inst.src_count = 2;
|
||||
inst.src[1].kind = OperandKind::ImmediateU32;
|
||||
inst.src[1].imm = decoded.offset & 0xffffu;
|
||||
if (!LowerRegisterOperand(decoded.dst, &inst.dst, error) ||
|
||||
!LowerSourceOperand(decoded.src0, &inst.src[0], error)) {
|
||||
return false;
|
||||
}
|
||||
block->instructions.push_back(inst);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LowerDsFloatMinMaxF32(const Decoder::Instruction& decoded, BasicBlock* block, Opcode op,
|
||||
std::string* error) {
|
||||
Instruction inst;
|
||||
inst.pc = decoded.pc;
|
||||
inst.op = op;
|
||||
inst.src_count = 2;
|
||||
inst.memory = MemoryInfoFromDecoded(decoded, DsMemoryKind(decoded));
|
||||
inst.memory.resource = 0;
|
||||
inst.dst.kind = OperandKind::Null;
|
||||
if (!LowerSourceOperand(decoded.src1, &inst.src[0], error) ||
|
||||
!LowerSourceOperand(decoded.src0, &inst.src[1], error) ||
|
||||
!LowerSourceOperand(decoded.src2, &inst.src[2], error)) {
|
||||
return false;
|
||||
}
|
||||
inst.src_count = 3;
|
||||
block->instructions.push_back(inst);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LowerDsWriteAddtidB32(const Decoder::Instruction& decoded, BasicBlock* block,
|
||||
std::string* error) {
|
||||
Instruction inst;
|
||||
inst.pc = decoded.pc;
|
||||
inst.op = Opcode::DsWriteAddtidB32;
|
||||
inst.src_count = 2;
|
||||
inst.memory = MemoryInfoFromDecoded(decoded, DsMemoryKind(decoded));
|
||||
inst.memory.resource = 0;
|
||||
inst.dst.kind = OperandKind::Null;
|
||||
const auto m0 = M0Operand();
|
||||
if (!LowerSourceOperand(decoded.src1, &inst.src[0], error) ||
|
||||
!LowerSourceOperand(m0, &inst.src[1], error)) {
|
||||
return false;
|
||||
}
|
||||
block->instructions.push_back(inst);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LowerDsReadAddtidB32(const Decoder::Instruction& decoded, BasicBlock* block,
|
||||
std::string* error) {
|
||||
Instruction inst;
|
||||
inst.pc = decoded.pc;
|
||||
inst.op = Opcode::DsReadAddtidB32;
|
||||
inst.src_count = 1;
|
||||
inst.memory = MemoryInfoFromDecoded(decoded, DsMemoryKind(decoded));
|
||||
inst.memory.resource = 0;
|
||||
const auto m0 = M0Operand();
|
||||
if (!LowerRegisterOperand(decoded.dst, &inst.dst, error) ||
|
||||
!LowerSourceOperand(m0, &inst.src[0], error)) {
|
||||
return false;
|
||||
}
|
||||
block->instructions.push_back(inst);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LowerDsAppendConsume(const Decoder::Instruction& decoded, BasicBlock* block, Opcode op,
|
||||
std::string* error) {
|
||||
Instruction inst;
|
||||
inst.pc = decoded.pc;
|
||||
inst.op = op;
|
||||
inst.src_count = 1;
|
||||
inst.memory = MemoryInfoFromDecoded(decoded, DsMemoryKind(decoded));
|
||||
const auto m0 = M0Operand();
|
||||
if (!LowerRegisterOperand(decoded.dst, &inst.dst, error) ||
|
||||
!LowerSourceOperand(m0, &inst.src[0], error)) {
|
||||
return false;
|
||||
}
|
||||
block->instructions.push_back(inst);
|
||||
return true;
|
||||
}
|
||||
|
||||
Opcode ImageAtomicIrOpcode(Decoder::Opcode opcode) {
|
||||
switch (opcode) {
|
||||
case Decoder::Opcode::ImageAtomicAdd: return Opcode::AtomicAddU32;
|
||||
case Decoder::Opcode::ImageAtomicUMin: return Opcode::AtomicUMinU32;
|
||||
case Decoder::Opcode::ImageAtomicUMax: return Opcode::AtomicUMaxU32;
|
||||
case Decoder::Opcode::ImageAtomicAnd: return Opcode::AtomicAndU32;
|
||||
case Decoder::Opcode::ImageAtomicOr: return Opcode::AtomicOrU32;
|
||||
case Decoder::Opcode::ImageAtomicXor: return Opcode::AtomicXorU32;
|
||||
default: return Opcode::AtomicAddU32;
|
||||
}
|
||||
}
|
||||
|
||||
bool LowerImageAtomicU32(const Decoder::Instruction& decoded, BasicBlock* block,
|
||||
std::string* error) {
|
||||
Instruction inst;
|
||||
inst.pc = decoded.pc;
|
||||
inst.op = ImageAtomicIrOpcode(decoded.opcode);
|
||||
inst.src_count = 2;
|
||||
inst.memory = MemoryInfoFromDecoded(decoded, ResourceKind::StorageImageUint);
|
||||
inst.memory.sampler = 0;
|
||||
inst.dst.kind = OperandKind::Null;
|
||||
if ((decoded.glc && !LowerRegisterOperand(decoded.dst, &inst.dst, error)) ||
|
||||
!LowerSourceOperand(decoded.dst, &inst.src[0], error) ||
|
||||
!LowerSourceOperand(decoded.src0, &inst.src[1], error)) {
|
||||
return false;
|
||||
}
|
||||
block->instructions.push_back(inst);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LowerFlatLoad(const Decoder::Instruction& decoded, BasicBlock* block, std::string* error) {
|
||||
const auto kind = FlatSegmentResourceKind(decoded.memory_segment);
|
||||
const auto ir_op = decoded.data_bits == 8u
|
||||
? (decoded.data_signed ? Opcode::FlatLoadSbyte : Opcode::FlatLoadUbyte)
|
||||
: decoded.data_bits == 16u
|
||||
? (decoded.data_signed ? Opcode::FlatLoadSshort : Opcode::FlatLoadUshort)
|
||||
: Opcode::FlatLoadDword;
|
||||
const auto count = decoded.data_bits == 32u ? decoded.data_dwords : 1u;
|
||||
if (decoded.data_bits == 32u && count > 1u) {
|
||||
Instruction inst;
|
||||
inst.pc = decoded.pc;
|
||||
inst.op = ir_op;
|
||||
inst.src_count = decoded.src_count;
|
||||
inst.memory = MemoryInfoFromDecoded(decoded, kind);
|
||||
inst.memory.resource = 0;
|
||||
if (!LowerRegisterOperand(decoded.dst, &inst.dst, error)) {
|
||||
return false;
|
||||
}
|
||||
for (uint32_t i = 0; i < decoded.src_count && i < 3u; i++) {
|
||||
if (!LowerSourceOperand(DecodedSourceAt(decoded, i), &inst.src[i], error)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
block->instructions.push_back(inst);
|
||||
return true;
|
||||
}
|
||||
|
||||
for (uint32_t dword = 0; dword < count; dword++) {
|
||||
Instruction inst;
|
||||
inst.pc = decoded.pc;
|
||||
inst.op = ir_op;
|
||||
inst.src_count = decoded.src_count;
|
||||
inst.memory = OffsetMemoryInfo(decoded, kind, dword);
|
||||
inst.memory.resource = 0;
|
||||
if (!LowerRegisterOperand(OffsetDecodedRegister(decoded.dst, dword), &inst.dst, error)) {
|
||||
return false;
|
||||
}
|
||||
for (uint32_t i = 0; i < decoded.src_count && i < 3u; i++) {
|
||||
if (!LowerSourceOperand(DecodedSourceAt(decoded, i), &inst.src[i], error)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
block->instructions.push_back(inst);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LowerFlatStore(const Decoder::Instruction& decoded, BasicBlock* block, std::string* error) {
|
||||
const auto kind = FlatSegmentResourceKind(decoded.memory_segment);
|
||||
const auto ir_op = decoded.data_bits == 8u ? Opcode::FlatStoreByte
|
||||
: decoded.data_bits == 16u ? Opcode::FlatStoreShort
|
||||
: Opcode::FlatStoreDword;
|
||||
const auto count = decoded.data_bits == 32u ? decoded.data_dwords : 1u;
|
||||
for (uint32_t dword = 0; dword < count; dword++) {
|
||||
Instruction inst;
|
||||
inst.pc = decoded.pc;
|
||||
inst.op = ir_op;
|
||||
inst.src_count = decoded.src_count + 1u;
|
||||
inst.memory = OffsetMemoryInfo(decoded, kind, dword);
|
||||
inst.memory.resource = 0;
|
||||
inst.dst.kind = OperandKind::Null;
|
||||
if (!LowerSourceOperand(OffsetDecodedRegister(decoded.dst, dword), &inst.src[0], error)) {
|
||||
return false;
|
||||
}
|
||||
for (uint32_t i = 0; i < decoded.src_count && i + 1u < 3u; i++) {
|
||||
if (!LowerSourceOperand(DecodedSourceAt(decoded, i), &inst.src[i + 1u], error)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
block->instructions.push_back(inst);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LowerDsWrite(const Decoder::Instruction& decoded, BasicBlock* block, std::string* error) {
|
||||
const auto ir_op = decoded.data_bits == 8u ? Opcode::DsWriteByte
|
||||
: decoded.data_bits == 16u ? Opcode::DsWriteShort
|
||||
: Opcode::DsWriteB32;
|
||||
const auto count = decoded.data_bits == 32u ? decoded.data_dwords : 1u;
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
Instruction inst;
|
||||
inst.pc = decoded.pc;
|
||||
inst.op = ir_op;
|
||||
inst.src_count = 2;
|
||||
inst.memory = OffsetMemoryInfo(decoded, DsMemoryKind(decoded), i);
|
||||
inst.dst.kind = OperandKind::Null;
|
||||
if (!LowerSourceOperand(OffsetDecodedRegister(decoded.src1, i), &inst.src[0], error) ||
|
||||
!LowerSourceOperand(decoded.src0, &inst.src[1], error)) {
|
||||
return false;
|
||||
}
|
||||
block->instructions.push_back(inst);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LowerDsWrite2(const Decoder::Instruction& decoded, BasicBlock* block,
|
||||
uint32_t dwords_per_write, std::string* error) {
|
||||
const Decoder::Operand* data[] = {&decoded.src1, &decoded.src2};
|
||||
const uint32_t offsets[] = {decoded.offset, decoded.secondary_offset};
|
||||
for (uint32_t write = 0; write < 2u; write++) {
|
||||
for (uint32_t dword = 0; dword < dwords_per_write; dword++) {
|
||||
Instruction inst;
|
||||
inst.pc = decoded.pc;
|
||||
inst.op = Opcode::DsWriteB32;
|
||||
inst.src_count = 2;
|
||||
inst.memory =
|
||||
ByteOffsetMemoryInfo(decoded, DsMemoryKind(decoded), offsets[write] + dword * 4u);
|
||||
inst.dst.kind = OperandKind::Null;
|
||||
if (!LowerSourceOperand(OffsetDecodedRegister(*data[write], dword), &inst.src[0],
|
||||
error) ||
|
||||
!LowerSourceOperand(decoded.src0, &inst.src[1], error)) {
|
||||
return false;
|
||||
}
|
||||
block->instructions.push_back(inst);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LowerImageOperation(const Decoder::Instruction& decoded, BasicBlock* block,
|
||||
std::string* error) {
|
||||
Instruction inst;
|
||||
inst.pc = decoded.pc;
|
||||
if (decoded.opcode == Decoder::Opcode::ImageStore ||
|
||||
decoded.opcode == Decoder::Opcode::ImageStoreMip) {
|
||||
inst.op = Opcode::ImageStore;
|
||||
inst.src_count = 2;
|
||||
inst.memory = MemoryInfoFromDecoded(decoded, ResourceKind::StorageImage);
|
||||
inst.memory.sampler = 0;
|
||||
inst.dst.kind = OperandKind::Null;
|
||||
if (!LowerSourceOperand(decoded.dst, &inst.src[0], error) ||
|
||||
!LowerSourceOperand(decoded.src0, &inst.src[1], error)) {
|
||||
return false;
|
||||
}
|
||||
block->instructions.push_back(inst);
|
||||
return true;
|
||||
}
|
||||
|
||||
inst.op = decoded.opcode == Decoder::Opcode::ImageGetResinfo ? Opcode::ImageGetResinfo
|
||||
: decoded.opcode == Decoder::Opcode::ImageGetLod ? Opcode::ImageGetLod
|
||||
: decoded.opcode == Decoder::Opcode::ImageLoad ||
|
||||
decoded.opcode == Decoder::Opcode::ImageLoadMip
|
||||
? Opcode::ImageLoad
|
||||
: decoded.opcode == Decoder::Opcode::ImageGather4Lz ||
|
||||
decoded.opcode == Decoder::Opcode::ImageGather4C ||
|
||||
decoded.opcode == Decoder::Opcode::ImageGather4CLz ||
|
||||
decoded.opcode == Decoder::Opcode::ImageGather4LzO ||
|
||||
decoded.opcode == Decoder::Opcode::ImageGather4CO ||
|
||||
decoded.opcode == Decoder::Opcode::ImageGather4CLzO ||
|
||||
decoded.opcode == Decoder::Opcode::ImageGather4H
|
||||
? Opcode::ImageGather4
|
||||
: Opcode::ImageSample;
|
||||
inst.src_count = 1;
|
||||
inst.memory = MemoryInfoFromDecoded(decoded, ResourceKind::Image);
|
||||
if (!LowerRegisterOperand(decoded.dst, &inst.dst, error) ||
|
||||
!LowerSourceOperand(decoded.src0, &inst.src[0], error)) {
|
||||
return false;
|
||||
}
|
||||
block->instructions.push_back(inst);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
bool LowerMemoryInstruction(const Decoder::Instruction& decoded, BasicBlock* block,
|
||||
std::string* error) {
|
||||
switch (decoded.opcode) {
|
||||
case Decoder::Opcode::SLoadDword:
|
||||
case Decoder::Opcode::SLoadDwordx2:
|
||||
case Decoder::Opcode::SLoadDwordx4:
|
||||
case Decoder::Opcode::SLoadDwordx8:
|
||||
case Decoder::Opcode::SLoadDwordx16:
|
||||
return LowerScalarBufferLoadDword(decoded, block, Opcode::SLoadDword, error);
|
||||
case Decoder::Opcode::SBufferLoadDword:
|
||||
case Decoder::Opcode::SBufferLoadDwordx2:
|
||||
case Decoder::Opcode::SBufferLoadDwordx4:
|
||||
case Decoder::Opcode::SBufferLoadDwordx8:
|
||||
case Decoder::Opcode::SBufferLoadDwordx16:
|
||||
return LowerScalarBufferLoadDword(decoded, block, Opcode::SBufferLoadDword, error);
|
||||
case Decoder::Opcode::BufferLoadUbyte:
|
||||
case Decoder::Opcode::BufferLoadSbyte:
|
||||
case Decoder::Opcode::BufferLoadUshort:
|
||||
case Decoder::Opcode::BufferLoadSshort:
|
||||
case Decoder::Opcode::BufferLoadDword:
|
||||
case Decoder::Opcode::BufferLoadDwordx2:
|
||||
case Decoder::Opcode::BufferLoadDwordx3:
|
||||
case Decoder::Opcode::BufferLoadDwordx4:
|
||||
case Decoder::Opcode::BufferLoadFormatX:
|
||||
case Decoder::Opcode::BufferLoadFormatXy:
|
||||
case Decoder::Opcode::BufferLoadFormatXyz:
|
||||
case Decoder::Opcode::BufferLoadFormatXyzw:
|
||||
case Decoder::Opcode::TBufferLoadFormatX:
|
||||
case Decoder::Opcode::TBufferLoadFormatXy:
|
||||
case Decoder::Opcode::TBufferLoadFormatXyz:
|
||||
case Decoder::Opcode::TBufferLoadFormatXyzw: return LowerBufferLoad(decoded, block, error);
|
||||
case Decoder::Opcode::BufferStoreDword:
|
||||
case Decoder::Opcode::BufferStoreDwordx2:
|
||||
case Decoder::Opcode::BufferStoreDwordx3:
|
||||
case Decoder::Opcode::BufferStoreDwordx4:
|
||||
case Decoder::Opcode::BufferStoreByte:
|
||||
case Decoder::Opcode::BufferStoreShort:
|
||||
case Decoder::Opcode::BufferStoreFormatX:
|
||||
case Decoder::Opcode::BufferStoreFormatXy:
|
||||
case Decoder::Opcode::BufferStoreFormatXyz:
|
||||
case Decoder::Opcode::BufferStoreFormatXyzw:
|
||||
case Decoder::Opcode::TBufferStoreFormatX:
|
||||
case Decoder::Opcode::TBufferStoreFormatXy:
|
||||
case Decoder::Opcode::TBufferStoreFormatXyz:
|
||||
case Decoder::Opcode::TBufferStoreFormatXyzw:
|
||||
return LowerBufferStore(decoded, block, error);
|
||||
case Decoder::Opcode::BufferAtomicSwap:
|
||||
return LowerBufferAtomicDword(decoded, block, Opcode::AtomicSwapU32, error);
|
||||
case Decoder::Opcode::BufferAtomicAdd:
|
||||
return LowerBufferAtomicDword(decoded, block, Opcode::AtomicAddU32, error);
|
||||
case Decoder::Opcode::BufferAtomicSub:
|
||||
return LowerBufferAtomicDword(decoded, block, Opcode::AtomicSubU32, error);
|
||||
case Decoder::Opcode::BufferAtomicSMin:
|
||||
return LowerBufferAtomicDword(decoded, block, Opcode::AtomicSMinI32, error);
|
||||
case Decoder::Opcode::BufferAtomicUMin:
|
||||
return LowerBufferAtomicDword(decoded, block, Opcode::AtomicUMinU32, error);
|
||||
case Decoder::Opcode::BufferAtomicSMax:
|
||||
return LowerBufferAtomicDword(decoded, block, Opcode::AtomicSMaxI32, error);
|
||||
case Decoder::Opcode::BufferAtomicUMax:
|
||||
return LowerBufferAtomicDword(decoded, block, Opcode::AtomicUMaxU32, error);
|
||||
case Decoder::Opcode::BufferAtomicAnd:
|
||||
return LowerBufferAtomicDword(decoded, block, Opcode::AtomicAndU32, error);
|
||||
case Decoder::Opcode::BufferAtomicOr:
|
||||
return LowerBufferAtomicDword(decoded, block, Opcode::AtomicOrU32, error);
|
||||
case Decoder::Opcode::BufferAtomicXor:
|
||||
return LowerBufferAtomicDword(decoded, block, Opcode::AtomicXorU32, error);
|
||||
case Decoder::Opcode::FlatLoadUbyte:
|
||||
case Decoder::Opcode::FlatLoadSbyte:
|
||||
case Decoder::Opcode::FlatLoadUshort:
|
||||
case Decoder::Opcode::FlatLoadSshort:
|
||||
case Decoder::Opcode::FlatLoadDword:
|
||||
case Decoder::Opcode::FlatLoadDwordx2:
|
||||
case Decoder::Opcode::FlatLoadDwordx3:
|
||||
case Decoder::Opcode::FlatLoadDwordx4: return LowerFlatLoad(decoded, block, error);
|
||||
case Decoder::Opcode::FlatStoreByte:
|
||||
case Decoder::Opcode::FlatStoreShort:
|
||||
case Decoder::Opcode::FlatStoreDword:
|
||||
case Decoder::Opcode::FlatStoreDwordx2:
|
||||
case Decoder::Opcode::FlatStoreDwordx3:
|
||||
case Decoder::Opcode::FlatStoreDwordx4: return LowerFlatStore(decoded, block, error);
|
||||
case Decoder::Opcode::DsAddU32:
|
||||
return LowerDsAtomicU32(decoded, block, Opcode::AtomicAddU32, false, error);
|
||||
case Decoder::Opcode::DsAddRtnU32:
|
||||
return LowerDsAtomicU32(decoded, block, Opcode::AtomicAddU32, true, error);
|
||||
case Decoder::Opcode::DsSubU32:
|
||||
return LowerDsAtomicU32(decoded, block, Opcode::AtomicSubU32, false, error);
|
||||
case Decoder::Opcode::DsSubRtnU32:
|
||||
return LowerDsAtomicU32(decoded, block, Opcode::AtomicSubU32, true, error);
|
||||
case Decoder::Opcode::DsMinI32:
|
||||
return LowerDsAtomicU32(decoded, block, Opcode::AtomicSMinI32, false, error);
|
||||
case Decoder::Opcode::DsMinRtnI32:
|
||||
return LowerDsAtomicU32(decoded, block, Opcode::AtomicSMinI32, true, error);
|
||||
case Decoder::Opcode::DsMaxI32:
|
||||
return LowerDsAtomicU32(decoded, block, Opcode::AtomicSMaxI32, false, error);
|
||||
case Decoder::Opcode::DsMaxRtnI32:
|
||||
return LowerDsAtomicU32(decoded, block, Opcode::AtomicSMaxI32, true, error);
|
||||
case Decoder::Opcode::DsMinU32:
|
||||
return LowerDsAtomicU32(decoded, block, Opcode::AtomicUMinU32, false, error);
|
||||
case Decoder::Opcode::DsMinRtnU32:
|
||||
return LowerDsAtomicU32(decoded, block, Opcode::AtomicUMinU32, true, error);
|
||||
case Decoder::Opcode::DsMaxU32:
|
||||
return LowerDsAtomicU32(decoded, block, Opcode::AtomicUMaxU32, false, error);
|
||||
case Decoder::Opcode::DsMaxRtnU32:
|
||||
return LowerDsAtomicU32(decoded, block, Opcode::AtomicUMaxU32, true, error);
|
||||
case Decoder::Opcode::DsAndB32:
|
||||
return LowerDsAtomicU32(decoded, block, Opcode::AtomicAndU32, false, error);
|
||||
case Decoder::Opcode::DsAndRtnB32:
|
||||
return LowerDsAtomicU32(decoded, block, Opcode::AtomicAndU32, true, error);
|
||||
case Decoder::Opcode::DsOrB32:
|
||||
return LowerDsAtomicU32(decoded, block, Opcode::AtomicOrU32, false, error);
|
||||
case Decoder::Opcode::DsOrRtnB32:
|
||||
return LowerDsAtomicU32(decoded, block, Opcode::AtomicOrU32, true, error);
|
||||
case Decoder::Opcode::DsXorB32:
|
||||
return LowerDsAtomicU32(decoded, block, Opcode::AtomicXorU32, false, error);
|
||||
case Decoder::Opcode::DsXorRtnB32:
|
||||
return LowerDsAtomicU32(decoded, block, Opcode::AtomicXorU32, true, error);
|
||||
case Decoder::Opcode::DsWrxchgRtnB32:
|
||||
return LowerDsAtomicU32(decoded, block, Opcode::AtomicSwapU32, true, error);
|
||||
case Decoder::Opcode::DsMinF32:
|
||||
return LowerDsFloatMinMaxF32(decoded, block, Opcode::DsMinF32, error);
|
||||
case Decoder::Opcode::DsMaxF32:
|
||||
return LowerDsFloatMinMaxF32(decoded, block, Opcode::DsMaxF32, error);
|
||||
case Decoder::Opcode::DsSwizzleB32: return LowerDsSwizzleB32(decoded, block, error);
|
||||
case Decoder::Opcode::DsConsume:
|
||||
return LowerDsAppendConsume(decoded, block, Opcode::DsConsume, error);
|
||||
case Decoder::Opcode::DsAppend:
|
||||
return LowerDsAppendConsume(decoded, block, Opcode::DsAppend, error);
|
||||
case Decoder::Opcode::DsWriteAddtidB32: return LowerDsWriteAddtidB32(decoded, block, error);
|
||||
case Decoder::Opcode::DsReadAddtidB32: return LowerDsReadAddtidB32(decoded, block, error);
|
||||
case Decoder::Opcode::DsRead2B32: return LowerDsRead2(decoded, block, 1, error);
|
||||
case Decoder::Opcode::DsRead2B64:
|
||||
case Decoder::Opcode::DsRead2St64B64: return LowerDsRead2(decoded, block, 2, error);
|
||||
case Decoder::Opcode::DsReadSbyte:
|
||||
case Decoder::Opcode::DsReadUbyte:
|
||||
case Decoder::Opcode::DsReadSshort:
|
||||
case Decoder::Opcode::DsReadUshort:
|
||||
case Decoder::Opcode::DsReadB32:
|
||||
case Decoder::Opcode::DsReadB64:
|
||||
case Decoder::Opcode::DsReadB96:
|
||||
case Decoder::Opcode::DsReadB128: return LowerDsRead(decoded, block, error);
|
||||
case Decoder::Opcode::DsWrite2B32:
|
||||
case Decoder::Opcode::DsWrite2St64B32: return LowerDsWrite2(decoded, block, 1, error);
|
||||
case Decoder::Opcode::DsWrite2B64:
|
||||
case Decoder::Opcode::DsWrite2St64B64: return LowerDsWrite2(decoded, block, 2, error);
|
||||
case Decoder::Opcode::DsWriteByte:
|
||||
case Decoder::Opcode::DsWriteShort:
|
||||
case Decoder::Opcode::DsWriteB32:
|
||||
case Decoder::Opcode::DsWriteB64:
|
||||
case Decoder::Opcode::DsWriteB96:
|
||||
case Decoder::Opcode::DsWriteB128: return LowerDsWrite(decoded, block, error);
|
||||
case Decoder::Opcode::ImageGetResinfo:
|
||||
case Decoder::Opcode::ImageGetLod:
|
||||
case Decoder::Opcode::ImageLoad:
|
||||
case Decoder::Opcode::ImageLoadMip:
|
||||
case Decoder::Opcode::ImageStore:
|
||||
case Decoder::Opcode::ImageStoreMip:
|
||||
case Decoder::Opcode::ImageGather4Lz:
|
||||
case Decoder::Opcode::ImageGather4C:
|
||||
case Decoder::Opcode::ImageGather4CLz:
|
||||
case Decoder::Opcode::ImageGather4LzO:
|
||||
case Decoder::Opcode::ImageGather4CO:
|
||||
case Decoder::Opcode::ImageGather4CLzO:
|
||||
case Decoder::Opcode::ImageGather4H:
|
||||
case Decoder::Opcode::ImageSample: return LowerImageOperation(decoded, block, error);
|
||||
case Decoder::Opcode::ImageAtomicAdd:
|
||||
case Decoder::Opcode::ImageAtomicUMin:
|
||||
case Decoder::Opcode::ImageAtomicUMax:
|
||||
case Decoder::Opcode::ImageAtomicAnd:
|
||||
case Decoder::Opcode::ImageAtomicOr:
|
||||
case Decoder::Opcode::ImageAtomicXor: return LowerImageAtomicU32(decoded, block, error);
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool IsMemoryOpcode(Decoder::Opcode opcode) {
|
||||
switch (opcode) {
|
||||
case Decoder::Opcode::SLoadDword:
|
||||
case Decoder::Opcode::SLoadDwordx2:
|
||||
case Decoder::Opcode::SLoadDwordx4:
|
||||
case Decoder::Opcode::SLoadDwordx8:
|
||||
case Decoder::Opcode::SLoadDwordx16:
|
||||
case Decoder::Opcode::SBufferLoadDword:
|
||||
case Decoder::Opcode::SBufferLoadDwordx2:
|
||||
case Decoder::Opcode::SBufferLoadDwordx4:
|
||||
case Decoder::Opcode::SBufferLoadDwordx8:
|
||||
case Decoder::Opcode::SBufferLoadDwordx16:
|
||||
case Decoder::Opcode::BufferLoadUbyte:
|
||||
case Decoder::Opcode::BufferLoadSbyte:
|
||||
case Decoder::Opcode::BufferLoadUshort:
|
||||
case Decoder::Opcode::BufferLoadSshort:
|
||||
case Decoder::Opcode::BufferLoadDword:
|
||||
case Decoder::Opcode::BufferLoadDwordx2:
|
||||
case Decoder::Opcode::BufferLoadDwordx3:
|
||||
case Decoder::Opcode::BufferLoadDwordx4:
|
||||
case Decoder::Opcode::BufferLoadFormatX:
|
||||
case Decoder::Opcode::BufferLoadFormatXy:
|
||||
case Decoder::Opcode::BufferLoadFormatXyz:
|
||||
case Decoder::Opcode::BufferLoadFormatXyzw:
|
||||
case Decoder::Opcode::TBufferLoadFormatX:
|
||||
case Decoder::Opcode::TBufferLoadFormatXy:
|
||||
case Decoder::Opcode::TBufferLoadFormatXyz:
|
||||
case Decoder::Opcode::TBufferLoadFormatXyzw:
|
||||
case Decoder::Opcode::BufferStoreDword:
|
||||
case Decoder::Opcode::BufferStoreDwordx2:
|
||||
case Decoder::Opcode::BufferStoreDwordx3:
|
||||
case Decoder::Opcode::BufferStoreDwordx4:
|
||||
case Decoder::Opcode::BufferStoreByte:
|
||||
case Decoder::Opcode::BufferStoreShort:
|
||||
case Decoder::Opcode::BufferStoreFormatX:
|
||||
case Decoder::Opcode::BufferStoreFormatXy:
|
||||
case Decoder::Opcode::BufferStoreFormatXyz:
|
||||
case Decoder::Opcode::BufferStoreFormatXyzw:
|
||||
case Decoder::Opcode::TBufferStoreFormatX:
|
||||
case Decoder::Opcode::TBufferStoreFormatXy:
|
||||
case Decoder::Opcode::TBufferStoreFormatXyz:
|
||||
case Decoder::Opcode::TBufferStoreFormatXyzw:
|
||||
case Decoder::Opcode::BufferAtomicSwap:
|
||||
case Decoder::Opcode::BufferAtomicAdd:
|
||||
case Decoder::Opcode::BufferAtomicSub:
|
||||
case Decoder::Opcode::BufferAtomicSMin:
|
||||
case Decoder::Opcode::BufferAtomicUMin:
|
||||
case Decoder::Opcode::BufferAtomicSMax:
|
||||
case Decoder::Opcode::BufferAtomicUMax:
|
||||
case Decoder::Opcode::BufferAtomicAnd:
|
||||
case Decoder::Opcode::BufferAtomicOr:
|
||||
case Decoder::Opcode::BufferAtomicXor:
|
||||
case Decoder::Opcode::FlatLoadUbyte:
|
||||
case Decoder::Opcode::FlatLoadSbyte:
|
||||
case Decoder::Opcode::FlatLoadUshort:
|
||||
case Decoder::Opcode::FlatLoadSshort:
|
||||
case Decoder::Opcode::FlatLoadDword:
|
||||
case Decoder::Opcode::FlatLoadDwordx2:
|
||||
case Decoder::Opcode::FlatLoadDwordx3:
|
||||
case Decoder::Opcode::FlatLoadDwordx4:
|
||||
case Decoder::Opcode::FlatStoreByte:
|
||||
case Decoder::Opcode::FlatStoreShort:
|
||||
case Decoder::Opcode::FlatStoreDword:
|
||||
case Decoder::Opcode::FlatStoreDwordx2:
|
||||
case Decoder::Opcode::FlatStoreDwordx3:
|
||||
case Decoder::Opcode::FlatStoreDwordx4:
|
||||
case Decoder::Opcode::DsAddU32:
|
||||
case Decoder::Opcode::DsAddRtnU32:
|
||||
case Decoder::Opcode::DsSubU32:
|
||||
case Decoder::Opcode::DsSubRtnU32:
|
||||
case Decoder::Opcode::DsMinI32:
|
||||
case Decoder::Opcode::DsMinRtnI32:
|
||||
case Decoder::Opcode::DsMaxI32:
|
||||
case Decoder::Opcode::DsMaxRtnI32:
|
||||
case Decoder::Opcode::DsMinU32:
|
||||
case Decoder::Opcode::DsMinRtnU32:
|
||||
case Decoder::Opcode::DsMaxU32:
|
||||
case Decoder::Opcode::DsMaxRtnU32:
|
||||
case Decoder::Opcode::DsAndB32:
|
||||
case Decoder::Opcode::DsAndRtnB32:
|
||||
case Decoder::Opcode::DsOrB32:
|
||||
case Decoder::Opcode::DsOrRtnB32:
|
||||
case Decoder::Opcode::DsXorB32:
|
||||
case Decoder::Opcode::DsXorRtnB32:
|
||||
case Decoder::Opcode::DsWrxchgRtnB32:
|
||||
case Decoder::Opcode::DsMinF32:
|
||||
case Decoder::Opcode::DsMaxF32:
|
||||
case Decoder::Opcode::DsSwizzleB32:
|
||||
case Decoder::Opcode::DsConsume:
|
||||
case Decoder::Opcode::DsAppend:
|
||||
case Decoder::Opcode::DsReadSbyte:
|
||||
case Decoder::Opcode::DsReadUbyte:
|
||||
case Decoder::Opcode::DsReadSshort:
|
||||
case Decoder::Opcode::DsReadUshort:
|
||||
case Decoder::Opcode::DsRead2B32:
|
||||
case Decoder::Opcode::DsReadB32:
|
||||
case Decoder::Opcode::DsReadB64:
|
||||
case Decoder::Opcode::DsRead2B64:
|
||||
case Decoder::Opcode::DsRead2St64B64:
|
||||
case Decoder::Opcode::DsReadB96:
|
||||
case Decoder::Opcode::DsReadB128:
|
||||
case Decoder::Opcode::DsWriteByte:
|
||||
case Decoder::Opcode::DsWriteShort:
|
||||
case Decoder::Opcode::DsWrite2B32:
|
||||
case Decoder::Opcode::DsWrite2St64B32:
|
||||
case Decoder::Opcode::DsWrite2B64:
|
||||
case Decoder::Opcode::DsWrite2St64B64:
|
||||
case Decoder::Opcode::DsWriteB32:
|
||||
case Decoder::Opcode::DsWriteB64:
|
||||
case Decoder::Opcode::DsWriteB96:
|
||||
case Decoder::Opcode::DsWriteB128:
|
||||
case Decoder::Opcode::DsWriteAddtidB32:
|
||||
case Decoder::Opcode::DsReadAddtidB32:
|
||||
case Decoder::Opcode::ImageGetResinfo:
|
||||
case Decoder::Opcode::ImageGetLod:
|
||||
case Decoder::Opcode::ImageLoad:
|
||||
case Decoder::Opcode::ImageLoadMip:
|
||||
case Decoder::Opcode::ImageStore:
|
||||
case Decoder::Opcode::ImageStoreMip:
|
||||
case Decoder::Opcode::ImageAtomicAdd:
|
||||
case Decoder::Opcode::ImageAtomicUMin:
|
||||
case Decoder::Opcode::ImageAtomicUMax:
|
||||
case Decoder::Opcode::ImageAtomicAnd:
|
||||
case Decoder::Opcode::ImageAtomicOr:
|
||||
case Decoder::Opcode::ImageAtomicXor:
|
||||
case Decoder::Opcode::ImageGather4Lz:
|
||||
case Decoder::Opcode::ImageGather4C:
|
||||
case Decoder::Opcode::ImageGather4CLz:
|
||||
case Decoder::Opcode::ImageGather4LzO:
|
||||
case Decoder::Opcode::ImageGather4CO:
|
||||
case Decoder::Opcode::ImageGather4CLzO:
|
||||
case Decoder::Opcode::ImageGather4H:
|
||||
case Decoder::Opcode::ImageSample: return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Libs::Graphics::ShaderRecompiler::IR
|
||||
@@ -0,0 +1,534 @@
|
||||
#include "graphics/shader/recompiler/ShaderIR.h"
|
||||
|
||||
#include "graphics/shader/recompiler/shaderIR/ShaderIRInternal.h"
|
||||
#include "common/assert.h"
|
||||
#include "graphics/shader/recompiler/BufferFormat.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::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::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::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::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;
|
||||
}
|
||||
}
|
||||
|
||||
Opcode LookupIrOpcode(Decoder::Opcode opcode) {
|
||||
for (const auto& op: LOWER_OPS) {
|
||||
if (op.decoded == opcode) {
|
||||
return op.ir;
|
||||
}
|
||||
}
|
||||
return Opcode::MoveU32;
|
||||
}
|
||||
|
||||
bool IsImplemented(Decoder::Opcode opcode) {
|
||||
for (const auto& op: LOWER_OPS) {
|
||||
if (op.decoded == opcode) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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
|
||||
Reference in new issue
Block a user