diff --git a/Source/Core/Core/DSP/Interpreter/DSPIntExtOps.cpp b/Source/Core/Core/DSP/Interpreter/DSPIntExtOps.cpp index c271c28f33..a2e1af2b9f 100644 --- a/Source/Core/Core/DSP/Interpreter/DSPIntExtOps.cpp +++ b/Source/Core/Core/DSP/Interpreter/DSPIntExtOps.cpp @@ -55,19 +55,8 @@ void Interpreter::mv(const UDSPInstruction opc) { const u8 sreg = (opc & 0x3) + DSP_REG_ACL0; const u8 dreg = ((opc >> 2) & 0x3); - auto& state = m_dsp_core.DSPState(); - switch (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; - } + WriteToBackLog(0, dreg + DSP_REG_AXL0, OpReadRegister(sreg)); } // S @$arD, $acS.S @@ -80,17 +69,7 @@ void Interpreter::s(const UDSPInstruction opc) const u8 sreg = ((opc >> 3) & 0x3) + DSP_REG_ACL0; auto& state = m_dsp_core.DSPState(); - switch (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; - } + state.WriteDMEM(state.r.ar[dreg], OpReadRegister(sreg)); WriteToBackLog(0, dreg, IncrementAddressRegister(dreg)); } @@ -104,17 +83,7 @@ void Interpreter::sn(const UDSPInstruction opc) const u8 sreg = ((opc >> 3) & 0x3) + DSP_REG_ACL0; auto& state = m_dsp_core.DSPState(); - switch (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; - } + state.WriteDMEM(state.r.ar[dreg], OpReadRegister(sreg)); WriteToBackLog(0, dreg, IncreaseAddressRegister(dreg, static_cast(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 // Load register $axD.D with value from memory pointed by register // $ar0. Store value from register $acS.m to memory location pointed by // register $ar3. Increment both $ar0 and $ar3. 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; 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(1, DSP_REG_AR3, IncrementAddressRegister(DSP_REG_AR3)); @@ -194,11 +163,11 @@ void Interpreter::ls(const UDSPInstruction opc) // register $ar0 and increment $ar3. 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; 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(1, DSP_REG_AR3, IncrementAddressRegister(DSP_REG_AR3)); @@ -214,11 +183,11 @@ void Interpreter::lsn(const UDSPInstruction opc) // register $ar3 and increment $ar0. 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; 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(1, DSP_REG_AR3, @@ -235,11 +204,11 @@ void Interpreter::lsm(const UDSPInstruction opc) // register $ar3. 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; 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(1, DSP_REG_AR3, @@ -255,11 +224,11 @@ void Interpreter::lsnm(const UDSPInstruction opc) // $ar3. Increment both $ar0 and $ar3. 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; 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(1, DSP_REG_AR3, IncrementAddressRegister(DSP_REG_AR3)); @@ -274,11 +243,11 @@ void Interpreter::sl(const UDSPInstruction opc) // and increment $ar3. 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; 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(1, DSP_REG_AR3, IncrementAddressRegister(DSP_REG_AR3)); @@ -294,11 +263,11 @@ void Interpreter::sln(const UDSPInstruction opc) // and increment $ar0. 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; 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(1, DSP_REG_AR3, @@ -314,11 +283,11 @@ void Interpreter::slm(const UDSPInstruction opc) // and add corresponding indexing register $ix3 to addressing register $ar3. 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; 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(1, DSP_REG_AR3, diff --git a/Source/Core/Core/DSP/Interpreter/DSPIntLoadStore.cpp b/Source/Core/Core/DSP/Interpreter/DSPIntLoadStore.cpp index 17973a9a1e..89bfa92b1d 100644 --- a/Source/Core/Core/DSP/Interpreter/DSPIntLoadStore.cpp +++ b/Source/Core/Core/DSP/Interpreter/DSPIntLoadStore.cpp @@ -34,10 +34,7 @@ void Interpreter::srs(const UDSPInstruction opc) const auto reg = static_cast(((opc >> 8) & 0x3) + DSP_REG_ACL0); const auto addr = static_cast((state.r.cr << 8) | (opc & 0xFF)); - if (reg >= DSP_REG_ACM0) - state.WriteDMEM(addr, OpReadRegisterAndSaturate(reg - DSP_REG_ACM0)); - else - state.WriteDMEM(addr, OpReadRegister(reg)); + state.WriteDMEM(addr, OpReadRegister(reg)); } // LRS $(0x18+D), @M @@ -80,10 +77,7 @@ void Interpreter::sr(const UDSPInstruction opc) const u8 reg = opc & 0x1F; const u16 addr = state.FetchInstruction(); - if (reg >= DSP_REG_ACM0) - state.WriteDMEM(addr, OpReadRegisterAndSaturate(reg - DSP_REG_ACM0)); - else - state.WriteDMEM(addr, OpReadRegister(reg)); + state.WriteDMEM(addr, OpReadRegister(reg)); } // SI @M, #I @@ -172,10 +166,7 @@ void Interpreter::srr(const UDSPInstruction opc) const u8 sreg = opc & 0x1f; auto& state = m_dsp_core.DSPState(); - if (sreg >= DSP_REG_ACM0) - state.WriteDMEM(state.r.ar[dreg], OpReadRegisterAndSaturate(sreg - DSP_REG_ACM0)); - else - state.WriteDMEM(state.r.ar[dreg], OpReadRegister(sreg)); + state.WriteDMEM(state.r.ar[dreg], OpReadRegister(sreg)); } // SRRD @$arD, $S @@ -188,10 +179,7 @@ void Interpreter::srrd(const UDSPInstruction opc) const u8 sreg = opc & 0x1f; auto& state = m_dsp_core.DSPState(); - if (sreg >= DSP_REG_ACM0) - state.WriteDMEM(state.r.ar[dreg], OpReadRegisterAndSaturate(sreg - DSP_REG_ACM0)); - else - state.WriteDMEM(state.r.ar[dreg], OpReadRegister(sreg)); + state.WriteDMEM(state.r.ar[dreg], OpReadRegister(sreg)); state.r.ar[dreg] = DecrementAddressRegister(dreg); } @@ -206,10 +194,7 @@ void Interpreter::srri(const UDSPInstruction opc) const u8 sreg = opc & 0x1f; auto& state = m_dsp_core.DSPState(); - if (sreg >= DSP_REG_ACM0) - state.WriteDMEM(state.r.ar[dreg], OpReadRegisterAndSaturate(sreg - DSP_REG_ACM0)); - else - state.WriteDMEM(state.r.ar[dreg], OpReadRegister(sreg)); + state.WriteDMEM(state.r.ar[dreg], OpReadRegister(sreg)); state.r.ar[dreg] = IncrementAddressRegister(dreg); } @@ -224,10 +209,7 @@ void Interpreter::srrn(const UDSPInstruction opc) const u8 sreg = opc & 0x1f; auto& state = m_dsp_core.DSPState(); - if (sreg >= DSP_REG_ACM0) - state.WriteDMEM(state.r.ar[dreg], OpReadRegisterAndSaturate(sreg - DSP_REG_ACM0)); - else - state.WriteDMEM(state.r.ar[dreg], OpReadRegister(sreg)); + state.WriteDMEM(state.r.ar[dreg], OpReadRegister(sreg)); state.r.ar[dreg] = IncreaseAddressRegister(dreg, static_cast(state.r.ix[dreg])); } diff --git a/Source/Core/Core/DSP/Interpreter/DSPIntMisc.cpp b/Source/Core/Core/DSP/Interpreter/DSPIntMisc.cpp index 7b1971adf4..4c3af7ec85 100644 --- a/Source/Core/Core/DSP/Interpreter/DSPIntMisc.cpp +++ b/Source/Core/Core/DSP/Interpreter/DSPIntMisc.cpp @@ -19,10 +19,7 @@ void Interpreter::mrr(const UDSPInstruction opc) const u8 sreg = opc & 0x1f; const u8 dreg = (opc >> 5) & 0x1f; - if (sreg >= DSP_REG_ACM0) - OpWriteRegister(dreg, OpReadRegisterAndSaturate(sreg - DSP_REG_ACM0)); - else - OpWriteRegister(dreg, OpReadRegister(sreg)); + OpWriteRegister(dreg, OpReadRegister(sreg)); ConditionalExtendAccum(dreg); } diff --git a/Source/Core/Core/DSP/Interpreter/DSPInterpreter.cpp b/Source/Core/Core/DSP/Interpreter/DSPInterpreter.cpp index c4cc0e5601..a2332320c8 100644 --- a/Source/Core/Core/DSP/Interpreter/DSPInterpreter.cpp +++ b/Source/Core/Core/DSP/Interpreter/DSPInterpreter.cpp @@ -700,33 +700,31 @@ u16 Interpreter::OpReadRegister(int reg_) return state.r.ac[reg - DSP_REG_ACL0].l; case DSP_REG_ACM0: 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(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; + } default: ASSERT_MSG(DSPLLE, 0, "cannot happen"); return 0; } } -u16 Interpreter::OpReadRegisterAndSaturate(int reg) const -{ - if (IsSRFlagSet(SR_40_MODE_BIT)) - { - const s64 acc = GetLongAcc(reg); - - if (acc != static_cast(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) { const int reg = reg_ & 0x1f; diff --git a/Source/Core/Core/DSP/Interpreter/DSPInterpreter.h b/Source/Core/Core/DSP/Interpreter/DSPInterpreter.h index e7cd266680..c6be4516b7 100644 --- a/Source/Core/Core/DSP/Interpreter/DSPInterpreter.h +++ b/Source/Core/Core/DSP/Interpreter/DSPInterpreter.h @@ -230,7 +230,6 @@ private: void UpdateSRLogicZero(bool value); u16 OpReadRegister(int reg_); - u16 OpReadRegisterAndSaturate(int reg) const; void OpWriteRegister(int reg_, u16 val); void ConditionalExtendAccum(int reg); diff --git a/Source/Core/Core/DSP/Jit/x64/DSPEmitter.h b/Source/Core/Core/DSP/Jit/x64/DSPEmitter.h index 21fab446e1..77f5eccb62 100644 --- a/Source/Core/Core/DSP/Jit/x64/DSPEmitter.h +++ b/Source/Core/Core/DSP/Jit/x64/DSPEmitter.h @@ -286,8 +286,6 @@ private: void dsp_op_write_reg_imm(int reg, u16 val); void dsp_conditional_extend_accum(int reg); 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, RegisterExtension extend = RegisterExtension::None); diff --git a/Source/Core/Core/DSP/Jit/x64/DSPJitBranch.cpp b/Source/Core/Core/DSP/Jit/x64/DSPJitBranch.cpp index 12e70e4663..79e2da9a91 100644 --- a/Source/Core/Core/DSP/Jit/x64/DSPJitBranch.cpp +++ b/Source/Core/Core/DSP/Jit/x64/DSPJitBranch.cpp @@ -358,8 +358,7 @@ void DSPEmitter::loop(const UDSPInstruction opc) { u16 reg = opc & 0x1f; // u16 cnt = g_dsp.r[reg]; - // todo: check if we can use normal variant here - dsp_op_read_reg_dont_saturate(reg, RDX, RegisterExtension::Zero); + dsp_op_read_reg(reg, RDX, RegisterExtension::Zero); u16 loop_pc = m_compile_pc + 1; TEST(16, R(EDX), R(EDX)); @@ -429,8 +428,7 @@ void DSPEmitter::bloop(const UDSPInstruction opc) { const u16 reg = opc & 0x1f; // u16 cnt = g_dsp.r[reg]; - // todo: check if we can use normal variant here - dsp_op_read_reg_dont_saturate(reg, RDX, RegisterExtension::Zero); + dsp_op_read_reg(reg, RDX, RegisterExtension::Zero); const u16 loop_pc = m_dsp_core.DSPState().ReadIMEM(m_compile_pc + 1); TEST(16, R(EDX), R(EDX)); diff --git a/Source/Core/Core/DSP/Jit/x64/DSPJitUtil.cpp b/Source/Core/Core/DSP/Jit/x64/DSPJitUtil.cpp index 67c66e06c3..bdddff746d 100644 --- a/Source/Core/Core/DSP/Jit/x64/DSPJitUtil.cpp +++ b/Source/Core/Core/DSP/Jit/x64/DSPJitUtil.cpp @@ -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(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) { switch (reg & 0x1f)