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 s(const UDSPInstruction opc);
void sn(const UDSPInstruction opc); void sn(const UDSPInstruction opc);
void ld(const UDSPInstruction opc); void ld(const UDSPInstruction opc);
void ldax(const UDSPInstruction opc);
void ldn(const UDSPInstruction opc); void ldn(const UDSPInstruction opc);
void ldaxn(const UDSPInstruction opc);
void ldm(const UDSPInstruction opc); void ldm(const UDSPInstruction opc);
void ldaxm(const UDSPInstruction opc);
void ldnm(const UDSPInstruction opc); void ldnm(const UDSPInstruction opc);
void ldaxnm(const UDSPInstruction opc);
void mv(const UDSPInstruction opc); void mv(const UDSPInstruction opc);
void dr(const UDSPInstruction opc); void dr(const UDSPInstruction opc);
void ir(const UDSPInstruction opc); void ir(const UDSPInstruction opc);

View File

@ -344,7 +344,6 @@ void ld(const UDSPInstruction opc)
u8 rreg = (opc >> 4) & 0x1; u8 rreg = (opc >> 4) & 0x1;
u8 sreg = opc & 0x3; 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])) if (IsSameMemArea(g_dsp.r.ar[sreg], g_dsp.r.ar[3]))
@ -353,16 +352,25 @@ void ld(const UDSPInstruction opc)
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r.ar[3])); 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 {
writeToBackLog(0, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp.r.ar[dreg]));
if (IsSameMemArea(g_dsp.r.ar[dreg], g_dsp.r.ar[3])) writeToBackLog(3, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3));
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[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 else
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[3])); writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[3]));
writeToBackLog(2, dreg, dsp_increment_addr_reg(dreg)); writeToBackLog(2, sreg, dsp_increment_addr_reg(sreg));
}
writeToBackLog(3, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3)); writeToBackLog(3, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3));
} }
@ -375,7 +383,6 @@ void ldn(const UDSPInstruction opc)
u8 rreg = (opc >> 4) & 0x1; u8 rreg = (opc >> 4) & 0x1;
u8 sreg = opc & 0x3; 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])) if (IsSameMemArea(g_dsp.r.ar[sreg], g_dsp.r.ar[3]))
@ -384,16 +391,25 @@ void ldn(const UDSPInstruction opc)
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r.ar[3])); 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])); 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]));
if (IsSameMemArea(g_dsp.r.ar[dreg], g_dsp.r.ar[3])) writeToBackLog(3, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3));
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[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 else
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[3])); 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.ix[dreg])); 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)); writeToBackLog(3, DSP_REG_AR3, dsp_increment_addr_reg(DSP_REG_AR3));
} }
@ -406,7 +422,6 @@ void ldm(const UDSPInstruction opc)
u8 rreg = (opc >> 4) & 0x1; u8 rreg = (opc >> 4) & 0x1;
u8 sreg = opc & 0x3; 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])) if (IsSameMemArea(g_dsp.r.ar[sreg], g_dsp.r.ar[3]))
@ -415,16 +430,26 @@ void ldm(const UDSPInstruction opc)
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r.ar[3])); 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 {
writeToBackLog(0, rreg + DSP_REG_AXH0, dsp_dmem_read(g_dsp.r.ar[dreg]));
if (IsSameMemArea(g_dsp.r.ar[dreg], g_dsp.r.ar[3])) writeToBackLog(3, DSP_REG_AR3,
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[dreg])); dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r.ix[3]));
}
// 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 else
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[3])); writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[3]));
writeToBackLog(2, dreg, dsp_increment_addr_reg(dreg)); writeToBackLog(2, sreg, dsp_increment_addr_reg(sreg));
}
writeToBackLog(3, DSP_REG_AR3, writeToBackLog(3, DSP_REG_AR3,
dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r.ix[3])); dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r.ix[3]));
@ -438,7 +463,6 @@ void ldnm(const UDSPInstruction opc)
u8 rreg = (opc >> 4) & 0x1; u8 rreg = (opc >> 4) & 0x1;
u8 sreg = opc & 0x3; 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])) if (IsSameMemArea(g_dsp.r.ar[sreg], g_dsp.r.ar[3]))
@ -447,16 +471,26 @@ void ldnm(const UDSPInstruction opc)
writeToBackLog(1, (rreg << 1) + DSP_REG_AXL1, dsp_dmem_read(g_dsp.r.ar[3])); 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])); 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]));
if (IsSameMemArea(g_dsp.r.ar[dreg], g_dsp.r.ar[3])) writeToBackLog(3, DSP_REG_AR3,
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[dreg])); dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r.ix[3]));
}
// 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 else
writeToBackLog(1, rreg + DSP_REG_AXL0, dsp_dmem_read(g_dsp.r.ar[3])); 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.ix[dreg])); writeToBackLog(2, sreg, dsp_increase_addr_reg(sreg, (s16)g_dsp.r.ix[sreg]));
}
writeToBackLog(3, DSP_REG_AR3, writeToBackLog(3, DSP_REG_AR3,
dsp_increase_addr_reg(DSP_REG_AR3, (s16)g_dsp.r.ix[3])); 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 s(const UDSPInstruction opc);
void sn(const UDSPInstruction opc); void sn(const UDSPInstruction opc);
void ld(const UDSPInstruction opc); void ld(const UDSPInstruction opc);
void ldax(const UDSPInstruction opc);
void ldn(const UDSPInstruction opc); void ldn(const UDSPInstruction opc);
void ldaxn(const UDSPInstruction opc);
void ldm(const UDSPInstruction opc); void ldm(const UDSPInstruction opc);
void ldaxm(const UDSPInstruction opc);
void ldnm(const UDSPInstruction opc); void ldnm(const UDSPInstruction opc);
void ldaxnm(const UDSPInstruction opc);
void mv(const UDSPInstruction opc); void mv(const UDSPInstruction opc);
void dr(const UDSPInstruction opc); void dr(const UDSPInstruction opc);
void ir(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}, {"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}, {"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}, {"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}, {"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}, {"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},
@ -540,7 +545,12 @@ void InitInstructionTable()
if (extOpTable[i] == &cw) if (extOpTable[i] == &cw)
extOpTable[i] = &opcodes_ext[j]; extOpTable[i] = &opcodes_ext[j];
else 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);
}
} }
} }
} }

