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