mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-23 04:16:57 +02:00
shader: read float inline constants on 64-bit operands as f64 bits (#1576)
A float inline constant (240-248) read by a 64-bit operand is the f64 bit
pattern for integer B64 opcodes too: AMD's compilers emit
v_lshrrev_b64 v[4:5], v0, 1.0 for 0x3ff0000000000000 >> lane. ReadU32Pair
returned {f32 bits, 0}, so only F64-typed reads had the right value.
Based on TheCruZ's 284deab28 (closed #1219).
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -233,13 +233,6 @@ IR::Value Translator::ReadOperand(const Decoder::Operand& operand, IR::Type type
|
|||||||
if (type == IR::Type::F64) {
|
if (type == IR::Type::F64) {
|
||||||
if (operand.kind == Decoder::OperandKind::LiteralConstant) {
|
if (operand.kind == Decoder::OperandKind::LiteralConstant) {
|
||||||
pair = {IR::U32(IR::Value(0u)), IR::U32(IR::Value(operand.value))};
|
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<uint64_t>(static_cast<double>(
|
|
||||||
std::bit_cast<float>(operand.value)));
|
|
||||||
pair = {IR::U32(IR::Value(static_cast<uint32_t>(bits))),
|
|
||||||
IR::U32(IR::Value(static_cast<uint32_t>(bits >> 32u)))};
|
|
||||||
}
|
}
|
||||||
if (operand.absolute) {
|
if (operand.absolute) {
|
||||||
pair[1] = ir.BitwiseAnd(pair[1], IR::U32(IR::Value(0x7fffffffu)));
|
pair[1] = ir.BitwiseAnd(pair[1], IR::U32(IR::Value(0x7fffffffu)));
|
||||||
@@ -488,6 +481,14 @@ std::array<IR::U32, 2> Translator::ReadU32Pair(const Decoder::Operand& operand)
|
|||||||
if (operand.kind == Decoder::OperandKind::VccLo) {
|
if (operand.kind == Decoder::OperandKind::VccLo) {
|
||||||
return {ir.GetVccLo(), ir.GetVccHi()};
|
return {ir.GetVccLo(), ir.GetVccHi()};
|
||||||
}
|
}
|
||||||
|
if (operand.kind == Decoder::OperandKind::FloatInlineConstant) {
|
||||||
|
const auto bits =
|
||||||
|
operand.value == 0x3e22f983u
|
||||||
|
? 0x3fc45f306dc9c882ull
|
||||||
|
: std::bit_cast<uint64_t>(static_cast<double>(std::bit_cast<float>(operand.value)));
|
||||||
|
return {IR::U32(IR::Value(static_cast<uint32_t>(bits))),
|
||||||
|
IR::U32(IR::Value(static_cast<uint32_t>(bits >> 32u)))};
|
||||||
|
}
|
||||||
const auto low = ApplyBitSourceModifiers(operand, ReadRawU32(operand));
|
const auto low = ApplyBitSourceModifiers(operand, ReadRawU32(operand));
|
||||||
IR::U32 high(IR::Value(0u));
|
IR::U32 high(IR::Value(0u));
|
||||||
if (operand.kind == Decoder::OperandKind::Sgpr || operand.kind == Decoder::OperandKind::Vgpr) {
|
if (operand.kind == Decoder::OperandKind::Sgpr || operand.kind == Decoder::OperandKind::Vgpr) {
|
||||||
|
|||||||
@@ -25192,6 +25192,34 @@ TestCase VectorCarryAndBitCountOps() {
|
|||||||
O::S_ENDPGM}};
|
O::S_ENDPGM}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestCase ScalarVector64BitFloatInlineConstants() {
|
||||||
|
using O = ShaderOpcode;
|
||||||
|
std::vector<u32> 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() {
|
TestCase VectorMbcntUsesThreadMask() {
|
||||||
using O = ShaderOpcode;
|
using O = ShaderOpcode;
|
||||||
|
|
||||||
@@ -42017,6 +42045,7 @@ std::vector<TestCase> MakeCases() {
|
|||||||
AddCase(VectorBfeI32SignExtendsField);
|
AddCase(VectorBfeI32SignExtendsField);
|
||||||
AddCase(VectorAlignByteUsesTwoBitByteOffset);
|
AddCase(VectorAlignByteUsesTwoBitByteOffset);
|
||||||
AddCase(VectorCarryAndBitCountOps);
|
AddCase(VectorCarryAndBitCountOps);
|
||||||
|
AddCase(ScalarVector64BitFloatInlineConstants);
|
||||||
AddCase(VectorMbcntUsesThreadMask);
|
AddCase(VectorMbcntUsesThreadMask);
|
||||||
AddCase(VectorAddcWritesPerLaneCarryOut);
|
AddCase(VectorAddcWritesPerLaneCarryOut);
|
||||||
AddCase(VectorAddcUsesPerLaneCarryIn);
|
AddCase(VectorAddcUsesPerLaneCarryIn);
|
||||||
|
|||||||
Reference in New Issue
Block a user