mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-21 21:30:19 -06:00
LLE JIT:
* Completed the JIT versions of the DSP arithmetic instructions (28 instructions added). * Added JIT versions of maddx and msubx (thanks to LM1234). x64 only git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6652 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -52,6 +52,8 @@ public:
|
|||||||
void Update_SR_Register64(Gen::X64Reg val = Gen::EAX);
|
void Update_SR_Register64(Gen::X64Reg val = Gen::EAX);
|
||||||
void Update_SR_Register64_Carry(Gen::X64Reg val = Gen::EAX);
|
void Update_SR_Register64_Carry(Gen::X64Reg val = Gen::EAX);
|
||||||
void Update_SR_Register64_Carry2(Gen::X64Reg val = Gen::EAX);
|
void Update_SR_Register64_Carry2(Gen::X64Reg val = Gen::EAX);
|
||||||
|
void Update_SR_Register16(Gen::X64Reg val = Gen::EAX);
|
||||||
|
void Update_SR_Register16_OverS32(Gen::X64Reg val = Gen::EAX);
|
||||||
|
|
||||||
// Register helpers
|
// Register helpers
|
||||||
void setCompileSR(u16 bit);
|
void setCompileSR(u16 bit);
|
||||||
@ -147,11 +149,31 @@ public:
|
|||||||
void ilrri(const UDSPInstruction opc);
|
void ilrri(const UDSPInstruction opc);
|
||||||
|
|
||||||
// Arithmetic
|
// Arithmetic
|
||||||
|
void clr(const UDSPInstruction opc);
|
||||||
|
void clrl(const UDSPInstruction opc);
|
||||||
|
void andcf(const UDSPInstruction opc);
|
||||||
|
void andf(const UDSPInstruction opc);
|
||||||
void tst(const UDSPInstruction opc);
|
void tst(const UDSPInstruction opc);
|
||||||
|
void tstaxh(const UDSPInstruction opc);
|
||||||
|
void cmp(const UDSPInstruction opc);
|
||||||
|
void cmpar(const UDSPInstruction opc);
|
||||||
|
void cmpi(const UDSPInstruction opc);
|
||||||
|
void cmpis(const UDSPInstruction opc);
|
||||||
|
void xorr(const UDSPInstruction opc);
|
||||||
|
void andr(const UDSPInstruction opc);
|
||||||
|
void orr(const UDSPInstruction opc);
|
||||||
|
void andc(const UDSPInstruction opc);
|
||||||
|
void orc(const UDSPInstruction opc);
|
||||||
|
void xorc(const UDSPInstruction opc);
|
||||||
|
void notc(const UDSPInstruction opc);
|
||||||
|
void xori(const UDSPInstruction opc);
|
||||||
|
void andi(const UDSPInstruction opc);
|
||||||
|
void ori(const UDSPInstruction opc);
|
||||||
void addr(const UDSPInstruction opc);
|
void addr(const UDSPInstruction opc);
|
||||||
void addax(const UDSPInstruction opc);
|
void addax(const UDSPInstruction opc);
|
||||||
void add(const UDSPInstruction opc);
|
void add(const UDSPInstruction opc);
|
||||||
void addp(const UDSPInstruction opc);
|
void addp(const UDSPInstruction opc);
|
||||||
|
void addaxl(const UDSPInstruction opc);
|
||||||
void addi(const UDSPInstruction opc);
|
void addi(const UDSPInstruction opc);
|
||||||
void addis(const UDSPInstruction opc);
|
void addis(const UDSPInstruction opc);
|
||||||
void incm(const UDSPInstruction opc);
|
void incm(const UDSPInstruction opc);
|
||||||
@ -171,7 +193,15 @@ public:
|
|||||||
void lsr16(const UDSPInstruction opc);
|
void lsr16(const UDSPInstruction opc);
|
||||||
void asr16(const UDSPInstruction opc);
|
void asr16(const UDSPInstruction opc);
|
||||||
void lsl(const UDSPInstruction opc);
|
void lsl(const UDSPInstruction opc);
|
||||||
|
void lsr(const UDSPInstruction opc);
|
||||||
void asl(const UDSPInstruction opc);
|
void asl(const UDSPInstruction opc);
|
||||||
|
void asr(const UDSPInstruction opc);
|
||||||
|
void lsrn(const UDSPInstruction opc);
|
||||||
|
void asrn(const UDSPInstruction opc);
|
||||||
|
void lsrnrx(const UDSPInstruction opc);
|
||||||
|
void asrnrx(const UDSPInstruction opc);
|
||||||
|
void lsrnr(const UDSPInstruction opc);
|
||||||
|
void asrnr(const UDSPInstruction opc);
|
||||||
|
|
||||||
// Multipliers
|
// Multipliers
|
||||||
void get_multiply_prod();
|
void get_multiply_prod();
|
||||||
@ -192,6 +222,8 @@ public:
|
|||||||
void mulcac(const UDSPInstruction opc);
|
void mulcac(const UDSPInstruction opc);
|
||||||
void mulcmv(const UDSPInstruction opc);
|
void mulcmv(const UDSPInstruction opc);
|
||||||
void mulcmvz(const UDSPInstruction opc);
|
void mulcmvz(const UDSPInstruction opc);
|
||||||
|
void maddx(const UDSPInstruction opc);
|
||||||
|
void msubx(const UDSPInstruction opc);
|
||||||
void maddc(const UDSPInstruction opc);
|
void maddc(const UDSPInstruction opc);
|
||||||
void msubc(const UDSPInstruction opc);
|
void msubc(const UDSPInstruction opc);
|
||||||
void madd(const UDSPInstruction opc);
|
void madd(const UDSPInstruction opc);
|
||||||
@ -223,11 +255,13 @@ private:
|
|||||||
void get_long_prod(Gen::X64Reg long_prod = Gen::RAX);
|
void get_long_prod(Gen::X64Reg long_prod = Gen::RAX);
|
||||||
void get_long_prod_round_prodl(Gen::X64Reg long_prod = Gen::RAX);
|
void get_long_prod_round_prodl(Gen::X64Reg long_prod = Gen::RAX);
|
||||||
void set_long_prod();
|
void set_long_prod();
|
||||||
|
void round_long_acc(Gen::X64Reg long_acc = Gen::EAX);
|
||||||
void set_long_acc(int _reg, Gen::X64Reg acc = Gen::EAX);
|
void set_long_acc(int _reg, Gen::X64Reg acc = Gen::EAX);
|
||||||
void get_acc_m(int _reg);
|
void get_acc_m(int _reg, Gen::X64Reg acc = Gen::EAX);
|
||||||
|
void set_acc_m(int _reg);
|
||||||
void get_long_acx(int _reg, Gen::X64Reg acx = Gen::EAX);
|
void get_long_acx(int _reg, Gen::X64Reg acx = Gen::EAX);
|
||||||
void get_ax_l(int _reg);
|
void get_ax_l(int _reg, Gen::X64Reg acx = Gen::EAX);
|
||||||
void get_ax_h(int _reg);
|
void get_ax_h(int _reg, Gen::X64Reg acc = Gen::EAX);
|
||||||
void get_long_acc(int _reg, Gen::X64Reg acc = Gen::EAX);
|
void get_long_acc(int _reg, Gen::X64Reg acc = Gen::EAX);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -111,8 +111,8 @@ void Update_SR_Register16(s16 _Value, bool carry, bool overflow, bool overS32)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update_SR_LZ(bool value) {
|
void Update_SR_LZ(bool value)
|
||||||
|
{
|
||||||
if (value == true)
|
if (value == true)
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_LOGIC_ZERO;
|
g_dsp.r[DSP_REG_SR] |= SR_LOGIC_ZERO;
|
||||||
else
|
else
|
||||||
|
@ -150,12 +150,12 @@ const DSPOPCTemplate opcodes[] =
|
|||||||
{"SBSET", 0x1300, 0xff00, DSPInterpreter::sbset, &DSPEmitter::sbset, 1, 1, {{P_IMM, 1, 0, 0, 0x0007}}, false, false, false, false, false},
|
{"SBSET", 0x1300, 0xff00, DSPInterpreter::sbset, &DSPEmitter::sbset, 1, 1, {{P_IMM, 1, 0, 0, 0x0007}}, false, false, false, false, false},
|
||||||
|
|
||||||
{"LSL", 0x1400, 0xfec0, DSPInterpreter::lsl, &DSPEmitter::lsl, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, false, false, false, false, true},
|
{"LSL", 0x1400, 0xfec0, DSPInterpreter::lsl, &DSPEmitter::lsl, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, false, false, false, false, true},
|
||||||
{"LSR", 0x1440, 0xfec0, DSPInterpreter::lsr, NULL, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, false, false, false, false, true},
|
{"LSR", 0x1440, 0xfec0, DSPInterpreter::lsr, &DSPEmitter::lsr, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, false, false, false, false, true},
|
||||||
{"ASL", 0x1480, 0xfec0, DSPInterpreter::asl, NULL, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, false, false, false, false, true},
|
{"ASL", 0x1480, 0xfec0, DSPInterpreter::asl, &DSPEmitter::asl, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, false, false, false, false, true},
|
||||||
{"ASR", 0x14c0, 0xfec0, DSPInterpreter::asr, NULL, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, false, false, false, false, true},
|
{"ASR", 0x14c0, 0xfec0, DSPInterpreter::asr, &DSPEmitter::asr, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}}, false, false, false, false, true},
|
||||||
|
|
||||||
{"LSRN", 0x02ca, 0xffff, DSPInterpreter::lsrn, NULL, 1, 0, {}, false, false, false, false, true}, // discovered by ector!
|
{"LSRN", 0x02ca, 0xffff, DSPInterpreter::lsrn, &DSPEmitter::lsrn, 1, 0, {}, false, false, false, false, true}, // discovered by ector!
|
||||||
{"ASRN", 0x02cb, 0xffff, DSPInterpreter::asrn, NULL, 1, 0, {}, false, false, false, false, true}, // discovered by ector!
|
{"ASRN", 0x02cb, 0xffff, DSPInterpreter::asrn, &DSPEmitter::asrn, 1, 0, {}, false, false, false, false, true}, // discovered by ector!
|
||||||
|
|
||||||
{"LRI", 0x0080, 0xffe0, DSPInterpreter::lri, &DSPEmitter::lri, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true, false},
|
{"LRI", 0x0080, 0xffe0, DSPInterpreter::lri, &DSPEmitter::lri, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true, false},
|
||||||
{"LR", 0x00c0, 0xffe0, DSPInterpreter::lr, &DSPEmitter::lr, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_MEM, 2, 1, 0, 0xffff}}, false, false, false, true, false},
|
{"LR", 0x00c0, 0xffe0, DSPInterpreter::lr, &DSPEmitter::lr, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_MEM, 2, 1, 0, 0xffff}}, false, false, false, true, false},
|
||||||
@ -166,17 +166,17 @@ const DSPOPCTemplate opcodes[] =
|
|||||||
{"SI", 0x1600, 0xff00, DSPInterpreter::si, &DSPEmitter::si, 2, 2, {{P_MEM, 1, 0, 0, 0x00ff}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true, false},
|
{"SI", 0x1600, 0xff00, DSPInterpreter::si, &DSPEmitter::si, 2, 2, {{P_MEM, 1, 0, 0, 0x00ff}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true, false},
|
||||||
|
|
||||||
{"ADDIS", 0x0400, 0xfe00, DSPInterpreter::addis, &DSPEmitter::addis, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}}, false, false, false, false, true},
|
{"ADDIS", 0x0400, 0xfe00, DSPInterpreter::addis, &DSPEmitter::addis, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}}, false, false, false, false, true},
|
||||||
{"CMPIS", 0x0600, 0xfe00, DSPInterpreter::cmpis, NULL, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}}, false, false, false, false, true},
|
{"CMPIS", 0x0600, 0xfe00, DSPInterpreter::cmpis, &DSPEmitter::cmpis, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}}, false, false, false, false, true},
|
||||||
{"LRIS", 0x0800, 0xf800, DSPInterpreter::lris, &DSPEmitter::lris, 1, 2, {{P_REG18, 1, 0, 8, 0x0700}, {P_IMM, 1, 0, 0, 0x00ff}}, false, false, false, false, true},
|
{"LRIS", 0x0800, 0xf800, DSPInterpreter::lris, &DSPEmitter::lris, 1, 2, {{P_REG18, 1, 0, 8, 0x0700}, {P_IMM, 1, 0, 0, 0x00ff}}, false, false, false, false, true},
|
||||||
|
|
||||||
{"ADDI", 0x0200, 0xfeff, DSPInterpreter::addi, &DSPEmitter::addi, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true, true},
|
{"ADDI", 0x0200, 0xfeff, DSPInterpreter::addi, &DSPEmitter::addi, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true, true},
|
||||||
{"XORI", 0x0220, 0xfeff, DSPInterpreter::xori, NULL, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true, true},
|
{"XORI", 0x0220, 0xfeff, DSPInterpreter::xori, &DSPEmitter::xori, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true, true},
|
||||||
{"ANDI", 0x0240, 0xfeff, DSPInterpreter::andi, NULL, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true, true},
|
{"ANDI", 0x0240, 0xfeff, DSPInterpreter::andi, &DSPEmitter::andi, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true, true},
|
||||||
{"ORI", 0x0260, 0xfeff, DSPInterpreter::ori, NULL, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true, true},
|
{"ORI", 0x0260, 0xfeff, DSPInterpreter::ori, &DSPEmitter::ori, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true, true},
|
||||||
{"CMPI", 0x0280, 0xfeff, DSPInterpreter::cmpi, NULL, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true, true},
|
{"CMPI", 0x0280, 0xfeff, DSPInterpreter::cmpi, &DSPEmitter::cmpi, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true, true},
|
||||||
|
|
||||||
{"ANDF", 0x02a0, 0xfeff, DSPInterpreter::andf, NULL, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true, true},
|
{"ANDF", 0x02a0, 0xfeff, DSPInterpreter::andf, &DSPEmitter::andf, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true, true},
|
||||||
{"ANDCF", 0x02c0, 0xfeff, DSPInterpreter::andcf, NULL, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true, true},
|
{"ANDCF", 0x02c0, 0xfeff, DSPInterpreter::andcf, &DSPEmitter::andcf, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true, true},
|
||||||
|
|
||||||
{"ILRR", 0x0210, 0xfefc, DSPInterpreter::ilrr, &DSPEmitter::ilrr, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, false, false, false, false, false},
|
{"ILRR", 0x0210, 0xfefc, DSPInterpreter::ilrr, &DSPEmitter::ilrr, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, false, false, false, false, false},
|
||||||
{"ILRRD", 0x0214, 0xfefc, DSPInterpreter::ilrrd, &DSPEmitter::ilrrd, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, false, false, false, false, false},
|
{"ILRRD", 0x0214, 0xfefc, DSPInterpreter::ilrrd, &DSPEmitter::ilrrd, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, false, false, false, false, false},
|
||||||
@ -207,17 +207,17 @@ const DSPOPCTemplate opcodes[] =
|
|||||||
// opcodes that can be extended
|
// opcodes that can be extended
|
||||||
|
|
||||||
//3 - main opcode defined by 9 bits, extension defined by last 7 bits!!
|
//3 - main opcode defined by 9 bits, extension defined by last 7 bits!!
|
||||||
{"XORR", 0x3000, 0xfc80, DSPInterpreter::xorr, NULL, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, true, false, false, false, true},
|
{"XORR", 0x3000, 0xfc80, DSPInterpreter::xorr, &DSPEmitter::xorr, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, true, false, false, false, true},
|
||||||
{"ANDR", 0x3400, 0xfc80, DSPInterpreter::andr, NULL, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, true, false, false, false, true},
|
{"ANDR", 0x3400, 0xfc80, DSPInterpreter::andr, &DSPEmitter::andr, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, true, false, false, false, true},
|
||||||
{"ORR", 0x3800, 0xfc80, DSPInterpreter::orr, NULL, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, true, false, false, false, true},
|
{"ORR", 0x3800, 0xfc80, DSPInterpreter::orr, &DSPEmitter::orr, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, true, false, false, false, true},
|
||||||
{"ANDC", 0x3c00, 0xfe80, DSPInterpreter::andc, NULL, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
{"ANDC", 0x3c00, 0xfe80, DSPInterpreter::andc, &DSPEmitter::andc, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
||||||
{"ORC", 0x3e00, 0xfe80, DSPInterpreter::orc, NULL, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
{"ORC", 0x3e00, 0xfe80, DSPInterpreter::orc, &DSPEmitter::orc, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
||||||
{"XORC", 0x3080, 0xfe80, DSPInterpreter::xorc, NULL, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
{"XORC", 0x3080, 0xfe80, DSPInterpreter::xorc, &DSPEmitter::xorc, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
||||||
{"NOT", 0x3280, 0xfe80, DSPInterpreter::notc, NULL, 1, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
{"NOT", 0x3280, 0xfe80, DSPInterpreter::notc, &DSPEmitter::notc, 1, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
||||||
{"LSRNRX", 0x3480, 0xfc80, DSPInterpreter::lsrnrx, NULL, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, true, false, false, false, true},
|
{"LSRNRX", 0x3480, 0xfc80, DSPInterpreter::lsrnrx, &DSPEmitter::lsrnrx, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, true, false, false, false, true},
|
||||||
{"ASRNRX", 0x3880, 0xfc80, DSPInterpreter::asrnrx, NULL, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, true, false, false, false, true},
|
{"ASRNRX", 0x3880, 0xfc80, DSPInterpreter::asrnrx, &DSPEmitter::asrnrx, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}}, true, false, false, false, true},
|
||||||
{"LSRNR", 0x3c80, 0xfe80, DSPInterpreter::lsrnr, NULL, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
{"LSRNR", 0x3c80, 0xfe80, DSPInterpreter::lsrnr, &DSPEmitter::lsrnr, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
||||||
{"ASRNR", 0x3e80, 0xfe80, DSPInterpreter::asrnr, NULL, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
{"ASRNR", 0x3e80, 0xfe80, DSPInterpreter::asrnr, &DSPEmitter::asrnr, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
||||||
|
|
||||||
//4
|
//4
|
||||||
{"ADDR", 0x4000, 0xf800, DSPInterpreter::addr, &DSPEmitter::addr, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}}, true, false, false, false, true},
|
{"ADDR", 0x4000, 0xf800, DSPInterpreter::addr, &DSPEmitter::addr, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}}, true, false, false, false, true},
|
||||||
@ -238,7 +238,7 @@ const DSPOPCTemplate opcodes[] =
|
|||||||
{"MOVP", 0x6e00, 0xfe00, DSPInterpreter::movp, &DSPEmitter::movp, 1, 1, {{P_ACC, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
{"MOVP", 0x6e00, 0xfe00, DSPInterpreter::movp, &DSPEmitter::movp, 1, 1, {{P_ACC, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
||||||
|
|
||||||
//7
|
//7
|
||||||
{"ADDAXL", 0x7000, 0xfc00, DSPInterpreter::addaxl, NULL, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}}, true, false, false, false, true},
|
{"ADDAXL", 0x7000, 0xfc00, DSPInterpreter::addaxl, &DSPEmitter::addaxl, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}}, true, false, false, false, true},
|
||||||
{"INCM", 0x7400, 0xfe00, DSPInterpreter::incm, &DSPEmitter::incm, 1, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
{"INCM", 0x7400, 0xfe00, DSPInterpreter::incm, &DSPEmitter::incm, 1, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
||||||
{"INC", 0x7600, 0xfe00, DSPInterpreter::inc, &DSPEmitter::inc, 1, 1, {{P_ACC, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
{"INC", 0x7600, 0xfe00, DSPInterpreter::inc, &DSPEmitter::inc, 1, 1, {{P_ACC, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
||||||
{"DECM", 0x7800, 0xfe00, DSPInterpreter::decm, &DSPEmitter::decm, 1, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
{"DECM", 0x7800, 0xfe00, DSPInterpreter::decm, &DSPEmitter::decm, 1, 1, {{P_ACCM, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
||||||
@ -248,12 +248,12 @@ const DSPOPCTemplate opcodes[] =
|
|||||||
|
|
||||||
//8
|
//8
|
||||||
{"NX", 0x8000, 0xf700, DSPInterpreter::nx, &DSPEmitter::nx, 1, 0, {}, true, false, false, false, false},
|
{"NX", 0x8000, 0xf700, DSPInterpreter::nx, &DSPEmitter::nx, 1, 0, {}, true, false, false, false, false},
|
||||||
{"CLR", 0x8100, 0xf700, DSPInterpreter::clr, NULL, 1, 1, {{P_ACC, 1, 0, 11, 0x0800}}, true, false, false, false, true},
|
{"CLR", 0x8100, 0xf700, DSPInterpreter::clr, &DSPEmitter::clr, 1, 1, {{P_ACC, 1, 0, 11, 0x0800}}, true, false, false, false, true},
|
||||||
{"CMP", 0x8200, 0xff00, DSPInterpreter::cmp, NULL, 1, 0, {}, true, false, false, false, true},
|
{"CMP", 0x8200, 0xff00, DSPInterpreter::cmp, &DSPEmitter::cmp, 1, 0, {}, true, false, false, false, true},
|
||||||
{"MULAXH", 0x8300, 0xff00, DSPInterpreter::mulaxh, &DSPEmitter::mulaxh, 1, 0, {}, true, false, false, false, true},
|
{"MULAXH", 0x8300, 0xff00, DSPInterpreter::mulaxh, &DSPEmitter::mulaxh, 1, 0, {}, true, false, false, false, true},
|
||||||
{"CLRP", 0x8400, 0xff00, DSPInterpreter::clrp, &DSPEmitter::clrp, 1, 0, {}, true, false, false, false, true},
|
{"CLRP", 0x8400, 0xff00, DSPInterpreter::clrp, &DSPEmitter::clrp, 1, 0, {}, true, false, false, false, true},
|
||||||
{"TSTPROD", 0x8500, 0xff00, DSPInterpreter::tstprod, &DSPEmitter::tstprod,1, 0, {}, true, false, false, false, true},
|
{"TSTPROD", 0x8500, 0xff00, DSPInterpreter::tstprod, &DSPEmitter::tstprod,1, 0, {}, true, false, false, false, true},
|
||||||
{"TSTAXH", 0x8600, 0xfe00, DSPInterpreter::tstaxh, NULL, 1, 1, {{P_REG1A, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
{"TSTAXH", 0x8600, 0xfe00, DSPInterpreter::tstaxh, &DSPEmitter::tstaxh, 1, 1, {{P_REG1A, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
||||||
{"M2", 0x8a00, 0xff00, DSPInterpreter::srbith, &DSPEmitter::srbith, 1, 0, {}, true, false, false, false, false},
|
{"M2", 0x8a00, 0xff00, DSPInterpreter::srbith, &DSPEmitter::srbith, 1, 0, {}, true, false, false, false, false},
|
||||||
{"M0", 0x8b00, 0xff00, DSPInterpreter::srbith, &DSPEmitter::srbith, 1, 0, {}, true, false, false, false, false},
|
{"M0", 0x8b00, 0xff00, DSPInterpreter::srbith, &DSPEmitter::srbith, 1, 0, {}, true, false, false, false, false},
|
||||||
{"CLR15", 0x8c00, 0xff00, DSPInterpreter::srbith, &DSPEmitter::srbith, 1, 0, {}, true, false, false, false, false},
|
{"CLR15", 0x8c00, 0xff00, DSPInterpreter::srbith, &DSPEmitter::srbith, 1, 0, {}, true, false, false, false, false},
|
||||||
@ -278,14 +278,14 @@ const DSPOPCTemplate opcodes[] =
|
|||||||
|
|
||||||
//c-d
|
//c-d
|
||||||
{"MULC", 0xc000, 0xe700, DSPInterpreter::mulc, &DSPEmitter::mulc, 1, 2, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}}, true, false, false, false, true},
|
{"MULC", 0xc000, 0xe700, DSPInterpreter::mulc, &DSPEmitter::mulc, 1, 2, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}}, true, false, false, false, true},
|
||||||
{"CMPAR" , 0xc100, 0xe700, DSPInterpreter::cmpar, NULL, 1, 2, {{P_ACC, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}}, true, false, false, false, true},
|
{"CMPAR" , 0xc100, 0xe700, DSPInterpreter::cmpar, &DSPEmitter::cmpar, 1, 2, {{P_ACC, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}}, true, false, false, false, true},
|
||||||
{"MULCMVZ", 0xc200, 0xe600, DSPInterpreter::mulcmvz, &DSPEmitter::mulcmvz,1, 3, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
{"MULCMVZ", 0xc200, 0xe600, DSPInterpreter::mulcmvz, &DSPEmitter::mulcmvz,1, 3, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
||||||
{"MULCAC", 0xc400, 0xe600, DSPInterpreter::mulcac, &DSPEmitter::mulcac, 1, 3, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
{"MULCAC", 0xc400, 0xe600, DSPInterpreter::mulcac, &DSPEmitter::mulcac, 1, 3, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
||||||
{"MULCMV", 0xc600, 0xe600, DSPInterpreter::mulcmv, &DSPEmitter::mulcmv, 1, 3, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
{"MULCMV", 0xc600, 0xe600, DSPInterpreter::mulcmv, &DSPEmitter::mulcmv, 1, 3, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACC, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
||||||
|
|
||||||
//e
|
//e
|
||||||
{"MADDX", 0xe000, 0xfc00, DSPInterpreter::maddx, NULL, 1, 2, {{P_REGM18, 1, 0, 8, 0x0200}, {P_REGM19, 1, 0, 7, 0x0100}}, true, false, false, false, true},
|
{"MADDX", 0xe000, 0xfc00, DSPInterpreter::maddx, &DSPEmitter::maddx, 1, 2, {{P_REGM18, 1, 0, 8, 0x0200}, {P_REGM19, 1, 0, 7, 0x0100}}, true, false, false, false, true},
|
||||||
{"MSUBX", 0xe400, 0xfc00, DSPInterpreter::msubx, NULL, 1, 2, {{P_REGM18, 1, 0, 8, 0x0200}, {P_REGM19, 1, 0, 7, 0x0100}}, true, false, false, false, true},
|
{"MSUBX", 0xe400, 0xfc00, DSPInterpreter::msubx, &DSPEmitter::msubx, 1, 2, {{P_REGM18, 1, 0, 8, 0x0200}, {P_REGM19, 1, 0, 7, 0x0100}}, true, false, false, false, true},
|
||||||
{"MADDC", 0xe800, 0xfc00, DSPInterpreter::maddc, &DSPEmitter::maddc, 1, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}}, true, false, false, false, true},
|
{"MADDC", 0xe800, 0xfc00, DSPInterpreter::maddc, &DSPEmitter::maddc, 1, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}}, true, false, false, false, true},
|
||||||
{"MSUBC", 0xec00, 0xfc00, DSPInterpreter::msubc, &DSPEmitter::msubc, 1, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}}, true, false, false, false, true},
|
{"MSUBC", 0xec00, 0xfc00, DSPInterpreter::msubc, &DSPEmitter::msubc, 1, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}}, true, false, false, false, true},
|
||||||
|
|
||||||
@ -295,7 +295,7 @@ const DSPOPCTemplate opcodes[] =
|
|||||||
{"LSR16", 0xf400, 0xfe00, DSPInterpreter::lsr16, &DSPEmitter::lsl16, 1, 1, {{P_ACC, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
{"LSR16", 0xf400, 0xfe00, DSPInterpreter::lsr16, &DSPEmitter::lsl16, 1, 1, {{P_ACC, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
||||||
{"MSUB", 0xf600, 0xfe00, DSPInterpreter::msub, &DSPEmitter::msub, 1, 2, {{P_REG18, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
{"MSUB", 0xf600, 0xfe00, DSPInterpreter::msub, &DSPEmitter::msub, 1, 2, {{P_REG18, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
||||||
{"ADDPAXZ", 0xf800, 0xfc00, DSPInterpreter::addpaxz, NULL, 1, 2, {{P_ACC, 1, 0, 9, 0x0200}, {P_AX, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
{"ADDPAXZ", 0xf800, 0xfc00, DSPInterpreter::addpaxz, NULL, 1, 2, {{P_ACC, 1, 0, 9, 0x0200}, {P_AX, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
||||||
{"CLRL", 0xfc00, 0xfe00, DSPInterpreter::clrl, NULL, 1, 1, {{P_ACCL, 1, 0, 11, 0x0800}}, true, false, false, false, true},
|
{"CLRL", 0xfc00, 0xfe00, DSPInterpreter::clrl, &DSPEmitter::clrl, 1, 1, {{P_ACCL, 1, 0, 11, 0x0800}}, true, false, false, false, true},
|
||||||
{"MOVPZ", 0xfe00, 0xfe00, DSPInterpreter::movpz, &DSPEmitter::movpz, 1, 1, {{P_ACC, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
{"MOVPZ", 0xfe00, 0xfe00, DSPInterpreter::movpz, &DSPEmitter::movpz, 1, 1, {{P_ACC, 1, 0, 8, 0x0100}}, true, false, false, false, true},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -150,38 +150,6 @@ void DSPEmitter::Update_SR_Register64_Carry2(Gen::X64Reg val)
|
|||||||
|
|
||||||
//void DSPEmitter::Update_SR_Register16(s16 _Value, bool carry, bool overflow, bool overS32)
|
//void DSPEmitter::Update_SR_Register16(s16 _Value, bool carry, bool overflow, bool overS32)
|
||||||
//{
|
//{
|
||||||
// g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
|
|
||||||
|
|
||||||
// // 0x01
|
|
||||||
// if (carry)
|
|
||||||
// {
|
|
||||||
// g_dsp.r[DSP_REG_SR] |= SR_CARRY;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 0x02 and 0x80
|
|
||||||
// if (overflow)
|
|
||||||
// {
|
|
||||||
// g_dsp.r[DSP_REG_SR] |= SR_OVERFLOW;
|
|
||||||
// g_dsp.r[DSP_REG_SR] |= SR_OVERFLOW_STICKY;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 0x04
|
|
||||||
// if (_Value == 0)
|
|
||||||
// {
|
|
||||||
// g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 0x08
|
|
||||||
// if (_Value < 0)
|
|
||||||
// {
|
|
||||||
// g_dsp.r[DSP_REG_SR] |= SR_SIGN;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 0x10
|
|
||||||
// if (overS32)
|
|
||||||
// {
|
|
||||||
// g_dsp.r[DSP_REG_SR] |= SR_OVER_S32;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 0x20 - Checks if top bits of m are equal
|
// // 0x20 - Checks if top bits of m are equal
|
||||||
// if ((((u16)_Value >> 14) == 0) || (((u16)_Value >> 14) == 3))
|
// if ((((u16)_Value >> 14) == 0) || (((u16)_Value >> 14) == 3))
|
||||||
@ -190,6 +158,69 @@ void DSPEmitter::Update_SR_Register64_Carry2(Gen::X64Reg val)
|
|||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
// In: RAX: s64 _Value
|
||||||
|
// In: RCX: 1 = carry, 2 = overflow
|
||||||
|
// Clobbers RDX
|
||||||
|
void DSPEmitter::Update_SR_Register16(Gen::X64Reg val)
|
||||||
|
{
|
||||||
|
#ifdef _M_X64
|
||||||
|
AND(16, MDisp(R11, DSP_REG_SR * 2), Imm16(~SR_CMP_MASK));
|
||||||
|
|
||||||
|
// // 0x04
|
||||||
|
// if (_Value == 0) g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
|
||||||
|
CMP(64, R(val), Imm8(0));
|
||||||
|
FixupBranch notZero = J_CC(CC_NZ);
|
||||||
|
OR(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_ARITH_ZERO));
|
||||||
|
SetJumpTarget(notZero);
|
||||||
|
|
||||||
|
// // 0x08
|
||||||
|
// if (_Value < 0) g_dsp.r[DSP_REG_SR] |= SR_SIGN;
|
||||||
|
CMP(64, R(val), Imm8(0));
|
||||||
|
FixupBranch greaterThanEqual = J_CC(CC_GE);
|
||||||
|
OR(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_SIGN));
|
||||||
|
SetJumpTarget(greaterThanEqual);
|
||||||
|
|
||||||
|
// // 0x20 - Checks if top bits of m are equal
|
||||||
|
// if ((((u16)_Value >> 14) == 0) || (((u16)_Value >> 14) == 3))
|
||||||
|
//AND(32, R(val), Imm32(0xc0000000));
|
||||||
|
SHR(16, R(val), Imm8(14));
|
||||||
|
CMP(16, R(val), Imm16(0));
|
||||||
|
FixupBranch nZero = J_CC(CC_NE);
|
||||||
|
OR(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_TOP2BITS));
|
||||||
|
FixupBranch cC = J();
|
||||||
|
SetJumpTarget(nZero);
|
||||||
|
CMP(16, R(val), Imm16(3));
|
||||||
|
FixupBranch notThree = J_CC(CC_NE);
|
||||||
|
// g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS;
|
||||||
|
OR(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_TOP2BITS));
|
||||||
|
SetJumpTarget(notThree);
|
||||||
|
SetJumpTarget(cC);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// In: RAX: s64 _Value
|
||||||
|
// In: RCX: 1 = carry, 2 = overflow
|
||||||
|
// Clobbers RDX
|
||||||
|
void DSPEmitter::Update_SR_Register16_OverS32(Gen::X64Reg val)
|
||||||
|
{
|
||||||
|
#ifdef _M_X64
|
||||||
|
AND(16, MDisp(R11, DSP_REG_SR * 2), Imm16(~SR_CMP_MASK));
|
||||||
|
|
||||||
|
// // 0x10
|
||||||
|
// if (_Value != (s32)_Value) g_dsp.r[DSP_REG_SR] |= SR_OVER_S32;
|
||||||
|
MOVSX(64, 32, RSI, R(val));
|
||||||
|
CMP(64, R(RSI), R(val));
|
||||||
|
FixupBranch noOverS32 = J_CC(CC_E);
|
||||||
|
OR(16, MDisp(R11, DSP_REG_SR * 2), Imm16(SR_OVER_S32));
|
||||||
|
SetJumpTarget(noOverS32);
|
||||||
|
|
||||||
|
// // 0x20 - Checks if top bits of m are equal
|
||||||
|
// if ((((u16)_Value >> 14) == 0) || (((u16)_Value >> 14) == 3))
|
||||||
|
//AND(32, R(val), Imm32(0xc0000000));
|
||||||
|
Update_SR_Register16(val);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
//void DSPEmitter::Update_SR_LZ(bool value) {
|
//void DSPEmitter::Update_SR_LZ(bool value) {
|
||||||
|
|
||||||
// if (value == true)
|
// if (value == true)
|
||||||
|
@ -407,16 +407,14 @@ void DSPEmitter::mulmvz(const UDSPInstruction opc)
|
|||||||
u8 rreg = (opc >> 8) & 0x1;
|
u8 rreg = (opc >> 8) & 0x1;
|
||||||
|
|
||||||
// s64 acc = dsp_get_long_prod_round_prodl();
|
// s64 acc = dsp_get_long_prod_round_prodl();
|
||||||
get_long_prod_round_prodl();
|
get_long_prod_round_prodl(RDX);
|
||||||
PUSH(64, R(RAX));
|
|
||||||
mul(opc);
|
|
||||||
// dsp_set_long_acc(rreg, acc);
|
// dsp_set_long_acc(rreg, acc);
|
||||||
POP(64, R(RAX));
|
set_long_acc(rreg, RDX);
|
||||||
set_long_acc(rreg);
|
mul(opc);
|
||||||
// Update_SR_Register64(dsp_get_long_acc(rreg));
|
// Update_SR_Register64(dsp_get_long_acc(rreg));
|
||||||
if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR))
|
if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR))
|
||||||
{
|
{
|
||||||
Update_SR_Register64();
|
Update_SR_Register64(RDX);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
Default(opc);
|
Default(opc);
|
||||||
@ -673,38 +671,50 @@ void DSPEmitter::mulcmvz(const UDSPInstruction opc)
|
|||||||
// Multiply one part of secondary accumulator $ax0 (selected by S) by
|
// Multiply one part of secondary accumulator $ax0 (selected by S) by
|
||||||
// one part of secondary accumulator $ax1 (selected by T) (treat them both as
|
// one part of secondary accumulator $ax1 (selected by T) (treat them both as
|
||||||
// signed) and add result to product register.
|
// signed) and add result to product register.
|
||||||
//void DSPEmitter::maddx(const UDSPInstruction opc)
|
void DSPEmitter::maddx(const UDSPInstruction opc)
|
||||||
//{
|
{
|
||||||
// u8 treg = (opc >> 8) & 0x1;
|
#ifdef _M_X64
|
||||||
// u8 sreg = (opc >> 9) & 0x1;
|
u8 treg = (opc >> 8) & 0x1;
|
||||||
|
u8 sreg = (opc >> 9) & 0x1;
|
||||||
|
|
||||||
// u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
|
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
||||||
// u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
|
// u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
|
||||||
// s64 prod = dsp_multiply_add(val1, val2);
|
MOVSX(64, 16, RSI, MDisp(R11, (DSP_REG_AXL0 + sreg*2) * 2));
|
||||||
//
|
// u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
|
||||||
// zeroWriteBackLog();
|
MOVSX(64, 16, RDI, MDisp(R11, (DSP_REG_AXL1 + treg*2) * 2));
|
||||||
|
// s64 prod = dsp_multiply_add(val1, val2);
|
||||||
// dsp_set_long_prod(prod);
|
multiply_add();
|
||||||
//}
|
// dsp_set_long_prod(prod);
|
||||||
|
set_long_prod();
|
||||||
|
#else
|
||||||
|
Default(opc);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// MSUBX $(0x18+S*2), $(0x19+T*2)
|
// MSUBX $(0x18+S*2), $(0x19+T*2)
|
||||||
// 1110 01st xxxx xxxx
|
// 1110 01st xxxx xxxx
|
||||||
// Multiply one part of secondary accumulator $ax0 (selected by S) by
|
// Multiply one part of secondary accumulator $ax0 (selected by S) by
|
||||||
// one part of secondary accumulator $ax1 (selected by T) (treat them both as
|
// one part of secondary accumulator $ax1 (selected by T) (treat them both as
|
||||||
// signed) and subtract result from product register.
|
// signed) and subtract result from product register.
|
||||||
//void DSPEmitter::msubx(const UDSPInstruction opc)
|
void DSPEmitter::msubx(const UDSPInstruction opc)
|
||||||
//{
|
{
|
||||||
// u8 treg = (opc >> 8) & 0x1;
|
#ifdef _M_X64
|
||||||
// u8 sreg = (opc >> 9) & 0x1;
|
u8 treg = (opc >> 8) & 0x1;
|
||||||
|
u8 sreg = (opc >> 9) & 0x1;
|
||||||
|
|
||||||
// u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
|
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
||||||
// u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
|
// u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
|
||||||
// s64 prod = dsp_multiply_sub(val1, val2);
|
MOVSX(64, 16, RSI, MDisp(R11, (DSP_REG_AXL0 + sreg*2) * 2));
|
||||||
|
// u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
|
||||||
// zeroWriteBackLog();
|
MOVSX(64, 16, RDI, MDisp(R11, (DSP_REG_AXL1 + treg*2) * 2));
|
||||||
|
// s64 prod = dsp_multiply_sub(val1, val2);
|
||||||
// dsp_set_long_prod(prod);
|
multiply_sub();
|
||||||
//}
|
// dsp_set_long_prod(prod);
|
||||||
|
set_long_prod();
|
||||||
|
#else
|
||||||
|
Default(opc);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// MADDC $acS.m, $axT.h
|
// MADDC $acS.m, $axT.h
|
||||||
// 1110 10st xxxx xxxx
|
// 1110 10st xxxx xxxx
|
||||||
|
@ -186,7 +186,7 @@ void DSPEmitter::increase_addr_reg(int reg)
|
|||||||
// TODO: ToMask flushes flags set by TEST,
|
// TODO: ToMask flushes flags set by TEST,
|
||||||
// needs another CMP here.
|
// needs another CMP here.
|
||||||
CMP(16, R(ECX), Imm16(0));
|
CMP(16, R(ECX), Imm16(0));
|
||||||
FixupBranch neg = J_CC(CC_L);
|
FixupBranch negative = J_CC(CC_L);
|
||||||
|
|
||||||
JumpTarget loop_pos = GetCodePtr();
|
JumpTarget loop_pos = GetCodePtr();
|
||||||
|
|
||||||
@ -211,7 +211,7 @@ void DSPEmitter::increase_addr_reg(int reg)
|
|||||||
FixupBranch end_pos = J();
|
FixupBranch end_pos = J();
|
||||||
|
|
||||||
// else, IX0 < 0
|
// else, IX0 < 0
|
||||||
SetJumpTarget(neg);
|
SetJumpTarget(negative);
|
||||||
JumpTarget loop_neg = GetCodePtr();
|
JumpTarget loop_neg = GetCodePtr();
|
||||||
|
|
||||||
// dsp_decrement
|
// dsp_decrement
|
||||||
@ -269,7 +269,7 @@ void DSPEmitter::decrease_addr_reg(int reg)
|
|||||||
// TODO: ToMask flushes flags set by TEST,
|
// TODO: ToMask flushes flags set by TEST,
|
||||||
// needs another CMP here.
|
// needs another CMP here.
|
||||||
CMP(16, R(ECX), Imm16(0));
|
CMP(16, R(ECX), Imm16(0));
|
||||||
FixupBranch neg = J_CC(CC_L);
|
FixupBranch negative = J_CC(CC_L);
|
||||||
|
|
||||||
JumpTarget loop_pos = GetCodePtr();
|
JumpTarget loop_pos = GetCodePtr();
|
||||||
|
|
||||||
@ -282,7 +282,7 @@ void DSPEmitter::decrease_addr_reg(int reg)
|
|||||||
FixupBranch end_pos = J();
|
FixupBranch end_pos = J();
|
||||||
|
|
||||||
// else, IX0 < 0
|
// else, IX0 < 0
|
||||||
SetJumpTarget(neg);
|
SetJumpTarget(negative);
|
||||||
JumpTarget loop_neg = GetCodePtr();
|
JumpTarget loop_neg = GetCodePtr();
|
||||||
|
|
||||||
// dsp_increment
|
// dsp_increment
|
||||||
@ -512,7 +512,7 @@ void DSPEmitter::get_long_prod_round_prodl(X64Reg long_prod)
|
|||||||
{
|
{
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
//s64 prod = dsp_get_long_prod();
|
//s64 prod = dsp_get_long_prod();
|
||||||
get_long_prod();
|
get_long_prod(long_prod);
|
||||||
|
|
||||||
//if (prod & 0x10000) prod = (prod + 0x8000) & ~0xffff;
|
//if (prod & 0x10000) prod = (prod + 0x8000) & ~0xffff;
|
||||||
TEST(32, R(long_prod), Imm32(0x10000));
|
TEST(32, R(long_prod), Imm32(0x10000));
|
||||||
@ -554,6 +554,28 @@ void DSPEmitter::set_long_prod()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns s64 in RAX
|
||||||
|
// Clobbers RSI
|
||||||
|
void DSPEmitter::round_long_acc(X64Reg long_acc)
|
||||||
|
{
|
||||||
|
#ifdef _M_X64
|
||||||
|
//if (prod & 0x10000) prod = (prod + 0x8000) & ~0xffff;
|
||||||
|
TEST(32, R(long_acc), Imm32(0x10000));
|
||||||
|
FixupBranch jump = J_CC(CC_Z);
|
||||||
|
ADD(64, R(long_acc), Imm32(0x8000));
|
||||||
|
MOV(64, R(ESI), Imm64(~0xffff));
|
||||||
|
AND(64, R(long_acc), R(RSI));
|
||||||
|
FixupBranch ret = J();
|
||||||
|
//else prod = (prod + 0x7fff) & ~0xffff;
|
||||||
|
SetJumpTarget(jump);
|
||||||
|
ADD(64, R(long_acc), Imm32(0x7fff));
|
||||||
|
MOV(64, R(RSI), Imm64(~0xffff));
|
||||||
|
AND(64, R(long_acc), R(RSI));
|
||||||
|
SetJumpTarget(ret);
|
||||||
|
//return prod;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// Returns s64 in RAX
|
// Returns s64 in RAX
|
||||||
void DSPEmitter::get_long_acc(int _reg, X64Reg acc)
|
void DSPEmitter::get_long_acc(int _reg, X64Reg acc)
|
||||||
{
|
{
|
||||||
@ -591,12 +613,22 @@ void DSPEmitter::set_long_acc(int _reg, X64Reg acc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns s16 in AX
|
// Returns s16 in AX
|
||||||
void DSPEmitter::get_acc_m(int _reg)
|
void DSPEmitter::get_acc_m(int _reg, X64Reg acm)
|
||||||
{
|
{
|
||||||
// return g_dsp.r[DSP_REG_ACM0 + _reg];
|
// return g_dsp.r[DSP_REG_ACM0 + _reg];
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
||||||
MOVSX(64, 16, RAX, MDisp(R11, (DSP_REG_ACM0 + _reg) * 2));
|
MOVSX(64, 16, acm, MDisp(R11, (DSP_REG_ACM0 + _reg) * 2));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns s16 in AX
|
||||||
|
void DSPEmitter::set_acc_m(int _reg)
|
||||||
|
{
|
||||||
|
// return g_dsp.r[DSP_REG_ACM0 + _reg];
|
||||||
|
#ifdef _M_X64
|
||||||
|
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
||||||
|
MOV(16, MDisp(R11, (DSP_REG_ACM0 + _reg) * 2), R(RAX));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -613,22 +645,22 @@ void DSPEmitter::get_long_acx(int _reg, X64Reg acx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns s16 in EAX
|
// Returns s16 in EAX
|
||||||
void DSPEmitter::get_ax_l(int _reg)
|
void DSPEmitter::get_ax_l(int _reg, X64Reg axl)
|
||||||
{
|
{
|
||||||
// return (s16)g_dsp.r[DSP_REG_AXL0 + _reg];
|
// return (s16)g_dsp.r[DSP_REG_AXL0 + _reg];
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
||||||
MOVSX(64, 16, RAX, MDisp(R11, (DSP_REG_AXL0 + _reg) * 2));
|
MOVSX(64, 16, axl, MDisp(R11, (DSP_REG_AXL0 + _reg) * 2));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns s16 in EAX
|
// Returns s16 in EAX
|
||||||
void DSPEmitter::get_ax_h(int _reg)
|
void DSPEmitter::get_ax_h(int _reg, X64Reg axh)
|
||||||
{
|
{
|
||||||
// return (s16)g_dsp.r[DSP_REG_AXH0 + _reg];
|
// return (s16)g_dsp.r[DSP_REG_AXH0 + _reg];
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
||||||
MOVSX(64, 16, RAX, MDisp(R11, (DSP_REG_AXH0 + _reg) * 2));
|
MOVSX(64, 16, axh, MDisp(R11, (DSP_REG_AXH0 + _reg) * 2));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user