VirtualBox

Changeset 108234 in vbox


Ignore:
Timestamp:
Feb 16, 2025 2:20:28 PM (2 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
167555
Message:

Runtime/RTAcpi*: Implement constant folding for ShiftLeft (used by vbox.dsl), bugref:10733

Location:
trunk/src/VBox/Runtime
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/acpi/acpi-ast.cpp

    r108230 r108234  
    9292
    9393
    94 DECLHIDDEN(int) rtAcpiAstNodeTransform(PRTACPIASTNODE pAstNd, PRTERRINFO pErrInfo)
    95 {
    96 #if 0
    97     /* Walk all arguments containing AST nodes first. */
    98     for (uint8_t i = 0; i < pAstNd->cArgs; i++)
    99     {
    100         if (   pAstNd->aArgs[i].enmType == kAcpiAstArgType_AstNode
    101             && pAstNd->aArgs[i].u.pAstNd)
    102         {
    103             int rc = rtAcpiAstNodeTransform(pAstNd->aArgs[i].u.pAstNd, pErrInfo);
    104             if (RT_FAILURE(rc))
    105                 return rc;
    106         }
    107     }
    108 
    109     if (pAstNd->fFlags & RTACPI_AST_NODE_F_NEW_SCOPE)
    110     {
    111         PRTACPIASTNODE pIt/*, pItPrev*/;
    112         /* Do transformations on the nodes first. */
    113         RTListForEach(&pAstNd->LstScopeNodes, pIt, RTACPIASTNODE, NdAst)
    114         {
    115             int rc = rtAcpiAstNodeTransform(pIt, pErrInfo);
    116             if (RT_FAILURE(rc))
    117                 return rc;
    118         }
    119 
    120         /* Now do transformations on our level. */
    121         RTListForEachReverseSafe(&pAstNd->LstScopeNodes, pIt, pItPrev, RTACPIASTNODE, NdAst)
    122         {
    123             /*
    124              * If there is an If AST node followed by Else we move the Else branch as the last
    125              * statement in the If because when emitting to AML the Else is enclosed in the If
    126              * package.
    127              */
    128             if (   pIt->enmOp == kAcpiAstNodeOp_Else
    129                 && pItPrev
    130                 && pItPrev->enmOp == kAcpiAstNodeOp_If)
    131             {
    132                 RTListNodeRemove(&pIt->NdAst);
    133                 RTListAppend(&pItPrev->LstScopeNodes, &pIt->NdAst);
    134             }
    135         }
    136     }
    137 #else
    138     RT_NOREF(pAstNd, pErrInfo);
    139 #endif
    140 
    141     return VINF_SUCCESS;
    142 }
    143 
    144 
    14594/**
    14695 * Evaluates the given AST node to an integer if possible.
    14796 *
    14897 * @returns IPRT status code.
    149  * @param   pAstNd          The AST node to evaluate.
    150  * @param   pNsRoot         The namespace root this AST belongs to.
    151  * @param   pu64            Where to store the integer on success.
     98 * @param   pAstNd                  The AST node to evaluate.
     99 * @param   pNsRoot                 The namespace root this AST belongs to.
     100 * @param   fResolveIdentifiers     Flag whether to try resolving identifiers to constant integers.
     101 * @param   pu64                    Where to store the integer on success.
    152102 */
    153 static int rtAcpiAstNodeEvaluateToInteger(PCRTACPIASTNODE pAstNd, PRTACPINSROOT pNsRoot, uint64_t *pu64)
     103static int rtAcpiAstNodeEvaluateToInteger(PCRTACPIASTNODE pAstNd, PRTACPINSROOT pNsRoot, bool fResolveIdentifiers, uint64_t *pu64)
    154104{
    155105    /* Easy way out?. */
     
    172122    }
    173123
    174     if (pAstNd->enmOp == kAcpiAstNodeOp_Identifier)
     124    if (   pAstNd->enmOp == kAcpiAstNodeOp_Identifier
     125        && fResolveIdentifiers)
    175126    {
    176127        /* Look it up in the namespace and use the result. */
     
    178129        if (!pNsEntry)
    179130            return VERR_NOT_FOUND;
    180 
    181         *pu64 = pNsEntry->offBits;
     131        if (pNsEntry->enmType != kAcpiNsEntryType_ResourceField)
     132            return VERR_NOT_SUPPORTED;
     133
     134        *pu64 = pNsEntry->RsrcFld.offBits;
    182135        return VINF_SUCCESS;
    183136    }
     
    185138    /** @todo */
    186139    return VERR_NOT_IMPLEMENTED;
     140}
     141
     142
     143DECLHIDDEN(int) rtAcpiAstNodeTransform(PRTACPIASTNODE pAstNd, PRTACPINSROOT pNsRoot, PRTERRINFO pErrInfo)
     144{
     145    /* Walk all arguments containing AST nodes first. */
     146    for (uint8_t i = 0; i < pAstNd->cArgs; i++)
     147    {
     148        if (   pAstNd->aArgs[i].enmType == kAcpiAstArgType_AstNode
     149            && pAstNd->aArgs[i].u.pAstNd)
     150        {
     151            int rc = rtAcpiAstNodeTransform(pAstNd->aArgs[i].u.pAstNd, pNsRoot, pErrInfo);
     152            if (RT_FAILURE(rc))
     153                return rc;
     154        }
     155    }
     156
     157    if (pAstNd->fFlags & RTACPI_AST_NODE_F_NEW_SCOPE)
     158    {
     159        PRTACPIASTNODE pIt/*, pItPrev*/;
     160        /* Do transformations on the nodes first. */
     161        RTListForEach(&pAstNd->LstScopeNodes, pIt, RTACPIASTNODE, NdAst)
     162        {
     163            int rc = rtAcpiAstNodeTransform(pIt, pNsRoot, pErrInfo);
     164            if (RT_FAILURE(rc))
     165                return rc;
     166        }
     167    }
     168
     169    /* Now do optimizations we can do here. */
     170    switch (pAstNd->enmOp)
     171    {
     172        case kAcpiAstNodeOp_ShiftLeft:
     173        {
     174            /*
     175             * If both arguments evaluate to constant integers we can convert this
     176             * to the final result.
     177             */
     178            /** @todo Skips the 3 operand variant (no target), check what iasl is doing here. */
     179            if (!pAstNd->aArgs[2].u.pAstNd)
     180            {
     181                uint64_t u64ValToShift = 0;
     182                uint64_t u64ValShift = 0;
     183                int rc = rtAcpiAstNodeEvaluateToInteger(pAstNd->aArgs[0].u.pAstNd, pNsRoot, false /*fResolveIdentifiers*/, &u64ValToShift);
     184                if (RT_SUCCESS(rc))
     185                    rc = rtAcpiAstNodeEvaluateToInteger(pAstNd->aArgs[1].u.pAstNd, pNsRoot, false /*fResolveIdentifiers*/, &u64ValShift);
     186                if (   RT_SUCCESS(rc)
     187                    && u64ValShift <= 63)
     188                {
     189                    /** @todo Check overflow handling. */
     190                    rtAcpiAstNodeFree(pAstNd->aArgs[0].u.pAstNd);
     191                    rtAcpiAstNodeFree(pAstNd->aArgs[1].u.pAstNd);
     192
     193                    pAstNd->aArgs[0].u.pAstNd = NULL;
     194                    pAstNd->aArgs[1].u.pAstNd = NULL;
     195                    pAstNd->cArgs             = 0;
     196                    pAstNd->enmOp             = kAcpiAstNodeOp_Number;
     197                    pAstNd->u64               = u64ValToShift << u64ValShift;
     198                }
     199            }
     200            break;
     201        }
     202        default:
     203            break;
     204    }
     205
     206    return VINF_SUCCESS;
    187207}
    188208
     
    548568            {
    549569                /* Try resolving to a constant expression. */
    550                 rc = rtAcpiAstNodeEvaluateToInteger(pAstNd->aArgs[0].u.pAstNd, pNsRoot, &cElems);
     570                rc = rtAcpiAstNodeEvaluateToInteger(pAstNd->aArgs[0].u.pAstNd, pNsRoot, true /*fResolveIdentifiers*/, &cElems);
    551571                if (RT_FAILURE(rc))
    552572                    break;
     
    615635                        /* Try resolving to a constant expression. */
    616636                        uint64_t u64 = 0;
    617                         rc = rtAcpiAstNodeEvaluateToInteger(pIt, pNsRoot, &u64);
     637                        rc = rtAcpiAstNodeEvaluateToInteger(pIt, pNsRoot, true /*fResolveIdentifiers*/, &u64);
    618638                        if (RT_FAILURE(rc))
    619639                            break;
     
    832852                else
    833853                {
    834                     rc = rtAcpiAstNodeEvaluateToInteger(pAstNd->aArgs[1].u.pAstNd, pNsRoot, &off);
     854                    rc = rtAcpiAstNodeEvaluateToInteger(pAstNd->aArgs[1].u.pAstNd, pNsRoot, true /*fResolveIdentifiers*/, &off);
    835855                    off = pAstNd->enmOp == kAcpiAstNodeOp_CreateBitField ? off : off / 8;
    836856                }
  • trunk/src/VBox/Runtime/common/acpi/acpi-compiler.cpp

    r108230 r108234  
    29892989                {
    29902990                    /* 2. - Optimize AST (constant folding, etc). */
     2991                    PRTACPIASTNODE pIt;
     2992                    RTListForEach(&pThis->LstStmts, pIt, RTACPIASTNODE, NdAst)
     2993                    {
     2994                        rc = rtAcpiAstNodeTransform(pIt, pThis->pNs, pErrInfo);
     2995                        if (RT_FAILURE(rc))
     2996                            break;
     2997                    }
    29912998
    29922999                    /* 3. - Traverse AST and output table. */
     
    30123019                    if (RT_SUCCESS(rc))
    30133020                    {
    3014                         PRTACPIASTNODE pIt;
     3021                        pIt;
    30153022                        RTListForEach(&pThis->LstStmts, pIt, RTACPIASTNODE, NdAst)
    30163023                        {
    3017                             rc = rtAcpiAstNodeTransform(pIt, pErrInfo);
    3018                             if (RT_FAILURE(rc))
    3019                                 break;
    3020 
    30213024                            rc = rtAcpiAstDumpToTbl(pIt, pThis->pNs, pThis->hAcpiTbl);
    30223025                            if (RT_FAILURE(rc))
  • trunk/src/VBox/Runtime/common/acpi/acpi-ns.cpp

    r108230 r108234  
    231231 * @returns IPRT status code.
    232232 * @param   pNsRoot             The namespace to add the new entry to.
     233 * @param   enmType             The type of the namespace entry.
    233234 * @param   pszNameString       The namestring to add.
    234235 * @param   fSwitchTo           Flag whether to switch to the new entry.
     
    236237 * @param   ppNsEntry           Where to store the pointer to the created entry on success.
    237238 */
    238 static int rtAcpiNsAddEntryWorker(PRTACPINSROOT pNsRoot, const char *pszNameString, bool fSwitchTo, bool fIgnoreExisting, PRTACPINSENTRY *ppNsEntry)
     239static int rtAcpiNsAddEntryWorker(PRTACPINSROOT pNsRoot, RTACPINSENTRYTYPE enmType, const char *pszNameString, bool fSwitchTo, bool fIgnoreExisting, PRTACPINSENTRY *ppNsEntry)
    239240{
    240241    AssertReturn(   !fSwitchTo
     
    263264        if (pNsEntry)
    264265        {
     266            pNsEntry->enmType = enmType;
    265267            pNsEntry->pParent = pNsEntryParent;
    266268            RTListInit(&pNsEntry->LstNsEntries);
     
    340342{
    341343    PRTACPINSENTRY pNsEntry = NULL;
    342     int rc = rtAcpiNsAddEntryWorker(pNsRoot, pszNameString, fSwitchTo, false /*fIgnoreExisting*/, &pNsEntry);
     344    int rc = rtAcpiNsAddEntryWorker(pNsRoot, kAcpiNsEntryType_AstNode, pszNameString, fSwitchTo, false /*fIgnoreExisting*/, &pNsEntry);
    343345    if (rc == VERR_ALREADY_EXISTS)
    344346        rc = VINF_SUCCESS;
    345347    if (RT_SUCCESS(rc))
    346     {
    347         pNsEntry->fAstNd = true;
    348348        pNsEntry->pAstNd = pAstNd;
    349     }
    350349
    351350    return rc;
     
    356355{
    357356    PRTACPINSENTRY pNsEntry = NULL;
    358     int rc = rtAcpiNsAddEntryWorker(pNsRoot, pszNameString, false /*fSwitchTo*/, true /*fIgnoreExisting*/, &pNsEntry);
     357    int rc = rtAcpiNsAddEntryWorker(pNsRoot, kAcpiNsEntryType_ResourceField, pszNameString, false /*fSwitchTo*/, true /*fIgnoreExisting*/, &pNsEntry);
    359358    if (RT_SUCCESS(rc))
    360359    {
    361         pNsEntry->fAstNd  = false;
    362         pNsEntry->pAstNd  = NULL;
    363         pNsEntry->offBits = offBits;
    364         pNsEntry->cBits   = cBits;
     360        pNsEntry->RsrcFld.offBits = offBits;
     361        pNsEntry->RsrcFld.cBits   = cBits;
    365362    }
    366363
     
    372369{
    373370    PRTACPINSENTRY pNsEntry = NULL;
    374     int rc = rtAcpiNsAddEntryWorker(pNsRoot, pszNameString, false /*fSwitchTo*/, false /*fIgnoreExisting*/, &pNsEntry);
     371    int rc = rtAcpiNsAddEntryWorker(pNsRoot, kAcpiNsEntryType_External, pszNameString, false /*fSwitchTo*/, false /*fIgnoreExisting*/, &pNsEntry);
    375372    if (RT_SUCCESS(rc))
    376     {
    377         pNsEntry->fAstNd    = false;
    378373        pNsEntry->pExternal = pExternal;
    379     }
    380374
    381375    return rc;
  • trunk/src/VBox/Runtime/include/internal/acpi.h

    r108230 r108234  
    7979
    8080/**
     81 * ACPI namespace entry type.
     82 */
     83typedef enum RTACPINSENTRYTYPE
     84{
     85    /** Invalid type. */
     86    kAcpiNsEntryType_Invalid = 0,
     87    /** Namespace entry points to an AST node. */
     88    kAcpiNsEntryType_AstNode,
     89    /** Namesapce entry points to an external declaration. */
     90    kAcpiNsEntryType_External,
     91    /** Namespace entry is a resource field containing an offset and number of bits. */
     92    kAcpiNsEntryType_ResourceField,
     93    /** 32bit hack. */
     94    kAcpiNsEntryType_32Bit_Hack = 0x7fffffff
     95} RTACPINSENTRYTYPE;
     96
     97
     98/**
    8199 * An ACPI namespace entry.
    82100 */
     
    89107    /** The name segment identifying the entry. */
    90108    char                    achNameSeg[4];
    91     /** Flag whether this points to an AST node or an external. */
    92     bool                    fAstNd;
     109    /** Namespace entry type.. */
     110    RTACPINSENTRYTYPE       enmType;
    93111    /** Type dependent data. */
    94112    union
     
    98116        /** Pointer to the external declaration. */
    99117        PCRTACPIASLEXTERNAL pExternal;
     118        /** Resource field data. */
     119        struct
     120        {
     121                /** Bit offset for resource fields. */
     122                uint32_t    offBits;
     123                /** Bit count for resource fields. */
     124                uint32_t    cBits;
     125        } RsrcFld;
    100126    };
    101     /** Bit offset for resource fields. */
    102     uint32_t                offBits;
    103     /** Bit count for resource fields. */
    104     uint32_t                cBits;
    105127    /** List of namespace entries below this entry. */
    106128    RTLISTANCHOR            LstNsEntries;
     
    347369 * @returns IPRT status.
    348370 * @param   pAstNd              The AST node to transform.
     371 * @param   pNsRoot             The namespace root.
    349372 * @param   pErrInfo            Some additional error information on failure.
    350  *
    351  * @note This currently only implements merging if ... else ... nodes but can be extended to
    352  *       also do some optimizations and proper checking.
    353  */
    354 DECLHIDDEN(int) rtAcpiAstNodeTransform(PRTACPIASTNODE pAstNd, PRTERRINFO pErrInfo);
     373 */
     374DECLHIDDEN(int) rtAcpiAstNodeTransform(PRTACPIASTNODE pAstNd, PRTACPINSROOT pNsRoot, PRTERRINFO pErrInfo);
    355375
    356376
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette