Home | History | Annotate | Line # | Download | only in compiler
      1 /******************************************************************************
      2  *
      3  * Module Name: aslparseop - Parse op create/allocate/cache interfaces
      4  *
      5  *****************************************************************************/
      6 
      7 /******************************************************************************
      8  *
      9  * 1. Copyright Notice
     10  *
     11  * Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.
     12  * All rights reserved.
     13  *
     14  * 2. License
     15  *
     16  * 2.1. This is your license from Intel Corp. under its intellectual property
     17  * rights. You may have additional license terms from the party that provided
     18  * you this software, covering your right to use that party's intellectual
     19  * property rights.
     20  *
     21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
     22  * copy of the source code appearing in this file ("Covered Code") an
     23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
     24  * base code distributed originally by Intel ("Original Intel Code") to copy,
     25  * make derivatives, distribute, use and display any portion of the Covered
     26  * Code in any form, with the right to sublicense such rights; and
     27  *
     28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
     29  * license (with the right to sublicense), under only those claims of Intel
     30  * patents that are infringed by the Original Intel Code, to make, use, sell,
     31  * offer to sell, and import the Covered Code and derivative works thereof
     32  * solely to the minimum extent necessary to exercise the above copyright
     33  * license, and in no event shall the patent license extend to any additions
     34  * to or modifications of the Original Intel Code. No other license or right
     35  * is granted directly or by implication, estoppel or otherwise;
     36  *
     37  * The above copyright and patent license is granted only if the following
     38  * conditions are met:
     39  *
     40  * 3. Conditions
     41  *
     42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
     43  * Redistribution of source code of any substantial portion of the Covered
     44  * Code or modification with rights to further distribute source must include
     45  * the above Copyright Notice, the above License, this list of Conditions,
     46  * and the following Disclaimer and Export Compliance provision. In addition,
     47  * Licensee must cause all Covered Code to which Licensee contributes to
     48  * contain a file documenting the changes Licensee made to create that Covered
     49  * Code and the date of any change. Licensee must include in that file the
     50  * documentation of any changes made by any predecessor Licensee. Licensee
     51  * must include a prominent statement that the modification is derived,
     52  * directly or indirectly, from Original Intel Code.
     53  *
     54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
     55  * Redistribution of source code of any substantial portion of the Covered
     56  * Code or modification without rights to further distribute source must
     57  * include the following Disclaimer and Export Compliance provision in the
     58  * documentation and/or other materials provided with distribution. In
     59  * addition, Licensee may not authorize further sublicense of source of any
     60  * portion of the Covered Code, and must include terms to the effect that the
     61  * license from Licensee to its licensee is limited to the intellectual
     62  * property embodied in the software Licensee provides to its licensee, and
     63  * not to intellectual property embodied in modifications its licensee may
     64  * make.
     65  *
     66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
     67  * substantial portion of the Covered Code or modification must reproduce the
     68  * above Copyright Notice, and the following Disclaimer and Export Compliance
     69  * provision in the documentation and/or other materials provided with the
     70  * distribution.
     71  *
     72  * 3.4. Intel retains all right, title, and interest in and to the Original
     73  * Intel Code.
     74  *
     75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
     76  * Intel shall be used in advertising or otherwise to promote the sale, use or
     77  * other dealings in products derived from or relating to the Covered Code
     78  * without prior written authorization from Intel.
     79  *
     80  * 4. Disclaimer and Export Compliance
     81  *
     82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
     83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
     84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
     85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
     86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
     87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
     88  * PARTICULAR PURPOSE.
     89  *
     90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
     91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
     92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
     93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
     94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
     95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
     96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
     97  * LIMITED REMEDY.
     98  *
     99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
    100  * software or system incorporating such software without first obtaining any
    101  * required license or other approval from the U. S. Department of Commerce or
    102  * any other agency or department of the United States Government. In the
    103  * event Licensee exports any such software from the United States or
    104  * re-exports any such software from a foreign destination, Licensee shall
    105  * ensure that the distribution and export/re-export of the software is in
    106  * compliance with all laws, regulations, orders, or other restrictions of the
    107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
    108  * any of its subsidiaries will export/re-export any technical data, process,
    109  * software, or service, directly or indirectly, to any country for which the
    110  * United States government or any agency thereof requires an export license,
    111  * other governmental approval, or letter of assurance, without first obtaining
    112  * such license, approval or letter.
    113  *
    114  *****************************************************************************
    115  *
    116  * Alternatively, you may choose to be licensed under the terms of the
    117  * following license:
    118  *
    119  * Redistribution and use in source and binary forms, with or without
    120  * modification, are permitted provided that the following conditions
    121  * are met:
    122  * 1. Redistributions of source code must retain the above copyright
    123  *    notice, this list of conditions, and the following disclaimer,
    124  *    without modification.
    125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
    126  *    substantially similar to the "NO WARRANTY" disclaimer below
    127  *    ("Disclaimer") and any redistribution must be conditioned upon
    128  *    including a substantially similar Disclaimer requirement for further
    129  *    binary redistribution.
    130  * 3. Neither the names of the above-listed copyright holders nor the names
    131  *    of any contributors may be used to endorse or promote products derived
    132  *    from this software without specific prior written permission.
    133  *
    134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    145  *
    146  * Alternatively, you may choose to be licensed under the terms of the
    147  * GNU General Public License ("GPL") version 2 as published by the Free
    148  * Software Foundation.
    149  *
    150  *****************************************************************************/
    151 
    152 #include "aslcompiler.h"
    153 #include "aslcompiler.y.h"
    154 #include "acapps.h"
    155 #include "acconvert.h"
    156 
    157 #define _COMPONENT          ACPI_COMPILER
    158         ACPI_MODULE_NAME    ("aslparseop")
    159 
    160 
    161 /*******************************************************************************
    162  *
    163  * FUNCTION:    TrCreateOp
    164  *
    165  * PARAMETERS:  ParseOpcode         - Opcode to be assigned to the op
    166  *              NumChildren         - Number of children to follow
    167  *              ...                 - A list of child ops to link to the new
    168  *                                    op. NumChildren long.
    169  *
    170  * RETURN:      Pointer to the new op. Aborts on allocation failure
    171  *
    172  * DESCRIPTION: Create a new parse op and link together a list of child
    173  *              ops underneath the new op.
    174  *
    175  ******************************************************************************/
    176 
    177 ACPI_PARSE_OBJECT *
    178 TrCreateOp (
    179     UINT32                  ParseOpcode,
    180     UINT32                  NumChildren,
    181     ...)
    182 {
    183     ACPI_PARSE_OBJECT       *Op;
    184     ACPI_PARSE_OBJECT       *Child;
    185     ACPI_PARSE_OBJECT       *PrevChild;
    186     va_list                 ap;
    187     UINT32                  i;
    188     BOOLEAN                 FirstChild;
    189 
    190 
    191     va_start (ap, NumChildren);
    192 
    193     /* Allocate one new op */
    194 
    195     Op = TrAllocateOp (ParseOpcode);
    196 
    197     DbgPrint (ASL_PARSE_OUTPUT,
    198         "\nCreateOp  Ln/Col %u/%u NewParent %p Child %u Op %s  ",
    199         Op->Asl.LineNumber, Op->Asl.Column, Op,
    200         NumChildren, UtGetOpName(ParseOpcode));
    201 
    202     /* Some extra debug output based on the parse opcode */
    203 
    204     switch (ParseOpcode)
    205     {
    206     case PARSEOP_ASL_CODE:
    207 
    208         AslGbl_ParseTreeRoot = Op;
    209         Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
    210         DbgPrint (ASL_PARSE_OUTPUT, "ASLCODE (Tree Completed)->");
    211         break;
    212 
    213     case PARSEOP_DEFINITION_BLOCK:
    214 
    215         DbgPrint (ASL_PARSE_OUTPUT, "DEFINITION_BLOCK (Tree Completed)->");
    216         break;
    217 
    218     case PARSEOP_OPERATIONREGION:
    219 
    220         DbgPrint (ASL_PARSE_OUTPUT, "OPREGION->");
    221         break;
    222 
    223     case PARSEOP_OR:
    224 
    225         DbgPrint (ASL_PARSE_OUTPUT, "OR->");
    226         break;
    227 
    228     default:
    229 
    230         /* Nothing to do for other opcodes */
    231 
    232         break;
    233     }
    234 
    235     /* Link the new op to its children */
    236 
    237     PrevChild = NULL;
    238     FirstChild = TRUE;
    239     for (i = 0; i < NumChildren; i++)
    240     {
    241         /* Get the next child */
    242 
    243         Child = va_arg (ap, ACPI_PARSE_OBJECT *);
    244         DbgPrint (ASL_PARSE_OUTPUT, "%p, ", Child);
    245 
    246         /*
    247          * If child is NULL, this means that an optional argument
    248          * was omitted. We must create a placeholder with a special
    249          * opcode (DEFAULT_ARG) so that the code generator will know
    250          * that it must emit the correct default for this argument
    251          */
    252         if (!Child)
    253         {
    254             Child = TrAllocateOp (PARSEOP_DEFAULT_ARG);
    255         }
    256 
    257         /* Link first child to parent */
    258 
    259         if (FirstChild)
    260         {
    261             FirstChild = FALSE;
    262             Op->Asl.Child = Child;
    263 
    264             /*
    265              * For the ASL-/ASL+ converter: if the ParseOp is a Connection,
    266              * External, Offset or AccessAs, it means that the comments in the
    267              * FirstChild belongs to their parent due to the parsing order in
    268              * the .y files. To correct this, take the comments in the
    269              * FirstChild place it in the parent. This also means that
    270              * legitimate comments for the child gets put to the parent.
    271              */
    272             if (AcpiGbl_CaptureComments &&
    273                 ((ParseOpcode == PARSEOP_CONNECTION) ||
    274                  (ParseOpcode == PARSEOP_EXTERNAL) ||
    275                  (ParseOpcode == PARSEOP_OFFSET) ||
    276                  (ParseOpcode == PARSEOP_ACCESSAS)))
    277             {
    278                 Op->Asl.CommentList      = Child->Asl.CommentList;
    279                 Op->Asl.EndBlkComment    = Child->Asl.EndBlkComment;
    280                 Op->Asl.InlineComment    = Child->Asl.InlineComment;
    281                 Op->Asl.FileChanged      = Child->Asl.FileChanged;
    282 
    283                 Child->Asl.CommentList   = NULL;
    284                 Child->Asl.EndBlkComment = NULL;
    285                 Child->Asl.InlineComment = NULL;
    286                 Child->Asl.FileChanged   = FALSE;
    287 
    288                 /*
    289                  * These do not need to be "passed off". They can be copied
    290                  * because the code for these opcodes should be printed in the
    291                  * same file.
    292                  */
    293                 Op->Asl.Filename         = Child->Asl.Filename;
    294                 Op->Asl.ParentFilename   = Child->Asl.ParentFilename;
    295             }
    296         }
    297 
    298         /* Point all children to parent */
    299 
    300         Child->Asl.Parent = Op;
    301 
    302         /* Link children in a peer list */
    303 
    304         if (PrevChild)
    305         {
    306             PrevChild->Asl.Next = Child;
    307         };
    308 
    309         /* Get the comment from last child in the resource template call */
    310 
    311         if (AcpiGbl_CaptureComments &&
    312             (Op->Asl.ParseOpcode == PARSEOP_RESOURCETEMPLATE))
    313         {
    314             CvDbgPrint ("Transferred current comment list to this op.\n");
    315             Op->Asl.CommentList = Child->Asl.CommentList;
    316             Child->Asl.CommentList = NULL;
    317 
    318             Op->Asl.InlineComment = Child->Asl.InlineComment;
    319             Child->Asl.InlineComment = NULL;
    320         }
    321 
    322         /*
    323          * This child might be a list, point all ops in the list
    324          * to the same parent
    325          */
    326         while (Child->Asl.Next)
    327         {
    328             Child = Child->Asl.Next;
    329             Child->Asl.Parent = Op;
    330         }
    331 
    332         PrevChild = Child;
    333     }
    334 
    335     va_end(ap);
    336     DbgPrint (ASL_PARSE_OUTPUT, "\n");
    337     return (Op);
    338 }
    339 
    340 
    341 /*******************************************************************************
    342  *
    343  * FUNCTION:    TrCreateLeafOp
    344  *
    345  * PARAMETERS:  ParseOpcode         - New opcode to be assigned to the op
    346  *
    347  * RETURN:      Pointer to the new op. Aborts on allocation failure
    348  *
    349  * DESCRIPTION: Create a simple leaf op (no children or peers, and no value
    350  *              assigned to the op)
    351  *
    352  ******************************************************************************/
    353 
    354 ACPI_PARSE_OBJECT *
    355 TrCreateLeafOp (
    356     UINT32                  ParseOpcode)
    357 {
    358     ACPI_PARSE_OBJECT       *Op;
    359 
    360 
    361     Op = TrAllocateOp (ParseOpcode);
    362 
    363     DbgPrint (ASL_PARSE_OUTPUT,
    364         "\nCreateLeafOp  Ln/Col %u/%u NewOp %p  Op %s\n\n",
    365         Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName (ParseOpcode));
    366 
    367     return (Op);
    368 }
    369 
    370 
    371 /*******************************************************************************
    372  *
    373  * FUNCTION:    TrCreateValuedLeafOp
    374  *
    375  * PARAMETERS:  ParseOpcode         - New opcode to be assigned to the op
    376  *              Value               - Value to be assigned to the op
    377  *
    378  * RETURN:      Pointer to the new op. Aborts on allocation failure
    379  *
    380  * DESCRIPTION: Create a leaf op (no children or peers) with a value
    381  *              assigned to it
    382  *
    383  ******************************************************************************/
    384 
    385 ACPI_PARSE_OBJECT *
    386 TrCreateValuedLeafOp (
    387     UINT32                  ParseOpcode,
    388     UINT64                  Value)
    389 {
    390     ACPI_PARSE_OBJECT       *Op;
    391     UINT32                  i;
    392     char                    *StringPtr = NULL;
    393 
    394 
    395     Op = TrAllocateOp (ParseOpcode);
    396     Op->Asl.Value.Integer = Value;
    397 
    398     DbgPrint (ASL_PARSE_OUTPUT,
    399         "\nCreateValuedLeafOp  Ln/Col %u/%u NewOp %p  "
    400         "Op %s  Value %8.8X%8.8X  ",
    401         Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName(ParseOpcode),
    402         ACPI_FORMAT_UINT64 (Value));
    403 
    404     switch (ParseOpcode)
    405     {
    406     case PARSEOP_STRING_LITERAL:
    407 
    408         DbgPrint (ASL_PARSE_OUTPUT, "STRING->%s", Op->Asl.Value.String);
    409         break;
    410 
    411     case PARSEOP_NAMESEG:
    412 
    413         /* Check for mixed case (or all lower case). Issue a remark in this case */
    414 
    415         for (i = 0; i < ACPI_NAMESEG_SIZE; i++)
    416         {
    417             if (islower ((int) Op->Asl.Value.Name[i]))
    418             {
    419                 AcpiUtStrupr (&Op->Asl.Value.Name[i]);
    420                 AslError (ASL_REMARK, ASL_MSG_LOWER_CASE_NAMESEG, Op, Op->Asl.Value.Name);
    421                 break;
    422             }
    423         }
    424         DbgPrint (ASL_PARSE_OUTPUT, "NAMESEG->%s", Op->Asl.Value.String);
    425         break;
    426 
    427     case PARSEOP_NAMESTRING:
    428 
    429         /* Check for mixed case (or all lower case). Issue a remark in this case */
    430 
    431         StringPtr = Op->Asl.Value.Name;
    432         for (i = 0; *StringPtr; i++)
    433         {
    434             if (islower ((int) *StringPtr))
    435             {
    436                 AcpiUtStrupr (&Op->Asl.Value.Name[i]);
    437                 AslError (ASL_REMARK, ASL_MSG_LOWER_CASE_NAMEPATH, Op, Op->Asl.Value.Name);
    438                 break;
    439             }
    440             StringPtr++;
    441         }
    442         DbgPrint (ASL_PARSE_OUTPUT, "NAMESTRING->%s", Op->Asl.Value.String);
    443         break;
    444 
    445     case PARSEOP_EISAID:
    446 
    447         DbgPrint (ASL_PARSE_OUTPUT, "EISAID->%s", Op->Asl.Value.String);
    448         break;
    449 
    450     case PARSEOP_METHOD:
    451 
    452         DbgPrint (ASL_PARSE_OUTPUT, "METHOD");
    453         break;
    454 
    455     case PARSEOP_INTEGER:
    456 
    457         DbgPrint (ASL_PARSE_OUTPUT, "INTEGER->%8.8X%8.8X",
    458             ACPI_FORMAT_UINT64 (Value));
    459         break;
    460 
    461     default:
    462         break;
    463     }
    464 
    465     DbgPrint (ASL_PARSE_OUTPUT, "\n\n");
    466     return (Op);
    467 }
    468 
    469 
    470 /*******************************************************************************
    471  *
    472  * FUNCTION:    TrCreateTargetOp
    473  *
    474  * PARAMETERS:  OriginalOp          - Op to be copied
    475  *
    476  * RETURN:      Pointer to the new op. Aborts on allocation failure
    477  *
    478  * DESCRIPTION: Copy an existing op (and subtree). Used in ASL+ (C-style)
    479  *              expressions where the target is the same as one of the
    480  *              operands. A new op and subtree must be created from the
    481  *              original so that the parse tree can be linked properly.
    482  *
    483  * NOTE:        This code is specific to target operands that are the last
    484  *              operand in an ASL/AML operator. Meaning that the top-level
    485  *              parse Op in a possible subtree has a NULL Next pointer.
    486  *              This simplifies the recursion.
    487  *
    488  *              Subtree example:
    489  *                  DeRefOf (Local1) += 32
    490  *
    491  *              This gets converted to:
    492  *                  Add (DeRefOf (Local1), 32, DeRefOf (Local1))
    493  *
    494  *              Each DeRefOf has a single child, Local1. Even more complex
    495  *              subtrees can be created via the Index and DeRefOf operators.
    496  *
    497  ******************************************************************************/
    498 
    499 ACPI_PARSE_OBJECT *
    500 TrCreateTargetOp (
    501     ACPI_PARSE_OBJECT       *OriginalOp,
    502     ACPI_PARSE_OBJECT       *ParentOp)
    503 {
    504     ACPI_PARSE_OBJECT       *Op;
    505 
    506 
    507     if (!OriginalOp)
    508     {
    509         return (NULL);
    510     }
    511 
    512     Op = UtParseOpCacheCalloc ();
    513 
    514     /* Copy the pertinent values (omit link pointer fields) */
    515 
    516     Op->Asl.Value               = OriginalOp->Asl.Value;
    517     Op->Asl.Filename            = OriginalOp->Asl.Filename;
    518     Op->Asl.LineNumber          = OriginalOp->Asl.LineNumber;
    519     Op->Asl.LogicalLineNumber   = OriginalOp->Asl.LogicalLineNumber;
    520     Op->Asl.LogicalByteOffset   = OriginalOp->Asl.LogicalByteOffset;
    521     Op->Asl.Column              = OriginalOp->Asl.Column;
    522     Op->Asl.Flags               = OriginalOp->Asl.Flags;
    523     Op->Asl.CompileFlags        = OriginalOp->Asl.CompileFlags;
    524     Op->Asl.AmlOpcode           = OriginalOp->Asl.AmlOpcode;
    525     Op->Asl.ParseOpcode         = OriginalOp->Asl.ParseOpcode;
    526     Op->Asl.Parent              = ParentOp;
    527 
    528     UtSetParseOpName (Op);
    529 
    530     /* Copy a possible subtree below this op */
    531 
    532     if (OriginalOp->Asl.Child)
    533     {
    534         Op->Asl.Child = TrCreateTargetOp (OriginalOp->Asl.Child, Op);
    535     }
    536 
    537     if (OriginalOp->Asl.Next) /* Null for top-level op */
    538     {
    539         Op->Asl.Next = TrCreateTargetOp (OriginalOp->Asl.Next, ParentOp);
    540     }
    541 
    542     return (Op);
    543 }
    544 
    545 
    546 /*******************************************************************************
    547  *
    548  * FUNCTION:    TrCreateAssignmentOp
    549  *
    550  * PARAMETERS:  Target              - Assignment target
    551  *              Source              - Assignment source
    552  *
    553  * RETURN:      Pointer to the new op. Aborts on allocation failure
    554  *
    555  * DESCRIPTION: Implements the C-style '=' operator. It changes the parse
    556  *              tree if possible to utilize the last argument of the math
    557  *              operators which is a target operand -- thus saving invocation
    558  *              of and additional Store() operator. An optimization.
    559  *
    560  ******************************************************************************/
    561 
    562 ACPI_PARSE_OBJECT *
    563 TrCreateAssignmentOp (
    564     ACPI_PARSE_OBJECT       *Target,
    565     ACPI_PARSE_OBJECT       *Source)
    566 {
    567     ACPI_PARSE_OBJECT       *TargetOp;
    568     ACPI_PARSE_OBJECT       *SourceOp1;
    569     ACPI_PARSE_OBJECT       *SourceOp2;
    570     ACPI_PARSE_OBJECT       *Operator;
    571 
    572 
    573     DbgPrint (ASL_PARSE_OUTPUT,
    574         "\nTrCreateAssignmentOp  Line [%u to %u] Source %s Target %s\n",
    575         Source->Asl.LineNumber, Source->Asl.EndLine,
    576         UtGetOpName (Source->Asl.ParseOpcode),
    577         UtGetOpName (Target->Asl.ParseOpcode));
    578 
    579     TrSetOpFlags (Target, OP_IS_TARGET);
    580 
    581     switch (Source->Asl.ParseOpcode)
    582     {
    583     /*
    584      * Only these operators can be optimized because they have
    585      * a target operand
    586      */
    587     case PARSEOP_ADD:
    588     case PARSEOP_AND:
    589     case PARSEOP_DIVIDE:
    590     case PARSEOP_INDEX:
    591     case PARSEOP_MOD:
    592     case PARSEOP_MULTIPLY:
    593     case PARSEOP_NOT:
    594     case PARSEOP_OR:
    595     case PARSEOP_SHIFTLEFT:
    596     case PARSEOP_SHIFTRIGHT:
    597     case PARSEOP_SUBTRACT:
    598     case PARSEOP_XOR:
    599 
    600         break;
    601 
    602     /* Otherwise, just create a normal Store operator */
    603 
    604     default:
    605         goto CannotOptimize;
    606     }
    607 
    608     /*
    609      * Transform the parse tree such that the target is moved to the
    610      * last operand of the operator
    611      */
    612     SourceOp1 = Source->Asl.Child;
    613     SourceOp2 = SourceOp1->Asl.Next;
    614 
    615     /* NOT only has one operand, but has a target */
    616 
    617     if (Source->Asl.ParseOpcode == PARSEOP_NOT)
    618     {
    619         SourceOp2 = SourceOp1;
    620     }
    621 
    622     /* DIVIDE has an extra target operand (remainder) */
    623 
    624     if (Source->Asl.ParseOpcode == PARSEOP_DIVIDE)
    625     {
    626         SourceOp2 = SourceOp2->Asl.Next;
    627     }
    628 
    629     TargetOp = SourceOp2->Asl.Next;
    630 
    631     /*
    632      * Can't perform this optimization if there already is a target
    633      * for the operator (ZERO is a "no target" placeholder).
    634      */
    635     if (TargetOp->Asl.ParseOpcode != PARSEOP_ZERO)
    636     {
    637         goto CannotOptimize;
    638     }
    639 
    640     /* Link in the target as the final operand */
    641 
    642     SourceOp2->Asl.Next = Target;
    643     Target->Asl.Parent = Source;
    644     return (Source);
    645 
    646 
    647 CannotOptimize:
    648 
    649     Operator = TrAllocateOp (PARSEOP_STORE);
    650     TrLinkOpChildren (Operator, 2, Source, Target);
    651 
    652     /* Set the appropriate line numbers for the new op */
    653 
    654     Operator->Asl.LineNumber        = Target->Asl.LineNumber;
    655     Operator->Asl.LogicalLineNumber = Target->Asl.LogicalLineNumber;
    656     Operator->Asl.LogicalByteOffset = Target->Asl.LogicalByteOffset;
    657     Operator->Asl.Column            = Target->Asl.Column;
    658 
    659     return (Operator);
    660 }
    661 
    662 
    663 /*******************************************************************************
    664  *
    665  * FUNCTION:    TrCreateNullTargetOp
    666  *
    667  * PARAMETERS:  None
    668  *
    669  * RETURN:      Pointer to the new op. Aborts on allocation failure
    670  *
    671  * DESCRIPTION: Create a "null" target op. This is defined by the ACPI
    672  *              specification to be a zero AML opcode, and indicates that
    673  *              no target has been specified for the parent operation
    674  *
    675  ******************************************************************************/
    676 
    677 ACPI_PARSE_OBJECT *
    678 TrCreateNullTargetOp (
    679     void)
    680 {
    681     ACPI_PARSE_OBJECT       *Op;
    682 
    683 
    684     Op = TrAllocateOp (PARSEOP_ZERO);
    685     Op->Asl.CompileFlags |= (OP_IS_TARGET | OP_COMPILE_TIME_CONST);
    686 
    687     DbgPrint (ASL_PARSE_OUTPUT,
    688         "\nCreateNullTargetOp  Ln/Col %u/%u NewOp %p  Op %s\n",
    689         Op->Asl.LineNumber, Op->Asl.Column, Op,
    690         UtGetOpName (Op->Asl.ParseOpcode));
    691 
    692     return (Op);
    693 }
    694 
    695 
    696 /*******************************************************************************
    697  *
    698  * FUNCTION:    TrCreateConstantLeafOp
    699  *
    700  * PARAMETERS:  ParseOpcode         - The constant opcode
    701  *
    702  * RETURN:      Pointer to the new op. Aborts on allocation failure
    703  *
    704  * DESCRIPTION: Create a leaf op (no children or peers) for one of the
    705  *              special constants - __LINE__, __FILE__, and __DATE__.
    706  *
    707  * Note: The fullimplemenation of __METHOD__ cannot happen here because we
    708  * don't have a full parse tree at this time and cannot find the parent
    709  * control method. __METHOD__ must be implemented later, after the parse
    710  * tree has been fully constructed.
    711  *
    712  ******************************************************************************/
    713 
    714 ACPI_PARSE_OBJECT *
    715 TrCreateConstantLeafOp (
    716     UINT32                  ParseOpcode)
    717 {
    718     ACPI_PARSE_OBJECT       *Op = NULL;
    719     time_t                  CurrentTime;
    720     char                    *StaticTimeString;
    721     char                    *TimeString;
    722     char                    *Filename = NULL;
    723     ACPI_STATUS             Status;
    724 
    725 
    726     switch (ParseOpcode)
    727     {
    728     case PARSEOP___LINE__:
    729 
    730         Op = TrAllocateOp (PARSEOP_INTEGER);
    731         Op->Asl.Value.Integer = Op->Asl.LineNumber;
    732         break;
    733 
    734     case PARSEOP___METHOD__:
    735 
    736         /* Will become a string literal later */
    737 
    738         Op = TrAllocateOp (PARSEOP___METHOD__);
    739         Op->Asl.Value.String = NULL;
    740         break;
    741 
    742     case PARSEOP___PATH__:
    743 
    744         Op = TrAllocateOp (PARSEOP_STRING_LITERAL);
    745 
    746         /* Op.Asl.Filename contains the full pathname to the file */
    747 
    748         Op->Asl.Value.String = Op->Asl.Filename;
    749         break;
    750 
    751     case PARSEOP___FILE__:
    752 
    753         Op = TrAllocateOp (PARSEOP_STRING_LITERAL);
    754 
    755         /* Get the simple filename from the full path */
    756 
    757         Status = FlSplitInputPathname (Op->Asl.Filename, NULL, &Filename);
    758         if (ACPI_FAILURE (Status))
    759         {
    760             return (NULL);
    761         }
    762 
    763         Op->Asl.Value.String = Filename;
    764         break;
    765 
    766     case PARSEOP___DATE__:
    767 
    768         Op = TrAllocateOp (PARSEOP_STRING_LITERAL);
    769 
    770         /* Get a copy of the current time */
    771 
    772         Op->Asl.Value.String = "";
    773         CurrentTime = time (NULL);
    774 
    775         StaticTimeString = ctime (&CurrentTime);
    776         if (StaticTimeString)
    777         {
    778             TimeString = UtLocalCalloc (strlen (StaticTimeString) + 1);
    779             strcpy (TimeString, StaticTimeString);
    780 
    781             TimeString[strlen(TimeString) -1] = 0;  /* Remove trailing newline */
    782             Op->Asl.Value.String = TimeString;
    783         }
    784         break;
    785 
    786     default: /* This would be an internal error */
    787 
    788         return (NULL);
    789     }
    790 
    791     DbgPrint (ASL_PARSE_OUTPUT,
    792         "\nCreateConstantLeafOp  Ln/Col %u/%u NewOp %p  "
    793         "Op %s  Value %8.8X%8.8X\n",
    794         Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName (ParseOpcode),
    795         ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
    796 
    797     return (Op);
    798 }
    799 
    800 
    801 /*******************************************************************************
    802  *
    803  * FUNCTION:    TrAllocateOp
    804  *
    805  * PARAMETERS:  ParseOpcode         - Opcode to be assigned to the op
    806  *
    807  * RETURN:      New parse op. Aborts on allocation failure
    808  *
    809  * DESCRIPTION: Allocate and initialize a new parse op for the parse tree
    810  *
    811  ******************************************************************************/
    812 
    813 ACPI_PARSE_OBJECT *
    814 TrAllocateOp (
    815     UINT32                  ParseOpcode)
    816 {
    817     ACPI_PARSE_OBJECT       *Op;
    818     ACPI_PARSE_OBJECT       *LatestOp;
    819 
    820     ACPI_FUNCTION_NAME (TrAllocateOp);
    821 
    822 
    823     Op = UtParseOpCacheCalloc ();
    824 
    825     Op->Asl.ParseOpcode       = (UINT16) ParseOpcode;
    826     Op->Asl.Filename          = AslGbl_Files[ASL_FILE_INPUT].Filename;
    827     Op->Asl.LineNumber        = AslGbl_CurrentLineNumber;
    828     Op->Asl.LogicalLineNumber = AslGbl_LogicalLineNumber;
    829     Op->Asl.LogicalByteOffset = AslGbl_CurrentLineOffset;
    830     Op->Asl.Column            = AslGbl_CurrentColumn;
    831 
    832     UtSetParseOpName (Op);
    833 
    834     /* The following is for capturing comments */
    835 
    836     if (AcpiGbl_CaptureComments)
    837     {
    838         LatestOp = AslGbl_CommentState.LatestParseOp;
    839         Op->Asl.InlineComment     = NULL;
    840         Op->Asl.EndNodeComment    = NULL;
    841         Op->Asl.CommentList       = NULL;
    842         Op->Asl.FileChanged       = FALSE;
    843 
    844         /*
    845          * Check to see if the file name has changed before resetting the
    846          * latest parse op.
    847          */
    848         if (LatestOp &&
    849             (ParseOpcode != PARSEOP_INCLUDE) &&
    850             (ParseOpcode != PARSEOP_INCLUDE_END) &&
    851             strcmp (LatestOp->Asl.Filename, Op->Asl.Filename))
    852         {
    853             CvDbgPrint ("latest op: %s\n", LatestOp->Asl.ParseOpName);
    854             Op->Asl.FileChanged = TRUE;
    855             if (AslGbl_IncludeFileStack)
    856             {
    857                 Op->Asl.ParentFilename = AslGbl_IncludeFileStack->Filename;
    858             }
    859             else
    860             {
    861                 Op->Asl.ParentFilename = NULL;
    862             }
    863         }
    864 
    865         AslGbl_CommentState.LatestParseOp = Op;
    866         CvDbgPrint ("%s=Set latest parse op to this op.\n",  ACPI_GET_FUNCTION_NAME);
    867         CvDbgPrint ("           Op->Asl.ParseOpName = %s\n",
    868             AslGbl_CommentState.LatestParseOp->Asl.ParseOpName);
    869         CvDbgPrint ("           Op->Asl.ParseOpcode = 0x%x\n", ParseOpcode);
    870 
    871         if (Op->Asl.FileChanged)
    872         {
    873             CvDbgPrint("    file has been changed!\n");
    874         }
    875 
    876         /*
    877          * if this parse op's syntax uses () and {} (i.e. Package(1){0x00}) then
    878          * set a flag in the comment state. This facilitates paring comments for
    879          * these types of opcodes.
    880          */
    881         if ((CvParseOpBlockType(Op) == (BLOCK_PAREN | BLOCK_BRACE)) &&
    882             (ParseOpcode != PARSEOP_DEFINITION_BLOCK))
    883         {
    884             CvDbgPrint ("Parsing paren/Brace op now!\n");
    885             AslGbl_CommentState.ParsingParenBraceNode = Op;
    886         }
    887 
    888         if (AslGbl_CommentListHead)
    889         {
    890             CvDbgPrint ("Transferring...\n");
    891             Op->Asl.CommentList = AslGbl_CommentListHead;
    892             AslGbl_CommentListHead = NULL;
    893             AslGbl_CommentListTail = NULL;
    894             CvDbgPrint ("    Transferred current comment list to this op.\n");
    895             CvDbgPrint ("    %s\n", Op->Asl.CommentList->Comment);
    896         }
    897 
    898         if (AslGbl_InlineCommentBuffer)
    899         {
    900             Op->Asl.InlineComment = AslGbl_InlineCommentBuffer;
    901             AslGbl_InlineCommentBuffer = NULL;
    902             CvDbgPrint ("Transferred current inline comment list to this op.\n");
    903         }
    904     }
    905 
    906     return (Op);
    907 }
    908 
    909 
    910 /*******************************************************************************
    911  *
    912  * FUNCTION:    TrPrintOpFlags
    913  *
    914  * PARAMETERS:  Flags               - Flags word to be decoded
    915  *              OutputLevel         - Debug output level: ASL_TREE_OUTPUT etc.
    916  *
    917  * RETURN:      None
    918  *
    919  * DESCRIPTION: Decode a flags word to text. Displays all flags that are set.
    920  *
    921  ******************************************************************************/
    922 
    923 void
    924 TrPrintOpFlags (
    925     UINT32                  Flags,
    926     UINT32                  OutputLevel)
    927 {
    928     UINT32                  FlagBit = 1;
    929     UINT32                  i;
    930 
    931 
    932     for (i = 0; i < ACPI_NUM_OP_FLAGS; i++)
    933     {
    934         if (Flags & FlagBit)
    935         {
    936             DbgPrint (OutputLevel, " %s", AslGbl_OpFlagNames[i]);
    937         }
    938 
    939         FlagBit <<= 1;
    940     }
    941 }
    942