From de9245bd24c06ba1907c988f6298365c79ec1328 Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Thu, 7 Mar 2019 17:08:53 -0800 Subject: [PATCH] Allow coalescing of SP adjustment into single register prolog STR/LDR Commit migrated from https://github.com/dotnet/coreclr/commit/6e6a4b26dfe914e6924d03ce91aa52f2fab05d79 --- src/coreclr/src/jit/codegenarm64.cpp | 56 ++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/src/coreclr/src/jit/codegenarm64.cpp b/src/coreclr/src/jit/codegenarm64.cpp index e07aad5..54985cd 100644 --- a/src/coreclr/src/jit/codegenarm64.cpp +++ b/src/coreclr/src/jit/codegenarm64.cpp @@ -280,16 +280,32 @@ void CodeGen::genPrologSaveReg(regNumber reg1, int spOffset, int spDelta, regNum assert(spDelta <= 0); assert((spDelta % 16) == 0); // SP changes must be 16-byte aligned + bool needToSaveRegs = true; if (spDelta != 0) { - // generate sub SP,SP,imm - genStackPointerAdjustment(spDelta, tmpReg, pTmpRegIsZero, /* reportUnwindData */ true); + if ((spOffset == 0) && (spDelta >= -256)) + { + // We can use pre-index addressing. + // str REG, [SP, #spDelta]! + getEmitter()->emitIns_R_R_I(INS_str, EA_PTRSIZE, reg1, REG_SPBASE, spDelta, INS_OPTS_PRE_INDEX); + compiler->unwindSaveRegPreindexed(reg1, spDelta); + + needToSaveRegs = false; + } + else // (spOffset != 0) || (spDelta < -256) + { + // generate sub SP,SP,imm + genStackPointerAdjustment(spDelta, tmpReg, pTmpRegIsZero, /* reportUnwindData */ true); + } } - // str REG, [SP, #offset] - // 64-bit STR offset range: 0 to 32760, multiple of 8. - getEmitter()->emitIns_R_R_I(INS_str, EA_PTRSIZE, reg1, REG_SPBASE, spOffset); - compiler->unwindSaveReg(reg1, spOffset); + if (needToSaveRegs) + { + // str REG, [SP, #offset] + // 64-bit STR offset range: 0 to 32760, multiple of 8. + getEmitter()->emitIns_R_R_I(INS_str, EA_PTRSIZE, reg1, REG_SPBASE, spOffset); + compiler->unwindSaveReg(reg1, spOffset); + } } //------------------------------------------------------------------------ @@ -385,14 +401,30 @@ void CodeGen::genEpilogRestoreReg(regNumber reg1, int spOffset, int spDelta, reg assert(spDelta >= 0); assert((spDelta % 16) == 0); // SP changes must be 16-byte aligned - // ldr reg1, [SP, #offset] - getEmitter()->emitIns_R_R_I(INS_ldr, EA_PTRSIZE, reg1, REG_SPBASE, spOffset); - compiler->unwindSaveReg(reg1, spOffset); - if (spDelta != 0) { - // generate add SP,SP,imm - genStackPointerAdjustment(spDelta, tmpReg, pTmpRegIsZero, /* reportUnwindData */ true); + if ((spOffset == 0) && (spDelta <= 255)) + { + // We can use post-index addressing. + // ldr REG, [SP], #spDelta + getEmitter()->emitIns_R_R_I(INS_ldr, EA_PTRSIZE, reg1, REG_SPBASE, spDelta, INS_OPTS_POST_INDEX); + compiler->unwindSaveRegPreindexed(reg1, -spDelta); + } + else // (spOffset != 0) || (spDelta > 255) + { + // ldr reg1, [SP, #offset] + getEmitter()->emitIns_R_R_I(INS_ldr, EA_PTRSIZE, reg1, REG_SPBASE, spOffset); + compiler->unwindSaveReg(reg1, spOffset); + + // generate add SP,SP,imm + genStackPointerAdjustment(spDelta, tmpReg, pTmpRegIsZero, /* reportUnwindData */ true); + } + } + else + { + // ldr reg1, [SP, #offset] + getEmitter()->emitIns_R_R_I(INS_ldr, EA_PTRSIZE, reg1, REG_SPBASE, spOffset); + compiler->unwindSaveReg(reg1, spOffset); } } -- 2.7.4