mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-10 08:09:26 +01:00
Merge pull request #1081 from phire/jitil-float-mem-opts
JitIL Float load/store optimizations.
This commit is contained in:
commit
088b6b2ec3
@ -632,6 +632,11 @@ public:
|
||||
void MOVHLPS(X64Reg regOp1, X64Reg regOp2);
|
||||
void MOVLHPS(X64Reg regOp1, X64Reg regOp2);
|
||||
|
||||
// Be careful when using these overloads for reg <--> xmm moves.
|
||||
// The one you cast to OpArg with R(reg) is the x86 reg, the other
|
||||
// one is the xmm reg.
|
||||
// ie: "MOVD_xmm(eax, R(xmm1))" generates incorrect code (movd xmm0, rcx)
|
||||
// use "MOVD_xmm(R(eax), xmm1)" instead.
|
||||
void MOVD_xmm(X64Reg dest, const OpArg &arg);
|
||||
void MOVQ_xmm(X64Reg dest, OpArg arg);
|
||||
void MOVD_xmm(const OpArg &arg, X64Reg src);
|
||||
|
@ -515,7 +515,7 @@ static void regMarkMemAddress(RegInfo& RI, InstLoc I, InstLoc AI, unsigned OpNum
|
||||
|
||||
// in 64-bit build, this returns a completely bizarre address sometimes!
|
||||
static std::pair<OpArg, u32> regBuildMemAddress(RegInfo& RI, InstLoc I, InstLoc AI,
|
||||
unsigned OpNum, unsigned Size, X64Reg* dest)
|
||||
unsigned OpNum, X64Reg* dest)
|
||||
{
|
||||
if (isImm(*AI))
|
||||
{
|
||||
@ -577,7 +577,7 @@ static std::pair<OpArg, u32> regBuildMemAddress(RegInfo& RI, InstLoc I, InstLoc
|
||||
static void regEmitMemLoad(RegInfo& RI, InstLoc I, unsigned Size)
|
||||
{
|
||||
X64Reg reg;
|
||||
auto info = regBuildMemAddress(RI, I, getOp1(I), 1, Size, ®);
|
||||
auto info = regBuildMemAddress(RI, I, getOp1(I), 1, ®);
|
||||
|
||||
RI.Jit->SafeLoadToReg(reg, info.first, Size, info.second, regsInUse(RI), false);
|
||||
if (regReadUse(RI, I))
|
||||
@ -604,7 +604,7 @@ static OpArg regImmForConst(RegInfo& RI, InstLoc I, unsigned Size)
|
||||
|
||||
static void regEmitMemStore(RegInfo& RI, InstLoc I, unsigned Size)
|
||||
{
|
||||
auto info = regBuildMemAddress(RI, I, getOp2(I), 2, Size, nullptr);
|
||||
auto info = regBuildMemAddress(RI, I, getOp2(I), 2, nullptr);
|
||||
if (info.first.IsImm())
|
||||
RI.Jit->MOV(32, R(RSCRATCH2), info.first);
|
||||
else
|
||||
@ -824,10 +824,10 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
|
||||
case Load8:
|
||||
case Load16:
|
||||
case Load32:
|
||||
regMarkMemAddress(RI, I, getOp1(I), 1);
|
||||
break;
|
||||
case LoadDouble:
|
||||
case LoadSingle:
|
||||
regMarkMemAddress(RI, I, getOp1(I), 1);
|
||||
break;
|
||||
case LoadPaired:
|
||||
if (thisUsed)
|
||||
regMarkUse(RI, I, getOp1(I), 1);
|
||||
@ -901,6 +901,9 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
|
||||
break;
|
||||
case StoreSingle:
|
||||
case StoreDouble:
|
||||
regMarkUse(RI, I, getOp1(I), 1);
|
||||
regMarkMemAddress(RI, I, getOp2(I), 2);
|
||||
break;
|
||||
case StorePaired:
|
||||
regMarkUse(RI, I, getOp1(I), 1);
|
||||
regMarkUse(RI, I, getOp2(I), 2);
|
||||
@ -1555,8 +1558,9 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
|
||||
break;
|
||||
|
||||
X64Reg reg = fregFindFreeReg(RI);
|
||||
Jit->MOV(32, R(RSCRATCH2), regLocForInst(RI, getOp1(I)));
|
||||
RI.Jit->SafeLoadToReg(RSCRATCH2, R(RSCRATCH2), 32, 0, regsInUse(RI), false);
|
||||
auto info = regBuildMemAddress(RI, I, getOp1(I), 1, nullptr);
|
||||
|
||||
RI.Jit->SafeLoadToReg(RSCRATCH2, info.first, 32, info.second, regsInUse(RI), false);
|
||||
Jit->MOVD_xmm(reg, R(RSCRATCH2));
|
||||
RI.fregs[reg] = I;
|
||||
regNormalRegClear(RI, I);
|
||||
@ -1568,9 +1572,9 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
|
||||
break;
|
||||
|
||||
X64Reg reg = fregFindFreeReg(RI);
|
||||
const OpArg loc = regLocForInst(RI, getOp1(I));
|
||||
Jit->MOV(32, R(RSCRATCH2), loc);
|
||||
RI.Jit->SafeLoadToReg(RSCRATCH2, R(RSCRATCH2), 64, 0, regsInUse(RI), false);
|
||||
auto info = regBuildMemAddress(RI, I, getOp1(I), 1, nullptr);
|
||||
|
||||
RI.Jit->SafeLoadToReg(RSCRATCH2, info.first, 64, info.second, regsInUse(RI), false);
|
||||
Jit->MOVQ_xmm(reg, R(RSCRATCH2));
|
||||
RI.fregs[reg] = I;
|
||||
regNormalRegClear(RI, I);
|
||||
@ -1610,8 +1614,14 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
|
||||
else
|
||||
Jit->MOV(32, R(RSCRATCH), loc1);
|
||||
|
||||
Jit->MOV(32, R(RSCRATCH2), regLocForInst(RI, getOp2(I)));
|
||||
auto info = regBuildMemAddress(RI, I, getOp2(I), 2, nullptr);
|
||||
if (info.first.IsImm())
|
||||
RI.Jit->MOV(32, R(RSCRATCH2), info.first);
|
||||
else
|
||||
RI.Jit->LEA(32, RSCRATCH2, MDisp(info.first.GetSimpleReg(), info.second));
|
||||
|
||||
RI.Jit->SafeWriteRegToReg(RSCRATCH, RSCRATCH2, 32, 0, regsInUse(RI));
|
||||
|
||||
if (RI.IInfo[I - RI.FirstI] & 4)
|
||||
fregClearInst(RI, getOp1(I));
|
||||
if (RI.IInfo[I - RI.FirstI] & 8)
|
||||
@ -1623,10 +1633,15 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
|
||||
regSpill(RI, RSCRATCH);
|
||||
|
||||
OpArg value = fregLocForInst(RI, getOp1(I));
|
||||
OpArg address = regLocForInst(RI, getOp2(I));
|
||||
Jit->MOVAPD(XMM0, value);
|
||||
Jit->MOVQ_xmm(R(RSCRATCH), XMM0);
|
||||
Jit->MOV(32, R(RSCRATCH2), address);
|
||||
|
||||
auto info = regBuildMemAddress(RI, I, getOp2(I), 2, nullptr);
|
||||
if (info.first.IsImm())
|
||||
RI.Jit->MOV(32, R(RSCRATCH2), info.first);
|
||||
else
|
||||
RI.Jit->LEA(32, RSCRATCH2, MDisp(info.first.GetSimpleReg(), info.second));
|
||||
|
||||
RI.Jit->SafeWriteRegToReg(RSCRATCH, RSCRATCH2, 64, 0, regsInUse(RI));
|
||||
|
||||
if (RI.IInfo[I - RI.FirstI] & 4)
|
||||
|
Loading…
x
Reference in New Issue
Block a user