Core/DSP: Split extended opcode 0xc0/mask 0xc0 to account for 0xc3/mask 0xc3 variant

In assembly, these are 'ld $ax0.d,$ax1.r,@$arS with their n,m and nm variants,
which have been special cased for S==3. The regular 'ld can be decomposed
into lrri $ax0.d,@$arS and lrri $ax1.r,@$ar3, while the S==3 case decomposes
to lrri $axR.h,@$arD and lrri $axR.l,@$ar3. The latter variant will be
disassembled to 'ldax $axR,@$arD after this change. The assembler recognizes
both the new 'ldax variant and the old 'ld with @$ar3 but the disassembler
only outputs 'ldax. Besides the readability, this allows for more correct
register use analysis(when it's done).


git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7413 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
pierre 2011-03-25 22:28:18 +00:00
parent c99c247ed5
commit f8037e3ccf
5 changed files with 313 additions and 233 deletions

View File

@ -96,9 +96,13 @@ public:
void s(const UDSPInstruction opc);
void sn(const UDSPInstruction opc);
void ld(const UDSPInstruction opc);
void ldax(const UDSPInstruction opc);
void ldn(const UDSPInstruction opc);
void ldaxn(const UDSPInstruction opc);
void ldm(const UDSPInstruction opc);
void ldaxm(const UDSPInstruction opc);
void ldnm(const UDSPInstruction opc);
void ldaxnm(const UDSPInstruction opc);
void mv(const UDSPInstruction opc);
void dr(const UDSPInstruction opc);
void ir(const UDSPInstruction opc);

View File

@ -344,25 +344,33 @@ void ld(const UDSPInstruction opc)
u8 rreg = (opc >> 4) & 0x1;
u8 sreg = opc & 0x3;
if (sreg != DSP_REG_AR3) {
writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[sreg]));
writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[sreg]));
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.ar[sreg]));
else
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r.ar[3]));
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.ar[sreg]));
else
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r.ar[3]));
writeToBackLog(2, sreg, dsp_increment_addr_reg(sreg));
} else {
writeToBackLog(0, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp.r.ar[dreg]));
writeToBackLog(2, sreg, dsp_increment_addr_reg(sreg));
if (IsSameMemArea(g_dsp.r.ar[dreg], g_dsp.r.ar[3]))
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[dreg]));
else
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[3]));
writeToBackLog(3, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3));
}
writeToBackLog(2, dreg, dsp_increment_addr_reg(dreg));
}
// LDAX $axR, @$arS
// xxxx xxxx 11sr 0011
void ldax(const UDSPInstruction opc)
{
u8 sreg = (opc >> 5) & 0x1;
u8 rreg = (opc >> 4) & 0x1;
writeToBackLog(0, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp.r.ar[sreg]));
if (IsSameMemArea(g_dsp.r.ar[sreg], g_dsp.r.ar[3]))
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[sreg]));
else
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[3]));
writeToBackLog(2, sreg, dsp_increment_addr_reg(sreg));
writeToBackLog(3, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3));
}
@ -375,25 +383,33 @@ void ldn(const UDSPInstruction opc)
u8 rreg = (opc >> 4) & 0x1;
u8 sreg = opc & 0x3;
if (sreg != DSP_REG_AR3) {
writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[sreg]));
writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[sreg]));
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.ar[sreg]));
else
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r.ar[3]));
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.ar[sreg]));
else
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.ix[sreg]));
} else {
writeToBackLog(0, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp.r.ar[dreg]));
writeToBackLog(2, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r.ix[sreg]));
if (IsSameMemArea(g_dsp.r.ar[dreg], g_dsp.r.ar[3]))
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[dreg]));
else
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[3]));
writeToBackLog(3, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3));
}
writeToBackLog(2, dreg, dsp_increase_addr_reg(dreg, (s16)g_dsp.r.ix[dreg]));
}
// LDAXN $axR, @$arS
// xxxx xxxx 11sr 0111
void ldaxn(const UDSPInstruction opc)
{
u8 sreg = (opc >> 5) & 0x1;
u8 rreg = (opc >> 4) & 0x1;
writeToBackLog(0, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp.r.ar[sreg]));
if (IsSameMemArea(g_dsp.r.ar[sreg], g_dsp.r.ar[3]))
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[sreg]));
else
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[3]));
writeToBackLog(2, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r.ix[sreg]));
writeToBackLog(3, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3));
}
@ -406,25 +422,34 @@ void ldm(const UDSPInstruction opc)
u8 rreg = (opc >> 4) & 0x1;
u8 sreg = opc & 0x3;
if (sreg != DSP_REG_AR3) {
writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[sreg]));
writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[sreg]));
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.ar[sreg]));
else
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r.ar[3]));
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.ar[sreg]));
else
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r.ar[3]));
writeToBackLog(2, sreg, dsp_increment_addr_reg(sreg));
} else {
writeToBackLog(0, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp.r.ar[dreg]));
writeToBackLog(2, sreg, dsp_increment_addr_reg(sreg));
if (IsSameMemArea(g_dsp.r.ar[dreg], g_dsp.r.ar[3]))
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[dreg]));
else
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[3]));
writeToBackLog(3, DSP_REG_AR3,
dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r.ix[3]));
}
writeToBackLog(2, dreg, dsp_increment_addr_reg(dreg));
}
// LDAXM $axR, @$arS
// xxxx xxxx 11sr 1011
void ldaxm(const UDSPInstruction opc)
{
u8 sreg = (opc >> 5) & 0x1;
u8 rreg = (opc >> 4) & 0x1;
writeToBackLog(0, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp.r.ar[sreg]));
if (IsSameMemArea(g_dsp.r.ar[sreg], g_dsp.r.ar[3]))
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[sreg]));
else
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[3]));
writeToBackLog(2, sreg, dsp_increment_addr_reg(sreg));
writeToBackLog(3, DSP_REG_AR3,
dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r.ix[3]));
@ -438,25 +463,34 @@ void ldnm(const UDSPInstruction opc)
u8 rreg = (opc >> 4) & 0x1;
u8 sreg = opc & 0x3;
if (sreg != DSP_REG_AR3) {
writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[sreg]));
writeToBackLog(0, (dreg << 1) + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[sreg]));
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.ar[sreg]));
else
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r.ar[3]));
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.ar[sreg]));
else
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.ix[sreg]));
} else {
writeToBackLog(0, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp.r.ar[dreg]));
writeToBackLog(2, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r.ix[sreg]));
if (IsSameMemArea(g_dsp.r.ar[dreg], g_dsp.r.ar[3]))
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[dreg]));
else
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[3]));
writeToBackLog(3, DSP_REG_AR3,
dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r.ix[3]));
}
writeToBackLog(2, dreg, dsp_increase_addr_reg(dreg, (s16)g_dsp.r.ix[dreg]));
}
// LDAXNM $axR, @$arS
// xxxx xxxx 11dr 1111
void ldaxnm(const UDSPInstruction opc)
{
u8 sreg = (opc >> 5) & 0x1;
u8 rreg = (opc >> 4) & 0x1;
writeToBackLog(0, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp.r.ar[sreg]));
if (IsSameMemArea(g_dsp.r.ar[sreg], g_dsp.r.ar[3]))
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[sreg]));
else
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[3]));
writeToBackLog(2, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r.ix[sreg]));
writeToBackLog(3, DSP_REG_AR3,
dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r.ix[3]));

