diff --git a/src/graphics/shader/recompiler/frontend/translate/Translate.cpp b/src/graphics/shader/recompiler/frontend/translate/Translate.cpp index 03a7f629c..8bbfb7e9f 100644 --- a/src/graphics/shader/recompiler/frontend/translate/Translate.cpp +++ b/src/graphics/shader/recompiler/frontend/translate/Translate.cpp @@ -233,13 +233,6 @@ IR::Value Translator::ReadOperand(const Decoder::Operand& operand, IR::Type type if (type == IR::Type::F64) { if (operand.kind == Decoder::OperandKind::LiteralConstant) { pair = {IR::U32(IR::Value(0u)), IR::U32(IR::Value(operand.value))}; - } else if (operand.kind == Decoder::OperandKind::FloatInlineConstant) { - const auto bits = operand.value == 0x3e22f983u - ? 0x3fc45f306dc9c882ull - : std::bit_cast(static_cast( - std::bit_cast(operand.value))); - pair = {IR::U32(IR::Value(static_cast(bits))), - IR::U32(IR::Value(static_cast(bits >> 32u)))}; } if (operand.absolute) { pair[1] = ir.BitwiseAnd(pair[1], IR::U32(IR::Value(0x7fffffffu))); @@ -488,6 +481,14 @@ std::array Translator::ReadU32Pair(const Decoder::Operand& operand) if (operand.kind == Decoder::OperandKind::VccLo) { return {ir.GetVccLo(), ir.GetVccHi()}; } + if (operand.kind == Decoder::OperandKind::FloatInlineConstant) { + const auto bits = + operand.value == 0x3e22f983u + ? 0x3fc45f306dc9c882ull + : std::bit_cast(static_cast(std::bit_cast(operand.value))); + return {IR::U32(IR::Value(static_cast(bits))), + IR::U32(IR::Value(static_cast(bits >> 32u)))}; + } const auto low = ApplyBitSourceModifiers(operand, ReadRawU32(operand)); IR::U32 high(IR::Value(0u)); if (operand.kind == Decoder::OperandKind::Sgpr || operand.kind == Decoder::OperandKind::Vgpr) { diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index 429175e6e..03a4d874f 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -25192,6 +25192,34 @@ TestCase VectorCarryAndBitCountOps() { O::S_ENDPGM}}; } +TestCase ScalarVector64BitFloatInlineConstants() { + using O = ShaderOpcode; + std::vector code; + code.push_back(EncodeSop1(0x04, 40, 242)); + code.push_back(EncodeSop2(0x11, 42, 240, InlineU32(0))); + code.push_back(EncodeSop1(0x04, 44, 248)); + AppendVop3(&code, 0x300, 2, InlineU32(32), 244); + code.push_back(EncodeSMovB32(46, InlineU32(0))); + AppendSMovLiteral(&code, 47, 0x3ff00000u); + code.push_back(EncodeSopc(0x12, 46, 242)); + code.push_back(EncodeSMovB32(48, 253)); + AppendStoreSgprPair(&code, 40, 0); + AppendStoreSgprPair(&code, 42, 2); + AppendStoreVgpr(&code, 2, 4); + AppendStoreVgpr(&code, 3, 5); + AppendStoreSgprPair(&code, 44, 6); + AppendStoreSgpr(&code, 48, 8); + AppendEnd(&code); + + TestCase test; + test.name = "ScalarVector64BitFloatInlineConstants"; + test.code = std::move(code); + test.expected = {0u, 0x3ff00000u, 0u, 0x3fe00000u, 0x40000000u, 0u, 0x6dc9c882u, 0x3fc45f30u, 1u}; + test.opcodes = {O::S_MOV_B64, O::S_OR_B64, O::V_LSHRREV_B64, O::S_MOV_B32, O::S_CMP_EQ_U64, + O::V_MOV_B32, O::BUFFER_STORE_DWORD, O::S_ENDPGM}; + return test; +} + TestCase VectorMbcntUsesThreadMask() { using O = ShaderOpcode; @@ -42017,6 +42045,7 @@ std::vector MakeCases() { AddCase(VectorBfeI32SignExtendsField); AddCase(VectorAlignByteUsesTwoBitByteOffset); AddCase(VectorCarryAndBitCountOps); + AddCase(ScalarVector64BitFloatInlineConstants); AddCase(VectorMbcntUsesThreadMask); AddCase(VectorAddcWritesPerLaneCarryOut); AddCase(VectorAddcUsesPerLaneCarryIn);