mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 22:29:39 -06:00
Core/DSPCore: Extended opcode handling fixes
* Make writeToBackLog private to DSPIntExtOps.cpp (JIT variants of 'l and 'ln are disabled and broken as is) * Make zeroing of the backlog conditional on doing an interpreter fallback and do it at a few more places * Fix selection of cleanup for extended opcodes. * Fix the DSP unit tests to correctly emit the function prolog/epilog (else EBX wouldn't be saved) * Add a few more DSP unit tests git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6325 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -19,8 +19,6 @@
|
||||
#include "x64Emitter.h"
|
||||
#include "ABI.h"
|
||||
|
||||
#include "../DSPIntExtOps.h" // remove when getting rid of writebacklog
|
||||
// See docs in the interpeter
|
||||
using namespace Gen;
|
||||
|
||||
// DR $arR
|
||||
@ -94,6 +92,7 @@ void DSPEmitter::l(const UDSPInstruction opc)
|
||||
|
||||
if ((dreg >= DSP_REG_ACM0) && (g_dsp.r[DSP_REG_SR] & SR_40_MODE_BIT))
|
||||
{
|
||||
/*
|
||||
u16 val;
|
||||
ext_dmem_read(sreg);
|
||||
MOV(16, M(&val), R(EAX));
|
||||
@ -102,6 +101,7 @@ void DSPEmitter::l(const UDSPInstruction opc)
|
||||
writeToBackLog(1, dreg, val);
|
||||
writeToBackLog(2, dreg - DSP_REG_ACM0 + DSP_REG_ACL0, 0);
|
||||
increment_addr_reg(sreg);
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -127,6 +127,7 @@ void DSPEmitter::ln(const UDSPInstruction opc)
|
||||
|
||||
if ((dreg >= DSP_REG_ACM0) && (g_dsp.r[DSP_REG_SR] & SR_40_MODE_BIT))
|
||||
{
|
||||
/*
|
||||
u16 val;
|
||||
ext_dmem_read(sreg);
|
||||
MOV(16, M(&val), R(EAX));
|
||||
@ -134,6 +135,7 @@ void DSPEmitter::ln(const UDSPInstruction opc)
|
||||
writeToBackLog(1, dreg, val);
|
||||
writeToBackLog(2, dreg - DSP_REG_ACM0 + DSP_REG_ACL0, 0);
|
||||
increase_addr_reg(sreg);
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -700,8 +702,8 @@ void DSPEmitter::pushExtValueFromReg(u16 dreg, u16 sreg) {
|
||||
|
||||
void DSPEmitter::pushExtValueFromMem(u16 dreg, u16 sreg) {
|
||||
ext_dmem_read(sreg);
|
||||
MOV(16, R(EBX), R(EAX));
|
||||
|
||||
MOVZX(32, 16, EBX, R(EAX));
|
||||
|
||||
storeIndex = dreg;
|
||||
}
|
||||
|
||||
@ -726,3 +728,26 @@ void DSPEmitter::popExtValueToReg() {
|
||||
// TODO handle commands such as 'l
|
||||
}
|
||||
|
||||
// This function is being called in the main op after all input regs were read
|
||||
// and before it writes into any regs. This way we can always use bitwise or to
|
||||
// apply the ext command output, because if the main op didn't change the value
|
||||
// then 0 | ext output = ext output and if it did then bitwise or is still the
|
||||
// right thing to do
|
||||
//this is only needed as long as we do fallback for ext ops
|
||||
void DSPEmitter::zeroWriteBackLog(const UDSPInstruction opc)
|
||||
{
|
||||
const DSPOPCTemplate *tinst = GetOpTemplate(opc);
|
||||
|
||||
// Call extended
|
||||
if (!tinst->extended)
|
||||
return;
|
||||
|
||||
if ((opc >> 12) == 0x3) {
|
||||
if (! extOpTable[opc & 0x7F]->jitFunc)
|
||||
ABI_CallFunction((void*)::zeroWriteBackLog);
|
||||
} else {
|
||||
if (! extOpTable[opc & 0xFF]->jitFunc)
|
||||
ABI_CallFunction((void*)::zeroWriteBackLog);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -88,6 +88,7 @@ void DSPEmitter::nx(const UDSPInstruction opc)
|
||||
void DSPEmitter::dar(const UDSPInstruction opc)
|
||||
{
|
||||
// g_dsp.r[opc & 0x3] = dsp_decrement_addr_reg(opc & 0x3);
|
||||
zeroWriteBackLog(opc);
|
||||
decrement_addr_reg(opc & 0x3);
|
||||
|
||||
}
|
||||
@ -98,6 +99,7 @@ void DSPEmitter::dar(const UDSPInstruction opc)
|
||||
void DSPEmitter::iar(const UDSPInstruction opc)
|
||||
{
|
||||
// g_dsp.r[opc & 0x3] = dsp_increment_addr_reg(opc & 0x3);
|
||||
zeroWriteBackLog(opc);
|
||||
increment_addr_reg(opc & 0x3);
|
||||
}
|
||||
|
||||
@ -109,6 +111,7 @@ void DSPEmitter::subarn(const UDSPInstruction opc)
|
||||
{
|
||||
// u8 dreg = opc & 0x3;
|
||||
// g_dsp.r[dreg] = dsp_decrease_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]);
|
||||
zeroWriteBackLog(opc);
|
||||
decrease_addr_reg(opc & 0x3);
|
||||
}
|
||||
|
||||
@ -123,6 +126,7 @@ void DSPEmitter::addarn(const UDSPInstruction opc)
|
||||
// g_dsp.r[dreg] = dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]);
|
||||
|
||||
// From looking around it is always called with the matching index register
|
||||
zeroWriteBackLog(opc);
|
||||
increase_addr_reg(opc & 0x3);
|
||||
}
|
||||
|
||||
@ -180,7 +184,7 @@ void DSPEmitter::sbset(const UDSPInstruction opc)
|
||||
// but it's harder to know exactly what effect they have.
|
||||
void DSPEmitter::srbith(const UDSPInstruction opc)
|
||||
{
|
||||
ABI_CallFunction((void *)zeroWriteBackLog);
|
||||
zeroWriteBackLog(opc);
|
||||
switch ((opc >> 8) & 0xf)
|
||||
{
|
||||
// M0/M2 change the multiplier mode (it can multiply by 2 for free).
|
||||
|
Reference in New Issue
Block a user