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:
XTra.KrazzY 2008-11-22 12:10:35 +00:00
parent fb2b57a47c
commit 145f80fc00
3 changed files with 75 additions and 25 deletions

View File

@ -936,6 +936,64 @@ namespace Gen
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 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)

View File

@ -282,7 +282,9 @@ namespace Gen
void DIV(int bits, OpArg src);
void IMUL(int bits, OpArg src); //SIGNED
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 NOT(int bits, OpArg src);

View File

@ -486,19 +486,11 @@ namespace Jit64
#endif
INSTRUCTION_START;
int a = inst.RA, d = inst.RD;
gpr.FlushLockX(EDX);
gpr.Lock(a, d);
if (d != a) {
gpr.LoadToX64(d, false, true);
} else {
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.UnlockAllX();
gpr.Lock(a, d);
gpr.LoadToX64(d, (d == a), true);
gpr.KillImmediate(a);
IMUL(32, gpr.RX(d), gpr.R(a), Imm32((u32)(s32)inst.SIMM_16));
gpr.UnlockAll();
}
void mullwx(UGeckoInstruction inst)
@ -509,21 +501,19 @@ namespace Jit64
#endif
INSTRUCTION_START;
int a = inst.RA, b = inst.RB, d = inst.RD;
gpr.FlushLockX(EDX);
gpr.Lock(a, b, d);
if (d != a && d != b) {
gpr.LoadToX64(d, false, true);
gpr.Lock(a, b, d);
gpr.LoadToX64(d, (d == a || d == b), 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 {
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.UnlockAllX();
// result is already in eax
if (inst.Rc) {
MOV(32, R(EAX), gpr.R(d));
CALL((u8*)Asm::computeRc);
}
}