예제 #1
0
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
}
예제 #2
0
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
}
예제 #3
0
파일: scopeinfo.cpp 프로젝트: ROOTU/coreclr
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
}
예제 #4
0
파일: scopeinfo.cpp 프로젝트: ROOTU/coreclr
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
}
예제 #5
0
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);
        }
    }
}