JITIL: Improve address calulation for float loads/stores.

For floating loads with a known address, this eliminates the pattern of:

   mov r12d, 80001014
   mov rdx, r12d
   mov rdx, dword ptr [rbp+rdx]

and generates a nice simple:

   mov rdx, dword ptr [rbp+00001014]
This commit is contained in:
Scott Mansell 2014-09-14 16:47:48 +12:00
parent 75815b9b0d
commit 3106b20fbe
1 changed files with 28 additions and 13 deletions

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)