Committing magumagu9's work on IMUL JIT
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1241 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
fb2b57a47c
commit
145f80fc00
|
@ -936,6 +936,64 @@ namespace Gen
|
||||||
void CMP (int bits, const OpArg &a1, const OpArg &a2) {WriteNormalOp(bits, nrmCMP, a1, a2);}
|
void CMP (int bits, const OpArg &a1, const OpArg &a2) {WriteNormalOp(bits, nrmCMP, a1, a2);}
|
||||||
void XCHG(int bits, const OpArg &a1, const OpArg &a2) {WriteNormalOp(bits, nrmXCHG, a1, a2);}
|
void XCHG(int bits, const OpArg &a1, const OpArg &a2) {WriteNormalOp(bits, nrmXCHG, a1, a2);}
|
||||||
|
|
||||||
|
void IMUL(int bits, X64Reg regOp, OpArg a1, OpArg a2)
|
||||||
|
{
|
||||||
|
if (bits == 8) {
|
||||||
|
_assert_msg_(DYNA_REC, 0, "IMUL - illegal bit size!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (a1.IsImm()) {
|
||||||
|
_assert_msg_(DYNA_REC, 0, "IMUL - second arg cannot be imm!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!a2.IsImm())
|
||||||
|
{
|
||||||
|
_assert_msg_(DYNA_REC, 0, "IMUL - third arg must be imm!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bits == 16)
|
||||||
|
Write8(0x66);
|
||||||
|
a1.WriteRex(bits == 64, regOp);
|
||||||
|
|
||||||
|
if (a2.GetImmBits() == 8) {
|
||||||
|
Write8(0x6B);
|
||||||
|
a1.WriteRest(1, regOp);
|
||||||
|
Write8((u8)a2.offset);
|
||||||
|
} else {
|
||||||
|
Write8(0x69);
|
||||||
|
if (a2.GetImmBits() == 16 && bits == 16) {
|
||||||
|
a1.WriteRest(2, regOp);
|
||||||
|
Write16((u16)a2.offset);
|
||||||
|
} else if (a2.GetImmBits() == 32 &&
|
||||||
|
(bits == 32 || bits == 64)) {
|
||||||
|
a1.WriteRest(4, regOp);
|
||||||
|
Write32((u32)a2.offset);
|
||||||
|
} else {
|
||||||
|
_assert_msg_(DYNA_REC, 0, "IMUL - unhandled case!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IMUL(int bits, X64Reg regOp, OpArg a)
|
||||||
|
{
|
||||||
|
if (bits == 8) {
|
||||||
|
_assert_msg_(DYNA_REC, 0, "IMUL - illegal bit size!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (a.IsImm())
|
||||||
|
{
|
||||||
|
IMUL(bits, regOp, R(regOp), a) ;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bits == 16)
|
||||||
|
Write8(0x66);
|
||||||
|
a.WriteRex(bits == 64, regOp);
|
||||||
|
Write8(0x0F);
|
||||||
|
Write8(0xAF);
|
||||||
|
a.WriteRest(0, regOp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void WriteSSEOp(int size, u8 sseOp, bool packed, X64Reg regOp, OpArg arg, int extrabytes = 0)
|
void WriteSSEOp(int size, u8 sseOp, bool packed, X64Reg regOp, OpArg arg, int extrabytes = 0)
|
||||||
|
|
|
@ -282,7 +282,9 @@ namespace Gen
|
||||||
void DIV(int bits, OpArg src);
|
void DIV(int bits, OpArg src);
|
||||||
void IMUL(int bits, OpArg src); //SIGNED
|
void IMUL(int bits, OpArg src); //SIGNED
|
||||||
void IDIV(int bits, OpArg src);
|
void IDIV(int bits, OpArg src);
|
||||||
//TODO: alternate IMUL forms
|
void IMUL(int bits, X64Reg regOp, OpArg src);
|
||||||
|
void IMUL(int bits, X64Reg regOp, OpArg src, OpArg imm);
|
||||||
|
|
||||||
|
|
||||||
void NEG(int bits, OpArg src);
|
void NEG(int bits, OpArg src);
|
||||||
void NOT(int bits, OpArg src);
|
void NOT(int bits, OpArg src);
|
||||||
|
|
|
@ -486,19 +486,11 @@ namespace Jit64
|
||||||
#endif
|
#endif
|
||||||
INSTRUCTION_START;
|
INSTRUCTION_START;
|
||||||
int a = inst.RA, d = inst.RD;
|
int a = inst.RA, d = inst.RD;
|
||||||
gpr.FlushLockX(EDX);
|
|
||||||
gpr.Lock(a, d);
|
gpr.Lock(a, d);
|
||||||
if (d != a) {
|
gpr.LoadToX64(d, (d == a), true);
|
||||||
gpr.LoadToX64(d, false, true);
|
gpr.KillImmediate(a);
|
||||||
} else {
|
IMUL(32, gpr.RX(d), gpr.R(a), Imm32((u32)(s32)inst.SIMM_16));
|
||||||
gpr.LoadToX64(d, true, true);
|
|
||||||
}
|
|
||||||
MOV(32, R(EAX), gpr.R(a));
|
|
||||||
MOV(32, R(EDX), Imm32((u32)(s32)inst.SIMM_16));
|
|
||||||
IMUL(32, R(EDX));
|
|
||||||
MOV(32, gpr.R(d), R(EAX));
|
|
||||||
gpr.UnlockAll();
|
gpr.UnlockAll();
|
||||||
gpr.UnlockAllX();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mullwx(UGeckoInstruction inst)
|
void mullwx(UGeckoInstruction inst)
|
||||||
|
@ -509,21 +501,19 @@ namespace Jit64
|
||||||
#endif
|
#endif
|
||||||
INSTRUCTION_START;
|
INSTRUCTION_START;
|
||||||
int a = inst.RA, b = inst.RB, d = inst.RD;
|
int a = inst.RA, b = inst.RB, d = inst.RD;
|
||||||
gpr.FlushLockX(EDX);
|
|
||||||
gpr.Lock(a, b, d);
|
gpr.Lock(a, b, d);
|
||||||
if (d != a && d != b) {
|
gpr.LoadToX64(d, (d == a || d == b), true);
|
||||||
gpr.LoadToX64(d, false, true);
|
if (d == a) {
|
||||||
|
IMUL(32, gpr.RX(d), gpr.R(b));
|
||||||
|
} else if (d == b) {
|
||||||
|
IMUL(32, gpr.RX(d), gpr.R(a));
|
||||||
} else {
|
} else {
|
||||||
gpr.LoadToX64(d, true, true);
|
MOV(32, gpr.R(d), gpr.R(b));
|
||||||
|
IMUL(32, gpr.RX(d), gpr.R(a));
|
||||||
}
|
}
|
||||||
MOV(32, R(EAX), gpr.R(a));
|
|
||||||
gpr.KillImmediate(b);
|
|
||||||
IMUL(32, gpr.R(b));
|
|
||||||
MOV(32, gpr.R(d), R(EAX));
|
|
||||||
gpr.UnlockAll();
|
gpr.UnlockAll();
|
||||||
gpr.UnlockAllX();
|
|
||||||
// result is already in eax
|
|
||||||
if (inst.Rc) {
|
if (inst.Rc) {
|
||||||
|
MOV(32, R(EAX), gpr.R(d));
|
||||||
CALL((u8*)Asm::computeRc);
|
CALL((u8*)Asm::computeRc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue