summaryrefslogtreecommitdiff
path: root/source/components/disassembler/dmcstyle.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/components/disassembler/dmcstyle.c')
-rw-r--r--source/components/disassembler/dmcstyle.c1690
1 files changed, 845 insertions, 845 deletions
diff --git a/source/components/disassembler/dmcstyle.c b/source/components/disassembler/dmcstyle.c
index 1f14bb936..73d7de2d2 100644
--- a/source/components/disassembler/dmcstyle.c
+++ b/source/components/disassembler/dmcstyle.c
@@ -1,845 +1,845 @@
-/*******************************************************************************
- *
- * Module Name: dmcstyle - Support for C-style operator disassembly
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * 1. Copyright Notice
- *
- * Some or all of this work - Copyright (c) 1999 - 2015, Intel Corp.
- * All rights reserved.
- *
- * 2. License
- *
- * 2.1. This is your license from Intel Corp. under its intellectual property
- * rights. You may have additional license terms from the party that provided
- * you this software, covering your right to use that party's intellectual
- * property rights.
- *
- * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
- * copy of the source code appearing in this file ("Covered Code") an
- * irrevocable, perpetual, worldwide license under Intel's copyrights in the
- * base code distributed originally by Intel ("Original Intel Code") to copy,
- * make derivatives, distribute, use and display any portion of the Covered
- * Code in any form, with the right to sublicense such rights; and
- *
- * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
- * license (with the right to sublicense), under only those claims of Intel
- * patents that are infringed by the Original Intel Code, to make, use, sell,
- * offer to sell, and import the Covered Code and derivative works thereof
- * solely to the minimum extent necessary to exercise the above copyright
- * license, and in no event shall the patent license extend to any additions
- * to or modifications of the Original Intel Code. No other license or right
- * is granted directly or by implication, estoppel or otherwise;
- *
- * The above copyright and patent license is granted only if the following
- * conditions are met:
- *
- * 3. Conditions
- *
- * 3.1. Redistribution of Source with Rights to Further Distribute Source.
- * Redistribution of source code of any substantial portion of the Covered
- * Code or modification with rights to further distribute source must include
- * the above Copyright Notice, the above License, this list of Conditions,
- * and the following Disclaimer and Export Compliance provision. In addition,
- * Licensee must cause all Covered Code to which Licensee contributes to
- * contain a file documenting the changes Licensee made to create that Covered
- * Code and the date of any change. Licensee must include in that file the
- * documentation of any changes made by any predecessor Licensee. Licensee
- * must include a prominent statement that the modification is derived,
- * directly or indirectly, from Original Intel Code.
- *
- * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
- * Redistribution of source code of any substantial portion of the Covered
- * Code or modification without rights to further distribute source must
- * include the following Disclaimer and Export Compliance provision in the
- * documentation and/or other materials provided with distribution. In
- * addition, Licensee may not authorize further sublicense of source of any
- * portion of the Covered Code, and must include terms to the effect that the
- * license from Licensee to its licensee is limited to the intellectual
- * property embodied in the software Licensee provides to its licensee, and
- * not to intellectual property embodied in modifications its licensee may
- * make.
- *
- * 3.3. Redistribution of Executable. Redistribution in executable form of any
- * substantial portion of the Covered Code or modification must reproduce the
- * above Copyright Notice, and the following Disclaimer and Export Compliance
- * provision in the documentation and/or other materials provided with the
- * distribution.
- *
- * 3.4. Intel retains all right, title, and interest in and to the Original
- * Intel Code.
- *
- * 3.5. Neither the name Intel nor any other trademark owned or controlled by
- * Intel shall be used in advertising or otherwise to promote the sale, use or
- * other dealings in products derived from or relating to the Covered Code
- * without prior written authorization from Intel.
- *
- * 4. Disclaimer and Export Compliance
- *
- * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
- * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
- * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
- * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
- * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
- * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
- * PARTICULAR PURPOSE.
- *
- * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
- * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
- * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
- * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
- * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
- * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
- * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
- * LIMITED REMEDY.
- *
- * 4.3. Licensee shall not export, either directly or indirectly, any of this
- * software or system incorporating such software without first obtaining any
- * required license or other approval from the U. S. Department of Commerce or
- * any other agency or department of the United States Government. In the
- * event Licensee exports any such software from the United States or
- * re-exports any such software from a foreign destination, Licensee shall
- * ensure that the distribution and export/re-export of the software is in
- * compliance with all laws, regulations, orders, or other restrictions of the
- * U.S. Export Administration Regulations. Licensee agrees that neither it nor
- * any of its subsidiaries will export/re-export any technical data, process,
- * software, or service, directly or indirectly, to any country for which the
- * United States government or any agency thereof requires an export license,
- * other governmental approval, or letter of assurance, without first obtaining
- * such license, approval or letter.
- *
- *****************************************************************************/
-
-#include "acpi.h"
-#include "accommon.h"
-#include "acparser.h"
-#include "amlcode.h"
-#include "acdisasm.h"
-#include "acdebug.h"
-
-#ifdef ACPI_DISASSEMBLER
-
-#define _COMPONENT ACPI_CA_DEBUGGER
- ACPI_MODULE_NAME ("dmcstyle")
-
-
-/* Local prototypes */
-
-static char *
-AcpiDmGetCompoundSymbol (
- UINT16 AslOpcode);
-
-static void
-AcpiDmPromoteTarget (
- ACPI_PARSE_OBJECT *Op,
- ACPI_PARSE_OBJECT *Target);
-
-static BOOLEAN
-AcpiDmIsValidTarget (
- ACPI_PARSE_OBJECT *Op);
-
-static BOOLEAN
-AcpiDmIsTargetAnOperand (
- ACPI_PARSE_OBJECT *Target,
- ACPI_PARSE_OBJECT *Operand,
- BOOLEAN TopLevel);
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiDmCheckForSymbolicOpcode
- *
- * PARAMETERS: Op - Current parse object
- * Walk - Current parse tree walk info
- *
- * RETURN: TRUE if opcode can be converted to symbolic, FALSE otherwise
- *
- * DESCRIPTION: This is the main code that implements disassembly of AML code
- * to C-style operators. Called during descending phase of the
- * parse tree walk.
- *
- ******************************************************************************/
-
-BOOLEAN
-AcpiDmCheckForSymbolicOpcode (
- ACPI_PARSE_OBJECT *Op,
- ACPI_OP_WALK_INFO *Info)
-{
- char *OperatorSymbol = NULL;
- ACPI_PARSE_OBJECT *Child1;
- ACPI_PARSE_OBJECT *Child2;
- ACPI_PARSE_OBJECT *Target;
-
-
- /* Exit immediately if ASL+ not enabled */
-
- if (!AcpiGbl_CstyleDisassembly)
- {
- return (FALSE);
- }
-
- /* Get the first operand */
-
- Child1 = AcpiPsGetArg (Op, 0);
- if (!Child1)
- {
- return (FALSE);
- }
-
- /* Get the second operand */
-
- Child2 = Child1->Common.Next;
-
- /* Setup the operator string for this opcode */
-
- switch (Op->Common.AmlOpcode)
- {
- case AML_ADD_OP:
- OperatorSymbol = " + ";
- break;
-
- case AML_SUBTRACT_OP:
- OperatorSymbol = " - ";
- break;
-
- case AML_MULTIPLY_OP:
- OperatorSymbol = " * ";
- break;
-
- case AML_DIVIDE_OP:
- OperatorSymbol = " / ";
- break;
-
- case AML_MOD_OP:
- OperatorSymbol = " % ";
- break;
-
- case AML_SHIFT_LEFT_OP:
- OperatorSymbol = " << ";
- break;
-
- case AML_SHIFT_RIGHT_OP:
- OperatorSymbol = " >> ";
- break;
-
- case AML_BIT_AND_OP:
- OperatorSymbol = " & ";
- break;
-
- case AML_BIT_OR_OP:
- OperatorSymbol = " | ";
- break;
-
- case AML_BIT_XOR_OP:
- OperatorSymbol = " ^ ";
- break;
-
- /* Logical operators, no target */
-
- case AML_LAND_OP:
- OperatorSymbol = " && ";
- break;
-
- case AML_LEQUAL_OP:
- OperatorSymbol = " == ";
- break;
-
- case AML_LGREATER_OP:
- OperatorSymbol = " > ";
- break;
-
- case AML_LLESS_OP:
- OperatorSymbol = " < ";
- break;
-
- case AML_LOR_OP:
- OperatorSymbol = " || ";
- break;
-
- case AML_LNOT_OP:
- /*
- * Check for the LNOT sub-opcodes. These correspond to
- * LNotEqual, LLessEqual, and LGreaterEqual. There are
- * no actual AML opcodes for these operators.
- */
- switch (Child1->Common.AmlOpcode)
- {
- case AML_LEQUAL_OP:
- OperatorSymbol = " != ";
- break;
-
- case AML_LGREATER_OP:
- OperatorSymbol = " <= ";
- break;
-
- case AML_LLESS_OP:
- OperatorSymbol = " >= ";
- break;
-
- default:
-
- /* Unary LNOT case, emit "!" immediately */
-
- AcpiOsPrintf ("!");
- return (TRUE);
- }
-
- Child1->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX;
- Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
-
- /* Save symbol string in the next child (not peer) */
-
- Child2 = AcpiPsGetArg (Child1, 0);
- if (!Child2)
- {
- return (FALSE);
- }
-
- Child2->Common.OperatorSymbol = OperatorSymbol;
- return (TRUE);
-
-#ifdef INDEX_SUPPORT
- case AML_INDEX_OP:
- Child1->Common.OperatorSymbol = " [";
- Child2->Common.OperatorSymbol = "]";
- break;
-#endif
-
- /* Unary operators */
-
- case AML_DECREMENT_OP:
- OperatorSymbol = "--";
- break;
-
- case AML_INCREMENT_OP:
- OperatorSymbol = "++";
- break;
-
- case AML_BIT_NOT_OP:
- case AML_STORE_OP:
- OperatorSymbol = NULL;
- break;
-
- default:
- return (FALSE);
- }
-
- if (Child1->Common.DisasmOpcode == ACPI_DASM_LNOT_SUFFIX)
- {
- return (TRUE);
- }
-
- /*
- * This is the key to how the disassembly of the C-style operators
- * works. We save the operator symbol in the first child, thus
- * deferring symbol output until after the first operand has been
- * emitted.
- */
- if (!Child1->Common.OperatorSymbol)
- {
- Child1->Common.OperatorSymbol = OperatorSymbol;
- }
-
- /*
- * Check for a valid target as the 3rd (or sometimes 2nd) operand
- *
- * Compound assignment operator support:
- * Attempt to optimize constructs of the form:
- * Add (Local1, 0xFF, Local1)
- * to:
- * Local1 += 0xFF
- *
- * Only the math operators and Store() have a target.
- * Logicals have no target.
- */
- switch (Op->Common.AmlOpcode)
- {
- case AML_ADD_OP:
- case AML_SUBTRACT_OP:
- case AML_MULTIPLY_OP:
- case AML_DIVIDE_OP:
- case AML_MOD_OP:
- case AML_SHIFT_LEFT_OP:
- case AML_SHIFT_RIGHT_OP:
- case AML_BIT_AND_OP:
- case AML_BIT_OR_OP:
- case AML_BIT_XOR_OP:
-
- /* Target is 3rd operand */
-
- Target = Child2->Common.Next;
- if (Op->Common.AmlOpcode == AML_DIVIDE_OP)
- {
- /*
- * Divide has an extra target operand (Remainder).
- * If this extra target is specified, it cannot be converted
- * to a C-style operator
- */
- if (AcpiDmIsValidTarget (Target))
- {
- Child1->Common.OperatorSymbol = NULL;
- return (FALSE);
- }
-
- Target->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
- Target = Target->Common.Next;
- }
-
- /* Parser should ensure there is at least a placeholder target */
-
- if (!Target)
- {
- return (FALSE);
- }
-
- if (!AcpiDmIsValidTarget (Target))
- {
- /* Not a valid target (placeholder only, from parser) */
- break;
- }
-
- /*
- * Promote the target up to the first child in the parse
- * tree. This is done because the target will be output
- * first, in the form:
- * <Target> = Operands...
- */
- AcpiDmPromoteTarget (Op, Target);
-
- /*
- * Check for possible conversion to a "Compound Assignment".
- *
- * Determine if either operand is the same as the target
- * and display compound assignment operator and other operand.
- */
- if ((AcpiDmIsTargetAnOperand (Target, Child1, TRUE)) ||
- (AcpiDmIsTargetAnOperand (Target, Child2, TRUE)))
- {
- Target->Common.OperatorSymbol =
- AcpiDmGetCompoundSymbol (Op->Common.AmlOpcode);
-
- /* Convert operator to compound assignment */
-
- Op->Common.DisasmFlags |= ACPI_PARSEOP_COMPOUND;
- Child1->Common.OperatorSymbol = NULL;
- return (TRUE);
- }
-
- /*
- * If we are within a C-style expression, emit an extra open
- * paren. Implemented by examining the parent op.
- */
- switch (Op->Common.Parent->Common.AmlOpcode)
- {
- case AML_ADD_OP:
- case AML_SUBTRACT_OP:
- case AML_MULTIPLY_OP:
- case AML_DIVIDE_OP:
- case AML_MOD_OP:
- case AML_SHIFT_LEFT_OP:
- case AML_SHIFT_RIGHT_OP:
- case AML_BIT_AND_OP:
- case AML_BIT_OR_OP:
- case AML_BIT_XOR_OP:
- case AML_LAND_OP:
- case AML_LEQUAL_OP:
- case AML_LGREATER_OP:
- case AML_LLESS_OP:
- case AML_LOR_OP:
-
- Op->Common.DisasmFlags |= ACPI_PARSEOP_ASSIGNMENT;
- AcpiOsPrintf ("(");
- break;
-
- default:
- break;
- }
-
- /* Normal output for ASL/AML operators with a target operand */
-
- Target->Common.OperatorSymbol = " = (";
- return (TRUE);
-
- /* Binary operators, no parens */
-
- case AML_DECREMENT_OP:
- case AML_INCREMENT_OP:
- return (TRUE);
-
-#ifdef INDEX_SUPPORT
- case AML_INDEX_OP:
-
- /* Target is optional, 3rd operand */
-
- Target = Child2->Common.Next;
- if (AcpiDmIsValidTarget (Target))
- {
- AcpiDmPromoteTarget (Op, Target);
-
- if (!Target->Common.OperatorSymbol)
- {
- Target->Common.OperatorSymbol = " = ";
- }
- }
- return (TRUE);
-#endif
-
- case AML_STORE_OP:
- /*
- * Target is the 2nd operand.
- * We know the target is valid, it is not optional.
- * In the parse tree, simply swap the target with the
- * source so that the target is processed first.
- */
- Target = Child1->Common.Next;
- AcpiDmPromoteTarget (Op, Target);
-
- if (!Target->Common.OperatorSymbol)
- {
- Target->Common.OperatorSymbol = " = ";
- }
- return (TRUE);
-
- case AML_BIT_NOT_OP:
-
- /* Target is optional, 2nd operand */
-
- Target = Child1->Common.Next;
- if (!Target)
- {
- return (FALSE);
- }
-
- if (AcpiDmIsValidTarget (Target))
- {
- /* Valid target, not a placeholder */
-
- AcpiDmPromoteTarget (Op, Target);
- Target->Common.OperatorSymbol = " = ~";
- }
- else
- {
- /* No target. Emit this prefix operator immediately */
-
- AcpiOsPrintf ("~");
- }
- return (TRUE);
-
- default:
- break;
- }
-
- /* All other operators, emit an open paren */
-
- AcpiOsPrintf ("(");
- return (TRUE);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiDmCloseOperator
- *
- * PARAMETERS: Op - Current parse object
- *
- * RETURN: None
- *
- * DESCRIPTION: Closes an operator by adding a closing parentheses if and
- * when necessary. Called during ascending phase of the
- * parse tree walk.
- *
- ******************************************************************************/
-
-void
-AcpiDmCloseOperator (
- ACPI_PARSE_OBJECT *Op)
-{
-
- /* Always emit paren if ASL+ disassembly disabled */
-
- if (!AcpiGbl_CstyleDisassembly)
- {
- AcpiOsPrintf (")");
- return;
- }
-
- /* Check if we need to add an additional closing paren */
-
- switch (Op->Common.AmlOpcode)
- {
- case AML_ADD_OP:
- case AML_SUBTRACT_OP:
- case AML_MULTIPLY_OP:
- case AML_DIVIDE_OP:
- case AML_MOD_OP:
- case AML_SHIFT_LEFT_OP:
- case AML_SHIFT_RIGHT_OP:
- case AML_BIT_AND_OP:
- case AML_BIT_OR_OP:
- case AML_BIT_XOR_OP:
- case AML_LAND_OP:
- case AML_LEQUAL_OP:
- case AML_LGREATER_OP:
- case AML_LLESS_OP:
- case AML_LOR_OP:
-
- /* Emit paren only if this is not a compound assignment */
-
- if (Op->Common.DisasmFlags & ACPI_PARSEOP_COMPOUND)
- {
- return;
- }
-
- /* Emit extra close paren for assignment within an expression */
-
- if (Op->Common.DisasmFlags & ACPI_PARSEOP_ASSIGNMENT)
- {
- AcpiOsPrintf (")");
- }
- break;
-
-
- /* No need for parens for these */
-
-#ifdef INDEX_SUPPORT
- case AML_INDEX_OP:
-#endif
- case AML_DECREMENT_OP:
- case AML_INCREMENT_OP:
- case AML_LNOT_OP:
- case AML_BIT_NOT_OP:
- case AML_STORE_OP:
- return;
-
- default:
-
- /* Always emit paren for non-ASL+ operators */
- break;
- }
-
- AcpiOsPrintf (")");
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiDmGetCompoundSymbol
- *
- * PARAMETERS: AslOpcode
- *
- * RETURN: String containing the compound assignment symbol
- *
- * DESCRIPTION: Detect opcodes that can be converted to compound assignment,
- * return the appropriate operator string.
- *
- ******************************************************************************/
-
-static char *
-AcpiDmGetCompoundSymbol (
- UINT16 AmlOpcode)
-{
- char *Symbol;
-
-
- switch (AmlOpcode)
- {
- case AML_ADD_OP:
- Symbol = " += ";
- break;
-
- case AML_SUBTRACT_OP:
- Symbol = " -= ";
- break;
-
- case AML_MULTIPLY_OP:
- Symbol = " *= ";
- break;
-
- case AML_DIVIDE_OP:
- Symbol = " /= ";
- break;
-
- case AML_MOD_OP:
- Symbol = " %= ";
- break;
-
- case AML_SHIFT_LEFT_OP:
- Symbol = " <<= ";
- break;
-
- case AML_SHIFT_RIGHT_OP:
- Symbol = " >>= ";
- break;
-
- case AML_BIT_AND_OP:
- Symbol = " &= ";
- break;
-
- case AML_BIT_OR_OP:
- Symbol = " |= ";
- break;
-
- case AML_BIT_XOR_OP:
- Symbol = " ^= ";
- break;
-
- default:
-
- /* No operator string for all other opcodes */
- return (NULL);
- }
-
- return (Symbol);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiDmPromoteTarget
- *
- * PARAMETERS: Op - Operator parse object
- * Target - Target associate with the Op
- *
- * RETURN: None
- *
- * DESCRIPTION: Transform the parse tree by moving the target up to the first
- * child of the Op.
- *
- ******************************************************************************/
-
-static void
-AcpiDmPromoteTarget (
- ACPI_PARSE_OBJECT *Op,
- ACPI_PARSE_OBJECT *Target)
-{
- ACPI_PARSE_OBJECT *Child;
-
-
- /* Link target directly to the Op as first child */
-
- Child = Op->Common.Value.Arg;
- Op->Common.Value.Arg = Target;
- Target->Common.Next = Child;
-
- /* Find the last peer, it is linked to the target. Unlink it. */
-
- while (Child->Common.Next != Target)
- {
- Child = Child->Common.Next;
- }
-
- Child->Common.Next = NULL;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiDmIsValidTarget
- *
- * PARAMETERS: Target - Target Op from the parse tree
- *
- * RETURN: TRUE if the Target is real. FALSE if it is just a placeholder
- * Op that was inserted by the parser.
- *
- * DESCRIPTION: Determine if a Target Op is a placeholder Op or a real Target.
- * In other words, determine if the optional target is used or
- * not.
- *
- ******************************************************************************/
-
-static BOOLEAN
-AcpiDmIsValidTarget (
- ACPI_PARSE_OBJECT *Target)
-{
-
- if ((Target->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
- (Target->Common.Value.Arg == NULL))
- {
- return (FALSE);
- }
-
- return (TRUE);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiDmIsTargetAnOperand
- *
- * PARAMETERS: Target - Target associated with the expression
- * Operand - An operand associated with expression
- *
- * RETURN: TRUE if expression can be converted to a compound assignment.
- * FALSE otherwise.
- *
- * DESCRIPTION: Determine if the Target duplicates the operand, in order to
- * detect if the expression can be converted to a compound
- * assigment. (+=, *=, etc.)
- *
- ******************************************************************************/
-
-static BOOLEAN
-AcpiDmIsTargetAnOperand (
- ACPI_PARSE_OBJECT *Target,
- ACPI_PARSE_OBJECT *Operand,
- BOOLEAN TopLevel)
-{
- const ACPI_OPCODE_INFO *OpInfo;
- BOOLEAN Same;
-
-
- /*
- * Opcodes must match. Note: ignoring the difference between nameseg
- * and namepath for now. May be needed later.
- */
- if (Target->Common.AmlOpcode != Operand->Common.AmlOpcode)
- {
- return (FALSE);
- }
-
- /* Nodes should match, even if they are NULL */
-
- if (Target->Common.Node != Operand->Common.Node)
- {
- return (FALSE);
- }
-
- /* Determine if a child exists */
-
- OpInfo = AcpiPsGetOpcodeInfo (Operand->Common.AmlOpcode);
- if (OpInfo->Flags & AML_HAS_ARGS)
- {
- Same = AcpiDmIsTargetAnOperand (Target->Common.Value.Arg,
- Operand->Common.Value.Arg, FALSE);
- if (!Same)
- {
- return (FALSE);
- }
- }
-
- /* Check the next peer, as long as we are not at the top level */
-
- if ((!TopLevel) &&
- Target->Common.Next)
- {
- Same = AcpiDmIsTargetAnOperand (Target->Common.Next,
- Operand->Common.Next, FALSE);
- if (!Same)
- {
- return (FALSE);
- }
- }
-
- /* Supress the duplicate operand at the top-level */
-
- if (TopLevel)
- {
- Operand->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
- }
- return (TRUE);
-}
-
-#endif
+/*******************************************************************************
+ *
+ * Module Name: dmcstyle - Support for C-style operator disassembly
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * 1. Copyright Notice
+ *
+ * Some or all of this work - Copyright (c) 1999 - 2014, Intel Corp.
+ * All rights reserved.
+ *
+ * 2. License
+ *
+ * 2.1. This is your license from Intel Corp. under its intellectual property
+ * rights. You may have additional license terms from the party that provided
+ * you this software, covering your right to use that party's intellectual
+ * property rights.
+ *
+ * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
+ * copy of the source code appearing in this file ("Covered Code") an
+ * irrevocable, perpetual, worldwide license under Intel's copyrights in the
+ * base code distributed originally by Intel ("Original Intel Code") to copy,
+ * make derivatives, distribute, use and display any portion of the Covered
+ * Code in any form, with the right to sublicense such rights; and
+ *
+ * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
+ * license (with the right to sublicense), under only those claims of Intel
+ * patents that are infringed by the Original Intel Code, to make, use, sell,
+ * offer to sell, and import the Covered Code and derivative works thereof
+ * solely to the minimum extent necessary to exercise the above copyright
+ * license, and in no event shall the patent license extend to any additions
+ * to or modifications of the Original Intel Code. No other license or right
+ * is granted directly or by implication, estoppel or otherwise;
+ *
+ * The above copyright and patent license is granted only if the following
+ * conditions are met:
+ *
+ * 3. Conditions
+ *
+ * 3.1. Redistribution of Source with Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification with rights to further distribute source must include
+ * the above Copyright Notice, the above License, this list of Conditions,
+ * and the following Disclaimer and Export Compliance provision. In addition,
+ * Licensee must cause all Covered Code to which Licensee contributes to
+ * contain a file documenting the changes Licensee made to create that Covered
+ * Code and the date of any change. Licensee must include in that file the
+ * documentation of any changes made by any predecessor Licensee. Licensee
+ * must include a prominent statement that the modification is derived,
+ * directly or indirectly, from Original Intel Code.
+ *
+ * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification without rights to further distribute source must
+ * include the following Disclaimer and Export Compliance provision in the
+ * documentation and/or other materials provided with distribution. In
+ * addition, Licensee may not authorize further sublicense of source of any
+ * portion of the Covered Code, and must include terms to the effect that the
+ * license from Licensee to its licensee is limited to the intellectual
+ * property embodied in the software Licensee provides to its licensee, and
+ * not to intellectual property embodied in modifications its licensee may
+ * make.
+ *
+ * 3.3. Redistribution of Executable. Redistribution in executable form of any
+ * substantial portion of the Covered Code or modification must reproduce the
+ * above Copyright Notice, and the following Disclaimer and Export Compliance
+ * provision in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3.4. Intel retains all right, title, and interest in and to the Original
+ * Intel Code.
+ *
+ * 3.5. Neither the name Intel nor any other trademark owned or controlled by
+ * Intel shall be used in advertising or otherwise to promote the sale, use or
+ * other dealings in products derived from or relating to the Covered Code
+ * without prior written authorization from Intel.
+ *
+ * 4. Disclaimer and Export Compliance
+ *
+ * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
+ * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
+ * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
+ * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
+ * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
+ * PARTICULAR PURPOSE.
+ *
+ * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
+ * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
+ * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
+ * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
+ * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
+ * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
+ * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
+ * LIMITED REMEDY.
+ *
+ * 4.3. Licensee shall not export, either directly or indirectly, any of this
+ * software or system incorporating such software without first obtaining any
+ * required license or other approval from the U. S. Department of Commerce or
+ * any other agency or department of the United States Government. In the
+ * event Licensee exports any such software from the United States or
+ * re-exports any such software from a foreign destination, Licensee shall
+ * ensure that the distribution and export/re-export of the software is in
+ * compliance with all laws, regulations, orders, or other restrictions of the
+ * U.S. Export Administration Regulations. Licensee agrees that neither it nor
+ * any of its subsidiaries will export/re-export any technical data, process,
+ * software, or service, directly or indirectly, to any country for which the
+ * United States government or any agency thereof requires an export license,
+ * other governmental approval, or letter of assurance, without first obtaining
+ * such license, approval or letter.
+ *
+ *****************************************************************************/
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acparser.h"
+#include "amlcode.h"
+#include "acdisasm.h"
+#include "acdebug.h"
+
+#ifdef ACPI_DISASSEMBLER
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dmcstyle")
+
+
+/* Local prototypes */
+
+static char *
+AcpiDmGetCompoundSymbol (
+ UINT16 AslOpcode);
+
+static void
+AcpiDmPromoteTarget (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_PARSE_OBJECT *Target);
+
+static BOOLEAN
+AcpiDmIsValidTarget (
+ ACPI_PARSE_OBJECT *Op);
+
+static BOOLEAN
+AcpiDmIsTargetAnOperand (
+ ACPI_PARSE_OBJECT *Target,
+ ACPI_PARSE_OBJECT *Operand,
+ BOOLEAN TopLevel);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmCheckForSymbolicOpcode
+ *
+ * PARAMETERS: Op - Current parse object
+ * Walk - Current parse tree walk info
+ *
+ * RETURN: TRUE if opcode can be converted to symbolic, FALSE otherwise
+ *
+ * DESCRIPTION: This is the main code that implements disassembly of AML code
+ * to C-style operators. Called during descending phase of the
+ * parse tree walk.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiDmCheckForSymbolicOpcode (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_OP_WALK_INFO *Info)
+{
+ char *OperatorSymbol = NULL;
+ ACPI_PARSE_OBJECT *Child1;
+ ACPI_PARSE_OBJECT *Child2;
+ ACPI_PARSE_OBJECT *Target;
+
+
+ /* Exit immediately if ASL+ not enabled */
+
+ if (!AcpiGbl_CstyleDisassembly)
+ {
+ return (FALSE);
+ }
+
+ /* Get the first operand */
+
+ Child1 = AcpiPsGetArg (Op, 0);
+ if (!Child1)
+ {
+ return (FALSE);
+ }
+
+ /* Get the second operand */
+
+ Child2 = Child1->Common.Next;
+
+ /* Setup the operator string for this opcode */
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_ADD_OP:
+ OperatorSymbol = " + ";
+ break;
+
+ case AML_SUBTRACT_OP:
+ OperatorSymbol = " - ";
+ break;
+
+ case AML_MULTIPLY_OP:
+ OperatorSymbol = " * ";
+ break;
+
+ case AML_DIVIDE_OP:
+ OperatorSymbol = " / ";
+ break;
+
+ case AML_MOD_OP:
+ OperatorSymbol = " % ";
+ break;
+
+ case AML_SHIFT_LEFT_OP:
+ OperatorSymbol = " << ";
+ break;
+
+ case AML_SHIFT_RIGHT_OP:
+ OperatorSymbol = " >> ";
+ break;
+
+ case AML_BIT_AND_OP:
+ OperatorSymbol = " & ";
+ break;
+
+ case AML_BIT_OR_OP:
+ OperatorSymbol = " | ";
+ break;
+
+ case AML_BIT_XOR_OP:
+ OperatorSymbol = " ^ ";
+ break;
+
+ /* Logical operators, no target */
+
+ case AML_LAND_OP:
+ OperatorSymbol = " && ";
+ break;
+
+ case AML_LEQUAL_OP:
+ OperatorSymbol = " == ";
+ break;
+
+ case AML_LGREATER_OP:
+ OperatorSymbol = " > ";
+ break;
+
+ case AML_LLESS_OP:
+ OperatorSymbol = " < ";
+ break;
+
+ case AML_LOR_OP:
+ OperatorSymbol = " || ";
+ break;
+
+ case AML_LNOT_OP:
+ /*
+ * Check for the LNOT sub-opcodes. These correspond to
+ * LNotEqual, LLessEqual, and LGreaterEqual. There are
+ * no actual AML opcodes for these operators.
+ */
+ switch (Child1->Common.AmlOpcode)
+ {
+ case AML_LEQUAL_OP:
+ OperatorSymbol = " != ";
+ break;
+
+ case AML_LGREATER_OP:
+ OperatorSymbol = " <= ";
+ break;
+
+ case AML_LLESS_OP:
+ OperatorSymbol = " >= ";
+ break;
+
+ default:
+
+ /* Unary LNOT case, emit "!" immediately */
+
+ AcpiOsPrintf ("!");
+ return (TRUE);
+ }
+
+ Child1->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX;
+ Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
+
+ /* Save symbol string in the next child (not peer) */
+
+ Child2 = AcpiPsGetArg (Child1, 0);
+ if (!Child2)
+ {
+ return (FALSE);
+ }
+
+ Child2->Common.OperatorSymbol = OperatorSymbol;
+ return (TRUE);
+
+#ifdef INDEX_SUPPORT
+ case AML_INDEX_OP:
+ Child1->Common.OperatorSymbol = " [";
+ Child2->Common.OperatorSymbol = "]";
+ break;
+#endif
+
+ /* Unary operators */
+
+ case AML_DECREMENT_OP:
+ OperatorSymbol = "--";
+ break;
+
+ case AML_INCREMENT_OP:
+ OperatorSymbol = "++";
+ break;
+
+ case AML_BIT_NOT_OP:
+ case AML_STORE_OP:
+ OperatorSymbol = NULL;
+ break;
+
+ default:
+ return (FALSE);
+ }
+
+ if (Child1->Common.DisasmOpcode == ACPI_DASM_LNOT_SUFFIX)
+ {
+ return (TRUE);
+ }
+
+ /*
+ * This is the key to how the disassembly of the C-style operators
+ * works. We save the operator symbol in the first child, thus
+ * deferring symbol output until after the first operand has been
+ * emitted.
+ */
+ if (!Child1->Common.OperatorSymbol)
+ {
+ Child1->Common.OperatorSymbol = OperatorSymbol;
+ }
+
+ /*
+ * Check for a valid target as the 3rd (or sometimes 2nd) operand
+ *
+ * Compound assignment operator support:
+ * Attempt to optimize constructs of the form:
+ * Add (Local1, 0xFF, Local1)
+ * to:
+ * Local1 += 0xFF
+ *
+ * Only the math operators and Store() have a target.
+ * Logicals have no target.
+ */
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_ADD_OP:
+ case AML_SUBTRACT_OP:
+ case AML_MULTIPLY_OP:
+ case AML_DIVIDE_OP:
+ case AML_MOD_OP:
+ case AML_SHIFT_LEFT_OP:
+ case AML_SHIFT_RIGHT_OP:
+ case AML_BIT_AND_OP:
+ case AML_BIT_OR_OP:
+ case AML_BIT_XOR_OP:
+
+ /* Target is 3rd operand */
+
+ Target = Child2->Common.Next;
+ if (Op->Common.AmlOpcode == AML_DIVIDE_OP)
+ {
+ /*
+ * Divide has an extra target operand (Remainder).
+ * If this extra target is specified, it cannot be converted
+ * to a C-style operator
+ */
+ if (AcpiDmIsValidTarget (Target))
+ {
+ Child1->Common.OperatorSymbol = NULL;
+ return (FALSE);
+ }
+
+ Target->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ Target = Target->Common.Next;
+ }
+
+ /* Parser should ensure there is at least a placeholder target */
+
+ if (!Target)
+ {
+ return (FALSE);
+ }
+
+ if (!AcpiDmIsValidTarget (Target))
+ {
+ /* Not a valid target (placeholder only, from parser) */
+ break;
+ }
+
+ /*
+ * Promote the target up to the first child in the parse
+ * tree. This is done because the target will be output
+ * first, in the form:
+ * <Target> = Operands...
+ */
+ AcpiDmPromoteTarget (Op, Target);
+
+ /*
+ * Check for possible conversion to a "Compound Assignment".
+ *
+ * Determine if either operand is the same as the target
+ * and display compound assignment operator and other operand.
+ */
+ if ((AcpiDmIsTargetAnOperand (Target, Child1, TRUE)) ||
+ (AcpiDmIsTargetAnOperand (Target, Child2, TRUE)))
+ {
+ Target->Common.OperatorSymbol =
+ AcpiDmGetCompoundSymbol (Op->Common.AmlOpcode);
+
+ /* Convert operator to compound assignment */
+
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_COMPOUND;
+ Child1->Common.OperatorSymbol = NULL;
+ return (TRUE);
+ }
+
+ /*
+ * If we are within a C-style expression, emit an extra open
+ * paren. Implemented by examining the parent op.
+ */
+ switch (Op->Common.Parent->Common.AmlOpcode)
+ {
+ case AML_ADD_OP:
+ case AML_SUBTRACT_OP:
+ case AML_MULTIPLY_OP:
+ case AML_DIVIDE_OP:
+ case AML_MOD_OP:
+ case AML_SHIFT_LEFT_OP:
+ case AML_SHIFT_RIGHT_OP:
+ case AML_BIT_AND_OP:
+ case AML_BIT_OR_OP:
+ case AML_BIT_XOR_OP:
+ case AML_LAND_OP:
+ case AML_LEQUAL_OP:
+ case AML_LGREATER_OP:
+ case AML_LLESS_OP:
+ case AML_LOR_OP:
+
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_ASSIGNMENT;
+ AcpiOsPrintf ("(");
+ break;
+
+ default:
+ break;
+ }
+
+ /* Normal output for ASL/AML operators with a target operand */
+
+ Target->Common.OperatorSymbol = " = (";
+ return (TRUE);
+
+ /* Binary operators, no parens */
+
+ case AML_DECREMENT_OP:
+ case AML_INCREMENT_OP:
+ return (TRUE);
+
+#ifdef INDEX_SUPPORT
+ case AML_INDEX_OP:
+
+ /* Target is optional, 3rd operand */
+
+ Target = Child2->Common.Next;
+ if (AcpiDmIsValidTarget (Target))
+ {
+ AcpiDmPromoteTarget (Op, Target);
+
+ if (!Target->Common.OperatorSymbol)
+ {
+ Target->Common.OperatorSymbol = " = ";
+ }
+ }
+ return (TRUE);
+#endif
+
+ case AML_STORE_OP:
+ /*
+ * Target is the 2nd operand.
+ * We know the target is valid, it is not optional.
+ * In the parse tree, simply swap the target with the
+ * source so that the target is processed first.
+ */
+ Target = Child1->Common.Next;
+ AcpiDmPromoteTarget (Op, Target);
+
+ if (!Target->Common.OperatorSymbol)
+ {
+ Target->Common.OperatorSymbol = " = ";
+ }
+ return (TRUE);
+
+ case AML_BIT_NOT_OP:
+
+ /* Target is optional, 2nd operand */
+
+ Target = Child1->Common.Next;
+ if (!Target)
+ {
+ return (FALSE);
+ }
+
+ if (AcpiDmIsValidTarget (Target))
+ {
+ /* Valid target, not a placeholder */
+
+ AcpiDmPromoteTarget (Op, Target);
+ Target->Common.OperatorSymbol = " = ~";
+ }
+ else
+ {
+ /* No target. Emit this prefix operator immediately */
+
+ AcpiOsPrintf ("~");
+ }
+ return (TRUE);
+
+ default:
+ break;
+ }
+
+ /* All other operators, emit an open paren */
+
+ AcpiOsPrintf ("(");
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmCloseOperator
+ *
+ * PARAMETERS: Op - Current parse object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Closes an operator by adding a closing parentheses if and
+ * when necessary. Called during ascending phase of the
+ * parse tree walk.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmCloseOperator (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ /* Always emit paren if ASL+ disassembly disabled */
+
+ if (!AcpiGbl_CstyleDisassembly)
+ {
+ AcpiOsPrintf (")");
+ return;
+ }
+
+ /* Check if we need to add an additional closing paren */
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_ADD_OP:
+ case AML_SUBTRACT_OP:
+ case AML_MULTIPLY_OP:
+ case AML_DIVIDE_OP:
+ case AML_MOD_OP:
+ case AML_SHIFT_LEFT_OP:
+ case AML_SHIFT_RIGHT_OP:
+ case AML_BIT_AND_OP:
+ case AML_BIT_OR_OP:
+ case AML_BIT_XOR_OP:
+ case AML_LAND_OP:
+ case AML_LEQUAL_OP:
+ case AML_LGREATER_OP:
+ case AML_LLESS_OP:
+ case AML_LOR_OP:
+
+ /* Emit paren only if this is not a compound assignment */
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_COMPOUND)
+ {
+ return;
+ }
+
+ /* Emit extra close paren for assignment within an expression */
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_ASSIGNMENT)
+ {
+ AcpiOsPrintf (")");
+ }
+ break;
+
+
+ /* No need for parens for these */
+
+#ifdef INDEX_SUPPORT
+ case AML_INDEX_OP:
+#endif
+ case AML_DECREMENT_OP:
+ case AML_INCREMENT_OP:
+ case AML_LNOT_OP:
+ case AML_BIT_NOT_OP:
+ case AML_STORE_OP:
+ return;
+
+ default:
+
+ /* Always emit paren for non-ASL+ operators */
+ break;
+ }
+
+ AcpiOsPrintf (")");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGetCompoundSymbol
+ *
+ * PARAMETERS: AslOpcode
+ *
+ * RETURN: String containing the compound assignment symbol
+ *
+ * DESCRIPTION: Detect opcodes that can be converted to compound assignment,
+ * return the appropriate operator string.
+ *
+ ******************************************************************************/
+
+static char *
+AcpiDmGetCompoundSymbol (
+ UINT16 AmlOpcode)
+{
+ char *Symbol;
+
+
+ switch (AmlOpcode)
+ {
+ case AML_ADD_OP:
+ Symbol = " += ";
+ break;
+
+ case AML_SUBTRACT_OP:
+ Symbol = " -= ";
+ break;
+
+ case AML_MULTIPLY_OP:
+ Symbol = " *= ";
+ break;
+
+ case AML_DIVIDE_OP:
+ Symbol = " /= ";
+ break;
+
+ case AML_MOD_OP:
+ Symbol = " %= ";
+ break;
+
+ case AML_SHIFT_LEFT_OP:
+ Symbol = " <<= ";
+ break;
+
+ case AML_SHIFT_RIGHT_OP:
+ Symbol = " >>= ";
+ break;
+
+ case AML_BIT_AND_OP:
+ Symbol = " &= ";
+ break;
+
+ case AML_BIT_OR_OP:
+ Symbol = " |= ";
+ break;
+
+ case AML_BIT_XOR_OP:
+ Symbol = " ^= ";
+ break;
+
+ default:
+
+ /* No operator string for all other opcodes */
+ return (NULL);
+ }
+
+ return (Symbol);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmPromoteTarget
+ *
+ * PARAMETERS: Op - Operator parse object
+ * Target - Target associate with the Op
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Transform the parse tree by moving the target up to the first
+ * child of the Op.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmPromoteTarget (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_PARSE_OBJECT *Target)
+{
+ ACPI_PARSE_OBJECT *Child;
+
+
+ /* Link target directly to the Op as first child */
+
+ Child = Op->Common.Value.Arg;
+ Op->Common.Value.Arg = Target;
+ Target->Common.Next = Child;
+
+ /* Find the last peer, it is linked to the target. Unlink it. */
+
+ while (Child->Common.Next != Target)
+ {
+ Child = Child->Common.Next;
+ }
+
+ Child->Common.Next = NULL;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIsValidTarget
+ *
+ * PARAMETERS: Target - Target Op from the parse tree
+ *
+ * RETURN: TRUE if the Target is real. FALSE if it is just a placeholder
+ * Op that was inserted by the parser.
+ *
+ * DESCRIPTION: Determine if a Target Op is a placeholder Op or a real Target.
+ * In other words, determine if the optional target is used or
+ * not.
+ *
+ ******************************************************************************/
+
+static BOOLEAN
+AcpiDmIsValidTarget (
+ ACPI_PARSE_OBJECT *Target)
+{
+
+ if ((Target->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
+ (Target->Common.Value.Arg == NULL))
+ {
+ return (FALSE);
+ }
+
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIsTargetAnOperand
+ *
+ * PARAMETERS: Target - Target associated with the expression
+ * Operand - An operand associated with expression
+ *
+ * RETURN: TRUE if expression can be converted to a compound assignment.
+ * FALSE otherwise.
+ *
+ * DESCRIPTION: Determine if the Target duplicates the operand, in order to
+ * detect if the expression can be converted to a compound
+ * assigment. (+=, *=, etc.)
+ *
+ ******************************************************************************/
+
+static BOOLEAN
+AcpiDmIsTargetAnOperand (
+ ACPI_PARSE_OBJECT *Target,
+ ACPI_PARSE_OBJECT *Operand,
+ BOOLEAN TopLevel)
+{
+ const ACPI_OPCODE_INFO *OpInfo;
+ BOOLEAN Same;
+
+
+ /*
+ * Opcodes must match. Note: ignoring the difference between nameseg
+ * and namepath for now. May be needed later.
+ */
+ if (Target->Common.AmlOpcode != Operand->Common.AmlOpcode)
+ {
+ return (FALSE);
+ }
+
+ /* Nodes should match, even if they are NULL */
+
+ if (Target->Common.Node != Operand->Common.Node)
+ {
+ return (FALSE);
+ }
+
+ /* Determine if a child exists */
+
+ OpInfo = AcpiPsGetOpcodeInfo (Operand->Common.AmlOpcode);
+ if (OpInfo->Flags & AML_HAS_ARGS)
+ {
+ Same = AcpiDmIsTargetAnOperand (Target->Common.Value.Arg,
+ Operand->Common.Value.Arg, FALSE);
+ if (!Same)
+ {
+ return (FALSE);
+ }
+ }
+
+ /* Check the next peer, as long as we are not at the top level */
+
+ if ((!TopLevel) &&
+ Target->Common.Next)
+ {
+ Same = AcpiDmIsTargetAnOperand (Target->Common.Next,
+ Operand->Common.Next, FALSE);
+ if (!Same)
+ {
+ return (FALSE);
+ }
+ }
+
+ /* Supress the duplicate operand at the top-level */
+
+ if (TopLevel)
+ {
+ Operand->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ }
+ return (TRUE);
+}
+
+#endif