diff --git a/core/shader/recompiler/RdnaDecoder/include/RdnaDecoder/RdnaOpcode.hpp b/core/shader/recompiler/RdnaDecoder/include/RdnaDecoder/RdnaOpcode.hpp index 70329c435..07e05c84d 100644 --- a/core/shader/recompiler/RdnaDecoder/include/RdnaDecoder/RdnaOpcode.hpp +++ b/core/shader/recompiler/RdnaDecoder/include/RdnaDecoder/RdnaOpcode.hpp @@ -153,6 +153,8 @@ enum class RdnaOpcode : std::uint16_t { SSubbU32, SBitcmp0B32, SBitcmp1B32, + SBitcmp0B64, + SBitcmp1B64, SBitset0B32, SBitset1B32, SBitset0B64, diff --git a/core/shader/recompiler/RdnaDecoder/src/RdnaOpcode.cpp b/core/shader/recompiler/RdnaDecoder/src/RdnaOpcode.cpp index 0dc1b8f0a..8d5c3e7e2 100644 --- a/core/shader/recompiler/RdnaDecoder/src/RdnaOpcode.cpp +++ b/core/shader/recompiler/RdnaDecoder/src/RdnaOpcode.cpp @@ -72,6 +72,8 @@ bool IsScalarAluOpcode(RdnaOpcode opcode) { case RdnaOpcode::SSubbU32: case RdnaOpcode::SBitcmp0B32: case RdnaOpcode::SBitcmp1B32: + case RdnaOpcode::SBitcmp0B64: + case RdnaOpcode::SBitcmp1B64: case RdnaOpcode::SBitset0B32: case RdnaOpcode::SBitset1B32: case RdnaOpcode::SBitset0B64: diff --git a/core/shader/recompiler/RdnaDecoder/src/RdnaScalarOpDecoder.cpp b/core/shader/recompiler/RdnaDecoder/src/RdnaScalarOpDecoder.cpp index 3bff0baac..156c2ba43 100644 --- a/core/shader/recompiler/RdnaDecoder/src/RdnaScalarOpDecoder.cpp +++ b/core/shader/recompiler/RdnaDecoder/src/RdnaScalarOpDecoder.cpp @@ -123,6 +123,8 @@ RdnaOpcode decodeSopcOpcode(std::uint32_t opcode) { case 0x0bu: return RdnaOpcode::SCmpLeU32; case 0x0cu: return RdnaOpcode::SBitcmp0B32; case 0x0du: return RdnaOpcode::SBitcmp1B32; + case 0x0eu: return RdnaOpcode::SBitcmp0B64; + case 0x0fu: return RdnaOpcode::SBitcmp1B64; case 0x12u: return RdnaOpcode::SCmpEqU64; case 0x13u: return RdnaOpcode::SCmpLgU64; default: throw std::invalid_argument("unsupported SOPC opcode " + std::to_string(opcode)); diff --git a/core/shader/recompiler/Translation/include/Translation/TranslationContext.hpp b/core/shader/recompiler/Translation/include/Translation/TranslationContext.hpp index eb9c775ac..60c123a62 100644 --- a/core/shader/recompiler/Translation/include/Translation/TranslationContext.hpp +++ b/core/shader/recompiler/Translation/include/Translation/TranslationContext.hpp @@ -183,6 +183,7 @@ private: bool vBfeU32(const RdnaInstruction& inst, bool sign); bool vBfiB32(const RdnaInstruction& inst); bool sBitcmpB32(const RdnaInstruction& inst, bool expected); + bool sBitcmpB64(const RdnaInstruction& inst, bool expected); bool vAlignbitB32(const RdnaInstruction& inst); bool vAlignbyteB32(const RdnaInstruction& inst); bool vLshlAddU32(const RdnaInstruction& inst); diff --git a/core/shader/recompiler/Translation/src/IntegerInstructions.cpp b/core/shader/recompiler/Translation/src/IntegerInstructions.cpp index 310dae951..3bda0cbaf 100644 --- a/core/shader/recompiler/Translation/src/IntegerInstructions.cpp +++ b/core/shader/recompiler/Translation/src/IntegerInstructions.cpp @@ -484,6 +484,15 @@ bool TranslationContext::sBitcmpB32(const RdnaInstruction& inst, bool expected) return true; } +bool TranslationContext::sBitcmpB64(const RdnaInstruction& inst, bool expected) { + const IrU64 value = readU64(sourceAt(inst, 0u)); + const IrU32 offset(ir.BitwiseAnd(readU32(sourceAt(inst, 1u)).Value(), ir.Constant(63u))); + const IrU64 shifted(ir.Emit(IrOpcode::ShiftRightLogical64, IrType::U64, {&value.Value(), &offset.Value()})); + const IrU64 bit(ir.Emit(IrOpcode::BitwiseAnd64, IrType::U64, {&shifted.Value(), &ir.ConstantU64(1u)})); + writeCompareResult(inst.destination, IrU1(ir.Emit(IrOpcode::IEqual64, IrType::U1, {&bit.Value(), &ir.ConstantU64(expected ? 1u : 0u)}))); + return true; +} + bool TranslationContext::vAlignbitB32(const RdnaInstruction& inst) { const IrU32 hi = readU32(sourceAt(inst, 0u)); const IrU32 lo = readU32(sourceAt(inst, 1u)); diff --git a/core/shader/recompiler/Translation/src/ScalarInstructions.cpp b/core/shader/recompiler/Translation/src/ScalarInstructions.cpp index 1d9e9380e..9c583375e 100644 --- a/core/shader/recompiler/Translation/src/ScalarInstructions.cpp +++ b/core/shader/recompiler/Translation/src/ScalarInstructions.cpp @@ -290,6 +290,10 @@ bool TranslationContext::emitScalar(const RdnaInstruction& inst) { return sBitcmpB32(inst, false); case RdnaOpcode::SBitcmp1B32: return sBitcmpB32(inst, true); + case RdnaOpcode::SBitcmp0B64: + return sBitcmpB64(inst, false); + case RdnaOpcode::SBitcmp1B64: + return sBitcmpB64(inst, true); case RdnaOpcode::SPackLlB32B16: return packB16(inst, false, false); case RdnaOpcode::SPackLhB32B16: