From f8037e3ccf7723c2c02f7cfae74128561e304727 Mon Sep 17 00:00:00 2001 From: pierre Date: Fri, 25 Mar 2011 22:28:18 +0000 Subject: [PATCH] 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 --- Source/Core/Core/Src/DSP/DSPEmitter.h | 4 + Source/Core/Core/Src/DSP/DSPIntExtOps.cpp | 154 +++++--- Source/Core/Core/Src/DSP/DSPIntExtOps.h | 4 + Source/Core/Core/Src/DSP/DSPTables.cpp | 22 +- Source/Core/Core/Src/DSP/Jit/DSPJitExtOps.cpp | 362 ++++++++++-------- 5 files changed, 313 insertions(+), 233 deletions(-) diff --git a/Source/Core/Core/Src/DSP/DSPEmitter.h b/Source/Core/Core/Src/DSP/DSPEmitter.h index fc51e1d376..19b90ff089 100644 --- a/Source/Core/Core/Src/DSP/DSPEmitter.h +++ b/Source/Core/Core/Src/DSP/DSPEmitter.h @@ -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); diff --git a/Source/Core/Core/Src/DSP/DSPIntExtOps.cpp b/Source/Core/Core/Src/DSP/DSPIntExtOps.cpp index 4eff38b240..274332f54d 100644 --- a/Source/Core/Core/Src/DSP/DSPIntExtOps.cpp +++ b/Source/Core/Core/Src/DSP/DSPIntExtOps.cpp @@ -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])); diff --git a/Source/Core/Core/Src/DSP/DSPIntExtOps.h b/Source/Core/Core/Src/DSP/DSPIntExtOps.h index 46b809ca14..33420a5b76 100644 --- a/Source/Core/Core/Src/DSP/DSPIntExtOps.h +++ b/Source/Core/Core/Src/DSP/DSPIntExtOps.h @@ -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); diff --git a/Source/Core/Core/Src/DSP/DSPTables.cpp b/Source/Core/Core/Src/DSP/DSPTables.cpp index db0db9bee7..995b21e536 100644 --- a/Source/Core/Core/Src/DSP/DSPTables.cpp +++ b/Source/Core/Core/Src/DSP/DSPTables.cpp @@ -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 diff --git a/Source/Core/Core/Src/DSP/Jit/DSPJitExtOps.cpp b/Source/Core/Core/Src/DSP/Jit/DSPJitExtOps.cpp index 5e0bece632..46527f8256 100644 --- a/Source/Core/Core/Src/DSP/Jit/DSPJitExtOps.cpp +++ b/Source/Core/Core/Src/DSP/Jit/DSPJitExtOps.cpp @@ -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); }