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:
parent
c99c247ed5
commit
f8037e3ccf
|
@ -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);
|
||||||
|
|
|
@ -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]));
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue