diff options
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.patch | 93 |
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 + |