summaryrefslogtreecommitdiff
path: root/packaging/0045-Replace-push-pop-of-R11-for-function-epilog-with-usa.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packaging/0045-Replace-push-pop-of-R11-for-function-epilog-with-usa.patch')
-rw-r--r--packaging/0045-Replace-push-pop-of-R11-for-function-epilog-with-usa.patch93
1 files changed, 93 insertions, 0 deletions
diff --git a/packaging/0045-Replace-push-pop-of-R11-for-function-epilog-with-usa.patch b/packaging/0045-Replace-push-pop-of-R11-for-function-epilog-with-usa.patch
new file mode 100644
index 0000000000..314cd00eba
--- /dev/null
+++ b/packaging/0045-Replace-push-pop-of-R11-for-function-epilog-with-usa.patch
@@ -0,0 +1,93 @@
+From 777191a4bb6197f29d04889698c167aec4b49d39 Mon Sep 17 00:00:00 2001
+From: Gleb Balykov <g.balykov@samsung.com>
+Date: Fri, 8 Jun 2018 19:16:11 +0300
+Subject: [PATCH 45/47] Replace push/pop of R11 for function epilog with usage
+ of LR as helper register right before its restore from stack
+
+---
+ src/jit/codegencommon.cpp | 52 +++++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 41 insertions(+), 11 deletions(-)
+
+diff --git a/src/jit/codegencommon.cpp b/src/jit/codegencommon.cpp
+index 51cc777..3084582 100644
+--- a/src/jit/codegencommon.cpp
++++ b/src/jit/codegencommon.cpp
+@@ -9433,6 +9433,43 @@ void CodeGen::genFnEpilog(BasicBlock* block)
+ unwindStarted = true;
+ }
+
++#ifdef FEATURE_NGEN_RELOCS_OPTIMIZATIONS
++ if (jmpEpilog)
++ {
++ // In case of FEATURE_NGEN_RELOCS_OPTIMIZATIONS and IAT_RELPVALUE jump at the end is done using
++ // relative indirection, so, additional helper register is required.
++ // We use LR just before it is going to be restored from stack, i.e.
++ //
++ // movw r12, laddr
++ // movt r12, haddr
++ // mov lr, r12
++ // ldr r12, [r12]
++ // add r12, r12, lr
++ // pop {lr}
++ // ...
++ // bx r12
++
++ GenTree* jmpNode = block->lastNode();
++
++ noway_assert(jmpNode->gtOper == GT_JMP);
++
++ CORINFO_METHOD_HANDLE methHnd = (CORINFO_METHOD_HANDLE)jmpNode->gtVal.gtVal1;
++ CORINFO_CONST_LOOKUP addrInfo;
++ compiler->info.compCompHnd->getFunctionEntryPoint(methHnd, &addrInfo);
++
++ if (addrInfo.accessType == IAT_RELPVALUE)
++ {
++ regNumber indCallReg = REG_R12;
++ regNumber vptrReg1 = REG_LR;
++
++ instGen_Set_Reg_To_Imm(EA_HANDLE_CNS_RELOC, indCallReg, (ssize_t)addrInfo.addr);
++ getEmitter()->emitIns_R_R(INS_mov, EA_PTRSIZE, vptrReg1, indCallReg);
++ getEmitter()->emitIns_R_R_I(INS_ldr, EA_PTRSIZE, indCallReg, indCallReg, 0);
++ getEmitter()->emitIns_R_R(INS_add, EA_PTRSIZE, indCallReg, vptrReg1);
++ }
++ }
++#endif // FEATURE_NGEN_RELOCS_OPTIMIZATIONS
++
+ genPopCalleeSavedRegisters(jmpEpilog);
+
+ if (regSet.rsMaskPreSpillRegs(true) != RBM_NONE)
+@@ -9497,27 +9534,20 @@ void CodeGen::genFnEpilog(BasicBlock* block)
+ break;
+
+ case IAT_RELPVALUE:
++#ifdef FEATURE_NGEN_RELOCS_OPTIMIZATIONS
+ {
+ // Load the address into a register, load relative indirect and call through a register
+ // We have to use R12 since we assume the argument registers are in use
++ // LR is used as helper register right before it is restored from stack, thus,
++ // all relative address calculations are performed before LR is restored.
+ callType = emitter::EC_INDIR_R;
+ indCallReg = REG_R12;
+ addr = NULL;
+
+- regNumber vptrReg1 = REG_R11;
+- regMaskTP vptrReg1Mask = genRegMask(vptrReg1);
+- inst_IV(INS_push, (int)vptrReg1Mask);
+-
+- instGen_Set_Reg_To_Imm(EA_HANDLE_CNS_RELOC, indCallReg, (ssize_t)addrInfo.addr);
+- getEmitter()->emitIns_R_R(INS_mov, EA_PTRSIZE, vptrReg1, indCallReg);
+- getEmitter()->emitIns_R_R_I(INS_ldr, EA_PTRSIZE, indCallReg, indCallReg, 0);
+- getEmitter()->emitIns_R_R(INS_add, EA_PTRSIZE, indCallReg, vptrReg1);
+-
+- inst_IV(INS_pop, (int)vptrReg1Mask);
+-
+ regTracker.rsTrackRegTrash(indCallReg);
+ break;
+ }
++#endif // FEATURE_NGEN_RELOCS_OPTIMIZATIONS
+
+ case IAT_PPVALUE:
+ default:
+--
+2.7.4
+