diff options
author | Bruce Forstall <brucefo@microsoft.com> | 2019-04-12 10:50:56 -0700 |
---|---|---|
committer | Bruce Forstall <brucefo@microsoft.com> | 2019-04-12 10:50:56 -0700 |
commit | 2688d6b3137b04d2c3263564334335ec3e1630ad (patch) | |
tree | 8c70a7d1ef088d75778621a21b22b53c2b943750 | |
parent | a6b1e978157278d09247bb82543a21886e087583 (diff) | |
download | coreclr-2688d6b3137b04d2c3263564334335ec3e1630ad.tar.gz coreclr-2688d6b3137b04d2c3263564334335ec3e1630ad.tar.bz2 coreclr-2688d6b3137b04d2c3263564334335ec3e1630ad.zip |
Fix arm64 localloc with large outgoing argument space
With a large outgoing argument space, we were attempting to
generate un-encodable ADD and SUB instructions. Call an existing
helper instead that uses the reserved register when needed to
load large constants into a register.
-rw-r--r-- | src/jit/codegenarm64.cpp | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/src/jit/codegenarm64.cpp b/src/jit/codegenarm64.cpp index 4668aaf5b8..91bb221b19 100644 --- a/src/jit/codegenarm64.cpp +++ b/src/jit/codegenarm64.cpp @@ -49,8 +49,10 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // attr - operation size and GC attribute // reg1, reg2 - first and second register operands // imm - immediate value (third operand when it fits) -// tmpReg - temp register to use when the 'imm' doesn't fit -// inUnwindRegion - true if we are in a prolog/epilog region with unwind codes +// tmpReg - temp register to use when the 'imm' doesn't fit. Can be REG_NA +// if caller knows for certain the constant will fit. +// inUnwindRegion - true if we are in a prolog/epilog region with unwind codes. +// Default: false. // // Return Value: // returns true if the immediate was too large and tmpReg was used and modified. @@ -2146,7 +2148,8 @@ void CodeGen::genLclHeap(GenTree* tree) { assert((compiler->lvaOutgoingArgSpaceSize % STACK_ALIGN) == 0); // This must be true for the stack to remain // aligned - inst_RV_IV(INS_add, REG_SPBASE, compiler->lvaOutgoingArgSpaceSize, EA_PTRSIZE); + genInstrWithConstant(INS_add, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, compiler->lvaOutgoingArgSpaceSize, + rsGetRsvdReg()); stackAdjustment += compiler->lvaOutgoingArgSpaceSize; } @@ -2301,12 +2304,12 @@ ALLOC_DONE: { assert((stackAdjustment % STACK_ALIGN) == 0); // This must be true for the stack to remain aligned assert(stackAdjustment > 0); - getEmitter()->emitIns_R_R_I(INS_sub, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, (int)stackAdjustment); + genInstrWithConstant(INS_sub, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, (ssize_t)stackAdjustment, rsGetRsvdReg()); // Return the stackalloc'ed address in result register. // TargetReg = SP + stackAdjustment. // - getEmitter()->emitIns_R_R_I(INS_add, EA_PTRSIZE, targetReg, REG_SPBASE, (int)stackAdjustment); + genInstrWithConstant(INS_add, EA_PTRSIZE, targetReg, REG_SPBASE, (ssize_t)stackAdjustment, rsGetRsvdReg()); } else // stackAdjustment == 0 { @@ -4534,7 +4537,7 @@ void CodeGen::genSIMDIntrinsicRelOp(GenTreeSIMD* simdNode) emitAttr attr = (simdNode->gtSIMDSize > 8) ? EA_16BYTE : EA_8BYTE; insOpts opt = genGetSimdInsOpt(attr, baseType); - // TODO-ARM64-CQ Contain integer constants where posible + // TODO-ARM64-CQ Contain integer constants where possible regNumber tmpFloatReg = simdNode->GetSingleTempReg(RBM_ALLFLOAT); |