View File

@ -49,9 +49,13 @@ void slnm(const UDSPInstruction opc);
void s(const UDSPInstruction opc);
void sn(const UDSPInstruction opc);
void ld(const UDSPInstruction opc);
void ldax(const UDSPInstruction opc);
void ldn(const UDSPInstruction opc);
void ldaxn(const UDSPInstruction opc);
void ldm(const UDSPInstruction opc);
void ldaxm(const UDSPInstruction opc);
void ldnm(const UDSPInstruction opc);
void ldaxnm(const UDSPInstruction opc);
void mv(const UDSPInstruction opc);
void dr(const UDSPInstruction opc);
void ir(const UDSPInstruction opc);

View File

@ -329,6 +329,11 @@ const DSPOPCTemplate opcodes_ext[] =
{"LSNM", 0x008c, 0x00ce, DSPInterpreter::Ext::lsnm, &DSPEmitter::lsnm, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}}, false, false, false, false, false},
{"SLNM", 0x008e, 0x00ce, DSPInterpreter::Ext::slnm, &DSPEmitter::slnm, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}}, false, false, false, false, false},
{"LDAX", 0x00c3, 0x00cf, DSPInterpreter::Ext::ldax, &DSPEmitter::ldax, 1, 2, {{P_AX, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}}, false, false, false, false, false},
{"LDAXN", 0x00c7, 0x00cf, DSPInterpreter::Ext::ldaxn, &DSPEmitter::ldaxn, 1, 2, {{P_AX, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}}, false, false, false, false, false},
{"LDAXM", 0x00cb, 0x00cf, DSPInterpreter::Ext::ldaxm, &DSPEmitter::ldaxm, 1, 2, {{P_AX, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}}, false, false, false, false, false},
{"LDAXNM", 0x00cf, 0x00cf, DSPInterpreter::Ext::ldaxnm, &DSPEmitter::ldaxnm, 1, 2, {{P_AX, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}}, false, false, false, false, false},
{"LD", 0x00c0, 0x00cc, DSPInterpreter::Ext::ld, &DSPEmitter::ld, 1, 3, {{P_REGM18, 1, 0, 4, 0x0020}, {P_REGM19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}}, false, false, false, false, false},
{"LDN", 0x00c4, 0x00cc, DSPInterpreter::Ext::ldn, &DSPEmitter::ldn, 1, 3, {{P_REGM18, 1, 0, 4, 0x0020}, {P_REGM19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}}, false, false, false, false, false},
{"LDM", 0x00c8, 0x00cc, DSPInterpreter::Ext::ldm, &DSPEmitter::ldm, 1, 3, {{P_REGM18, 1, 0, 4, 0x0020}, {P_REGM19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}}, false, false, false, false, false},
@ -527,22 +532,27 @@ const DSPOPCTemplate *GetOpTemplate(const UDSPInstruction &inst)
void InitInstructionTable()
{
// ext op table
for (int i = 0; i < EXT_OPTABLE_SIZE; i++)
for (int i = 0; i < EXT_OPTABLE_SIZE; i++)
extOpTable[i] = &cw;
for (int i = 0; i < EXT_OPTABLE_SIZE; i++)
for (int i = 0; i < EXT_OPTABLE_SIZE; i++)
{
for (int j = 0; j < opcodes_ext_size; j++)
{
u16 mask = opcodes_ext[j].opcode_mask;
if ((mask & i) == opcodes_ext[j].opcode)
if ((mask & i) == opcodes_ext[j].opcode)
{
if (extOpTable[i] == &cw)
if (extOpTable[i] == &cw)
extOpTable[i] = &opcodes_ext[j];
else
ERROR_LOG(DSPLLE, "opcode ext table place %d already in use for %s", i, opcodes_ext[j].name);
{
//if the entry already in the table
//is a strict subset, allow it
if ((extOpTable[i]->opcode_mask | opcodes_ext[j].opcode_mask) != extOpTable[i]->opcode_mask)
ERROR_LOG(DSPLLE, "opcode ext table place %d already in use by %s when inserting %s", i, extOpTable[i]->name, opcodes_ext[j].name);
}
}
}
}
}
// op table