View File

@ -415,16 +415,12 @@ void DSPEmitter::slnm(const UDSPInstruction opc)
// points into an invalid memory page (ie 0x2000), then AX0.H keeps its old // 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 // 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) // 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) void DSPEmitter::ld(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) {
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])) { // if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
@ -447,20 +443,29 @@ void DSPEmitter::ld(const UDSPInstruction opc)
increment_addr_reg(sreg); increment_addr_reg(sreg);
} else { increment_addr_reg(DSP_REG_AR3);
pushExtValueFromMem(rreg + DSP_REG_AXH0, dreg); }
// LDAX $axR, @$arS
// xxxx xxxx 11sr 0011
void DSPEmitter::ldax(const UDSPInstruction opc)
{
u8 sreg = (opc >> 5) & 0x1;
u8 rreg = (opc >> 4) & 0x1;
pushExtValueFromMem(rreg + DSP_REG_AXH0, sreg);
X64Reg tmp; X64Reg tmp;
gpr.getFreeXReg(tmp); gpr.getFreeXReg(tmp);
//if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3])) { //if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
dsp_op_read_reg(dreg, RCX, NONE); dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE); dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp)); XOR(16, R(ECX), R(tmp));
gpr.putXReg(tmp); gpr.putXReg(tmp);
DSPJitRegCache c(gpr); DSPJitRegCache c(gpr);
TEST(16, R(ECX), Imm16(0xfc00)); TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE, true); FixupBranch not_equal = J_CC(CC_NE, true);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, dreg); pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
gpr.flushRegs(c); gpr.flushRegs(c);
FixupBranch after = J(true); // else FixupBranch after = J(true); // else
SetJumpTarget(not_equal); SetJumpTarget(not_equal);
@ -468,8 +473,7 @@ void DSPEmitter::ld(const UDSPInstruction opc)
gpr.flushRegs(c); gpr.flushRegs(c);
SetJumpTarget(after); SetJumpTarget(after);
increment_addr_reg(dreg); increment_addr_reg(sreg);
}
increment_addr_reg(DSP_REG_AR3); increment_addr_reg(DSP_REG_AR3);
} }
@ -482,7 +486,6 @@ void DSPEmitter::ldn(const UDSPInstruction opc)
u8 rreg = (opc >> 4) & 0x1; u8 rreg = (opc >> 4) & 0x1;
u8 sreg = opc & 0x3; 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; X64Reg tmp;
@ -504,20 +507,30 @@ void DSPEmitter::ldn(const UDSPInstruction opc)
SetJumpTarget(after); SetJumpTarget(after);
increase_addr_reg(sreg, sreg); increase_addr_reg(sreg, sreg);
} else {
pushExtValueFromMem(rreg + DSP_REG_AXH0, dreg); increment_addr_reg(DSP_REG_AR3);
}
// 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; X64Reg tmp;
gpr.getFreeXReg(tmp); gpr.getFreeXReg(tmp);
//if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3])) { //if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
dsp_op_read_reg(dreg, RCX, NONE); dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE); dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp)); XOR(16, R(ECX), R(tmp));
gpr.putXReg(tmp); gpr.putXReg(tmp);
DSPJitRegCache c(gpr); DSPJitRegCache c(gpr);
TEST(16, R(ECX), Imm16(0xfc00)); TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE,true); FixupBranch not_equal = J_CC(CC_NE,true);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, dreg); pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
gpr.flushRegs(c); gpr.flushRegs(c);
FixupBranch after = J(true); // else FixupBranch after = J(true); // else
SetJumpTarget(not_equal); SetJumpTarget(not_equal);
@ -525,8 +538,7 @@ void DSPEmitter::ldn(const UDSPInstruction opc)
gpr.flushRegs(c); gpr.flushRegs(c);
SetJumpTarget(after); SetJumpTarget(after);
increase_addr_reg(dreg, dreg); increase_addr_reg(sreg, sreg);
}
increment_addr_reg(DSP_REG_AR3); increment_addr_reg(DSP_REG_AR3);
} }
@ -539,7 +551,6 @@ void DSPEmitter::ldm(const UDSPInstruction opc)
u8 rreg = (opc >> 4) & 0x1; u8 rreg = (opc >> 4) & 0x1;
u8 sreg = opc & 0x3; 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; X64Reg tmp;
@ -561,20 +572,30 @@ void DSPEmitter::ldm(const UDSPInstruction opc)
SetJumpTarget(after); SetJumpTarget(after);
increment_addr_reg(sreg); increment_addr_reg(sreg);
} else {
pushExtValueFromMem(rreg + DSP_REG_AXH0, dreg); increase_addr_reg(DSP_REG_AR3, DSP_REG_AR3);
}
// 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; X64Reg tmp;
gpr.getFreeXReg(tmp); gpr.getFreeXReg(tmp);
//if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3])) { //if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
dsp_op_read_reg(dreg, RCX, NONE); dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE); dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp)); XOR(16, R(ECX), R(tmp));
gpr.putXReg(tmp); gpr.putXReg(tmp);
DSPJitRegCache c(gpr); DSPJitRegCache c(gpr);
TEST(16, R(ECX), Imm16(0xfc00)); TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE,true); FixupBranch not_equal = J_CC(CC_NE,true);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, dreg); pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
gpr.flushRegs(c); gpr.flushRegs(c);
FixupBranch after = J(true); // else FixupBranch after = J(true); // else
SetJumpTarget(not_equal); SetJumpTarget(not_equal);
@ -582,8 +603,7 @@ void DSPEmitter::ldm(const UDSPInstruction opc)
gpr.flushRegs(c); gpr.flushRegs(c);
SetJumpTarget(after); SetJumpTarget(after);
increment_addr_reg(dreg); increment_addr_reg(sreg);
}
increase_addr_reg(DSP_REG_AR3, DSP_REG_AR3); increase_addr_reg(DSP_REG_AR3, DSP_REG_AR3);
} }
@ -596,7 +616,6 @@ void DSPEmitter::ldnm(const UDSPInstruction opc)
u8 rreg = (opc >> 4) & 0x1; u8 rreg = (opc >> 4) & 0x1;
u8 sreg = opc & 0x3; 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; X64Reg tmp;
@ -618,20 +637,30 @@ void DSPEmitter::ldnm(const UDSPInstruction opc)
SetJumpTarget(after); SetJumpTarget(after);
increase_addr_reg(sreg, sreg); increase_addr_reg(sreg, sreg);
} else {
pushExtValueFromMem(rreg + DSP_REG_AXH0, dreg); increase_addr_reg(DSP_REG_AR3, DSP_REG_AR3);
}
// 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; X64Reg tmp;
gpr.getFreeXReg(tmp); gpr.getFreeXReg(tmp);
//if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3])) { //if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
dsp_op_read_reg(dreg, RCX, NONE); dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE); dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp)); XOR(16, R(ECX), R(tmp));
gpr.putXReg(tmp); gpr.putXReg(tmp);
DSPJitRegCache c(gpr); DSPJitRegCache c(gpr);
TEST(16, R(ECX), Imm16(0xfc00)); TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE,true); FixupBranch not_equal = J_CC(CC_NE,true);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, dreg); pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
gpr.flushRegs(c); gpr.flushRegs(c);
FixupBranch after = J(true); // else FixupBranch after = J(true); // else
SetJumpTarget(not_equal); SetJumpTarget(not_equal);
@ -639,8 +668,7 @@ void DSPEmitter::ldnm(const UDSPInstruction opc)
gpr.flushRegs(c); gpr.flushRegs(c);
SetJumpTarget(after); SetJumpTarget(after);
increase_addr_reg(dreg, dreg); increase_addr_reg(sreg, sreg);
}
increase_addr_reg(DSP_REG_AR3, DSP_REG_AR3); increase_addr_reg(DSP_REG_AR3, DSP_REG_AR3);
} }