From 79b478e0baec46fc09e95b4611a56f1a25026aba Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Thu, 21 Jun 2018 16:33:02 -0700 Subject: [PATCH] Expand ARM local variable R11-based addressing When addressing a local with negative offsets from R11 (if it can't be reached from SP), allow the full range of negative offsets allowed in the instructions. Floating-point load/store especially has a much bigger range than what was previously allowed. Commit migrated from https://github.com/dotnet/coreclr/commit/a8bccc94862a03ed1503b63cf8a38a7446353471 --- src/coreclr/src/jit/compiler.hpp | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/coreclr/src/jit/compiler.hpp b/src/coreclr/src/jit/compiler.hpp index f0c7449..92ea539 100644 --- a/src/coreclr/src/jit/compiler.hpp +++ b/src/coreclr/src/jit/compiler.hpp @@ -2425,32 +2425,34 @@ inline { *pBaseReg = REG_FPBASE; } - // Change the FP-based addressing to the SP-based addressing when possible because + // Change the Frame Pointer (R11)-based addressing to the SP-based addressing when possible because // it generates smaller code on ARM. See frame picture above for the math. else { // If it is the final frame layout phase, we don't have a choice, we should stick // to either FP based or SP based that we decided in the earlier phase. Because - // we have already selected the instruction. Min-opts will have R10 enabled, so just - // use that. - - int spOffset = fConservative ? compLclFrameSize : offset + codeGen->genSPtoFPdelta(); - int actualOffset = (spOffset + addrModeOffset); - int ldrEncodeLimit = (varTypeIsFloating(type) ? 0x3FC : 0xFFC); - // Use ldr sp imm encoding. - if (opts.MinOpts() || (actualOffset <= ldrEncodeLimit)) + // we have already selected the instruction. MinOpts will always reserve R10, so + // for MinOpts always use SP-based offsets, using R10 as necessary, for simplicity. + + int spOffset = fConservative ? compLclFrameSize : offset + codeGen->genSPtoFPdelta(); + int actualOffset = spOffset + addrModeOffset; + int encodingLimitUpper = varTypeIsFloating(type) ? 0x3FC : 0xFFF; + int encodingLimitLower = varTypeIsFloating(type) ? -0x3FC : -0xFF; + + // Use SP-based encoding. During encoding, we'll pick the best encoding for the actual offset we have. + if (opts.MinOpts() || (actualOffset <= encodingLimitUpper)) { offset = spOffset; *pBaseReg = compLocallocUsed ? REG_SAVED_LOCALLOC_SP : REG_SPBASE; } - // Use ldr +/-imm8 encoding. - else if (offset >= -0x7C && offset <= ldrEncodeLimit) + // Use Frame Pointer (R11)-based encoding. + else if ((encodingLimitLower <= offset) && (offset <= encodingLimitUpper)) { *pBaseReg = REG_FPBASE; } - // Otherwise, use SP. This is either (1) a small positive offset using a single movw, (2) - // a large offset using movw/movt. In either case, we must have already reserved - // the "reserved register". + // Otherwise, use SP-based encoding. This is either (1) a small positive offset using a single movw, + // (2) a large offset using movw/movt. In either case, we must have already reserved + // the "reserved register", which will get used during encoding. else { offset = spOffset; -- 2.7.4