summaryrefslogtreecommitdiff
path: root/src/jit
diff options
context:
space:
mode:
authorBruce Forstall <brucefo@microsoft.com>2019-04-12 10:50:56 -0700
committerBruce Forstall <brucefo@microsoft.com>2019-04-12 10:50:56 -0700
commit2688d6b3137b04d2c3263564334335ec3e1630ad (patch)
tree8c70a7d1ef088d75778621a21b22b53c2b943750 /src/jit
parenta6b1e978157278d09247bb82543a21886e087583 (diff)
downloadcoreclr-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.
Diffstat (limited to 'src/jit')
-rw-r--r--src/jit/codegenarm64.cpp15
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);