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:
parent
2f2a76b28a
commit
4b9831cdce
|
@ -93,6 +93,7 @@ void DSPEmitter::checkExceptions(u32 retval) {
|
||||||
void DSPEmitter::EmitInstruction(UDSPInstruction inst)
|
void DSPEmitter::EmitInstruction(UDSPInstruction inst)
|
||||||
{
|
{
|
||||||
const DSPOPCTemplate *tinst = GetOpTemplate(inst);
|
const DSPOPCTemplate *tinst = GetOpTemplate(inst);
|
||||||
|
bool ext_is_jit = false;
|
||||||
|
|
||||||
// Call extended
|
// Call extended
|
||||||
if (tinst->extended) {
|
if (tinst->extended) {
|
||||||
|
@ -100,15 +101,19 @@ void DSPEmitter::EmitInstruction(UDSPInstruction inst)
|
||||||
if (! extOpTable[inst & 0x7F]->jitFunc) {
|
if (! extOpTable[inst & 0x7F]->jitFunc) {
|
||||||
// Fall back to interpreter
|
// Fall back to interpreter
|
||||||
ABI_CallFunctionC16((void*)extOpTable[inst & 0x7F]->intFunc, inst);
|
ABI_CallFunctionC16((void*)extOpTable[inst & 0x7F]->intFunc, inst);
|
||||||
|
ext_is_jit = false;
|
||||||
} else {
|
} else {
|
||||||
(this->*extOpTable[inst & 0x7F]->jitFunc)(inst);
|
(this->*extOpTable[inst & 0x7F]->jitFunc)(inst);
|
||||||
|
ext_is_jit = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!extOpTable[inst & 0xFF]->jitFunc) {
|
if (!extOpTable[inst & 0xFF]->jitFunc) {
|
||||||
// Fall back to interpreter
|
// Fall back to interpreter
|
||||||
ABI_CallFunctionC16((void*)extOpTable[inst & 0xFF]->intFunc, inst);
|
ABI_CallFunctionC16((void*)extOpTable[inst & 0xFF]->intFunc, inst);
|
||||||
|
ext_is_jit = false;
|
||||||
} else {
|
} else {
|
||||||
(this->*extOpTable[inst & 0xFF]->jitFunc)(inst);
|
(this->*extOpTable[inst & 0xFF]->jitFunc)(inst);
|
||||||
|
ext_is_jit = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,8 +130,10 @@ void DSPEmitter::EmitInstruction(UDSPInstruction inst)
|
||||||
|
|
||||||
// Backlog
|
// Backlog
|
||||||
if (tinst->extended) {
|
if (tinst->extended) {
|
||||||
if (! extOpTable[inst & 0x7F]->jitFunc) {
|
if (!ext_is_jit) {
|
||||||
ABI_CallFunction((void*)applyWriteBackLog);
|
//need to call the online cleanup function because
|
||||||
|
//the writeBackLog gets populated at runtime
|
||||||
|
ABI_CallFunction((void*)::applyWriteBackLog);
|
||||||
} else {
|
} else {
|
||||||
popExtValueToReg();
|
popExtValueToReg();
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,7 @@ public:
|
||||||
void popExtValueToReg();
|
void popExtValueToReg();
|
||||||
void pushExtValueFromMem(u16 dreg, u16 sreg);
|
void pushExtValueFromMem(u16 dreg, u16 sreg);
|
||||||
|
|
||||||
|
void zeroWriteBackLog(const UDSPInstruction opc);
|
||||||
// Ext commands
|
// Ext commands
|
||||||
void l(const UDSPInstruction opc);
|
void l(const UDSPInstruction opc);
|
||||||
void ln(const UDSPInstruction opc);
|
void ln(const UDSPInstruction opc);
|
||||||
|
|
|
@ -28,6 +28,13 @@
|
||||||
// registers will wrap in odd ways, dictated by the corresponding wrapping
|
// registers will wrap in odd ways, dictated by the corresponding wrapping
|
||||||
// register, WR0-3.
|
// register, WR0-3.
|
||||||
|
|
||||||
|
// Needs comments.
|
||||||
|
inline static void writeToBackLog(int i, int idx, u16 value)
|
||||||
|
{
|
||||||
|
writeBackLog[i] = value;
|
||||||
|
writeBackLogIdx[i] = idx;
|
||||||
|
}
|
||||||
|
|
||||||
namespace DSPInterpreter
|
namespace DSPInterpreter
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -61,11 +61,4 @@ void nop(const UDSPInstruction opc);
|
||||||
} // end namespace Ext
|
} // end namespace Ext
|
||||||
} // end namespace DSPinterpeter
|
} // end namespace DSPinterpeter
|
||||||
|
|
||||||
// Needs comments.
|
|
||||||
inline void writeToBackLog(int i, int idx, u16 value)
|
|
||||||
{
|
|
||||||
writeBackLog[i] = value;
|
|
||||||
writeBackLogIdx[i] = idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
#include "x64Emitter.h"
|
#include "x64Emitter.h"
|
||||||
#include "ABI.h"
|
#include "ABI.h"
|
||||||
|
|
||||||
#include "../DSPIntExtOps.h" // remove when getting rid of writebacklog
|
|
||||||
// See docs in the interpeter
|
|
||||||
using namespace Gen;
|
using namespace Gen;
|
||||||
|
|
||||||
// DR $arR
|
// 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))
|
if ((dreg >= DSP_REG_ACM0) && (g_dsp.r[DSP_REG_SR] & SR_40_MODE_BIT))
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
u16 val;
|
u16 val;
|
||||||
ext_dmem_read(sreg);
|
ext_dmem_read(sreg);
|
||||||
MOV(16, M(&val), R(EAX));
|
MOV(16, M(&val), R(EAX));
|
||||||
|
@ -102,6 +101,7 @@ void DSPEmitter::l(const UDSPInstruction opc)
|
||||||
writeToBackLog(1, dreg, val);
|
writeToBackLog(1, dreg, val);
|
||||||
writeToBackLog(2, dreg - DSP_REG_ACM0 + DSP_REG_ACL0, 0);
|
writeToBackLog(2, dreg - DSP_REG_ACM0 + DSP_REG_ACL0, 0);
|
||||||
increment_addr_reg(sreg);
|
increment_addr_reg(sreg);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
else
|
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))
|
if ((dreg >= DSP_REG_ACM0) && (g_dsp.r[DSP_REG_SR] & SR_40_MODE_BIT))
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
u16 val;
|
u16 val;
|
||||||
ext_dmem_read(sreg);
|
ext_dmem_read(sreg);
|
||||||
MOV(16, M(&val), R(EAX));
|
MOV(16, M(&val), R(EAX));
|
||||||
|
@ -134,6 +135,7 @@ void DSPEmitter::ln(const UDSPInstruction opc)
|
||||||
writeToBackLog(1, dreg, val);
|
writeToBackLog(1, dreg, val);
|
||||||
writeToBackLog(2, dreg - DSP_REG_ACM0 + DSP_REG_ACL0, 0);
|
writeToBackLog(2, dreg - DSP_REG_ACM0 + DSP_REG_ACL0, 0);
|
||||||
increase_addr_reg(sreg);
|
increase_addr_reg(sreg);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -700,7 +702,7 @@ void DSPEmitter::pushExtValueFromReg(u16 dreg, u16 sreg) {
|
||||||
|
|
||||||
void DSPEmitter::pushExtValueFromMem(u16 dreg, u16 sreg) {
|
void DSPEmitter::pushExtValueFromMem(u16 dreg, u16 sreg) {
|
||||||
ext_dmem_read(sreg);
|
ext_dmem_read(sreg);
|
||||||
MOV(16, R(EBX), R(EAX));
|
MOVZX(32, 16, EBX, R(EAX));
|
||||||
|
|
||||||
storeIndex = dreg;
|
storeIndex = dreg;
|
||||||
}
|
}
|
||||||
|
@ -726,3 +728,26 @@ void DSPEmitter::popExtValueToReg() {
|
||||||
// TODO handle commands such as 'l
|
// 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)
|
void DSPEmitter::dar(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
// g_dsp.r[opc & 0x3] = dsp_decrement_addr_reg(opc & 0x3);
|
// g_dsp.r[opc & 0x3] = dsp_decrement_addr_reg(opc & 0x3);
|
||||||
|
zeroWriteBackLog(opc);
|
||||||
decrement_addr_reg(opc & 0x3);
|
decrement_addr_reg(opc & 0x3);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -98,6 +99,7 @@ void DSPEmitter::dar(const UDSPInstruction opc)
|
||||||
void DSPEmitter::iar(const UDSPInstruction opc)
|
void DSPEmitter::iar(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
// g_dsp.r[opc & 0x3] = dsp_increment_addr_reg(opc & 0x3);
|
// g_dsp.r[opc & 0x3] = dsp_increment_addr_reg(opc & 0x3);
|
||||||
|
zeroWriteBackLog(opc);
|
||||||
increment_addr_reg(opc & 0x3);
|
increment_addr_reg(opc & 0x3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,6 +111,7 @@ void DSPEmitter::subarn(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
// u8 dreg = opc & 0x3;
|
// u8 dreg = opc & 0x3;
|
||||||
// g_dsp.r[dreg] = dsp_decrease_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]);
|
// g_dsp.r[dreg] = dsp_decrease_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]);
|
||||||
|
zeroWriteBackLog(opc);
|
||||||
decrease_addr_reg(opc & 0x3);
|
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]);
|
// 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
|
// From looking around it is always called with the matching index register
|
||||||
|
zeroWriteBackLog(opc);
|
||||||
increase_addr_reg(opc & 0x3);
|
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.
|
// but it's harder to know exactly what effect they have.
|
||||||
void DSPEmitter::srbith(const UDSPInstruction opc)
|
void DSPEmitter::srbith(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
ABI_CallFunction((void *)zeroWriteBackLog);
|
zeroWriteBackLog(opc);
|
||||||
switch ((opc >> 8) & 0xf)
|
switch ((opc >> 8) & 0xf)
|
||||||
{
|
{
|
||||||
// M0/M2 change the multiplier mode (it can multiply by 2 for free).
|
// M0/M2 change the multiplier mode (it can multiply by 2 for free).
|
||||||
|
|
|
@ -28,6 +28,15 @@ void nx_nr()
|
||||||
tester.Report();
|
tester.Report();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nx_mv()
|
||||||
|
{
|
||||||
|
DSPJitTester tester(0x8000, 0x0010);
|
||||||
|
tester.AddTestData(DSP_REG_ACL0);
|
||||||
|
tester.AddTestData(DSP_REG_AXL0);
|
||||||
|
tester.TestAll(true);
|
||||||
|
tester.Report();
|
||||||
|
}
|
||||||
|
|
||||||
void dar()
|
void dar()
|
||||||
{
|
{
|
||||||
DSPJitTester tester(0x0004);
|
DSPJitTester tester(0x0004);
|
||||||
|
@ -81,14 +90,205 @@ void nx_s()
|
||||||
{
|
{
|
||||||
DSPJitTester tester(0x8000, 0x0020);
|
DSPJitTester tester(0x8000, 0x0020);
|
||||||
tester.AddTestData(DSP_REG_AR0);
|
tester.AddTestData(DSP_REG_AR0);
|
||||||
|
tester.AddTestData(DSP_REG_WR0);
|
||||||
tester.AddTestData(DSP_REG_ACL0);
|
tester.AddTestData(DSP_REG_ACL0);
|
||||||
tester.TestAll(true);
|
tester.TestAll(true);
|
||||||
tester.Report();
|
tester.Report();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nx_sn()
|
||||||
|
{
|
||||||
|
DSPJitTester tester(0x8000, 0x0024);
|
||||||
|
tester.AddTestData(DSP_REG_AR0);
|
||||||
|
tester.AddTestData(DSP_REG_WR0);
|
||||||
|
tester.AddTestData(DSP_REG_IX0);
|
||||||
|
tester.AddTestData(DSP_REG_ACL0);
|
||||||
|
tester.TestAll(true);
|
||||||
|
tester.Report();
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx_l()
|
||||||
|
{
|
||||||
|
|
||||||
|
DSPJitTester tester(0x8000, 0x0040);
|
||||||
|
tester.AddTestData(DSP_REG_AR0);
|
||||||
|
tester.AddTestData(DSP_REG_WR0);
|
||||||
|
tester.AddTestData(DSP_REG_AXL0);
|
||||||
|
tester.TestAll(true);
|
||||||
|
tester.Report();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set16_l()
|
||||||
|
{
|
||||||
|
|
||||||
|
DSPJitTester tester(0x8e00, 0x0070);
|
||||||
|
tester.AddTestData(DSP_REG_SR, 0);
|
||||||
|
tester.AddTestData(DSP_REG_SR, SR_40_MODE_BIT);
|
||||||
|
tester.AddTestData(DSP_REG_AR0);
|
||||||
|
tester.AddTestData(DSP_REG_WR0);
|
||||||
|
tester.AddTestData(DSP_REG_ACM0);
|
||||||
|
tester.TestAll(true);
|
||||||
|
tester.Report();
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx_ln()
|
||||||
|
{
|
||||||
|
DSPJitTester tester(0x8000, 0x0044);
|
||||||
|
tester.AddTestData(DSP_REG_AR0);
|
||||||
|
tester.AddTestData(DSP_REG_WR0);
|
||||||
|
tester.AddTestData(DSP_REG_IX0);
|
||||||
|
tester.AddTestData(DSP_REG_AXL0);
|
||||||
|
tester.TestAll(true);
|
||||||
|
tester.Report();
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx_ls()
|
||||||
|
{
|
||||||
|
DSPJitTester tester1(0x8000, 0x0080);
|
||||||
|
tester1.AddTestData(DSP_REG_ACM0);
|
||||||
|
tester1.AddTestData(DSP_REG_AR0);
|
||||||
|
tester1.AddTestData(DSP_REG_WR0);
|
||||||
|
tester1.TestAll(true);
|
||||||
|
tester1.Report();
|
||||||
|
|
||||||
|
DSPJitTester tester2(0x8000, 0x0080);
|
||||||
|
tester2.AddTestData(DSP_REG_ACM0);
|
||||||
|
tester2.AddTestData(DSP_REG_AR3);
|
||||||
|
tester2.AddTestData(DSP_REG_WR3);
|
||||||
|
tester2.TestAll(true);
|
||||||
|
tester2.Report();
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx_lsn()
|
||||||
|
{
|
||||||
|
DSPJitTester tester1(0x8000, 0x0084);
|
||||||
|
tester1.AddTestData(DSP_REG_ACM0);
|
||||||
|
tester1.AddTestData(DSP_REG_AR0);
|
||||||
|
tester1.AddTestData(DSP_REG_WR0);
|
||||||
|
tester1.AddTestData(DSP_REG_IX0);
|
||||||
|
tester1.TestAll(true);
|
||||||
|
tester1.Report();
|
||||||
|
|
||||||
|
DSPJitTester tester2(0x8000, 0x0084);
|
||||||
|
tester2.AddTestData(DSP_REG_ACM0);
|
||||||
|
tester2.AddTestData(DSP_REG_AR3);
|
||||||
|
tester2.AddTestData(DSP_REG_WR3);
|
||||||
|
tester2.TestAll(true);
|
||||||
|
tester2.Report();
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx_lsm()
|
||||||
|
{
|
||||||
|
DSPJitTester tester1(0x8000, 0x0088);
|
||||||
|
tester1.AddTestData(DSP_REG_ACM0);
|
||||||
|
tester1.AddTestData(DSP_REG_AR0);
|
||||||
|
tester1.AddTestData(DSP_REG_WR0);
|
||||||
|
tester1.TestAll(true);
|
||||||
|
tester1.Report();
|
||||||
|
|
||||||
|
DSPJitTester tester2(0x8000, 0x0088);
|
||||||
|
tester2.AddTestData(DSP_REG_ACM0);
|
||||||
|
tester2.AddTestData(DSP_REG_AR3);
|
||||||
|
tester2.AddTestData(DSP_REG_WR3);
|
||||||
|
tester2.AddTestData(DSP_REG_IX3);
|
||||||
|
tester2.TestAll(true);
|
||||||
|
tester2.Report();
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx_lsnm()
|
||||||
|
{
|
||||||
|
DSPJitTester tester1(0x8000, 0x008c);
|
||||||
|
tester1.AddTestData(DSP_REG_ACM0);
|
||||||
|
tester1.AddTestData(DSP_REG_AR0);
|
||||||
|
tester1.AddTestData(DSP_REG_WR0);
|
||||||
|
tester1.AddTestData(DSP_REG_IX0);
|
||||||
|
tester1.TestAll(true);
|
||||||
|
tester1.Report();
|
||||||
|
|
||||||
|
DSPJitTester tester2(0x8000, 0x008c);
|
||||||
|
tester2.AddTestData(DSP_REG_ACM0);
|
||||||
|
tester2.AddTestData(DSP_REG_AR3);
|
||||||
|
tester2.AddTestData(DSP_REG_WR3);
|
||||||
|
tester2.AddTestData(DSP_REG_IX3);
|
||||||
|
tester2.TestAll(true);
|
||||||
|
tester2.Report();
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx_sl()
|
||||||
|
{
|
||||||
|
DSPJitTester tester1(0x8000, 0x0082);
|
||||||
|
tester1.AddTestData(DSP_REG_ACM0);
|
||||||
|
tester1.AddTestData(DSP_REG_AR0);
|
||||||
|
tester1.AddTestData(DSP_REG_WR0);
|
||||||
|
tester1.TestAll(true);
|
||||||
|
tester1.Report();
|
||||||
|
|
||||||
|
DSPJitTester tester2(0x8000, 0x0082);
|
||||||
|
tester2.AddTestData(DSP_REG_ACM0);
|
||||||
|
tester2.AddTestData(DSP_REG_AR3);
|
||||||
|
tester2.AddTestData(DSP_REG_WR3);
|
||||||
|
tester2.TestAll(true);
|
||||||
|
tester2.Report();
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx_sln()
|
||||||
|
{
|
||||||
|
DSPJitTester tester1(0x8000, 0x0086);
|
||||||
|
tester1.AddTestData(DSP_REG_ACM0);
|
||||||
|
tester1.AddTestData(DSP_REG_AR0);
|
||||||
|
tester1.AddTestData(DSP_REG_WR0);
|
||||||
|
tester1.AddTestData(DSP_REG_IX0);
|
||||||
|
tester1.TestAll(true);
|
||||||
|
tester1.Report();
|
||||||
|
|
||||||
|
DSPJitTester tester2(0x8000, 0x0086);
|
||||||
|
tester2.AddTestData(DSP_REG_ACM0);
|
||||||
|
tester2.AddTestData(DSP_REG_AR3);
|
||||||
|
tester2.AddTestData(DSP_REG_WR3);
|
||||||
|
tester2.TestAll(true);
|
||||||
|
tester2.Report();
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx_slm()
|
||||||
|
{
|
||||||
|
DSPJitTester tester1(0x8000, 0x008a);
|
||||||
|
tester1.AddTestData(DSP_REG_ACM0);
|
||||||
|
tester1.AddTestData(DSP_REG_AR0);
|
||||||
|
tester1.AddTestData(DSP_REG_WR0);
|
||||||
|
tester1.TestAll(true);
|
||||||
|
tester1.Report();
|
||||||
|
|
||||||
|
DSPJitTester tester2(0x8000, 0x008a);
|
||||||
|
tester2.AddTestData(DSP_REG_ACM0);
|
||||||
|
tester2.AddTestData(DSP_REG_AR3);
|
||||||
|
tester2.AddTestData(DSP_REG_WR3);
|
||||||
|
tester2.AddTestData(DSP_REG_IX3);
|
||||||
|
tester2.TestAll(true);
|
||||||
|
tester2.Report();
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx_slnm()
|
||||||
|
{
|
||||||
|
DSPJitTester tester1(0x8000, 0x008e);
|
||||||
|
tester1.AddTestData(DSP_REG_ACM0);
|
||||||
|
tester1.AddTestData(DSP_REG_AR0);
|
||||||
|
tester1.AddTestData(DSP_REG_WR0);
|
||||||
|
tester1.AddTestData(DSP_REG_IX0);
|
||||||
|
tester1.TestAll(true);
|
||||||
|
tester1.Report();
|
||||||
|
|
||||||
|
DSPJitTester tester2(0x8000, 0x008e);
|
||||||
|
tester2.AddTestData(DSP_REG_ACM0);
|
||||||
|
tester2.AddTestData(DSP_REG_AR3);
|
||||||
|
tester2.AddTestData(DSP_REG_WR3);
|
||||||
|
tester2.AddTestData(DSP_REG_IX3);
|
||||||
|
tester2.TestAll(true);
|
||||||
|
tester2.Report();
|
||||||
|
}
|
||||||
|
|
||||||
void AudioJitTests()
|
void AudioJitTests()
|
||||||
{
|
{
|
||||||
DSPJitTester::Initialize();
|
DSPJitTester::Initialize();
|
||||||
|
|
||||||
dar();
|
dar();
|
||||||
iar();
|
iar();
|
||||||
subarn();
|
subarn();
|
||||||
|
@ -99,7 +299,22 @@ void AudioJitTests()
|
||||||
nx_ir();
|
nx_ir();
|
||||||
nx_dr();
|
nx_dr();
|
||||||
nx_nr();
|
nx_nr();
|
||||||
|
nx_mv();
|
||||||
|
|
||||||
|
set16_l();
|
||||||
|
|
||||||
nx_s();
|
nx_s();
|
||||||
|
nx_sn();
|
||||||
|
nx_l();
|
||||||
|
nx_ln();
|
||||||
|
nx_ls();
|
||||||
|
nx_lsn();
|
||||||
|
nx_lsm();
|
||||||
|
nx_lsnm();
|
||||||
|
nx_sl();
|
||||||
|
nx_sln();
|
||||||
|
nx_slm();
|
||||||
|
nx_slnm();
|
||||||
}
|
}
|
||||||
|
|
||||||
//required to be able to link against DSPCore
|
//required to be able to link against DSPCore
|
||||||
|
|
|
@ -41,7 +41,9 @@ SDSP DSPJitTester::RunJit(SDSP dsp_settings)
|
||||||
ResetJit();
|
ResetJit();
|
||||||
memcpy(&g_dsp, &dsp_settings, sizeof(SDSP));
|
memcpy(&g_dsp, &dsp_settings, sizeof(SDSP));
|
||||||
const u8* code = jit.GetCodePtr();
|
const u8* code = jit.GetCodePtr();
|
||||||
|
jit.ABI_PushAllCalleeSavedRegsAndAdjustStack();
|
||||||
jit.EmitInstruction(instruction);
|
jit.EmitInstruction(instruction);
|
||||||
|
jit.ABI_PopAllCalleeSavedRegsAndAdjustStack();
|
||||||
jit.RET();
|
jit.RET();
|
||||||
((void(*)())code)();
|
((void(*)())code)();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue