summaryrefslogtreecommitdiff
path: root/src/jit/codegenlegacy.cpp
diff options
context:
space:
mode:
authorJiyoung Yun <jy910.yun@samsung.com>2016-12-27 16:46:08 +0900
committerJiyoung Yun <jy910.yun@samsung.com>2016-12-27 16:46:08 +0900
commitdb20f3f1bb8595633a7e16c8900fd401a453a6b5 (patch)
treee5435159cd1bf0519276363a6fe1663d1721bed3 /src/jit/codegenlegacy.cpp
parent4b4aad7217d3292650e77eec2cf4c198ea9c3b4b (diff)
downloadcoreclr-db20f3f1bb8595633a7e16c8900fd401a453a6b5.tar.gz
coreclr-db20f3f1bb8595633a7e16c8900fd401a453a6b5.tar.bz2
coreclr-db20f3f1bb8595633a7e16c8900fd401a453a6b5.zip
Imported Upstream version 1.0.0.9127upstream/1.0.0.9127
Diffstat (limited to 'src/jit/codegenlegacy.cpp')
-rw-r--r--src/jit/codegenlegacy.cpp448
1 files changed, 97 insertions, 351 deletions
diff --git a/src/jit/codegenlegacy.cpp b/src/jit/codegenlegacy.cpp
index ea40eb2aff..667b9d4af8 100644
--- a/src/jit/codegenlegacy.cpp
+++ b/src/jit/codegenlegacy.cpp
@@ -243,18 +243,6 @@ GenTreePtr CodeGen::genGetAddrModeBase(GenTreePtr tree)
return NULL;
}
-// inline
-void CodeGen::genSinglePush()
-{
- genStackLevel += sizeof(void*);
-}
-
-// inline
-void CodeGen::genSinglePop()
-{
- genStackLevel -= sizeof(void*);
-}
-
#if FEATURE_STACK_FP_X87
// inline
void CodeGenInterface::genResetFPstkLevel(unsigned newValue /* = 0 */)
@@ -497,9 +485,10 @@ void CodeGen::genIncRegBy(regNumber reg, ssize_t ival, GenTreePtr tree, var_type
}
}
#endif
-
- insFlags flags = setFlags ? INS_FLAGS_SET : INS_FLAGS_DONT_CARE;
- inst_RV_IV(INS_add, reg, ival, emitActualTypeSize(dstType), flags);
+ {
+ insFlags flags = setFlags ? INS_FLAGS_SET : INS_FLAGS_DONT_CARE;
+ inst_RV_IV(INS_add, reg, ival, emitActualTypeSize(dstType), flags);
+ }
#ifdef _TARGET_XARCH_
UPDATE_LIVENESS:
@@ -4328,8 +4317,6 @@ emitJumpKind CodeGen::genCondSetFlags(GenTreePtr cond)
addrReg1 = genMakeRvalueAddressable(op1, RBM_NONE, RegSet::KEEP_REG, false, smallOk);
}
- // #if defined(DEBUGGING_SUPPORT)
-
/* Special case: comparison of two constants */
// Needed if Importer doesn't call gtFoldExpr()
@@ -4347,8 +4334,6 @@ emitJumpKind CodeGen::genCondSetFlags(GenTreePtr cond)
addrReg1 = genRegMask(op1->gtRegNum);
}
- // #endif
-
/* Compare the operand against the constant */
if (op2->IsIconHandle())
@@ -7087,84 +7072,87 @@ void CodeGen::genCodeForTreeSmpBinArithLogOp(GenTreePtr tree, regMaskTP destReg,
regTracker.rsTrackRegTrash(reg);
- bool op2Released = false;
+ {
+ bool op2Released = false;
- // For overflow instructions, tree->gtType is the accurate type,
- // and gives us the size for the operands.
+ // For overflow instructions, tree->gtType is the accurate type,
+ // and gives us the size for the operands.
- emitAttr opSize = emitTypeSize(treeType);
+ emitAttr opSize = emitTypeSize(treeType);
- /* Compute the new value */
+ /* Compute the new value */
- if (isArith && !op2->InReg() && (op2->OperKind() & GTK_CONST)
+ if (isArith && !op2->InReg() && (op2->OperKind() & GTK_CONST)
#if !CPU_HAS_FP_SUPPORT
- && (treeType == TYP_INT || treeType == TYP_I_IMPL)
+ && (treeType == TYP_INT || treeType == TYP_I_IMPL)
#endif
- )
- {
- ssize_t ival = op2->gtIntCon.gtIconVal;
-
- if (oper == GT_ADD)
- {
- genIncRegBy(reg, ival, tree, treeType, ovfl);
- }
- else if (oper == GT_SUB)
- {
- if (ovfl && ((tree->gtFlags & GTF_UNSIGNED) ||
- (ival == ((treeType == TYP_INT) ? INT32_MIN : SSIZE_T_MIN))) // -0x80000000 == 0x80000000.
- // Therefore we can't use -ival.
)
- {
- /* For unsigned overflow, we have to use INS_sub to set
- the flags correctly */
+ {
+ ssize_t ival = op2->gtIntCon.gtIconVal;
- genDecRegBy(reg, ival, tree);
+ if (oper == GT_ADD)
+ {
+ genIncRegBy(reg, ival, tree, treeType, ovfl);
}
- else
+ else if (oper == GT_SUB)
{
- /* Else, we simply add the negative of the value */
+ if (ovfl && ((tree->gtFlags & GTF_UNSIGNED) ||
+ (ival == ((treeType == TYP_INT) ? INT32_MIN : SSIZE_T_MIN))) // -0x80000000 == 0x80000000.
+ // Therefore we can't use -ival.
+ )
+ {
+ /* For unsigned overflow, we have to use INS_sub to set
+ the flags correctly */
- genIncRegBy(reg, -ival, tree, treeType, ovfl);
+ genDecRegBy(reg, ival, tree);
+ }
+ else
+ {
+ /* Else, we simply add the negative of the value */
+
+ genIncRegBy(reg, -ival, tree, treeType, ovfl);
+ }
+ }
+ else if (oper == GT_MUL)
+ {
+ genMulRegBy(reg, ival, tree, treeType, ovfl);
}
}
- else if (oper == GT_MUL)
- {
- genMulRegBy(reg, ival, tree, treeType, ovfl);
- }
- }
- else
- {
- // op2 could be a GT_COMMA (i.e. an assignment for a CSE def)
- op2 = op2->gtEffectiveVal();
- if (varTypeIsByte(treeType) && op2->InReg())
+ else
{
- noway_assert(genRegMask(reg) & RBM_BYTE_REGS);
+ // op2 could be a GT_COMMA (i.e. an assignment for a CSE def)
+ op2 = op2->gtEffectiveVal();
+ if (varTypeIsByte(treeType) && op2->InReg())
+ {
+ noway_assert(genRegMask(reg) & RBM_BYTE_REGS);
- regNumber op2reg = op2->gtRegNum;
- regMaskTP op2regMask = genRegMask(op2reg);
+ regNumber op2reg = op2->gtRegNum;
+ regMaskTP op2regMask = genRegMask(op2reg);
- if (!(op2regMask & RBM_BYTE_REGS))
- {
- regNumber byteReg = regSet.rsGrabReg(RBM_BYTE_REGS);
+ if (!(op2regMask & RBM_BYTE_REGS))
+ {
+ regNumber byteReg = regSet.rsGrabReg(RBM_BYTE_REGS);
- inst_RV_RV(INS_mov, byteReg, op2reg);
- regTracker.rsTrackRegTrash(byteReg);
+ inst_RV_RV(INS_mov, byteReg, op2reg);
+ regTracker.rsTrackRegTrash(byteReg);
- genDoneAddressable(op2, addrReg, RegSet::KEEP_REG);
- op2Released = true;
+ genDoneAddressable(op2, addrReg, RegSet::KEEP_REG);
+ op2Released = true;
- op2->gtRegNum = byteReg;
+ op2->gtRegNum = byteReg;
+ }
}
- }
- inst_RV_TT(ins, reg, op2, 0, opSize, flags);
- }
+ inst_RV_TT(ins, reg, op2, 0, opSize, flags);
+ }
- /* Free up anything that was tied up by the operand */
-
- if (!op2Released)
- genDoneAddressable(op2, addrReg, RegSet::KEEP_REG);
+ /* Free up anything that was tied up by the operand */
+ if (!op2Released)
+ {
+ genDoneAddressable(op2, addrReg, RegSet::KEEP_REG);
+ }
+ }
/* The result will be where the first operand is sitting */
/* We must use RegSet::KEEP_REG since op1 can have a GC pointer here */
@@ -9721,7 +9709,7 @@ void CodeGen::genCodeForTreeSmpOp(GenTreePtr tree, regMaskTP destReg, regMaskTP
switch (oper)
{
case GT_ASG:
- if (tree->OperIsBlkOp())
+ if (tree->OperIsBlkOp() && op1->gtOper != GT_LCL_VAR)
{
genCodeForBlkOp(tree, destReg);
}
@@ -10184,6 +10172,9 @@ void CodeGen::genCodeForTreeSmpOp(GenTreePtr tree, regMaskTP destReg, regMaskTP
if (op1 == NULL)
return;
#endif
+ __fallthrough;
+
+ case GT_INIT_VAL:
/* Generate the operand into some register */
@@ -11293,10 +11284,8 @@ void CodeGen::genCodeForTreeSmpOpAsg(GenTreePtr tree)
bool volat = false; // Is this a volatile store
regMaskTP regGC;
instruction ins;
-#ifdef DEBUGGING_SUPPORT
- unsigned lclVarNum = compiler->lvaCount;
- unsigned lclILoffs = DUMMY_INIT(0);
-#endif
+ unsigned lclVarNum = compiler->lvaCount;
+ unsigned lclILoffs = DUMMY_INIT(0);
#ifdef _TARGET_ARM_
if (tree->gtType == TYP_STRUCT)
@@ -11335,7 +11324,6 @@ void CodeGen::genCodeForTreeSmpOpAsg(GenTreePtr tree)
noway_assert(varNum < compiler->lvaCount);
varDsc = compiler->lvaTable + varNum;
-#ifdef DEBUGGING_SUPPORT
/* For non-debuggable code, every definition of a lcl-var has
* to be checked to see if we need to open a new scope for it.
* Remember the local var info to call siCheckVarScope
@@ -11346,7 +11334,6 @@ void CodeGen::genCodeForTreeSmpOpAsg(GenTreePtr tree)
lclVarNum = varNum;
lclILoffs = op1->gtLclVar.gtLclILoffs;
}
-#endif
/* Check against dead store ? (with min opts we may have dead stores) */
@@ -11999,13 +11986,11 @@ void CodeGen::genCodeForTreeSmpOpAsg(GenTreePtr tree)
genCodeForTreeSmpOpAsg_DONE_ASSG(tree, addrReg, REG_NA, ovfl);
LExit:
-#ifdef DEBUGGING_SUPPORT
/* For non-debuggable code, every definition of a lcl-var has
* to be checked to see if we need to open a new scope for it.
*/
if (lclVarNum < compiler->lvaCount)
siCheckVarScope(lclVarNum, lclILoffs);
-#endif
}
#ifdef _PREFAST_
#pragma warning(pop)
@@ -12436,14 +12421,12 @@ void CodeGen::genCodeForBBlist()
regSet.rsSpillBeg();
-#ifdef DEBUGGING_SUPPORT
/* Initialize the line# tracking logic */
if (compiler->opts.compScopeInfo)
{
siInit();
}
-#endif
#ifdef _TARGET_X86_
if (compiler->compTailCallUsed)
@@ -12774,27 +12757,7 @@ void CodeGen::genCodeForBBlist()
genResetFPstkLevel();
#endif // FEATURE_STACK_FP_X87
-#if !FEATURE_FIXED_OUT_ARGS
- /* Check for inserted throw blocks and adjust genStackLevel */
-
- if (!isFramePointerUsed() && compiler->fgIsThrowHlpBlk(block))
- {
- noway_assert(block->bbFlags & BBF_JMP_TARGET);
-
- genStackLevel = compiler->fgThrowHlpBlkStkLevel(block) * sizeof(int);
-
- if (genStackLevel)
- {
-#ifdef _TARGET_X86_
- getEmitter()->emitMarkStackLvl(genStackLevel);
- inst_RV_IV(INS_add, REG_SPBASE, genStackLevel, EA_PTRSIZE);
- genStackLevel = 0;
-#else // _TARGET_X86_
- NYI("Need emitMarkStackLvl()");
-#endif // _TARGET_X86_
- }
- }
-#endif // !FEATURE_FIXED_OUT_ARGS
+ genAdjustStackLevel(block);
savedStkLvl = genStackLevel;
@@ -12802,7 +12765,6 @@ void CodeGen::genCodeForBBlist()
compiler->compCurBB = block;
-#ifdef DEBUGGING_SUPPORT
siBeginBlock(block);
// BBF_INTERNAL blocks don't correspond to any single IL instruction.
@@ -12810,7 +12772,6 @@ void CodeGen::genCodeForBBlist()
genIPmappingAdd((IL_OFFSETX)ICorDebugInfo::NO_MAPPING, true);
bool firstMapping = true;
-#endif // DEBUGGING_SUPPORT
/*---------------------------------------------------------------------
*
@@ -12830,8 +12791,6 @@ void CodeGen::genCodeForBBlist()
{
noway_assert(stmt->gtOper == GT_STMT);
-#if defined(DEBUGGING_SUPPORT)
-
/* Do we have a new IL-offset ? */
if (stmt->gtStmt.gtStmtILoffsx != BAD_IL_OFFSET)
@@ -12841,8 +12800,6 @@ void CodeGen::genCodeForBBlist()
firstMapping = false;
}
-#endif // DEBUGGING_SUPPORT
-
#ifdef DEBUG
if (stmt->gtStmt.gtStmtLastILoffs != BAD_IL_OFFSET)
{
@@ -12945,7 +12902,7 @@ void CodeGen::genCodeForBBlist()
// harmless "inc" instruction (does not interfere with the exception
// object).
- if ((compiler->opts.eeFlags & CORJIT_FLG_BBINSTR) && (stmt == block->bbTreeList) &&
+ if (compiler->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_BBINSTR) && (stmt == block->bbTreeList) &&
(block->bbCatchTyp && handlerGetsXcptnObj(block->bbCatchTyp)))
{
nonVarPtrRegs &= ~RBM_EXCEPTION_OBJECT;
@@ -12972,14 +12929,10 @@ void CodeGen::genCodeForBBlist()
noway_assert(stmt->gtOper == GT_STMT);
-#ifdef DEBUGGING_SUPPORT
genEnsureCodeEmitted(stmt->gtStmt.gtStmtILoffsx);
-#endif
} //-------- END-FOR each statement-tree of the current block ---------
-#ifdef DEBUGGING_SUPPORT
-
if (compiler->opts.compScopeInfo && (compiler->info.compVarScopesCount > 0))
{
siEndBlock(block);
@@ -13005,8 +12958,6 @@ void CodeGen::genCodeForBBlist()
}
}
-#endif // DEBUGGING_SUPPORT
-
genStackLevel -= savedStkLvl;
gcInfo.gcMarkRegSetNpt(gcrefRegs | byrefRegs);
@@ -13449,10 +13400,8 @@ void CodeGen::genCodeForTreeLng(GenTreePtr tree, regMaskTP needReg, regMaskTP av
{
case GT_ASG:
{
-#ifdef DEBUGGING_SUPPORT
unsigned lclVarNum = compiler->lvaCount;
unsigned lclVarILoffs = DUMMY_INIT(0);
-#endif
/* Is the target a local ? */
@@ -13467,7 +13416,6 @@ void CodeGen::genCodeForTreeLng(GenTreePtr tree, regMaskTP needReg, regMaskTP av
// No dead stores, (with min opts we may have dead stores)
noway_assert(!varDsc->lvTracked || compiler->opts.MinOpts() || !(op1->gtFlags & GTF_VAR_DEATH));
-#ifdef DEBUGGING_SUPPORT
/* For non-debuggable code, every definition of a lcl-var has
* to be checked to see if we need to open a new scope for it.
* Remember the local var info to call siCheckVarScope
@@ -13479,7 +13427,6 @@ void CodeGen::genCodeForTreeLng(GenTreePtr tree, regMaskTP needReg, regMaskTP av
lclVarNum = varNum;
lclVarILoffs = op1->gtLclVar.gtLclILoffs;
}
-#endif
/* Has the variable been assigned to a register (pair) ? */
@@ -13767,13 +13714,11 @@ void CodeGen::genCodeForTreeLng(GenTreePtr tree, regMaskTP needReg, regMaskTP av
genUpdateLife(op1);
genUpdateLife(tree);
-#ifdef DEBUGGING_SUPPORT
/* For non-debuggable code, every definition of a lcl-var has
* to be checked to see if we need to open a new scope for it.
*/
if (lclVarNum < compiler->lvaCount)
siCheckVarScope(lclVarNum, lclVarILoffs);
-#endif
}
return;
@@ -15792,132 +15737,6 @@ void CodeGen::genEmitHelperCall(unsigned helper, int argSize, emitAttr retSize)
/*****************************************************************************
*
- * Push the given registers.
- * This function does not check if the register is marked as used, etc.
- */
-
-regMaskTP CodeGen::genPushRegs(regMaskTP regs, regMaskTP* byrefRegs, regMaskTP* noRefRegs)
-{
- *byrefRegs = RBM_NONE;
- *noRefRegs = RBM_NONE;
-
- // noway_assert((regs & regSet.rsRegMaskFree()) == regs); // Don't care. Caller is responsible for all this
-
- if (regs == RBM_NONE)
- return RBM_NONE;
-
-#if FEATURE_FIXED_OUT_ARGS
-
- NYI("Don't call genPushRegs with real regs!");
- return RBM_NONE;
-
-#else // FEATURE_FIXED_OUT_ARGS
-
- noway_assert(genTypeStSz(TYP_REF) == genTypeStSz(TYP_I_IMPL));
- noway_assert(genTypeStSz(TYP_BYREF) == genTypeStSz(TYP_I_IMPL));
-
- regMaskTP pushedRegs = regs;
-
- for (regNumber reg = REG_INT_FIRST; regs != RBM_NONE; reg = REG_NEXT(reg))
- {
- regMaskTP regBit = regMaskTP(1) << reg;
-
- if ((regBit & regs) == RBM_NONE)
- continue;
-
- var_types type;
- if (regBit & gcInfo.gcRegGCrefSetCur)
- {
- type = TYP_REF;
- }
- else if (regBit & gcInfo.gcRegByrefSetCur)
- {
- *byrefRegs |= regBit;
- type = TYP_BYREF;
- }
- else if (noRefRegs != NULL)
- {
- *noRefRegs |= regBit;
- type = TYP_I_IMPL;
- }
- else
- {
- continue;
- }
-
- inst_RV(INS_push, reg, type);
-
- genSinglePush();
- gcInfo.gcMarkRegSetNpt(regBit);
-
- regs &= ~regBit;
- }
-
- return pushedRegs;
-
-#endif // FEATURE_FIXED_OUT_ARGS
-}
-
-/*****************************************************************************
- *
- * Pop the registers pushed by genPushRegs()
- */
-
-void CodeGen::genPopRegs(regMaskTP regs, regMaskTP byrefRegs, regMaskTP noRefRegs)
-{
- if (regs == RBM_NONE)
- return;
-
-#if FEATURE_FIXED_OUT_ARGS
-
- NYI("Don't call genPopRegs with real regs!");
-
-#else // FEATURE_FIXED_OUT_ARGS
-
- noway_assert((regs & byrefRegs) == byrefRegs);
- noway_assert((regs & noRefRegs) == noRefRegs);
- // noway_assert((regs & regSet.rsRegMaskFree()) == regs); // Don't care. Caller is responsible for all this
- noway_assert((regs & (gcInfo.gcRegGCrefSetCur | gcInfo.gcRegByrefSetCur)) == RBM_NONE);
-
- noway_assert(genTypeStSz(TYP_REF) == genTypeStSz(TYP_INT));
- noway_assert(genTypeStSz(TYP_BYREF) == genTypeStSz(TYP_INT));
-
- // Walk the registers in the reverse order as genPushRegs()
- for (regNumber reg = REG_INT_LAST; regs != RBM_NONE; reg = REG_PREV(reg))
- {
- regMaskTP regBit = regMaskTP(1) << reg;
-
- if ((regBit & regs) == RBM_NONE)
- continue;
-
- var_types type;
- if (regBit & byrefRegs)
- {
- type = TYP_BYREF;
- }
- else if (regBit & noRefRegs)
- {
- type = TYP_INT;
- }
- else
- {
- type = TYP_REF;
- }
-
- inst_RV(INS_pop, reg, type);
- genSinglePop();
-
- if (type != TYP_INT)
- gcInfo.gcMarkRegPtrVal(reg, type);
-
- regs &= ~regBit;
- }
-
-#endif // FEATURE_FIXED_OUT_ARGS
-}
-
-/*****************************************************************************
- *
* Push the given argument list, right to left; returns the total amount of
* stuff pushed.
*/
@@ -18519,12 +18338,10 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
CORINFO_SIG_INFO* sigInfo = nullptr;
-#ifdef DEBUGGING_SUPPORT
if (compiler->opts.compDbgInfo && compiler->genCallSite2ILOffsetMap != NULL)
{
(void)compiler->genCallSite2ILOffsetMap->Lookup(call, &ilOffset);
}
-#endif
/* Make some sanity checks on the call node */
@@ -19600,6 +19417,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
regNumber indCallReg;
case IAT_VALUE:
+ {
//------------------------------------------------------
// Non-virtual direct calls to known addressess
//
@@ -19607,7 +19425,24 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
// it be nice if they all did!
CLANG_FORMAT_COMMENT_ANCHOR;
#ifdef _TARGET_ARM_
- if (!arm_Valid_Imm_For_BL((ssize_t)addr))
+ // We may use direct call for some of recursive calls
+ // as we can safely estimate the distance from the call site to the top of the method
+ const int codeOffset = MAX_PROLOG_SIZE_BYTES + // prolog size
+ getEmitter()->emitCurCodeOffset + // offset of the current IG
+ getEmitter()->emitCurIGsize + // size of the current IG
+ 4; // size of the jump instruction
+ // that we are now emitting
+ if (compiler->gtIsRecursiveCall(call->AsCall()) && codeOffset <= -CALL_DIST_MAX_NEG)
+ {
+ getEmitter()->emitIns_Call(emitter::EC_FUNC_TOKEN, methHnd,
+ INDEBUG_LDISASM_COMMA(sigInfo) NULL, // addr
+ args, retSize, gcInfo.gcVarPtrSetCur,
+ gcInfo.gcRegGCrefSetCur, gcInfo.gcRegByrefSetCur, ilOffset,
+ REG_NA, REG_NA, 0, 0, // ireg, xreg, xmul, disp
+ false, // isJump
+ emitter::emitNoGChelper(helperNum));
+ }
+ else if (!arm_Valid_Imm_For_BL((ssize_t)addr))
{
// Load the address into a register and call through a register
indCallReg = regSet.rsGrabReg(RBM_ALLINT); // Grab an available register to use for the
@@ -19634,7 +19469,8 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
false, /* isJump */
emitter::emitNoGChelper(helperNum));
}
- break;
+ }
+ break;
case IAT_PVALUE:
//------------------------------------------------------
@@ -20046,7 +19882,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
#if defined(_TARGET_X86_)
if (call->gtFlags & GTF_CALL_UNMANAGED)
{
- if ((compiler->opts.eeFlags & CORJIT_FLG_PINVOKE_RESTORE_ESP) ||
+ if (compiler->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PINVOKE_RESTORE_ESP) ||
compiler->compStressCompile(Compiler::STRESS_PINVOKE_RESTORE_ESP, 50))
{
// P/Invoke signature mismatch resilience - restore ESP to pre-call value. We would ideally
@@ -20756,9 +20592,11 @@ DONE:
}
#endif
- /* Write the lvaShadowSPfirst stack frame slot */
- noway_assert(compiler->lvaLocAllocSPvar != BAD_VAR_NUM);
- getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, REG_SPBASE, compiler->lvaLocAllocSPvar, 0);
+ /* Write the lvaLocAllocSPvar stack frame slot */
+ if (compiler->lvaLocAllocSPvar != BAD_VAR_NUM)
+ {
+ getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, REG_SPBASE, compiler->lvaLocAllocSPvar, 0);
+ }
#if STACK_PROBES
// Don't think it is worth it the codegen complexity to embed this
@@ -20783,98 +20621,6 @@ DONE:
return regCnt;
}
-/*****************************************************************************/
-#ifdef DEBUGGING_SUPPORT
-/*****************************************************************************
- * genSetScopeInfo
- *
- * Called for every scope info piece to record by the main genSetScopeInfo()
- */
-
-void CodeGen::genSetScopeInfo(unsigned which,
- UNATIVE_OFFSET startOffs,
- UNATIVE_OFFSET length,
- unsigned varNum,
- unsigned LVnum,
- bool avail,
- Compiler::siVarLoc& varLoc)
-{
- /* We need to do some mapping while reporting back these variables */
-
- unsigned ilVarNum = compiler->compMap2ILvarNum(varNum);
- noway_assert((int)ilVarNum != ICorDebugInfo::UNKNOWN_ILNUM);
-
-#ifdef _TARGET_X86_
- // Non-x86 platforms are allowed to access all arguments directly
- // so we don't need this code.
-
- // Is this a varargs function?
-
- if (compiler->info.compIsVarArgs && varNum != compiler->lvaVarargsHandleArg &&
- varNum < compiler->info.compArgsCount && !compiler->lvaTable[varNum].lvIsRegArg)
- {
- noway_assert(varLoc.vlType == Compiler::VLT_STK || varLoc.vlType == Compiler::VLT_STK2);
-
- // All stack arguments (except the varargs handle) have to be
- // accessed via the varargs cookie. Discard generated info,
- // and just find its position relative to the varargs handle
-
- PREFIX_ASSUME(compiler->lvaVarargsHandleArg < compiler->info.compArgsCount);
- if (!compiler->lvaTable[compiler->lvaVarargsHandleArg].lvOnFrame)
- {
- noway_assert(!compiler->opts.compDbgCode);
- return;
- }
-
- // Can't check compiler->lvaTable[varNum].lvOnFrame as we don't set it for
- // arguments of vararg functions to avoid reporting them to GC.
- noway_assert(!compiler->lvaTable[varNum].lvRegister);
- unsigned cookieOffset = compiler->lvaTable[compiler->lvaVarargsHandleArg].lvStkOffs;
- unsigned varOffset = compiler->lvaTable[varNum].lvStkOffs;
-
- noway_assert(cookieOffset < varOffset);
- unsigned offset = varOffset - cookieOffset;
- unsigned stkArgSize = compiler->compArgSize - intRegState.rsCalleeRegArgCount * sizeof(void*);
- noway_assert(offset < stkArgSize);
- offset = stkArgSize - offset;
-
- varLoc.vlType = Compiler::VLT_FIXED_VA;
- varLoc.vlFixedVarArg.vlfvOffset = offset;
- }
-
-#endif // _TARGET_X86_
-
- VarName name = NULL;
-
-#ifdef DEBUG
-
- for (unsigned scopeNum = 0; scopeNum < compiler->info.compVarScopesCount; scopeNum++)
- {
- if (LVnum == compiler->info.compVarScopes[scopeNum].vsdLVnum)
- {
- name = compiler->info.compVarScopes[scopeNum].vsdName;
- }
- }
-
- // Hang on to this compiler->info.
-
- TrnslLocalVarInfo& tlvi = genTrnslLocalVarInfo[which];
-
- tlvi.tlviVarNum = ilVarNum;
- tlvi.tlviLVnum = LVnum;
- tlvi.tlviName = name;
- tlvi.tlviStartPC = startOffs;
- tlvi.tlviLength = length;
- tlvi.tlviAvailable = avail;
- tlvi.tlviVarLoc = varLoc;
-
-#endif // DEBUG
-
- compiler->eeSetLVinfo(which, startOffs, length, ilVarNum, LVnum, name, avail, varLoc);
-}
-
-#endif // DEBUGGING_SUPPORT
-
/*****************************************************************************
*
* Return non-zero if the given register is free after the given tree is