void CodeGen::psiMoveESPtoEBP() { assert(compiler->compGeneratingProlog); assert(doubleAlignOrFramePointerUsed()); #ifdef ACCURATE_PROLOG_DEBUG_INFO psiScope * scope; // walk the list backwards // Works as psiEndPrologScope does not change scPrev for (scope = psiOpenScopeLast; scope != &psiOpenScopeList; scope = scope->scPrev) { if (scope->scRegister) { assert(compiler->lvaTable[scope->scSlotNum].lvIsRegArg); continue; } assert(scope->u2.scBaseReg == REG_SPBASE); psiScope * newScope = psiNewPrologScope(scope->scLVnum, scope->scSlotNum); newScope->scRegister = false; newScope->u2.scBaseReg = REG_FPBASE; newScope->u2.scOffset = scope->u2.scOffset; psiEndPrologScope (scope); } #endif // ACCURATE_PROLOG_DEBUG_INFO }
void CodeGen::psiAdjustStackLevel(unsigned size) { assert(compiler->compGeneratingProlog); #ifdef ACCURATE_PROLOG_DEBUG_INFO psiScope * scope; // walk the list backwards // Works as psiEndPrologScope does not change scPrev for (scope = psiOpenScopeLast; scope != &psiOpenScopeList; scope = scope->scPrev) { if (scope->scRegister) { assert(compiler->lvaTable[scope->scSlotNum].lvIsRegArg); continue; } assert(scope->u2.scBaseReg == REG_SPBASE); psiScope * newScope = psiNewPrologScope(scope->scLVnum, scope->scSlotNum); newScope->scRegister = false; newScope->u2.scBaseReg = REG_SPBASE; newScope->u2.scOffset = scope->u2.scOffset + size; psiEndPrologScope (scope); } #endif // ACCURATE_PROLOG_DEBUG_INFO }
void CodeGen::psiMoveToReg(unsigned varNum, regNumber reg, regNumber otherReg) { assert(compiler->compGeneratingProlog); if (!compiler->opts.compScopeInfo) { return; } if (compiler->info.compVarScopesCount == 0) { return; } assert((int)varNum >= 0); // It's not a spill temp number. assert(compiler->lvaTable[varNum].lvIsInReg()); #ifdef ACCURATE_PROLOG_DEBUG_INFO /* If reg!=REG_NA, the parameter is part of a cirular dependancy, and is * being moved through temp register "reg". * If reg==REG_NA, it is being moved to its assigned register. */ if (reg == REG_NA) { // Grab the assigned registers. reg = compiler->lvaTable[varNum].lvRegNum; otherReg = compiler->lvaTable[varNum].lvOtherReg; } psiScope* scope; // walk the list backwards // Works as psiEndPrologScope does not change scPrev for (scope = psiOpenScopeLast; scope != &psiOpenScopeList; scope = scope->scPrev) { if (scope->scSlotNum != compiler->lvaTable[varNum].lvSlotNum) continue; psiScope* newScope = psiNewPrologScope(scope->scLVnum, scope->scSlotNum); newScope->scRegister = true; newScope->u1.scRegNum = reg; newScope->u1.scOtherReg = otherReg; psiEndPrologScope(scope); return; } // May happen if a parameter does not have an entry in the LocalVarTab // But assert() just in case it is because of something else. assert(varNum == compiler->info.compRetBuffArg || !"Parameter scope not found (Assert doesnt always indicate error)"); #endif // ACCURATE_PROLOG_DEBUG_INFO }
void CodeGen::psiMoveToStack(unsigned varNum) { if (!compiler->opts.compScopeInfo || (compiler->info.compVarScopesCount == 0)) { return; } assert(compiler->compGeneratingProlog); assert(compiler->lvaTable[varNum].lvIsRegArg); assert(!compiler->lvaTable[varNum].lvRegister); #ifdef ACCURATE_PROLOG_DEBUG_INFO psiScope* scope; // walk the list backwards // Works as psiEndPrologScope does not change scPrev for (scope = psiOpenScopeLast; scope != &psiOpenScopeList; scope = scope->scPrev) { if (scope->scSlotNum != compiler->lvaTable[varNum].lvSlotNum) continue; /* The param must be currently sitting in the register in which it was passed in */ assert(scope->scRegister); assert(scope->u1.scRegNum == compiler->lvaTable[varNum].lvArgReg); psiScope* newScope = psiNewPrologScope(scope->scLVnum, scope->scSlotNum); newScope->scRegister = false; newScope->u2.scBaseReg = (compiler->lvaTable[varNum].lvFramePointerBased) ? REG_FPBASE : REG_SPBASE; newScope->u2.scOffset = compiler->lvaTable[varNum].lvStkOffs; psiEndPrologScope(scope); return; } // May happen if a parameter does not have an entry in the LocalVarTab // But assert() just in case it is because of something else. assert(varNum == compiler->info.compRetBuffArg || !"Parameter scope not found (Assert doesnt always indicate error)"); #endif // ACCURATE_PROLOG_DEBUG_INFO }
void CodeGen::psiBegProlog() { assert(compiler->compGeneratingProlog); VarScopeDsc* varScope; psiOpenScopeList.scNext = NULL; psiOpenScopeLast = &psiOpenScopeList; psiScopeLast = &psiScopeList; psiScopeCnt = 0; compiler->compResetScopeLists(); while ((varScope = compiler->compGetNextEnterScope(0)) != NULL) { LclVarDsc * lclVarDsc1 = &compiler->lvaTable[varScope->vsdVarNum]; if (!lclVarDsc1->lvIsParam) continue; psiScope * newScope = psiNewPrologScope(varScope->vsdLVnum, varScope->vsdVarNum); if (lclVarDsc1->lvIsRegArg) { bool isStructHandled = false; #if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING) SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR structDesc; if (lclVarDsc1->TypeGet() == TYP_STRUCT) { CORINFO_CLASS_HANDLE typeHnd = lclVarDsc1->lvVerTypeInfo.GetClassHandle(); assert(typeHnd != nullptr); compiler->eeGetSystemVAmd64PassStructInRegisterDescriptor(typeHnd, &structDesc); if (structDesc.passedInRegisters) { regNumber regNum = REG_NA; regNumber otherRegNum = REG_NA; for (unsigned nCnt = 0; nCnt < structDesc.eightByteCount; nCnt++) { unsigned len = structDesc.eightByteSizes[nCnt]; var_types regType = TYP_UNDEF; if (nCnt == 0) { regNum = lclVarDsc1->lvArgReg; } else if (nCnt == 1) { otherRegNum = lclVarDsc1->lvOtherArgReg; } else { assert(false && "Invalid eightbyte number."); } regType = compiler->getEightByteType(structDesc, nCnt); #ifdef DEBUG regType = compiler->mangleVarArgsType(regType); assert(genMapRegNumToRegArgNum((nCnt == 0 ? regNum : otherRegNum), regType) != (unsigned)-1); #endif // DEBUG } newScope->scRegister = true; newScope->u1.scRegNum = (regNumberSmall)regNum; newScope->u1.scOtherReg = (regNumberSmall)otherRegNum; } else { // Stack passed argument. Get the offset from the caller's frame. psSetScopeOffset(newScope, lclVarDsc1); } isStructHandled = true; } #endif // !defined(FEATURE_UNIX_AMD64_STRUCT_PASSING) if (!isStructHandled) { #ifdef DEBUG var_types regType = compiler->mangleVarArgsType(lclVarDsc1->TypeGet()); #ifdef _TARGET_ARM_ if (lclVarDsc1->lvIsHfaRegArg) { regType = lclVarDsc1->GetHfaType(); } #endif // _TARGET_ARM_ assert(genMapRegNumToRegArgNum(lclVarDsc1->lvArgReg, regType) != (unsigned)-1); #endif // DEBUG newScope->scRegister = true; newScope->u1.scRegNum = (regNumberSmall)lclVarDsc1->lvArgReg; } } else { psSetScopeOffset(newScope, lclVarDsc1); } } }