View File

@ -415,61 +415,65 @@ void DSPEmitter::slnm(const UDSPInstruction opc)
// points into an invalid memory page (ie 0x2000), then AX0.H keeps its old
// value. (not implemented yet) If AR3 points into an invalid memory page, then
// AX0.L gets the same value as AX0.H. (not implemented yet)
// LD $axr.h, @$ard
// xxxx xxxx 11dr 0011
void DSPEmitter::ld(const UDSPInstruction opc)
{
u8 dreg = (opc >> 5) & 0x1;
u8 rreg = (opc >> 4) & 0x1;
u8 sreg = opc & 0x3;
if (sreg != DSP_REG_AR3) {
pushExtValueFromMem((dreg << 1) + DSP_REG_AXL0, sreg);
pushExtValueFromMem((dreg << 1) + DSP_REG_AXL0, sreg);
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
X64Reg tmp;
gpr.getFreeXReg(tmp);
dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.putXReg(tmp);
DSPJitRegCache c(gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE,true);
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
gpr.flushRegs(c);
FixupBranch after = J(true);
SetJumpTarget(not_equal); // else
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
gpr.flushRegs(c);
SetJumpTarget(after);
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
X64Reg tmp;
gpr.getFreeXReg(tmp);
dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.putXReg(tmp);
DSPJitRegCache c(gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE,true);
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
gpr.flushRegs(c);
FixupBranch after = J(true);
SetJumpTarget(not_equal); // else
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
gpr.flushRegs(c);
SetJumpTarget(after);
increment_addr_reg(sreg);
increment_addr_reg(sreg);
} else {
pushExtValueFromMem(rreg + DSP_REG_AXH0, dreg);
increment_addr_reg(DSP_REG_AR3);
}
X64Reg tmp;
gpr.getFreeXReg(tmp);
//if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3])) {
dsp_op_read_reg(dreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.putXReg(tmp);
DSPJitRegCache c(gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE, true);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, dreg);
gpr.flushRegs(c);
FixupBranch after = J(true); // else
SetJumpTarget(not_equal);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
gpr.flushRegs(c);
SetJumpTarget(after);
// LDAX $axR, @$arS
// xxxx xxxx 11sr 0011
void DSPEmitter::ldax(const UDSPInstruction opc)
{
u8 sreg = (opc >> 5) & 0x1;
u8 rreg = (opc >> 4) & 0x1;
increment_addr_reg(dreg);
}
pushExtValueFromMem(rreg + DSP_REG_AXH0, sreg);
X64Reg tmp;
gpr.getFreeXReg(tmp);
//if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.putXReg(tmp);
DSPJitRegCache c(gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE, true);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
gpr.flushRegs(c);
FixupBranch after = J(true); // else
SetJumpTarget(not_equal);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
gpr.flushRegs(c);
SetJumpTarget(after);
increment_addr_reg(sreg);
increment_addr_reg(DSP_REG_AR3);
}
@ -482,51 +486,59 @@ void DSPEmitter::ldn(const UDSPInstruction opc)
u8 rreg = (opc >> 4) & 0x1;
u8 sreg = opc & 0x3;
if (sreg != DSP_REG_AR3) {
pushExtValueFromMem((dreg << 1) + DSP_REG_AXL0, sreg);
pushExtValueFromMem((dreg << 1) + DSP_REG_AXL0, sreg);
X64Reg tmp;
gpr.getFreeXReg(tmp);
//if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.putXReg(tmp);
DSPJitRegCache c(gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE,true);
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
gpr.flushRegs(c);
FixupBranch after = J(true);
SetJumpTarget(not_equal); // else
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
gpr.flushRegs(c);
SetJumpTarget(after);
X64Reg tmp;
gpr.getFreeXReg(tmp);
//if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.putXReg(tmp);
DSPJitRegCache c(gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE,true);
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
gpr.flushRegs(c);
FixupBranch after = J(true);
SetJumpTarget(not_equal); // else
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
gpr.flushRegs(c);
SetJumpTarget(after);
increase_addr_reg(sreg, sreg);
} else {
pushExtValueFromMem(rreg + DSP_REG_AXH0, dreg);
increase_addr_reg(sreg, sreg);
X64Reg tmp;
gpr.getFreeXReg(tmp);
//if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3])) {
dsp_op_read_reg(dreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.putXReg(tmp);
DSPJitRegCache c(gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE,true);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, dreg);
gpr.flushRegs(c);
FixupBranch after = J(true); // else
SetJumpTarget(not_equal);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
gpr.flushRegs(c);
SetJumpTarget(after);
increment_addr_reg(DSP_REG_AR3);
}
increase_addr_reg(dreg, dreg);
}
// LDAXN $axR, @$arS
// xxxx xxxx 11sr 0111
void DSPEmitter::ldaxn(const UDSPInstruction opc)
{
u8 sreg = (opc >> 5) & 0x1;
u8 rreg = (opc >> 4) & 0x1;
pushExtValueFromMem(rreg + DSP_REG_AXH0, sreg);
X64Reg tmp;
gpr.getFreeXReg(tmp);
//if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.putXReg(tmp);
DSPJitRegCache c(gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE,true);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
gpr.flushRegs(c);
FixupBranch after = J(true); // else
SetJumpTarget(not_equal);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
gpr.flushRegs(c);
SetJumpTarget(after);
increase_addr_reg(sreg, sreg);
increment_addr_reg(DSP_REG_AR3);
}
@ -539,51 +551,59 @@ void DSPEmitter::ldm(const UDSPInstruction opc)
u8 rreg = (opc >> 4) & 0x1;
u8 sreg = opc & 0x3;
if (sreg != DSP_REG_AR3) {
pushExtValueFromMem((dreg << 1) + DSP_REG_AXL0, sreg);
pushExtValueFromMem((dreg << 1) + DSP_REG_AXL0, sreg);
X64Reg tmp;
gpr.getFreeXReg(tmp);
//if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.putXReg(tmp);
DSPJitRegCache c(gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE,true);
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
gpr.flushRegs(c);
FixupBranch after = J(true);
SetJumpTarget(not_equal); // else
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
gpr.flushRegs(c);
SetJumpTarget(after);
X64Reg tmp;
gpr.getFreeXReg(tmp);
//if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.putXReg(tmp);
DSPJitRegCache c(gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE,true);
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
gpr.flushRegs(c);
FixupBranch after = J(true);
SetJumpTarget(not_equal); // else
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
gpr.flushRegs(c);
SetJumpTarget(after);
increment_addr_reg(sreg);
} else {
pushExtValueFromMem(rreg + DSP_REG_AXH0, dreg);
increment_addr_reg(sreg);
X64Reg tmp;
gpr.getFreeXReg(tmp);
//if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3])) {
dsp_op_read_reg(dreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.putXReg(tmp);
DSPJitRegCache c(gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE,true);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, dreg);
gpr.flushRegs(c);
FixupBranch after = J(true); // else
SetJumpTarget(not_equal);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
gpr.flushRegs(c);
SetJumpTarget(after);
increase_addr_reg(DSP_REG_AR3, DSP_REG_AR3);
}
increment_addr_reg(dreg);
}
// LDAXM $axR, @$arS
// xxxx xxxx 11sr 1011
void DSPEmitter::ldaxm(const UDSPInstruction opc)
{
u8 sreg = (opc >> 5) & 0x1;
u8 rreg = (opc >> 4) & 0x1;
pushExtValueFromMem(rreg + DSP_REG_AXH0, sreg);
X64Reg tmp;
gpr.getFreeXReg(tmp);
//if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.putXReg(tmp);
DSPJitRegCache c(gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE,true);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
gpr.flushRegs(c);
FixupBranch after = J(true); // else
SetJumpTarget(not_equal);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
gpr.flushRegs(c);
SetJumpTarget(after);
increment_addr_reg(sreg);
increase_addr_reg(DSP_REG_AR3, DSP_REG_AR3);
}
@ -596,51 +616,59 @@ void DSPEmitter::ldnm(const UDSPInstruction opc)
u8 rreg = (opc >> 4) & 0x1;
u8 sreg = opc & 0x3;
if (sreg != DSP_REG_AR3) {
pushExtValueFromMem((dreg << 1) + DSP_REG_AXL0, sreg);
pushExtValueFromMem((dreg << 1) + DSP_REG_AXL0, sreg);
X64Reg tmp;
gpr.getFreeXReg(tmp);
//if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.putXReg(tmp);
DSPJitRegCache c(gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE,true);
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
gpr.flushRegs(c);
FixupBranch after = J(true);
SetJumpTarget(not_equal); // else
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
gpr.flushRegs(c);
SetJumpTarget(after);
X64Reg tmp;
gpr.getFreeXReg(tmp);
//if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.putXReg(tmp);
DSPJitRegCache c(gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE,true);
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
gpr.flushRegs(c);
FixupBranch after = J(true);
SetJumpTarget(not_equal); // else
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
gpr.flushRegs(c);
SetJumpTarget(after);
increase_addr_reg(sreg, sreg);
} else {
pushExtValueFromMem(rreg + DSP_REG_AXH0, dreg);
increase_addr_reg(sreg, sreg);
X64Reg tmp;
gpr.getFreeXReg(tmp);
//if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3])) {
dsp_op_read_reg(dreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.putXReg(tmp);
DSPJitRegCache c(gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE,true);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, dreg);
gpr.flushRegs(c);
FixupBranch after = J(true); // else
SetJumpTarget(not_equal);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
gpr.flushRegs(c);
SetJumpTarget(after);
increase_addr_reg(DSP_REG_AR3, DSP_REG_AR3);
}
increase_addr_reg(dreg, dreg);
}
// LDAXNM $axR, @$arS
// xxxx xxxx 11sr 1111
void DSPEmitter::ldaxnm(const UDSPInstruction opc)
{
u8 sreg = (opc >> 5) & 0x1;
u8 rreg = (opc >> 4) & 0x1;
pushExtValueFromMem(rreg + DSP_REG_AXH0, sreg);
X64Reg tmp;
gpr.getFreeXReg(tmp);
//if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.putXReg(tmp);
DSPJitRegCache c(gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE,true);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
gpr.flushRegs(c);
FixupBranch after = J(true); // else
SetJumpTarget(not_equal);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
gpr.flushRegs(c);
SetJumpTarget(after);
increase_addr_reg(sreg, sreg);
increase_addr_reg(DSP_REG_AR3, DSP_REG_AR3);
}