| /****************************************************************************** |
| * |
| * Module Name: aslparseop - Parse op create/allocate/cache interfaces |
| * |
| *****************************************************************************/ |
| |
| /* |
| * Copyright (C) 2000 - 2023, Intel Corp. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions, and the following disclaimer, |
| * without modification. |
| * 2. Redistributions in binary form must reproduce at minimum a disclaimer |
| * substantially similar to the "NO WARRANTY" disclaimer below |
| * ("Disclaimer") and any redistribution must be conditioned upon |
| * including a substantially similar Disclaimer requirement for further |
| * binary redistribution. |
| * 3. Neither the names of the above-listed copyright holders nor the names |
| * of any contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * Alternatively, this software may be distributed under the terms of the |
| * GNU General Public License ("GPL") version 2 as published by the Free |
| * Software Foundation. |
| * |
| * NO WARRANTY |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
| * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGES. |
| */ |
| |
| #include "aslcompiler.h" |
| #include "aslcompiler.y.h" |
| #include "acapps.h" |
| #include "acconvert.h" |
| |
| #define _COMPONENT ACPI_COMPILER |
| ACPI_MODULE_NAME ("aslparseop") |
| |
| |
| /******************************************************************************* |
| * |
| * FUNCTION: TrCreateOp |
| * |
| * PARAMETERS: ParseOpcode - Opcode to be assigned to the op |
| * NumChildren - Number of children to follow |
| * ... - A list of child ops to link to the new |
| * op. NumChildren long. |
| * |
| * RETURN: Pointer to the new op. Aborts on allocation failure |
| * |
| * DESCRIPTION: Create a new parse op and link together a list of child |
| * ops underneath the new op. |
| * |
| ******************************************************************************/ |
| |
| ACPI_PARSE_OBJECT * |
| TrCreateOp ( |
| UINT32 ParseOpcode, |
| UINT32 NumChildren, |
| ...) |
| { |
| ACPI_PARSE_OBJECT *Op; |
| ACPI_PARSE_OBJECT *Child; |
| ACPI_PARSE_OBJECT *PrevChild; |
| va_list ap; |
| UINT32 i; |
| BOOLEAN FirstChild; |
| |
| |
| va_start (ap, NumChildren); |
| |
| /* Allocate one new op */ |
| |
| Op = TrAllocateOp (ParseOpcode); |
| |
| DbgPrint (ASL_PARSE_OUTPUT, |
| "\nCreateOp Ln/Col %u/%u NewParent %p Child %u Op %s ", |
| Op->Asl.LineNumber, Op->Asl.Column, Op, |
| NumChildren, UtGetOpName(ParseOpcode)); |
| |
| /* Some extra debug output based on the parse opcode */ |
| |
| switch (ParseOpcode) |
| { |
| case PARSEOP_ASL_CODE: |
| |
| AslGbl_ParseTreeRoot = Op; |
| Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; |
| DbgPrint (ASL_PARSE_OUTPUT, "ASLCODE (Tree Completed)->"); |
| break; |
| |
| case PARSEOP_DEFINITION_BLOCK: |
| |
| DbgPrint (ASL_PARSE_OUTPUT, "DEFINITION_BLOCK (Tree Completed)->"); |
| break; |
| |
| case PARSEOP_OPERATIONREGION: |
| |
| DbgPrint (ASL_PARSE_OUTPUT, "OPREGION->"); |
| break; |
| |
| case PARSEOP_OR: |
| |
| DbgPrint (ASL_PARSE_OUTPUT, "OR->"); |
| break; |
| |
| default: |
| |
| /* Nothing to do for other opcodes */ |
| |
| break; |
| } |
| |
| /* Link the new op to its children */ |
| |
| PrevChild = NULL; |
| FirstChild = TRUE; |
| for (i = 0; i < NumChildren; i++) |
| { |
| /* Get the next child */ |
| |
| Child = va_arg (ap, ACPI_PARSE_OBJECT *); |
| DbgPrint (ASL_PARSE_OUTPUT, "%p, ", Child); |
| |
| /* |
| * If child is NULL, this means that an optional argument |
| * was omitted. We must create a placeholder with a special |
| * opcode (DEFAULT_ARG) so that the code generator will know |
| * that it must emit the correct default for this argument |
| */ |
| if (!Child) |
| { |
| Child = TrAllocateOp (PARSEOP_DEFAULT_ARG); |
| } |
| |
| /* Link first child to parent */ |
| |
| if (FirstChild) |
| { |
| FirstChild = FALSE; |
| Op->Asl.Child = Child; |
| |
| /* |
| * For the ASL-/ASL+ converter: if the ParseOp is a Connection, |
| * External, Offset or AccessAs, it means that the comments in the |
| * FirstChild belongs to their parent due to the parsing order in |
| * the .y files. To correct this, take the comments in the |
| * FirstChild place it in the parent. This also means that |
| * legitimate comments for the child gets put to the parent. |
| */ |
| if (AcpiGbl_CaptureComments && |
| ((ParseOpcode == PARSEOP_CONNECTION) || |
| (ParseOpcode == PARSEOP_EXTERNAL) || |
| (ParseOpcode == PARSEOP_OFFSET) || |
| (ParseOpcode == PARSEOP_ACCESSAS))) |
| { |
| Op->Asl.CommentList = Child->Asl.CommentList; |
| Op->Asl.EndBlkComment = Child->Asl.EndBlkComment; |
| Op->Asl.InlineComment = Child->Asl.InlineComment; |
| Op->Asl.FileChanged = Child->Asl.FileChanged; |
| |
| Child->Asl.CommentList = NULL; |
| Child->Asl.EndBlkComment = NULL; |
| Child->Asl.InlineComment = NULL; |
| Child->Asl.FileChanged = FALSE; |
| |
| /* |
| * These do not need to be "passed off". They can be copied |
| * because the code for these opcodes should be printed in the |
| * same file. |
| */ |
| Op->Asl.Filename = Child->Asl.Filename; |
| Op->Asl.ParentFilename = Child->Asl.ParentFilename; |
| } |
| } |
| |
| /* Point all children to parent */ |
| |
| Child->Asl.Parent = Op; |
| |
| /* Link children in a peer list */ |
| |
| if (PrevChild) |
| { |
| PrevChild->Asl.Next = Child; |
| }; |
| |
| /* Get the comment from last child in the resource template call */ |
| |
| if (AcpiGbl_CaptureComments && |
| (Op->Asl.ParseOpcode == PARSEOP_RESOURCETEMPLATE)) |
| { |
| CvDbgPrint ("Transferred current comment list to this op.\n"); |
| Op->Asl.CommentList = Child->Asl.CommentList; |
| Child->Asl.CommentList = NULL; |
| |
| Op->Asl.InlineComment = Child->Asl.InlineComment; |
| Child->Asl.InlineComment = NULL; |
| } |
| |
| /* |
| * This child might be a list, point all ops in the list |
| * to the same parent |
| */ |
| while (Child->Asl.Next) |
| { |
| Child = Child->Asl.Next; |
| Child->Asl.Parent = Op; |
| } |
| |
| PrevChild = Child; |
| } |
| |
| va_end(ap); |
| DbgPrint (ASL_PARSE_OUTPUT, "\n"); |
| return (Op); |
| } |
| |
| |
| /******************************************************************************* |
| * |
| * FUNCTION: TrCreateLeafOp |
| * |
| * PARAMETERS: ParseOpcode - New opcode to be assigned to the op |
| * |
| * RETURN: Pointer to the new op. Aborts on allocation failure |
| * |
| * DESCRIPTION: Create a simple leaf op (no children or peers, and no value |
| * assigned to the op) |
| * |
| ******************************************************************************/ |
| |
| ACPI_PARSE_OBJECT * |
| TrCreateLeafOp ( |
| UINT32 ParseOpcode) |
| { |
| ACPI_PARSE_OBJECT *Op; |
| |
| |
| Op = TrAllocateOp (ParseOpcode); |
| |
| DbgPrint (ASL_PARSE_OUTPUT, |
| "\nCreateLeafOp Ln/Col %u/%u NewOp %p Op %s\n\n", |
| Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName (ParseOpcode)); |
| |
| return (Op); |
| } |
| |
| |
| /******************************************************************************* |
| * |
| * FUNCTION: TrCreateValuedLeafOp |
| * |
| * PARAMETERS: ParseOpcode - New opcode to be assigned to the op |
| * Value - Value to be assigned to the op |
| * |
| * RETURN: Pointer to the new op. Aborts on allocation failure |
| * |
| * DESCRIPTION: Create a leaf op (no children or peers) with a value |
| * assigned to it |
| * |
| ******************************************************************************/ |
| |
| ACPI_PARSE_OBJECT * |
| TrCreateValuedLeafOp ( |
| UINT32 ParseOpcode, |
| UINT64 Value) |
| { |
| ACPI_PARSE_OBJECT *Op; |
| UINT32 i; |
| char *StringPtr = NULL; |
| |
| |
| Op = TrAllocateOp (ParseOpcode); |
| Op->Asl.Value.Integer = Value; |
| |
| DbgPrint (ASL_PARSE_OUTPUT, |
| "\nCreateValuedLeafOp Ln/Col %u/%u NewOp %p " |
| "Op %s Value %8.8X%8.8X ", |
| Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName(ParseOpcode), |
| ACPI_FORMAT_UINT64 (Value)); |
| |
| switch (ParseOpcode) |
| { |
| case PARSEOP_STRING_LITERAL: |
| |
| DbgPrint (ASL_PARSE_OUTPUT, "STRING->%s", Op->Asl.Value.String); |
| break; |
| |
| case PARSEOP_NAMESEG: |
| |
| /* Check for mixed case (or all lower case). Issue a remark in this case */ |
| |
| for (i = 0; i < ACPI_NAMESEG_SIZE; i++) |
| { |
| if (islower ((int) Op->Asl.Value.Name[i])) |
| { |
| AcpiUtStrupr (&Op->Asl.Value.Name[i]); |
| AslError (ASL_REMARK, ASL_MSG_LOWER_CASE_NAMESEG, Op, Op->Asl.Value.Name); |
| break; |
| } |
| } |
| DbgPrint (ASL_PARSE_OUTPUT, "NAMESEG->%s", Op->Asl.Value.String); |
| break; |
| |
| case PARSEOP_NAMESTRING: |
| |
| /* Check for mixed case (or all lower case). Issue a remark in this case */ |
| |
| StringPtr = Op->Asl.Value.Name; |
| for (i = 0; *StringPtr; i++) |
| { |
| if (islower ((int) *StringPtr)) |
| { |
| AcpiUtStrupr (&Op->Asl.Value.Name[i]); |
| AslError (ASL_REMARK, ASL_MSG_LOWER_CASE_NAMEPATH, Op, Op->Asl.Value.Name); |
| break; |
| } |
| StringPtr++; |
| } |
| DbgPrint (ASL_PARSE_OUTPUT, "NAMESTRING->%s", Op->Asl.Value.String); |
| break; |
| |
| case PARSEOP_EISAID: |
| |
| DbgPrint (ASL_PARSE_OUTPUT, "EISAID->%s", Op->Asl.Value.String); |
| break; |
| |
| case PARSEOP_METHOD: |
| |
| DbgPrint (ASL_PARSE_OUTPUT, "METHOD"); |
| break; |
| |
| case PARSEOP_INTEGER: |
| |
| DbgPrint (ASL_PARSE_OUTPUT, "INTEGER->%8.8X%8.8X", |
| ACPI_FORMAT_UINT64 (Value)); |
| break; |
| |
| default: |
| break; |
| } |
| |
| DbgPrint (ASL_PARSE_OUTPUT, "\n\n"); |
| return (Op); |
| } |
| |
| |
| /******************************************************************************* |
| * |
| * FUNCTION: TrCreateTargetOp |
| * |
| * PARAMETERS: OriginalOp - Op to be copied |
| * |
| * RETURN: Pointer to the new op. Aborts on allocation failure |
| * |
| * DESCRIPTION: Copy an existing op (and subtree). Used in ASL+ (C-style) |
| * expressions where the target is the same as one of the |
| * operands. A new op and subtree must be created from the |
| * original so that the parse tree can be linked properly. |
| * |
| * NOTE: This code is specific to target operands that are the last |
| * operand in an ASL/AML operator. Meaning that the top-level |
| * parse Op in a possible subtree has a NULL Next pointer. |
| * This simplifies the recursion. |
| * |
| * Subtree example: |
| * DeRefOf (Local1) += 32 |
| * |
| * This gets converted to: |
| * Add (DeRefOf (Local1), 32, DeRefOf (Local1)) |
| * |
| * Each DeRefOf has a single child, Local1. Even more complex |
| * subtrees can be created via the Index and DeRefOf operators. |
| * |
| ******************************************************************************/ |
| |
| ACPI_PARSE_OBJECT * |
| TrCreateTargetOp ( |
| ACPI_PARSE_OBJECT *OriginalOp, |
| ACPI_PARSE_OBJECT *ParentOp) |
| { |
| ACPI_PARSE_OBJECT *Op; |
| |
| |
| if (!OriginalOp) |
| { |
| return (NULL); |
| } |
| |
| Op = UtParseOpCacheCalloc (); |
| |
| /* Copy the pertinent values (omit link pointer fields) */ |
| |
| Op->Asl.Value = OriginalOp->Asl.Value; |
| Op->Asl.Filename = OriginalOp->Asl.Filename; |
| Op->Asl.LineNumber = OriginalOp->Asl.LineNumber; |
| Op->Asl.LogicalLineNumber = OriginalOp->Asl.LogicalLineNumber; |
| Op->Asl.LogicalByteOffset = OriginalOp->Asl.LogicalByteOffset; |
| Op->Asl.Column = OriginalOp->Asl.Column; |
| Op->Asl.Flags = OriginalOp->Asl.Flags; |
| Op->Asl.CompileFlags = OriginalOp->Asl.CompileFlags; |
| Op->Asl.AmlOpcode = OriginalOp->Asl.AmlOpcode; |
| Op->Asl.ParseOpcode = OriginalOp->Asl.ParseOpcode; |
| Op->Asl.Parent = ParentOp; |
| |
| UtSetParseOpName (Op); |
| |
| /* Copy a possible subtree below this op */ |
| |
| if (OriginalOp->Asl.Child) |
| { |
| Op->Asl.Child = TrCreateTargetOp (OriginalOp->Asl.Child, Op); |
| } |
| |
| if (OriginalOp->Asl.Next) /* Null for top-level op */ |
| { |
| Op->Asl.Next = TrCreateTargetOp (OriginalOp->Asl.Next, ParentOp); |
| } |
| |
| return (Op); |
| } |
| |
| |
| /******************************************************************************* |
| * |
| * FUNCTION: TrCreateAssignmentOp |
| * |
| * PARAMETERS: Target - Assignment target |
| * Source - Assignment source |
| * |
| * RETURN: Pointer to the new op. Aborts on allocation failure |
| * |
| * DESCRIPTION: Implements the C-style '=' operator. It changes the parse |
| * tree if possible to utilize the last argument of the math |
| * operators which is a target operand -- thus saving invocation |
| * of and additional Store() operator. An optimization. |
| * |
| ******************************************************************************/ |
| |
| ACPI_PARSE_OBJECT * |
| TrCreateAssignmentOp ( |
| ACPI_PARSE_OBJECT *Target, |
| ACPI_PARSE_OBJECT *Source) |
| { |
| ACPI_PARSE_OBJECT *TargetOp; |
| ACPI_PARSE_OBJECT *SourceOp1; |
| ACPI_PARSE_OBJECT *SourceOp2; |
| ACPI_PARSE_OBJECT *Operator; |
| |
| |
| DbgPrint (ASL_PARSE_OUTPUT, |
| "\nTrCreateAssignmentOp Line [%u to %u] Source %s Target %s\n", |
| Source->Asl.LineNumber, Source->Asl.EndLine, |
| UtGetOpName (Source->Asl.ParseOpcode), |
| UtGetOpName (Target->Asl.ParseOpcode)); |
| |
| TrSetOpFlags (Target, OP_IS_TARGET); |
| |
| switch (Source->Asl.ParseOpcode) |
| { |
| /* |
| * Only these operators can be optimized because they have |
| * a target operand |
| */ |
| case PARSEOP_ADD: |
| case PARSEOP_AND: |
| case PARSEOP_DIVIDE: |
| case PARSEOP_INDEX: |
| case PARSEOP_MOD: |
| case PARSEOP_MULTIPLY: |
| case PARSEOP_NOT: |
| case PARSEOP_OR: |
| case PARSEOP_SHIFTLEFT: |
| case PARSEOP_SHIFTRIGHT: |
| case PARSEOP_SUBTRACT: |
| case PARSEOP_XOR: |
| |
| break; |
| |
| /* Otherwise, just create a normal Store operator */ |
| |
| default: |
| goto CannotOptimize; |
| } |
| |
| /* |
| * Transform the parse tree such that the target is moved to the |
| * last operand of the operator |
| */ |
| SourceOp1 = Source->Asl.Child; |
| SourceOp2 = SourceOp1->Asl.Next; |
| |
| /* NOT only has one operand, but has a target */ |
| |
| if (Source->Asl.ParseOpcode == PARSEOP_NOT) |
| { |
| SourceOp2 = SourceOp1; |
| } |
| |
| /* DIVIDE has an extra target operand (remainder) */ |
| |
| if (Source->Asl.ParseOpcode == PARSEOP_DIVIDE) |
| { |
| SourceOp2 = SourceOp2->Asl.Next; |
| } |
| |
| TargetOp = SourceOp2->Asl.Next; |
| |
| /* |
| * Can't perform this optimization if there already is a target |
| * for the operator (ZERO is a "no target" placeholder). |
| */ |
| if (TargetOp->Asl.ParseOpcode != PARSEOP_ZERO) |
| { |
| goto CannotOptimize; |
| } |
| |
| /* Link in the target as the final operand */ |
| |
| SourceOp2->Asl.Next = Target; |
| Target->Asl.Parent = Source; |
| return (Source); |
| |
| |
| CannotOptimize: |
| |
| Operator = TrAllocateOp (PARSEOP_STORE); |
| TrLinkOpChildren (Operator, 2, Source, Target); |
| |
| /* Set the appropriate line numbers for the new op */ |
| |
| Operator->Asl.LineNumber = Target->Asl.LineNumber; |
| Operator->Asl.LogicalLineNumber = Target->Asl.LogicalLineNumber; |
| Operator->Asl.LogicalByteOffset = Target->Asl.LogicalByteOffset; |
| Operator->Asl.Column = Target->Asl.Column; |
| |
| return (Operator); |
| } |
| |
| |
| /******************************************************************************* |
| * |
| * FUNCTION: TrCreateNullTargetOp |
| * |
| * PARAMETERS: None |
| * |
| * RETURN: Pointer to the new op. Aborts on allocation failure |
| * |
| * DESCRIPTION: Create a "null" target op. This is defined by the ACPI |
| * specification to be a zero AML opcode, and indicates that |
| * no target has been specified for the parent operation |
| * |
| ******************************************************************************/ |
| |
| ACPI_PARSE_OBJECT * |
| TrCreateNullTargetOp ( |
| void) |
| { |
| ACPI_PARSE_OBJECT *Op; |
| |
| |
| Op = TrAllocateOp (PARSEOP_ZERO); |
| Op->Asl.CompileFlags |= (OP_IS_TARGET | OP_COMPILE_TIME_CONST); |
| |
| DbgPrint (ASL_PARSE_OUTPUT, |
| "\nCreateNullTargetOp Ln/Col %u/%u NewOp %p Op %s\n", |
| Op->Asl.LineNumber, Op->Asl.Column, Op, |
| UtGetOpName (Op->Asl.ParseOpcode)); |
| |
| return (Op); |
| } |
| |
| |
| /******************************************************************************* |
| * |
| * FUNCTION: TrCreateConstantLeafOp |
| * |
| * PARAMETERS: ParseOpcode - The constant opcode |
| * |
| * RETURN: Pointer to the new op. Aborts on allocation failure |
| * |
| * DESCRIPTION: Create a leaf op (no children or peers) for one of the |
| * special constants - __LINE__, __FILE__, and __DATE__. |
| * |
| * Note: The fullimplemenation of __METHOD__ cannot happen here because we |
| * don't have a full parse tree at this time and cannot find the parent |
| * control method. __METHOD__ must be implemented later, after the parse |
| * tree has been fully constructed. |
| * |
| ******************************************************************************/ |
| |
| ACPI_PARSE_OBJECT * |
| TrCreateConstantLeafOp ( |
| UINT32 ParseOpcode) |
| { |
| ACPI_PARSE_OBJECT *Op = NULL; |
| time_t CurrentTime; |
| char *StaticTimeString; |
| char *TimeString; |
| char *Filename = NULL; |
| ACPI_STATUS Status; |
| |
| |
| switch (ParseOpcode) |
| { |
| case PARSEOP___LINE__: |
| |
| Op = TrAllocateOp (PARSEOP_INTEGER); |
| Op->Asl.Value.Integer = Op->Asl.LineNumber; |
| break; |
| |
| case PARSEOP___METHOD__: |
| |
| /* Will become a string literal later */ |
| |
| Op = TrAllocateOp (PARSEOP___METHOD__); |
| Op->Asl.Value.String = NULL; |
| break; |
| |
| case PARSEOP___PATH__: |
| |
| Op = TrAllocateOp (PARSEOP_STRING_LITERAL); |
| |
| /* Op.Asl.Filename contains the full pathname to the file */ |
| |
| Op->Asl.Value.String = Op->Asl.Filename; |
| break; |
| |
| case PARSEOP___FILE__: |
| |
| Op = TrAllocateOp (PARSEOP_STRING_LITERAL); |
| |
| /* Get the simple filename from the full path */ |
| |
| Status = FlSplitInputPathname (Op->Asl.Filename, NULL, &Filename); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (NULL); |
| } |
| |
| Op->Asl.Value.String = Filename; |
| break; |
| |
| case PARSEOP___DATE__: |
| |
| Op = TrAllocateOp (PARSEOP_STRING_LITERAL); |
| |
| /* Get a copy of the current time */ |
| |
| Op->Asl.Value.String = ""; |
| CurrentTime = time (NULL); |
| |
| StaticTimeString = ctime (&CurrentTime); |
| if (StaticTimeString) |
| { |
| TimeString = UtLocalCalloc (strlen (StaticTimeString) + 1); |
| strcpy (TimeString, StaticTimeString); |
| |
| TimeString[strlen(TimeString) -1] = 0; /* Remove trailing newline */ |
| Op->Asl.Value.String = TimeString; |
| } |
| break; |
| |
| default: /* This would be an internal error */ |
| |
| return (NULL); |
| } |
| |
| DbgPrint (ASL_PARSE_OUTPUT, |
| "\nCreateConstantLeafOp Ln/Col %u/%u NewOp %p " |
| "Op %s Value %8.8X%8.8X \n", |
| Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName (ParseOpcode), |
| ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer)); |
| |
| return (Op); |
| } |
| |
| |
| /******************************************************************************* |
| * |
| * FUNCTION: TrAllocateOp |
| * |
| * PARAMETERS: ParseOpcode - Opcode to be assigned to the op |
| * |
| * RETURN: New parse op. Aborts on allocation failure |
| * |
| * DESCRIPTION: Allocate and initialize a new parse op for the parse tree |
| * |
| ******************************************************************************/ |
| |
| ACPI_PARSE_OBJECT * |
| TrAllocateOp ( |
| UINT32 ParseOpcode) |
| { |
| ACPI_PARSE_OBJECT *Op; |
| ACPI_PARSE_OBJECT *LatestOp; |
| |
| ACPI_FUNCTION_NAME (TrAllocateOp); |
| |
| |
| Op = UtParseOpCacheCalloc (); |
| |
| Op->Asl.ParseOpcode = (UINT16) ParseOpcode; |
| Op->Asl.Filename = AslGbl_Files[ASL_FILE_INPUT].Filename; |
| Op->Asl.LineNumber = AslGbl_CurrentLineNumber; |
| Op->Asl.LogicalLineNumber = AslGbl_LogicalLineNumber; |
| Op->Asl.LogicalByteOffset = AslGbl_CurrentLineOffset; |
| Op->Asl.Column = AslGbl_CurrentColumn; |
| |
| UtSetParseOpName (Op); |
| |
| /* The following is for capturing comments */ |
| |
| if (AcpiGbl_CaptureComments) |
| { |
| LatestOp = AslGbl_CommentState.LatestParseOp; |
| Op->Asl.InlineComment = NULL; |
| Op->Asl.EndNodeComment = NULL; |
| Op->Asl.CommentList = NULL; |
| Op->Asl.FileChanged = FALSE; |
| |
| /* |
| * Check to see if the file name has changed before resetting the |
| * latest parse op. |
| */ |
| if (LatestOp && |
| (ParseOpcode != PARSEOP_INCLUDE) && |
| (ParseOpcode != PARSEOP_INCLUDE_END) && |
| strcmp (LatestOp->Asl.Filename, Op->Asl.Filename)) |
| { |
| CvDbgPrint ("latest op: %s\n", LatestOp->Asl.ParseOpName); |
| Op->Asl.FileChanged = TRUE; |
| if (AslGbl_IncludeFileStack) |
| { |
| Op->Asl.ParentFilename = AslGbl_IncludeFileStack->Filename; |
| } |
| else |
| { |
| Op->Asl.ParentFilename = NULL; |
| } |
| } |
| |
| AslGbl_CommentState.LatestParseOp = Op; |
| CvDbgPrint ("%s=Set latest parse op to this op.\n", ACPI_GET_FUNCTION_NAME); |
| CvDbgPrint (" Op->Asl.ParseOpName = %s\n", |
| AslGbl_CommentState.LatestParseOp->Asl.ParseOpName); |
| CvDbgPrint (" Op->Asl.ParseOpcode = 0x%x\n", ParseOpcode); |
| |
| if (Op->Asl.FileChanged) |
| { |
| CvDbgPrint(" file has been changed!\n"); |
| } |
| |
| /* |
| * if this parse op's syntax uses () and {} (i.e. Package(1){0x00}) then |
| * set a flag in the comment state. This facilitates paring comments for |
| * these types of opcodes. |
| */ |
| if ((CvParseOpBlockType(Op) == (BLOCK_PAREN | BLOCK_BRACE)) && |
| (ParseOpcode != PARSEOP_DEFINITION_BLOCK)) |
| { |
| CvDbgPrint ("Parsing paren/Brace op now!\n"); |
| AslGbl_CommentState.ParsingParenBraceNode = Op; |
| } |
| |
| if (AslGbl_CommentListHead) |
| { |
| CvDbgPrint ("Transferring...\n"); |
| Op->Asl.CommentList = AslGbl_CommentListHead; |
| AslGbl_CommentListHead = NULL; |
| AslGbl_CommentListTail = NULL; |
| CvDbgPrint (" Transferred current comment list to this op.\n"); |
| CvDbgPrint (" %s\n", Op->Asl.CommentList->Comment); |
| } |
| |
| if (AslGbl_InlineCommentBuffer) |
| { |
| Op->Asl.InlineComment = AslGbl_InlineCommentBuffer; |
| AslGbl_InlineCommentBuffer = NULL; |
| CvDbgPrint ("Transferred current inline comment list to this op.\n"); |
| } |
| } |
| |
| return (Op); |
| } |
| |
| |
| /******************************************************************************* |
| * |
| * FUNCTION: TrPrintOpFlags |
| * |
| * PARAMETERS: Flags - Flags word to be decoded |
| * OutputLevel - Debug output level: ASL_TREE_OUTPUT etc. |
| * |
| * RETURN: None |
| * |
| * DESCRIPTION: Decode a flags word to text. Displays all flags that are set. |
| * |
| ******************************************************************************/ |
| |
| void |
| TrPrintOpFlags ( |
| UINT32 Flags, |
| UINT32 OutputLevel) |
| { |
| UINT32 FlagBit = 1; |
| UINT32 i; |
| |
| |
| for (i = 0; i < ACPI_NUM_OP_FLAGS; i++) |
| { |
| if (Flags & FlagBit) |
| { |
| DbgPrint (OutputLevel, " %s", AslGbl_OpFlagNames[i]); |
| } |
| |
| FlagBit <<= 1; |
| } |
| } |