Home | History | Annotate | Line # | Download | only in compiler
aslfold.c revision 1.1.1.5
      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         Status = AE_TYPE;
    240         goto CleanupAndExit;
    241     }
    242 
    243     /*
    244      * These opcodes do not appear in the OpcodeInfo table, but
    245      * they represent constants, so abort the constant walk now.
    246      */
    247     if ((WalkState->Opcode == AML_RAW_DATA_BYTE) ||
    248         (WalkState->Opcode == AML_RAW_DATA_WORD) ||
    249         (WalkState->Opcode == AML_RAW_DATA_DWORD) ||
    250         (WalkState->Opcode == AML_RAW_DATA_QWORD))
    251     {
    252         DbgPrint (ASL_PARSE_OUTPUT, "RAW DATA");
    253         Status = AE_TYPE;
    254         goto CleanupAndExit;
    255     }
    256 
    257     /* Type 3/4/5 opcodes have the AML_CONSTANT flag set */
    258 
    259     if (!(WalkState->OpInfo->Flags & AML_CONSTANT))
    260     {
    261         /* Not 3/4/5 opcode, but maybe can convert to STORE */
    262 
    263         if (Op->Asl.CompileFlags & NODE_IS_TARGET)
    264         {
    265             DbgPrint (ASL_PARSE_OUTPUT,
    266                 "**** Valid Target, transform to Store ****\n");
    267             return (AE_CTRL_RETURN_VALUE);
    268         }
    269 
    270         /* Expression cannot be reduced */
    271 
    272         DbgPrint (ASL_PARSE_OUTPUT,
    273             "**** Not a Type 3/4/5 opcode (%s) ****",
    274              Op->Asl.ParseOpName);
    275 
    276         Status = AE_TYPE;
    277         goto CleanupAndExit;
    278     }
    279 
    280     /* Debug output */
    281 
    282     DbgPrint (ASL_PARSE_OUTPUT, "TYPE_345");
    283 
    284     if (Op->Asl.CompileFlags & NODE_IS_TARGET)
    285     {
    286         if (Op->Asl.ParseOpcode == PARSEOP_ZERO)
    287         {
    288             DbgPrint (ASL_PARSE_OUTPUT, "%-16s", " NULL TARGET");
    289         }
    290         else
    291         {
    292             DbgPrint (ASL_PARSE_OUTPUT, "%-16s", " VALID TARGET");
    293         }
    294     }
    295     if (Op->Asl.CompileFlags & NODE_IS_TERM_ARG)
    296     {
    297         DbgPrint (ASL_PARSE_OUTPUT, "%-16s", " TERMARG");
    298     }
    299 
    300 CleanupAndExit:
    301 
    302     /* Dump the node compile flags also */
    303 
    304     TrPrintNodeCompileFlags (Op->Asl.CompileFlags);
    305     DbgPrint (ASL_PARSE_OUTPUT, "\n");
    306     return (Status);
    307 }
    308 
    309 
    310 /*******************************************************************************
    311  *
    312  * FUNCTION:    TrSimpleConstantReduction
    313  *
    314  * PARAMETERS:  Op                  - Parent operator to be transformed
    315  *              WalkState           - Current walk state
    316  *
    317  * RETURN:      Status
    318  *
    319  * DESCRIPTION: Reduce an entire AML operation to a single constant. The
    320  *              operation must not have a target operand.
    321  *
    322  *              Add (32,64) --> 96
    323  *
    324  ******************************************************************************/
    325 
    326 static ACPI_STATUS
    327 TrSimpleConstantReduction (
    328     ACPI_PARSE_OBJECT       *Op,
    329     ACPI_WALK_STATE         *WalkState)
    330 {
    331     ACPI_PARSE_OBJECT       *RootOp;
    332     ACPI_PARSE_OBJECT       *OriginalParentOp;
    333     ACPI_OPERAND_OBJECT     *ObjDesc;
    334     ACPI_STATUS             Status;
    335 
    336 
    337     DbgPrint (ASL_PARSE_OUTPUT,
    338         "Simple subtree constant reduction, operator to constant\n");
    339 
    340     /* Allocate a new temporary root for this subtree */
    341 
    342     RootOp = TrAllocateNode (PARSEOP_INTEGER);
    343     if (!RootOp)
    344     {
    345         return (AE_NO_MEMORY);
    346     }
    347 
    348     RootOp->Common.AmlOpcode = AML_INT_EVAL_SUBTREE_OP;
    349 
    350     OriginalParentOp = Op->Common.Parent;
    351     Op->Common.Parent = RootOp;
    352 
    353     /* Hand off the subtree to the AML interpreter */
    354 
    355     WalkState->CallerReturnDesc = &ObjDesc;
    356 
    357     Status = TrWalkParseTree (Op, ASL_WALK_VISIT_TWICE,
    358         OpcAmlEvaluationWalk1, OpcAmlEvaluationWalk2, WalkState);
    359 
    360     /* Restore original parse tree */
    361 
    362     Op->Common.Parent = OriginalParentOp;
    363 
    364     if (ACPI_FAILURE (Status))
    365     {
    366         DbgPrint (ASL_PARSE_OUTPUT,
    367             "Constant Subtree evaluation(1), %s\n",
    368             AcpiFormatException (Status));
    369         return (Status);
    370     }
    371 
    372     /* Get the final result */
    373 
    374     Status = AcpiDsResultPop (&ObjDesc, WalkState);
    375     if (ACPI_FAILURE (Status))
    376     {
    377         DbgPrint (ASL_PARSE_OUTPUT,
    378             "Constant Subtree evaluation(2), %s\n",
    379             AcpiFormatException (Status));
    380         return (Status);
    381     }
    382 
    383     TrInstallReducedConstant (Op, ObjDesc);
    384 
    385     UtSetParseOpName (Op);
    386     Op->Asl.Child = NULL;
    387     return (AE_OK);
    388 }
    389 
    390 
    391 /*******************************************************************************
    392  *
    393  * FUNCTION:    TrTransformToStoreOp
    394  *
    395  * PARAMETERS:  Op                  - Parent operator to be transformed
    396  *              WalkState           - Current walk state
    397  *
    398  * RETURN:      Status
    399  *
    400  * DESCRIPTION: Transforms a single AML operation with a constant and target
    401  *              to a simple store operation:
    402  *
    403  *              Add (32,64,DATA) --> Store (96,DATA)
    404  *
    405  ******************************************************************************/
    406 
    407 static ACPI_STATUS
    408 TrTransformToStoreOp (
    409     ACPI_PARSE_OBJECT       *Op,
    410     ACPI_WALK_STATE         *WalkState)
    411 {
    412     ACPI_PARSE_OBJECT       *OriginalTarget;
    413     ACPI_PARSE_OBJECT       *NewTarget;
    414     ACPI_PARSE_OBJECT       *Child1;
    415     ACPI_PARSE_OBJECT       *Child2;
    416     ACPI_OPERAND_OBJECT     *ObjDesc;
    417     ACPI_PARSE_OBJECT       *NewParent;
    418     ACPI_PARSE_OBJECT       *OriginalParent;
    419     ACPI_STATUS             Status;
    420 
    421 
    422     DbgPrint (ASL_PARSE_OUTPUT,
    423         "Reduction/Transform to StoreOp: Store(Constant, Target)\n");
    424 
    425     /* Extract the operands */
    426 
    427     Child1 = Op->Asl.Child;
    428     Child2 = Child1->Asl.Next;
    429 
    430     /*
    431      * Special case for DIVIDE -- it has two targets. The first
    432      * is for the remainder and if present, we will not attempt
    433      * to reduce the expression.
    434      */
    435     if (Op->Asl.ParseOpcode == PARSEOP_DIVIDE)
    436     {
    437         Child2 = Child2->Asl.Next;
    438         if (Child2->Asl.ParseOpcode != PARSEOP_ZERO)
    439         {
    440             DbgPrint (ASL_PARSE_OUTPUT,
    441                 "Cannot reduce DIVIDE - has two targets\n\n");
    442             return (AE_OK);
    443         }
    444     }
    445 
    446     /*
    447      * Create a NULL (zero) target so that we can use the
    448      * interpreter to evaluate the expression.
    449      */
    450     NewTarget = TrCreateNullTarget ();
    451     NewTarget->Common.AmlOpcode = AML_INT_NAMEPATH_OP;
    452 
    453     /* Handle one-operand cases (NOT, TOBCD, etc.) */
    454 
    455     if (!Child2->Asl.Next)
    456     {
    457         Child2 = Child1;
    458     }
    459 
    460     /* Link in new NULL target as the last operand */
    461 
    462     OriginalTarget = Child2->Asl.Next;
    463     Child2->Asl.Next = NewTarget;
    464     NewTarget->Asl.Parent = OriginalTarget->Asl.Parent;
    465 
    466     NewParent = TrAllocateNode (PARSEOP_INTEGER);
    467     NewParent->Common.AmlOpcode = AML_INT_EVAL_SUBTREE_OP;
    468 
    469     OriginalParent = Op->Common.Parent;
    470     Op->Common.Parent = NewParent;
    471 
    472     /* Hand off the subtree to the AML interpreter */
    473 
    474     WalkState->CallerReturnDesc = &ObjDesc;
    475 
    476     Status = TrWalkParseTree (Op, ASL_WALK_VISIT_TWICE,
    477         OpcAmlEvaluationWalk1, OpcAmlEvaluationWalk2, WalkState);
    478     if (ACPI_FAILURE (Status))
    479     {
    480         DbgPrint (ASL_PARSE_OUTPUT,
    481             "Constant Subtree evaluation(3), %s\n",
    482             AcpiFormatException (Status));
    483         goto EvalError;
    484     }
    485 
    486     /* Get the final result */
    487 
    488     Status = AcpiDsResultPop (&ObjDesc, WalkState);
    489     if (ACPI_FAILURE (Status))
    490     {
    491         DbgPrint (ASL_PARSE_OUTPUT,
    492             "Constant Subtree evaluation(4), %s\n",
    493             AcpiFormatException (Status));
    494         goto EvalError;
    495     }
    496 
    497     /* Folded constant is in ObjDesc, store into Child1 */
    498 
    499     TrInstallReducedConstant (Child1, ObjDesc);
    500 
    501     /* Convert operator to STORE */
    502 
    503     Op->Asl.ParseOpcode = PARSEOP_STORE;
    504     Op->Asl.AmlOpcode = AML_STORE_OP;
    505     UtSetParseOpName (Op);
    506     Op->Common.Parent = OriginalParent;
    507 
    508     /* Truncate any subtree expressions, they have been evaluated */
    509 
    510     Child1->Asl.Child = NULL;
    511     Child2->Asl.Child = NULL;
    512 
    513     /* First child is the folded constant */
    514 
    515     /* Second child will be the target */
    516 
    517     Child1->Asl.Next = OriginalTarget;
    518     return (AE_OK);
    519 
    520 
    521 EvalError:
    522 
    523     /* Restore original links */
    524 
    525     Op->Common.Parent = OriginalParent;
    526     Child2->Asl.Next = OriginalTarget;
    527     return (Status);
    528 }
    529 
    530 
    531 /*******************************************************************************
    532  *
    533  * FUNCTION:    TrInstallReducedConstant
    534  *
    535  * PARAMETERS:  Op                  - Parent operator to be transformed
    536  *              ObjDesc             - Reduced constant to be installed
    537  *
    538  * RETURN:      None
    539  *
    540  * DESCRIPTION: Transform the original operator to a simple constant.
    541  *              Handles Integers, Strings, and Buffers.
    542  *
    543  ******************************************************************************/
    544 
    545 static void
    546 TrInstallReducedConstant (
    547     ACPI_PARSE_OBJECT       *Op,
    548     ACPI_OPERAND_OBJECT     *ObjDesc)
    549 {
    550     ACPI_PARSE_OBJECT       *RootOp;
    551 
    552 
    553     TotalFolds++;
    554     AslError (ASL_OPTIMIZATION, ASL_MSG_CONSTANT_FOLDED, Op,
    555         Op->Asl.ParseOpName);
    556 
    557     /*
    558      * Because we know we executed type 3/4/5 opcodes above, we know that
    559      * the result must be either an Integer, String, or Buffer.
    560      */
    561     switch (ObjDesc->Common.Type)
    562     {
    563     case ACPI_TYPE_INTEGER:
    564 
    565         OpcUpdateIntegerNode (Op, ObjDesc->Integer.Value);
    566 
    567         DbgPrint (ASL_PARSE_OUTPUT,
    568             "Constant expression reduced to (%s) %8.8X%8.8X\n\n",
    569             Op->Asl.ParseOpName,
    570             ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
    571         break;
    572 
    573     case ACPI_TYPE_STRING:
    574 
    575         Op->Asl.ParseOpcode = PARSEOP_STRING_LITERAL;
    576         Op->Common.AmlOpcode = AML_STRING_OP;
    577         Op->Asl.AmlLength = ACPI_STRLEN (ObjDesc->String.Pointer) + 1;
    578         Op->Common.Value.String = ObjDesc->String.Pointer;
    579 
    580         DbgPrint (ASL_PARSE_OUTPUT,
    581             "Constant expression reduced to (STRING) %s\n\n",
    582             Op->Common.Value.String);
    583 
    584         break;
    585 
    586     case ACPI_TYPE_BUFFER:
    587 
    588         Op->Asl.ParseOpcode = PARSEOP_BUFFER;
    589         Op->Common.AmlOpcode = AML_BUFFER_OP;
    590         Op->Asl.CompileFlags = NODE_AML_PACKAGE;
    591         UtSetParseOpName (Op);
    592 
    593         /* Child node is the buffer length */
    594 
    595         RootOp = TrAllocateNode (PARSEOP_INTEGER);
    596 
    597         RootOp->Asl.AmlOpcode = AML_DWORD_OP;
    598         RootOp->Asl.Value.Integer = ObjDesc->Buffer.Length;
    599         RootOp->Asl.Parent = Op;
    600 
    601         (void) OpcSetOptimalIntegerSize (RootOp);
    602 
    603         Op->Asl.Child = RootOp;
    604         Op = RootOp;
    605         UtSetParseOpName (Op);
    606 
    607         /* Peer to the child is the raw buffer data */
    608 
    609         RootOp = TrAllocateNode (PARSEOP_RAW_DATA);
    610         RootOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER;
    611         RootOp->Asl.AmlLength = ObjDesc->Buffer.Length;
    612         RootOp->Asl.Value.String = (char *) ObjDesc->Buffer.Pointer;
    613         RootOp->Asl.Parent = Op->Asl.Parent;
    614 
    615         Op->Asl.Next = RootOp;
    616         Op = RootOp;
    617 
    618         DbgPrint (ASL_PARSE_OUTPUT,
    619             "Constant expression reduced to (BUFFER) length %X\n\n",
    620             ObjDesc->Buffer.Length);
    621         break;
    622 
    623     default:
    624         break;
    625     }
    626 }
    627 
    628 
    629 /*******************************************************************************
    630  *
    631  * FUNCTION:    OpcUpdateIntegerNode
    632  *
    633  * PARAMETERS:  Op                  - Current parse object
    634  *              Value               - Value for the integer op
    635  *
    636  * RETURN:      None
    637  *
    638  * DESCRIPTION: Update node to the correct Integer type and value
    639  *
    640  ******************************************************************************/
    641 
    642 static void
    643 OpcUpdateIntegerNode (
    644     ACPI_PARSE_OBJECT       *Op,
    645     UINT64                  Value)
    646 {
    647 
    648     Op->Common.Value.Integer = Value;
    649 
    650     /*
    651      * The AmlLength is used by the parser to indicate a constant,
    652      * (if non-zero). Length is either (1/2/4/8)
    653      */
    654     switch (Op->Asl.AmlLength)
    655     {
    656     case 1:
    657 
    658         TrUpdateNode (PARSEOP_BYTECONST, Op);
    659         Op->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
    660         break;
    661 
    662     case 2:
    663 
    664         TrUpdateNode (PARSEOP_WORDCONST, Op);
    665         Op->Asl.AmlOpcode = AML_RAW_DATA_WORD;
    666         break;
    667 
    668     case 4:
    669 
    670         TrUpdateNode (PARSEOP_DWORDCONST, Op);
    671         Op->Asl.AmlOpcode = AML_RAW_DATA_DWORD;
    672         break;
    673 
    674     case 8:
    675 
    676         TrUpdateNode (PARSEOP_QWORDCONST, Op);
    677         Op->Asl.AmlOpcode = AML_RAW_DATA_QWORD;
    678         break;
    679 
    680     case 0:
    681     default:
    682 
    683         OpcSetOptimalIntegerSize (Op);
    684         TrUpdateNode (PARSEOP_INTEGER, Op);
    685         break;
    686     }
    687 
    688     Op->Asl.AmlLength = 0;
    689 }
    690 
    691 
    692 /*******************************************************************************
    693  *
    694  * FUNCTION:    OpcAmlEvaluationWalk1
    695  *
    696  * PARAMETERS:  ASL_WALK_CALLBACK
    697  *
    698  * RETURN:      Status
    699  *
    700  * DESCRIPTION: Descending callback for AML execution of constant subtrees
    701  *
    702  ******************************************************************************/
    703 
    704 static ACPI_STATUS
    705 OpcAmlEvaluationWalk1 (
    706     ACPI_PARSE_OBJECT       *Op,
    707     UINT32                  Level,
    708     void                    *Context)
    709 {
    710     ACPI_WALK_STATE         *WalkState = Context;
    711     ACPI_STATUS             Status;
    712     ACPI_PARSE_OBJECT       *OutOp;
    713 
    714 
    715     WalkState->Op = Op;
    716     WalkState->Opcode = Op->Common.AmlOpcode;
    717     WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
    718 
    719     /* Copy child pointer to Arg for compatibility with Interpreter */
    720 
    721     if (Op->Asl.Child)
    722     {
    723         Op->Common.Value.Arg = Op->Asl.Child;
    724     }
    725 
    726     /* Call AML dispatcher */
    727 
    728     Status = AcpiDsExecBeginOp (WalkState, &OutOp);
    729     if (ACPI_FAILURE (Status))
    730     {
    731         DbgPrint (ASL_PARSE_OUTPUT,
    732             "%s Constant interpretation failed (1) - %s\n",
    733             Op->Asl.ParseOpName, AcpiFormatException (Status));
    734     }
    735 
    736     return (Status);
    737 }
    738 
    739 
    740 /*******************************************************************************
    741  *
    742  * FUNCTION:    OpcAmlEvaluationWalk2
    743  *
    744  * PARAMETERS:  ASL_WALK_CALLBACK
    745  *
    746  * RETURN:      Status
    747  *
    748  * DESCRIPTION: Ascending callback for AML execution of constant subtrees
    749  *
    750  ******************************************************************************/
    751 
    752 static ACPI_STATUS
    753 OpcAmlEvaluationWalk2 (
    754     ACPI_PARSE_OBJECT       *Op,
    755     UINT32                  Level,
    756     void                    *Context)
    757 {
    758     ACPI_WALK_STATE         *WalkState = Context;
    759     ACPI_STATUS             Status;
    760 
    761 
    762     WalkState->Op = Op;
    763     WalkState->Opcode = Op->Common.AmlOpcode;
    764     WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
    765 
    766     /* Copy child pointer to Arg for compatibility with Interpreter */
    767 
    768     if (Op->Asl.Child)
    769     {
    770         Op->Common.Value.Arg = Op->Asl.Child;
    771     }
    772 
    773     /* Call AML dispatcher */
    774 
    775     Status = AcpiDsExecEndOp (WalkState);
    776     if (ACPI_FAILURE (Status))
    777     {
    778         DbgPrint (ASL_PARSE_OUTPUT,
    779             "%s: Constant interpretation failed (2) - %s\n",
    780             Op->Asl.ParseOpName, AcpiFormatException (Status));
    781     }
    782 
    783     return (Status);
    784 }
    785