Merge pull request #39 from Pacuka/fix/recompiler-64bit-constants

fix(recompiler): widen constants of 64-bit operands instead of repeating them
TranslationContext::readU32Pair builds a 64-bit source from two 32-bit reads, taking the high half from offsetOperand(operand, 1). For registers that is the next register. For a literal or an inline constant, offsetOperand returns the same operand, so the constant ended up in both halves: the literal L was read as L:L instead of 0:L.
This commit is contained in:
boykopovar 2026-09-28 08:22:01 +03:00 committed by GitHub
commit f65ca6806c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 11 additions and 1 deletions

View File

@ -1,5 +1,7 @@
#include "Translation/TranslationContext.hpp"
#include <array>
#include <bit>
#include <cstdint>
namespace ShaderRecompiler {
@ -8,7 +10,15 @@ IrU32 TranslationContext::readU32(const RdnaOperand& operand) {
}
std::array<IrU32, 2> TranslationContext::readU32Pair(const RdnaOperand& operand) {
return {readU32(operand), readU32(offsetOperand(operand, 1u))};
switch (operand.kind) {
case RdnaOperandKind::LiteralConstant: return {readU32(operand), IrU32(ir.Constant(0u))};
case RdnaOperandKind::IntegerInlineConstant: return {readU32(operand), IrU32(ir.Constant(operand.signedVal < 0 ? 0xffffffffu : 0u))};
case RdnaOperandKind::FloatInlineConstant: {
const auto bits = std::bit_cast<std::uint64_t>(static_cast<double>(std::bit_cast<float>(operand.value)));
return {IrU32(ir.Constant(static_cast<std::uint32_t>(bits))), IrU32(ir.Constant(static_cast<std::uint32_t>(bits >> 32u)))};
}
default: return {readU32(operand), readU32(offsetOperand(operand, 1u))};
}
}
IrU64 TranslationContext::readU64(const RdnaOperand& operand) {