Home | History | Annotate | Line # | Download | only in compiler
aslfold.c revision 1.1.1.6
      1 /******************************************************************************
      2  *
      3  * Module Name: aslfold - Constant folding
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2015, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #include "aslcompiler.h"
     45 #include "aslcompiler.y.h"
     46 #include "amlcode.h"
     47 
     48 #include "acdispat.h"
     49 #include "acparser.h"
     50 
     51 #define _COMPONENT          ACPI_COMPILER
     52         ACPI_MODULE_NAME    ("aslfold")
     53 
     54 /* Local prototypes */
     55 
     56 static ACPI_STATUS
     57 OpcAmlEvaluationWalk1 (
     58     ACPI_PARSE_OBJECT       *Op,
     59     UINT32                  Level,
     60     void                    *Context);
     61 
     62 static ACPI_STATUS
     63 OpcAmlEvaluationWalk2 (
     64     ACPI_PARSE_OBJECT       *Op,
     65     UINT32                  Level,
     66     void                    *Context);
     67 
     68 static ACPI_STATUS
     69 OpcAmlCheckForConstant (
     70     ACPI_PARSE_OBJECT       *Op,
     71     UINT32                  Level,
     72     void                    *Context);
     73 
     74 static void
     75 OpcUpdateIntegerNode (
     76     ACPI_PARSE_OBJECT       *Op,
     77     UINT64                  Value);
     78 
     79 static ACPI_STATUS
     80 TrTransformToStoreOp (
     81     ACPI_PARSE_OBJECT       *Op,
     82     ACPI_WALK_STATE         *WalkState);
     83 
     84 static ACPI_STATUS
     85 TrSimpleConstantReduction (
     86     ACPI_PARSE_OBJECT       *Op,
     87     ACPI_WALK_STATE         *WalkState);
     88 
     89 static void
     90 TrInstallReducedConstant (
     91     ACPI_PARSE_OBJECT       *Op,
     92     ACPI_OPERAND_OBJECT     *ObjDesc);
     93 
     94 
     95 /*******************************************************************************
     96  *
     97  * FUNCTION:    OpcAmlConstantWalk
     98  *
     99  * PARAMETERS:  ASL_WALK_CALLBACK
    100  *
    101  * RETURN:      Status
    102  *
    103  * DESCRIPTION: Reduce an Op and its subtree to a constant if possible
    104  *
    105  ******************************************************************************/
    106 
    107 ACPI_STATUS
    108 OpcAmlConstantWalk (
    109     ACPI_PARSE_OBJECT       *Op,
    110     UINT32                  Level,
    111     void                    *Context)
    112 {
    113     ACPI_WALK_STATE         *WalkState;
    114     ACPI_STATUS             Status = AE_OK;
    115 
    116 
    117     if (Op->Asl.CompileFlags == 0)
    118     {
    119         return (AE_OK);
    120     }
    121 
    122     /*
    123      * Only interested in subtrees that could possibly contain
    124      * expressions that can be evaluated at this time
    125      */
    126     if ((!(Op->Asl.CompileFlags & NODE_COMPILE_TIME_CONST)) ||
    127           (Op->Asl.CompileFlags & NODE_IS_TARGET))
    128     {
    129         return (AE_OK);
    130     }
    131 
    132     /* Create a new walk state */
    133 
    134     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
    135     if (!WalkState)
    136     {
    137         return (AE_NO_MEMORY);
    138     }
    139 
    140     WalkState->NextOp = NULL;
    141     WalkState->Params = NULL;
    142 
    143     /*
    144      * Examine the entire subtree -- all nodes must be constants
    145      * or type 3/4/5 opcodes
    146      */
    147     Status = TrWalkParseTree (Op, ASL_WALK_VISIT_DOWNWARD,
    148         OpcAmlCheckForConstant, NULL, WalkState);
    149 
    150     /*
    151      * Did we find an entire subtree that contains all constants
    152      * and type 3/4/5 opcodes?
    153      */
    154     switch (Status)
    155     {
    156     case AE_OK:
    157 
    158         /* Simple case, like Add(3,4) -> 7 */
    159 
    160         Status = TrSimpleConstantReduction (Op, WalkState);
    161         break;
    162 
    163     case AE_CTRL_RETURN_VALUE:
    164 
    165         /* More complex case, like Add(3,4,Local0) -> Store(7,Local0) */
    166 
    167         Status = TrTransformToStoreOp (Op, WalkState);
    168         break;
    169 
    170     case AE_TYPE:
    171 
    172         AcpiDsDeleteWalkState (WalkState);
    173         return (AE_OK);
    174 
    175     default:
    176         AcpiDsDeleteWalkState (WalkState);
    177         break;
    178     }
    179 
    180     if (ACPI_FAILURE (Status))
    181     {
    182         DbgPrint (ASL_PARSE_OUTPUT, "Cannot resolve, %s\n",
    183             AcpiFormatException (Status));
    184 
    185         /* We could not resolve the subtree for some reason */
    186 
    187         AslError (ASL_ERROR, ASL_MSG_CONSTANT_EVALUATION, Op,
    188             (char *) AcpiFormatException (Status));
    189 
    190         /* Set the subtree value to ZERO anyway. Eliminates further errors */
    191 
    192         OpcUpdateIntegerNode (Op, 0);
    193     }
    194 
    195     /* Abort the walk of this subtree, we are done with it */
    196 
    197     return (AE_CTRL_DEPTH);
    198 }
    199 
    200 
    201 /*******************************************************************************
    202  *
    203  * FUNCTION:    OpcAmlCheckForConstant
    204  *
    205  * PARAMETERS:  ASL_WALK_CALLBACK
    206  *
    207  * RETURN:      Status
    208  *
    209  * DESCRIPTION: Check one Op for a type 3/4/5 AML opcode
    210  *
    211  ******************************************************************************/
    212 
    213 static ACPI_STATUS
    214 OpcAmlCheckForConstant (
    215     ACPI_PARSE_OBJECT       *Op,
    216     UINT32                  Level,
    217     void                    *Context)
    218 {
    219     ACPI_WALK_STATE         *WalkState = Context;
    220     ACPI_STATUS             Status = AE_OK;
    221 
    222 
    223     WalkState->Op = Op;
    224     WalkState->Opcode = Op->Common.AmlOpcode;
    225     WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
    226 
    227     DbgPrint (ASL_PARSE_OUTPUT, "[%.4d] Opcode: %12.12s ",
    228         Op->Asl.LogicalLineNumber, Op->Asl.ParseOpName);
    229 
    230     /*
    231      * TBD: Ignore buffer constants for now. The problem is that these
    232      * constants have been transformed into RAW_DATA at this point, from
    233      * the parse tree transform process which currently happens before
    234      * the constant folding process. We may need to defer this transform
    235      * for buffer until after the constant folding.
    236      */
    237     if (WalkState->Opcode == AML_BUFFER_OP)
    238     {
    239         DbgPrint (ASL_PARSE_OUTPUT,
    240             "\nBuffer+Buffer->Buffer constant reduction is not supported yet");
    241         Status = AE_TYPE;
    242         goto CleanupAndExit;
    243     }
    244 
    245     /*
    246      * These opcodes do not appear in the OpcodeInfo table, but
    247      * they represent constants, so abort the constant walk now.
    248      */
    249     if ((WalkState->Opcode == AML_RAW_DATA_BYTE) ||
    250         (WalkState->Opcode == AML_RAW_DATA_WORD) ||
    251         (WalkState->Opcode == AML_RAW_DATA_DWORD) ||
    252         (WalkState->Opcode == AML_RAW_DATA_QWORD))
    253     {
    254         DbgPrint (ASL_PARSE_OUTPUT, "RAW DATA");
    255         Status = AE_TYPE;
    256         goto CleanupAndExit;
    257     }
    258 
    259     /* Type 3/4/5 opcodes have the AML_CONSTANT flag set */
    260 
    261     if (!(WalkState->OpInfo->Flags & AML_CONSTANT))
    262     {
    263         /* Not 3/4/5 opcode, but maybe can convert to STORE */
    264 
    265         if (Op->Asl.CompileFlags & NODE_IS_TARGET)
    266         {
    267             DbgPrint (ASL_PARSE_OUTPUT,
    268                 "**** Valid Target, transform to Store ****\n");
    269             return (AE_CTRL_RETURN_VALUE);
    270         }
    271 
    272         /* Expression cannot be reduced */
    273 
    274         DbgPrint (ASL_PARSE_OUTPUT,
    275             "**** Not a Type 3/4/5 opcode (%s) ****",
    276              Op->Asl.ParseOpName);
    277 
    278         Status = AE_TYPE;
    279         goto CleanupAndExit;
    280     }
    281 
    282     /* Debug output */
    283 
    284     DbgPrint (ASL_PARSE_OUTPUT, "TYPE_345");
    285 
    286     if (Op->Asl.CompileFlags & NODE_IS_TARGET)
    287     {
    288         if (Op->Asl.ParseOpcode == PARSEOP_ZERO)
    289         {
    290             DbgPrint (ASL_PARSE_OUTPUT, "%-16s", " NULL TARGET");
    291         }
    292         else
    293         {
    294             DbgPrint (ASL_PARSE_OUTPUT, "%-16s", " VALID TARGET");
    295         }
    296     }
    297     if (Op->Asl.CompileFlags & NODE_IS_TERM_ARG)
    298     {
    299         DbgPrint (ASL_PARSE_OUTPUT, "%-16s", " TERMARG");
    300     }
    301 
    302 CleanupAndExit:
    303 
    304     /* Dump the node compile flags also */
    305 
    306     TrPrintNodeCompileFlags (Op->Asl.CompileFlags);
    307     DbgPrint (ASL_PARSE_OUTPUT, "\n");
    308     return (Status);
    309 }
    310 
    311 
    312 /*******************************************************************************
    313  *
    314  * FUNCTION:    TrSimpleConstantReduction
    315  *
    316  * PARAMETERS:  Op                  - Parent operator to be transformed
    317  *              WalkState           - Current walk state
    318  *
    319  * RETURN:      Status
    320  *
    321  * DESCRIPTION: Reduce an entire AML operation to a single constant. The
    322  *              operation must not have a target operand.
    323  *
    324  *              Add (32,64) --> 96
    325  *
    326  ******************************************************************************/
    327 
    328 static ACPI_STATUS
    329 TrSimpleConstantReduction (
    330     ACPI_PARSE_OBJECT       *Op,
    331     ACPI_WALK_STATE         *WalkState)
    332 {
    333     ACPI_PARSE_OBJECT       *RootOp;
    334     ACPI_PARSE_OBJECT       *OriginalParentOp;
    335     ACPI_OPERAND_OBJECT     *ObjDesc;
    336     ACPI_STATUS             Status;
    337 
    338 
    339     DbgPrint (ASL_PARSE_OUTPUT,
    340         "Simple subtree constant reduction, operator to constant\n");
    341 
    342     /* Allocate a new temporary root for this subtree */
    343 
    344     RootOp = TrAllocateNode (PARSEOP_INTEGER);
    345     if (!RootOp)
    346     {
    347         return (AE_NO_MEMORY);
    348     }
    349 
    350     RootOp->Common.AmlOpcode = AML_INT_EVAL_SUBTREE_OP;
    351 
    352     OriginalParentOp = Op->Common.Parent;
    353     Op->Common.Parent = RootOp;
    354 
    355     /* Hand off the subtree to the AML interpreter */
    356 
    357     WalkState->CallerReturnDesc = &ObjDesc;
    358 
    359     Status = TrWalkParseTree (Op, ASL_WALK_VISIT_TWICE,
    360         OpcAmlEvaluationWalk1, OpcAmlEvaluationWalk2, WalkState);
    361 
    362     /* Restore original parse tree */
    363 
    364     Op->Common.Parent = OriginalParentOp;
    365 
    366     if (ACPI_FAILURE (Status))
    367     {
    368         DbgPrint (ASL_PARSE_OUTPUT,
    369             "Constant Subtree evaluation(1), %s\n",
    370             AcpiFormatException (Status));
    371         return (Status);
    372     }
    373 
    374     /* Get the final result */
    375 
    376     Status = AcpiDsResultPop (&ObjDesc, WalkState);
    377     if (ACPI_FAILURE (Status))
    378     {
    379         DbgPrint (ASL_PARSE_OUTPUT,
    380             "Constant Subtree evaluation(2), %s\n",
    381             AcpiFormatException (Status));
    382         return (Status);
    383     }
    384 
    385     /* Disconnect any existing children, install new constant */
    386 
    387     Op->Asl.Child = NULL;
    388     TrInstallReducedConstant (Op, ObjDesc);
    389 
    390     UtSetParseOpName (Op);
    391     return (AE_OK);
    392 }
    393 
    394 
    395 /*******************************************************************************
    396  *
    397  * FUNCTION:    TrTransformToStoreOp
    398  *
    399  * PARAMETERS:  Op                  - Parent operator to be transformed
    400  *              WalkState           - Current walk state
    401  *
    402  * RETURN:      Status
    403  *
    404  * DESCRIPTION: Transforms a single AML operation with a constant and target
    405  *              to a simple store operation:
    406  *
    407  *              Add (32,64,DATA) --> Store (96,DATA)
    408  *
    409  ******************************************************************************/
    410 
    411 static ACPI_STATUS
    412 TrTransformToStoreOp (
    413     ACPI_PARSE_OBJECT       *Op,
    414     ACPI_WALK_STATE         *WalkState)
    415 {
    416     ACPI_PARSE_OBJECT       *OriginalTarget;
    417     ACPI_PARSE_OBJECT       *NewTarget;
    418     ACPI_PARSE_OBJECT       *Child1;
    419     ACPI_PARSE_OBJECT       *Child2;
    420     ACPI_OPERAND_OBJECT     *ObjDesc;
    421     ACPI_PARSE_OBJECT       *NewParent;
    422     ACPI_PARSE_OBJECT       *OriginalParent;
    423     ACPI_STATUS             Status;
    424 
    425 
    426     DbgPrint (ASL_PARSE_OUTPUT,
    427         "Reduction/Transform to StoreOp: Store(Constant, Target)\n");
    428 
    429     /* Extract the operands */
    430 
    431     Child1 = Op->Asl.Child;
    432     Child2 = Child1->Asl.Next;
    433 
    434     /*
    435      * Special case for DIVIDE -- it has two targets. The first
    436      * is for the remainder and if present, we will not attempt
    437      * to reduce the expression.
    438      */
    439     if (Op->Asl.ParseOpcode == PARSEOP_DIVIDE)
    440     {
    441         Child2 = Child2->Asl.Next;
    442         if (Child2->Asl.ParseOpcode != PARSEOP_ZERO)
    443         {
    444             DbgPrint (ASL_PARSE_OUTPUT,
    445                 "Cannot reduce DIVIDE - has two targets\n\n");
    446             return (AE_OK);
    447         }
    448     }
    449 
    450     /*
    451      * Create a NULL (zero) target so that we can use the
    452      * interpreter to evaluate the expression.
    453      */
    454     NewTarget = TrCreateNullTarget ();
    455     NewTarget->Common.AmlOpcode = AML_INT_NAMEPATH_OP;
    456 
    457     /* Handle one-operand cases (NOT, TOBCD, etc.) */
    458 
    459     if (!Child2->Asl.Next)
    460     {
    461         Child2 = Child1;
    462     }
    463 
    464     /* Link in new NULL target as the last operand */
    465 
    466     OriginalTarget = Child2->Asl.Next;
    467     Child2->Asl.Next = NewTarget;
    468     NewTarget->Asl.Parent = OriginalTarget->Asl.Parent;
    469 
    470     NewParent = TrAllocateNode (PARSEOP_INTEGER);
    471     NewParent->Common.AmlOpcode = AML_INT_EVAL_SUBTREE_OP;
    472 
    473     OriginalParent = Op->Common.Parent;
    474     Op->Common.Parent = NewParent;
    475 
    476     /* Hand off the subtree to the AML interpreter */
    477 
    478     WalkState->CallerReturnDesc = &ObjDesc;
    479 
    480     Status = TrWalkParseTree (Op, ASL_WALK_VISIT_TWICE,
    481         OpcAmlEvaluationWalk1, OpcAmlEvaluationWalk2, WalkState);
    482     if (ACPI_FAILURE (Status))
    483     {
    484         DbgPrint (ASL_PARSE_OUTPUT,
    485             "Constant Subtree evaluation(3), %s\n",
    486             AcpiFormatException (Status));
    487         goto EvalError;
    488     }
    489 
    490     /* Get the final result */
    491 
    492     Status = AcpiDsResultPop (&ObjDesc, WalkState);
    493     if (ACPI_FAILURE (Status))
    494     {
    495         DbgPrint (ASL_PARSE_OUTPUT,
    496             "Constant Subtree evaluation(4), %s\n",
    497             AcpiFormatException (Status));
    498         goto EvalError;
    499     }
    500 
    501     /* Truncate any subtree expressions, they have been evaluated */
    502 
    503     Child1->Asl.Child = NULL;
    504 
    505     /* Folded constant is in ObjDesc, store into Child1 */
    506 
    507     TrInstallReducedConstant (Child1, ObjDesc);
    508 
    509     /* Convert operator to STORE */
    510 
    511     Op->Asl.ParseOpcode = PARSEOP_STORE;
    512     Op->Asl.AmlOpcode = AML_STORE_OP;
    513     UtSetParseOpName (Op);
    514     Op->Common.Parent = OriginalParent;
    515 
    516     /* First child is the folded constant */
    517 
    518     /* Second child will be the target */
    519 
    520     Child1->Asl.Next = OriginalTarget;
    521     return (AE_OK);
    522 
    523 
    524 EvalError:
    525 
    526     /* Restore original links */
    527 
    528     Op->Common.Parent = OriginalParent;
    529     Child2->Asl.Next = OriginalTarget;
    530     return (Status);
    531 }
    532 
    533 
    534 /*******************************************************************************
    535  *
    536  * FUNCTION:    TrInstallReducedConstant
    537  *
    538  * PARAMETERS:  Op                  - Parent operator to be transformed
    539  *              ObjDesc             - Reduced constant to be installed
    540  *
    541  * RETURN:      None
    542  *
    543  * DESCRIPTION: Transform the original operator to a simple constant.
    544  *              Handles Integers, Strings, and Buffers.
    545  *
    546  ******************************************************************************/
    547 
    548 static void
    549 TrInstallReducedConstant (
    550     ACPI_PARSE_OBJECT       *Op,
    551     ACPI_OPERAND_OBJECT     *ObjDesc)
    552 {
    553     ACPI_PARSE_OBJECT       *LengthOp;
    554     ACPI_PARSE_OBJECT       *DataOp;
    555 
    556 
    557     TotalFolds++;
    558     AslError (ASL_OPTIMIZATION, ASL_MSG_CONSTANT_FOLDED, Op,
    559         Op->Asl.ParseOpName);
    560 
    561     /*
    562      * Because we know we executed type 3/4/5 opcodes above, we know that
    563      * the result must be either an Integer, String, or Buffer.
    564      */
    565     switch (ObjDesc->Common.Type)
    566     {
    567     case ACPI_TYPE_INTEGER:
    568 
    569         OpcUpdateIntegerNode (Op, ObjDesc->Integer.Value);
    570 
    571         DbgPrint (ASL_PARSE_OUTPUT,
    572             "Constant expression reduced to (%s) %8.8X%8.8X\n\n",
    573             Op->Asl.ParseOpName,
    574             ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
    575         break;
    576 
    577     case ACPI_TYPE_STRING:
    578 
    579         Op->Asl.ParseOpcode = PARSEOP_STRING_LITERAL;
    580         Op->Common.AmlOpcode = AML_STRING_OP;
    581         Op->Asl.AmlLength = strlen (ObjDesc->String.Pointer) + 1;
    582         Op->Common.Value.String = ObjDesc->String.Pointer;
    583 
    584         DbgPrint (ASL_PARSE_OUTPUT,
    585             "Constant expression reduced to (STRING) %s\n\n",
    586             Op->Common.Value.String);
    587         break;
    588 
    589     case ACPI_TYPE_BUFFER:
    590         /*
    591          * Create a new parse subtree of the form:
    592          *
    593          * BUFFER (Buffer AML opcode)
    594          *    INTEGER (Buffer length in bytes)
    595          *    RAW_DATA (Buffer byte data)
    596          */
    597         Op->Asl.ParseOpcode = PARSEOP_BUFFER;
    598         Op->Common.AmlOpcode = AML_BUFFER_OP;
    599         Op->Asl.CompileFlags = NODE_AML_PACKAGE;
    600         UtSetParseOpName (Op);
    601 
    602         /* Child node is the buffer length */
    603 
    604         LengthOp = TrAllocateNode (PARSEOP_INTEGER);
    605 
    606         LengthOp->Asl.AmlOpcode = AML_DWORD_OP;
    607         LengthOp->Asl.Value.Integer = ObjDesc->Buffer.Length;
    608         LengthOp->Asl.Parent = Op;
    609         (void) OpcSetOptimalIntegerSize (LengthOp);
    610 
    611         Op->Asl.Child = LengthOp;
    612 
    613         /* Next child is the raw buffer data */
    614 
    615         DataOp = TrAllocateNode (PARSEOP_RAW_DATA);
    616         DataOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER;
    617         DataOp->Asl.AmlLength = ObjDesc->Buffer.Length;
    618         DataOp->Asl.Value.String = (char *) ObjDesc->Buffer.Pointer;
    619         DataOp->Asl.Parent = Op;
    620 
    621         LengthOp->Asl.Next = DataOp;
    622 
    623         DbgPrint (ASL_PARSE_OUTPUT,
    624             "Constant expression reduced to (BUFFER) length %X\n\n",
    625             ObjDesc->Buffer.Length);
    626         break;
    627 
    628     default:
    629         break;
    630     }
    631 }
    632 
    633 
    634 /*******************************************************************************
    635  *
    636  * FUNCTION:    OpcUpdateIntegerNode
    637  *
    638  * PARAMETERS:  Op                  - Current parse object
    639  *              Value               - Value for the integer op
    640  *
    641  * RETURN:      None
    642  *
    643  * DESCRIPTION: Update node to the correct Integer type and value
    644  *
    645  ******************************************************************************/
    646 
    647 static void
    648 OpcUpdateIntegerNode (
    649     ACPI_PARSE_OBJECT       *Op,
    650     UINT64                  Value)
    651 {
    652 
    653     Op->Common.Value.Integer = Value;
    654 
    655     /*
    656      * The AmlLength is used by the parser to indicate a constant,
    657      * (if non-zero). Length is either (1/2/4/8)
    658      */
    659     switch (Op->Asl.AmlLength)
    660     {
    661     case 1:
    662 
    663         TrUpdateNode (PARSEOP_BYTECONST, Op);
    664         Op->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
    665         break;
    666 
    667     case 2:
    668 
    669         TrUpdateNode (PARSEOP_WORDCONST, Op);
    670         Op->Asl.AmlOpcode = AML_RAW_DATA_WORD;
    671         break;
    672 
    673     case 4:
    674 
    675         TrUpdateNode (PARSEOP_DWORDCONST, Op);
    676         Op->Asl.AmlOpcode = AML_RAW_DATA_DWORD;
    677         break;
    678 
    679     case 8:
    680 
    681         TrUpdateNode (PARSEOP_QWORDCONST, Op);
    682         Op->Asl.AmlOpcode = AML_RAW_DATA_QWORD;
    683         break;
    684 
    685     case 0:
    686     default:
    687 
    688         OpcSetOptimalIntegerSize (Op);
    689         TrUpdateNode (PARSEOP_INTEGER, Op);
    690         break;
    691     }
    692 
    693     Op->Asl.AmlLength = 0;
    694 }
    695 
    696 
    697 /*******************************************************************************
    698  *
    699  * FUNCTION:    OpcAmlEvaluationWalk1
    700  *
    701  * PARAMETERS:  ASL_WALK_CALLBACK
    702  *
    703  * RETURN:      Status
    704  *
    705  * DESCRIPTION: Descending callback for AML execution of constant subtrees
    706  *
    707  ******************************************************************************/
    708 
    709 static ACPI_STATUS
    710 OpcAmlEvaluationWalk1 (
    711     ACPI_PARSE_OBJECT       *Op,
    712     UINT32                  Level,
    713     void                    *Context)
    714 {
    715     ACPI_WALK_STATE         *WalkState = Context;
    716     ACPI_STATUS             Status;
    717     ACPI_PARSE_OBJECT       *OutOp;
    718 
    719 
    720     WalkState->Op = Op;
    721     WalkState->Opcode = Op->Common.AmlOpcode;
    722     WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
    723 
    724     /* Copy child pointer to Arg for compatibility with Interpreter */
    725 
    726     if (Op->Asl.Child)
    727     {
    728         Op->Common.Value.Arg = Op->Asl.Child;
    729     }
    730 
    731     /* Call AML dispatcher */
    732 
    733     Status = AcpiDsExecBeginOp (WalkState, &OutOp);
    734     if (ACPI_FAILURE (Status))
    735     {
    736         DbgPrint (ASL_PARSE_OUTPUT,
    737             "%s Constant interpretation failed (1) - %s\n",
    738             Op->Asl.ParseOpName, AcpiFormatException (Status));
    739     }
    740 
    741     return (Status);
    742 }
    743 
    744 
    745 /*******************************************************************************
    746  *
    747  * FUNCTION:    OpcAmlEvaluationWalk2
    748  *
    749  * PARAMETERS:  ASL_WALK_CALLBACK
    750  *
    751  * RETURN:      Status
    752  *
    753  * DESCRIPTION: Ascending callback for AML execution of constant subtrees
    754  *
    755  ******************************************************************************/
    756 
    757 static ACPI_STATUS
    758 OpcAmlEvaluationWalk2 (
    759     ACPI_PARSE_OBJECT       *Op,
    760     UINT32                  Level,
    761     void                    *Context)
    762 {
    763     ACPI_WALK_STATE         *WalkState = Context;
    764     ACPI_STATUS             Status;
    765 
    766 
    767     WalkState->Op = Op;
    768     WalkState->Opcode = Op->Common.AmlOpcode;
    769     WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
    770 
    771     /* Copy child pointer to Arg for compatibility with Interpreter */
    772 
    773     if (Op->Asl.Child)
    774     {
    775         Op->Common.Value.Arg = Op->Asl.Child;
    776     }
    777 
    778     /* Call AML dispatcher */
    779 
    780     Status = AcpiDsExecEndOp (WalkState);
    781     if (ACPI_FAILURE (Status))
    782     {
    783         DbgPrint (ASL_PARSE_OUTPUT,
    784             "%s: Constant interpretation failed (2) - %s\n",
    785             Op->Asl.ParseOpName, AcpiFormatException (Status));
    786     }
    787 
    788     return (Status);
    789 }
    790