From 75815b9b0dd7c7d8d8e6603190570f8834500e54 Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Sun, 14 Sep 2014 16:23:38 +1200 Subject: [PATCH 1/2] Added a comment to document an issue with the codegen. --- Source/Core/Common/x64Emitter.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Source/Core/Common/x64Emitter.h b/Source/Core/Common/x64Emitter.h index 48a1eae3b1..1c32c54969 100644 --- a/Source/Core/Common/x64Emitter.h +++ b/Source/Core/Common/x64Emitter.h @@ -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); From 3106b20fbec2487c29f11feac24bd912d7372293 Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Sun, 14 Sep 2014 16:47:48 +1200 Subject: [PATCH 2/2] 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] --- Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp | 41 ++++++++++++++------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp b/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp index 21288492a7..c9aae70d21 100644 --- a/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp +++ b/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp @@ -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 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 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)