Core/DSPCore: Reorganize register layout for accessing accumulators
(acc and ax) and product register with one read/write. Gives a minuscule speedup of not more than 4%. In exchange, breaks all your out-of-tree changes to dsp. Tests are not building again, yet. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6680 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
0059b0f44f
commit
fc1db5eaa0
|
@ -187,6 +187,24 @@ inline OpArg ImmPtr(void* imm) {return Imm64((u64)imm);}
|
||||||
#else
|
#else
|
||||||
inline OpArg ImmPtr(void* imm) {return Imm32((u32)imm);}
|
inline OpArg ImmPtr(void* imm) {return Imm32((u32)imm);}
|
||||||
#endif
|
#endif
|
||||||
|
inline u32 PtrOffset(void* ptr, void* base) {
|
||||||
|
#ifdef _M_X64
|
||||||
|
s64 distance = (s64)ptr-(s64)base;
|
||||||
|
if (distance >= 0x80000000LL ||
|
||||||
|
distance < -0x80000000LL) {
|
||||||
|
_assert_msg_(DYNA_REC, 0, "pointer offset out of range");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return distance;
|
||||||
|
#else
|
||||||
|
return (u32)ptr-(u32)base;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//usage: int a[]; ARRAY_OFFSET(a,10)
|
||||||
|
#define ARRAY_OFFSET(array,index) ((u64)&(array)[index]-(u64)&(array)[0])
|
||||||
|
//usage: struct {int e;} s; STRUCT_OFFSET(s,e)
|
||||||
|
#define STRUCT_OFFSET(str,elem) ((u64)&(str).elem-(u64)&(str))
|
||||||
|
|
||||||
struct FixupBranch
|
struct FixupBranch
|
||||||
{
|
{
|
||||||
|
|
|
@ -88,10 +88,7 @@ bool DSPCore_Init(const char *irom_filename, const char *coef_filename,
|
||||||
LoadRom(irom_filename, DSP_IROM_SIZE, g_dsp.irom);
|
LoadRom(irom_filename, DSP_IROM_SIZE, g_dsp.irom);
|
||||||
LoadRom(coef_filename, DSP_COEF_SIZE, g_dsp.coef);
|
LoadRom(coef_filename, DSP_COEF_SIZE, g_dsp.coef);
|
||||||
|
|
||||||
for (int i = 0; i < 32; i++)
|
memset(&g_dsp._r,0,sizeof(g_dsp._r));
|
||||||
{
|
|
||||||
g_dsp.r[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
|
@ -116,13 +113,13 @@ bool DSPCore_Init(const char *irom_filename, const char *coef_filename,
|
||||||
|
|
||||||
// Copied from a real console after the custom UCode has been loaded.
|
// Copied from a real console after the custom UCode has been loaded.
|
||||||
// These are the indexing wrapping registers.
|
// These are the indexing wrapping registers.
|
||||||
g_dsp.r[DSP_REG_WR0] = 0xffff;
|
g_dsp._r.wr[0] = 0xffff;
|
||||||
g_dsp.r[DSP_REG_WR1] = 0xffff;
|
g_dsp._r.wr[1] = 0xffff;
|
||||||
g_dsp.r[DSP_REG_WR2] = 0xffff;
|
g_dsp._r.wr[2] = 0xffff;
|
||||||
g_dsp.r[DSP_REG_WR3] = 0xffff;
|
g_dsp._r.wr[3] = 0xffff;
|
||||||
|
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_INT_ENABLE;
|
g_dsp._r.sr |= SR_INT_ENABLE;
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_EXT_INT_ENABLE;
|
g_dsp._r.sr |= SR_EXT_INT_ENABLE;
|
||||||
|
|
||||||
g_dsp.cr = 0x804;
|
g_dsp.cr = 0x804;
|
||||||
gdsp_ifx_init();
|
gdsp_ifx_init();
|
||||||
|
@ -162,10 +159,10 @@ void DSPCore_Reset()
|
||||||
{
|
{
|
||||||
g_dsp.pc = DSP_RESET_VECTOR;
|
g_dsp.pc = DSP_RESET_VECTOR;
|
||||||
|
|
||||||
g_dsp.r[DSP_REG_WR0] = 0xffff;
|
g_dsp._r.wr[0] = 0xffff;
|
||||||
g_dsp.r[DSP_REG_WR1] = 0xffff;
|
g_dsp._r.wr[1] = 0xffff;
|
||||||
g_dsp.r[DSP_REG_WR2] = 0xffff;
|
g_dsp._r.wr[2] = 0xffff;
|
||||||
g_dsp.r[DSP_REG_WR3] = 0xffff;
|
g_dsp._r.wr[3] = 0xffff;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,27 +188,27 @@ void DSPCore_CheckExternalInterrupt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DSPCore_CheckExceptions()
|
void DSPCore_CheckExceptions()
|
||||||
{
|
{
|
||||||
// Early out to skip the loop in the common case.
|
// Early out to skip the loop in the common case.
|
||||||
if (g_dsp.exceptions == 0)
|
if (g_dsp.exceptions == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = 7; i > 0; i--) {
|
for (int i = 7; i > 0; i--) {
|
||||||
// Seems exp int are not masked by sr_int_enable
|
// Seems exp int are not masked by sr_int_enable
|
||||||
if (g_dsp.exceptions & (1 << i)) {
|
if (g_dsp.exceptions & (1 << i)) {
|
||||||
if (dsp_SR_is_flag_set(SR_INT_ENABLE) || (i == EXP_INT)) {
|
if (dsp_SR_is_flag_set(SR_INT_ENABLE) || (i == EXP_INT)) {
|
||||||
|
|
||||||
// store pc and sr until RTI
|
// store pc and sr until RTI
|
||||||
dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc);
|
dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc);
|
||||||
dsp_reg_store_stack(DSP_STACK_D, g_dsp.r[DSP_REG_SR]);
|
dsp_reg_store_stack(DSP_STACK_D, g_dsp._r.sr);
|
||||||
|
|
||||||
g_dsp.pc = i * 2;
|
g_dsp.pc = i * 2;
|
||||||
g_dsp.exceptions &= ~(1 << i);
|
g_dsp.exceptions &= ~(1 << i);
|
||||||
if (i == 7)
|
if (i == 7)
|
||||||
g_dsp.r[DSP_REG_SR] &= ~SR_EXT_INT_ENABLE;
|
g_dsp._r.sr &= ~SR_EXT_INT_ENABLE;
|
||||||
else
|
else
|
||||||
g_dsp.r[DSP_REG_SR] &= ~SR_INT_ENABLE;
|
g_dsp._r.sr &= ~SR_INT_ENABLE;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
|
@ -296,3 +293,106 @@ void CompileCurrent()
|
||||||
jit->Compile(g_dsp.pc);
|
jit->Compile(g_dsp.pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u16 DSPCore_ReadRegister(int reg) {
|
||||||
|
switch(reg) {
|
||||||
|
case DSP_REG_AR0:
|
||||||
|
case DSP_REG_AR1:
|
||||||
|
case DSP_REG_AR2:
|
||||||
|
case DSP_REG_AR3:
|
||||||
|
return g_dsp._r.ar[reg - DSP_REG_AR0];
|
||||||
|
case DSP_REG_IX0:
|
||||||
|
case DSP_REG_IX1:
|
||||||
|
case DSP_REG_IX2:
|
||||||
|
case DSP_REG_IX3:
|
||||||
|
return g_dsp._r.ix[reg - DSP_REG_IX0];
|
||||||
|
case DSP_REG_WR0:
|
||||||
|
case DSP_REG_WR1:
|
||||||
|
case DSP_REG_WR2:
|
||||||
|
case DSP_REG_WR3:
|
||||||
|
return g_dsp._r.wr[reg - DSP_REG_WR0];
|
||||||
|
case DSP_REG_ST0:
|
||||||
|
case DSP_REG_ST1:
|
||||||
|
case DSP_REG_ST2:
|
||||||
|
case DSP_REG_ST3:
|
||||||
|
return g_dsp._r.st[reg - DSP_REG_ST0];
|
||||||
|
case DSP_REG_ACH0:
|
||||||
|
case DSP_REG_ACH1:
|
||||||
|
return g_dsp._r.ac[reg - DSP_REG_ACH0].h;
|
||||||
|
case DSP_REG_CR: return g_dsp._r.cr;
|
||||||
|
case DSP_REG_SR: return g_dsp._r.sr;
|
||||||
|
case DSP_REG_PRODL: return g_dsp._r.prod.l;
|
||||||
|
case DSP_REG_PRODM: return g_dsp._r.prod.m;
|
||||||
|
case DSP_REG_PRODH: return g_dsp._r.prod.h;
|
||||||
|
case DSP_REG_PRODM2: return g_dsp._r.prod.m2;
|
||||||
|
case DSP_REG_AXL0:
|
||||||
|
case DSP_REG_AXL1:
|
||||||
|
return g_dsp._r.ax[reg - DSP_REG_AXL0].l;
|
||||||
|
case DSP_REG_AXH0:
|
||||||
|
case DSP_REG_AXH1:
|
||||||
|
return g_dsp._r.ax[reg - DSP_REG_AXH0].h;
|
||||||
|
case DSP_REG_ACL0:
|
||||||
|
case DSP_REG_ACL1:
|
||||||
|
return g_dsp._r.ac[reg - DSP_REG_ACL0].l;
|
||||||
|
case DSP_REG_ACM0:
|
||||||
|
case DSP_REG_ACM1:
|
||||||
|
return g_dsp._r.ac[reg - DSP_REG_ACM0].m;
|
||||||
|
default:
|
||||||
|
_assert_msg_(DSP_CORE, 0, "cannot happen");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSPCore_WriteRegister(int reg, u16 val) {
|
||||||
|
switch(reg) {
|
||||||
|
case DSP_REG_AR0:
|
||||||
|
case DSP_REG_AR1:
|
||||||
|
case DSP_REG_AR2:
|
||||||
|
case DSP_REG_AR3:
|
||||||
|
g_dsp._r.ar[reg - DSP_REG_AR0] = val;
|
||||||
|
break;
|
||||||
|
case DSP_REG_IX0:
|
||||||
|
case DSP_REG_IX1:
|
||||||
|
case DSP_REG_IX2:
|
||||||
|
case DSP_REG_IX3:
|
||||||
|
g_dsp._r.ix[reg - DSP_REG_IX0] = val;
|
||||||
|
break;
|
||||||
|
case DSP_REG_WR0:
|
||||||
|
case DSP_REG_WR1:
|
||||||
|
case DSP_REG_WR2:
|
||||||
|
case DSP_REG_WR3:
|
||||||
|
g_dsp._r.wr[reg - DSP_REG_WR0] = val;
|
||||||
|
break;
|
||||||
|
case DSP_REG_ST0:
|
||||||
|
case DSP_REG_ST1:
|
||||||
|
case DSP_REG_ST2:
|
||||||
|
case DSP_REG_ST3:
|
||||||
|
g_dsp._r.st[reg - DSP_REG_ST0] = val;
|
||||||
|
break;
|
||||||
|
case DSP_REG_ACH0:
|
||||||
|
case DSP_REG_ACH1:
|
||||||
|
g_dsp._r.ac[reg - DSP_REG_ACH0].h = val;
|
||||||
|
break;
|
||||||
|
case DSP_REG_CR: g_dsp._r.cr = val; break;
|
||||||
|
case DSP_REG_SR: g_dsp._r.sr = val; break;
|
||||||
|
case DSP_REG_PRODL: g_dsp._r.prod.l = val; break;
|
||||||
|
case DSP_REG_PRODM: g_dsp._r.prod.m = val; break;
|
||||||
|
case DSP_REG_PRODH: g_dsp._r.prod.h = val; break;
|
||||||
|
case DSP_REG_PRODM2: g_dsp._r.prod.m2 = val; break;
|
||||||
|
case DSP_REG_AXL0:
|
||||||
|
case DSP_REG_AXL1:
|
||||||
|
g_dsp._r.ax[reg - DSP_REG_AXL0].l = val;
|
||||||
|
break;
|
||||||
|
case DSP_REG_AXH0:
|
||||||
|
case DSP_REG_AXH1:
|
||||||
|
g_dsp._r.ax[reg - DSP_REG_AXH0].h = val;
|
||||||
|
break;
|
||||||
|
case DSP_REG_ACL0:
|
||||||
|
case DSP_REG_ACL1:
|
||||||
|
g_dsp._r.ac[reg - DSP_REG_ACL0].l = val;
|
||||||
|
break;
|
||||||
|
case DSP_REG_ACM0:
|
||||||
|
case DSP_REG_ACM1:
|
||||||
|
g_dsp._r.ac[reg - DSP_REG_ACM0].m = val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -180,17 +180,50 @@
|
||||||
#define EXP_6 6 // 0x000c
|
#define EXP_6 6 // 0x000c
|
||||||
#define EXP_INT 7 // 0x000e external int (message from cpu)
|
#define EXP_INT 7 // 0x000e external int (message from cpu)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u16 ar[4];
|
||||||
|
u16 ix[4];
|
||||||
|
u16 wr[4];
|
||||||
|
u16 st[4];
|
||||||
|
u16 cr;
|
||||||
|
u16 sr;
|
||||||
|
union {
|
||||||
|
u64 val;
|
||||||
|
struct {
|
||||||
|
u16 l;
|
||||||
|
u16 m;
|
||||||
|
u16 h;
|
||||||
|
u16 m2;//if this gets in the way, drop it.
|
||||||
|
};
|
||||||
|
} prod;
|
||||||
|
union {
|
||||||
|
u32 val;
|
||||||
|
struct {
|
||||||
|
u16 l;
|
||||||
|
u16 h;
|
||||||
|
};
|
||||||
|
} ax[2];
|
||||||
|
union {
|
||||||
|
u64 val;
|
||||||
|
struct {
|
||||||
|
u16 l;
|
||||||
|
u16 m;
|
||||||
|
u16 h;
|
||||||
|
};
|
||||||
|
} ac[2];
|
||||||
|
} DSP_Regs;
|
||||||
|
|
||||||
// All the state of the DSP should be in this struct. Any DSP state that is not filled on init
|
// All the state of the DSP should be in this struct. Any DSP state that is not filled on init
|
||||||
// should be moved here.
|
// should be moved here.
|
||||||
struct SDSP
|
struct SDSP
|
||||||
{
|
{
|
||||||
u16 r[32];
|
DSP_Regs _r;
|
||||||
u16 pc;
|
u16 pc;
|
||||||
#if PROFILE
|
#if PROFILE
|
||||||
u16 err_pc;
|
u16 err_pc;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// This is NOT the same cr as r[DSP_REG_CR].
|
// This is NOT the same cr as r.cr.
|
||||||
// This register is shared with the main emulation, see DSP.cpp
|
// This register is shared with the main emulation, see DSP.cpp
|
||||||
// The plugin has control over 0x0C07 of this reg.
|
// The plugin has control over 0x0C07 of this reg.
|
||||||
// Bits are defined in a struct in DSP.cpp.
|
// Bits are defined in a struct in DSP.cpp.
|
||||||
|
@ -265,4 +298,7 @@ DSPCoreState DSPCore_GetState();
|
||||||
|
|
||||||
void DSPCore_Step();
|
void DSPCore_Step();
|
||||||
|
|
||||||
|
u16 DSPCore_ReadRegister(int reg);
|
||||||
|
void DSPCore_WriteRegister(int reg, u16 val);
|
||||||
|
|
||||||
#endif // _DSPCORE_H
|
#endif // _DSPCORE_H
|
||||||
|
|
|
@ -112,6 +112,35 @@ void DSPEmitter::checkExceptions(u32 retval)
|
||||||
SetJumpTarget(skipCheck);
|
SetJumpTarget(skipCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool checkExtendedExclude(UDSPInstruction inst)
|
||||||
|
{
|
||||||
|
const DSPOPCTemplate *tinst = GetOpTemplate(inst);
|
||||||
|
|
||||||
|
// Call extended
|
||||||
|
if (!tinst->extended)
|
||||||
|
return false;
|
||||||
|
if ((inst >> 12) != 0x3)
|
||||||
|
return false;
|
||||||
|
/*
|
||||||
|
if((inst & 0x00ff) == 0x00c0) {
|
||||||
|
fprintf(stderr,"blocking %04x\n", inst);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool checkMainExclude(UDSPInstruction inst)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
if((inst & 0xfffc) == 0x1fcc)
|
||||||
|
return true;
|
||||||
|
*/
|
||||||
|
// if((inst & 0xfffc) == 0x1fcc)
|
||||||
|
// return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void DSPEmitter::Default(UDSPInstruction inst)
|
void DSPEmitter::Default(UDSPInstruction inst)
|
||||||
{
|
{
|
||||||
if (opTable[inst]->reads_pc)
|
if (opTable[inst]->reads_pc)
|
||||||
|
@ -139,18 +168,20 @@ void DSPEmitter::EmitInstruction(UDSPInstruction inst)
|
||||||
// Call extended
|
// Call extended
|
||||||
if (tinst->extended) {
|
if (tinst->extended) {
|
||||||
if ((inst >> 12) == 0x3) {
|
if ((inst >> 12) == 0x3) {
|
||||||
if (! extOpTable[inst & 0x7F]->jitFunc) {
|
if (! extOpTable[inst & 0x7F]->jitFunc || checkExtendedExclude(inst)) {
|
||||||
// Fall back to interpreter
|
// Fall back to interpreter
|
||||||
ABI_CallFunctionC16((void*)extOpTable[inst & 0x7F]->intFunc, inst);
|
ABI_CallFunctionC16((void*)extOpTable[inst & 0x7F]->intFunc, inst);
|
||||||
|
INFO_LOG(DSPLLE,"Instruction not JITed(ext part): %04x\n",inst);
|
||||||
ext_is_jit = false;
|
ext_is_jit = false;
|
||||||
} else {
|
} else {
|
||||||
(this->*extOpTable[inst & 0x7F]->jitFunc)(inst);
|
(this->*extOpTable[inst & 0x7F]->jitFunc)(inst);
|
||||||
ext_is_jit = true;
|
ext_is_jit = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!extOpTable[inst & 0xFF]->jitFunc) {
|
if (!extOpTable[inst & 0xFF]->jitFunc || checkExtendedExclude(inst)) {
|
||||||
// Fall back to interpreter
|
// Fall back to interpreter
|
||||||
ABI_CallFunctionC16((void*)extOpTable[inst & 0xFF]->intFunc, inst);
|
ABI_CallFunctionC16((void*)extOpTable[inst & 0xFF]->intFunc, inst);
|
||||||
|
INFO_LOG(DSPLLE,"Instruction not JITed(ext part): %04x\n",inst);
|
||||||
ext_is_jit = false;
|
ext_is_jit = false;
|
||||||
} else {
|
} else {
|
||||||
(this->*extOpTable[inst & 0xFF]->jitFunc)(inst);
|
(this->*extOpTable[inst & 0xFF]->jitFunc)(inst);
|
||||||
|
@ -160,8 +191,9 @@ void DSPEmitter::EmitInstruction(UDSPInstruction inst)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main instruction
|
// Main instruction
|
||||||
if (!opTable[inst]->jitFunc) {
|
if (!opTable[inst]->jitFunc || checkMainExclude(inst)) {
|
||||||
Default(inst);
|
Default(inst);
|
||||||
|
INFO_LOG(DSPLLE,"Instruction not JITed(main part): %04x\n",inst);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -239,7 +271,7 @@ void DSPEmitter::Compile(int start_addr)
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
TEST(16, M(&g_dsp.cr), Imm16(CR_EXTERNAL_INT));
|
TEST(16, M(&g_dsp.cr), Imm16(CR_EXTERNAL_INT));
|
||||||
FixupBranch noExternalInterrupt = J_CC(CC_Z);
|
FixupBranch noExternalInterrupt = J_CC(CC_Z);
|
||||||
TEST(16, M(&g_dsp.r[DSP_REG_SR]), Imm16(SR_EXT_INT_ENABLE));
|
TEST(16, M(&g_dsp._r.sr), Imm16(SR_EXT_INT_ENABLE));
|
||||||
FixupBranch externalInterruptDisabled = J_CC(CC_Z);
|
FixupBranch externalInterruptDisabled = J_CC(CC_Z);
|
||||||
OR(8, M(&g_dsp.exceptions), Imm8(1 << EXP_INT));
|
OR(8, M(&g_dsp.exceptions), Imm8(1 << EXP_INT));
|
||||||
AND(16, M(&g_dsp.cr), Imm16(~CR_EXTERNAL_INT));
|
AND(16, M(&g_dsp.cr), Imm16(~CR_EXTERNAL_INT));
|
||||||
|
@ -250,8 +282,8 @@ void DSPEmitter::Compile(int start_addr)
|
||||||
MOV(64, R(RAX), ImmPtr(&g_dsp.cr));
|
MOV(64, R(RAX), ImmPtr(&g_dsp.cr));
|
||||||
TEST(16, MatR(RAX), Imm16(CR_EXTERNAL_INT));
|
TEST(16, MatR(RAX), Imm16(CR_EXTERNAL_INT));
|
||||||
FixupBranch noExternalInterrupt = J_CC(CC_Z);
|
FixupBranch noExternalInterrupt = J_CC(CC_Z);
|
||||||
MOV(64, R(RAX), ImmPtr(&g_dsp.r));
|
MOV(64, R(RAX), ImmPtr(&g_dsp._r.sr));
|
||||||
TEST(16, MDisp(RAX,DSP_REG_SR*2), Imm16(SR_EXT_INT_ENABLE));
|
TEST(16, MatR(RAX), Imm16(SR_EXT_INT_ENABLE));
|
||||||
FixupBranch externalInterruptDisabled = J_CC(CC_Z);
|
FixupBranch externalInterruptDisabled = J_CC(CC_Z);
|
||||||
MOV(64, R(RAX), ImmPtr(&g_dsp.exceptions));
|
MOV(64, R(RAX), ImmPtr(&g_dsp.exceptions));
|
||||||
OR(8, MatR(RAX), Imm8(1 << EXP_INT));
|
OR(8, MatR(RAX), Imm8(1 << EXP_INT));
|
||||||
|
@ -293,18 +325,18 @@ void DSPEmitter::Compile(int start_addr)
|
||||||
if (DSPAnalyzer::code_flags[compilePC-1] & DSPAnalyzer::CODE_LOOP_END)
|
if (DSPAnalyzer::code_flags[compilePC-1] & DSPAnalyzer::CODE_LOOP_END)
|
||||||
{
|
{
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, EAX, M(&(g_dsp.r[DSP_REG_ST2])));
|
MOVZX(32, 16, EAX, M(&(g_dsp._r.st[2])));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(32, 16, EAX, MDisp(R11,DSP_REG_ST2*2));
|
MOVZX(32, 16, EAX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, st[2])));
|
||||||
#endif
|
#endif
|
||||||
CMP(32, R(EAX), Imm32(0));
|
CMP(32, R(EAX), Imm32(0));
|
||||||
FixupBranch rLoopAddressExit = J_CC(CC_LE, true);
|
FixupBranch rLoopAddressExit = J_CC(CC_LE, true);
|
||||||
|
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, EAX, M(&(g_dsp.r[DSP_REG_ST3])));
|
MOVZX(32, 16, EAX, M(&g_dsp._r.st[3]));
|
||||||
#else
|
#else
|
||||||
MOVZX(32, 16, EAX, MDisp(R11,DSP_REG_ST3*2));
|
MOVZX(32, 16, EAX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, st[3])));
|
||||||
#endif
|
#endif
|
||||||
CMP(32, R(EAX), Imm32(0));
|
CMP(32, R(EAX), Imm32(0));
|
||||||
FixupBranch rLoopCounterExit = J_CC(CC_LE, true);
|
FixupBranch rLoopCounterExit = J_CC(CC_LE, true);
|
||||||
|
@ -447,7 +479,7 @@ void DSPEmitter::CompileDispatcher()
|
||||||
// Using R12 here since it is callee save register on both
|
// Using R12 here since it is callee save register on both
|
||||||
// linux and windows 64.
|
// linux and windows 64.
|
||||||
MOV(64, R(R12), ImmPtr(&cyclesLeft));
|
MOV(64, R(R12), ImmPtr(&cyclesLeft));
|
||||||
MOV(32, R(R12), MDisp(R12,0));
|
MOV(32, R(R12), MatR(R12));
|
||||||
MOV(64, R(RBX), ImmPtr(blocks));
|
MOV(64, R(RBX), ImmPtr(blocks));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -458,7 +490,7 @@ void DSPEmitter::CompileDispatcher()
|
||||||
TEST(8, M(&g_dsp.cr), Imm8(CR_HALT));
|
TEST(8, M(&g_dsp.cr), Imm8(CR_HALT));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.cr));
|
MOV(64, R(R11), ImmPtr(&g_dsp.cr));
|
||||||
TEST(8, MDisp(R11,0), Imm8(CR_HALT));
|
TEST(8, MatR(R11), Imm8(CR_HALT));
|
||||||
#endif
|
#endif
|
||||||
FixupBranch halt = J_CC(CC_NE);
|
FixupBranch halt = J_CC(CC_NE);
|
||||||
|
|
||||||
|
@ -466,7 +498,7 @@ void DSPEmitter::CompileDispatcher()
|
||||||
MOVZX(32, 16, ECX, M(&g_dsp.pc));
|
MOVZX(32, 16, ECX, M(&g_dsp.pc));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(RCX), ImmPtr(&g_dsp.pc));
|
MOV(64, R(RCX), ImmPtr(&g_dsp.pc));
|
||||||
MOVZX(64, 16, RCX, MDisp(RCX,0));
|
MOVZX(64, 16, RCX, MatR(RCX));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Execute block. Cycles executed returned in EAX.
|
// Execute block. Cycles executed returned in EAX.
|
||||||
|
|
|
@ -28,128 +28,128 @@ namespace DSPInterpreter {
|
||||||
|
|
||||||
void Update_SR_Register64(s64 _Value, bool carry, bool overflow)
|
void Update_SR_Register64(s64 _Value, bool carry, bool overflow)
|
||||||
{
|
{
|
||||||
g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
|
g_dsp._r.sr &= ~SR_CMP_MASK;
|
||||||
|
|
||||||
// 0x01
|
// 0x01
|
||||||
if (carry)
|
if (carry)
|
||||||
{
|
{
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_CARRY;
|
g_dsp._r.sr |= SR_CARRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x02 and 0x80
|
// 0x02 and 0x80
|
||||||
if (overflow)
|
if (overflow)
|
||||||
{
|
{
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_OVERFLOW;
|
g_dsp._r.sr |= SR_OVERFLOW;
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_OVERFLOW_STICKY;
|
g_dsp._r.sr |= SR_OVERFLOW_STICKY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x04
|
// 0x04
|
||||||
if (_Value == 0)
|
if (_Value == 0)
|
||||||
{
|
{
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
|
g_dsp._r.sr |= SR_ARITH_ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x08
|
// 0x08
|
||||||
if (_Value < 0)
|
if (_Value < 0)
|
||||||
{
|
{
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_SIGN;
|
g_dsp._r.sr |= SR_SIGN;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x10
|
// 0x10
|
||||||
if (_Value != (s32)_Value)
|
if (_Value != (s32)_Value)
|
||||||
{
|
{
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_OVER_S32;
|
g_dsp._r.sr |= SR_OVER_S32;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x20 - Checks if top bits of m are equal
|
// 0x20 - Checks if top bits of m are equal
|
||||||
if (((_Value & 0xc0000000) == 0) || ((_Value & 0xc0000000) == 0xc0000000))
|
if (((_Value & 0xc0000000) == 0) || ((_Value & 0xc0000000) == 0xc0000000))
|
||||||
{
|
{
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS;
|
g_dsp._r.sr |= SR_TOP2BITS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Update_SR_Register16(s16 _Value, bool carry, bool overflow, bool overS32)
|
void Update_SR_Register16(s16 _Value, bool carry, bool overflow, bool overS32)
|
||||||
{
|
{
|
||||||
g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
|
g_dsp._r.sr &= ~SR_CMP_MASK;
|
||||||
|
|
||||||
// 0x01
|
// 0x01
|
||||||
if (carry)
|
if (carry)
|
||||||
{
|
{
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_CARRY;
|
g_dsp._r.sr |= SR_CARRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x02 and 0x80
|
// 0x02 and 0x80
|
||||||
if (overflow)
|
if (overflow)
|
||||||
{
|
{
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_OVERFLOW;
|
g_dsp._r.sr |= SR_OVERFLOW;
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_OVERFLOW_STICKY;
|
g_dsp._r.sr |= SR_OVERFLOW_STICKY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x04
|
// 0x04
|
||||||
if (_Value == 0)
|
if (_Value == 0)
|
||||||
{
|
{
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
|
g_dsp._r.sr |= SR_ARITH_ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x08
|
// 0x08
|
||||||
if (_Value < 0)
|
if (_Value < 0)
|
||||||
{
|
{
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_SIGN;
|
g_dsp._r.sr |= SR_SIGN;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x10
|
// 0x10
|
||||||
if (overS32)
|
if (overS32)
|
||||||
{
|
{
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_OVER_S32;
|
g_dsp._r.sr |= SR_OVER_S32;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x20 - Checks if top bits of m are equal
|
// 0x20 - Checks if top bits of m are equal
|
||||||
if ((((u16)_Value >> 14) == 0) || (((u16)_Value >> 14) == 3))
|
if ((((u16)_Value >> 14) == 0) || (((u16)_Value >> 14) == 3))
|
||||||
{
|
{
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS;
|
g_dsp._r.sr |= SR_TOP2BITS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update_SR_LZ(bool value)
|
void Update_SR_LZ(bool value)
|
||||||
{
|
{
|
||||||
if (value == true)
|
if (value == true)
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_LOGIC_ZERO;
|
g_dsp._r.sr |= SR_LOGIC_ZERO;
|
||||||
else
|
else
|
||||||
g_dsp.r[DSP_REG_SR] &= ~SR_LOGIC_ZERO;
|
g_dsp._r.sr &= ~SR_LOGIC_ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int GetMultiplyModifier()
|
inline int GetMultiplyModifier()
|
||||||
{
|
{
|
||||||
return (g_dsp.r[DSP_REG_SR] & SR_MUL_MODIFY)?1:2;
|
return (g_dsp._r.sr & SR_MUL_MODIFY)?1:2;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isCarry() {
|
inline bool isCarry() {
|
||||||
return (g_dsp.r[DSP_REG_SR] & SR_CARRY) ? true : false;
|
return (g_dsp._r.sr & SR_CARRY) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isOverflow() {
|
inline bool isOverflow() {
|
||||||
return (g_dsp.r[DSP_REG_SR] & SR_OVERFLOW) ? true : false;
|
return (g_dsp._r.sr & SR_OVERFLOW) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isOverS32() {
|
inline bool isOverS32() {
|
||||||
return (g_dsp.r[DSP_REG_SR] & SR_OVER_S32) ? true : false;
|
return (g_dsp._r.sr & SR_OVER_S32) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isLess() {
|
inline bool isLess() {
|
||||||
return (!(g_dsp.r[DSP_REG_SR] & SR_OVERFLOW) != !(g_dsp.r[DSP_REG_SR] & SR_SIGN));
|
return (!(g_dsp._r.sr & SR_OVERFLOW) != !(g_dsp._r.sr & SR_SIGN));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isZero() {
|
inline bool isZero() {
|
||||||
return (g_dsp.r[DSP_REG_SR] & SR_ARITH_ZERO) ? true : false;
|
return (g_dsp._r.sr & SR_ARITH_ZERO) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isLogicZero() {
|
inline bool isLogicZero() {
|
||||||
return (g_dsp.r[DSP_REG_SR] & SR_LOGIC_ZERO) ? true : false;
|
return (g_dsp._r.sr & SR_LOGIC_ZERO) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isConditionA() {
|
inline bool isConditionA() {
|
||||||
return (((g_dsp.r[DSP_REG_SR] & SR_OVER_S32) || (g_dsp.r[DSP_REG_SR] & SR_TOP2BITS)) && !(g_dsp.r[DSP_REG_SR] & SR_ARITH_ZERO)) ? true : false;
|
return (((g_dsp._r.sr & SR_OVER_S32) || (g_dsp._r.sr & SR_TOP2BITS)) && !(g_dsp._r.sr & SR_ARITH_ZERO)) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//see DSPCore.h for flags
|
//see DSPCore.h for flags
|
||||||
|
|
|
@ -70,7 +70,7 @@ void ir(const UDSPInstruction opc) {
|
||||||
void nr(const UDSPInstruction opc) {
|
void nr(const UDSPInstruction opc) {
|
||||||
u8 reg = opc & 0x3;
|
u8 reg = opc & 0x3;
|
||||||
|
|
||||||
writeToBackLog(0, reg, dsp_increase_addr_reg(reg, (s16)g_dsp.r[DSP_REG_IX0 + reg]));
|
writeToBackLog(0, reg, dsp_increase_addr_reg(reg, (s16)g_dsp._r.ix[reg]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// MV $axD.D, $acS.S
|
// MV $axD.D, $acS.S
|
||||||
|
@ -81,7 +81,16 @@ void mv(const UDSPInstruction opc)
|
||||||
u8 sreg = (opc & 0x3) + DSP_REG_ACL0;
|
u8 sreg = (opc & 0x3) + DSP_REG_ACL0;
|
||||||
u8 dreg = ((opc >> 2) & 0x3);
|
u8 dreg = ((opc >> 2) & 0x3);
|
||||||
|
|
||||||
writeToBackLog(0, dreg + DSP_REG_AXL0, g_dsp.r[sreg]);
|
switch(sreg) {
|
||||||
|
case DSP_REG_ACL0:
|
||||||
|
case DSP_REG_ACL1:
|
||||||
|
writeToBackLog(0, dreg + DSP_REG_AXL0, g_dsp._r.ac[sreg-DSP_REG_ACL0].l);
|
||||||
|
break;
|
||||||
|
case DSP_REG_ACM0:
|
||||||
|
case DSP_REG_ACM1:
|
||||||
|
writeToBackLog(0, dreg + DSP_REG_AXL0, g_dsp._r.ac[sreg-DSP_REG_ACM0].m);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// S @$arD, $acS.S
|
// S @$arD, $acS.S
|
||||||
|
@ -93,7 +102,16 @@ void s(const UDSPInstruction opc)
|
||||||
u8 dreg = opc & 0x3;
|
u8 dreg = opc & 0x3;
|
||||||
u8 sreg = ((opc >> 3) & 0x3) + DSP_REG_ACL0;
|
u8 sreg = ((opc >> 3) & 0x3) + DSP_REG_ACL0;
|
||||||
|
|
||||||
dsp_dmem_write(g_dsp.r[dreg], g_dsp.r[sreg]);
|
switch(sreg) {
|
||||||
|
case DSP_REG_ACL0:
|
||||||
|
case DSP_REG_ACL1:
|
||||||
|
dsp_dmem_write(g_dsp._r.ar[dreg], g_dsp._r.ac[sreg-DSP_REG_ACL0].l);
|
||||||
|
break;
|
||||||
|
case DSP_REG_ACM0:
|
||||||
|
case DSP_REG_ACM1:
|
||||||
|
dsp_dmem_write(g_dsp._r.ar[dreg], g_dsp._r.ac[sreg-DSP_REG_ACM0].m);
|
||||||
|
break;
|
||||||
|
}
|
||||||
writeToBackLog(0, dreg, dsp_increment_addr_reg(dreg));
|
writeToBackLog(0, dreg, dsp_increment_addr_reg(dreg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,8 +124,17 @@ void sn(const UDSPInstruction opc)
|
||||||
u8 dreg = opc & 0x3;
|
u8 dreg = opc & 0x3;
|
||||||
u8 sreg = ((opc >> 3) & 0x3) + DSP_REG_ACL0;
|
u8 sreg = ((opc >> 3) & 0x3) + DSP_REG_ACL0;
|
||||||
|
|
||||||
dsp_dmem_write(g_dsp.r[dreg], g_dsp.r[sreg]);
|
switch(sreg) {
|
||||||
writeToBackLog(0, dreg, dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]));
|
case DSP_REG_ACL0:
|
||||||
|
case DSP_REG_ACL1:
|
||||||
|
dsp_dmem_write(g_dsp._r.ar[dreg], g_dsp._r.ac[sreg-DSP_REG_ACL0].l);
|
||||||
|
break;
|
||||||
|
case DSP_REG_ACM0:
|
||||||
|
case DSP_REG_ACM1:
|
||||||
|
dsp_dmem_write(g_dsp._r.ar[dreg], g_dsp._r.ac[sreg-DSP_REG_ACM0].m);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
writeToBackLog(0, dreg, dsp_increase_addr_reg(dreg, (s16)g_dsp._r.ix[dreg]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// L $axD.D, @$arS
|
// L $axD.D, @$arS
|
||||||
|
@ -119,9 +146,9 @@ void l(const UDSPInstruction opc)
|
||||||
u8 sreg = opc & 0x3;
|
u8 sreg = opc & 0x3;
|
||||||
u8 dreg = ((opc >> 3) & 0x7) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 3) & 0x7) + DSP_REG_AXL0;
|
||||||
|
|
||||||
if ((dreg >= DSP_REG_ACM0) && (g_dsp.r[DSP_REG_SR] & SR_40_MODE_BIT))
|
if ((dreg >= DSP_REG_ACM0) && (g_dsp._r.sr & SR_40_MODE_BIT))
|
||||||
{
|
{
|
||||||
u16 val = dsp_dmem_read(g_dsp.r[sreg]);
|
u16 val = dsp_dmem_read(g_dsp._r.ar[sreg]);
|
||||||
writeToBackLog(0, dreg - DSP_REG_ACM0 + DSP_REG_ACH0, (val & 0x8000) ? 0xFFFF : 0x0000);
|
writeToBackLog(0, dreg - DSP_REG_ACM0 + DSP_REG_ACH0, (val & 0x8000) ? 0xFFFF : 0x0000);
|
||||||
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);
|
||||||
|
@ -129,7 +156,7 @@ void l(const UDSPInstruction opc)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[sreg]));
|
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp._r.ar[sreg]));
|
||||||
writeToBackLog(1, sreg, dsp_increment_addr_reg(sreg));
|
writeToBackLog(1, sreg, dsp_increment_addr_reg(sreg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,34 +170,34 @@ void ln(const UDSPInstruction opc)
|
||||||
u8 sreg = opc & 0x3;
|
u8 sreg = opc & 0x3;
|
||||||
u8 dreg = ((opc >> 3) & 0x7) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 3) & 0x7) + DSP_REG_AXL0;
|
||||||
|
|
||||||
if ((dreg >= DSP_REG_ACM0) && (g_dsp.r[DSP_REG_SR] & SR_40_MODE_BIT))
|
if ((dreg >= DSP_REG_ACM0) && (g_dsp._r.sr & SR_40_MODE_BIT))
|
||||||
{
|
{
|
||||||
u16 val = dsp_dmem_read(g_dsp.r[sreg]);
|
u16 val = dsp_dmem_read(g_dsp._r.ar[sreg]);
|
||||||
writeToBackLog(0, dreg - DSP_REG_ACM0 + DSP_REG_ACH0, (val & 0x8000) ? 0xFFFF : 0x0000);
|
writeToBackLog(0, dreg - DSP_REG_ACM0 + DSP_REG_ACH0, (val & 0x8000) ? 0xFFFF : 0x0000);
|
||||||
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);
|
||||||
writeToBackLog(3, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]));
|
writeToBackLog(3, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp._r.ix[sreg]));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[sreg]));
|
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp._r.ar[sreg]));
|
||||||
writeToBackLog(1, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]));
|
writeToBackLog(1, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp._r.ix[sreg]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// LS $axD.D, $acS.m
|
// LS $axD.D, $acS.m108
|
||||||
// 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 ls(const UDSPInstruction opc)
|
void ls(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
u8 sreg = opc & 0x1;
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
|
|
||||||
dsp_dmem_write(g_dsp.r[DSP_REG_AR3], g_dsp.r[sreg]);
|
dsp_dmem_write(g_dsp._r.ar[3], g_dsp._r.ac[sreg].m);
|
||||||
|
|
||||||
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[DSP_REG_AR0]));
|
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp._r.ar[0]));
|
||||||
writeToBackLog(1, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3));
|
writeToBackLog(1, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3));
|
||||||
writeToBackLog(2, DSP_REG_AR0, dsp_increment_addr_reg(DSP_REG_AR0));
|
writeToBackLog(2, DSP_REG_AR0, dsp_increment_addr_reg(DSP_REG_AR0));
|
||||||
}
|
}
|
||||||
|
@ -184,14 +211,14 @@ void ls(const UDSPInstruction opc)
|
||||||
// register $ar0 and increment $ar3.
|
// register $ar0 and increment $ar3.
|
||||||
void lsn(const UDSPInstruction opc)
|
void lsn(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
u8 sreg = opc & 0x1;
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
|
|
||||||
dsp_dmem_write(g_dsp.r[DSP_REG_AR3], g_dsp.r[sreg]);
|
dsp_dmem_write(g_dsp._r.ar[3], g_dsp._r.ac[sreg].m);
|
||||||
|
|
||||||
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[DSP_REG_AR0]));
|
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp._r.ar[0]));
|
||||||
writeToBackLog(1, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3));
|
writeToBackLog(1, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3));
|
||||||
writeToBackLog(2, DSP_REG_AR0, dsp_increase_addr_reg(DSP_REG_AR0, (s16)g_dsp.r[DSP_REG_IX0]));
|
writeToBackLog(2, DSP_REG_AR0, dsp_increase_addr_reg(DSP_REG_AR0, (s16)g_dsp._r.ix[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// LSM $axD.D, $acS.m
|
// LSM $axD.D, $acS.m
|
||||||
|
@ -202,13 +229,13 @@ void lsn(const UDSPInstruction opc)
|
||||||
// register $ar3 and increment $ar0.
|
// register $ar3 and increment $ar0.
|
||||||
void lsm(const UDSPInstruction opc)
|
void lsm(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
u8 sreg = opc & 0x1;
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
|
|
||||||
dsp_dmem_write(g_dsp.r[DSP_REG_AR3], g_dsp.r[sreg]);
|
|
||||||
|
|
||||||
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[DSP_REG_AR0]));
|
dsp_dmem_write(g_dsp._r.ar[3], g_dsp._r.ac[sreg].m);
|
||||||
writeToBackLog(1, DSP_REG_AR3, dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r[DSP_REG_IX3]));
|
|
||||||
|
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp._r.ar[0]));
|
||||||
|
writeToBackLog(1, DSP_REG_AR3, dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp._r.ix[3]));
|
||||||
writeToBackLog(2, DSP_REG_AR0, dsp_increment_addr_reg(DSP_REG_AR0));
|
writeToBackLog(2, DSP_REG_AR0, dsp_increment_addr_reg(DSP_REG_AR0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,14 +248,14 @@ void lsm(const UDSPInstruction opc)
|
||||||
// register $ar3.
|
// register $ar3.
|
||||||
void lsnm(const UDSPInstruction opc)
|
void lsnm(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
u8 sreg = opc & 0x1;
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
|
|
||||||
dsp_dmem_write(g_dsp.r[DSP_REG_AR3], g_dsp.r[sreg]);
|
|
||||||
|
|
||||||
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[DSP_REG_AR0]));
|
dsp_dmem_write(g_dsp._r.ar[3], g_dsp._r.ac[sreg].m);
|
||||||
writeToBackLog(1, DSP_REG_AR3, dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r[DSP_REG_IX3]));
|
|
||||||
writeToBackLog(2, DSP_REG_AR0, dsp_increase_addr_reg(DSP_REG_AR0, (s16)g_dsp.r[DSP_REG_IX0]));
|
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp._r.ar[0]));
|
||||||
|
writeToBackLog(1, DSP_REG_AR3, dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp._r.ix[3]));
|
||||||
|
writeToBackLog(2, DSP_REG_AR0, dsp_increase_addr_reg(DSP_REG_AR0, (s16)g_dsp._r.ix[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// SL $acS.m, $axD.D
|
// SL $acS.m, $axD.D
|
||||||
|
@ -238,12 +265,12 @@ void lsnm(const UDSPInstruction opc)
|
||||||
// $ar3. Increment both $ar0 and $ar3.
|
// $ar3. Increment both $ar0 and $ar3.
|
||||||
void sl(const UDSPInstruction opc)
|
void sl(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
u8 sreg = opc & 0x1;
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
|
|
||||||
dsp_dmem_write(g_dsp.r[DSP_REG_AR0], g_dsp.r[sreg]);
|
|
||||||
|
|
||||||
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[DSP_REG_AR3]));
|
dsp_dmem_write(g_dsp._r.ar[0], g_dsp._r.ac[sreg].m);
|
||||||
|
|
||||||
|
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp._r.ar[3]));
|
||||||
writeToBackLog(1, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3));
|
writeToBackLog(1, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3));
|
||||||
writeToBackLog(2, DSP_REG_AR0, dsp_increment_addr_reg(DSP_REG_AR0));
|
writeToBackLog(2, DSP_REG_AR0, dsp_increment_addr_reg(DSP_REG_AR0));
|
||||||
}
|
}
|
||||||
|
@ -256,14 +283,14 @@ void sl(const UDSPInstruction opc)
|
||||||
// and increment $ar3.
|
// and increment $ar3.
|
||||||
void sln(const UDSPInstruction opc)
|
void sln(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
u8 sreg = opc & 0x1;
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
|
|
||||||
dsp_dmem_write(g_dsp.r[DSP_REG_AR0], g_dsp.r[sreg]);
|
dsp_dmem_write(g_dsp._r.ar[0], g_dsp._r.ac[sreg].m);
|
||||||
|
|
||||||
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[DSP_REG_AR3]));
|
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp._r.ar[3]));
|
||||||
writeToBackLog(1, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3));
|
writeToBackLog(1, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3));
|
||||||
writeToBackLog(2, DSP_REG_AR0, dsp_increase_addr_reg(DSP_REG_AR0, (s16)g_dsp.r[DSP_REG_IX0]));
|
writeToBackLog(2, DSP_REG_AR0, dsp_increase_addr_reg(DSP_REG_AR0, (s16)g_dsp._r.ix[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// SLM $acS.m, $axD.D
|
// SLM $acS.m, $axD.D
|
||||||
|
@ -274,13 +301,13 @@ void sln(const UDSPInstruction opc)
|
||||||
// and increment $ar0.
|
// and increment $ar0.
|
||||||
void slm(const UDSPInstruction opc)
|
void slm(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
u8 sreg = opc & 0x1;
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
|
|
||||||
dsp_dmem_write(g_dsp.r[DSP_REG_AR0], g_dsp.r[sreg]);
|
|
||||||
|
|
||||||
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[DSP_REG_AR3]));
|
dsp_dmem_write(g_dsp._r.ar[0], g_dsp._r.ac[sreg].m);
|
||||||
writeToBackLog(1, DSP_REG_AR3, dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r[DSP_REG_IX3]));
|
|
||||||
|
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp._r.ar[3]));
|
||||||
|
writeToBackLog(1, DSP_REG_AR3, dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp._r.ix[3]));
|
||||||
writeToBackLog(2, DSP_REG_AR0, dsp_increment_addr_reg(DSP_REG_AR0));
|
writeToBackLog(2, DSP_REG_AR0, dsp_increment_addr_reg(DSP_REG_AR0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,14 +319,14 @@ void 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 slnm(const UDSPInstruction opc)
|
void slnm(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
u8 sreg = opc & 0x1;
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
|
|
||||||
dsp_dmem_write(g_dsp.r[DSP_REG_AR0], g_dsp.r[sreg]);
|
|
||||||
|
|
||||||
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp.r[DSP_REG_AR3]));
|
dsp_dmem_write(g_dsp._r.ar[0], g_dsp._r.ac[sreg].m);
|
||||||
writeToBackLog(1, DSP_REG_AR3, dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r[DSP_REG_IX3]));
|
|
||||||
writeToBackLog(2, DSP_REG_AR0, dsp_increase_addr_reg(DSP_REG_AR0, (s16)g_dsp.r[DSP_REG_IX0]));
|
writeToBackLog(0, dreg, dsp_dmem_read(g_dsp._r.ar[3]));
|
||||||
|
writeToBackLog(1, DSP_REG_AR3, dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp._r.ix[3]));
|
||||||
|
writeToBackLog(2, DSP_REG_AR0, dsp_increase_addr_reg(DSP_REG_AR0, (s16)g_dsp._r.ix[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// LD $ax0.d, $ax1.r, @$arS
|
// LD $ax0.d, $ax1.r, @$arS
|
||||||
|
@ -318,21 +345,21 @@ void ld(const UDSPInstruction opc)
|
||||||
u8 sreg = opc & 0x3;
|
u8 sreg = opc & 0x3;
|
||||||
|
|
||||||
if (sreg != DSP_REG_AR3) {
|
if (sreg != DSP_REG_AR3) {
|
||||||
writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[sreg]));
|
writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp._r.ar[sreg]));
|
||||||
|
|
||||||
if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3]))
|
if (IsSameMemArea(g_dsp._r.ar[sreg], g_dsp._r.ar[3]))
|
||||||
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r[sreg]));
|
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp._r.ar[sreg]));
|
||||||
else
|
else
|
||||||
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r[DSP_REG_AR3]));
|
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp._r.ar[3]));
|
||||||
|
|
||||||
writeToBackLog(2, sreg, dsp_increment_addr_reg(sreg));
|
writeToBackLog(2, sreg, dsp_increment_addr_reg(sreg));
|
||||||
} else {
|
} else {
|
||||||
writeToBackLog(0, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp.r[dreg]));
|
writeToBackLog(0, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp._r.ar[dreg]));
|
||||||
|
|
||||||
if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3]))
|
if (IsSameMemArea(g_dsp._r.ar[dreg], g_dsp._r.ar[3]))
|
||||||
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[dreg]));
|
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp._r.ar[dreg]));
|
||||||
else
|
else
|
||||||
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[DSP_REG_AR3]));
|
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp._r.ar[3]));
|
||||||
|
|
||||||
writeToBackLog(2, dreg, dsp_increment_addr_reg(dreg));
|
writeToBackLog(2, dreg, dsp_increment_addr_reg(dreg));
|
||||||
}
|
}
|
||||||
|
@ -347,27 +374,27 @@ void ldn(const UDSPInstruction opc)
|
||||||
u8 dreg = (opc >> 5) & 0x1;
|
u8 dreg = (opc >> 5) & 0x1;
|
||||||
u8 rreg = (opc >> 4) & 0x1;
|
u8 rreg = (opc >> 4) & 0x1;
|
||||||
u8 sreg = opc & 0x3;
|
u8 sreg = opc & 0x3;
|
||||||
|
|
||||||
if (sreg != DSP_REG_AR3) {
|
if (sreg != DSP_REG_AR3) {
|
||||||
writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[sreg]));
|
writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp._r.ar[sreg]));
|
||||||
|
|
||||||
if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3]))
|
if (IsSameMemArea(g_dsp._r.ar[sreg], g_dsp._r.ar[3]))
|
||||||
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r[sreg]));
|
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp._r.ar[sreg]));
|
||||||
else
|
else
|
||||||
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r[DSP_REG_AR3]));
|
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp._r.ar[3]));
|
||||||
|
|
||||||
writeToBackLog(2, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]));
|
writeToBackLog(2, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp._r.ix[sreg]));
|
||||||
} else {
|
} else {
|
||||||
writeToBackLog(0, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp.r[dreg]));
|
writeToBackLog(0, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp._r.ar[dreg]));
|
||||||
|
|
||||||
if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3]))
|
if (IsSameMemArea(g_dsp._r.ar[dreg], g_dsp._r.ar[3]))
|
||||||
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[dreg]));
|
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp._r.ar[dreg]));
|
||||||
else
|
else
|
||||||
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[DSP_REG_AR3]));
|
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp._r.ar[3]));
|
||||||
|
|
||||||
writeToBackLog(2, dreg, dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]));
|
writeToBackLog(2, dreg, dsp_increase_addr_reg(dreg, (s16)g_dsp._r.ix[dreg]));
|
||||||
}
|
}
|
||||||
|
|
||||||
writeToBackLog(3, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3));
|
writeToBackLog(3, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,27 +407,27 @@ void ldm(const UDSPInstruction opc)
|
||||||
u8 sreg = opc & 0x3;
|
u8 sreg = opc & 0x3;
|
||||||
|
|
||||||
if (sreg != DSP_REG_AR3) {
|
if (sreg != DSP_REG_AR3) {
|
||||||
writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[sreg]));
|
writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp._r.ar[sreg]));
|
||||||
|
|
||||||
if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3]))
|
if (IsSameMemArea(g_dsp._r.ar[sreg], g_dsp._r.ar[3]))
|
||||||
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r[sreg]));
|
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp._r.ar[sreg]));
|
||||||
else
|
else
|
||||||
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r[DSP_REG_AR3]));
|
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp._r.ar[3]));
|
||||||
|
|
||||||
writeToBackLog(2, sreg, dsp_increment_addr_reg(sreg));
|
writeToBackLog(2, sreg, dsp_increment_addr_reg(sreg));
|
||||||
} else {
|
} else {
|
||||||
writeToBackLog(0, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp.r[dreg]));
|
writeToBackLog(0, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp._r.ar[dreg]));
|
||||||
|
|
||||||
if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3]))
|
if (IsSameMemArea(g_dsp._r.ar[dreg], g_dsp._r.ar[3]))
|
||||||
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[dreg]));
|
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp._r.ar[dreg]));
|
||||||
else
|
else
|
||||||
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[DSP_REG_AR3]));
|
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp._r.ar[3]));
|
||||||
|
|
||||||
writeToBackLog(2, dreg, dsp_increment_addr_reg(dreg));
|
writeToBackLog(2, dreg, dsp_increment_addr_reg(dreg));
|
||||||
}
|
}
|
||||||
|
|
||||||
writeToBackLog(3, DSP_REG_AR3,
|
writeToBackLog(3, DSP_REG_AR3,
|
||||||
dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r[DSP_REG_IX3]));
|
dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp._r.ix[3]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// LDNM $ax0.d, $ax1.r, @$arS
|
// LDNM $ax0.d, $ax1.r, @$arS
|
||||||
|
@ -412,27 +439,27 @@ void ldnm(const UDSPInstruction opc)
|
||||||
u8 sreg = opc & 0x3;
|
u8 sreg = opc & 0x3;
|
||||||
|
|
||||||
if (sreg != DSP_REG_AR3) {
|
if (sreg != DSP_REG_AR3) {
|
||||||
writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[sreg]));
|
writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp._r.ar[sreg]));
|
||||||
|
|
||||||
if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3]))
|
if (IsSameMemArea(g_dsp._r.ar[sreg], g_dsp._r.ar[3]))
|
||||||
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r[sreg]));
|
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp._r.ar[sreg]));
|
||||||
else
|
else
|
||||||
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r[DSP_REG_AR3]));
|
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp._r.ar[3]));
|
||||||
|
|
||||||
writeToBackLog(2, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]));
|
writeToBackLog(2, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp._r.ix[sreg]));
|
||||||
} else {
|
} else {
|
||||||
writeToBackLog(0, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp.r[dreg]));
|
writeToBackLog(0, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp._r.ar[dreg]));
|
||||||
|
|
||||||
if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3]))
|
if (IsSameMemArea(g_dsp._r.ar[dreg], g_dsp._r.ar[3]))
|
||||||
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[dreg]));
|
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp._r.ar[dreg]));
|
||||||
else
|
else
|
||||||
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r[DSP_REG_AR3]));
|
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp._r.ar[3]));
|
||||||
|
|
||||||
writeToBackLog(2, dreg, dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]));
|
writeToBackLog(2, dreg, dsp_increase_addr_reg(dreg, (s16)g_dsp._r.ix[dreg]));
|
||||||
}
|
}
|
||||||
|
|
||||||
writeToBackLog(3, DSP_REG_AR3,
|
writeToBackLog(3, DSP_REG_AR3,
|
||||||
dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r[DSP_REG_IX3]));
|
dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp._r.ix[3]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -457,7 +484,7 @@ void applyWriteBackLog()
|
||||||
// always make sure to have an extra entry at the end w/ -1 to avoid
|
// always make sure to have an extra entry at the end w/ -1 to avoid
|
||||||
// infinitive loops
|
// infinitive loops
|
||||||
for (int i = 0; writeBackLogIdx[i] != -1; i++) {
|
for (int i = 0; writeBackLogIdx[i] != -1; i++) {
|
||||||
dsp_op_write_reg(writeBackLogIdx[i], g_dsp.r[writeBackLogIdx[i]] | writeBackLog[i]);
|
dsp_op_write_reg(writeBackLogIdx[i], dsp_op_read_reg(writeBackLogIdx[i]) | writeBackLog[i]);
|
||||||
// Clear back log
|
// Clear back log
|
||||||
writeBackLogIdx[i] = -1;
|
writeBackLogIdx[i] = -1;
|
||||||
}
|
}
|
||||||
|
@ -468,7 +495,7 @@ void applyWriteBackLog()
|
||||||
// apply the ext command output, because if the main op didn't change the value
|
// 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
|
// then 0 | ext output = ext output and if it did then bitwise or is still the
|
||||||
// right thing to do
|
// right thing to do
|
||||||
void zeroWriteBackLog()
|
void zeroWriteBackLog()
|
||||||
{
|
{
|
||||||
// always make sure to have an extra entry at the end w/ -1 to avoid
|
// always make sure to have an extra entry at the end w/ -1 to avoid
|
||||||
// infinitive loops
|
// infinitive loops
|
||||||
|
|
|
@ -40,12 +40,12 @@
|
||||||
|
|
||||||
inline void dsp_SR_set_flag(int flag)
|
inline void dsp_SR_set_flag(int flag)
|
||||||
{
|
{
|
||||||
g_dsp.r[DSP_REG_SR] |= flag;
|
g_dsp._r.sr |= flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool dsp_SR_is_flag_set(int flag)
|
inline bool dsp_SR_is_flag_set(int flag)
|
||||||
{
|
{
|
||||||
return (g_dsp.r[DSP_REG_SR] & flag) != 0;
|
return (g_dsp._r.sr & flag) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------
|
||||||
|
@ -63,8 +63,8 @@ inline u16 ToMask(u16 a)
|
||||||
|
|
||||||
inline u16 dsp_increase_addr_reg(u16 reg, s16 ix)
|
inline u16 dsp_increase_addr_reg(u16 reg, s16 ix)
|
||||||
{
|
{
|
||||||
u16 ar = g_dsp.r[reg];
|
u16 ar = g_dsp._r.ar[reg];
|
||||||
u16 wr = g_dsp.r[reg+8];
|
u16 wr = g_dsp._r.wr[reg];
|
||||||
u16 m = ToMask(wr) | 1;
|
u16 m = ToMask(wr) | 1;
|
||||||
u16 nar = ar+ix;
|
u16 nar = ar+ix;
|
||||||
if (ix >= 0) {
|
if (ix >= 0) {
|
||||||
|
@ -79,8 +79,8 @@ inline u16 dsp_increase_addr_reg(u16 reg, s16 ix)
|
||||||
|
|
||||||
inline u16 dsp_decrease_addr_reg(u16 reg, s16 ix)
|
inline u16 dsp_decrease_addr_reg(u16 reg, s16 ix)
|
||||||
{
|
{
|
||||||
u16 ar = g_dsp.r[reg];
|
u16 ar = g_dsp._r.ar[reg];
|
||||||
u16 wr = g_dsp.r[reg+8];
|
u16 wr = g_dsp._r.wr[reg];
|
||||||
u16 m = ToMask(wr) | 1;
|
u16 m = ToMask(wr) | 1;
|
||||||
u16 nar = ar-ix;
|
u16 nar = ar-ix;
|
||||||
if ((u16)ix > 0x8000) { // equiv: ix < 0 && ix != -0x8000
|
if ((u16)ix > 0x8000) { // equiv: ix < 0 && ix != -0x8000
|
||||||
|
@ -115,9 +115,46 @@ inline u16 dsp_op_read_reg(int reg)
|
||||||
case DSP_REG_ST1:
|
case DSP_REG_ST1:
|
||||||
case DSP_REG_ST2:
|
case DSP_REG_ST2:
|
||||||
case DSP_REG_ST3:
|
case DSP_REG_ST3:
|
||||||
return dsp_reg_load_stack(reg - 0x0c);
|
return dsp_reg_load_stack(reg - DSP_REG_ST0);
|
||||||
|
case DSP_REG_AR0:
|
||||||
|
case DSP_REG_AR1:
|
||||||
|
case DSP_REG_AR2:
|
||||||
|
case DSP_REG_AR3:
|
||||||
|
return g_dsp._r.ar[reg - DSP_REG_AR0];
|
||||||
|
case DSP_REG_IX0:
|
||||||
|
case DSP_REG_IX1:
|
||||||
|
case DSP_REG_IX2:
|
||||||
|
case DSP_REG_IX3:
|
||||||
|
return g_dsp._r.ix[reg - DSP_REG_IX0];
|
||||||
|
case DSP_REG_WR0:
|
||||||
|
case DSP_REG_WR1:
|
||||||
|
case DSP_REG_WR2:
|
||||||
|
case DSP_REG_WR3:
|
||||||
|
return g_dsp._r.wr[reg - DSP_REG_WR0];
|
||||||
|
case DSP_REG_ACH0:
|
||||||
|
case DSP_REG_ACH1:
|
||||||
|
return g_dsp._r.ac[reg - DSP_REG_ACH0].h;
|
||||||
|
case DSP_REG_CR: return g_dsp._r.cr;
|
||||||
|
case DSP_REG_SR: return g_dsp._r.sr;
|
||||||
|
case DSP_REG_PRODL: return g_dsp._r.prod.l;
|
||||||
|
case DSP_REG_PRODM: return g_dsp._r.prod.m;
|
||||||
|
case DSP_REG_PRODH: return g_dsp._r.prod.h;
|
||||||
|
case DSP_REG_PRODM2: return g_dsp._r.prod.m2;
|
||||||
|
case DSP_REG_AXL0:
|
||||||
|
case DSP_REG_AXL1:
|
||||||
|
return g_dsp._r.ax[reg - DSP_REG_AXL0].l;
|
||||||
|
case DSP_REG_AXH0:
|
||||||
|
case DSP_REG_AXH1:
|
||||||
|
return g_dsp._r.ax[reg - DSP_REG_AXH0].h;
|
||||||
|
case DSP_REG_ACL0:
|
||||||
|
case DSP_REG_ACL1:
|
||||||
|
return g_dsp._r.ac[reg - DSP_REG_ACL0].l;
|
||||||
|
case DSP_REG_ACM0:
|
||||||
|
case DSP_REG_ACM1:
|
||||||
|
return g_dsp._r.ac[reg - DSP_REG_ACM0].m;
|
||||||
default:
|
default:
|
||||||
return g_dsp.r[reg];
|
_assert_msg_(DSP_INT, 0, "cannot happen");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +165,7 @@ inline void dsp_op_write_reg(int reg, u16 val)
|
||||||
case DSP_REG_ACH0:
|
case DSP_REG_ACH0:
|
||||||
case DSP_REG_ACH1:
|
case DSP_REG_ACH1:
|
||||||
// sign extend from the bottom 8 bits.
|
// sign extend from the bottom 8 bits.
|
||||||
g_dsp.r[reg] = (u16)(s16)(s8)(u8)val;
|
g_dsp._r.ac[reg-DSP_REG_ACH0].h = (u16)(s16)(s8)(u8)val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Stack registers.
|
// Stack registers.
|
||||||
|
@ -136,11 +173,48 @@ inline void dsp_op_write_reg(int reg, u16 val)
|
||||||
case DSP_REG_ST1:
|
case DSP_REG_ST1:
|
||||||
case DSP_REG_ST2:
|
case DSP_REG_ST2:
|
||||||
case DSP_REG_ST3:
|
case DSP_REG_ST3:
|
||||||
dsp_reg_store_stack(reg - 0x0c, val);
|
dsp_reg_store_stack(reg - DSP_REG_ST0, val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case DSP_REG_AR0:
|
||||||
g_dsp.r[reg] = val;
|
case DSP_REG_AR1:
|
||||||
|
case DSP_REG_AR2:
|
||||||
|
case DSP_REG_AR3:
|
||||||
|
g_dsp._r.ar[reg - DSP_REG_AR0] = val;
|
||||||
|
break;
|
||||||
|
case DSP_REG_IX0:
|
||||||
|
case DSP_REG_IX1:
|
||||||
|
case DSP_REG_IX2:
|
||||||
|
case DSP_REG_IX3:
|
||||||
|
g_dsp._r.ix[reg - DSP_REG_IX0] = val;
|
||||||
|
break;
|
||||||
|
case DSP_REG_WR0:
|
||||||
|
case DSP_REG_WR1:
|
||||||
|
case DSP_REG_WR2:
|
||||||
|
case DSP_REG_WR3:
|
||||||
|
g_dsp._r.wr[reg - DSP_REG_WR0] = val;
|
||||||
|
break;
|
||||||
|
case DSP_REG_CR: g_dsp._r.cr = val; break;
|
||||||
|
case DSP_REG_SR: g_dsp._r.sr = val; break;
|
||||||
|
case DSP_REG_PRODL: g_dsp._r.prod.l = val; break;
|
||||||
|
case DSP_REG_PRODM: g_dsp._r.prod.m = val; break;
|
||||||
|
case DSP_REG_PRODH: g_dsp._r.prod.h = val; break;
|
||||||
|
case DSP_REG_PRODM2: g_dsp._r.prod.m2 = val; break;
|
||||||
|
case DSP_REG_AXL0:
|
||||||
|
case DSP_REG_AXL1:
|
||||||
|
g_dsp._r.ax[reg - DSP_REG_AXL0].l = val;
|
||||||
|
break;
|
||||||
|
case DSP_REG_AXH0:
|
||||||
|
case DSP_REG_AXH1:
|
||||||
|
g_dsp._r.ax[reg - DSP_REG_AXH0].h = val;
|
||||||
|
break;
|
||||||
|
case DSP_REG_ACL0:
|
||||||
|
case DSP_REG_ACL1:
|
||||||
|
g_dsp._r.ac[reg - DSP_REG_ACL0].l = val;
|
||||||
|
break;
|
||||||
|
case DSP_REG_ACM0:
|
||||||
|
case DSP_REG_ACM1:
|
||||||
|
g_dsp._r.ac[reg - DSP_REG_ACM0].m = val;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,12 +225,12 @@ inline void dsp_conditional_extend_accum(int reg)
|
||||||
{
|
{
|
||||||
case DSP_REG_ACM0:
|
case DSP_REG_ACM0:
|
||||||
case DSP_REG_ACM1:
|
case DSP_REG_ACM1:
|
||||||
if (g_dsp.r[DSP_REG_SR] & SR_40_MODE_BIT)
|
if (g_dsp._r.sr & SR_40_MODE_BIT)
|
||||||
{
|
{
|
||||||
// Sign extend into whole accum.
|
// Sign extend into whole accum.
|
||||||
u16 val = g_dsp.r[reg];
|
u16 val = g_dsp._r.ac[reg-DSP_REG_ACM0].m;
|
||||||
g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACH0] = (val & 0x8000) ? 0xFFFF : 0x0000;
|
g_dsp._r.ac[reg - DSP_REG_ACM0].h = (val & 0x8000) ? 0xFFFF : 0x0000;
|
||||||
g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACL0] = 0;
|
g_dsp._r.ac[reg - DSP_REG_ACM0].l = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,12 +245,12 @@ inline s64 dsp_get_long_prod()
|
||||||
ProfilerAddDelta(g_dsp.err_pc, 1);
|
ProfilerAddDelta(g_dsp.err_pc, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s64 val = (s8)(u8)g_dsp.r[DSP_REG_PRODH];
|
s64 val = (s8)(u8)g_dsp._r.prod.h;
|
||||||
val <<= 32;
|
val <<= 32;
|
||||||
s64 low_prod = g_dsp.r[DSP_REG_PRODM];
|
s64 low_prod = g_dsp._r.prod.m;
|
||||||
low_prod += g_dsp.r[DSP_REG_PRODM2];
|
low_prod += g_dsp._r.prod.m2;
|
||||||
low_prod <<= 16;
|
low_prod <<= 16;
|
||||||
low_prod |= g_dsp.r[DSP_REG_PRODL];
|
low_prod |= g_dsp._r.prod.l;
|
||||||
val += low_prod;
|
val += low_prod;
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
@ -184,7 +258,7 @@ inline s64 dsp_get_long_prod()
|
||||||
inline s64 dsp_get_long_prod_round_prodl()
|
inline s64 dsp_get_long_prod_round_prodl()
|
||||||
{
|
{
|
||||||
s64 prod = dsp_get_long_prod();
|
s64 prod = dsp_get_long_prod();
|
||||||
|
|
||||||
if (prod & 0x10000)
|
if (prod & 0x10000)
|
||||||
prod = (prod + 0x8000) & ~0xffff;
|
prod = (prod + 0x8000) & ~0xffff;
|
||||||
else
|
else
|
||||||
|
@ -201,12 +275,12 @@ inline void dsp_set_long_prod(s64 val)
|
||||||
ProfilerAddDelta(g_dsp.err_pc, 1);
|
ProfilerAddDelta(g_dsp.err_pc, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
g_dsp.r[DSP_REG_PRODL] = (u16)val;
|
g_dsp._r.prod.l = (u16)val;
|
||||||
val >>= 16;
|
val >>= 16;
|
||||||
g_dsp.r[DSP_REG_PRODM] = (u16)val;
|
g_dsp._r.prod.m = (u16)val;
|
||||||
val >>= 16;
|
val >>= 16;
|
||||||
g_dsp.r[DSP_REG_PRODH] = (u8)val;
|
g_dsp._r.prod.h = /*(s16)(s8)*/(u8)val;//todo: check expansion
|
||||||
g_dsp.r[DSP_REG_PRODM2] = 0;
|
g_dsp._r.prod.m2 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------
|
||||||
|
@ -219,8 +293,8 @@ inline s64 dsp_get_long_acc(int reg)
|
||||||
ProfilerAddDelta(g_dsp.err_pc, 1);
|
ProfilerAddDelta(g_dsp.err_pc, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s64 high = (s64)(s8)g_dsp.r[DSP_REG_ACH0 + reg] << 32;
|
s64 high = (s64)(s8)g_dsp._r.ac[reg].h << 32;
|
||||||
u32 mid_low = ((u32)g_dsp.r[DSP_REG_ACM0 + reg] << 16) | g_dsp.r[DSP_REG_ACL0 + reg];
|
u32 mid_low = ((u32)g_dsp._r.ac[reg].m << 16) | g_dsp._r.ac[reg].l;
|
||||||
return high | mid_low;
|
return high | mid_low;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,11 +304,11 @@ inline void dsp_set_long_acc(int _reg, s64 val)
|
||||||
ProfilerAddDelta(g_dsp.err_pc, 1);
|
ProfilerAddDelta(g_dsp.err_pc, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
g_dsp.r[DSP_REG_ACL0 + _reg] = (u16)val;
|
g_dsp._r.ac[_reg].l = (u16)val;
|
||||||
val >>= 16;
|
val >>= 16;
|
||||||
g_dsp.r[DSP_REG_ACM0 + _reg] = (u16)val;
|
g_dsp._r.ac[_reg].m = (u16)val;
|
||||||
val >>= 16;
|
val >>= 16;
|
||||||
g_dsp.r[DSP_REG_ACH0 + _reg] = (u16)(s16)(s8)(u8)val;
|
g_dsp._r.ac[_reg].h = (u16)(s16)(s8)(u8)val;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline s64 dsp_convert_long_acc(s64 val) // s64 -> s40
|
inline s64 dsp_convert_long_acc(s64 val) // s64 -> s40
|
||||||
|
@ -254,17 +328,17 @@ inline s64 dsp_round_long_acc(s64 val)
|
||||||
|
|
||||||
inline s16 dsp_get_acc_l(int _reg)
|
inline s16 dsp_get_acc_l(int _reg)
|
||||||
{
|
{
|
||||||
return g_dsp.r[DSP_REG_ACL0 + _reg];
|
return g_dsp._r.ac[_reg].l;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline s16 dsp_get_acc_m(int _reg)
|
inline s16 dsp_get_acc_m(int _reg)
|
||||||
{
|
{
|
||||||
return g_dsp.r[DSP_REG_ACM0 + _reg];
|
return g_dsp._r.ac[_reg].m;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline s16 dsp_get_acc_h(int _reg)
|
inline s16 dsp_get_acc_h(int _reg)
|
||||||
{
|
{
|
||||||
return g_dsp.r[DSP_REG_ACH0 + _reg];
|
return g_dsp._r.ac[_reg].h;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------
|
||||||
|
@ -277,17 +351,17 @@ inline s32 dsp_get_long_acx(int _reg)
|
||||||
ProfilerAddDelta(g_dsp.err_pc, 1);
|
ProfilerAddDelta(g_dsp.err_pc, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ((u32)g_dsp.r[DSP_REG_AXH0 + _reg] << 16) | g_dsp.r[DSP_REG_AXL0 + _reg];
|
return ((u32)g_dsp._r.ax[_reg].h << 16) | g_dsp._r.ax[_reg].l;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline s16 dsp_get_ax_l(int _reg)
|
inline s16 dsp_get_ax_l(int _reg)
|
||||||
{
|
{
|
||||||
return (s16)g_dsp.r[DSP_REG_AXL0 + _reg];
|
return (s16)g_dsp._r.ax[_reg].l;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline s16 dsp_get_ax_h(int _reg)
|
inline s16 dsp_get_ax_h(int _reg)
|
||||||
{
|
{
|
||||||
return (s16)g_dsp.r[DSP_REG_AXH0 + _reg];
|
return (s16)g_dsp._r.ax[_reg].h;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -34,12 +34,12 @@ void dsp_reg_stack_push(int stack_reg)
|
||||||
{
|
{
|
||||||
g_dsp.reg_stack_ptr[stack_reg]++;
|
g_dsp.reg_stack_ptr[stack_reg]++;
|
||||||
g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK;
|
g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK;
|
||||||
g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]] = g_dsp.r[DSP_REG_ST0 + stack_reg];
|
g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]] = g_dsp._r.st[stack_reg];
|
||||||
}
|
}
|
||||||
|
|
||||||
void dsp_reg_stack_pop(int stack_reg)
|
void dsp_reg_stack_pop(int stack_reg)
|
||||||
{
|
{
|
||||||
g_dsp.r[DSP_REG_ST0 + stack_reg] = g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]];
|
g_dsp._r.st[stack_reg] = g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]];
|
||||||
g_dsp.reg_stack_ptr[stack_reg]--;
|
g_dsp.reg_stack_ptr[stack_reg]--;
|
||||||
g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK;
|
g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK;
|
||||||
}
|
}
|
||||||
|
@ -47,12 +47,12 @@ void dsp_reg_stack_pop(int stack_reg)
|
||||||
void dsp_reg_store_stack(int stack_reg, u16 val)
|
void dsp_reg_store_stack(int stack_reg, u16 val)
|
||||||
{
|
{
|
||||||
dsp_reg_stack_push(stack_reg);
|
dsp_reg_stack_push(stack_reg);
|
||||||
g_dsp.r[DSP_REG_ST0 + stack_reg] = val;
|
g_dsp._r.st[stack_reg] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 dsp_reg_load_stack(int stack_reg)
|
u16 dsp_reg_load_stack(int stack_reg)
|
||||||
{
|
{
|
||||||
u16 val = g_dsp.r[DSP_REG_ST0 + stack_reg];
|
u16 val = g_dsp._r.st[stack_reg];
|
||||||
dsp_reg_stack_pop(stack_reg);
|
dsp_reg_stack_pop(stack_reg);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,7 +149,7 @@ void cmpar(const UDSPInstruction opc)
|
||||||
u8 sreg = (opc >> 11) & 0x1;
|
u8 sreg = (opc >> 11) & 0x1;
|
||||||
|
|
||||||
s64 sr = dsp_get_long_acc(sreg);
|
s64 sr = dsp_get_long_acc(sreg);
|
||||||
s64 rr = (s16)g_dsp.r[rreg];
|
s64 rr = (s16)g_dsp._r.ax[rreg-DSP_REG_AXH0].h;
|
||||||
rr <<= 16;
|
rr <<= 16;
|
||||||
s64 res = dsp_convert_long_acc(sr - rr);
|
s64 res = dsp_convert_long_acc(sr - rr);
|
||||||
|
|
||||||
|
@ -207,11 +207,11 @@ void xorr(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
u8 sreg = (opc >> 9) & 0x1;
|
u8 sreg = (opc >> 9) & 0x1;
|
||||||
u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] ^ g_dsp.r[DSP_REG_AXH0 + sreg];
|
u16 accm = g_dsp._r.ac[dreg].m ^ g_dsp._r.ax[sreg].h;
|
||||||
|
|
||||||
zeroWriteBackLogPreserveAcc(dreg);
|
zeroWriteBackLogPreserveAcc(dreg);
|
||||||
|
|
||||||
g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
|
g_dsp._r.ac[dreg].m = accm;
|
||||||
Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,11 +226,11 @@ void andr(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
u8 sreg = (opc >> 9) & 0x1;
|
u8 sreg = (opc >> 9) & 0x1;
|
||||||
u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] & g_dsp.r[DSP_REG_AXH0 + sreg];
|
u16 accm = g_dsp._r.ac[dreg].m & g_dsp._r.ax[sreg].h;
|
||||||
|
|
||||||
zeroWriteBackLogPreserveAcc(dreg);
|
zeroWriteBackLogPreserveAcc(dreg);
|
||||||
|
|
||||||
g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
|
g_dsp._r.ac[dreg].m = accm;
|
||||||
Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,11 +245,11 @@ void orr(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
u8 sreg = (opc >> 9) & 0x1;
|
u8 sreg = (opc >> 9) & 0x1;
|
||||||
u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] | g_dsp.r[DSP_REG_AXH0 + sreg];
|
u16 accm = g_dsp._r.ac[dreg].m | g_dsp._r.ax[sreg].h;
|
||||||
|
|
||||||
zeroWriteBackLogPreserveAcc(dreg);
|
zeroWriteBackLogPreserveAcc(dreg);
|
||||||
|
|
||||||
g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
|
g_dsp._r.ac[dreg].m = accm;
|
||||||
Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,11 +263,11 @@ void orr(const UDSPInstruction opc)
|
||||||
void andc(const UDSPInstruction opc)
|
void andc(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] & g_dsp.r[DSP_REG_ACM0 + (1 - dreg)];
|
u16 accm = g_dsp._r.ac[dreg].m & g_dsp._r.ac[1 - dreg].m;
|
||||||
|
|
||||||
zeroWriteBackLogPreserveAcc(dreg);
|
zeroWriteBackLogPreserveAcc(dreg);
|
||||||
|
|
||||||
g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
|
g_dsp._r.ac[dreg].m = accm;
|
||||||
Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,11 +281,11 @@ void andc(const UDSPInstruction opc)
|
||||||
void orc(const UDSPInstruction opc)
|
void orc(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] | g_dsp.r[DSP_REG_ACM0 + (1 - dreg)];
|
u16 accm = g_dsp._r.ac[dreg].m | g_dsp._r.ac[1 - dreg].m;
|
||||||
|
|
||||||
zeroWriteBackLogPreserveAcc(dreg);
|
zeroWriteBackLogPreserveAcc(dreg);
|
||||||
|
|
||||||
g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
|
g_dsp._r.ac[dreg].m = accm;
|
||||||
Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,11 +298,11 @@ void orc(const UDSPInstruction opc)
|
||||||
void xorc(const UDSPInstruction opc)
|
void xorc(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] ^ g_dsp.r[DSP_REG_ACM0 + (1 - dreg)];
|
u16 accm = g_dsp._r.ac[dreg].m ^ g_dsp._r.ac[1 - dreg].m;
|
||||||
|
|
||||||
zeroWriteBackLogPreserveAcc(dreg);
|
zeroWriteBackLogPreserveAcc(dreg);
|
||||||
|
|
||||||
g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
|
g_dsp._r.ac[dreg].m = accm;
|
||||||
Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,11 +315,11 @@ void xorc(const UDSPInstruction opc)
|
||||||
void notc(const UDSPInstruction opc)
|
void notc(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] ^ 0xffff;
|
u16 accm = g_dsp._r.ac[dreg].m ^ 0xffff;
|
||||||
|
|
||||||
zeroWriteBackLogPreserveAcc(dreg);
|
zeroWriteBackLogPreserveAcc(dreg);
|
||||||
|
|
||||||
g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
|
g_dsp._r.ac[dreg].m = accm;
|
||||||
Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,9 +334,9 @@ void xori(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 reg = (opc >> 8) & 0x1;
|
u8 reg = (opc >> 8) & 0x1;
|
||||||
u16 imm = dsp_fetch_code();
|
u16 imm = dsp_fetch_code();
|
||||||
g_dsp.r[DSP_REG_ACM0 + reg] ^= imm;
|
g_dsp._r.ac[reg].m ^= imm;
|
||||||
|
|
||||||
Update_SR_Register16((s16)g_dsp.r[DSP_REG_ACM0 + reg], false, false, isOverS32(dsp_get_long_acc(reg)));
|
Update_SR_Register16((s16)g_dsp._r.ac[reg].m, false, false, isOverS32(dsp_get_long_acc(reg)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANDI $acD.m, #I
|
// ANDI $acD.m, #I
|
||||||
|
@ -349,9 +349,9 @@ void andi(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 reg = (opc >> 8) & 0x1;
|
u8 reg = (opc >> 8) & 0x1;
|
||||||
u16 imm = dsp_fetch_code();
|
u16 imm = dsp_fetch_code();
|
||||||
g_dsp.r[DSP_REG_ACM0 + reg] &= imm;
|
g_dsp._r.ac[reg].m &= imm;
|
||||||
|
|
||||||
Update_SR_Register16((s16)g_dsp.r[DSP_REG_ACM0 + reg], false, false, isOverS32(dsp_get_long_acc(reg)));
|
Update_SR_Register16((s16)g_dsp._r.ac[reg].m, false, false, isOverS32(dsp_get_long_acc(reg)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ORI $acD.m, #I
|
// ORI $acD.m, #I
|
||||||
|
@ -364,9 +364,9 @@ void ori(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 reg = (opc >> 8) & 0x1;
|
u8 reg = (opc >> 8) & 0x1;
|
||||||
u16 imm = dsp_fetch_code();
|
u16 imm = dsp_fetch_code();
|
||||||
g_dsp.r[DSP_REG_ACM0 + reg] |= imm;
|
g_dsp._r.ac[reg].m |= imm;
|
||||||
|
|
||||||
Update_SR_Register16((s16)g_dsp.r[DSP_REG_ACM0 + reg], false, false, isOverS32(dsp_get_long_acc(reg)));
|
Update_SR_Register16((s16)g_dsp._r.ac[reg].m, false, false, isOverS32(dsp_get_long_acc(reg)));
|
||||||
}
|
}
|
||||||
|
|
||||||
//----
|
//----
|
||||||
|
@ -382,7 +382,17 @@ void addr(const UDSPInstruction opc)
|
||||||
u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
|
u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
|
||||||
|
|
||||||
s64 acc = dsp_get_long_acc(dreg);
|
s64 acc = dsp_get_long_acc(dreg);
|
||||||
s64 ax = (s16)g_dsp.r[sreg];
|
s64 ax;
|
||||||
|
switch(sreg) {
|
||||||
|
case DSP_REG_AXL0:
|
||||||
|
case DSP_REG_AXL1:
|
||||||
|
ax = (s16)g_dsp._r.ax[sreg-DSP_REG_AXL0].l;
|
||||||
|
break;
|
||||||
|
case DSP_REG_AXH0:
|
||||||
|
case DSP_REG_AXH1:
|
||||||
|
ax = (s16)g_dsp._r.ax[sreg-DSP_REG_AXH0].h;
|
||||||
|
break;
|
||||||
|
}
|
||||||
ax <<= 16;
|
ax <<= 16;
|
||||||
s64 res = acc + ax;
|
s64 res = acc + ax;
|
||||||
|
|
||||||
|
@ -568,7 +578,17 @@ void subr(const UDSPInstruction opc)
|
||||||
u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
|
u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
|
||||||
|
|
||||||
s64 acc = dsp_get_long_acc(dreg);
|
s64 acc = dsp_get_long_acc(dreg);
|
||||||
s64 ax = (s16)g_dsp.r[sreg];
|
s64 ax;
|
||||||
|
switch(sreg) {
|
||||||
|
case DSP_REG_AXL0:
|
||||||
|
case DSP_REG_AXL1:
|
||||||
|
ax = (s16)g_dsp._r.ax[sreg-DSP_REG_AXL0].l;
|
||||||
|
break;
|
||||||
|
case DSP_REG_AXH0:
|
||||||
|
case DSP_REG_AXH1:
|
||||||
|
ax = (s16)g_dsp._r.ax[sreg-DSP_REG_AXH0].h;
|
||||||
|
break;
|
||||||
|
}
|
||||||
ax <<= 16;
|
ax <<= 16;
|
||||||
s64 res = acc - ax;
|
s64 res = acc - ax;
|
||||||
|
|
||||||
|
@ -732,14 +752,24 @@ void movr(const UDSPInstruction opc)
|
||||||
u8 areg = (opc >> 8) & 0x1;
|
u8 areg = (opc >> 8) & 0x1;
|
||||||
u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
|
u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
|
||||||
|
|
||||||
s64 acc = (s16)g_dsp.r[sreg];
|
s64 ax;
|
||||||
acc <<= 16;
|
switch(sreg) {
|
||||||
acc &= ~0xffff;
|
case DSP_REG_AXL0:
|
||||||
|
case DSP_REG_AXL1:
|
||||||
|
ax = (s16)g_dsp._r.ax[sreg-DSP_REG_AXL0].l;
|
||||||
|
break;
|
||||||
|
case DSP_REG_AXH0:
|
||||||
|
case DSP_REG_AXH1:
|
||||||
|
ax = (s16)g_dsp._r.ax[sreg-DSP_REG_AXH0].h;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ax <<= 16;
|
||||||
|
ax &= ~0xffff;
|
||||||
|
|
||||||
zeroWriteBackLog();
|
zeroWriteBackLog();
|
||||||
|
|
||||||
dsp_set_long_acc(areg, acc);
|
dsp_set_long_acc(areg, ax);
|
||||||
Update_SR_Register64(acc);
|
Update_SR_Register64(ax);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOVAX $acD, $axS
|
// MOVAX $acD, $axS
|
||||||
|
@ -986,7 +1016,7 @@ void lsrnrx(const UDSPInstruction opc)
|
||||||
u8 sreg = (opc >> 9) & 0x1;
|
u8 sreg = (opc >> 9) & 0x1;
|
||||||
|
|
||||||
s16 shift;
|
s16 shift;
|
||||||
u16 axh = g_dsp.r[DSP_REG_AXH0 + sreg];
|
u16 axh = g_dsp._r.ax[sreg].h;
|
||||||
u64 acc = dsp_get_long_acc(dreg);
|
u64 acc = dsp_get_long_acc(dreg);
|
||||||
acc &= 0x000000FFFFFFFFFFULL;
|
acc &= 0x000000FFFFFFFFFFULL;
|
||||||
|
|
||||||
|
@ -1021,7 +1051,7 @@ void asrnrx(const UDSPInstruction opc)
|
||||||
u8 sreg = (opc >> 9) & 0x1;
|
u8 sreg = (opc >> 9) & 0x1;
|
||||||
|
|
||||||
s16 shift;
|
s16 shift;
|
||||||
u16 axh = g_dsp.r[DSP_REG_AXH0 + sreg];
|
u16 axh = g_dsp._r.ax[sreg].h;
|
||||||
s64 acc = dsp_get_long_acc(dreg);
|
s64 acc = dsp_get_long_acc(dreg);
|
||||||
|
|
||||||
if ((axh & 0x3f) == 0)
|
if ((axh & 0x3f) == 0)
|
||||||
|
|
|
@ -123,7 +123,7 @@ void ret(const UDSPInstruction opc)
|
||||||
// location.
|
// location.
|
||||||
void rti(const UDSPInstruction opc)
|
void rti(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
g_dsp.r[DSP_REG_SR] = dsp_reg_load_stack(DSP_STACK_D);
|
g_dsp._r.sr = dsp_reg_load_stack(DSP_STACK_D);
|
||||||
g_dsp.pc = dsp_reg_load_stack(DSP_STACK_C);
|
g_dsp.pc = dsp_reg_load_stack(DSP_STACK_C);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -147,9 +147,9 @@ void halt(const UDSPInstruction opc)
|
||||||
void HandleLoop()
|
void HandleLoop()
|
||||||
{
|
{
|
||||||
// Handle looping hardware.
|
// Handle looping hardware.
|
||||||
const u16 rCallAddress = g_dsp.r[DSP_REG_ST0];
|
const u16 rCallAddress = g_dsp._r.st[0];
|
||||||
const u16 rLoopAddress = g_dsp.r[DSP_REG_ST2];
|
const u16 rLoopAddress = g_dsp._r.st[2];
|
||||||
u16& rLoopCounter = g_dsp.r[DSP_REG_ST3];
|
u16& rLoopCounter = g_dsp._r.st[3];
|
||||||
|
|
||||||
if (rLoopAddress > 0 && rLoopCounter > 0)
|
if (rLoopAddress > 0 && rLoopCounter > 0)
|
||||||
{
|
{
|
||||||
|
@ -184,7 +184,7 @@ void HandleLoop()
|
||||||
void loop(const UDSPInstruction opc)
|
void loop(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u16 reg = opc & 0x1f;
|
u16 reg = opc & 0x1f;
|
||||||
u16 cnt = g_dsp.r[reg];
|
u16 cnt = dsp_op_read_reg(reg);
|
||||||
u16 loop_pc = g_dsp.pc;
|
u16 loop_pc = g_dsp.pc;
|
||||||
|
|
||||||
if (cnt)
|
if (cnt)
|
||||||
|
@ -229,7 +229,7 @@ void loopi(const UDSPInstruction opc)
|
||||||
void bloop(const UDSPInstruction opc)
|
void bloop(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u16 reg = opc & 0x1f;
|
u16 reg = opc & 0x1f;
|
||||||
u16 cnt = g_dsp.r[reg];
|
u16 cnt = dsp_op_read_reg(reg);
|
||||||
u16 loop_pc = dsp_fetch_code();
|
u16 loop_pc = dsp_fetch_code();
|
||||||
|
|
||||||
if (cnt)
|
if (cnt)
|
||||||
|
|
|
@ -33,10 +33,10 @@ namespace DSPInterpreter {
|
||||||
void srs(const UDSPInstruction opc)
|
void srs(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 reg = ((opc >> 8) & 0x7) + 0x18;
|
u8 reg = ((opc >> 8) & 0x7) + 0x18;
|
||||||
u16 addr = (g_dsp.r[DSP_REG_CR] << 8) | (opc & 0xFF);
|
u16 addr = (g_dsp._r.cr << 8) | (opc & 0xFF);
|
||||||
dsp_dmem_write(addr, g_dsp.r[reg]);
|
dsp_dmem_write(addr, dsp_op_read_reg(reg));
|
||||||
}
|
}
|
||||||
|
|
||||||
// LRS $(0x18+D), @M
|
// LRS $(0x18+D), @M
|
||||||
// 0010 0ddd mmmm mmmm
|
// 0010 0ddd mmmm mmmm
|
||||||
// Move value from data memory pointed by address CR[0-7] | M to register
|
// Move value from data memory pointed by address CR[0-7] | M to register
|
||||||
|
@ -45,8 +45,8 @@ void srs(const UDSPInstruction opc)
|
||||||
void lrs(const UDSPInstruction opc)
|
void lrs(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 reg = ((opc >> 8) & 0x7) + 0x18;
|
u8 reg = ((opc >> 8) & 0x7) + 0x18;
|
||||||
u16 addr = (g_dsp.r[DSP_REG_CR] << 8) | (opc & 0xFF);
|
u16 addr = (g_dsp._r.cr << 8) | (opc & 0xFF);
|
||||||
g_dsp.r[reg] = dsp_dmem_read(addr);
|
dsp_op_write_reg(reg, dsp_dmem_read(addr));
|
||||||
dsp_conditional_extend_accum(reg);
|
dsp_conditional_extend_accum(reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ void lrrd(const UDSPInstruction opc)
|
||||||
u16 val = dsp_dmem_read(dsp_op_read_reg(sreg));
|
u16 val = dsp_dmem_read(dsp_op_read_reg(sreg));
|
||||||
dsp_op_write_reg(dreg, val);
|
dsp_op_write_reg(dreg, val);
|
||||||
dsp_conditional_extend_accum(dreg);
|
dsp_conditional_extend_accum(dreg);
|
||||||
g_dsp.r[sreg] = dsp_decrement_addr_reg(sreg);
|
g_dsp._r.ar[sreg] = dsp_decrement_addr_reg(sreg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// LRRI $D, @$S
|
// LRRI $D, @$S
|
||||||
|
@ -132,7 +132,7 @@ void lrri(const UDSPInstruction opc)
|
||||||
u16 val = dsp_dmem_read(dsp_op_read_reg(sreg));
|
u16 val = dsp_dmem_read(dsp_op_read_reg(sreg));
|
||||||
dsp_op_write_reg(dreg, val);
|
dsp_op_write_reg(dreg, val);
|
||||||
dsp_conditional_extend_accum(dreg);
|
dsp_conditional_extend_accum(dreg);
|
||||||
g_dsp.r[sreg] = dsp_increment_addr_reg(sreg);
|
g_dsp._r.ar[sreg] = dsp_increment_addr_reg(sreg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// LRRN $D, @$S
|
// LRRN $D, @$S
|
||||||
|
@ -148,7 +148,7 @@ void lrrn(const UDSPInstruction opc)
|
||||||
u16 val = dsp_dmem_read(dsp_op_read_reg(sreg));
|
u16 val = dsp_dmem_read(dsp_op_read_reg(sreg));
|
||||||
dsp_op_write_reg(dreg, val);
|
dsp_op_write_reg(dreg, val);
|
||||||
dsp_conditional_extend_accum(dreg);
|
dsp_conditional_extend_accum(dreg);
|
||||||
g_dsp.r[sreg] = dsp_increase_addr_reg(sreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]);
|
g_dsp._r.ar[sreg] = dsp_increase_addr_reg(sreg, (s16)g_dsp._r.ix[sreg]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SRR @$D, $S
|
// SRR @$D, $S
|
||||||
|
@ -162,7 +162,7 @@ void srr(const UDSPInstruction opc)
|
||||||
u8 sreg = opc & 0x1f;
|
u8 sreg = opc & 0x1f;
|
||||||
|
|
||||||
u16 val = dsp_op_read_reg(sreg);
|
u16 val = dsp_op_read_reg(sreg);
|
||||||
dsp_dmem_write(g_dsp.r[dreg], val);
|
dsp_dmem_write(g_dsp._r.ar[dreg], val);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SRRD @$D, $S
|
// SRRD @$D, $S
|
||||||
|
@ -176,8 +176,8 @@ void srrd(const UDSPInstruction opc)
|
||||||
u8 sreg = opc & 0x1f;
|
u8 sreg = opc & 0x1f;
|
||||||
|
|
||||||
u16 val = dsp_op_read_reg(sreg);
|
u16 val = dsp_op_read_reg(sreg);
|
||||||
dsp_dmem_write(g_dsp.r[dreg], val);
|
dsp_dmem_write(g_dsp._r.ar[dreg], val);
|
||||||
g_dsp.r[dreg] = dsp_decrement_addr_reg(dreg);
|
g_dsp._r.ar[dreg] = dsp_decrement_addr_reg(dreg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SRRI @$D, $S
|
// SRRI @$D, $S
|
||||||
|
@ -192,8 +192,8 @@ void srri(const UDSPInstruction opc)
|
||||||
|
|
||||||
u16 val = dsp_op_read_reg(sreg);
|
u16 val = dsp_op_read_reg(sreg);
|
||||||
|
|
||||||
dsp_dmem_write(g_dsp.r[dreg], val);
|
dsp_dmem_write(g_dsp._r.ar[dreg], val);
|
||||||
g_dsp.r[dreg] = dsp_increment_addr_reg(dreg);
|
g_dsp._r.ar[dreg] = dsp_increment_addr_reg(dreg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SRRN @$D, $S
|
// SRRN @$D, $S
|
||||||
|
@ -207,8 +207,8 @@ void srrn(const UDSPInstruction opc)
|
||||||
u8 sreg = opc & 0x1f;
|
u8 sreg = opc & 0x1f;
|
||||||
|
|
||||||
u16 val = dsp_op_read_reg(sreg);
|
u16 val = dsp_op_read_reg(sreg);
|
||||||
dsp_dmem_write(g_dsp.r[dreg], val);
|
dsp_dmem_write(g_dsp._r.ar[dreg], val);
|
||||||
g_dsp.r[dreg] = dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + dreg]);
|
g_dsp._r.ar[dreg] = dsp_increase_addr_reg(dreg, (s16)g_dsp._r.ix[dreg]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ILRR $acD.m, @$arS
|
// ILRR $acD.m, @$arS
|
||||||
|
@ -220,7 +220,7 @@ void ilrr(const UDSPInstruction opc)
|
||||||
u16 reg = opc & 0x3;
|
u16 reg = opc & 0x3;
|
||||||
u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1);
|
u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1);
|
||||||
|
|
||||||
g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]);
|
g_dsp._r.ac[dreg-DSP_REG_ACM0].m = dsp_imem_read(g_dsp._r.ar[reg]);
|
||||||
dsp_conditional_extend_accum(dreg);
|
dsp_conditional_extend_accum(dreg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,9 +233,9 @@ void ilrrd(const UDSPInstruction opc)
|
||||||
u16 reg = opc & 0x3;
|
u16 reg = opc & 0x3;
|
||||||
u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1);
|
u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1);
|
||||||
|
|
||||||
g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]);
|
g_dsp._r.ac[dreg-DSP_REG_ACM0].m = dsp_imem_read(g_dsp._r.ar[reg]);
|
||||||
dsp_conditional_extend_accum(dreg);
|
dsp_conditional_extend_accum(dreg);
|
||||||
g_dsp.r[reg] = dsp_decrement_addr_reg(reg);
|
g_dsp._r.ar[reg] = dsp_decrement_addr_reg(reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ILRRI $acD.m, @$S
|
// ILRRI $acD.m, @$S
|
||||||
|
@ -247,9 +247,9 @@ void ilrri(const UDSPInstruction opc)
|
||||||
u16 reg = opc & 0x3;
|
u16 reg = opc & 0x3;
|
||||||
u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1);
|
u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1);
|
||||||
|
|
||||||
g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]);
|
g_dsp._r.ac[dreg-DSP_REG_ACM0].m = dsp_imem_read(g_dsp._r.ar[reg]);
|
||||||
dsp_conditional_extend_accum(dreg);
|
dsp_conditional_extend_accum(dreg);
|
||||||
g_dsp.r[reg] = dsp_increment_addr_reg(reg);
|
g_dsp._r.ar[reg] = dsp_increment_addr_reg(reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ILRRN $acD.m, @$arS
|
// ILRRN $acD.m, @$arS
|
||||||
|
@ -262,9 +262,9 @@ void ilrrn(const UDSPInstruction opc)
|
||||||
u16 reg = opc & 0x3;
|
u16 reg = opc & 0x3;
|
||||||
u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1);
|
u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1);
|
||||||
|
|
||||||
g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]);
|
g_dsp._r.ac[dreg-DSP_REG_ACM0].m = dsp_imem_read(g_dsp._r.ar[reg]);
|
||||||
dsp_conditional_extend_accum(dreg);
|
dsp_conditional_extend_accum(dreg);
|
||||||
g_dsp.r[reg] = dsp_increase_addr_reg(reg, (s16)g_dsp.r[DSP_REG_IX0 + reg]);
|
g_dsp._r.ar[reg] = dsp_increase_addr_reg(reg, (s16)g_dsp._r.ix[reg]);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace DSPInterpreter {
|
||||||
// MRR $D, $S
|
// MRR $D, $S
|
||||||
// 0001 11dd ddds ssss
|
// 0001 11dd ddds ssss
|
||||||
// Move value from register $S to register $D.
|
// Move value from register $S to register $D.
|
||||||
// FIXME: Perform additional operation depending on destination register.
|
// todo: Perform additional operation depending on destination register.
|
||||||
void mrr(const UDSPInstruction opc)
|
void mrr(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 sreg = opc & 0x1f;
|
u8 sreg = opc & 0x1f;
|
||||||
|
@ -86,7 +86,7 @@ void nx(const UDSPInstruction opc)
|
||||||
// Decrement address register $arD.
|
// Decrement address register $arD.
|
||||||
void dar(const UDSPInstruction opc)
|
void dar(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
g_dsp.r[opc & 0x3] = dsp_decrement_addr_reg(opc & 0x3);
|
g_dsp._r.ar[opc & 0x3] = dsp_decrement_addr_reg(opc & 0x3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// IAR $arD
|
// IAR $arD
|
||||||
|
@ -94,7 +94,7 @@ void dar(const UDSPInstruction opc)
|
||||||
// Increment address register $arD.
|
// Increment address register $arD.
|
||||||
void iar(const UDSPInstruction opc)
|
void iar(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
g_dsp.r[opc & 0x3] = dsp_increment_addr_reg(opc & 0x3);
|
g_dsp._r.ar[opc & 0x3] = dsp_increment_addr_reg(opc & 0x3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SUBARN $arD
|
// SUBARN $arD
|
||||||
|
@ -104,7 +104,7 @@ void iar(const UDSPInstruction opc)
|
||||||
void subarn(const UDSPInstruction opc)
|
void 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.ar[dreg] = dsp_decrease_addr_reg(dreg, (s16)g_dsp._r.ix[dreg]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ADDARN $arD, $ixS
|
// ADDARN $arD, $ixS
|
||||||
|
@ -115,7 +115,7 @@ void addarn(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 dreg = opc & 0x3;
|
u8 dreg = opc & 0x3;
|
||||||
u8 sreg = (opc >> 2) & 0x3;
|
u8 sreg = (opc >> 2) & 0x3;
|
||||||
g_dsp.r[dreg] = dsp_increase_addr_reg(dreg, (s16)g_dsp.r[DSP_REG_IX0 + sreg]);
|
g_dsp._r.ar[dreg] = dsp_increase_addr_reg(dreg, (s16)g_dsp._r.ix[sreg]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----
|
//----
|
||||||
|
@ -127,7 +127,7 @@ void addarn(const UDSPInstruction opc)
|
||||||
void sbclr(const UDSPInstruction opc)
|
void sbclr(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 bit = (opc & 0x7) + 6;
|
u8 bit = (opc & 0x7) + 6;
|
||||||
g_dsp.r[DSP_REG_SR] &= ~(1 << bit);
|
g_dsp._r.sr &= ~(1 << bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SBSET #I
|
// SBSET #I
|
||||||
|
@ -137,7 +137,7 @@ void sbclr(const UDSPInstruction opc)
|
||||||
void sbset(const UDSPInstruction opc)
|
void sbset(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 bit = (opc & 0x7) + 6;
|
u8 bit = (opc & 0x7) + 6;
|
||||||
g_dsp.r[DSP_REG_SR] |= (1 << bit);
|
g_dsp._r.sr |= (1 << bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a bunch of flag setters, flipping bits in SR. So far so good,
|
// This is a bunch of flag setters, flipping bits in SR. So far so good,
|
||||||
|
@ -149,29 +149,29 @@ void srbith(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
// 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).
|
||||||
case 0xa: // M2
|
case 0xa: // M2
|
||||||
g_dsp.r[DSP_REG_SR] &= ~SR_MUL_MODIFY;
|
g_dsp._r.sr &= ~SR_MUL_MODIFY;
|
||||||
break;
|
break;
|
||||||
case 0xb: // M0
|
case 0xb: // M0
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_MUL_MODIFY;
|
g_dsp._r.sr |= SR_MUL_MODIFY;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// If set, treat multiplicands as unsigned.
|
// If set, treat multiplicands as unsigned.
|
||||||
// If clear, treat them as signed.
|
// If clear, treat them as signed.
|
||||||
case 0xc: // CLR15
|
case 0xc: // CLR15
|
||||||
g_dsp.r[DSP_REG_SR] &= ~SR_MUL_UNSIGNED;
|
g_dsp._r.sr &= ~SR_MUL_UNSIGNED;
|
||||||
break;
|
break;
|
||||||
case 0xd: // SET15
|
case 0xd: // SET15
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_MUL_UNSIGNED;
|
g_dsp._r.sr |= SR_MUL_UNSIGNED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Automatic 40-bit sign extension when loading ACx.M.
|
// Automatic 40-bit sign extension when loading ACx.M.
|
||||||
// SET40 changes something very important: see the LRI instruction above.
|
// SET40 changes something very important: see the LRI instruction above.
|
||||||
case 0xe: // SET16 (CLR40)
|
case 0xe: // SET16 (CLR40)
|
||||||
g_dsp.r[DSP_REG_SR] &= ~SR_40_MODE_BIT;
|
g_dsp._r.sr &= ~SR_40_MODE_BIT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xf: // SET40
|
case 0xf: // SET40
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_40_MODE_BIT;
|
g_dsp._r.sr |= SR_40_MODE_BIT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -32,15 +32,15 @@ inline s64 dsp_get_multiply_prod(u16 a, u16 b, u8 sign)
|
||||||
{
|
{
|
||||||
s64 prod;
|
s64 prod;
|
||||||
|
|
||||||
if ((sign == 1) && (g_dsp.r[DSP_REG_SR] & SR_MUL_UNSIGNED)) //unsigned
|
if ((sign == 1) && (g_dsp._r.sr & SR_MUL_UNSIGNED)) //unsigned
|
||||||
prod = (u32)(a * b);
|
prod = (u32)(a * b);
|
||||||
else if ((sign == 2) && (g_dsp.r[DSP_REG_SR] & SR_MUL_UNSIGNED)) //mixed
|
else if ((sign == 2) && (g_dsp._r.sr & SR_MUL_UNSIGNED)) //mixed
|
||||||
prod = a * (s16)b;
|
prod = a * (s16)b;
|
||||||
else
|
else
|
||||||
prod = (s16)a * (s16)b; //signed
|
prod = (s16)a * (s16)b; //signed
|
||||||
|
|
||||||
// Conditionally multiply by 2.
|
// Conditionally multiply by 2.
|
||||||
if ((g_dsp.r[DSP_REG_SR] & SR_MUL_MODIFY) == 0)
|
if ((g_dsp._r.sr & SR_MUL_MODIFY) == 0)
|
||||||
prod <<= 1;
|
prod <<= 1;
|
||||||
|
|
||||||
return prod;
|
return prod;
|
||||||
|
@ -95,10 +95,10 @@ void clrp(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
zeroWriteBackLog();
|
zeroWriteBackLog();
|
||||||
|
|
||||||
g_dsp.r[DSP_REG_PRODL] = 0x0000;
|
g_dsp._r.prod.l = 0x0000;
|
||||||
g_dsp.r[DSP_REG_PRODM] = 0xfff0;
|
g_dsp._r.prod.m = 0xfff0;
|
||||||
g_dsp.r[DSP_REG_PRODH] = 0x00ff;
|
g_dsp._r.prod.h = 0x00ff;
|
||||||
g_dsp.r[DSP_REG_PRODM2] = 0x0010;
|
g_dsp._r.prod.m2 = 0x0010;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TSTPROD
|
// TSTPROD
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "../DSPIntUtil.h"
|
#include "../DSPIntUtil.h"
|
||||||
#include "../DSPEmitter.h"
|
#include "../DSPEmitter.h"
|
||||||
#include "../DSPAnalyzer.h"
|
#include "../DSPAnalyzer.h"
|
||||||
|
#include "DSPJitUtil.h"
|
||||||
#include "x64Emitter.h"
|
#include "x64Emitter.h"
|
||||||
#include "ABI.h"
|
#include "ABI.h"
|
||||||
using namespace Gen;
|
using namespace Gen;
|
||||||
|
@ -92,16 +93,17 @@ void DSPEmitter::andcf(const UDSPInstruction opc)
|
||||||
get_acc_m(reg);
|
get_acc_m(reg);
|
||||||
// Update_SR_LZ(((val & imm) == imm) ? true : false);
|
// Update_SR_LZ(((val & imm) == imm) ? true : false);
|
||||||
// if ((val & imm) == imm)
|
// if ((val & imm) == imm)
|
||||||
// g_dsp.r[DSP_REG_SR] |= SR_LOGIC_ZERO;
|
// g_dsp._r.sr |= SR_LOGIC_ZERO;
|
||||||
// else
|
// else
|
||||||
// g_dsp.r[DSP_REG_SR] &= ~SR_LOGIC_ZERO;
|
// g_dsp._r.sr &= ~SR_LOGIC_ZERO;
|
||||||
AND(16, R(RAX), Imm16(imm));
|
AND(16, R(RAX), Imm16(imm));
|
||||||
CMP(16, R(RAX), Imm16(imm));
|
CMP(16, R(RAX), Imm16(imm));
|
||||||
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
FixupBranch notLogicZero = J_CC(CC_NE);
|
FixupBranch notLogicZero = J_CC(CC_NE);
|
||||||
OR(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_LOGIC_ZERO));
|
OR(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(SR_LOGIC_ZERO));
|
||||||
FixupBranch exit = J();
|
FixupBranch exit = J();
|
||||||
SetJumpTarget(notLogicZero);
|
SetJumpTarget(notLogicZero);
|
||||||
AND(16, MDisp(R11, DSP_REG_SR * 2), Imm16(~SR_LOGIC_ZERO));
|
AND(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(~SR_LOGIC_ZERO));
|
||||||
SetJumpTarget(exit);
|
SetJumpTarget(exit);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -129,15 +131,16 @@ void DSPEmitter::andf(const UDSPInstruction opc)
|
||||||
get_acc_m(reg);
|
get_acc_m(reg);
|
||||||
// Update_SR_LZ(((val & imm) == 0) ? true : false);
|
// Update_SR_LZ(((val & imm) == 0) ? true : false);
|
||||||
// if ((val & imm) == 0)
|
// if ((val & imm) == 0)
|
||||||
// g_dsp.r[DSP_REG_SR] |= SR_LOGIC_ZERO;
|
// g_dsp._r.sr |= SR_LOGIC_ZERO;
|
||||||
// else
|
// else
|
||||||
// g_dsp.r[DSP_REG_SR] &= ~SR_LOGIC_ZERO;
|
// g_dsp._r.sr &= ~SR_LOGIC_ZERO;
|
||||||
TEST(16, R(RAX), Imm16(imm));
|
TEST(16, R(RAX), Imm16(imm));
|
||||||
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
FixupBranch notLogicZero = J_CC(CC_NE);
|
FixupBranch notLogicZero = J_CC(CC_NE);
|
||||||
OR(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_LOGIC_ZERO));
|
OR(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(SR_LOGIC_ZERO));
|
||||||
FixupBranch exit = J();
|
FixupBranch exit = J();
|
||||||
SetJumpTarget(notLogicZero);
|
SetJumpTarget(notLogicZero);
|
||||||
AND(16, MDisp(R11, DSP_REG_SR * 2), Imm16(~SR_LOGIC_ZERO));
|
AND(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(~SR_LOGIC_ZERO));
|
||||||
SetJumpTarget(exit);
|
SetJumpTarget(exit);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -234,7 +237,7 @@ void DSPEmitter::cmpar(const UDSPInstruction opc)
|
||||||
// s64 sr = dsp_get_long_acc(sreg);
|
// s64 sr = dsp_get_long_acc(sreg);
|
||||||
get_long_acc(sreg, RCX);
|
get_long_acc(sreg, RCX);
|
||||||
MOV(64, R(RAX), R(RCX));
|
MOV(64, R(RAX), R(RCX));
|
||||||
// s64 rr = (s16)g_dsp.r[rreg];
|
// s64 rr = (s16)g_dsp._r.axh[rreg];
|
||||||
get_ax_h(rreg, RDX);
|
get_ax_h(rreg, RDX);
|
||||||
// rr <<= 16;
|
// rr <<= 16;
|
||||||
SHL(64, R(RDX), Imm8(16));
|
SHL(64, R(RDX), Imm8(16));
|
||||||
|
@ -323,11 +326,11 @@ void DSPEmitter::xorr(const UDSPInstruction opc)
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
u8 sreg = (opc >> 9) & 0x1;
|
u8 sreg = (opc >> 9) & 0x1;
|
||||||
// u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] ^ g_dsp.r[DSP_REG_AXH0 + sreg];
|
// u16 accm = g_dsp._r.acm[dreg] ^ g_dsp._r.axh[sreg];
|
||||||
get_acc_m(dreg, RAX);
|
get_acc_m(dreg, RAX);
|
||||||
get_ax_h(sreg, RDX);
|
get_ax_h(sreg, RDX);
|
||||||
XOR(64, R(RAX), R(RDX));
|
XOR(64, R(RAX), R(RDX));
|
||||||
// g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
|
// g_dsp._r.acm[dreg] = accm;
|
||||||
set_acc_m(dreg);
|
set_acc_m(dreg);
|
||||||
// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
||||||
if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR))
|
if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR))
|
||||||
|
@ -352,11 +355,11 @@ void DSPEmitter::andr(const UDSPInstruction opc)
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
u8 sreg = (opc >> 9) & 0x1;
|
u8 sreg = (opc >> 9) & 0x1;
|
||||||
// u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] & g_dsp.r[DSP_REG_AXH0 + sreg];
|
// u16 accm = g_dsp._r.acm[dreg] & g_dsp._r.axh[sreg];
|
||||||
get_acc_m(dreg, RAX);
|
get_acc_m(dreg, RAX);
|
||||||
get_ax_h(sreg, RDX);
|
get_ax_h(sreg, RDX);
|
||||||
AND(64, R(RAX), R(RDX));
|
AND(64, R(RAX), R(RDX));
|
||||||
// g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
|
// g_dsp._r.acm[dreg] = accm;
|
||||||
set_acc_m(dreg);
|
set_acc_m(dreg);
|
||||||
// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
||||||
if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR))
|
if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR))
|
||||||
|
@ -381,11 +384,11 @@ void DSPEmitter::orr(const UDSPInstruction opc)
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
u8 sreg = (opc >> 9) & 0x1;
|
u8 sreg = (opc >> 9) & 0x1;
|
||||||
// u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] | g_dsp.r[DSP_REG_AXH0 + sreg];
|
// u16 accm = g_dsp._r.acm[dreg] | g_dsp._r.axh[sreg];
|
||||||
get_acc_m(dreg, RAX);
|
get_acc_m(dreg, RAX);
|
||||||
get_ax_h(sreg, RDX);
|
get_ax_h(sreg, RDX);
|
||||||
OR(64, R(RAX), R(RDX));
|
OR(64, R(RAX), R(RDX));
|
||||||
// g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
|
// g_dsp._r.acm[dreg] = accm;
|
||||||
set_acc_m(dreg);
|
set_acc_m(dreg);
|
||||||
// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
||||||
if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR))
|
if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR))
|
||||||
|
@ -409,11 +412,11 @@ void DSPEmitter::andc(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
// u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] & g_dsp.r[DSP_REG_ACM0 + (1 - dreg)];
|
// u16 accm = g_dsp._r.acm[dreg] & g_dsp._r.acm[1 - dreg];
|
||||||
get_acc_m(dreg, RAX);
|
get_acc_m(dreg, RAX);
|
||||||
get_acc_m(1 - dreg, RDX);
|
get_acc_m(1 - dreg, RDX);
|
||||||
AND(64, R(RAX), R(RDX));
|
AND(64, R(RAX), R(RDX));
|
||||||
// g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
|
// g_dsp._r.acm[dreg] = accm;
|
||||||
set_acc_m(dreg);
|
set_acc_m(dreg);
|
||||||
// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
||||||
if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR))
|
if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR))
|
||||||
|
@ -437,11 +440,11 @@ void DSPEmitter::orc(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
// u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] | g_dsp.r[DSP_REG_ACM0 + (1 - dreg)];
|
// u16 accm = g_dsp._r.acm[dreg] | g_dsp._r.acm[1 - dreg];
|
||||||
get_acc_m(dreg, RAX);
|
get_acc_m(dreg, RAX);
|
||||||
get_acc_m(1 - dreg, RDX);
|
get_acc_m(1 - dreg, RDX);
|
||||||
OR(64, R(RAX), R(RDX));
|
OR(64, R(RAX), R(RDX));
|
||||||
// g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
|
// g_dsp._r.acm[dreg] = accm;
|
||||||
set_acc_m(dreg);
|
set_acc_m(dreg);
|
||||||
// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
||||||
if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR))
|
if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR))
|
||||||
|
@ -464,11 +467,11 @@ void DSPEmitter::xorc(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
// u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] ^ g_dsp.r[DSP_REG_ACM0 + (1 - dreg)];
|
// u16 accm = g_dsp._r.acm[dreg] ^ g_dsp._r.acm[1 - dreg];
|
||||||
get_acc_m(dreg, RAX);
|
get_acc_m(dreg, RAX);
|
||||||
get_acc_m(1 - dreg, RDX);
|
get_acc_m(1 - dreg, RDX);
|
||||||
XOR(64, R(RAX), R(RDX));
|
XOR(64, R(RAX), R(RDX));
|
||||||
// g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
|
// g_dsp._r.acm[dreg] = accm;
|
||||||
set_acc_m(dreg);
|
set_acc_m(dreg);
|
||||||
// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
||||||
if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR))
|
if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR))
|
||||||
|
@ -491,10 +494,10 @@ void DSPEmitter::notc(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
// u16 accm = g_dsp.r[DSP_REG_ACM0 + dreg] ^ 0xffff;
|
// u16 accm = g_dsp._r.acm[dreg] ^ 0xffff;
|
||||||
get_acc_m(dreg, RAX);
|
get_acc_m(dreg, RAX);
|
||||||
XOR(16, R(RAX), Imm16(0xffff));
|
XOR(16, R(RAX), Imm16(0xffff));
|
||||||
// g_dsp.r[DSP_REG_ACM0 + dreg] = accm;
|
// g_dsp._r.acm[dreg] = accm;
|
||||||
set_acc_m(dreg);
|
set_acc_m(dreg);
|
||||||
// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
|
||||||
if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR))
|
if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR))
|
||||||
|
@ -520,11 +523,11 @@ void DSPEmitter::xori(const UDSPInstruction opc)
|
||||||
u8 reg = (opc >> 8) & 0x1;
|
u8 reg = (opc >> 8) & 0x1;
|
||||||
// u16 imm = dsp_fetch_code();
|
// u16 imm = dsp_fetch_code();
|
||||||
u16 imm = dsp_imem_read(compilePC+1);
|
u16 imm = dsp_imem_read(compilePC+1);
|
||||||
// g_dsp.r[DSP_REG_ACM0 + reg] ^= imm;
|
// g_dsp._r.acm[reg] ^= imm;
|
||||||
get_acc_m(reg, RAX);
|
get_acc_m(reg, RAX);
|
||||||
XOR(16, R(RAX), Imm16(imm));
|
XOR(16, R(RAX), Imm16(imm));
|
||||||
set_acc_m(reg);
|
set_acc_m(reg);
|
||||||
// Update_SR_Register16((s16)g_dsp.r[DSP_REG_ACM0 + reg], false, false, isOverS32(dsp_get_long_acc(reg)));
|
// Update_SR_Register16((s16)g_dsp._r.acm[reg], false, false, isOverS32(dsp_get_long_acc(reg)));
|
||||||
if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR))
|
if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR))
|
||||||
{
|
{
|
||||||
get_long_acc(reg, RSI);
|
get_long_acc(reg, RSI);
|
||||||
|
@ -547,11 +550,11 @@ void DSPEmitter::andi(const UDSPInstruction opc)
|
||||||
u8 reg = (opc >> 8) & 0x1;
|
u8 reg = (opc >> 8) & 0x1;
|
||||||
// u16 imm = dsp_fetch_code();
|
// u16 imm = dsp_fetch_code();
|
||||||
u16 imm = dsp_imem_read(compilePC+1);
|
u16 imm = dsp_imem_read(compilePC+1);
|
||||||
// g_dsp.r[DSP_REG_ACM0 + reg] &= imm;
|
// g_dsp._r.acm[reg] &= imm;
|
||||||
get_acc_m(reg, RAX);
|
get_acc_m(reg, RAX);
|
||||||
AND(16, R(RAX), Imm16(imm));
|
AND(16, R(RAX), Imm16(imm));
|
||||||
set_acc_m(reg);
|
set_acc_m(reg);
|
||||||
// Update_SR_Register16((s16)g_dsp.r[DSP_REG_ACM0 + reg], false, false, isOverS32(dsp_get_long_acc(reg)));
|
// Update_SR_Register16((s16)g_dsp._r.acm[reg], false, false, isOverS32(dsp_get_long_acc(reg)));
|
||||||
if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR))
|
if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR))
|
||||||
{
|
{
|
||||||
get_long_acc(reg, RSI);
|
get_long_acc(reg, RSI);
|
||||||
|
@ -574,11 +577,11 @@ void DSPEmitter::ori(const UDSPInstruction opc)
|
||||||
u8 reg = (opc >> 8) & 0x1;
|
u8 reg = (opc >> 8) & 0x1;
|
||||||
// u16 imm = dsp_fetch_code();
|
// u16 imm = dsp_fetch_code();
|
||||||
u16 imm = dsp_imem_read(compilePC+1);
|
u16 imm = dsp_imem_read(compilePC+1);
|
||||||
// g_dsp.r[DSP_REG_ACM0 + reg] |= imm;
|
// g_dsp._r.acm[reg] |= imm;
|
||||||
get_acc_m(reg, RAX);
|
get_acc_m(reg, RAX);
|
||||||
OR(16, R(RAX), Imm16(imm));
|
OR(16, R(RAX), Imm16(imm));
|
||||||
set_acc_m(reg);
|
set_acc_m(reg);
|
||||||
// Update_SR_Register16((s16)g_dsp.r[DSP_REG_ACM0 + reg], false, false, isOverS32(dsp_get_long_acc(reg)));
|
// Update_SR_Register16((s16)g_dsp._r.acm[reg], false, false, isOverS32(dsp_get_long_acc(reg)));
|
||||||
if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR))
|
if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR))
|
||||||
{
|
{
|
||||||
get_long_acc(reg, RSI);
|
get_long_acc(reg, RSI);
|
||||||
|
@ -601,13 +604,14 @@ void DSPEmitter::addr(const UDSPInstruction opc)
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
|
u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
|
||||||
|
u16 *sregp = reg_ptr(sreg);
|
||||||
|
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
// s64 acc = dsp_get_long_acc(dreg);
|
// s64 acc = dsp_get_long_acc(dreg);
|
||||||
get_long_acc(dreg, RCX);
|
get_long_acc(dreg, RCX);
|
||||||
MOV(64, R(RAX), R(RCX));
|
MOV(64, R(RAX), R(RCX));
|
||||||
// s64 ax = (s16)g_dsp.r[sreg];
|
// s64 ax = (s16)g_dsp.r[sreg];
|
||||||
MOVSX(64, 16, RDX, MDisp(R11, sreg * 2));
|
MOVSX(64, 16, RDX, MDisp(R11, PtrOffset(sregp,&g_dsp._r)));
|
||||||
// ax <<= 16;
|
// ax <<= 16;
|
||||||
SHL(64, R(RDX), Imm8(16));
|
SHL(64, R(RDX), Imm8(16));
|
||||||
// s64 res = acc + ax;
|
// s64 res = acc + ax;
|
||||||
|
@ -931,13 +935,14 @@ void DSPEmitter::subr(const UDSPInstruction opc)
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
|
u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
|
||||||
|
u16 *sregp = reg_ptr(sreg);
|
||||||
|
|
||||||
// s64 acc = dsp_get_long_acc(dreg);
|
// s64 acc = dsp_get_long_acc(dreg);
|
||||||
get_long_acc(dreg, RCX);
|
get_long_acc(dreg, RCX);
|
||||||
MOV(64, R(RAX), R(RCX));
|
MOV(64, R(RAX), R(RCX));
|
||||||
// s64 ax = (s16)g_dsp.r[sreg];
|
// s64 ax = (s16)g_dsp.r[sreg];
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVSX(64, 16, RDX, MDisp(R11, sreg * 2));
|
MOVSX(64, 16, RDX, MDisp(R11, PtrOffset(sregp,&g_dsp._r)));
|
||||||
// ax <<= 16;
|
// ax <<= 16;
|
||||||
SHL(64, R(RDX), Imm8(16));
|
SHL(64, R(RDX), Imm8(16));
|
||||||
// s64 res = acc - ax;
|
// s64 res = acc - ax;
|
||||||
|
@ -1205,10 +1210,11 @@ void DSPEmitter::movr(const UDSPInstruction opc)
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
u8 areg = (opc >> 8) & 0x1;
|
u8 areg = (opc >> 8) & 0x1;
|
||||||
u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
|
u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
|
||||||
|
u16 *sregp = reg_ptr(sreg);
|
||||||
// s64 acc = (s16)g_dsp.r[sreg];
|
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
// s64 acc = (s16)g_dsp._r[sreg];
|
||||||
MOVSX(64, 16, RAX, MDisp(R11, sreg * 2));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
|
MOVSX(64, 16, RAX, MDisp(R11, PtrOffset(sregp,&g_dsp._r)));
|
||||||
// acc <<= 16;
|
// acc <<= 16;
|
||||||
SHL(64, R(RAX), Imm8(16));
|
SHL(64, R(RAX), Imm8(16));
|
||||||
// acc &= ~0xffff;
|
// acc &= ~0xffff;
|
||||||
|
@ -1612,7 +1618,7 @@ void DSPEmitter::lsrnrx(const UDSPInstruction opc)
|
||||||
u8 sreg = (opc >> 9) & 0x1;
|
u8 sreg = (opc >> 9) & 0x1;
|
||||||
|
|
||||||
// s16 shift;
|
// s16 shift;
|
||||||
// u16 axh = g_dsp.r[DSP_REG_AXH0 + sreg];
|
// u16 axh = g_dsp._r.axh[sreg];
|
||||||
get_ax_h(sreg);
|
get_ax_h(sreg);
|
||||||
// u64 acc = dsp_get_long_acc(dreg);
|
// u64 acc = dsp_get_long_acc(dreg);
|
||||||
get_long_acc(dreg, RDX);
|
get_long_acc(dreg, RDX);
|
||||||
|
@ -1676,7 +1682,7 @@ void DSPEmitter::asrnrx(const UDSPInstruction opc)
|
||||||
u8 sreg = (opc >> 9) & 0x1;
|
u8 sreg = (opc >> 9) & 0x1;
|
||||||
|
|
||||||
// s16 shift;
|
// s16 shift;
|
||||||
// u16 axh = g_dsp.r[DSP_REG_AXH0 + sreg];
|
// u16 axh = g_dsp._r.axh[sreg];
|
||||||
get_ax_h(sreg);
|
get_ax_h(sreg);
|
||||||
// s64 acc = dsp_get_long_acc(dreg);
|
// s64 acc = dsp_get_long_acc(dreg);
|
||||||
get_long_acc(dreg, RDX);
|
get_long_acc(dreg, RDX);
|
||||||
|
|
|
@ -14,9 +14,11 @@
|
||||||
|
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include "../DSPMemoryMap.h"
|
#include "../DSPMemoryMap.h"
|
||||||
#include "../DSPEmitter.h"
|
#include "../DSPEmitter.h"
|
||||||
#include "../DSPStacks.h"
|
#include "../DSPStacks.h"
|
||||||
|
#include "DSPJitUtil.h"
|
||||||
#include "x64Emitter.h"
|
#include "x64Emitter.h"
|
||||||
#include "ABI.h"
|
#include "ABI.h"
|
||||||
|
|
||||||
|
@ -41,9 +43,9 @@ const u8* CheckCondition(DSPEmitter& emitter, u8 cond, u8 skipCodeSize)
|
||||||
//emitter.INT3();
|
//emitter.INT3();
|
||||||
FixupBranch skipCode2;
|
FixupBranch skipCode2;
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
emitter.MOV(16, R(EAX), M(&g_dsp.r[DSP_REG_SR]));
|
emitter.MOV(16, R(EAX), M(&g_dsp._r.sr));
|
||||||
#else
|
#else
|
||||||
emitter.MOV(64, R(RAX), ImmPtr(&g_dsp.r[DSP_REG_SR]));
|
emitter.MOV(64, R(RAX), ImmPtr(&g_dsp._r.sr));
|
||||||
emitter.MOV(16, R(EAX), MatR(RAX));
|
emitter.MOV(16, R(EAX), MatR(RAX));
|
||||||
#endif
|
#endif
|
||||||
switch(cond)
|
switch(cond)
|
||||||
|
@ -66,9 +68,9 @@ const u8* CheckCondition(DSPEmitter& emitter, u8 cond, u8 skipCodeSize)
|
||||||
skipCode2 = emitter.J_CC(CC_NE);
|
skipCode2 = emitter.J_CC(CC_NE);
|
||||||
//skipCode2 = emitter.J_CC((CCFlags)(CC_NE - (cond & 1)));
|
//skipCode2 = emitter.J_CC((CCFlags)(CC_NE - (cond & 1)));
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
emitter.MOV(16, R(EAX), M(&g_dsp.r[DSP_REG_SR]));
|
emitter.MOV(16, R(EAX), M(&g_dsp._r.sr));
|
||||||
#else
|
#else
|
||||||
emitter.MOV(64, R(RAX), ImmPtr(&g_dsp.r[DSP_REG_SR]));
|
emitter.MOV(64, R(RAX), ImmPtr(&g_dsp._r.sr));
|
||||||
emitter.MOV(16, R(EAX), MatR(RAX));
|
emitter.MOV(16, R(EAX), MatR(RAX));
|
||||||
#endif
|
#endif
|
||||||
emitter.TEST(16, R(EAX), Imm16(SR_ARITH_ZERO));
|
emitter.TEST(16, R(EAX), Imm16(SR_ARITH_ZERO));
|
||||||
|
@ -194,13 +196,14 @@ void DSPEmitter::jcc(const UDSPInstruction opc)
|
||||||
void r_jmprcc(const UDSPInstruction opc, DSPEmitter& emitter)
|
void r_jmprcc(const UDSPInstruction opc, DSPEmitter& emitter)
|
||||||
{
|
{
|
||||||
u8 reg = (opc >> 5) & 0x7;
|
u8 reg = (opc >> 5) & 0x7;
|
||||||
|
u16 *regp = reg_ptr(reg);
|
||||||
//reg can only be DSP_REG_ARx and DSP_REG_IXx now,
|
//reg can only be DSP_REG_ARx and DSP_REG_IXx now,
|
||||||
//no need to handle DSP_REG_STx.
|
//no need to handle DSP_REG_STx.
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
emitter.MOV(16, R(EAX), M(&g_dsp.r[reg]));
|
emitter.MOV(16, R(EAX), M(regp));
|
||||||
emitter.MOV(16, M(&g_dsp.pc), R(EAX));
|
emitter.MOV(16, M(&g_dsp.pc), R(EAX));
|
||||||
#else
|
#else
|
||||||
emitter.MOV(64, R(RSI), ImmPtr(&g_dsp.r[reg]));
|
emitter.MOV(64, R(RSI), ImmPtr(regp));
|
||||||
emitter.MOV(16, R(RSI), MatR(RSI));
|
emitter.MOV(16, R(RSI), MatR(RSI));
|
||||||
emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
emitter.MOV(16, MatR(RAX), R(RSI));
|
emitter.MOV(16, MatR(RAX), R(RSI));
|
||||||
|
@ -264,13 +267,14 @@ void DSPEmitter::call(const UDSPInstruction opc)
|
||||||
void r_callr(const UDSPInstruction opc, DSPEmitter& emitter)
|
void r_callr(const UDSPInstruction opc, DSPEmitter& emitter)
|
||||||
{
|
{
|
||||||
u8 reg = (opc >> 5) & 0x7;
|
u8 reg = (opc >> 5) & 0x7;
|
||||||
|
u16 *regp = reg_ptr(reg);
|
||||||
emitter.MOV(16, R(DX), Imm16(emitter.compilePC + 1));
|
emitter.MOV(16, R(DX), Imm16(emitter.compilePC + 1));
|
||||||
emitter.dsp_reg_store_stack(DSP_STACK_C);
|
emitter.dsp_reg_store_stack(DSP_STACK_C);
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
emitter.MOV(16, R(EAX), M(&g_dsp.r[reg]));
|
emitter.MOV(16, R(EAX), M(regp));
|
||||||
emitter.MOV(16, M(&g_dsp.pc), R(EAX));
|
emitter.MOV(16, M(&g_dsp.pc), R(EAX));
|
||||||
#else
|
#else
|
||||||
emitter.MOV(64, R(RSI), ImmPtr(&g_dsp.r[reg]));
|
emitter.MOV(64, R(RSI), ImmPtr(regp));
|
||||||
emitter.MOV(16, R(RSI), MatR(RSI));
|
emitter.MOV(16, R(RSI), MatR(RSI));
|
||||||
emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
emitter.MOV(16, MatR(RAX), R(RSI));
|
emitter.MOV(16, MatR(RAX), R(RSI));
|
||||||
|
@ -355,10 +359,10 @@ void DSPEmitter::rti(const UDSPInstruction opc)
|
||||||
// g_dsp.r[DSP_REG_SR] = dsp_reg_load_stack(DSP_STACK_D);
|
// g_dsp.r[DSP_REG_SR] = dsp_reg_load_stack(DSP_STACK_D);
|
||||||
dsp_reg_load_stack(DSP_STACK_D);
|
dsp_reg_load_stack(DSP_STACK_D);
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, M(&g_dsp.r[DSP_REG_SR]), R(DX));
|
MOV(16, M(&g_dsp._r.sr), R(DX));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11,DSP_REG_SR*2), R(DX));
|
MOV(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, sr)), R(DX));
|
||||||
#endif
|
#endif
|
||||||
// g_dsp.pc = dsp_reg_load_stack(DSP_STACK_C);
|
// g_dsp.pc = dsp_reg_load_stack(DSP_STACK_C);
|
||||||
dsp_reg_load_stack(DSP_STACK_C);
|
dsp_reg_load_stack(DSP_STACK_C);
|
||||||
|
@ -400,12 +404,12 @@ void DSPEmitter::halt(const UDSPInstruction opc)
|
||||||
void DSPEmitter::HandleLoop()
|
void DSPEmitter::HandleLoop()
|
||||||
{
|
{
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, EAX, M(&(g_dsp.r[DSP_REG_ST2])));
|
MOVZX(32, 16, EAX, M(&g_dsp._r.st[2]));
|
||||||
MOVZX(32, 16, ECX, M(&(g_dsp.r[DSP_REG_ST3])));
|
MOVZX(32, 16, ECX, M(&g_dsp._r.st[3]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(32, 16, EAX, MDisp(R11,DSP_REG_ST2*2));
|
MOVZX(32, 16, EAX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, st[2])));
|
||||||
MOVZX(32, 16, ECX, MDisp(R11,DSP_REG_ST3*2));
|
MOVZX(32, 16, ECX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, st[3])));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CMP(32, R(RCX), Imm32(0));
|
CMP(32, R(RCX), Imm32(0));
|
||||||
|
@ -414,19 +418,19 @@ void DSPEmitter::HandleLoop()
|
||||||
FixupBranch rLoopAddrG = J_CC(CC_NE, true);
|
FixupBranch rLoopAddrG = J_CC(CC_NE, true);
|
||||||
|
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
SUB(16, M(&(g_dsp.r[DSP_REG_ST3])), Imm16(1));
|
SUB(16, M(&(g_dsp._r.st[3])), Imm16(1));
|
||||||
CMP(16, M(&(g_dsp.r[DSP_REG_ST3])), Imm16(0));
|
CMP(16, M(&(g_dsp._r.st[3])), Imm16(0));
|
||||||
#else
|
#else
|
||||||
SUB(16, MDisp(R11,DSP_REG_ST3*2), Imm16(1));
|
SUB(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, st[3])), Imm16(1));
|
||||||
CMP(16, MDisp(R11,DSP_REG_ST3*2), Imm16(0));
|
CMP(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, st[3])), Imm16(0));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FixupBranch loadStack = J_CC(CC_LE, true);
|
FixupBranch loadStack = J_CC(CC_LE, true);
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, ECX, M(&(g_dsp.r[DSP_REG_ST0])));
|
MOVZX(32, 16, ECX, M(&(g_dsp._r.st[0])));
|
||||||
MOV(16, M(&g_dsp.pc), R(RCX));
|
MOV(16, M(&g_dsp.pc), R(RCX));
|
||||||
#else
|
#else
|
||||||
MOVZX(32, 16, RCX, MDisp(R11,DSP_REG_ST0*2));
|
MOVZX(32, 16, RCX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, st[0])));
|
||||||
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
MOV(16, MatR(RAX), R(RCX));
|
MOV(16, MatR(RAX), R(RCX));
|
||||||
#endif
|
#endif
|
||||||
|
@ -454,12 +458,13 @@ void DSPEmitter::HandleLoop()
|
||||||
void DSPEmitter::loop(const UDSPInstruction opc)
|
void DSPEmitter::loop(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u16 reg = opc & 0x1f;
|
u16 reg = opc & 0x1f;
|
||||||
|
u16 *regp = reg_ptr(reg);
|
||||||
// u16 cnt = g_dsp.r[reg];
|
// u16 cnt = g_dsp.r[reg];
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, EDX, M(&(g_dsp.r[reg])));
|
MOVZX(32, 16, EDX, M(regp));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(32, 16, EDX, MDisp(R11,reg*2));
|
MOVZX(32, 16, EDX, MDisp(R11,PtrOffset(regp, &g_dsp._r)));
|
||||||
#endif
|
#endif
|
||||||
u16 loop_pc = compilePC + 1;
|
u16 loop_pc = compilePC + 1;
|
||||||
|
|
||||||
|
@ -524,12 +529,13 @@ void DSPEmitter::loopi(const UDSPInstruction opc)
|
||||||
void DSPEmitter::bloop(const UDSPInstruction opc)
|
void DSPEmitter::bloop(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u16 reg = opc & 0x1f;
|
u16 reg = opc & 0x1f;
|
||||||
|
u16* regp = reg_ptr(reg);
|
||||||
// u16 cnt = g_dsp.r[reg];
|
// u16 cnt = g_dsp.r[reg];
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, EDX, M(&(g_dsp.r[reg])));
|
MOVZX(32, 16, EDX, M(regp));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(32, 16, EDX, MDisp(R11,reg*2));
|
MOVZX(32, 16, EDX, MDisp(R11,PtrOffset(regp, &g_dsp._r)));
|
||||||
#endif
|
#endif
|
||||||
u16 loop_pc = dsp_imem_read(compilePC + 1);
|
u16 loop_pc = dsp_imem_read(compilePC + 1);
|
||||||
|
|
||||||
|
|
|
@ -36,14 +36,14 @@ void DSPEmitter::Update_SR_Register(Gen::X64Reg val)
|
||||||
// if (_Value == 0) g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
|
// if (_Value == 0) g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
|
||||||
CMP(64, R(val), Imm8(0));
|
CMP(64, R(val), Imm8(0));
|
||||||
FixupBranch notZero = J_CC(CC_NZ);
|
FixupBranch notZero = J_CC(CC_NZ);
|
||||||
OR(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_ARITH_ZERO));
|
OR(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(SR_ARITH_ZERO));
|
||||||
SetJumpTarget(notZero);
|
SetJumpTarget(notZero);
|
||||||
|
|
||||||
// // 0x08
|
// // 0x08
|
||||||
// if (_Value < 0) g_dsp.r[DSP_REG_SR] |= SR_SIGN;
|
// if (_Value < 0) g_dsp.r[DSP_REG_SR] |= SR_SIGN;
|
||||||
CMP(64, R(val), Imm8(0));
|
CMP(64, R(val), Imm8(0));
|
||||||
FixupBranch greaterThanEqual = J_CC(CC_GE);
|
FixupBranch greaterThanEqual = J_CC(CC_GE);
|
||||||
OR(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_SIGN));
|
OR(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(SR_SIGN));
|
||||||
SetJumpTarget(greaterThanEqual);
|
SetJumpTarget(greaterThanEqual);
|
||||||
|
|
||||||
// // 0x10
|
// // 0x10
|
||||||
|
@ -51,7 +51,7 @@ void DSPEmitter::Update_SR_Register(Gen::X64Reg val)
|
||||||
MOVSX(64, 32, RDX, R(val));
|
MOVSX(64, 32, RDX, R(val));
|
||||||
CMP(64, R(RDX), R(val));
|
CMP(64, R(RDX), R(val));
|
||||||
FixupBranch noOverS32 = J_CC(CC_E);
|
FixupBranch noOverS32 = J_CC(CC_E);
|
||||||
OR(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_OVER_S32));
|
OR(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(SR_OVER_S32));
|
||||||
SetJumpTarget(noOverS32);
|
SetJumpTarget(noOverS32);
|
||||||
|
|
||||||
// // 0x20 - Checks if top bits of m are equal
|
// // 0x20 - Checks if top bits of m are equal
|
||||||
|
@ -63,7 +63,7 @@ void DSPEmitter::Update_SR_Register(Gen::X64Reg val)
|
||||||
FixupBranch cC = J_CC(CC_NE);
|
FixupBranch cC = J_CC(CC_NE);
|
||||||
SetJumpTarget(zeroC);
|
SetJumpTarget(zeroC);
|
||||||
// g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS;
|
// g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS;
|
||||||
OR(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_TOP2BITS));
|
OR(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(SR_TOP2BITS));
|
||||||
SetJumpTarget(cC);
|
SetJumpTarget(cC);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ void DSPEmitter::Update_SR_Register64(Gen::X64Reg val)
|
||||||
{
|
{
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
// g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
|
// g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
|
||||||
AND(16, MDisp(R11, DSP_REG_SR * 2), Imm16(~SR_CMP_MASK));
|
AND(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(~SR_CMP_MASK));
|
||||||
Update_SR_Register(val);
|
Update_SR_Register(val);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ void DSPEmitter::Update_SR_Register64_Carry(Gen::X64Reg val)
|
||||||
{
|
{
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
// g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
|
// g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
|
||||||
AND(16, MDisp(R11, DSP_REG_SR * 2), Imm16(~SR_CMP_MASK));
|
AND(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(~SR_CMP_MASK));
|
||||||
|
|
||||||
CMP(64, R(RCX), R(val));
|
CMP(64, R(RCX), R(val));
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ void DSPEmitter::Update_SR_Register64_Carry(Gen::X64Reg val)
|
||||||
// g_dsp.r[DSP_REG_SR] |= SR_CARRY;
|
// g_dsp.r[DSP_REG_SR] |= SR_CARRY;
|
||||||
// Carry = (acc>res)
|
// Carry = (acc>res)
|
||||||
FixupBranch noCarry = J_CC(CC_BE);
|
FixupBranch noCarry = J_CC(CC_BE);
|
||||||
OR(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_CARRY));
|
OR(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(SR_CARRY));
|
||||||
SetJumpTarget(noCarry);
|
SetJumpTarget(noCarry);
|
||||||
|
|
||||||
// 0x02 and 0x80
|
// 0x02 and 0x80
|
||||||
|
@ -107,7 +107,7 @@ void DSPEmitter::Update_SR_Register64_Carry(Gen::X64Reg val)
|
||||||
AND(64, R(RCX), R(RDX));
|
AND(64, R(RCX), R(RDX));
|
||||||
CMP(64, R(RCX), Imm8(0));
|
CMP(64, R(RCX), Imm8(0));
|
||||||
FixupBranch noOverflow = J_CC(CC_GE);
|
FixupBranch noOverflow = J_CC(CC_GE);
|
||||||
OR(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_OVERFLOW | SR_OVERFLOW_STICKY));
|
OR(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(SR_OVERFLOW | SR_OVERFLOW_STICKY));
|
||||||
SetJumpTarget(noOverflow);
|
SetJumpTarget(noOverflow);
|
||||||
|
|
||||||
Update_SR_Register(val);
|
Update_SR_Register(val);
|
||||||
|
@ -121,7 +121,7 @@ void DSPEmitter::Update_SR_Register64_Carry2(Gen::X64Reg val)
|
||||||
{
|
{
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
// g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
|
// g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
|
||||||
AND(16, MDisp(R11, DSP_REG_SR * 2), Imm16(~SR_CMP_MASK));
|
AND(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(~SR_CMP_MASK));
|
||||||
|
|
||||||
CMP(64, R(RCX), R(val));
|
CMP(64, R(RCX), R(val));
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ void DSPEmitter::Update_SR_Register64_Carry2(Gen::X64Reg val)
|
||||||
// g_dsp.r[DSP_REG_SR] |= SR_CARRY;
|
// g_dsp.r[DSP_REG_SR] |= SR_CARRY;
|
||||||
// Carry2 = (acc>=res)
|
// Carry2 = (acc>=res)
|
||||||
FixupBranch noCarry2 = J_CC(CC_B);
|
FixupBranch noCarry2 = J_CC(CC_B);
|
||||||
OR(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_CARRY));
|
OR(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(SR_CARRY));
|
||||||
SetJumpTarget(noCarry2);
|
SetJumpTarget(noCarry2);
|
||||||
|
|
||||||
// 0x02 and 0x80
|
// 0x02 and 0x80
|
||||||
|
@ -141,7 +141,7 @@ void DSPEmitter::Update_SR_Register64_Carry2(Gen::X64Reg val)
|
||||||
AND(64, R(RCX), R(RDX));
|
AND(64, R(RCX), R(RDX));
|
||||||
CMP(64, R(RCX), Imm8(0));
|
CMP(64, R(RCX), Imm8(0));
|
||||||
FixupBranch noOverflow = J_CC(CC_GE);
|
FixupBranch noOverflow = J_CC(CC_GE);
|
||||||
OR(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_OVERFLOW | SR_OVERFLOW_STICKY));
|
OR(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(SR_OVERFLOW | SR_OVERFLOW_STICKY));
|
||||||
SetJumpTarget(noOverflow);
|
SetJumpTarget(noOverflow);
|
||||||
|
|
||||||
Update_SR_Register();
|
Update_SR_Register();
|
||||||
|
@ -164,20 +164,20 @@ void DSPEmitter::Update_SR_Register64_Carry2(Gen::X64Reg val)
|
||||||
void DSPEmitter::Update_SR_Register16(Gen::X64Reg val)
|
void DSPEmitter::Update_SR_Register16(Gen::X64Reg val)
|
||||||
{
|
{
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
AND(16, MDisp(R11, DSP_REG_SR * 2), Imm16(~SR_CMP_MASK));
|
AND(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(~SR_CMP_MASK));
|
||||||
|
|
||||||
// // 0x04
|
// // 0x04
|
||||||
// if (_Value == 0) g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
|
// if (_Value == 0) g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
|
||||||
CMP(64, R(val), Imm8(0));
|
CMP(64, R(val), Imm8(0));
|
||||||
FixupBranch notZero = J_CC(CC_NZ);
|
FixupBranch notZero = J_CC(CC_NZ);
|
||||||
OR(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_ARITH_ZERO));
|
OR(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(SR_ARITH_ZERO));
|
||||||
SetJumpTarget(notZero);
|
SetJumpTarget(notZero);
|
||||||
|
|
||||||
// // 0x08
|
// // 0x08
|
||||||
// if (_Value < 0) g_dsp.r[DSP_REG_SR] |= SR_SIGN;
|
// if (_Value < 0) g_dsp.r[DSP_REG_SR] |= SR_SIGN;
|
||||||
CMP(64, R(val), Imm8(0));
|
CMP(64, R(val), Imm8(0));
|
||||||
FixupBranch greaterThanEqual = J_CC(CC_GE);
|
FixupBranch greaterThanEqual = J_CC(CC_GE);
|
||||||
OR(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_SIGN));
|
OR(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(SR_SIGN));
|
||||||
SetJumpTarget(greaterThanEqual);
|
SetJumpTarget(greaterThanEqual);
|
||||||
|
|
||||||
// // 0x20 - Checks if top bits of m are equal
|
// // 0x20 - Checks if top bits of m are equal
|
||||||
|
@ -186,13 +186,13 @@ void DSPEmitter::Update_SR_Register16(Gen::X64Reg val)
|
||||||
SHR(16, R(val), Imm8(14));
|
SHR(16, R(val), Imm8(14));
|
||||||
CMP(16, R(val), Imm16(0));
|
CMP(16, R(val), Imm16(0));
|
||||||
FixupBranch nZero = J_CC(CC_NE);
|
FixupBranch nZero = J_CC(CC_NE);
|
||||||
OR(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_TOP2BITS));
|
OR(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(SR_TOP2BITS));
|
||||||
FixupBranch cC = J();
|
FixupBranch cC = J();
|
||||||
SetJumpTarget(nZero);
|
SetJumpTarget(nZero);
|
||||||
CMP(16, R(val), Imm16(3));
|
CMP(16, R(val), Imm16(3));
|
||||||
FixupBranch notThree = J_CC(CC_NE);
|
FixupBranch notThree = J_CC(CC_NE);
|
||||||
// g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS;
|
// g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS;
|
||||||
OR(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_TOP2BITS));
|
OR(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(SR_TOP2BITS));
|
||||||
SetJumpTarget(notThree);
|
SetJumpTarget(notThree);
|
||||||
SetJumpTarget(cC);
|
SetJumpTarget(cC);
|
||||||
#endif
|
#endif
|
||||||
|
@ -204,14 +204,14 @@ void DSPEmitter::Update_SR_Register16(Gen::X64Reg val)
|
||||||
void DSPEmitter::Update_SR_Register16_OverS32(Gen::X64Reg val)
|
void DSPEmitter::Update_SR_Register16_OverS32(Gen::X64Reg val)
|
||||||
{
|
{
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
AND(16, MDisp(R11, DSP_REG_SR * 2), Imm16(~SR_CMP_MASK));
|
AND(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(~SR_CMP_MASK));
|
||||||
|
|
||||||
// // 0x10
|
// // 0x10
|
||||||
// if (_Value != (s32)_Value) g_dsp.r[DSP_REG_SR] |= SR_OVER_S32;
|
// if (_Value != (s32)_Value) g_dsp.r[DSP_REG_SR] |= SR_OVER_S32;
|
||||||
MOVSX(64, 32, RSI, R(val));
|
MOVSX(64, 32, RSI, R(val));
|
||||||
CMP(64, R(RSI), R(val));
|
CMP(64, R(RSI), R(val));
|
||||||
FixupBranch noOverS32 = J_CC(CC_E);
|
FixupBranch noOverS32 = J_CC(CC_E);
|
||||||
OR(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_OVER_S32));
|
OR(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(SR_OVER_S32));
|
||||||
SetJumpTarget(noOverS32);
|
SetJumpTarget(noOverS32);
|
||||||
|
|
||||||
// // 0x20 - Checks if top bits of m are equal
|
// // 0x20 - Checks if top bits of m are equal
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
#include "../DSPMemoryMap.h"
|
#include "../DSPMemoryMap.h"
|
||||||
#include "../DSPEmitter.h"
|
#include "../DSPEmitter.h"
|
||||||
|
#include "DSPJitUtil.h"
|
||||||
#include "x64Emitter.h"
|
#include "x64Emitter.h"
|
||||||
#include "ABI.h"
|
#include "ABI.h"
|
||||||
|
|
||||||
|
@ -68,7 +69,6 @@ void DSPEmitter::mv(const UDSPInstruction opc)
|
||||||
u8 sreg = (opc & 0x3) + DSP_REG_ACL0;
|
u8 sreg = (opc & 0x3) + DSP_REG_ACL0;
|
||||||
u8 dreg = ((opc >> 2) & 0x3);
|
u8 dreg = ((opc >> 2) & 0x3);
|
||||||
pushExtValueFromReg(dreg + DSP_REG_AXL0, sreg);
|
pushExtValueFromReg(dreg + DSP_REG_AXL0, sreg);
|
||||||
// MOV(16, M(&g_dsp.r[dreg + DSP_REG_AXL0]), M(&g_dsp.r[sreg]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// S @$arD, $acS.S
|
// S @$arD, $acS.S
|
||||||
|
@ -79,14 +79,25 @@ void DSPEmitter::s(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 dreg = opc & 0x3;
|
u8 dreg = opc & 0x3;
|
||||||
u8 sreg = ((opc >> 3) & 0x3) + DSP_REG_ACL0;
|
u8 sreg = ((opc >> 3) & 0x3) + DSP_REG_ACL0;
|
||||||
|
u16 *sregp;
|
||||||
|
switch(sreg) {
|
||||||
|
case DSP_REG_ACL0:
|
||||||
|
case DSP_REG_ACL1:
|
||||||
|
sregp = &(g_dsp._r.ac[sreg-DSP_REG_ACL0].l);
|
||||||
|
break;
|
||||||
|
case DSP_REG_ACM0:
|
||||||
|
case DSP_REG_ACM1:
|
||||||
|
sregp = &(g_dsp._r.ac[sreg-DSP_REG_ACM0].m);
|
||||||
|
break;
|
||||||
|
}
|
||||||
// u16 addr = g_dsp.r[dest];
|
// u16 addr = g_dsp.r[dest];
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, EAX, M(&g_dsp.r[dreg]));
|
MOVZX(32, 16, EAX, M(&g_dsp._r.ar[dreg]));
|
||||||
MOVZX(32, 16, ECX, M(&g_dsp.r[sreg]));
|
MOVZX(32, 16, ECX, M(sregp));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(64, 16, EAX, MDisp(R11,dreg*2));
|
MOVZX(64, 16, EAX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[dreg])));
|
||||||
MOVZX(64, 16, ECX, MDisp(R11,sreg*2));
|
MOVZX(64, 16, ECX, MDisp(R11,PtrOffset(sregp, &g_dsp._r)));
|
||||||
#endif
|
#endif
|
||||||
// u16 val = g_dsp.r[src];
|
// u16 val = g_dsp.r[src];
|
||||||
dmem_write();
|
dmem_write();
|
||||||
|
@ -101,13 +112,24 @@ void DSPEmitter::sn(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 dreg = opc & 0x3;
|
u8 dreg = opc & 0x3;
|
||||||
u8 sreg = ((opc >> 3) & 0x3) + DSP_REG_ACL0;
|
u8 sreg = ((opc >> 3) & 0x3) + DSP_REG_ACL0;
|
||||||
|
u16 *sregp;
|
||||||
|
switch(sreg) {
|
||||||
|
case DSP_REG_ACL0:
|
||||||
|
case DSP_REG_ACL1:
|
||||||
|
sregp = &(g_dsp._r.ac[sreg-DSP_REG_ACL0].l);
|
||||||
|
break;
|
||||||
|
case DSP_REG_ACM0:
|
||||||
|
case DSP_REG_ACM1:
|
||||||
|
sregp = &(g_dsp._r.ac[sreg-DSP_REG_ACM0].m);
|
||||||
|
break;
|
||||||
|
}
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, EAX, M(&g_dsp.r[dreg]));
|
MOVZX(32, 16, EAX, M(&g_dsp._r.ar[dreg]));
|
||||||
MOVZX(32, 16, ECX, M(&g_dsp.r[sreg]));
|
MOVZX(32, 16, ECX, M(sregp));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(64, 16, EAX, MDisp(R11,dreg*2));
|
MOVZX(64, 16, EAX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[dreg])));
|
||||||
MOVZX(64, 16, ECX, MDisp(R11,sreg*2));
|
MOVZX(64, 16, ECX, MDisp(R11,PtrOffset(sregp,&g_dsp._r)));
|
||||||
#endif
|
#endif
|
||||||
dmem_write();
|
dmem_write();
|
||||||
increase_addr_reg(dreg);
|
increase_addr_reg(dreg);
|
||||||
|
@ -130,10 +152,10 @@ void DSPEmitter::l(const UDSPInstruction opc)
|
||||||
//store (up to) two registers in EBX,
|
//store (up to) two registers in EBX,
|
||||||
//so store all of SR
|
//so store all of SR
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, R(EAX), M(&g_dsp.r[DSP_REG_SR]));
|
MOV(16, R(EAX), M(&g_dsp._r.sr));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r.sr));
|
||||||
MOV(16, R(EAX), MDisp(R11,DSP_REG_SR*2));
|
MOV(16, R(EAX), MatR(R11));
|
||||||
#endif
|
#endif
|
||||||
SHL(32, R(EAX), Imm8(16));
|
SHL(32, R(EAX), Imm8(16));
|
||||||
OR(32, R(EBX), R(EAX));
|
OR(32, R(EBX), R(EAX));
|
||||||
|
@ -159,10 +181,10 @@ void DSPEmitter::ln(const UDSPInstruction opc)
|
||||||
//store (up to) two registers in EBX,
|
//store (up to) two registers in EBX,
|
||||||
//so store all of SR
|
//so store all of SR
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, R(EAX), M(&g_dsp.r[DSP_REG_SR]));
|
MOV(16, R(EAX), M(&g_dsp._r.sr));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r.sr));
|
||||||
MOV(16, R(EAX), MDisp(R11,DSP_REG_SR*2));
|
MOV(16, R(EAX), MatR(R11));
|
||||||
#endif
|
#endif
|
||||||
SHL(32, R(EAX), Imm8(16));
|
SHL(32, R(EAX), Imm8(16));
|
||||||
OR(32, R(EBX), R(EAX));
|
OR(32, R(EBX), R(EAX));
|
||||||
|
@ -178,15 +200,15 @@ void DSPEmitter::ln(const UDSPInstruction opc)
|
||||||
// register $ar3. Increment both $ar0 and $ar3.
|
// register $ar3. Increment both $ar0 and $ar3.
|
||||||
void DSPEmitter::ls(const UDSPInstruction opc)
|
void DSPEmitter::ls(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
u8 sreg = opc & 0x1;
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, EAX, M(&g_dsp.r[DSP_REG_AR3]));
|
MOVZX(32, 16, EAX, M(&g_dsp._r.ar[3]));
|
||||||
MOVZX(32, 16, ECX, M(&g_dsp.r[sreg]));
|
MOVZX(32, 16, ECX, M(&g_dsp._r.ac[sreg].m));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(64, 16, EAX, MDisp(R11,DSP_REG_AR3*2));
|
MOVZX(64, 16, EAX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[3])));
|
||||||
MOVZX(64, 16, ECX, MDisp(R11,sreg*2));
|
MOVZX(64, 16, ECX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ac[sreg].m)));
|
||||||
#endif
|
#endif
|
||||||
dmem_write();
|
dmem_write();
|
||||||
|
|
||||||
|
@ -205,15 +227,15 @@ void DSPEmitter::ls(const UDSPInstruction opc)
|
||||||
// register $ar0 and increment $ar3.
|
// register $ar0 and increment $ar3.
|
||||||
void DSPEmitter::lsn(const UDSPInstruction opc)
|
void DSPEmitter::lsn(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
u8 sreg = opc & 0x1;
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, EAX, M(&g_dsp.r[DSP_REG_AR3]));
|
MOVZX(32, 16, EAX, M(&g_dsp._r.ar[3]));
|
||||||
MOVZX(32, 16, ECX, M(&g_dsp.r[sreg]));
|
MOVZX(32, 16, ECX, M(&g_dsp._r.ac[sreg].m));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(64, 16, EAX, MDisp(R11,DSP_REG_AR3*2));
|
MOVZX(64, 16, EAX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[3])));
|
||||||
MOVZX(64, 16, ECX, MDisp(R11,sreg*2));
|
MOVZX(64, 16, ECX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ac[sreg].m)));
|
||||||
#endif
|
#endif
|
||||||
dmem_write();
|
dmem_write();
|
||||||
|
|
||||||
|
@ -231,15 +253,15 @@ void DSPEmitter::lsn(const UDSPInstruction opc)
|
||||||
// register $ar3 and increment $ar0.
|
// register $ar3 and increment $ar0.
|
||||||
void DSPEmitter::lsm(const UDSPInstruction opc)
|
void DSPEmitter::lsm(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
u8 sreg = opc & 0x1;
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, EAX, M(&g_dsp.r[DSP_REG_AR3]));
|
MOVZX(32, 16, EAX, M(&g_dsp._r.ar[3]));
|
||||||
MOVZX(32, 16, ECX, M(&g_dsp.r[sreg]));
|
MOVZX(32, 16, ECX, M(&g_dsp._r.ac[sreg].m));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(64, 16, EAX, MDisp(R11,DSP_REG_AR3*2));
|
MOVZX(64, 16, EAX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[3])));
|
||||||
MOVZX(64, 16, ECX, MDisp(R11,sreg*2));
|
MOVZX(64, 16, ECX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ac[sreg].m)));
|
||||||
#endif
|
#endif
|
||||||
dmem_write();
|
dmem_write();
|
||||||
|
|
||||||
|
@ -258,15 +280,15 @@ void DSPEmitter::lsm(const UDSPInstruction opc)
|
||||||
// register $ar3.
|
// register $ar3.
|
||||||
void DSPEmitter::lsnm(const UDSPInstruction opc)
|
void DSPEmitter::lsnm(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
u8 sreg = opc & 0x1;
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, EAX, M(&g_dsp.r[DSP_REG_AR3]));
|
MOVZX(32, 16, EAX, M(&g_dsp._r.ar[3]));
|
||||||
MOVZX(32, 16, ECX, M(&g_dsp.r[sreg]));
|
MOVZX(32, 16, ECX, M(&g_dsp._r.ac[sreg].m));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(64, 16, EAX, MDisp(R11,DSP_REG_AR3*2));
|
MOVZX(64, 16, EAX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[3])));
|
||||||
MOVZX(64, 16, ECX, MDisp(R11,sreg*2));
|
MOVZX(64, 16, ECX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ac[sreg].m)));
|
||||||
#endif
|
#endif
|
||||||
dmem_write();
|
dmem_write();
|
||||||
|
|
||||||
|
@ -283,15 +305,15 @@ void DSPEmitter::lsnm(const UDSPInstruction opc)
|
||||||
// $ar3. Increment both $ar0 and $ar3.
|
// $ar3. Increment both $ar0 and $ar3.
|
||||||
void DSPEmitter::sl(const UDSPInstruction opc)
|
void DSPEmitter::sl(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
u8 sreg = opc & 0x1;
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, EAX, M(&g_dsp.r[DSP_REG_AR0]));
|
MOVZX(32, 16, EAX, M(&g_dsp._r.ar[0]));
|
||||||
MOVZX(32, 16, ECX, M(&g_dsp.r[sreg]));
|
MOVZX(32, 16, ECX, M(&g_dsp._r.ac[sreg].m));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(64, 16, EAX, MDisp(R11,DSP_REG_AR0*2));
|
MOVZX(64, 16, EAX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[0])));
|
||||||
MOVZX(64, 16, ECX, MDisp(R11,sreg*2));
|
MOVZX(64, 16, ECX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ac[sreg].m)));
|
||||||
#endif
|
#endif
|
||||||
dmem_write();
|
dmem_write();
|
||||||
|
|
||||||
|
@ -309,15 +331,15 @@ void DSPEmitter::sl(const UDSPInstruction opc)
|
||||||
// and increment $ar3.
|
// and increment $ar3.
|
||||||
void DSPEmitter::sln(const UDSPInstruction opc)
|
void DSPEmitter::sln(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
u8 sreg = opc & 0x1;
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, EAX, M(&g_dsp.r[DSP_REG_AR0]));
|
MOVZX(32, 16, EAX, M(&g_dsp._r.ar[0]));
|
||||||
MOVZX(32, 16, ECX, M(&g_dsp.r[sreg]));
|
MOVZX(32, 16, ECX, M(&g_dsp._r.ac[sreg].m));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(64, 16, EAX, MDisp(R11,DSP_REG_AR0*2));
|
MOVZX(64, 16, EAX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[0])));
|
||||||
MOVZX(64, 16, ECX, MDisp(R11,sreg*2));
|
MOVZX(64, 16, ECX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ac[sreg].m)));
|
||||||
#endif
|
#endif
|
||||||
dmem_write();
|
dmem_write();
|
||||||
|
|
||||||
|
@ -335,15 +357,15 @@ void DSPEmitter::sln(const UDSPInstruction opc)
|
||||||
// and increment $ar0.
|
// and increment $ar0.
|
||||||
void DSPEmitter::slm(const UDSPInstruction opc)
|
void DSPEmitter::slm(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
u8 sreg = opc & 0x1;
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, EAX, M(&g_dsp.r[DSP_REG_AR0]));
|
MOVZX(32, 16, EAX, M(&g_dsp._r.ar[0]));
|
||||||
MOVZX(32, 16, ECX, M(&g_dsp.r[sreg]));
|
MOVZX(32, 16, ECX, M(&g_dsp._r.ac[sreg].m));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(64, 16, EAX, MDisp(R11,DSP_REG_AR0*2));
|
MOVZX(64, 16, EAX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[0])));
|
||||||
MOVZX(64, 16, ECX, MDisp(R11,sreg*2));
|
MOVZX(64, 16, ECX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ac[sreg].m)));
|
||||||
#endif
|
#endif
|
||||||
dmem_write();
|
dmem_write();
|
||||||
|
|
||||||
|
@ -361,15 +383,15 @@ void DSPEmitter::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 DSPEmitter::slnm(const UDSPInstruction opc)
|
void DSPEmitter::slnm(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 sreg = (opc & 0x1) + DSP_REG_ACM0;
|
u8 sreg = opc & 0x1;
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, EAX, M(&g_dsp.r[DSP_REG_AR0]));
|
MOVZX(32, 16, EAX, M(&g_dsp._r.ar[0]));
|
||||||
MOVZX(32, 16, ECX, M(&g_dsp.r[sreg]));
|
MOVZX(32, 16, ECX, M(&g_dsp._r.ac[sreg].m));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(64, 16, EAX, MDisp(R11,DSP_REG_AR0*2));
|
MOVZX(64, 16, EAX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[0])));
|
||||||
MOVZX(64, 16, ECX, MDisp(R11,sreg*2));
|
MOVZX(64, 16, ECX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ac[sreg].m)));
|
||||||
#endif
|
#endif
|
||||||
dmem_write();
|
dmem_write();
|
||||||
|
|
||||||
|
@ -400,12 +422,12 @@ void DSPEmitter::ld(const UDSPInstruction opc)
|
||||||
|
|
||||||
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, R(ESI), M(&g_dsp.r[sreg]));
|
MOV(16, R(ESI), M(&g_dsp._r.ar[sreg]));
|
||||||
MOV(16, R(EDI), M(&g_dsp.r[DSP_REG_AR3]));
|
MOV(16, R(EDI), M(&g_dsp._r.ar[3]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, R(ESI), MDisp(R11,sreg*2));
|
MOV(16, R(ESI), MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[sreg])));
|
||||||
MOV(16, R(EDI), MDisp(R11,DSP_REG_AR3*2));
|
MOV(16, R(EDI), MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[3])));
|
||||||
#endif
|
#endif
|
||||||
SHR(16, R(ESI), Imm8(10));
|
SHR(16, R(ESI), Imm8(10));
|
||||||
SHR(16, R(EDI), Imm8(10));
|
SHR(16, R(EDI), Imm8(10));
|
||||||
|
@ -424,12 +446,12 @@ void DSPEmitter::ld(const UDSPInstruction opc)
|
||||||
|
|
||||||
//if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3])) {
|
//if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3])) {
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, R(ESI), M(&g_dsp.r[dreg]));
|
MOV(16, R(ESI), M(&g_dsp._r.ar[dreg]));
|
||||||
MOV(16, R(EDI), M(&g_dsp.r[DSP_REG_AR3]));
|
MOV(16, R(EDI), M(&g_dsp._r.ar[3]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, R(ESI), MDisp(R11,dreg*2));
|
MOV(16, R(ESI), MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[dreg])));
|
||||||
MOV(16, R(EDI), MDisp(R11,DSP_REG_AR3*2));
|
MOV(16, R(EDI), MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[3])));
|
||||||
#endif
|
#endif
|
||||||
SHR(16, R(ESI), Imm8(10));
|
SHR(16, R(ESI), Imm8(10));
|
||||||
SHR(16, R(EDI), Imm8(10));
|
SHR(16, R(EDI), Imm8(10));
|
||||||
|
@ -460,12 +482,12 @@ void DSPEmitter::ldn(const UDSPInstruction opc)
|
||||||
|
|
||||||
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, R(ESI), M(&g_dsp.r[sreg]));
|
MOV(16, R(ESI), M(&g_dsp._r.ar[sreg]));
|
||||||
MOV(16, R(EDI), M(&g_dsp.r[DSP_REG_AR3]));
|
MOV(16, R(EDI), M(&g_dsp._r.ar[3]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, R(ESI), MDisp(R11,sreg*2));
|
MOV(16, R(ESI), MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[sreg])));
|
||||||
MOV(16, R(EDI), MDisp(R11,DSP_REG_AR3*2));
|
MOV(16, R(EDI), MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[3])));
|
||||||
#endif
|
#endif
|
||||||
SHR(16, R(ESI), Imm8(10));
|
SHR(16, R(ESI), Imm8(10));
|
||||||
SHR(16, R(EDI), Imm8(10));
|
SHR(16, R(EDI), Imm8(10));
|
||||||
|
@ -483,12 +505,12 @@ void DSPEmitter::ldn(const UDSPInstruction opc)
|
||||||
|
|
||||||
//if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3])) {
|
//if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3])) {
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, R(ESI), M(&g_dsp.r[dreg]));
|
MOV(16, R(ESI), M(&g_dsp._r.ar[dreg]));
|
||||||
MOV(16, R(EDI), M(&g_dsp.r[DSP_REG_AR3]));
|
MOV(16, R(EDI), M(&g_dsp._r.ar[3]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, R(ESI), MDisp(R11,dreg*2));
|
MOV(16, R(ESI), MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[dreg])));
|
||||||
MOV(16, R(EDI), MDisp(R11,DSP_REG_AR3*2));
|
MOV(16, R(EDI), MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[3])));
|
||||||
#endif
|
#endif
|
||||||
SHR(16, R(ESI), Imm8(10));
|
SHR(16, R(ESI), Imm8(10));
|
||||||
SHR(16, R(EDI), Imm8(10));
|
SHR(16, R(EDI), Imm8(10));
|
||||||
|
@ -519,12 +541,12 @@ void DSPEmitter::ldm(const UDSPInstruction opc)
|
||||||
|
|
||||||
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, R(ESI), M(&g_dsp.r[sreg]));
|
MOV(16, R(ESI), M(&g_dsp._r.ar[sreg]));
|
||||||
MOV(16, R(EDI), M(&g_dsp.r[DSP_REG_AR3]));
|
MOV(16, R(EDI), M(&g_dsp._r.ar[3]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, R(ESI), MDisp(R11,sreg*2));
|
MOV(16, R(ESI), MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[sreg])));
|
||||||
MOV(16, R(EDI), MDisp(R11,DSP_REG_AR3*2));
|
MOV(16, R(EDI), MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[3])));
|
||||||
#endif
|
#endif
|
||||||
SHR(16, R(ESI), Imm8(10));
|
SHR(16, R(ESI), Imm8(10));
|
||||||
SHR(16, R(EDI), Imm8(10));
|
SHR(16, R(EDI), Imm8(10));
|
||||||
|
@ -542,12 +564,12 @@ void DSPEmitter::ldm(const UDSPInstruction opc)
|
||||||
|
|
||||||
//if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3])) {
|
//if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3])) {
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, R(ESI), M(&g_dsp.r[dreg]));
|
MOV(16, R(ESI), M(&g_dsp._r.ar[dreg]));
|
||||||
MOV(16, R(EDI), M(&g_dsp.r[DSP_REG_AR3]));
|
MOV(16, R(EDI), M(&g_dsp._r.ar[3]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, R(ESI), MDisp(R11,dreg*2));
|
MOV(16, R(ESI), MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[dreg])));
|
||||||
MOV(16, R(EDI), MDisp(R11,DSP_REG_AR3*2));
|
MOV(16, R(EDI), MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[3])));
|
||||||
#endif
|
#endif
|
||||||
SHR(16, R(ESI), Imm8(10));
|
SHR(16, R(ESI), Imm8(10));
|
||||||
SHR(16, R(EDI), Imm8(10));
|
SHR(16, R(EDI), Imm8(10));
|
||||||
|
@ -578,12 +600,12 @@ void DSPEmitter::ldnm(const UDSPInstruction opc)
|
||||||
|
|
||||||
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, R(ESI), M(&g_dsp.r[sreg]));
|
MOV(16, R(ESI), M(&g_dsp._r.ar[sreg]));
|
||||||
MOV(16, R(EDI), M(&g_dsp.r[DSP_REG_AR3]));
|
MOV(16, R(EDI), M(&g_dsp._r.ar[3]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, R(ESI), MDisp(R11,sreg*2));
|
MOV(16, R(ESI), MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[sreg])));
|
||||||
MOV(16, R(EDI), MDisp(R11,DSP_REG_AR3*2));
|
MOV(16, R(EDI), MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[3])));
|
||||||
#endif
|
#endif
|
||||||
SHR(16, R(ESI), Imm8(10));
|
SHR(16, R(ESI), Imm8(10));
|
||||||
SHR(16, R(EDI), Imm8(10));
|
SHR(16, R(EDI), Imm8(10));
|
||||||
|
@ -601,12 +623,12 @@ void DSPEmitter::ldnm(const UDSPInstruction opc)
|
||||||
|
|
||||||
//if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3])) {
|
//if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3])) {
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, R(ESI), M(&g_dsp.r[dreg]));
|
MOV(16, R(ESI), M(&g_dsp._r.ar[dreg]));
|
||||||
MOV(16, R(EDI), M(&g_dsp.r[DSP_REG_AR3]));
|
MOV(16, R(EDI), M(&g_dsp._r.ar[3]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, R(ESI), MDisp(R11,dreg*2));
|
MOV(16, R(ESI), MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[dreg])));
|
||||||
MOV(16, R(EDI), MDisp(R11,DSP_REG_AR3*2));
|
MOV(16, R(EDI), MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[3])));
|
||||||
#endif
|
#endif
|
||||||
SHR(16, R(ESI), Imm8(10));
|
SHR(16, R(ESI), Imm8(10));
|
||||||
SHR(16, R(EDI), Imm8(10));
|
SHR(16, R(EDI), Imm8(10));
|
||||||
|
@ -628,11 +650,12 @@ void DSPEmitter::ldnm(const UDSPInstruction opc)
|
||||||
// Push value from g_dsp.r[sreg] into EBX and stores the destinationindex in
|
// Push value from g_dsp.r[sreg] into EBX and stores the destinationindex in
|
||||||
// storeIndex
|
// storeIndex
|
||||||
void DSPEmitter::pushExtValueFromReg(u16 dreg, u16 sreg) {
|
void DSPEmitter::pushExtValueFromReg(u16 dreg, u16 sreg) {
|
||||||
|
u16 *sregp = reg_ptr(sreg);
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, EBX, M(&g_dsp.r[sreg]));
|
MOVZX(32, 16, EBX, M(sregp));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(RBX), ImmPtr(&g_dsp.r));
|
MOV(64, R(RBX), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(32, 16, EBX, MDisp(RBX,sreg*2));
|
MOVZX(32, 16, EBX, MDisp(RBX,PtrOffset(sregp,&g_dsp._r)));
|
||||||
#endif
|
#endif
|
||||||
storeIndex = dreg;
|
storeIndex = dreg;
|
||||||
}
|
}
|
||||||
|
@ -640,10 +663,10 @@ void DSPEmitter::pushExtValueFromReg(u16 dreg, u16 sreg) {
|
||||||
void DSPEmitter::pushExtValueFromMem(u16 dreg, u16 sreg) {
|
void DSPEmitter::pushExtValueFromMem(u16 dreg, u16 sreg) {
|
||||||
// u16 addr = g_dsp.r[addr];
|
// u16 addr = g_dsp.r[addr];
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, ECX, M(&g_dsp.r[sreg]));
|
MOVZX(32, 16, ECX, M(&g_dsp._r.ar[sreg]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(64, 16, ECX, MDisp(R11,sreg*2));
|
MOVZX(64, 16, ECX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[sreg])));
|
||||||
#endif
|
#endif
|
||||||
dmem_read();
|
dmem_read();
|
||||||
MOVZX(32, 16, EBX, R(EAX));
|
MOVZX(32, 16, EBX, R(EAX));
|
||||||
|
@ -654,10 +677,10 @@ void DSPEmitter::pushExtValueFromMem(u16 dreg, u16 sreg) {
|
||||||
void DSPEmitter::pushExtValueFromMem2(u16 dreg, u16 sreg) {
|
void DSPEmitter::pushExtValueFromMem2(u16 dreg, u16 sreg) {
|
||||||
// u16 addr = g_dsp.r[addr];
|
// u16 addr = g_dsp.r[addr];
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, ECX, M(&g_dsp.r[sreg]));
|
MOVZX(32, 16, ECX, M(&g_dsp._r.ar[sreg]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(64, 16, ECX, MDisp(R11,sreg*2));
|
MOVZX(64, 16, ECX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[sreg])));
|
||||||
#endif
|
#endif
|
||||||
dmem_read();
|
dmem_read();
|
||||||
SHL(32,R(EAX),Imm8(16));
|
SHL(32,R(EAX),Imm8(16));
|
||||||
|
@ -675,11 +698,12 @@ void DSPEmitter::popExtValueToReg() {
|
||||||
// [nakeee] the or case never happens in real
|
// [nakeee] the or case never happens in real
|
||||||
// [nakeee] it's just how the hardware works so we added it
|
// [nakeee] it's just how the hardware works so we added it
|
||||||
if (storeIndex != -1) {
|
if (storeIndex != -1) {
|
||||||
|
u16 *dregp = reg_ptr(storeIndex);
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, M(&g_dsp.r[storeIndex]), R(EBX));
|
MOV(16, M(dregp), R(EBX));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11,storeIndex*2), R(EBX));
|
MOV(16, MDisp(R11,PtrOffset(dregp,&g_dsp._r)), R(EBX));
|
||||||
#endif
|
#endif
|
||||||
if (storeIndex >= DSP_REG_ACM0 && storeIndex2 == -1) {
|
if (storeIndex >= DSP_REG_ACM0 && storeIndex2 == -1) {
|
||||||
TEST(32, R(EBX), Imm32(SR_40_MODE_BIT << 16));
|
TEST(32, R(EBX), Imm32(SR_40_MODE_BIT << 16));
|
||||||
|
@ -693,13 +717,13 @@ void DSPEmitter::popExtValueToReg() {
|
||||||
//g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACH0] = (val & 0x8000) ? 0xFFFF : 0x0000;
|
//g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACH0] = (val & 0x8000) ? 0xFFFF : 0x0000;
|
||||||
//g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACL0] = 0;
|
//g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACL0] = 0;
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16,M(&g_dsp.r[storeIndex - DSP_REG_ACM0 + DSP_REG_ACH0]),
|
MOV(16,M(&g_dsp._r.ac[storeIndex - DSP_REG_ACM0].h),
|
||||||
R(EAX));
|
R(EAX));
|
||||||
MOV(16,M(&g_dsp.r[storeIndex - DSP_REG_ACM0 + DSP_REG_ACL0]),
|
MOV(16,M(&g_dsp._r.ac[storeIndex - DSP_REG_ACM0].l),
|
||||||
Imm16(0));
|
Imm16(0));
|
||||||
#else
|
#else
|
||||||
MOV(16, MDisp(R11,(storeIndex - DSP_REG_ACM0 + DSP_REG_ACH0)*2), R(EAX));
|
MOV(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ac[storeIndex - DSP_REG_ACM0].h)), R(EAX));
|
||||||
MOV(16, MDisp(R11,(storeIndex - DSP_REG_ACM0 + DSP_REG_ACL0)*2), Imm16(0));
|
MOV(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ac[storeIndex - DSP_REG_ACM0].l)), Imm16(0));
|
||||||
#endif
|
#endif
|
||||||
//}
|
//}
|
||||||
SetJumpTarget(not_40bit);
|
SetJumpTarget(not_40bit);
|
||||||
|
@ -710,11 +734,12 @@ void DSPEmitter::popExtValueToReg() {
|
||||||
|
|
||||||
if (storeIndex2 != -1) {
|
if (storeIndex2 != -1) {
|
||||||
SHR(32,R(EBX),Imm8(16));
|
SHR(32,R(EBX),Imm8(16));
|
||||||
|
u16 *dregp = reg_ptr(storeIndex2);
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, M(&g_dsp.r[storeIndex2]), R(EBX));
|
MOV(16, M(dregp), R(EBX));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11,storeIndex2*2), R(EBX));
|
MOV(16, MDisp(R11,PtrOffset(dregp, &g_dsp._r)), R(EBX));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
storeIndex2 = -1;
|
storeIndex2 = -1;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "../DSPIntCCUtil.h"
|
#include "../DSPIntCCUtil.h"
|
||||||
#include "../DSPIntUtil.h"
|
#include "../DSPIntUtil.h"
|
||||||
#include "../DSPEmitter.h"
|
#include "../DSPEmitter.h"
|
||||||
|
#include "DSPJitUtil.h"
|
||||||
#include "x64Emitter.h"
|
#include "x64Emitter.h"
|
||||||
#include "ABI.h"
|
#include "ABI.h"
|
||||||
using namespace Gen;
|
using namespace Gen;
|
||||||
|
@ -33,14 +34,15 @@ using namespace Gen;
|
||||||
void DSPEmitter::srs(const UDSPInstruction opc)
|
void DSPEmitter::srs(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 reg = ((opc >> 8) & 0x7) + 0x18;
|
u8 reg = ((opc >> 8) & 0x7) + 0x18;
|
||||||
//u16 addr = (g_dsp.r[DSP_REG_CR] << 8) | (opc & 0xFF);
|
u16 *regp = reg_ptr(reg);
|
||||||
|
//u16 addr = (g_dsp._r.cr << 8) | (opc & 0xFF);
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, ECX, M(&g_dsp.r[reg]));
|
MOVZX(32, 16, ECX, M(regp));
|
||||||
MOVZX(32, 8, EAX, M(&g_dsp.r[DSP_REG_CR]));
|
MOVZX(32, 8, EAX, M(&g_dsp._r.cr));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(64, 16, RCX, MDisp(R11,reg*2));
|
MOVZX(64, 16, RCX, MDisp(R11,PtrOffset(regp,&g_dsp._r)));
|
||||||
MOVZX(64, 8, RAX, MDisp(R11,DSP_REG_CR*2));
|
MOVZX(64, 8, RAX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, cr)));
|
||||||
#endif
|
#endif
|
||||||
SHL(16, R(EAX), Imm8(8));
|
SHL(16, R(EAX), Imm8(8));
|
||||||
OR(8, R(EAX), Imm8(opc & 0xFF));
|
OR(8, R(EAX), Imm8(opc & 0xFF));
|
||||||
|
@ -55,21 +57,22 @@ void DSPEmitter::srs(const UDSPInstruction opc)
|
||||||
void DSPEmitter::lrs(const UDSPInstruction opc)
|
void DSPEmitter::lrs(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 reg = ((opc >> 8) & 0x7) + 0x18;
|
u8 reg = ((opc >> 8) & 0x7) + 0x18;
|
||||||
|
u16 *regp = reg_ptr(reg);
|
||||||
//u16 addr = (g_dsp.r[DSP_REG_CR] << 8) | (opc & 0xFF);
|
//u16 addr = (g_dsp.r[DSP_REG_CR] << 8) | (opc & 0xFF);
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 8, ECX, M(&g_dsp.r[DSP_REG_CR]));
|
MOVZX(32, 8, ECX, M(&g_dsp._r.cr));
|
||||||
SHL(16, R(ECX), Imm8(8));
|
SHL(16, R(ECX), Imm8(8));
|
||||||
OR(8, R(ECX), Imm8(opc & 0xFF));
|
OR(8, R(ECX), Imm8(opc & 0xFF));
|
||||||
dmem_read();
|
dmem_read();
|
||||||
MOV(16, M(&g_dsp.r[reg]), R(EAX));
|
MOV(16, M(regp), R(EAX));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(64, 8, RCX, MDisp(R11,DSP_REG_CR*2));
|
MOVZX(64, 8, RCX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, cr)));
|
||||||
SHL(16, R(ECX), Imm8(8));
|
SHL(16, R(ECX), Imm8(8));
|
||||||
OR(8, R(ECX), Imm8(opc & 0xFF));
|
OR(8, R(ECX), Imm8(opc & 0xFF));
|
||||||
dmem_read();
|
dmem_read();
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11,reg*2), R(RAX));
|
MOV(16, MDisp(R11,PtrOffset(regp, &g_dsp._r)), R(RAX));
|
||||||
#endif
|
#endif
|
||||||
dsp_conditional_extend_accum(reg);
|
dsp_conditional_extend_accum(reg);
|
||||||
}
|
}
|
||||||
|
@ -192,10 +195,10 @@ void DSPEmitter::srr(const UDSPInstruction opc)
|
||||||
|
|
||||||
dsp_op_read_reg(sreg, ECX);
|
dsp_op_read_reg(sreg, ECX);
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, EAX, M(&g_dsp.r[dreg]));
|
MOVZX(32, 16, EAX, M(&g_dsp._r.ar[dreg]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(64, 16, RAX, MDisp(R11,dreg*2));
|
MOVZX(64, 16, RAX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[dreg])));
|
||||||
#endif
|
#endif
|
||||||
dmem_write();
|
dmem_write();
|
||||||
}
|
}
|
||||||
|
@ -212,10 +215,10 @@ void DSPEmitter::srrd(const UDSPInstruction opc)
|
||||||
|
|
||||||
dsp_op_read_reg(sreg, ECX);
|
dsp_op_read_reg(sreg, ECX);
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, EAX, M(&g_dsp.r[dreg]));
|
MOVZX(32, 16, EAX, M(&g_dsp._r.ar[dreg]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(64, 16, RAX, MDisp(R11,dreg*2));
|
MOVZX(64, 16, RAX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[dreg])));
|
||||||
#endif
|
#endif
|
||||||
dmem_write();
|
dmem_write();
|
||||||
decrement_addr_reg(dreg);
|
decrement_addr_reg(dreg);
|
||||||
|
@ -233,10 +236,10 @@ void DSPEmitter::srri(const UDSPInstruction opc)
|
||||||
|
|
||||||
dsp_op_read_reg(sreg, ECX);
|
dsp_op_read_reg(sreg, ECX);
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, EAX, M(&g_dsp.r[dreg]));
|
MOVZX(32, 16, EAX, M(&g_dsp._r.ar[dreg]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(64, 16, RAX, MDisp(R11,dreg*2));
|
MOVZX(64, 16, RAX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[dreg])));
|
||||||
#endif
|
#endif
|
||||||
dmem_write();
|
dmem_write();
|
||||||
increment_addr_reg(dreg);
|
increment_addr_reg(dreg);
|
||||||
|
@ -254,10 +257,10 @@ void DSPEmitter::srrn(const UDSPInstruction opc)
|
||||||
|
|
||||||
dsp_op_read_reg(sreg, ECX);
|
dsp_op_read_reg(sreg, ECX);
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, EAX, M(&g_dsp.r[dreg]));
|
MOVZX(32, 16, EAX, M(&g_dsp._r.ar[dreg]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(64, 16, RAX, MDisp(R11,dreg*2));
|
MOVZX(64, 16, RAX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[dreg])));
|
||||||
#endif
|
#endif
|
||||||
dmem_write();
|
dmem_write();
|
||||||
increase_addr_reg(dreg);
|
increase_addr_reg(dreg);
|
||||||
|
@ -270,20 +273,20 @@ void DSPEmitter::srrn(const UDSPInstruction opc)
|
||||||
void DSPEmitter::ilrr(const UDSPInstruction opc)
|
void DSPEmitter::ilrr(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u16 reg = opc & 0x3;
|
u16 reg = opc & 0x3;
|
||||||
u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1);
|
u16 dreg = (opc >> 8) & 1;
|
||||||
|
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, ECX, M(&g_dsp.r[reg]));
|
MOVZX(32, 16, ECX, M(&g_dsp._r.ar[reg]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(64, 16, RCX, MDisp(R11,reg*2));
|
MOVZX(64, 16, RCX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[reg])));
|
||||||
#endif
|
#endif
|
||||||
imem_read();
|
imem_read();
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, M(&g_dsp.r[dreg]), R(EAX));
|
MOV(16, M(&g_dsp._r.ac[dreg].m), R(EAX));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11,dreg*2), R(RAX));
|
MOV(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ac[dreg].m)), R(RAX));
|
||||||
#endif
|
#endif
|
||||||
dsp_conditional_extend_accum(dreg);
|
dsp_conditional_extend_accum(dreg);
|
||||||
}
|
}
|
||||||
|
@ -295,20 +298,20 @@ void DSPEmitter::ilrr(const UDSPInstruction opc)
|
||||||
void DSPEmitter::ilrrd(const UDSPInstruction opc)
|
void DSPEmitter::ilrrd(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u16 reg = opc & 0x3;
|
u16 reg = opc & 0x3;
|
||||||
u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1);
|
u16 dreg = (opc >> 8) & 1;
|
||||||
|
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, ECX, M(&g_dsp.r[reg]));
|
MOVZX(32, 16, ECX, M(&g_dsp._r.ar[reg]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(64, 16, RCX, MDisp(R11,reg*2));
|
MOVZX(64, 16, RCX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[reg])));
|
||||||
#endif
|
#endif
|
||||||
imem_read();
|
imem_read();
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, M(&g_dsp.r[dreg]), R(EAX));
|
MOV(16, M(&g_dsp._r.ac[dreg].m), R(EAX));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11,dreg*2), R(RAX));
|
MOV(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ac[dreg].m)), R(RAX));
|
||||||
#endif
|
#endif
|
||||||
dsp_conditional_extend_accum(dreg);
|
dsp_conditional_extend_accum(dreg);
|
||||||
decrement_addr_reg(reg);
|
decrement_addr_reg(reg);
|
||||||
|
@ -321,20 +324,20 @@ void DSPEmitter::ilrrd(const UDSPInstruction opc)
|
||||||
void DSPEmitter::ilrri(const UDSPInstruction opc)
|
void DSPEmitter::ilrri(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u16 reg = opc & 0x3;
|
u16 reg = opc & 0x3;
|
||||||
u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1);
|
u16 dreg = (opc >> 8) & 1;
|
||||||
|
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, ECX, M(&g_dsp.r[reg]));
|
MOVZX(32, 16, ECX, M(&g_dsp._r.ar[reg]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(64, 16, RCX, MDisp(R11,reg*2));
|
MOVZX(64, 16, RCX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[reg])));
|
||||||
#endif
|
#endif
|
||||||
imem_read();
|
imem_read();
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, M(&g_dsp.r[dreg]), R(EAX));
|
MOV(16, M(&g_dsp._r.ac[dreg].m), R(EAX));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11,dreg*2), R(RAX));
|
MOV(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ac[dreg].m)), R(RAX));
|
||||||
#endif
|
#endif
|
||||||
dsp_conditional_extend_accum(dreg);
|
dsp_conditional_extend_accum(dreg);
|
||||||
increment_addr_reg(reg);
|
increment_addr_reg(reg);
|
||||||
|
@ -348,20 +351,20 @@ void DSPEmitter::ilrri(const UDSPInstruction opc)
|
||||||
void DSPEmitter::ilrrn(const UDSPInstruction opc)
|
void DSPEmitter::ilrrn(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u16 reg = opc & 0x3;
|
u16 reg = opc & 0x3;
|
||||||
u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1);
|
u16 dreg = (opc >> 8) & 1;
|
||||||
|
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 16, ECX, M(&g_dsp.r[reg]));
|
MOVZX(32, 16, ECX, M(&g_dsp._r.ar[reg]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVZX(64, 16, RCX, MDisp(R11,reg*2));
|
MOVZX(64, 16, RCX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[reg])));
|
||||||
#endif
|
#endif
|
||||||
imem_read();
|
imem_read();
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, M(&g_dsp.r[dreg]), R(EAX));
|
MOV(16, M(&g_dsp._r.ac[dreg].m), R(EAX));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11,dreg*2), R(RAX));
|
MOV(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ac[dreg].m)), R(RAX));
|
||||||
#endif
|
#endif
|
||||||
dsp_conditional_extend_accum(dreg);
|
dsp_conditional_extend_accum(dreg);
|
||||||
increase_addr_reg(reg);
|
increase_addr_reg(reg);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include "../DSPIntUtil.h"
|
#include "../DSPIntUtil.h"
|
||||||
#include "../DSPEmitter.h"
|
#include "../DSPEmitter.h"
|
||||||
|
#include "DSPJitUtil.h"
|
||||||
#include "x64Emitter.h"
|
#include "x64Emitter.h"
|
||||||
#include "ABI.h"
|
#include "ABI.h"
|
||||||
using namespace Gen;
|
using namespace Gen;
|
||||||
|
@ -47,12 +48,12 @@ void DSPEmitter::dsp_reg_stack_push(int stack_reg)
|
||||||
|
|
||||||
//g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]] = g_dsp.r[DSP_REG_ST0 + stack_reg];
|
//g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]] = g_dsp.r[DSP_REG_ST0 + stack_reg];
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, R(CX), M(&g_dsp.r[DSP_REG_ST0 + stack_reg]));
|
MOV(16, R(CX), M(&g_dsp._r.st[stack_reg]));
|
||||||
MOVZX(32, 8, EAX, R(AL));
|
MOVZX(32, 8, EAX, R(AL));
|
||||||
MOV(16, MComplex(EAX,EAX,1,(u32)&g_dsp.reg_stack[stack_reg][0]), R(CX));
|
MOV(16, MComplex(EAX,EAX,1,(u32)&g_dsp.reg_stack[stack_reg][0]), R(CX));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, R(CX), MDisp(R11,(DSP_REG_ST0 + stack_reg)*2));
|
MOV(16, R(CX), MDisp(R11,STRUCT_OFFSET(g_dsp._r, st[stack_reg])));
|
||||||
MOVZX(64, 8, RAX, R(AL));
|
MOVZX(64, 8, RAX, R(AL));
|
||||||
MOV(64, R(R10), ImmPtr(&g_dsp.reg_stack[stack_reg][0]));
|
MOV(64, R(R10), ImmPtr(&g_dsp.reg_stack[stack_reg][0]));
|
||||||
MOV(16, MComplex(R10,RAX,2,0), R(CX));
|
MOV(16, MComplex(R10,RAX,2,0), R(CX));
|
||||||
|
@ -76,13 +77,13 @@ void DSPEmitter::dsp_reg_stack_pop(int stack_reg)
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVZX(32, 8, EAX, R(AL));
|
MOVZX(32, 8, EAX, R(AL));
|
||||||
MOV(16, R(CX), MComplex(EAX,EAX,1,(u32)&g_dsp.reg_stack[stack_reg][0]));
|
MOV(16, R(CX), MComplex(EAX,EAX,1,(u32)&g_dsp.reg_stack[stack_reg][0]));
|
||||||
MOV(16, M(&g_dsp.r[DSP_REG_ST0 + stack_reg]), R(CX));
|
MOV(16, M(&g_dsp._r.st[stack_reg]), R(CX));
|
||||||
#else
|
#else
|
||||||
MOVZX(64, 8, RAX, R(AL));
|
MOVZX(64, 8, RAX, R(AL));
|
||||||
MOV(64, R(R10), ImmPtr(&g_dsp.reg_stack[stack_reg][0]));
|
MOV(64, R(R10), ImmPtr(&g_dsp.reg_stack[stack_reg][0]));
|
||||||
MOV(16, R(CX), MComplex(R10,RAX,2,0));
|
MOV(16, R(CX), MComplex(R10,RAX,2,0));
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11,(DSP_REG_ST0 + stack_reg)*2), R(CX));
|
MOV(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, st[stack_reg])), R(CX));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//g_dsp.reg_stack_ptr[stack_reg]--;
|
//g_dsp.reg_stack_ptr[stack_reg]--;
|
||||||
|
@ -106,10 +107,10 @@ void DSPEmitter::dsp_reg_store_stack(int stack_reg, Gen::X64Reg host_sreg)
|
||||||
dsp_reg_stack_push(stack_reg);
|
dsp_reg_stack_push(stack_reg);
|
||||||
//g_dsp.r[DSP_REG_ST0 + stack_reg] = val;
|
//g_dsp.r[DSP_REG_ST0 + stack_reg] = val;
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, M(&g_dsp.r[DSP_REG_ST0+stack_reg]), R(EDX));
|
MOV(16, M(&g_dsp._r.st[stack_reg]), R(EDX));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11,(DSP_REG_ST0+stack_reg)*2), R(EDX));
|
MOV(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, st[stack_reg])), R(EDX));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,10 +118,10 @@ void DSPEmitter::dsp_reg_load_stack(int stack_reg, Gen::X64Reg host_dreg)
|
||||||
{
|
{
|
||||||
//u16 val = g_dsp.r[DSP_REG_ST0 + stack_reg];
|
//u16 val = g_dsp.r[DSP_REG_ST0 + stack_reg];
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, R(EDX), M(&g_dsp.r[DSP_REG_ST0+stack_reg]));
|
MOV(16, R(EDX), M(&g_dsp._r.st[stack_reg]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, R(EDX), MDisp(R11,(DSP_REG_ST0+stack_reg)*2));
|
MOV(16, R(EDX), MDisp(R11,STRUCT_OFFSET(g_dsp._r, st[stack_reg])));
|
||||||
#endif
|
#endif
|
||||||
dsp_reg_stack_pop(stack_reg);
|
dsp_reg_stack_pop(stack_reg);
|
||||||
if (host_dreg != EDX) {
|
if (host_dreg != EDX) {
|
||||||
|
@ -133,10 +134,10 @@ void DSPEmitter::dsp_reg_store_stack_imm(int stack_reg, u16 val)
|
||||||
dsp_reg_stack_push(stack_reg);
|
dsp_reg_stack_push(stack_reg);
|
||||||
//g_dsp.r[DSP_REG_ST0 + stack_reg] = val;
|
//g_dsp.r[DSP_REG_ST0 + stack_reg] = val;
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, M(&g_dsp.r[DSP_REG_ST0+stack_reg]), Imm16(val));
|
MOV(16, M(&g_dsp._r.st[stack_reg]), Imm16(val));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11,(DSP_REG_ST0+stack_reg)*2), Imm16(val));
|
MOV(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, st[stack_reg])), Imm16(val));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,10 +150,10 @@ void DSPEmitter::dsp_op_write_reg(int reg, Gen::X64Reg host_sreg)
|
||||||
// sign extend from the bottom 8 bits.
|
// sign extend from the bottom 8 bits.
|
||||||
MOVSX(16,8,host_sreg,R(host_sreg));
|
MOVSX(16,8,host_sreg,R(host_sreg));
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, M(&g_dsp.r[reg]), R(host_sreg));
|
MOV(16, M(&g_dsp._r.ac[reg-DSP_REG_ACH0].h), R(host_sreg));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11,reg*2), R(host_sreg));
|
MOV(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ac[reg-DSP_REG_ACH0].h)), R(host_sreg));
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -165,14 +166,17 @@ void DSPEmitter::dsp_op_write_reg(int reg, Gen::X64Reg host_sreg)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
{
|
||||||
|
u16 *regp = reg_ptr(reg);
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, M(&g_dsp.r[reg]), R(host_sreg));
|
MOV(16, M(regp), R(host_sreg));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11,reg*2), R(host_sreg));
|
MOV(16, MDisp(R11,PtrOffset(regp,&g_dsp._r)), R(host_sreg));
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPEmitter::dsp_op_write_reg_imm(int reg, u16 val)
|
void DSPEmitter::dsp_op_write_reg_imm(int reg, u16 val)
|
||||||
|
@ -183,10 +187,10 @@ void DSPEmitter::dsp_op_write_reg_imm(int reg, u16 val)
|
||||||
case DSP_REG_ACH1:
|
case DSP_REG_ACH1:
|
||||||
// sign extend from the bottom 8 bits.
|
// sign extend from the bottom 8 bits.
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, M(&g_dsp.r[reg]), Imm16((u16)(s16)(s8)(u8)val));
|
MOV(16, M(&g_dsp._r.ac[reg-DSP_REG_ACH0].h), Imm16((u16)(s16)(s8)(u8)val));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11,reg*2), Imm16((u16)(s16)(s8)(u8)val));
|
MOV(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ac[reg-DSP_REG_ACH0].h)), Imm16((u16)(s16)(s8)(u8)val));
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -199,14 +203,17 @@ void DSPEmitter::dsp_op_write_reg_imm(int reg, u16 val)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
{
|
||||||
|
u16 *regp = reg_ptr(reg);
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, M(&g_dsp.r[reg]), Imm16(val));
|
MOV(16, M(regp), Imm16(val));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11,reg*2), Imm16(val));
|
MOV(16, MDisp(R11,PtrOffset(regp,&g_dsp._r)), Imm16(val));
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPEmitter::dsp_conditional_extend_accum(int reg)
|
void DSPEmitter::dsp_conditional_extend_accum(int reg)
|
||||||
|
@ -217,10 +224,10 @@ void DSPEmitter::dsp_conditional_extend_accum(int reg)
|
||||||
case DSP_REG_ACM1:
|
case DSP_REG_ACM1:
|
||||||
{
|
{
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, R(EAX), M(&g_dsp.r[DSP_REG_SR]));
|
MOV(16, R(EAX), M(&g_dsp._r.sr));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, R(EAX), MDisp(R11,DSP_REG_SR*2));
|
MOV(16, R(EAX), MDisp(R11,STRUCT_OFFSET(g_dsp._r, sr)));
|
||||||
#endif
|
#endif
|
||||||
TEST(16, R(EAX), Imm16(SR_40_MODE_BIT));
|
TEST(16, R(EAX), Imm16(SR_40_MODE_BIT));
|
||||||
FixupBranch not_40bit = J_CC(CC_Z);
|
FixupBranch not_40bit = J_CC(CC_Z);
|
||||||
|
@ -229,21 +236,21 @@ void DSPEmitter::dsp_conditional_extend_accum(int reg)
|
||||||
// Sign extend into whole accum.
|
// Sign extend into whole accum.
|
||||||
//u16 val = g_dsp.r[reg];
|
//u16 val = g_dsp.r[reg];
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOVSX(32, 16, EAX, M(&g_dsp.r[reg]));
|
MOVSX(32, 16, EAX, M(&g_dsp._r.ac[reg-DSP_REG_ACM0].m));
|
||||||
#else
|
#else
|
||||||
MOVSX(64, 16, EAX, MDisp(R11,reg*2));
|
MOVSX(64, 16, EAX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ac[reg-DSP_REG_ACM0].m)));
|
||||||
#endif
|
#endif
|
||||||
SHR(32,R(EAX),Imm8(16));
|
SHR(32,R(EAX),Imm8(16));
|
||||||
//g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACH0] = (val & 0x8000) ? 0xFFFF : 0x0000;
|
//g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACH0] = (val & 0x8000) ? 0xFFFF : 0x0000;
|
||||||
//g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACL0] = 0;
|
//g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACL0] = 0;
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16,M(&g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACH0]),
|
MOV(16,M(&g_dsp._r.ac[reg - DSP_REG_ACM0].h),
|
||||||
R(EAX));
|
R(EAX));
|
||||||
MOV(16,M(&g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACL0]),
|
MOV(16,M(&g_dsp._r.ac[reg - DSP_REG_ACM0].l),
|
||||||
Imm16(0));
|
Imm16(0));
|
||||||
#else
|
#else
|
||||||
MOV(16, MDisp(R11,(reg - DSP_REG_ACM0 + DSP_REG_ACH0)*2), R(EAX));
|
MOV(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ac[reg-DSP_REG_ACM0].h)), R(EAX));
|
||||||
MOV(16, MDisp(R11,(reg - DSP_REG_ACM0 + DSP_REG_ACL0)*2), Imm16(0));
|
MOV(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ac[reg-DSP_REG_ACM0].l)), Imm16(0));
|
||||||
#endif
|
#endif
|
||||||
//}
|
//}
|
||||||
SetJumpTarget(not_40bit);
|
SetJumpTarget(not_40bit);
|
||||||
|
@ -259,10 +266,10 @@ void DSPEmitter::dsp_conditional_extend_accum_imm(int reg, u16 val)
|
||||||
case DSP_REG_ACM1:
|
case DSP_REG_ACM1:
|
||||||
{
|
{
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, R(EAX), M(&g_dsp.r[DSP_REG_SR]));
|
MOV(16, R(EAX), M(&g_dsp._r.sr));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, R(EAX), MDisp(R11,DSP_REG_SR*2));
|
MOV(16, R(EAX), MDisp(R11,STRUCT_OFFSET(g_dsp._r, sr)));
|
||||||
#endif
|
#endif
|
||||||
TEST(16, R(EAX), Imm16(SR_40_MODE_BIT));
|
TEST(16, R(EAX), Imm16(SR_40_MODE_BIT));
|
||||||
FixupBranch not_40bit = J_CC(CC_Z);
|
FixupBranch not_40bit = J_CC(CC_Z);
|
||||||
|
@ -272,14 +279,14 @@ void DSPEmitter::dsp_conditional_extend_accum_imm(int reg, u16 val)
|
||||||
//g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACH0] = (val & 0x8000) ? 0xFFFF : 0x0000;
|
//g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACH0] = (val & 0x8000) ? 0xFFFF : 0x0000;
|
||||||
//g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACL0] = 0;
|
//g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACL0] = 0;
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16,M(&g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACH0]),
|
MOV(16,M(&g_dsp._r.ac[reg - DSP_REG_ACM0].h),
|
||||||
Imm16((val & 0x8000)?0xffff:0x0000));
|
Imm16((val & 0x8000)?0xffff:0x0000));
|
||||||
MOV(16,M(&g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACL0]),
|
MOV(16,M(&g_dsp._r.ac[reg - DSP_REG_ACM0].l),
|
||||||
Imm16(0));
|
Imm16(0));
|
||||||
#else
|
#else
|
||||||
MOV(16, MDisp(R11,(reg - DSP_REG_ACM0 + DSP_REG_ACH0)*2),
|
MOV(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ac[reg-DSP_REG_ACM0].h)),
|
||||||
Imm16((val & 0x8000)?0xffff:0x0000));
|
Imm16((val & 0x8000)?0xffff:0x0000));
|
||||||
MOV(16, MDisp(R11,(reg - DSP_REG_ACM0 + DSP_REG_ACL0)*2),
|
MOV(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ac[reg-DSP_REG_ACM0].l)),
|
||||||
Imm16(0));
|
Imm16(0));
|
||||||
#endif
|
#endif
|
||||||
//}
|
//}
|
||||||
|
@ -297,14 +304,17 @@ void DSPEmitter::dsp_op_read_reg(int reg, Gen::X64Reg host_dreg)
|
||||||
case DSP_REG_ST3:
|
case DSP_REG_ST3:
|
||||||
return dsp_reg_load_stack(reg - DSP_REG_ST0, host_dreg);
|
return dsp_reg_load_stack(reg - DSP_REG_ST0, host_dreg);
|
||||||
default:
|
default:
|
||||||
|
{
|
||||||
|
u16 *regp = reg_ptr(reg);
|
||||||
//return g_dsp.r[reg];
|
//return g_dsp.r[reg];
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, R(host_dreg), M(&g_dsp.r[reg]));
|
MOV(16, R(host_dreg), M(regp));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, R(host_dreg), MDisp(R11,reg*2));
|
MOV(16, R(host_dreg), MDisp(R11,PtrOffset(regp,&g_dsp._r)));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MRR $D, $S
|
// MRR $D, $S
|
||||||
|
@ -415,10 +425,10 @@ void DSPEmitter::setCompileSR(u16 bit) {
|
||||||
|
|
||||||
// g_dsp.r[DSP_REG_SR] |= bit
|
// g_dsp.r[DSP_REG_SR] |= bit
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
OR(16, M(&g_dsp.r[DSP_REG_SR]), Imm16(bit));
|
OR(16, M(&g_dsp._r.sr), Imm16(bit));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
OR(16, MDisp(R11,DSP_REG_SR*2), Imm16(bit));
|
OR(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, sr)), Imm16(bit));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
compileSR |= bit;
|
compileSR |= bit;
|
||||||
|
@ -428,10 +438,10 @@ void DSPEmitter::clrCompileSR(u16 bit) {
|
||||||
|
|
||||||
// g_dsp.r[DSP_REG_SR] &= bit
|
// g_dsp.r[DSP_REG_SR] &= bit
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
AND(16, M(&g_dsp.r[DSP_REG_SR]), Imm16(~bit));
|
AND(16, M(&g_dsp._r.sr), Imm16(~bit));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
AND(16, MDisp(R11,DSP_REG_SR*2), Imm16(~bit));
|
AND(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, sr)), Imm16(~bit));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
compileSR &= ~bit;
|
compileSR &= ~bit;
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "../DSPIntUtil.h"
|
#include "../DSPIntUtil.h"
|
||||||
#include "../DSPEmitter.h"
|
#include "../DSPEmitter.h"
|
||||||
#include "../DSPAnalyzer.h"
|
#include "../DSPAnalyzer.h"
|
||||||
|
#include "DSPJitUtil.h"
|
||||||
#include "x64Emitter.h"
|
#include "x64Emitter.h"
|
||||||
#include "ABI.h"
|
#include "ABI.h"
|
||||||
using namespace Gen;
|
using namespace Gen;
|
||||||
|
@ -37,8 +38,8 @@ void DSPEmitter::multiply()
|
||||||
IMUL(64, R(ESI));
|
IMUL(64, R(ESI));
|
||||||
|
|
||||||
// Conditionally multiply by 2.
|
// Conditionally multiply by 2.
|
||||||
// if ((g_dsp.r[DSP_REG_SR] & SR_MUL_MODIFY) == 0)
|
// if ((g_dsp._r.sr & SR_MUL_MODIFY) == 0)
|
||||||
TEST(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_MUL_MODIFY));
|
TEST(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(SR_MUL_MODIFY));
|
||||||
FixupBranch noMult2 = J_CC(CC_NZ);
|
FixupBranch noMult2 = J_CC(CC_NZ);
|
||||||
// prod <<= 1;
|
// prod <<= 1;
|
||||||
SHL(64, R(EAX), Imm8(1));
|
SHL(64, R(EAX), Imm8(1));
|
||||||
|
@ -89,8 +90,8 @@ void DSPEmitter::multiply_mulx(u8 axh0, u8 axh1)
|
||||||
// result = dsp_multiply(val1, val2, 0); // unsigned support OFF if both ax?.h regs are used
|
// result = dsp_multiply(val1, val2, 0); // unsigned support OFF if both ax?.h regs are used
|
||||||
|
|
||||||
|
|
||||||
// if ((sign == 1) && (g_dsp.r[DSP_REG_SR] & SR_MUL_UNSIGNED)) //unsigned
|
// if ((sign == 1) && (g_dsp._r.sr & SR_MUL_UNSIGNED)) //unsigned
|
||||||
TEST(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_MUL_UNSIGNED));
|
TEST(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(SR_MUL_UNSIGNED));
|
||||||
FixupBranch unsignedMul = J_CC(CC_NZ);
|
FixupBranch unsignedMul = J_CC(CC_NZ);
|
||||||
// prod = (s16)a * (s16)b; //signed
|
// prod = (s16)a * (s16)b; //signed
|
||||||
MOVSX(64, 16, RAX, R(RDI));
|
MOVSX(64, 16, RAX, R(RDI));
|
||||||
|
@ -131,8 +132,8 @@ void DSPEmitter::multiply_mulx(u8 axh0, u8 axh1)
|
||||||
SetJumpTarget(signedMul);
|
SetJumpTarget(signedMul);
|
||||||
|
|
||||||
// Conditionally multiply by 2.
|
// Conditionally multiply by 2.
|
||||||
// if ((g_dsp.r[DSP_REG_SR] & SR_MUL_MODIFY) == 0)
|
// if ((g_dsp._r.sr & SR_MUL_MODIFY) == 0)
|
||||||
TEST(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_MUL_MODIFY));
|
TEST(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, sr)), Imm16(SR_MUL_MODIFY));
|
||||||
FixupBranch noMult2 = J_CC(CC_NZ);
|
FixupBranch noMult2 = J_CC(CC_NZ);
|
||||||
// prod <<= 1;
|
// prod <<= 1;
|
||||||
SHL(64, R(RAX), Imm8(1));
|
SHL(64, R(RAX), Imm8(1));
|
||||||
|
@ -155,14 +156,14 @@ void DSPEmitter::clrp(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
// g_dsp.r[DSP_REG_PRODL] = 0x0000;
|
// g_dsp.r[DSP_REG_PRODL] = 0x0000;
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11, DSP_REG_PRODL * 2), Imm16(0x0000));
|
MOV(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, prod.l)), Imm16(0x0000));
|
||||||
// g_dsp.r[DSP_REG_PRODM] = 0xfff0;
|
// g_dsp.r[DSP_REG_PRODM] = 0xfff0;
|
||||||
MOV(16, MDisp(R11, DSP_REG_PRODM * 2), Imm16(0xfff0));
|
MOV(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, prod.m)), Imm16(0xfff0));
|
||||||
// g_dsp.r[DSP_REG_PRODH] = 0x00ff;
|
// g_dsp.r[DSP_REG_PRODH] = 0x00ff;
|
||||||
MOV(16, MDisp(R11, DSP_REG_PRODH * 2), Imm16(0x00ff));
|
MOV(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, prod.h)), Imm16(0x00ff));
|
||||||
// g_dsp.r[DSP_REG_PRODM2] = 0x0010;
|
// g_dsp.r[DSP_REG_PRODM2] = 0x0010;
|
||||||
MOV(16, MDisp(R11, DSP_REG_PRODM2 * 2), Imm16(0x0010));
|
MOV(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, prod.m2)), Imm16(0x0010));
|
||||||
#else
|
#else
|
||||||
Default(opc);
|
Default(opc);
|
||||||
#endif
|
#endif
|
||||||
|
@ -316,8 +317,8 @@ void DSPEmitter::mulaxh(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
// s64 prod = dsp_multiply(dsp_get_ax_h(0), dsp_get_ax_h(0));
|
// s64 prod = dsp_multiply(dsp_get_ax_h(0), dsp_get_ax_h(0));
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVSX(64, 16, RSI, MDisp(R11, DSP_REG_AXH0 * 2));
|
MOVSX(64, 16, RSI, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ax[0].h)));
|
||||||
MOV(64, R(RDI), R(RSI));
|
MOV(64, R(RDI), R(RSI));
|
||||||
multiply();
|
multiply();
|
||||||
// dsp_set_long_prod(prod);
|
// dsp_set_long_prod(prod);
|
||||||
|
@ -339,10 +340,10 @@ void DSPEmitter::mul(const UDSPInstruction opc)
|
||||||
u8 sreg = (opc >> 11) & 0x1;
|
u8 sreg = (opc >> 11) & 0x1;
|
||||||
|
|
||||||
// u16 axl = dsp_get_ax_l(sreg);
|
// u16 axl = dsp_get_ax_l(sreg);
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVSX(64, 16, RSI, MDisp(R11, (DSP_REG_AXL0 + sreg) * 2));
|
MOVSX(64, 16, RSI, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ax[sreg].l)));
|
||||||
// u16 axh = dsp_get_ax_h(sreg);
|
// u16 axh = dsp_get_ax_h(sreg);
|
||||||
MOVSX(64, 16, RDI, MDisp(R11, (DSP_REG_AXH0 + sreg) * 2));
|
MOVSX(64, 16, RDI, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ax[sreg].h)));
|
||||||
// s64 prod = dsp_multiply(axh, axl);
|
// s64 prod = dsp_multiply(axh, axl);
|
||||||
multiply();
|
multiply();
|
||||||
// dsp_set_long_prod(prod);
|
// dsp_set_long_prod(prod);
|
||||||
|
@ -372,9 +373,9 @@ void DSPEmitter::mulac(const UDSPInstruction opc)
|
||||||
ADD(64, R(RAX), R(RDX));
|
ADD(64, R(RAX), R(RDX));
|
||||||
PUSH(64, R(RAX));
|
PUSH(64, R(RAX));
|
||||||
// u16 axl = dsp_get_ax_l(sreg);
|
// u16 axl = dsp_get_ax_l(sreg);
|
||||||
MOVSX(64, 16, RSI, MDisp(R11, (DSP_REG_AXL0 + sreg) * 2));
|
MOVSX(64, 16, RSI, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ax[sreg].l)));
|
||||||
// u16 axh = dsp_get_ax_h(sreg);
|
// u16 axh = dsp_get_ax_h(sreg);
|
||||||
MOVSX(64, 16, RDI, MDisp(R11, (DSP_REG_AXH0 + sreg) * 2));
|
MOVSX(64, 16, RDI, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ax[sreg].h)));
|
||||||
// s64 prod = dsp_multiply(axl, axh);
|
// s64 prod = dsp_multiply(axl, axh);
|
||||||
multiply();
|
multiply();
|
||||||
// dsp_set_long_prod(prod);
|
// dsp_set_long_prod(prod);
|
||||||
|
@ -460,12 +461,14 @@ void DSPEmitter::mulx(const UDSPInstruction opc)
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
u8 treg = ((opc >> 11) & 0x1);
|
u8 treg = ((opc >> 11) & 0x1);
|
||||||
u8 sreg = ((opc >> 12) & 0x1);
|
u8 sreg = ((opc >> 12) & 0x1);
|
||||||
|
u16 *sregp = reg_ptr(DSP_REG_AXL0 + sreg*2);
|
||||||
|
u16 *tregp = reg_ptr(DSP_REG_AXL1 + treg*2);
|
||||||
|
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
// u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
|
// u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
|
||||||
MOVSX(64, 16, RSI, MDisp(R11, (DSP_REG_AXL0 + sreg*2) * 2));
|
MOVSX(64, 16, RSI, MDisp(R11, PtrOffset(sregp,&g_dsp._r)));
|
||||||
// u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
|
// u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
|
||||||
MOVSX(64, 16, RDI, MDisp(R11, (DSP_REG_AXL1 + treg*2) * 2));
|
MOVSX(64, 16, RDI, MDisp(R11, PtrOffset(tregp,&g_dsp._r)));
|
||||||
// s64 prod = dsp_multiply_mulx(sreg, treg, val1, val2);
|
// s64 prod = dsp_multiply_mulx(sreg, treg, val1, val2);
|
||||||
multiply_mulx(sreg, treg);
|
multiply_mulx(sreg, treg);
|
||||||
// dsp_set_long_prod(prod);
|
// dsp_set_long_prod(prod);
|
||||||
|
@ -488,15 +491,17 @@ void DSPEmitter::mulxac(const UDSPInstruction opc)
|
||||||
u8 rreg = (opc >> 8) & 0x1;
|
u8 rreg = (opc >> 8) & 0x1;
|
||||||
u8 treg = (opc >> 11) & 0x1;
|
u8 treg = (opc >> 11) & 0x1;
|
||||||
u8 sreg = (opc >> 12) & 0x1;
|
u8 sreg = (opc >> 12) & 0x1;
|
||||||
|
u16 *sregp = reg_ptr(DSP_REG_AXL0 + sreg*2);
|
||||||
|
u16 *tregp = reg_ptr(DSP_REG_AXL1 + treg*2);
|
||||||
|
|
||||||
// s64 acc = dsp_get_long_acc(rreg) + dsp_get_long_prod();
|
// s64 acc = dsp_get_long_acc(rreg) + dsp_get_long_prod();
|
||||||
get_long_acc(rreg, RCX);
|
get_long_acc(rreg, RCX);
|
||||||
get_long_prod();
|
get_long_prod();
|
||||||
ADD(64, R(RCX), R(RAX));
|
ADD(64, R(RCX), R(RAX));
|
||||||
// u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
|
// u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
|
||||||
MOVSX(64, 16, RSI, MDisp(R11, (DSP_REG_AXL0 + sreg*2) * 2));
|
MOVSX(64, 16, RSI, MDisp(R11, PtrOffset(sregp, &g_dsp._r)));
|
||||||
// u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
|
// u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
|
||||||
MOVSX(64, 16, RDI, MDisp(R11, (DSP_REG_AXL1 + treg*2) * 2));
|
MOVSX(64, 16, RDI, MDisp(R11, PtrOffset(tregp, &g_dsp._r)));
|
||||||
// s64 prod = dsp_multiply_mulx(sreg, treg, val1, val2);
|
// s64 prod = dsp_multiply_mulx(sreg, treg, val1, val2);
|
||||||
multiply_mulx(sreg, treg);
|
multiply_mulx(sreg, treg);
|
||||||
|
|
||||||
|
@ -527,13 +532,15 @@ void DSPEmitter::mulxmv(const UDSPInstruction opc)
|
||||||
u8 rreg = ((opc >> 8) & 0x1);
|
u8 rreg = ((opc >> 8) & 0x1);
|
||||||
u8 treg = (opc >> 11) & 0x1;
|
u8 treg = (opc >> 11) & 0x1;
|
||||||
u8 sreg = (opc >> 12) & 0x1;
|
u8 sreg = (opc >> 12) & 0x1;
|
||||||
|
u16 *sregp = reg_ptr(DSP_REG_AXL0 + sreg*2);
|
||||||
|
u16 *tregp = reg_ptr(DSP_REG_AXL1 + treg*2);
|
||||||
|
|
||||||
// s64 acc = dsp_get_long_prod();
|
// s64 acc = dsp_get_long_prod();
|
||||||
get_long_prod(RCX);
|
get_long_prod(RCX);
|
||||||
// u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
|
// u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
|
||||||
MOVSX(64, 16, RSI, MDisp(R11, (DSP_REG_AXL0 + sreg*2) * 2));
|
MOVSX(64, 16, RSI, MDisp(R11, PtrOffset(sregp, &g_dsp._r)));
|
||||||
// u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
|
// u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
|
||||||
MOVSX(64, 16, RDI, MDisp(R11, (DSP_REG_AXL1 + treg*2) * 2));
|
MOVSX(64, 16, RDI, MDisp(R11, PtrOffset(tregp, &g_dsp._r)));
|
||||||
// s64 prod = dsp_multiply_mulx(sreg, treg, val1, val2);
|
// s64 prod = dsp_multiply_mulx(sreg, treg, val1, val2);
|
||||||
multiply_mulx(sreg, treg);
|
multiply_mulx(sreg, treg);
|
||||||
|
|
||||||
|
@ -565,13 +572,15 @@ void DSPEmitter::mulxmvz(const UDSPInstruction opc)
|
||||||
u8 rreg = (opc >> 8) & 0x1;
|
u8 rreg = (opc >> 8) & 0x1;
|
||||||
u8 treg = (opc >> 11) & 0x1;
|
u8 treg = (opc >> 11) & 0x1;
|
||||||
u8 sreg = (opc >> 12) & 0x1;
|
u8 sreg = (opc >> 12) & 0x1;
|
||||||
|
u16 *sregp = reg_ptr(DSP_REG_AXL0 + sreg*2);
|
||||||
|
u16 *tregp = reg_ptr(DSP_REG_AXL1 + treg*2);
|
||||||
|
|
||||||
// s64 acc = dsp_get_long_prod_round_prodl();
|
// s64 acc = dsp_get_long_prod_round_prodl();
|
||||||
get_long_prod_round_prodl(RCX);
|
get_long_prod_round_prodl(RCX);
|
||||||
// u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
|
// u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
|
||||||
MOVSX(64, 16, RSI, MDisp(R11, (DSP_REG_AXL0 + sreg*2) * 2));
|
MOVSX(64, 16, RSI, MDisp(R11, PtrOffset(sregp, &g_dsp._r)));
|
||||||
// u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
|
// u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
|
||||||
MOVSX(64, 16, RDI, MDisp(R11, (DSP_REG_AXL1 + treg*2) * 2));
|
MOVSX(64, 16, RDI, MDisp(R11, PtrOffset(tregp, &g_dsp._r)));
|
||||||
// s64 prod = dsp_multiply_mulx(sreg, treg, val1, val2);
|
// s64 prod = dsp_multiply_mulx(sreg, treg, val1, val2);
|
||||||
multiply_mulx(sreg, treg);
|
multiply_mulx(sreg, treg);
|
||||||
|
|
||||||
|
@ -602,10 +611,10 @@ void DSPEmitter::mulc(const UDSPInstruction opc)
|
||||||
u8 sreg = (opc >> 12) & 0x1;
|
u8 sreg = (opc >> 12) & 0x1;
|
||||||
|
|
||||||
// u16 accm = dsp_get_acc_m(sreg);
|
// u16 accm = dsp_get_acc_m(sreg);
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVSX(64, 16, ESI, MDisp(R11, (DSP_REG_ACM0 + sreg) * 2));
|
MOVSX(64, 16, ESI, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ac[sreg].m)));
|
||||||
// u16 axh = dsp_get_ax_h(treg);
|
// u16 axh = dsp_get_ax_h(treg);
|
||||||
MOVSX(64, 16, EDI, MDisp(R11, (DSP_REG_AXH0 + treg) * 2));
|
MOVSX(64, 16, EDI, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ax[treg].h)));
|
||||||
// s64 prod = dsp_multiply(accm, axh);
|
// s64 prod = dsp_multiply(accm, axh);
|
||||||
multiply();
|
multiply();
|
||||||
// dsp_set_long_prod(prod);
|
// dsp_set_long_prod(prod);
|
||||||
|
@ -636,9 +645,9 @@ void DSPEmitter::mulcac(const UDSPInstruction opc)
|
||||||
ADD(64, R(RAX), R(RDX));
|
ADD(64, R(RAX), R(RDX));
|
||||||
PUSH(64, R(RAX));
|
PUSH(64, R(RAX));
|
||||||
// u16 accm = dsp_get_acc_m(sreg);
|
// u16 accm = dsp_get_acc_m(sreg);
|
||||||
MOVSX(64, 16, RSI, MDisp(R11, (DSP_REG_ACM0 + sreg) * 2));
|
MOVSX(64, 16, RSI, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ac[sreg].m)));
|
||||||
// u16 axh = dsp_get_ax_h(treg);
|
// u16 axh = dsp_get_ax_h(treg);
|
||||||
MOVSX(64, 16, RDI, MDisp(R11, (DSP_REG_AXH0 + treg) * 2));
|
MOVSX(64, 16, RDI, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ax[treg].h)));
|
||||||
// s64 prod = dsp_multiply(accm, axh);
|
// s64 prod = dsp_multiply(accm, axh);
|
||||||
multiply();
|
multiply();
|
||||||
// dsp_set_long_prod(prod);
|
// dsp_set_long_prod(prod);
|
||||||
|
@ -675,9 +684,9 @@ void DSPEmitter::mulcmv(const UDSPInstruction opc)
|
||||||
get_long_prod();
|
get_long_prod();
|
||||||
PUSH(64, R(RAX));
|
PUSH(64, R(RAX));
|
||||||
// u16 accm = dsp_get_acc_m(sreg);
|
// u16 accm = dsp_get_acc_m(sreg);
|
||||||
MOVSX(64, 16, RSI, MDisp(R11, (DSP_REG_ACM0 + sreg) * 2));
|
MOVSX(64, 16, RSI, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ac[sreg].m)));
|
||||||
// u16 axh = dsp_get_ax_h(treg);
|
// u16 axh = dsp_get_ax_h(treg);
|
||||||
MOVSX(64, 16, RDI, MDisp(R11, (DSP_REG_AXH0 + treg) * 2));
|
MOVSX(64, 16, RDI, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ax[treg].h)));
|
||||||
// s64 prod = dsp_multiply(accm, axh);
|
// s64 prod = dsp_multiply(accm, axh);
|
||||||
multiply();
|
multiply();
|
||||||
// dsp_set_long_prod(prod);
|
// dsp_set_long_prod(prod);
|
||||||
|
@ -711,14 +720,14 @@ void DSPEmitter::mulcmvz(const UDSPInstruction opc)
|
||||||
u8 treg = (opc >> 11) & 0x1;
|
u8 treg = (opc >> 11) & 0x1;
|
||||||
u8 sreg = (opc >> 12) & 0x1;
|
u8 sreg = (opc >> 12) & 0x1;
|
||||||
|
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
// s64 acc = dsp_get_long_prod_round_prodl();
|
// s64 acc = dsp_get_long_prod_round_prodl();
|
||||||
get_long_prod_round_prodl();
|
get_long_prod_round_prodl();
|
||||||
PUSH(64, R(RAX));
|
PUSH(64, R(RAX));
|
||||||
// u16 accm = dsp_get_acc_m(sreg);
|
// u16 accm = dsp_get_acc_m(sreg);
|
||||||
MOVSX(64, 16, RSI, MDisp(R11, (DSP_REG_ACM0 + sreg) * 2));
|
MOVSX(64, 16, RSI, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ac[sreg].m)));
|
||||||
// u16 axh = dsp_get_ax_h(treg);
|
// u16 axh = dsp_get_ax_h(treg);
|
||||||
MOVSX(64, 16, RDI, MDisp(R11, (DSP_REG_AXH0 + treg) * 2));
|
MOVSX(64, 16, RDI, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ax[treg].h)));
|
||||||
// s64 prod = dsp_multiply(accm, axh);
|
// s64 prod = dsp_multiply(accm, axh);
|
||||||
multiply();
|
multiply();
|
||||||
// dsp_set_long_prod(prod);
|
// dsp_set_long_prod(prod);
|
||||||
|
@ -748,12 +757,14 @@ void DSPEmitter::maddx(const UDSPInstruction opc)
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
u8 treg = (opc >> 8) & 0x1;
|
u8 treg = (opc >> 8) & 0x1;
|
||||||
u8 sreg = (opc >> 9) & 0x1;
|
u8 sreg = (opc >> 9) & 0x1;
|
||||||
|
u16 *sregp = reg_ptr(DSP_REG_AXL0 + sreg*2);
|
||||||
|
u16 *tregp = reg_ptr(DSP_REG_AXL1 + treg*2);
|
||||||
|
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
// u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
|
// u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
|
||||||
MOVSX(64, 16, RSI, MDisp(R11, (DSP_REG_AXL0 + sreg*2) * 2));
|
MOVSX(64, 16, RSI, MDisp(R11, PtrOffset(sregp, &g_dsp._r)));
|
||||||
// u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
|
// u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
|
||||||
MOVSX(64, 16, RDI, MDisp(R11, (DSP_REG_AXL1 + treg*2) * 2));
|
MOVSX(64, 16, RDI, MDisp(R11, PtrOffset(tregp, &g_dsp._r)));
|
||||||
// s64 prod = dsp_multiply_add(val1, val2);
|
// s64 prod = dsp_multiply_add(val1, val2);
|
||||||
multiply_add();
|
multiply_add();
|
||||||
// dsp_set_long_prod(prod);
|
// dsp_set_long_prod(prod);
|
||||||
|
@ -773,12 +784,14 @@ void DSPEmitter::msubx(const UDSPInstruction opc)
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
u8 treg = (opc >> 8) & 0x1;
|
u8 treg = (opc >> 8) & 0x1;
|
||||||
u8 sreg = (opc >> 9) & 0x1;
|
u8 sreg = (opc >> 9) & 0x1;
|
||||||
|
u16 *sregp = reg_ptr(DSP_REG_AXL0 + sreg*2);
|
||||||
|
u16 *tregp = reg_ptr(DSP_REG_AXL1 + treg*2);
|
||||||
|
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
// u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
|
// u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
|
||||||
MOVSX(64, 16, RSI, MDisp(R11, (DSP_REG_AXL0 + sreg*2) * 2));
|
MOVSX(64, 16, RSI, MDisp(R11, PtrOffset(sregp, &g_dsp._r)));
|
||||||
// u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
|
// u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
|
||||||
MOVSX(64, 16, RDI, MDisp(R11, (DSP_REG_AXL1 + treg*2) * 2));
|
MOVSX(64, 16, RDI, MDisp(R11, PtrOffset(tregp, &g_dsp._r)));
|
||||||
// s64 prod = dsp_multiply_sub(val1, val2);
|
// s64 prod = dsp_multiply_sub(val1, val2);
|
||||||
multiply_sub();
|
multiply_sub();
|
||||||
// dsp_set_long_prod(prod);
|
// dsp_set_long_prod(prod);
|
||||||
|
@ -799,11 +812,11 @@ void DSPEmitter::maddc(const UDSPInstruction opc)
|
||||||
u8 treg = (opc >> 8) & 0x1;
|
u8 treg = (opc >> 8) & 0x1;
|
||||||
u8 sreg = (opc >> 9) & 0x1;
|
u8 sreg = (opc >> 9) & 0x1;
|
||||||
|
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
// u16 accm = dsp_get_acc_m(sreg);
|
// u16 accm = dsp_get_acc_m(sreg);
|
||||||
MOVSX(64, 16, RSI, MDisp(R11, (DSP_REG_ACM0 + sreg) * 2));
|
MOVSX(64, 16, RSI, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ac[sreg].m)));
|
||||||
// u16 axh = dsp_get_ax_h(treg);
|
// u16 axh = dsp_get_ax_h(treg);
|
||||||
MOVSX(64, 16, RDI, MDisp(R11, (DSP_REG_AXH0 + treg) * 2));
|
MOVSX(64, 16, RDI, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ax[treg].h)));
|
||||||
// s64 prod = dsp_multiply_add(accm, axh);
|
// s64 prod = dsp_multiply_add(accm, axh);
|
||||||
multiply_add();
|
multiply_add();
|
||||||
// dsp_set_long_prod(prod);
|
// dsp_set_long_prod(prod);
|
||||||
|
@ -823,12 +836,12 @@ void DSPEmitter::msubc(const UDSPInstruction opc)
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
u8 treg = (opc >> 8) & 0x1;
|
u8 treg = (opc >> 8) & 0x1;
|
||||||
u8 sreg = (opc >> 9) & 0x1;
|
u8 sreg = (opc >> 9) & 0x1;
|
||||||
//
|
|
||||||
// u16 accm = dsp_get_acc_m(sreg);
|
// u16 accm = dsp_get_acc_m(sreg);
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVSX(64, 16, RSI, MDisp(R11, (DSP_REG_ACM0 + sreg) * 2));
|
MOVSX(64, 16, RSI, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ac[sreg].m)));
|
||||||
// u16 axh = dsp_get_ax_h(treg);
|
// u16 axh = dsp_get_ax_h(treg);
|
||||||
MOVSX(64, 16, RDI, MDisp(R11, (DSP_REG_AXH0 + treg) * 2));
|
MOVSX(64, 16, RDI, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ax[treg].h)));
|
||||||
// s64 prod = dsp_multiply_sub(accm, axh);
|
// s64 prod = dsp_multiply_sub(accm, axh);
|
||||||
multiply_sub();
|
multiply_sub();
|
||||||
// dsp_set_long_prod(prod);
|
// dsp_set_long_prod(prod);
|
||||||
|
@ -848,11 +861,11 @@ void DSPEmitter::madd(const UDSPInstruction opc)
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
u8 sreg = (opc >> 8) & 0x1;
|
u8 sreg = (opc >> 8) & 0x1;
|
||||||
|
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
// u16 axl = dsp_get_ax_l(sreg);
|
// u16 axl = dsp_get_ax_l(sreg);
|
||||||
MOVSX(64, 16, RSI, MDisp(R11, (DSP_REG_AXL0 + sreg) * 2));
|
MOVSX(64, 16, RSI, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ax[sreg].l)));
|
||||||
// u16 axh = dsp_get_ax_h(sreg);
|
// u16 axh = dsp_get_ax_h(sreg);
|
||||||
MOVSX(64, 16, RDI, MDisp(R11, (DSP_REG_AXH0 + sreg) * 2));
|
MOVSX(64, 16, RDI, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ax[sreg].h)));
|
||||||
// s64 prod = dsp_multiply_add(axl, axh);
|
// s64 prod = dsp_multiply_add(axl, axh);
|
||||||
multiply_add();
|
multiply_add();
|
||||||
// dsp_set_long_prod(prod);
|
// dsp_set_long_prod(prod);
|
||||||
|
@ -873,10 +886,10 @@ void DSPEmitter::msub(const UDSPInstruction opc)
|
||||||
u8 sreg = (opc >> 8) & 0x1;
|
u8 sreg = (opc >> 8) & 0x1;
|
||||||
//
|
//
|
||||||
// u16 axl = dsp_get_ax_l(sreg);
|
// u16 axl = dsp_get_ax_l(sreg);
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVSX(64, 16, RSI, MDisp(R11, (DSP_REG_AXL0 + sreg) * 2));
|
MOVSX(64, 16, RSI, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ax[sreg].l)));
|
||||||
// u16 axh = dsp_get_ax_h(sreg);
|
// u16 axh = dsp_get_ax_h(sreg);
|
||||||
MOVSX(64, 16, RDI, MDisp(R11, (DSP_REG_AXH0 + sreg) * 2));
|
MOVSX(64, 16, RDI, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ax[sreg].h)));
|
||||||
// s64 prod = dsp_multiply_sub(axl, axh);
|
// s64 prod = dsp_multiply_sub(axl, axh);
|
||||||
multiply_sub();
|
multiply_sub();
|
||||||
// dsp_set_long_prod(prod);
|
// dsp_set_long_prod(prod);
|
||||||
|
|
|
@ -15,9 +15,6 @@
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#ifndef _DSP_JIT_UTIL_H
|
|
||||||
#define _DSP_JIT_UTIL_H
|
|
||||||
|
|
||||||
#include "../DSPMemoryMap.h"
|
#include "../DSPMemoryMap.h"
|
||||||
#include "../DSPHWInterface.h"
|
#include "../DSPHWInterface.h"
|
||||||
#include "../DSPEmitter.h"
|
#include "../DSPEmitter.h"
|
||||||
|
@ -30,6 +27,10 @@ using namespace Gen;
|
||||||
// clobbers RCX
|
// clobbers RCX
|
||||||
void DSPEmitter::ToMask(X64Reg value_reg)
|
void DSPEmitter::ToMask(X64Reg value_reg)
|
||||||
{
|
{
|
||||||
|
//microbenchmarking results(1 000 000 000 iterations):
|
||||||
|
// cpu\variant| 1 | 2
|
||||||
|
//intel mobile C2D@2.5GHz | 5.5s | 4.0s
|
||||||
|
//amd athlon64x2@3GHz | 6.1s | 6.4s
|
||||||
#if 0
|
#if 0
|
||||||
MOV(16, R(CX), R(value_reg));
|
MOV(16, R(CX), R(value_reg));
|
||||||
SHR(16, R(CX), Imm8(8));
|
SHR(16, R(CX), Imm8(8));
|
||||||
|
@ -77,12 +78,12 @@ void DSPEmitter::increment_addr_reg(int reg)
|
||||||
|
|
||||||
// s16 tmp = g_dsp.r[reg];
|
// s16 tmp = g_dsp.r[reg];
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, R(AX), M(&g_dsp.r[reg]));
|
MOV(16, R(AX), M(&g_dsp._r.ar[reg]));
|
||||||
MOV(16, R(DX), M(&g_dsp.r[DSP_REG_WR0 + reg]));
|
MOV(16, R(DX), M(&g_dsp._r.wr[reg]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, R(AX), MDisp(R11,reg*2));
|
MOV(16, R(AX), MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[reg])));
|
||||||
MOV(16, R(DX), MDisp(R11,(DSP_REG_WR0 + reg)*2));
|
MOV(16, R(DX), MDisp(R11,STRUCT_OFFSET(g_dsp._r, wr[reg])));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MOV(16,R(DI), R(AX));
|
MOV(16,R(DI), R(AX));
|
||||||
|
@ -102,10 +103,10 @@ void DSPEmitter::increment_addr_reg(int reg)
|
||||||
|
|
||||||
// g_dsp.r[reg] = tmp;
|
// g_dsp.r[reg] = tmp;
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, M(&g_dsp.r[reg]), R(AX));
|
MOV(16, M(&g_dsp._r.ar[reg]), R(AX));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11,reg*2), R(AX));
|
MOV(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[reg])), R(AX));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,12 +127,12 @@ void DSPEmitter::decrement_addr_reg(int reg)
|
||||||
|
|
||||||
// s16 ar = g_dsp.r[reg];
|
// s16 ar = g_dsp.r[reg];
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, R(AX), M(&g_dsp.r[reg]));
|
MOV(16, R(AX), M(&g_dsp._r.ar[reg]));
|
||||||
MOVZX(32, 16, EDX, M(&g_dsp.r[DSP_REG_WR0 + reg]));
|
MOVZX(32, 16, EDX, M(&g_dsp._r.wr[reg]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, R(AX), MDisp(R11,reg*2));
|
MOV(16, R(AX), MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[reg])));
|
||||||
MOVZX(32, 16, EDX, MDisp(R11,(DSP_REG_WR0 + reg)*2));
|
MOVZX(32, 16, EDX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, wr[reg])));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ToMask(WR0), calculating it into EDI
|
// ToMask(WR0), calculating it into EDI
|
||||||
|
@ -158,10 +159,10 @@ void DSPEmitter::decrement_addr_reg(int reg)
|
||||||
|
|
||||||
// g_dsp.r[reg] = tmp;
|
// g_dsp.r[reg] = tmp;
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, M(&g_dsp.r[reg]), R(AX));
|
MOV(16, M(&g_dsp._r.ar[reg]), R(AX));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11,reg*2), R(AX));
|
MOV(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[reg])), R(AX));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,14 +190,14 @@ void DSPEmitter::increase_addr_reg(int reg)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, R(SI), M(&g_dsp.r[DSP_REG_IX0 + reg]));
|
MOV(16, R(SI), M(&g_dsp._r.ix[reg]));
|
||||||
MOV(16, R(AX), M(&g_dsp.r[reg]));
|
MOV(16, R(AX), M(&g_dsp._r.ar[reg]));
|
||||||
MOVZX(32, 16, EDX, M(&g_dsp.r[DSP_REG_WR0 + reg]));
|
MOVZX(32, 16, EDX, M(&g_dsp._r.wr[reg]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, R(SI), MDisp(R11,(DSP_REG_IX0 + reg)*2));
|
MOV(16, R(SI), MDisp(R11,STRUCT_OFFSET(g_dsp._r, ix[reg])));
|
||||||
MOV(16, R(AX), MDisp(R11,reg*2));
|
MOV(16, R(AX), MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[reg])));
|
||||||
MOVZX(32, 16, EDX, MDisp(R11,(DSP_REG_WR0 + reg)*2));
|
MOVZX(32, 16, EDX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, wr[reg])));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ToMask(WR0), calculating it into EDI
|
// ToMask(WR0), calculating it into EDI
|
||||||
|
@ -239,10 +240,10 @@ void DSPEmitter::increase_addr_reg(int reg)
|
||||||
|
|
||||||
// g_dsp.r[reg] = tmp;
|
// g_dsp.r[reg] = tmp;
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, M(&g_dsp.r[reg]), R(EAX));
|
MOV(16, M(&g_dsp._r.ar[reg]), R(EAX));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11,reg*2), R(EAX));
|
MOV(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[reg])), R(EAX));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,14 +271,14 @@ void DSPEmitter::decrease_addr_reg(int reg)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, R(SI), M(&g_dsp.r[DSP_REG_IX0 + reg]));
|
MOV(16, R(SI), M(&g_dsp._r.ix[reg]));
|
||||||
MOV(16, R(AX), M(&g_dsp.r[reg]));
|
MOV(16, R(AX), M(&g_dsp._r.ar[reg]));
|
||||||
MOVZX(32, 16, EDX, M(&g_dsp.r[DSP_REG_WR0 + reg]));
|
MOVZX(32, 16, EDX, M(&g_dsp._r.wr[reg]));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, R(SI), MDisp(R11,(DSP_REG_IX0 + reg)*2));
|
MOV(16, R(SI), MDisp(R11,STRUCT_OFFSET(g_dsp._r, ix[reg])));
|
||||||
MOV(16, R(AX), MDisp(R11,reg*2));
|
MOV(16, R(AX), MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[reg])));
|
||||||
MOVZX(32, 16, EDX, MDisp(R11,(DSP_REG_WR0 + reg)*2));
|
MOVZX(32, 16, EDX, MDisp(R11,STRUCT_OFFSET(g_dsp._r, wr[reg])));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ToMask(WR0), calculating it into EDI
|
// ToMask(WR0), calculating it into EDI
|
||||||
|
@ -318,10 +319,10 @@ void DSPEmitter::decrease_addr_reg(int reg)
|
||||||
|
|
||||||
// g_dsp.r[reg] = tmp;
|
// g_dsp.r[reg] = tmp;
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
MOV(16, M(&g_dsp.r[reg]), R(EAX));
|
MOV(16, M(&g_dsp._r.ar[reg]), R(EAX));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11,reg*2), R(EAX));
|
MOV(16, MDisp(R11,STRUCT_OFFSET(g_dsp._r, ar[reg])), R(EAX));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -492,20 +493,34 @@ void DSPEmitter::dmem_read_imm(u16 address)
|
||||||
void DSPEmitter::get_long_prod(X64Reg long_prod)
|
void DSPEmitter::get_long_prod(X64Reg long_prod)
|
||||||
{
|
{
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
#if 0
|
||||||
//s64 val = (s8)(u8)g_dsp.r[DSP_REG_PRODH];
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVSX(64, 8, long_prod, MDisp(R11,DSP_REG_PRODH*2));
|
//s64 val = (s8)(u8)g_dsp.r[DSP_REG_PRODH];
|
||||||
|
MOVSX(64, 8, long_prod, MDisp(R11,STRUCT_OFFSET(g_dsp._r, prod.h)));
|
||||||
//val <<= 32;
|
//val <<= 32;
|
||||||
SHL(64, R(long_prod), Imm8(16));
|
SHL(64, R(long_prod), Imm8(16));
|
||||||
//s64 low_prod = g_dsp.r[DSP_REG_PRODM];
|
//s64 low_prod = g_dsp.r[DSP_REG_PRODM];
|
||||||
OR(16, R(long_prod), MDisp(R11,DSP_REG_PRODM*2));
|
OR(16, R(long_prod), MDisp(R11,STRUCT_OFFSET(g_dsp._r, prod.m)));
|
||||||
//low_prod += g_dsp.r[DSP_REG_PRODM2];
|
//low_prod += g_dsp.r[DSP_REG_PRODM2];
|
||||||
ADD(16, R(long_prod), MDisp(R11,DSP_REG_PRODM2*2));
|
ADD(16, R(long_prod), MDisp(R11,STRUCT_OFFSET(g_dsp._r, prod.m2)));
|
||||||
//low_prod <<= 16;
|
//low_prod <<= 16;
|
||||||
SHL(64, R(long_prod), Imm8(16));
|
SHL(64, R(long_prod), Imm8(16));
|
||||||
//low_prod |= g_dsp.r[DSP_REG_PRODL];
|
//low_prod |= g_dsp.r[DSP_REG_PRODL];
|
||||||
OR(16, R(long_prod), MDisp(R11,DSP_REG_PRODL*2));
|
OR(16, R(long_prod), MDisp(R11,STRUCT_OFFSET(g_dsp._r, prod.l)));
|
||||||
//return val;
|
//return val;
|
||||||
|
#else
|
||||||
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
|
//s64 val = (s8)(u8)g_dsp.r[DSP_REG_PRODH];
|
||||||
|
MOV(64, R(long_prod), MDisp(R11,STRUCT_OFFSET(g_dsp._r, prod.val)));
|
||||||
|
MOV(64, R(R11), R(long_prod));
|
||||||
|
SHL(64, R(long_prod), Imm8(64-40));//sign extend
|
||||||
|
SAR(64, R(long_prod), Imm8(64-40));
|
||||||
|
SHR(64, R(R11), Imm8(48));
|
||||||
|
SHL(64, R(R11), Imm8(16));
|
||||||
|
ADD(64, R(long_prod), R(R11));
|
||||||
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
|
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -540,20 +555,28 @@ void DSPEmitter::get_long_prod_round_prodl(X64Reg long_prod)
|
||||||
void DSPEmitter::set_long_prod()
|
void DSPEmitter::set_long_prod()
|
||||||
{
|
{
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
|
#if 0
|
||||||
// g_dsp.r[DSP_REG_PRODL] = (u16)val;
|
// g_dsp.r[DSP_REG_PRODL] = (u16)val;
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11, DSP_REG_PRODL * 2), R(AX));
|
MOV(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, prod.l)), R(AX));
|
||||||
// val >>= 16;
|
// val >>= 16;
|
||||||
SAR(64, R(RAX), Imm8(16));
|
SAR(64, R(RAX), Imm8(16));
|
||||||
// g_dsp.r[DSP_REG_PRODM] = (u16)val;
|
// g_dsp.r[DSP_REG_PRODM] = (u16)val;
|
||||||
MOV(16, MDisp(R11, DSP_REG_PRODM * 2), R(AX));
|
MOV(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, prod.m)), R(AX));
|
||||||
// val >>= 16;
|
// val >>= 16;
|
||||||
SAR(64, R(RAX), Imm8(16));
|
SAR(64, R(RAX), Imm8(16));
|
||||||
// g_dsp.r[DSP_REG_PRODH] = (u8)val;
|
// g_dsp.r[DSP_REG_PRODH] = (u8)val;
|
||||||
MOVSX(64, 8, RAX, R(AL));
|
MOVSX(64, 8, RAX, R(AL));
|
||||||
MOV(8, MDisp(R11, DSP_REG_PRODH * 2), R(AL));
|
MOV(8, MDisp(R11, STRUCT_OFFSET(g_dsp._r, prod.h)), R(AL));
|
||||||
// g_dsp.r[DSP_REG_PRODM2] = 0;
|
// g_dsp.r[DSP_REG_PRODM2] = 0;
|
||||||
MOV(16, MDisp(R11, DSP_REG_PRODM2 * 2), Imm16(0));
|
MOV(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, prod.m2)), Imm16(0));
|
||||||
|
#else
|
||||||
|
MOV(64, R(R11), Imm64(0x000000ffffffffffULL));
|
||||||
|
AND(64, R(RAX), R(R11));
|
||||||
|
// g_dsp.r[DSP_REG_PRODL] = (u16)val;
|
||||||
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
|
MOV(64, MDisp(R11, STRUCT_OFFSET(g_dsp._r, prod.val)), R(RAX));
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -583,15 +606,23 @@ void DSPEmitter::round_long_acc(X64Reg long_acc)
|
||||||
void DSPEmitter::get_long_acc(int _reg, X64Reg acc)
|
void DSPEmitter::get_long_acc(int _reg, X64Reg acc)
|
||||||
{
|
{
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
|
#if 0
|
||||||
// s64 high = (s64)(s8)g_dsp.r[DSP_REG_ACH0 + reg] << 32;
|
// s64 high = (s64)(s8)g_dsp.r[DSP_REG_ACH0 + reg] << 32;
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVSX(64, 8, acc, MDisp(R11, (DSP_REG_ACH0 + _reg) * 2));
|
MOVSX(64, 8, acc, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ac[_reg].h)));
|
||||||
SHL(64, R(acc), Imm8(16));
|
SHL(64, R(acc), Imm8(16));
|
||||||
// u32 mid_low = ((u32)g_dsp.r[DSP_REG_ACM0 + reg] << 16) | g_dsp.r[DSP_REG_ACL0 + reg];
|
// u32 mid_low = ((u32)g_dsp.r[DSP_REG_ACM0 + reg] << 16) | g_dsp.r[DSP_REG_ACL0 + reg];
|
||||||
OR(16, R(acc), MDisp(R11, (DSP_REG_ACM0 + _reg) * 2));
|
OR(16, R(acc), MDisp(R11, STRUCT_OFFSET(g_dsp._r, ac[_reg].m)));
|
||||||
SHL(64, R(acc), Imm8(16));
|
SHL(64, R(acc), Imm8(16));
|
||||||
OR(16, R(acc), MDisp(R11, (DSP_REG_ACL0 + _reg) * 2));
|
OR(16, R(acc), MDisp(R11, STRUCT_OFFSET(g_dsp._r, ac[_reg].l)));
|
||||||
// return high | mid_low;
|
// return high | mid_low;
|
||||||
|
#else
|
||||||
|
// s64 high = (s64)(s8)g_dsp.r[DSP_REG_ACH0 + reg] << 32;
|
||||||
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
|
MOV(64, R(acc), MDisp(R11, STRUCT_OFFSET(g_dsp._r, ac[_reg].val)));
|
||||||
|
SHL(64, R(acc), Imm8(64-40));//sign extend
|
||||||
|
SAR(64, R(acc), Imm8(64-40));
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,18 +631,26 @@ void DSPEmitter::get_long_acc(int _reg, X64Reg acc)
|
||||||
void DSPEmitter::set_long_acc(int _reg, X64Reg acc)
|
void DSPEmitter::set_long_acc(int _reg, X64Reg acc)
|
||||||
{
|
{
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
|
#if 0
|
||||||
// g_dsp.r[DSP_REG_ACL0 + _reg] = (u16)val;
|
// g_dsp.r[DSP_REG_ACL0 + _reg] = (u16)val;
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11, (DSP_REG_ACL0 + _reg) * 2), R(acc));
|
MOV(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ac[_reg].l)), R(acc));
|
||||||
// val >>= 16;
|
// val >>= 16;
|
||||||
SHR(64, R(acc), Imm8(16));
|
SHR(64, R(acc), Imm8(16));
|
||||||
// g_dsp.r[DSP_REG_ACM0 + _reg] = (u16)val;
|
// g_dsp.r[DSP_REG_ACM0 + _reg] = (u16)val;
|
||||||
MOV(16, MDisp(R11, (DSP_REG_ACM0 + _reg) * 2), R(acc));
|
MOV(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ac[_reg].m)), R(acc));
|
||||||
// val >>= 16;
|
// val >>= 16;
|
||||||
SHR(64, R(acc), Imm8(16));
|
SHR(64, R(acc), Imm8(16));
|
||||||
// g_dsp.r[DSP_REG_ACH0 + _reg] = (u16)(s16)(s8)(u8)val;
|
// g_dsp.r[DSP_REG_ACH0 + _reg] = (u16)(s16)(s8)(u8)val;
|
||||||
MOVSX(64, 8, acc, R(acc));
|
MOVSX(64, 8, acc, R(acc));
|
||||||
MOV(16, MDisp(R11, (DSP_REG_ACH0 + _reg) * 2), R(acc));
|
MOV(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ac[_reg].h)), R(acc));
|
||||||
|
#else
|
||||||
|
SHL(64, R(acc), Imm8(64-40));//sign extend
|
||||||
|
SAR(64, R(acc), Imm8(64-40));
|
||||||
|
// g_dsp.r[DSP_REG_ACL0 + _reg] = (u16)val;
|
||||||
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
|
MOV(64, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ac[_reg].val)), R(acc));
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -620,8 +659,8 @@ void DSPEmitter::get_acc_m(int _reg, X64Reg acm)
|
||||||
{
|
{
|
||||||
// return g_dsp.r[DSP_REG_ACM0 + _reg];
|
// return g_dsp.r[DSP_REG_ACM0 + _reg];
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVSX(64, 16, acm, MDisp(R11, (DSP_REG_ACM0 + _reg) * 2));
|
MOVSX(64, 16, acm, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ac[_reg].m)));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -630,8 +669,8 @@ void DSPEmitter::set_acc_m(int _reg)
|
||||||
{
|
{
|
||||||
// return g_dsp.r[DSP_REG_ACM0 + _reg];
|
// return g_dsp.r[DSP_REG_ACM0 + _reg];
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOV(16, MDisp(R11, (DSP_REG_ACM0 + _reg) * 2), R(RAX));
|
MOV(16, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ac[_reg].m)), R(RAX));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -640,10 +679,15 @@ void DSPEmitter::get_long_acx(int _reg, X64Reg acx)
|
||||||
{
|
{
|
||||||
// return ((u32)g_dsp.r[DSP_REG_AXH0 + _reg] << 16) | g_dsp.r[DSP_REG_AXL0 + _reg];
|
// return ((u32)g_dsp.r[DSP_REG_AXH0 + _reg] << 16) | g_dsp.r[DSP_REG_AXL0 + _reg];
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
#if 0
|
||||||
MOVSX(64, 16, acx, MDisp(R11, (DSP_REG_AXH0 + _reg) * 2));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
|
MOVSX(64, 16, acx, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ax[_reg].h)));
|
||||||
SHL(64, R(acx), Imm8(16));
|
SHL(64, R(acx), Imm8(16));
|
||||||
OR(16, R(acx), MDisp(R11, (DSP_REG_AXL0 + _reg) * 2));
|
OR(16, R(acx), MDisp(R11, STRUCT_OFFSET(g_dsp._r, ax[_reg].l)));
|
||||||
|
#else
|
||||||
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
|
MOVSX(64, 32, acx, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ax[_reg].val)));
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -652,8 +696,8 @@ void DSPEmitter::get_ax_l(int _reg, X64Reg axl)
|
||||||
{
|
{
|
||||||
// return (s16)g_dsp.r[DSP_REG_AXL0 + _reg];
|
// return (s16)g_dsp.r[DSP_REG_AXL0 + _reg];
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVSX(64, 16, axl, MDisp(R11, (DSP_REG_AXL0 + _reg) * 2));
|
MOVSX(64, 16, axl, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ax[_reg].l)));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -662,9 +706,7 @@ void DSPEmitter::get_ax_h(int _reg, X64Reg axh)
|
||||||
{
|
{
|
||||||
// return (s16)g_dsp.r[DSP_REG_AXH0 + _reg];
|
// return (s16)g_dsp.r[DSP_REG_AXH0 + _reg];
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp._r));
|
||||||
MOVSX(64, 16, axh, MDisp(R11, (DSP_REG_AXH0 + _reg) * 2));
|
MOVSX(64, 16, axh, MDisp(R11, STRUCT_OFFSET(g_dsp._r, ax[_reg].h)));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
// Copyright (C) 2010 Dolphin Project.
|
||||||
|
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
|
// Official SVN repository and contact information can be found at
|
||||||
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
#ifndef __DSPJITUTIL_H__
|
||||||
|
#define __DSPJITUTIL_H__
|
||||||
|
|
||||||
|
#include "../DSPMemoryMap.h"
|
||||||
|
#include "../DSPHWInterface.h"
|
||||||
|
#include "../DSPEmitter.h"
|
||||||
|
|
||||||
|
static u16 *reg_ptr(int reg) {
|
||||||
|
switch(reg) {
|
||||||
|
case DSP_REG_AR0:
|
||||||
|
case DSP_REG_AR1:
|
||||||
|
case DSP_REG_AR2:
|
||||||
|
case DSP_REG_AR3:
|
||||||
|
return &g_dsp._r.ar[reg - DSP_REG_AR0];
|
||||||
|
case DSP_REG_IX0:
|
||||||
|
case DSP_REG_IX1:
|
||||||
|
case DSP_REG_IX2:
|
||||||
|
case DSP_REG_IX3:
|
||||||
|
return &g_dsp._r.ix[reg - DSP_REG_IX0];
|
||||||
|
case DSP_REG_WR0:
|
||||||
|
case DSP_REG_WR1:
|
||||||
|
case DSP_REG_WR2:
|
||||||
|
case DSP_REG_WR3:
|
||||||
|
return &g_dsp._r.wr[reg - DSP_REG_WR0];
|
||||||
|
case DSP_REG_ST0:
|
||||||
|
case DSP_REG_ST1:
|
||||||
|
case DSP_REG_ST2:
|
||||||
|
case DSP_REG_ST3:
|
||||||
|
return &g_dsp._r.st[reg - DSP_REG_ST0];
|
||||||
|
case DSP_REG_ACH0:
|
||||||
|
case DSP_REG_ACH1:
|
||||||
|
return &g_dsp._r.ac[reg - DSP_REG_ACH0].h;
|
||||||
|
case DSP_REG_CR: return &g_dsp._r.cr;
|
||||||
|
case DSP_REG_SR: return &g_dsp._r.sr;
|
||||||
|
case DSP_REG_PRODL: return &g_dsp._r.prod.l;
|
||||||
|
case DSP_REG_PRODM: return &g_dsp._r.prod.m;
|
||||||
|
case DSP_REG_PRODH: return &g_dsp._r.prod.h;
|
||||||
|
case DSP_REG_PRODM2: return &g_dsp._r.prod.m2;
|
||||||
|
case DSP_REG_AXL0:
|
||||||
|
case DSP_REG_AXL1:
|
||||||
|
return &g_dsp._r.ax[reg - DSP_REG_AXL0].l;
|
||||||
|
case DSP_REG_AXH0:
|
||||||
|
case DSP_REG_AXH1:
|
||||||
|
return &g_dsp._r.ax[reg - DSP_REG_AXH0].h;
|
||||||
|
case DSP_REG_ACL0:
|
||||||
|
case DSP_REG_ACL1:
|
||||||
|
return &g_dsp._r.ac[reg - DSP_REG_ACL0].l;
|
||||||
|
case DSP_REG_ACM0:
|
||||||
|
case DSP_REG_ACM1:
|
||||||
|
return &g_dsp._r.ac[reg - DSP_REG_ACM0].m;
|
||||||
|
default:
|
||||||
|
_assert_msg_(DSP_JIT, 0, "cannot happen");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /*__DSPJITUTIL_H__*/
|
|
@ -26,7 +26,7 @@ wxString CRegTable::GetValue(int row, int col)
|
||||||
switch (col)
|
switch (col)
|
||||||
{
|
{
|
||||||
case 0: return wxString::FromAscii(pdregname(row));
|
case 0: return wxString::FromAscii(pdregname(row));
|
||||||
case 1: return wxString::Format(wxT("0x%04x"), g_dsp.r[row]);
|
case 1: return wxString::Format(wxT("0x%04x"), DSPCore_ReadRegister(row));
|
||||||
default: return wxString::FromAscii("");
|
default: return wxString::FromAscii("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,8 +48,8 @@ void CRegTable::UpdateCachedRegs()
|
||||||
|
|
||||||
for (int i = 0; i < 32; ++i)
|
for (int i = 0; i < 32; ++i)
|
||||||
{
|
{
|
||||||
m_CachedRegHasChanged[i] = (m_CachedRegs[i] != g_dsp.r[i]);
|
m_CachedRegHasChanged[i] = (m_CachedRegs[i] != DSPCore_ReadRegister(i));
|
||||||
m_CachedRegs[i] = g_dsp.r[i];
|
m_CachedRegs[i] = DSPCore_ReadRegister(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue