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 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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.LoadToX64(d, (d == a), true);
|
||||
gpr.KillImmediate(a);
|
||||
IMUL(32, gpr.RX(d), gpr.R(a), Imm32((u32)(s32)inst.SIMM_16));
|
||||
gpr.UnlockAll();
|
||||
gpr.UnlockAllX();
|
||||
}
|
||||
|
||||
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.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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue