diff options
author | Jiyoung Yun <jy910.yun@samsung.com> | 2016-12-27 16:46:08 +0900 |
---|---|---|
committer | Jiyoung Yun <jy910.yun@samsung.com> | 2016-12-27 16:46:08 +0900 |
commit | db20f3f1bb8595633a7e16c8900fd401a453a6b5 (patch) | |
tree | e5435159cd1bf0519276363a6fe1663d1721bed3 /src/jit/codegenlegacy.cpp | |
parent | 4b4aad7217d3292650e77eec2cf4c198ea9c3b4b (diff) | |
download | coreclr-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.cpp | 448 |
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 |