summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorPokechu22 <Pokechu022@gmail.com>2021-08-15 18:18:43 -0700
committerPokechu22 <Pokechu022@gmail.com>2021-08-16 15:09:20 -0700
commit3b4bc9852fa19a66188ce2015ba8b1ab008dd9b3 (patch)
tree9cafa444a700ec139350e482f8309f159037f11a /Source
parent858d0675b9d940fbd2062c31aabac34dadd853e8 (diff)
DSPInterpreter: Fix sign extension of accumulators
The extension needs to happen in SetLongAcc, not GetLongAcc, as the extension needs to always be reflected in acS.h. There is no functional difference with the write handler for acS.h, but it is more readable than 4 casts in a row.
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/DSP/Interpreter/DSPInterpreter.cpp9
1 files changed, 5 insertions, 4 deletions
diff --git a/Source/Core/Core/DSP/Interpreter/DSPInterpreter.cpp b/Source/Core/Core/DSP/Interpreter/DSPInterpreter.cpp
index 3d1e7216ce..1fd3aa3ff3 100644
--- a/Source/Core/Core/DSP/Interpreter/DSPInterpreter.cpp
+++ b/Source/Core/Core/DSP/Interpreter/DSPInterpreter.cpp
@@ -394,13 +394,14 @@ s16 Interpreter::GetAXHigh(s32 reg) const
s64 Interpreter::GetLongAcc(s32 reg) const
{
const auto& state = m_dsp_core.DSPState();
- return static_cast<s64>(state.r.ac[reg].val << 24) >> 24;
+ return static_cast<s64>(state.r.ac[reg].val);
}
void Interpreter::SetLongAcc(s32 reg, s64 value)
{
auto& state = m_dsp_core.DSPState();
- state.r.ac[reg].val = static_cast<u64>(value);
+ // 40-bit sign extension
+ state.r.ac[reg].val = static_cast<u64>((value << (64 - 40)) >> (64 - 40));
}
s16 Interpreter::GetAccLow(s32 reg) const
@@ -690,8 +691,8 @@ void Interpreter::OpWriteRegister(int reg_, u16 val)
// 8-bit sign extended registers.
case DSP_REG_ACH0:
case DSP_REG_ACH1:
- // sign extend from the bottom 8 bits.
- state.r.ac[reg - DSP_REG_ACH0].h = (u16)(s16)(s8)(u8)val;
+ // Sign extend from the bottom 8 bits.
+ state.r.ac[reg - DSP_REG_ACH0].h = static_cast<s8>(val);
break;
// Stack registers.