mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-26 15:55:31 +01:00
Merge pull request #10716 from Pokechu22/dsp-lle-loop-saturation
DSP LLE: Apply saturation to LOOP and BLOOP with $ac0.m and $ac1.m
This commit is contained in:
commit
d7cda67462
@ -55,19 +55,8 @@ void Interpreter::mv(const UDSPInstruction opc)
|
|||||||
{
|
{
|
||||||
const u8 sreg = (opc & 0x3) + DSP_REG_ACL0;
|
const u8 sreg = (opc & 0x3) + DSP_REG_ACL0;
|
||||||
const u8 dreg = ((opc >> 2) & 0x3);
|
const u8 dreg = ((opc >> 2) & 0x3);
|
||||||
auto& state = m_dsp_core.DSPState();
|
|
||||||
|
|
||||||
switch (sreg)
|
WriteToBackLog(0, dreg + DSP_REG_AXL0, OpReadRegister(sreg));
|
||||||
{
|
|
||||||
case DSP_REG_ACL0:
|
|
||||||
case DSP_REG_ACL1:
|
|
||||||
WriteToBackLog(0, dreg + DSP_REG_AXL0, state.r.ac[sreg - DSP_REG_ACL0].l);
|
|
||||||
break;
|
|
||||||
case DSP_REG_ACM0:
|
|
||||||
case DSP_REG_ACM1:
|
|
||||||
WriteToBackLog(0, dreg + DSP_REG_AXL0, OpReadRegisterAndSaturate(sreg - DSP_REG_ACM0));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// S @$arD, $acS.S
|
// S @$arD, $acS.S
|
||||||
@ -80,17 +69,7 @@ void Interpreter::s(const UDSPInstruction opc)
|
|||||||
const u8 sreg = ((opc >> 3) & 0x3) + DSP_REG_ACL0;
|
const u8 sreg = ((opc >> 3) & 0x3) + DSP_REG_ACL0;
|
||||||
auto& state = m_dsp_core.DSPState();
|
auto& state = m_dsp_core.DSPState();
|
||||||
|
|
||||||
switch (sreg)
|
state.WriteDMEM(state.r.ar[dreg], OpReadRegister(sreg));
|
||||||
{
|
|
||||||
case DSP_REG_ACL0:
|
|
||||||
case DSP_REG_ACL1:
|
|
||||||
state.WriteDMEM(state.r.ar[dreg], state.r.ac[sreg - DSP_REG_ACL0].l);
|
|
||||||
break;
|
|
||||||
case DSP_REG_ACM0:
|
|
||||||
case DSP_REG_ACM1:
|
|
||||||
state.WriteDMEM(state.r.ar[dreg], OpReadRegisterAndSaturate(sreg - DSP_REG_ACM0));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
WriteToBackLog(0, dreg, IncrementAddressRegister(dreg));
|
WriteToBackLog(0, dreg, IncrementAddressRegister(dreg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,17 +83,7 @@ void Interpreter::sn(const UDSPInstruction opc)
|
|||||||
const u8 sreg = ((opc >> 3) & 0x3) + DSP_REG_ACL0;
|
const u8 sreg = ((opc >> 3) & 0x3) + DSP_REG_ACL0;
|
||||||
auto& state = m_dsp_core.DSPState();
|
auto& state = m_dsp_core.DSPState();
|
||||||
|
|
||||||
switch (sreg)
|
state.WriteDMEM(state.r.ar[dreg], OpReadRegister(sreg));
|
||||||
{
|
|
||||||
case DSP_REG_ACL0:
|
|
||||||
case DSP_REG_ACL1:
|
|
||||||
state.WriteDMEM(state.r.ar[dreg], state.r.ac[sreg - DSP_REG_ACL0].l);
|
|
||||||
break;
|
|
||||||
case DSP_REG_ACM0:
|
|
||||||
case DSP_REG_ACM1:
|
|
||||||
state.WriteDMEM(state.r.ar[dreg], OpReadRegisterAndSaturate(sreg - DSP_REG_ACM0));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
WriteToBackLog(0, dreg, IncreaseAddressRegister(dreg, static_cast<s16>(state.r.ix[dreg])));
|
WriteToBackLog(0, dreg, IncreaseAddressRegister(dreg, static_cast<s16>(state.r.ix[dreg])));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,18 +137,18 @@ void Interpreter::ln(const UDSPInstruction opc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// LS $axD.D, $acS.m108
|
// LS $axD.D, $acS.m
|
||||||
// xxxx xxxx 10dd 000s
|
// xxxx xxxx 10dd 000s
|
||||||
// Load register $axD.D with value from memory pointed by register
|
// Load register $axD.D with value from memory pointed by register
|
||||||
// $ar0. Store value from register $acS.m to memory location pointed by
|
// $ar0. Store value from register $acS.m to memory location pointed by
|
||||||
// register $ar3. Increment both $ar0 and $ar3.
|
// register $ar3. Increment both $ar0 and $ar3.
|
||||||
void Interpreter::ls(const UDSPInstruction opc)
|
void Interpreter::ls(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
const u8 sreg = opc & 0x1;
|
const u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
||||||
const u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
const u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
auto& state = m_dsp_core.DSPState();
|
auto& state = m_dsp_core.DSPState();
|
||||||
|
|
||||||
state.WriteDMEM(state.r.ar[3], OpReadRegisterAndSaturate(sreg));
|
state.WriteDMEM(state.r.ar[3], OpReadRegister(sreg));
|
||||||
|
|
||||||
WriteToBackLog(0, dreg, state.ReadDMEM(state.r.ar[0]));
|
WriteToBackLog(0, dreg, state.ReadDMEM(state.r.ar[0]));
|
||||||
WriteToBackLog(1, DSP_REG_AR3, IncrementAddressRegister(DSP_REG_AR3));
|
WriteToBackLog(1, DSP_REG_AR3, IncrementAddressRegister(DSP_REG_AR3));
|
||||||
@ -194,11 +163,11 @@ void Interpreter::ls(const UDSPInstruction opc)
|
|||||||
// register $ar0 and increment $ar3.
|
// register $ar0 and increment $ar3.
|
||||||
void Interpreter::lsn(const UDSPInstruction opc)
|
void Interpreter::lsn(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
const u8 sreg = opc & 0x1;
|
const u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
||||||
const u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
const u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
auto& state = m_dsp_core.DSPState();
|
auto& state = m_dsp_core.DSPState();
|
||||||
|
|
||||||
state.WriteDMEM(state.r.ar[3], OpReadRegisterAndSaturate(sreg));
|
state.WriteDMEM(state.r.ar[3], OpReadRegister(sreg));
|
||||||
|
|
||||||
WriteToBackLog(0, dreg, state.ReadDMEM(state.r.ar[0]));
|
WriteToBackLog(0, dreg, state.ReadDMEM(state.r.ar[0]));
|
||||||
WriteToBackLog(1, DSP_REG_AR3, IncrementAddressRegister(DSP_REG_AR3));
|
WriteToBackLog(1, DSP_REG_AR3, IncrementAddressRegister(DSP_REG_AR3));
|
||||||
@ -214,11 +183,11 @@ void Interpreter::lsn(const UDSPInstruction opc)
|
|||||||
// register $ar3 and increment $ar0.
|
// register $ar3 and increment $ar0.
|
||||||
void Interpreter::lsm(const UDSPInstruction opc)
|
void Interpreter::lsm(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
const u8 sreg = opc & 0x1;
|
const u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
||||||
const u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
const u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
auto& state = m_dsp_core.DSPState();
|
auto& state = m_dsp_core.DSPState();
|
||||||
|
|
||||||
state.WriteDMEM(state.r.ar[3], OpReadRegisterAndSaturate(sreg));
|
state.WriteDMEM(state.r.ar[3], OpReadRegister(sreg));
|
||||||
|
|
||||||
WriteToBackLog(0, dreg, state.ReadDMEM(state.r.ar[0]));
|
WriteToBackLog(0, dreg, state.ReadDMEM(state.r.ar[0]));
|
||||||
WriteToBackLog(1, DSP_REG_AR3,
|
WriteToBackLog(1, DSP_REG_AR3,
|
||||||
@ -235,11 +204,11 @@ void Interpreter::lsm(const UDSPInstruction opc)
|
|||||||
// register $ar3.
|
// register $ar3.
|
||||||
void Interpreter::lsnm(const UDSPInstruction opc)
|
void Interpreter::lsnm(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
const u8 sreg = opc & 0x1;
|
const u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
||||||
const u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
const u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
auto& state = m_dsp_core.DSPState();
|
auto& state = m_dsp_core.DSPState();
|
||||||
|
|
||||||
state.WriteDMEM(state.r.ar[3], OpReadRegisterAndSaturate(sreg));
|
state.WriteDMEM(state.r.ar[3], OpReadRegister(sreg));
|
||||||
|
|
||||||
WriteToBackLog(0, dreg, state.ReadDMEM(state.r.ar[0]));
|
WriteToBackLog(0, dreg, state.ReadDMEM(state.r.ar[0]));
|
||||||
WriteToBackLog(1, DSP_REG_AR3,
|
WriteToBackLog(1, DSP_REG_AR3,
|
||||||
@ -255,11 +224,11 @@ void Interpreter::lsnm(const UDSPInstruction opc)
|
|||||||
// $ar3. Increment both $ar0 and $ar3.
|
// $ar3. Increment both $ar0 and $ar3.
|
||||||
void Interpreter::sl(const UDSPInstruction opc)
|
void Interpreter::sl(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
const u8 sreg = opc & 0x1;
|
const u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
||||||
const u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
const u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
auto& state = m_dsp_core.DSPState();
|
auto& state = m_dsp_core.DSPState();
|
||||||
|
|
||||||
state.WriteDMEM(state.r.ar[0], OpReadRegisterAndSaturate(sreg));
|
state.WriteDMEM(state.r.ar[0], OpReadRegister(sreg));
|
||||||
|
|
||||||
WriteToBackLog(0, dreg, state.ReadDMEM(state.r.ar[3]));
|
WriteToBackLog(0, dreg, state.ReadDMEM(state.r.ar[3]));
|
||||||
WriteToBackLog(1, DSP_REG_AR3, IncrementAddressRegister(DSP_REG_AR3));
|
WriteToBackLog(1, DSP_REG_AR3, IncrementAddressRegister(DSP_REG_AR3));
|
||||||
@ -274,11 +243,11 @@ void Interpreter::sl(const UDSPInstruction opc)
|
|||||||
// and increment $ar3.
|
// and increment $ar3.
|
||||||
void Interpreter::sln(const UDSPInstruction opc)
|
void Interpreter::sln(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
const u8 sreg = opc & 0x1;
|
const u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
||||||
const u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
const u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
auto& state = m_dsp_core.DSPState();
|
auto& state = m_dsp_core.DSPState();
|
||||||
|
|
||||||
state.WriteDMEM(state.r.ar[0], OpReadRegisterAndSaturate(sreg));
|
state.WriteDMEM(state.r.ar[0], OpReadRegister(sreg));
|
||||||
|
|
||||||
WriteToBackLog(0, dreg, state.ReadDMEM(state.r.ar[3]));
|
WriteToBackLog(0, dreg, state.ReadDMEM(state.r.ar[3]));
|
||||||
WriteToBackLog(1, DSP_REG_AR3, IncrementAddressRegister(DSP_REG_AR3));
|
WriteToBackLog(1, DSP_REG_AR3, IncrementAddressRegister(DSP_REG_AR3));
|
||||||
@ -294,11 +263,11 @@ void Interpreter::sln(const UDSPInstruction opc)
|
|||||||
// and increment $ar0.
|
// and increment $ar0.
|
||||||
void Interpreter::slm(const UDSPInstruction opc)
|
void Interpreter::slm(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
const u8 sreg = opc & 0x1;
|
const u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
||||||
const u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
const u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
auto& state = m_dsp_core.DSPState();
|
auto& state = m_dsp_core.DSPState();
|
||||||
|
|
||||||
state.WriteDMEM(state.r.ar[0], OpReadRegisterAndSaturate(sreg));
|
state.WriteDMEM(state.r.ar[0], OpReadRegister(sreg));
|
||||||
|
|
||||||
WriteToBackLog(0, dreg, state.ReadDMEM(state.r.ar[3]));
|
WriteToBackLog(0, dreg, state.ReadDMEM(state.r.ar[3]));
|
||||||
WriteToBackLog(1, DSP_REG_AR3,
|
WriteToBackLog(1, DSP_REG_AR3,
|
||||||
@ -314,11 +283,11 @@ void Interpreter::slm(const UDSPInstruction opc)
|
|||||||
// and add corresponding indexing register $ix3 to addressing register $ar3.
|
// and add corresponding indexing register $ix3 to addressing register $ar3.
|
||||||
void Interpreter::slnm(const UDSPInstruction opc)
|
void Interpreter::slnm(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
const u8 sreg = opc & 0x1;
|
const u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
||||||
const u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
const u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
auto& state = m_dsp_core.DSPState();
|
auto& state = m_dsp_core.DSPState();
|
||||||
|
|
||||||
state.WriteDMEM(state.r.ar[0], OpReadRegisterAndSaturate(sreg));
|
state.WriteDMEM(state.r.ar[0], OpReadRegister(sreg));
|
||||||
|
|
||||||
WriteToBackLog(0, dreg, state.ReadDMEM(state.r.ar[3]));
|
WriteToBackLog(0, dreg, state.ReadDMEM(state.r.ar[3]));
|
||||||
WriteToBackLog(1, DSP_REG_AR3,
|
WriteToBackLog(1, DSP_REG_AR3,
|
||||||
|
@ -34,10 +34,7 @@ void Interpreter::srs(const UDSPInstruction opc)
|
|||||||
const auto reg = static_cast<u8>(((opc >> 8) & 0x3) + DSP_REG_ACL0);
|
const auto reg = static_cast<u8>(((opc >> 8) & 0x3) + DSP_REG_ACL0);
|
||||||
const auto addr = static_cast<u16>((state.r.cr << 8) | (opc & 0xFF));
|
const auto addr = static_cast<u16>((state.r.cr << 8) | (opc & 0xFF));
|
||||||
|
|
||||||
if (reg >= DSP_REG_ACM0)
|
state.WriteDMEM(addr, OpReadRegister(reg));
|
||||||
state.WriteDMEM(addr, OpReadRegisterAndSaturate(reg - DSP_REG_ACM0));
|
|
||||||
else
|
|
||||||
state.WriteDMEM(addr, OpReadRegister(reg));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LRS $(0x18+D), @M
|
// LRS $(0x18+D), @M
|
||||||
@ -80,10 +77,7 @@ void Interpreter::sr(const UDSPInstruction opc)
|
|||||||
const u8 reg = opc & 0x1F;
|
const u8 reg = opc & 0x1F;
|
||||||
const u16 addr = state.FetchInstruction();
|
const u16 addr = state.FetchInstruction();
|
||||||
|
|
||||||
if (reg >= DSP_REG_ACM0)
|
state.WriteDMEM(addr, OpReadRegister(reg));
|
||||||
state.WriteDMEM(addr, OpReadRegisterAndSaturate(reg - DSP_REG_ACM0));
|
|
||||||
else
|
|
||||||
state.WriteDMEM(addr, OpReadRegister(reg));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SI @M, #I
|
// SI @M, #I
|
||||||
@ -172,10 +166,7 @@ void Interpreter::srr(const UDSPInstruction opc)
|
|||||||
const u8 sreg = opc & 0x1f;
|
const u8 sreg = opc & 0x1f;
|
||||||
auto& state = m_dsp_core.DSPState();
|
auto& state = m_dsp_core.DSPState();
|
||||||
|
|
||||||
if (sreg >= DSP_REG_ACM0)
|
state.WriteDMEM(state.r.ar[dreg], OpReadRegister(sreg));
|
||||||
state.WriteDMEM(state.r.ar[dreg], OpReadRegisterAndSaturate(sreg - DSP_REG_ACM0));
|
|
||||||
else
|
|
||||||
state.WriteDMEM(state.r.ar[dreg], OpReadRegister(sreg));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SRRD @$arD, $S
|
// SRRD @$arD, $S
|
||||||
@ -188,10 +179,7 @@ void Interpreter::srrd(const UDSPInstruction opc)
|
|||||||
const u8 sreg = opc & 0x1f;
|
const u8 sreg = opc & 0x1f;
|
||||||
auto& state = m_dsp_core.DSPState();
|
auto& state = m_dsp_core.DSPState();
|
||||||
|
|
||||||
if (sreg >= DSP_REG_ACM0)
|
state.WriteDMEM(state.r.ar[dreg], OpReadRegister(sreg));
|
||||||
state.WriteDMEM(state.r.ar[dreg], OpReadRegisterAndSaturate(sreg - DSP_REG_ACM0));
|
|
||||||
else
|
|
||||||
state.WriteDMEM(state.r.ar[dreg], OpReadRegister(sreg));
|
|
||||||
|
|
||||||
state.r.ar[dreg] = DecrementAddressRegister(dreg);
|
state.r.ar[dreg] = DecrementAddressRegister(dreg);
|
||||||
}
|
}
|
||||||
@ -206,10 +194,7 @@ void Interpreter::srri(const UDSPInstruction opc)
|
|||||||
const u8 sreg = opc & 0x1f;
|
const u8 sreg = opc & 0x1f;
|
||||||
auto& state = m_dsp_core.DSPState();
|
auto& state = m_dsp_core.DSPState();
|
||||||
|
|
||||||
if (sreg >= DSP_REG_ACM0)
|
state.WriteDMEM(state.r.ar[dreg], OpReadRegister(sreg));
|
||||||
state.WriteDMEM(state.r.ar[dreg], OpReadRegisterAndSaturate(sreg - DSP_REG_ACM0));
|
|
||||||
else
|
|
||||||
state.WriteDMEM(state.r.ar[dreg], OpReadRegister(sreg));
|
|
||||||
|
|
||||||
state.r.ar[dreg] = IncrementAddressRegister(dreg);
|
state.r.ar[dreg] = IncrementAddressRegister(dreg);
|
||||||
}
|
}
|
||||||
@ -224,10 +209,7 @@ void Interpreter::srrn(const UDSPInstruction opc)
|
|||||||
const u8 sreg = opc & 0x1f;
|
const u8 sreg = opc & 0x1f;
|
||||||
auto& state = m_dsp_core.DSPState();
|
auto& state = m_dsp_core.DSPState();
|
||||||
|
|
||||||
if (sreg >= DSP_REG_ACM0)
|
state.WriteDMEM(state.r.ar[dreg], OpReadRegister(sreg));
|
||||||
state.WriteDMEM(state.r.ar[dreg], OpReadRegisterAndSaturate(sreg - DSP_REG_ACM0));
|
|
||||||
else
|
|
||||||
state.WriteDMEM(state.r.ar[dreg], OpReadRegister(sreg));
|
|
||||||
|
|
||||||
state.r.ar[dreg] = IncreaseAddressRegister(dreg, static_cast<s16>(state.r.ix[dreg]));
|
state.r.ar[dreg] = IncreaseAddressRegister(dreg, static_cast<s16>(state.r.ix[dreg]));
|
||||||
}
|
}
|
||||||
|
@ -19,10 +19,7 @@ void Interpreter::mrr(const UDSPInstruction opc)
|
|||||||
const u8 sreg = opc & 0x1f;
|
const u8 sreg = opc & 0x1f;
|
||||||
const u8 dreg = (opc >> 5) & 0x1f;
|
const u8 dreg = (opc >> 5) & 0x1f;
|
||||||
|
|
||||||
if (sreg >= DSP_REG_ACM0)
|
OpWriteRegister(dreg, OpReadRegister(sreg));
|
||||||
OpWriteRegister(dreg, OpReadRegisterAndSaturate(sreg - DSP_REG_ACM0));
|
|
||||||
else
|
|
||||||
OpWriteRegister(dreg, OpReadRegister(sreg));
|
|
||||||
|
|
||||||
ConditionalExtendAccum(dreg);
|
ConditionalExtendAccum(dreg);
|
||||||
}
|
}
|
||||||
|
@ -700,33 +700,31 @@ u16 Interpreter::OpReadRegister(int reg_)
|
|||||||
return state.r.ac[reg - DSP_REG_ACL0].l;
|
return state.r.ac[reg - DSP_REG_ACL0].l;
|
||||||
case DSP_REG_ACM0:
|
case DSP_REG_ACM0:
|
||||||
case DSP_REG_ACM1:
|
case DSP_REG_ACM1:
|
||||||
|
{
|
||||||
|
// Saturate reads from $ac0.m or $ac1.m if that mode is enabled.
|
||||||
|
if (IsSRFlagSet(SR_40_MODE_BIT))
|
||||||
|
{
|
||||||
|
const s64 acc = GetLongAcc(reg - DSP_REG_ACM0);
|
||||||
|
|
||||||
|
if (acc != static_cast<s32>(acc))
|
||||||
|
{
|
||||||
|
if (acc > 0)
|
||||||
|
return 0x7fff;
|
||||||
|
else
|
||||||
|
return 0x8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
return state.r.ac[reg - DSP_REG_ACM0].m;
|
||||||
|
}
|
||||||
|
|
||||||
return state.r.ac[reg - DSP_REG_ACM0].m;
|
return state.r.ac[reg - DSP_REG_ACM0].m;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
ASSERT_MSG(DSPLLE, 0, "cannot happen");
|
ASSERT_MSG(DSPLLE, 0, "cannot happen");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 Interpreter::OpReadRegisterAndSaturate(int reg) const
|
|
||||||
{
|
|
||||||
if (IsSRFlagSet(SR_40_MODE_BIT))
|
|
||||||
{
|
|
||||||
const s64 acc = GetLongAcc(reg);
|
|
||||||
|
|
||||||
if (acc != static_cast<s32>(acc))
|
|
||||||
{
|
|
||||||
if (acc > 0)
|
|
||||||
return 0x7fff;
|
|
||||||
else
|
|
||||||
return 0x8000;
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_dsp_core.DSPState().r.ac[reg].m;
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_dsp_core.DSPState().r.ac[reg].m;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Interpreter::OpWriteRegister(int reg_, u16 val)
|
void Interpreter::OpWriteRegister(int reg_, u16 val)
|
||||||
{
|
{
|
||||||
const int reg = reg_ & 0x1f;
|
const int reg = reg_ & 0x1f;
|
||||||
|
@ -230,7 +230,6 @@ private:
|
|||||||
void UpdateSRLogicZero(bool value);
|
void UpdateSRLogicZero(bool value);
|
||||||
|
|
||||||
u16 OpReadRegister(int reg_);
|
u16 OpReadRegister(int reg_);
|
||||||
u16 OpReadRegisterAndSaturate(int reg) const;
|
|
||||||
void OpWriteRegister(int reg_, u16 val);
|
void OpWriteRegister(int reg_, u16 val);
|
||||||
|
|
||||||
void ConditionalExtendAccum(int reg);
|
void ConditionalExtendAccum(int reg);
|
||||||
|
@ -286,8 +286,6 @@ private:
|
|||||||
void dsp_op_write_reg_imm(int reg, u16 val);
|
void dsp_op_write_reg_imm(int reg, u16 val);
|
||||||
void dsp_conditional_extend_accum(int reg);
|
void dsp_conditional_extend_accum(int reg);
|
||||||
void dsp_conditional_extend_accum_imm(int reg, u16 val);
|
void dsp_conditional_extend_accum_imm(int reg, u16 val);
|
||||||
void dsp_op_read_reg_dont_saturate(int reg, Gen::X64Reg host_dreg,
|
|
||||||
RegisterExtension extend = RegisterExtension::None);
|
|
||||||
void dsp_op_read_reg(int reg, Gen::X64Reg host_dreg,
|
void dsp_op_read_reg(int reg, Gen::X64Reg host_dreg,
|
||||||
RegisterExtension extend = RegisterExtension::None);
|
RegisterExtension extend = RegisterExtension::None);
|
||||||
|
|
||||||
|
@ -358,8 +358,7 @@ void DSPEmitter::loop(const UDSPInstruction opc)
|
|||||||
{
|
{
|
||||||
u16 reg = opc & 0x1f;
|
u16 reg = opc & 0x1f;
|
||||||
// u16 cnt = g_dsp.r[reg];
|
// u16 cnt = g_dsp.r[reg];
|
||||||
// todo: check if we can use normal variant here
|
dsp_op_read_reg(reg, RDX, RegisterExtension::Zero);
|
||||||
dsp_op_read_reg_dont_saturate(reg, RDX, RegisterExtension::Zero);
|
|
||||||
u16 loop_pc = m_compile_pc + 1;
|
u16 loop_pc = m_compile_pc + 1;
|
||||||
|
|
||||||
TEST(16, R(EDX), R(EDX));
|
TEST(16, R(EDX), R(EDX));
|
||||||
@ -429,8 +428,7 @@ void DSPEmitter::bloop(const UDSPInstruction opc)
|
|||||||
{
|
{
|
||||||
const u16 reg = opc & 0x1f;
|
const u16 reg = opc & 0x1f;
|
||||||
// u16 cnt = g_dsp.r[reg];
|
// u16 cnt = g_dsp.r[reg];
|
||||||
// todo: check if we can use normal variant here
|
dsp_op_read_reg(reg, RDX, RegisterExtension::Zero);
|
||||||
dsp_op_read_reg_dont_saturate(reg, RDX, RegisterExtension::Zero);
|
|
||||||
const u16 loop_pc = m_dsp_core.DSPState().ReadIMEM(m_compile_pc + 1);
|
const u16 loop_pc = m_dsp_core.DSPState().ReadIMEM(m_compile_pc + 1);
|
||||||
|
|
||||||
TEST(16, R(EDX), R(EDX));
|
TEST(16, R(EDX), R(EDX));
|
||||||
|
@ -196,35 +196,6 @@ void DSPEmitter::dsp_conditional_extend_accum_imm(int reg, u16 val)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPEmitter::dsp_op_read_reg_dont_saturate(int reg, Gen::X64Reg host_dreg,
|
|
||||||
RegisterExtension extend)
|
|
||||||
{
|
|
||||||
switch (reg & 0x1f)
|
|
||||||
{
|
|
||||||
case DSP_REG_ST0:
|
|
||||||
case DSP_REG_ST1:
|
|
||||||
case DSP_REG_ST2:
|
|
||||||
case DSP_REG_ST3:
|
|
||||||
dsp_reg_load_stack(static_cast<StackRegister>(reg - DSP_REG_ST0), host_dreg);
|
|
||||||
switch (extend)
|
|
||||||
{
|
|
||||||
case RegisterExtension::Sign:
|
|
||||||
MOVSX(64, 16, host_dreg, R(host_dreg));
|
|
||||||
break;
|
|
||||||
case RegisterExtension::Zero:
|
|
||||||
MOVZX(64, 16, host_dreg, R(host_dreg));
|
|
||||||
break;
|
|
||||||
case RegisterExtension::None:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
m_gpr.ReadReg(reg, host_dreg, extend);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DSPEmitter::dsp_op_read_reg(int reg, Gen::X64Reg host_dreg, RegisterExtension extend)
|
void DSPEmitter::dsp_op_read_reg(int reg, Gen::X64Reg host_dreg, RegisterExtension extend)
|
||||||
{
|
{
|
||||||
switch (reg & 0x1f)
|
switch (reg & 0x1f)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user