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! // in 64-bit build, this returns a completely bizarre address sometimes!
static std::pair<OpArg, u32> regBuildMemAddress(RegInfo& RI, InstLoc I, InstLoc AI, 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)) 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) static void regEmitMemLoad(RegInfo& RI, InstLoc I, unsigned Size)
{ {
X64Reg reg; 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); RI.Jit->SafeLoadToReg(reg, info.first, Size, info.second, regsInUse(RI), false);
if (regReadUse(RI, I)) 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) 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()) if (info.first.IsImm())
RI.Jit->MOV(32, R(RSCRATCH2), info.first); RI.Jit->MOV(32, R(RSCRATCH2), info.first);
else else
@ -824,10 +824,10 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
case Load8: case Load8:
case Load16: case Load16:
case Load32: case Load32:
regMarkMemAddress(RI, I, getOp1(I), 1);
break;
case LoadDouble: case LoadDouble:
case LoadSingle: case LoadSingle:
regMarkMemAddress(RI, I, getOp1(I), 1);
break;
case LoadPaired: case LoadPaired:
if (thisUsed) if (thisUsed)
regMarkUse(RI, I, getOp1(I), 1); regMarkUse(RI, I, getOp1(I), 1);
@ -901,6 +901,9 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
break; break;
case StoreSingle: case StoreSingle:
case StoreDouble: case StoreDouble:
regMarkUse(RI, I, getOp1(I), 1);
regMarkMemAddress(RI, I, getOp2(I), 2);
break;
case StorePaired: case StorePaired:
regMarkUse(RI, I, getOp1(I), 1); regMarkUse(RI, I, getOp1(I), 1);
regMarkUse(RI, I, getOp2(I), 2); regMarkUse(RI, I, getOp2(I), 2);
@ -1555,8 +1558,9 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
break; break;
X64Reg reg = fregFindFreeReg(RI); X64Reg reg = fregFindFreeReg(RI);
Jit->MOV(32, R(RSCRATCH2), regLocForInst(RI, getOp1(I))); auto info = regBuildMemAddress(RI, I, getOp1(I), 1, nullptr);
RI.Jit->SafeLoadToReg(RSCRATCH2, R(RSCRATCH2), 32, 0, regsInUse(RI), false);
RI.Jit->SafeLoadToReg(RSCRATCH2, info.first, 32, info.second, regsInUse(RI), false);
Jit->MOVD_xmm(reg, R(RSCRATCH2)); Jit->MOVD_xmm(reg, R(RSCRATCH2));
RI.fregs[reg] = I; RI.fregs[reg] = I;
regNormalRegClear(RI, I); regNormalRegClear(RI, I);
@ -1568,9 +1572,9 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
break; break;
X64Reg reg = fregFindFreeReg(RI); X64Reg reg = fregFindFreeReg(RI);
const OpArg loc = regLocForInst(RI, getOp1(I)); auto info = regBuildMemAddress(RI, I, getOp1(I), 1, nullptr);
Jit->MOV(32, R(RSCRATCH2), loc);
RI.Jit->SafeLoadToReg(RSCRATCH2, R(RSCRATCH2), 64, 0, regsInUse(RI), false); RI.Jit->SafeLoadToReg(RSCRATCH2, info.first, 64, info.second, regsInUse(RI), false);
Jit->MOVQ_xmm(reg, R(RSCRATCH2)); Jit->MOVQ_xmm(reg, R(RSCRATCH2));
RI.fregs[reg] = I; RI.fregs[reg] = I;
regNormalRegClear(RI, I); regNormalRegClear(RI, I);
@ -1610,8 +1614,14 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
else else
Jit->MOV(32, R(RSCRATCH), loc1); 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)); RI.Jit->SafeWriteRegToReg(RSCRATCH, RSCRATCH2, 32, 0, regsInUse(RI));
if (RI.IInfo[I - RI.FirstI] & 4) if (RI.IInfo[I - RI.FirstI] & 4)
fregClearInst(RI, getOp1(I)); fregClearInst(RI, getOp1(I));
if (RI.IInfo[I - RI.FirstI] & 8) if (RI.IInfo[I - RI.FirstI] & 8)
@ -1623,10 +1633,15 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
regSpill(RI, RSCRATCH); regSpill(RI, RSCRATCH);
OpArg value = fregLocForInst(RI, getOp1(I)); OpArg value = fregLocForInst(RI, getOp1(I));
OpArg address = regLocForInst(RI, getOp2(I));
Jit->MOVAPD(XMM0, value); Jit->MOVAPD(XMM0, value);
Jit->MOVQ_xmm(R(RSCRATCH), XMM0); 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)); RI.Jit->SafeWriteRegToReg(RSCRATCH, RSCRATCH2, 64, 0, regsInUse(RI));
if (RI.IInfo[I - RI.FirstI] & 4) if (RI.IInfo[I - RI.FirstI] & 4)