Merge pull request #1081 from phire/jitil-float-mem-opts

JitIL Float load/store optimizations.
This commit is contained in:
Ryan Houdek 2015-01-23 21:47:03 -06:00
commit 088b6b2ec3
2 changed files with 33 additions and 13 deletions

View File

@ -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);

View File

@ -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, &reg);
auto info = regBuildMemAddress(RI, I, getOp1(I), 1, &reg);
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)