mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 21:37:52 -07:00
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 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);
|
||||
|
@ -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]));
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user