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:
parent
75815b9b0d
commit
3106b20fbe
|
@ -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, ®);
|
auto info = regBuildMemAddress(RI, I, getOp1(I), 1, ®);
|
||||||
|
|
||||||
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)
|
||||||
|
|
Loading…
Reference in New Issue