11c0e1b6dSJung-uk Kim /*******************************************************************************
21c0e1b6dSJung-uk Kim *
31c0e1b6dSJung-uk Kim * Module Name: dmcstyle - Support for C-style operator disassembly
41c0e1b6dSJung-uk Kim *
51c0e1b6dSJung-uk Kim ******************************************************************************/
61c0e1b6dSJung-uk Kim
70d84335fSJung-uk Kim /******************************************************************************
80d84335fSJung-uk Kim *
90d84335fSJung-uk Kim * 1. Copyright Notice
100d84335fSJung-uk Kim *
11*804fe266SJung-uk Kim * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
121c0e1b6dSJung-uk Kim * All rights reserved.
131c0e1b6dSJung-uk Kim *
140d84335fSJung-uk Kim * 2. License
150d84335fSJung-uk Kim *
160d84335fSJung-uk Kim * 2.1. This is your license from Intel Corp. under its intellectual property
170d84335fSJung-uk Kim * rights. You may have additional license terms from the party that provided
180d84335fSJung-uk Kim * you this software, covering your right to use that party's intellectual
190d84335fSJung-uk Kim * property rights.
200d84335fSJung-uk Kim *
210d84335fSJung-uk Kim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
220d84335fSJung-uk Kim * copy of the source code appearing in this file ("Covered Code") an
230d84335fSJung-uk Kim * irrevocable, perpetual, worldwide license under Intel's copyrights in the
240d84335fSJung-uk Kim * base code distributed originally by Intel ("Original Intel Code") to copy,
250d84335fSJung-uk Kim * make derivatives, distribute, use and display any portion of the Covered
260d84335fSJung-uk Kim * Code in any form, with the right to sublicense such rights; and
270d84335fSJung-uk Kim *
280d84335fSJung-uk Kim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
290d84335fSJung-uk Kim * license (with the right to sublicense), under only those claims of Intel
300d84335fSJung-uk Kim * patents that are infringed by the Original Intel Code, to make, use, sell,
310d84335fSJung-uk Kim * offer to sell, and import the Covered Code and derivative works thereof
320d84335fSJung-uk Kim * solely to the minimum extent necessary to exercise the above copyright
330d84335fSJung-uk Kim * license, and in no event shall the patent license extend to any additions
340d84335fSJung-uk Kim * to or modifications of the Original Intel Code. No other license or right
350d84335fSJung-uk Kim * is granted directly or by implication, estoppel or otherwise;
360d84335fSJung-uk Kim *
370d84335fSJung-uk Kim * The above copyright and patent license is granted only if the following
380d84335fSJung-uk Kim * conditions are met:
390d84335fSJung-uk Kim *
400d84335fSJung-uk Kim * 3. Conditions
410d84335fSJung-uk Kim *
420d84335fSJung-uk Kim * 3.1. Redistribution of Source with Rights to Further Distribute Source.
430d84335fSJung-uk Kim * Redistribution of source code of any substantial portion of the Covered
440d84335fSJung-uk Kim * Code or modification with rights to further distribute source must include
450d84335fSJung-uk Kim * the above Copyright Notice, the above License, this list of Conditions,
460d84335fSJung-uk Kim * and the following Disclaimer and Export Compliance provision. In addition,
470d84335fSJung-uk Kim * Licensee must cause all Covered Code to which Licensee contributes to
480d84335fSJung-uk Kim * contain a file documenting the changes Licensee made to create that Covered
490d84335fSJung-uk Kim * Code and the date of any change. Licensee must include in that file the
500d84335fSJung-uk Kim * documentation of any changes made by any predecessor Licensee. Licensee
510d84335fSJung-uk Kim * must include a prominent statement that the modification is derived,
520d84335fSJung-uk Kim * directly or indirectly, from Original Intel Code.
530d84335fSJung-uk Kim *
540d84335fSJung-uk Kim * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
550d84335fSJung-uk Kim * Redistribution of source code of any substantial portion of the Covered
560d84335fSJung-uk Kim * Code or modification without rights to further distribute source must
570d84335fSJung-uk Kim * include the following Disclaimer and Export Compliance provision in the
580d84335fSJung-uk Kim * documentation and/or other materials provided with distribution. In
590d84335fSJung-uk Kim * addition, Licensee may not authorize further sublicense of source of any
600d84335fSJung-uk Kim * portion of the Covered Code, and must include terms to the effect that the
610d84335fSJung-uk Kim * license from Licensee to its licensee is limited to the intellectual
620d84335fSJung-uk Kim * property embodied in the software Licensee provides to its licensee, and
630d84335fSJung-uk Kim * not to intellectual property embodied in modifications its licensee may
640d84335fSJung-uk Kim * make.
650d84335fSJung-uk Kim *
660d84335fSJung-uk Kim * 3.3. Redistribution of Executable. Redistribution in executable form of any
670d84335fSJung-uk Kim * substantial portion of the Covered Code or modification must reproduce the
680d84335fSJung-uk Kim * above Copyright Notice, and the following Disclaimer and Export Compliance
690d84335fSJung-uk Kim * provision in the documentation and/or other materials provided with the
700d84335fSJung-uk Kim * distribution.
710d84335fSJung-uk Kim *
720d84335fSJung-uk Kim * 3.4. Intel retains all right, title, and interest in and to the Original
730d84335fSJung-uk Kim * Intel Code.
740d84335fSJung-uk Kim *
750d84335fSJung-uk Kim * 3.5. Neither the name Intel nor any other trademark owned or controlled by
760d84335fSJung-uk Kim * Intel shall be used in advertising or otherwise to promote the sale, use or
770d84335fSJung-uk Kim * other dealings in products derived from or relating to the Covered Code
780d84335fSJung-uk Kim * without prior written authorization from Intel.
790d84335fSJung-uk Kim *
800d84335fSJung-uk Kim * 4. Disclaimer and Export Compliance
810d84335fSJung-uk Kim *
820d84335fSJung-uk Kim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
830d84335fSJung-uk Kim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
840d84335fSJung-uk Kim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
850d84335fSJung-uk Kim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
860d84335fSJung-uk Kim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
870d84335fSJung-uk Kim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
880d84335fSJung-uk Kim * PARTICULAR PURPOSE.
890d84335fSJung-uk Kim *
900d84335fSJung-uk Kim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
910d84335fSJung-uk Kim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
920d84335fSJung-uk Kim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
930d84335fSJung-uk Kim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
940d84335fSJung-uk Kim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
950d84335fSJung-uk Kim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
960d84335fSJung-uk Kim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
970d84335fSJung-uk Kim * LIMITED REMEDY.
980d84335fSJung-uk Kim *
990d84335fSJung-uk Kim * 4.3. Licensee shall not export, either directly or indirectly, any of this
1000d84335fSJung-uk Kim * software or system incorporating such software without first obtaining any
1010d84335fSJung-uk Kim * required license or other approval from the U. S. Department of Commerce or
1020d84335fSJung-uk Kim * any other agency or department of the United States Government. In the
1030d84335fSJung-uk Kim * event Licensee exports any such software from the United States or
1040d84335fSJung-uk Kim * re-exports any such software from a foreign destination, Licensee shall
1050d84335fSJung-uk Kim * ensure that the distribution and export/re-export of the software is in
1060d84335fSJung-uk Kim * compliance with all laws, regulations, orders, or other restrictions of the
1070d84335fSJung-uk Kim * U.S. Export Administration Regulations. Licensee agrees that neither it nor
1080d84335fSJung-uk Kim * any of its subsidiaries will export/re-export any technical data, process,
1090d84335fSJung-uk Kim * software, or service, directly or indirectly, to any country for which the
1100d84335fSJung-uk Kim * United States government or any agency thereof requires an export license,
1110d84335fSJung-uk Kim * other governmental approval, or letter of assurance, without first obtaining
1120d84335fSJung-uk Kim * such license, approval or letter.
1130d84335fSJung-uk Kim *
1140d84335fSJung-uk Kim *****************************************************************************
1150d84335fSJung-uk Kim *
1160d84335fSJung-uk Kim * Alternatively, you may choose to be licensed under the terms of the
1170d84335fSJung-uk Kim * following license:
1180d84335fSJung-uk Kim *
1191c0e1b6dSJung-uk Kim * Redistribution and use in source and binary forms, with or without
1201c0e1b6dSJung-uk Kim * modification, are permitted provided that the following conditions
1211c0e1b6dSJung-uk Kim * are met:
1221c0e1b6dSJung-uk Kim * 1. Redistributions of source code must retain the above copyright
1231c0e1b6dSJung-uk Kim * notice, this list of conditions, and the following disclaimer,
1241c0e1b6dSJung-uk Kim * without modification.
1251c0e1b6dSJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1261c0e1b6dSJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below
1271c0e1b6dSJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon
1281c0e1b6dSJung-uk Kim * including a substantially similar Disclaimer requirement for further
1291c0e1b6dSJung-uk Kim * binary redistribution.
1301c0e1b6dSJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names
1311c0e1b6dSJung-uk Kim * of any contributors may be used to endorse or promote products derived
1321c0e1b6dSJung-uk Kim * from this software without specific prior written permission.
1331c0e1b6dSJung-uk Kim *
1340d84335fSJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1350d84335fSJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1360d84335fSJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1370d84335fSJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1380d84335fSJung-uk Kim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1390d84335fSJung-uk Kim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1400d84335fSJung-uk Kim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1410d84335fSJung-uk Kim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1420d84335fSJung-uk Kim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1430d84335fSJung-uk Kim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1440d84335fSJung-uk Kim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1450d84335fSJung-uk Kim *
1460d84335fSJung-uk Kim * Alternatively, you may choose to be licensed under the terms of the
1471c0e1b6dSJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free
1481c0e1b6dSJung-uk Kim * Software Foundation.
1491c0e1b6dSJung-uk Kim *
1500d84335fSJung-uk Kim *****************************************************************************/
1511c0e1b6dSJung-uk Kim
1521c0e1b6dSJung-uk Kim #include <contrib/dev/acpica/include/acpi.h>
1531c0e1b6dSJung-uk Kim #include <contrib/dev/acpica/include/accommon.h>
1541c0e1b6dSJung-uk Kim #include <contrib/dev/acpica/include/acparser.h>
1551c0e1b6dSJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h>
1561c0e1b6dSJung-uk Kim #include <contrib/dev/acpica/include/acdebug.h>
1570d84335fSJung-uk Kim #include <contrib/dev/acpica/include/acconvert.h>
1581c0e1b6dSJung-uk Kim
1591c0e1b6dSJung-uk Kim
1601c0e1b6dSJung-uk Kim #define _COMPONENT ACPI_CA_DEBUGGER
1611c0e1b6dSJung-uk Kim ACPI_MODULE_NAME ("dmcstyle")
1621c0e1b6dSJung-uk Kim
1631c0e1b6dSJung-uk Kim
1641c0e1b6dSJung-uk Kim /* Local prototypes */
1651c0e1b6dSJung-uk Kim
1661c0e1b6dSJung-uk Kim static char *
1671c0e1b6dSJung-uk Kim AcpiDmGetCompoundSymbol (
1681c0e1b6dSJung-uk Kim UINT16 AslOpcode);
1691c0e1b6dSJung-uk Kim
1701c0e1b6dSJung-uk Kim static void
1711c0e1b6dSJung-uk Kim AcpiDmPromoteTarget (
1721c0e1b6dSJung-uk Kim ACPI_PARSE_OBJECT *Op,
1731c0e1b6dSJung-uk Kim ACPI_PARSE_OBJECT *Target);
1741c0e1b6dSJung-uk Kim
1751c0e1b6dSJung-uk Kim static BOOLEAN
1761c0e1b6dSJung-uk Kim AcpiDmIsValidTarget (
1771c0e1b6dSJung-uk Kim ACPI_PARSE_OBJECT *Op);
1781c0e1b6dSJung-uk Kim
1791c0e1b6dSJung-uk Kim static BOOLEAN
1801c0e1b6dSJung-uk Kim AcpiDmIsTargetAnOperand (
1811c0e1b6dSJung-uk Kim ACPI_PARSE_OBJECT *Target,
1821c0e1b6dSJung-uk Kim ACPI_PARSE_OBJECT *Operand,
1831c0e1b6dSJung-uk Kim BOOLEAN TopLevel);
1841c0e1b6dSJung-uk Kim
1851cc50d6bSJung-uk Kim static BOOLEAN
1861cc50d6bSJung-uk Kim AcpiDmIsOptimizationIgnored (
1871cc50d6bSJung-uk Kim ACPI_PARSE_OBJECT *StoreOp,
1881cc50d6bSJung-uk Kim ACPI_PARSE_OBJECT *StoreArgument);
1891cc50d6bSJung-uk Kim
1901c0e1b6dSJung-uk Kim
1911c0e1b6dSJung-uk Kim /*******************************************************************************
1921c0e1b6dSJung-uk Kim *
1931c0e1b6dSJung-uk Kim * FUNCTION: AcpiDmCheckForSymbolicOpcode
1941c0e1b6dSJung-uk Kim *
1951c0e1b6dSJung-uk Kim * PARAMETERS: Op - Current parse object
1961c0e1b6dSJung-uk Kim * Walk - Current parse tree walk info
1971c0e1b6dSJung-uk Kim *
1981c0e1b6dSJung-uk Kim * RETURN: TRUE if opcode can be converted to symbolic, FALSE otherwise
1991c0e1b6dSJung-uk Kim *
2001c0e1b6dSJung-uk Kim * DESCRIPTION: This is the main code that implements disassembly of AML code
2011c0e1b6dSJung-uk Kim * to C-style operators. Called during descending phase of the
2021c0e1b6dSJung-uk Kim * parse tree walk.
2031c0e1b6dSJung-uk Kim *
2041c0e1b6dSJung-uk Kim ******************************************************************************/
2051c0e1b6dSJung-uk Kim
2061c0e1b6dSJung-uk Kim BOOLEAN
AcpiDmCheckForSymbolicOpcode(ACPI_PARSE_OBJECT * Op,ACPI_OP_WALK_INFO * Info)2071c0e1b6dSJung-uk Kim AcpiDmCheckForSymbolicOpcode (
2081c0e1b6dSJung-uk Kim ACPI_PARSE_OBJECT *Op,
2091c0e1b6dSJung-uk Kim ACPI_OP_WALK_INFO *Info)
2101c0e1b6dSJung-uk Kim {
2111c0e1b6dSJung-uk Kim char *OperatorSymbol = NULL;
2121cc50d6bSJung-uk Kim ACPI_PARSE_OBJECT *Argument1;
2131cc50d6bSJung-uk Kim ACPI_PARSE_OBJECT *Argument2;
2141c0e1b6dSJung-uk Kim ACPI_PARSE_OBJECT *Target;
2151cc50d6bSJung-uk Kim ACPI_PARSE_OBJECT *Target2;
2161c0e1b6dSJung-uk Kim
2171c0e1b6dSJung-uk Kim
2181c0e1b6dSJung-uk Kim /* Exit immediately if ASL+ not enabled */
2191c0e1b6dSJung-uk Kim
2201c0e1b6dSJung-uk Kim if (!AcpiGbl_CstyleDisassembly)
2211c0e1b6dSJung-uk Kim {
2221c0e1b6dSJung-uk Kim return (FALSE);
2231c0e1b6dSJung-uk Kim }
2241c0e1b6dSJung-uk Kim
2251c0e1b6dSJung-uk Kim /* Get the first operand */
2261c0e1b6dSJung-uk Kim
2271cc50d6bSJung-uk Kim Argument1 = AcpiPsGetArg (Op, 0);
2281cc50d6bSJung-uk Kim if (!Argument1)
2291c0e1b6dSJung-uk Kim {
2301c0e1b6dSJung-uk Kim return (FALSE);
2311c0e1b6dSJung-uk Kim }
2321c0e1b6dSJung-uk Kim
2331c0e1b6dSJung-uk Kim /* Get the second operand */
2341c0e1b6dSJung-uk Kim
2351cc50d6bSJung-uk Kim Argument2 = Argument1->Common.Next;
2361c0e1b6dSJung-uk Kim
2371c0e1b6dSJung-uk Kim /* Setup the operator string for this opcode */
2381c0e1b6dSJung-uk Kim
2391c0e1b6dSJung-uk Kim switch (Op->Common.AmlOpcode)
2401c0e1b6dSJung-uk Kim {
2411c0e1b6dSJung-uk Kim case AML_ADD_OP:
2421c0e1b6dSJung-uk Kim OperatorSymbol = " + ";
2431c0e1b6dSJung-uk Kim break;
2441c0e1b6dSJung-uk Kim
2451c0e1b6dSJung-uk Kim case AML_SUBTRACT_OP:
2461c0e1b6dSJung-uk Kim OperatorSymbol = " - ";
2471c0e1b6dSJung-uk Kim break;
2481c0e1b6dSJung-uk Kim
2491c0e1b6dSJung-uk Kim case AML_MULTIPLY_OP:
2501c0e1b6dSJung-uk Kim OperatorSymbol = " * ";
2511c0e1b6dSJung-uk Kim break;
2521c0e1b6dSJung-uk Kim
2531c0e1b6dSJung-uk Kim case AML_DIVIDE_OP:
2541c0e1b6dSJung-uk Kim OperatorSymbol = " / ";
2551c0e1b6dSJung-uk Kim break;
2561c0e1b6dSJung-uk Kim
2571c0e1b6dSJung-uk Kim case AML_MOD_OP:
2581c0e1b6dSJung-uk Kim OperatorSymbol = " % ";
2591c0e1b6dSJung-uk Kim break;
2601c0e1b6dSJung-uk Kim
2611c0e1b6dSJung-uk Kim case AML_SHIFT_LEFT_OP:
2621c0e1b6dSJung-uk Kim OperatorSymbol = " << ";
2631c0e1b6dSJung-uk Kim break;
2641c0e1b6dSJung-uk Kim
2651c0e1b6dSJung-uk Kim case AML_SHIFT_RIGHT_OP:
2661c0e1b6dSJung-uk Kim OperatorSymbol = " >> ";
2671c0e1b6dSJung-uk Kim break;
2681c0e1b6dSJung-uk Kim
2691c0e1b6dSJung-uk Kim case AML_BIT_AND_OP:
2701c0e1b6dSJung-uk Kim OperatorSymbol = " & ";
2711c0e1b6dSJung-uk Kim break;
2721c0e1b6dSJung-uk Kim
2731c0e1b6dSJung-uk Kim case AML_BIT_OR_OP:
2741c0e1b6dSJung-uk Kim OperatorSymbol = " | ";
2751c0e1b6dSJung-uk Kim break;
2761c0e1b6dSJung-uk Kim
2771c0e1b6dSJung-uk Kim case AML_BIT_XOR_OP:
2781c0e1b6dSJung-uk Kim OperatorSymbol = " ^ ";
2791c0e1b6dSJung-uk Kim break;
2801c0e1b6dSJung-uk Kim
2811c0e1b6dSJung-uk Kim /* Logical operators, no target */
2821c0e1b6dSJung-uk Kim
2830d84335fSJung-uk Kim case AML_LOGICAL_AND_OP:
2841c0e1b6dSJung-uk Kim OperatorSymbol = " && ";
2851c0e1b6dSJung-uk Kim break;
2861c0e1b6dSJung-uk Kim
2870d84335fSJung-uk Kim case AML_LOGICAL_EQUAL_OP:
2881c0e1b6dSJung-uk Kim OperatorSymbol = " == ";
2891c0e1b6dSJung-uk Kim break;
2901c0e1b6dSJung-uk Kim
2910d84335fSJung-uk Kim case AML_LOGICAL_GREATER_OP:
2921c0e1b6dSJung-uk Kim OperatorSymbol = " > ";
2931c0e1b6dSJung-uk Kim break;
2941c0e1b6dSJung-uk Kim
2950d84335fSJung-uk Kim case AML_LOGICAL_LESS_OP:
2961c0e1b6dSJung-uk Kim OperatorSymbol = " < ";
2971c0e1b6dSJung-uk Kim break;
2981c0e1b6dSJung-uk Kim
2990d84335fSJung-uk Kim case AML_LOGICAL_OR_OP:
3001c0e1b6dSJung-uk Kim OperatorSymbol = " || ";
3011c0e1b6dSJung-uk Kim break;
3021c0e1b6dSJung-uk Kim
3030d84335fSJung-uk Kim case AML_LOGICAL_NOT_OP:
3041c0e1b6dSJung-uk Kim /*
3051c0e1b6dSJung-uk Kim * Check for the LNOT sub-opcodes. These correspond to
3061c0e1b6dSJung-uk Kim * LNotEqual, LLessEqual, and LGreaterEqual. There are
3071c0e1b6dSJung-uk Kim * no actual AML opcodes for these operators.
3081c0e1b6dSJung-uk Kim */
3091cc50d6bSJung-uk Kim switch (Argument1->Common.AmlOpcode)
3101c0e1b6dSJung-uk Kim {
3110d84335fSJung-uk Kim case AML_LOGICAL_EQUAL_OP:
3121c0e1b6dSJung-uk Kim OperatorSymbol = " != ";
3131c0e1b6dSJung-uk Kim break;
3141c0e1b6dSJung-uk Kim
3150d84335fSJung-uk Kim case AML_LOGICAL_GREATER_OP:
3161c0e1b6dSJung-uk Kim OperatorSymbol = " <= ";
3171c0e1b6dSJung-uk Kim break;
3181c0e1b6dSJung-uk Kim
3190d84335fSJung-uk Kim case AML_LOGICAL_LESS_OP:
3201c0e1b6dSJung-uk Kim OperatorSymbol = " >= ";
3211c0e1b6dSJung-uk Kim break;
3221c0e1b6dSJung-uk Kim
3231c0e1b6dSJung-uk Kim default:
3241c0e1b6dSJung-uk Kim
3251c0e1b6dSJung-uk Kim /* Unary LNOT case, emit "!" immediately */
3261c0e1b6dSJung-uk Kim
3271c0e1b6dSJung-uk Kim AcpiOsPrintf ("!");
3281c0e1b6dSJung-uk Kim return (TRUE);
3291c0e1b6dSJung-uk Kim }
3301c0e1b6dSJung-uk Kim
3311cc50d6bSJung-uk Kim Argument1->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX;
3321c0e1b6dSJung-uk Kim Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
3331c0e1b6dSJung-uk Kim
3341c0e1b6dSJung-uk Kim /* Save symbol string in the next child (not peer) */
3351c0e1b6dSJung-uk Kim
3361cc50d6bSJung-uk Kim Argument2 = AcpiPsGetArg (Argument1, 0);
3371cc50d6bSJung-uk Kim if (!Argument2)
3381c0e1b6dSJung-uk Kim {
3391c0e1b6dSJung-uk Kim return (FALSE);
3401c0e1b6dSJung-uk Kim }
3411c0e1b6dSJung-uk Kim
3421cc50d6bSJung-uk Kim Argument2->Common.OperatorSymbol = OperatorSymbol;
3431c0e1b6dSJung-uk Kim return (TRUE);
3441c0e1b6dSJung-uk Kim
3451c0e1b6dSJung-uk Kim case AML_INDEX_OP:
346f8146b88SJung-uk Kim /*
347f8146b88SJung-uk Kim * Check for constant source operand. Note: although technically
348f8146b88SJung-uk Kim * legal syntax, the iASL compiler does not support this with
349f8146b88SJung-uk Kim * the symbolic operators for Index(). It doesn't make sense to
350f8146b88SJung-uk Kim * use Index() with a constant anyway.
351f8146b88SJung-uk Kim */
3521cc50d6bSJung-uk Kim if ((Argument1->Common.AmlOpcode == AML_STRING_OP) ||
3531cc50d6bSJung-uk Kim (Argument1->Common.AmlOpcode == AML_BUFFER_OP) ||
3541cc50d6bSJung-uk Kim (Argument1->Common.AmlOpcode == AML_PACKAGE_OP) ||
3550d84335fSJung-uk Kim (Argument1->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP))
356f8146b88SJung-uk Kim {
357f8146b88SJung-uk Kim Op->Common.DisasmFlags |= ACPI_PARSEOP_CLOSING_PAREN;
358f8146b88SJung-uk Kim return (FALSE);
359f8146b88SJung-uk Kim }
360f8146b88SJung-uk Kim
361f8146b88SJung-uk Kim /* Index operator is [] */
362f8146b88SJung-uk Kim
3631cc50d6bSJung-uk Kim Argument1->Common.OperatorSymbol = " [";
3641cc50d6bSJung-uk Kim Argument2->Common.OperatorSymbol = "]";
3651c0e1b6dSJung-uk Kim break;
3661c0e1b6dSJung-uk Kim
3671c0e1b6dSJung-uk Kim /* Unary operators */
3681c0e1b6dSJung-uk Kim
3691c0e1b6dSJung-uk Kim case AML_DECREMENT_OP:
3701c0e1b6dSJung-uk Kim OperatorSymbol = "--";
3711c0e1b6dSJung-uk Kim break;
3721c0e1b6dSJung-uk Kim
3731c0e1b6dSJung-uk Kim case AML_INCREMENT_OP:
3741c0e1b6dSJung-uk Kim OperatorSymbol = "++";
3751c0e1b6dSJung-uk Kim break;
3761c0e1b6dSJung-uk Kim
3771c0e1b6dSJung-uk Kim case AML_BIT_NOT_OP:
3781c0e1b6dSJung-uk Kim case AML_STORE_OP:
3791c0e1b6dSJung-uk Kim OperatorSymbol = NULL;
3801c0e1b6dSJung-uk Kim break;
3811c0e1b6dSJung-uk Kim
3821c0e1b6dSJung-uk Kim default:
3831c0e1b6dSJung-uk Kim return (FALSE);
3841c0e1b6dSJung-uk Kim }
3851c0e1b6dSJung-uk Kim
3861cc50d6bSJung-uk Kim if (Argument1->Common.DisasmOpcode == ACPI_DASM_LNOT_SUFFIX)
3871c0e1b6dSJung-uk Kim {
3881c0e1b6dSJung-uk Kim return (TRUE);
3891c0e1b6dSJung-uk Kim }
3901c0e1b6dSJung-uk Kim
3911c0e1b6dSJung-uk Kim /*
3921c0e1b6dSJung-uk Kim * This is the key to how the disassembly of the C-style operators
3931c0e1b6dSJung-uk Kim * works. We save the operator symbol in the first child, thus
3941c0e1b6dSJung-uk Kim * deferring symbol output until after the first operand has been
3951c0e1b6dSJung-uk Kim * emitted.
3961c0e1b6dSJung-uk Kim */
3971cc50d6bSJung-uk Kim if (!Argument1->Common.OperatorSymbol)
3981c0e1b6dSJung-uk Kim {
3991cc50d6bSJung-uk Kim Argument1->Common.OperatorSymbol = OperatorSymbol;
4001c0e1b6dSJung-uk Kim }
4011c0e1b6dSJung-uk Kim
4021c0e1b6dSJung-uk Kim /*
4031c0e1b6dSJung-uk Kim * Check for a valid target as the 3rd (or sometimes 2nd) operand
4041c0e1b6dSJung-uk Kim *
4051c0e1b6dSJung-uk Kim * Compound assignment operator support:
4061c0e1b6dSJung-uk Kim * Attempt to optimize constructs of the form:
4071c0e1b6dSJung-uk Kim * Add (Local1, 0xFF, Local1)
4081c0e1b6dSJung-uk Kim * to:
4091c0e1b6dSJung-uk Kim * Local1 += 0xFF
4101c0e1b6dSJung-uk Kim *
4111c0e1b6dSJung-uk Kim * Only the math operators and Store() have a target.
4121c0e1b6dSJung-uk Kim * Logicals have no target.
4131c0e1b6dSJung-uk Kim */
4141c0e1b6dSJung-uk Kim switch (Op->Common.AmlOpcode)
4151c0e1b6dSJung-uk Kim {
4161c0e1b6dSJung-uk Kim case AML_ADD_OP:
4171c0e1b6dSJung-uk Kim case AML_SUBTRACT_OP:
4181c0e1b6dSJung-uk Kim case AML_MULTIPLY_OP:
4191c0e1b6dSJung-uk Kim case AML_DIVIDE_OP:
4201c0e1b6dSJung-uk Kim case AML_MOD_OP:
4211c0e1b6dSJung-uk Kim case AML_SHIFT_LEFT_OP:
4221c0e1b6dSJung-uk Kim case AML_SHIFT_RIGHT_OP:
4231c0e1b6dSJung-uk Kim case AML_BIT_AND_OP:
4241c0e1b6dSJung-uk Kim case AML_BIT_OR_OP:
4251c0e1b6dSJung-uk Kim case AML_BIT_XOR_OP:
4261c0e1b6dSJung-uk Kim
4271c0e1b6dSJung-uk Kim /* Target is 3rd operand */
4281c0e1b6dSJung-uk Kim
4291cc50d6bSJung-uk Kim Target = Argument2->Common.Next;
4301c0e1b6dSJung-uk Kim if (Op->Common.AmlOpcode == AML_DIVIDE_OP)
4311c0e1b6dSJung-uk Kim {
4321cc50d6bSJung-uk Kim Target2 = Target->Common.Next;
4331cc50d6bSJung-uk Kim
4341c0e1b6dSJung-uk Kim /*
4351c0e1b6dSJung-uk Kim * Divide has an extra target operand (Remainder).
4361cc50d6bSJung-uk Kim * Default behavior is to simply ignore ASL+ conversion
4371cc50d6bSJung-uk Kim * if the remainder target (modulo) is specified.
4381c0e1b6dSJung-uk Kim */
4391cc50d6bSJung-uk Kim if (!AcpiGbl_DoDisassemblerOptimizations)
4401cc50d6bSJung-uk Kim {
4411c0e1b6dSJung-uk Kim if (AcpiDmIsValidTarget (Target))
4421c0e1b6dSJung-uk Kim {
4431cc50d6bSJung-uk Kim Argument1->Common.OperatorSymbol = NULL;
444493deb39SJung-uk Kim Op->Common.DisasmFlags |= ACPI_PARSEOP_LEGACY_ASL_ONLY;
4451c0e1b6dSJung-uk Kim return (FALSE);
4461c0e1b6dSJung-uk Kim }
4471c0e1b6dSJung-uk Kim
4481c0e1b6dSJung-uk Kim Target->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
4491cc50d6bSJung-uk Kim Target = Target2;
4501cc50d6bSJung-uk Kim }
4511cc50d6bSJung-uk Kim else
4521cc50d6bSJung-uk Kim {
4531cc50d6bSJung-uk Kim /*
4541cc50d6bSJung-uk Kim * Divide has an extra target operand (Remainder).
4551cc50d6bSJung-uk Kim * If both targets are specified, it cannot be converted
4561cc50d6bSJung-uk Kim * to a C-style operator.
4571cc50d6bSJung-uk Kim */
4581cc50d6bSJung-uk Kim if (AcpiDmIsValidTarget (Target) &&
4591cc50d6bSJung-uk Kim AcpiDmIsValidTarget (Target2))
4601cc50d6bSJung-uk Kim {
4611cc50d6bSJung-uk Kim Argument1->Common.OperatorSymbol = NULL;
4621cc50d6bSJung-uk Kim Op->Common.DisasmFlags |= ACPI_PARSEOP_LEGACY_ASL_ONLY;
4631cc50d6bSJung-uk Kim return (FALSE);
4641cc50d6bSJung-uk Kim }
4651cc50d6bSJung-uk Kim
4661cc50d6bSJung-uk Kim if (AcpiDmIsValidTarget (Target)) /* Only first Target is valid (remainder) */
4671cc50d6bSJung-uk Kim {
4681cc50d6bSJung-uk Kim /* Convert the Divide to Modulo */
4691cc50d6bSJung-uk Kim
4701cc50d6bSJung-uk Kim Op->Common.AmlOpcode = AML_MOD_OP;
4711cc50d6bSJung-uk Kim
4721cc50d6bSJung-uk Kim Argument1->Common.OperatorSymbol = " % ";
4731cc50d6bSJung-uk Kim Target2->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
4741cc50d6bSJung-uk Kim }
4751cc50d6bSJung-uk Kim else /* Only second Target (quotient) is valid */
4761cc50d6bSJung-uk Kim {
4771cc50d6bSJung-uk Kim Target->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
4781cc50d6bSJung-uk Kim Target = Target2;
4791cc50d6bSJung-uk Kim }
4801cc50d6bSJung-uk Kim }
4811c0e1b6dSJung-uk Kim }
4821c0e1b6dSJung-uk Kim
4831c0e1b6dSJung-uk Kim /* Parser should ensure there is at least a placeholder target */
4841c0e1b6dSJung-uk Kim
4851c0e1b6dSJung-uk Kim if (!Target)
4861c0e1b6dSJung-uk Kim {
4871c0e1b6dSJung-uk Kim return (FALSE);
4881c0e1b6dSJung-uk Kim }
4891c0e1b6dSJung-uk Kim
4901c0e1b6dSJung-uk Kim if (!AcpiDmIsValidTarget (Target))
4911c0e1b6dSJung-uk Kim {
4921c0e1b6dSJung-uk Kim /* Not a valid target (placeholder only, from parser) */
4931c0e1b6dSJung-uk Kim break;
4941c0e1b6dSJung-uk Kim }
4951c0e1b6dSJung-uk Kim
4961c0e1b6dSJung-uk Kim /*
4971c0e1b6dSJung-uk Kim * Promote the target up to the first child in the parse
4981c0e1b6dSJung-uk Kim * tree. This is done because the target will be output
4991c0e1b6dSJung-uk Kim * first, in the form:
5001c0e1b6dSJung-uk Kim * <Target> = Operands...
5011c0e1b6dSJung-uk Kim */
5021c0e1b6dSJung-uk Kim AcpiDmPromoteTarget (Op, Target);
5031c0e1b6dSJung-uk Kim
5045ef50723SJung-uk Kim /* Check operands for conversion to a "Compound Assignment" */
5055ef50723SJung-uk Kim
5065ef50723SJung-uk Kim switch (Op->Common.AmlOpcode)
5075ef50723SJung-uk Kim {
5085ef50723SJung-uk Kim /* Commutative operators */
5095ef50723SJung-uk Kim
5105ef50723SJung-uk Kim case AML_ADD_OP:
5115ef50723SJung-uk Kim case AML_MULTIPLY_OP:
5125ef50723SJung-uk Kim case AML_BIT_AND_OP:
5135ef50723SJung-uk Kim case AML_BIT_OR_OP:
5145ef50723SJung-uk Kim case AML_BIT_XOR_OP:
5151c0e1b6dSJung-uk Kim /*
5165ef50723SJung-uk Kim * For the commutative operators, we can convert to a
5175ef50723SJung-uk Kim * compound statement only if at least one (either) operand
5185ef50723SJung-uk Kim * is the same as the target.
5191c0e1b6dSJung-uk Kim *
5205ef50723SJung-uk Kim * Add (A, B, A) --> A += B
5215ef50723SJung-uk Kim * Add (B, A, A) --> A += B
5225ef50723SJung-uk Kim * Add (B, C, A) --> A = (B + C)
5231c0e1b6dSJung-uk Kim */
5241cc50d6bSJung-uk Kim if ((AcpiDmIsTargetAnOperand (Target, Argument1, TRUE)) ||
5251cc50d6bSJung-uk Kim (AcpiDmIsTargetAnOperand (Target, Argument2, TRUE)))
5261c0e1b6dSJung-uk Kim {
5271c0e1b6dSJung-uk Kim Target->Common.OperatorSymbol =
5281c0e1b6dSJung-uk Kim AcpiDmGetCompoundSymbol (Op->Common.AmlOpcode);
5291c0e1b6dSJung-uk Kim
5301c0e1b6dSJung-uk Kim /* Convert operator to compound assignment */
5311c0e1b6dSJung-uk Kim
532f8146b88SJung-uk Kim Op->Common.DisasmFlags |= ACPI_PARSEOP_COMPOUND_ASSIGNMENT;
5331cc50d6bSJung-uk Kim Argument1->Common.OperatorSymbol = NULL;
5341c0e1b6dSJung-uk Kim return (TRUE);
5351c0e1b6dSJung-uk Kim }
5365ef50723SJung-uk Kim break;
5375ef50723SJung-uk Kim
5385ef50723SJung-uk Kim /* Non-commutative operators */
5395ef50723SJung-uk Kim
5405ef50723SJung-uk Kim case AML_SUBTRACT_OP:
5415ef50723SJung-uk Kim case AML_DIVIDE_OP:
5425ef50723SJung-uk Kim case AML_MOD_OP:
5435ef50723SJung-uk Kim case AML_SHIFT_LEFT_OP:
5445ef50723SJung-uk Kim case AML_SHIFT_RIGHT_OP:
5455ef50723SJung-uk Kim /*
5465ef50723SJung-uk Kim * For the non-commutative operators, we can convert to a
5475ef50723SJung-uk Kim * compound statement only if the target is the same as the
5485ef50723SJung-uk Kim * first operand.
5495ef50723SJung-uk Kim *
5505ef50723SJung-uk Kim * Subtract (A, B, A) --> A -= B
5515ef50723SJung-uk Kim * Subtract (B, A, A) --> A = (B - A)
5525ef50723SJung-uk Kim */
5531cc50d6bSJung-uk Kim if ((AcpiDmIsTargetAnOperand (Target, Argument1, TRUE)))
5545ef50723SJung-uk Kim {
5555ef50723SJung-uk Kim Target->Common.OperatorSymbol =
5565ef50723SJung-uk Kim AcpiDmGetCompoundSymbol (Op->Common.AmlOpcode);
5575ef50723SJung-uk Kim
5585ef50723SJung-uk Kim /* Convert operator to compound assignment */
5595ef50723SJung-uk Kim
560f8146b88SJung-uk Kim Op->Common.DisasmFlags |= ACPI_PARSEOP_COMPOUND_ASSIGNMENT;
5611cc50d6bSJung-uk Kim Argument1->Common.OperatorSymbol = NULL;
5625ef50723SJung-uk Kim return (TRUE);
5635ef50723SJung-uk Kim }
5645ef50723SJung-uk Kim break;
5655ef50723SJung-uk Kim
5665ef50723SJung-uk Kim default:
5675ef50723SJung-uk Kim break;
5685ef50723SJung-uk Kim }
5691c0e1b6dSJung-uk Kim
5701c0e1b6dSJung-uk Kim /*
5711c0e1b6dSJung-uk Kim * If we are within a C-style expression, emit an extra open
5721c0e1b6dSJung-uk Kim * paren. Implemented by examining the parent op.
5731c0e1b6dSJung-uk Kim */
5741c0e1b6dSJung-uk Kim switch (Op->Common.Parent->Common.AmlOpcode)
5751c0e1b6dSJung-uk Kim {
5761c0e1b6dSJung-uk Kim case AML_ADD_OP:
5771c0e1b6dSJung-uk Kim case AML_SUBTRACT_OP:
5781c0e1b6dSJung-uk Kim case AML_MULTIPLY_OP:
5791c0e1b6dSJung-uk Kim case AML_DIVIDE_OP:
5801c0e1b6dSJung-uk Kim case AML_MOD_OP:
5811c0e1b6dSJung-uk Kim case AML_SHIFT_LEFT_OP:
5821c0e1b6dSJung-uk Kim case AML_SHIFT_RIGHT_OP:
5831c0e1b6dSJung-uk Kim case AML_BIT_AND_OP:
5841c0e1b6dSJung-uk Kim case AML_BIT_OR_OP:
5851c0e1b6dSJung-uk Kim case AML_BIT_XOR_OP:
5860d84335fSJung-uk Kim case AML_LOGICAL_AND_OP:
5870d84335fSJung-uk Kim case AML_LOGICAL_EQUAL_OP:
5880d84335fSJung-uk Kim case AML_LOGICAL_GREATER_OP:
5890d84335fSJung-uk Kim case AML_LOGICAL_LESS_OP:
5900d84335fSJung-uk Kim case AML_LOGICAL_OR_OP:
5911c0e1b6dSJung-uk Kim
5921c0e1b6dSJung-uk Kim Op->Common.DisasmFlags |= ACPI_PARSEOP_ASSIGNMENT;
5931c0e1b6dSJung-uk Kim AcpiOsPrintf ("(");
5941c0e1b6dSJung-uk Kim break;
5951c0e1b6dSJung-uk Kim
5961c0e1b6dSJung-uk Kim default:
5971c0e1b6dSJung-uk Kim break;
5981c0e1b6dSJung-uk Kim }
5991c0e1b6dSJung-uk Kim
6001c0e1b6dSJung-uk Kim /* Normal output for ASL/AML operators with a target operand */
6011c0e1b6dSJung-uk Kim
6021c0e1b6dSJung-uk Kim Target->Common.OperatorSymbol = " = (";
6031c0e1b6dSJung-uk Kim return (TRUE);
6041c0e1b6dSJung-uk Kim
6051c0e1b6dSJung-uk Kim /* Binary operators, no parens */
6061c0e1b6dSJung-uk Kim
6071c0e1b6dSJung-uk Kim case AML_DECREMENT_OP:
6081c0e1b6dSJung-uk Kim case AML_INCREMENT_OP:
6091c0e1b6dSJung-uk Kim return (TRUE);
6101c0e1b6dSJung-uk Kim
6111c0e1b6dSJung-uk Kim case AML_INDEX_OP:
6121c0e1b6dSJung-uk Kim
6131c0e1b6dSJung-uk Kim /* Target is optional, 3rd operand */
6141c0e1b6dSJung-uk Kim
6151cc50d6bSJung-uk Kim Target = Argument2->Common.Next;
6161c0e1b6dSJung-uk Kim if (AcpiDmIsValidTarget (Target))
6171c0e1b6dSJung-uk Kim {
6181c0e1b6dSJung-uk Kim AcpiDmPromoteTarget (Op, Target);
6191c0e1b6dSJung-uk Kim
6201c0e1b6dSJung-uk Kim if (!Target->Common.OperatorSymbol)
6211c0e1b6dSJung-uk Kim {
6221c0e1b6dSJung-uk Kim Target->Common.OperatorSymbol = " = ";
6231c0e1b6dSJung-uk Kim }
6241c0e1b6dSJung-uk Kim }
6251c0e1b6dSJung-uk Kim return (TRUE);
6261c0e1b6dSJung-uk Kim
6271c0e1b6dSJung-uk Kim case AML_STORE_OP:
6281c0e1b6dSJung-uk Kim /*
6291cc50d6bSJung-uk Kim * For Store, the Target is the 2nd operand. We know the target
6301cc50d6bSJung-uk Kim * is valid, because it is not optional.
631493deb39SJung-uk Kim *
6321cc50d6bSJung-uk Kim * Ignore any optimizations/folding if flag is set.
6331cc50d6bSJung-uk Kim * Used for iASL/disassembler test suite only.
634493deb39SJung-uk Kim */
6351cc50d6bSJung-uk Kim if (AcpiDmIsOptimizationIgnored (Op, Argument1))
636493deb39SJung-uk Kim {
637493deb39SJung-uk Kim return (FALSE);
638493deb39SJung-uk Kim }
639493deb39SJung-uk Kim
640493deb39SJung-uk Kim /*
6411cc50d6bSJung-uk Kim * Perform conversion.
6421c0e1b6dSJung-uk Kim * In the parse tree, simply swap the target with the
6431c0e1b6dSJung-uk Kim * source so that the target is processed first.
6441c0e1b6dSJung-uk Kim */
6451cc50d6bSJung-uk Kim Target = Argument1->Common.Next;
6465ef50723SJung-uk Kim if (!Target)
6475ef50723SJung-uk Kim {
6485ef50723SJung-uk Kim return (FALSE);
6495ef50723SJung-uk Kim }
6501c0e1b6dSJung-uk Kim
6515ef50723SJung-uk Kim AcpiDmPromoteTarget (Op, Target);
6521c0e1b6dSJung-uk Kim if (!Target->Common.OperatorSymbol)
6531c0e1b6dSJung-uk Kim {
6541c0e1b6dSJung-uk Kim Target->Common.OperatorSymbol = " = ";
6551c0e1b6dSJung-uk Kim }
6561c0e1b6dSJung-uk Kim return (TRUE);
6571c0e1b6dSJung-uk Kim
6581c0e1b6dSJung-uk Kim case AML_BIT_NOT_OP:
6591c0e1b6dSJung-uk Kim
6601c0e1b6dSJung-uk Kim /* Target is optional, 2nd operand */
6611c0e1b6dSJung-uk Kim
6621cc50d6bSJung-uk Kim Target = Argument1->Common.Next;
6631c0e1b6dSJung-uk Kim if (!Target)
6641c0e1b6dSJung-uk Kim {
6651c0e1b6dSJung-uk Kim return (FALSE);
6661c0e1b6dSJung-uk Kim }
6671c0e1b6dSJung-uk Kim
6681c0e1b6dSJung-uk Kim if (AcpiDmIsValidTarget (Target))
6691c0e1b6dSJung-uk Kim {
6701c0e1b6dSJung-uk Kim /* Valid target, not a placeholder */
6711c0e1b6dSJung-uk Kim
6721c0e1b6dSJung-uk Kim AcpiDmPromoteTarget (Op, Target);
6731c0e1b6dSJung-uk Kim Target->Common.OperatorSymbol = " = ~";
6741c0e1b6dSJung-uk Kim }
6751c0e1b6dSJung-uk Kim else
6761c0e1b6dSJung-uk Kim {
6771c0e1b6dSJung-uk Kim /* No target. Emit this prefix operator immediately */
6781c0e1b6dSJung-uk Kim
6791c0e1b6dSJung-uk Kim AcpiOsPrintf ("~");
6801c0e1b6dSJung-uk Kim }
6811c0e1b6dSJung-uk Kim return (TRUE);
6821c0e1b6dSJung-uk Kim
6831c0e1b6dSJung-uk Kim default:
6841c0e1b6dSJung-uk Kim break;
6851c0e1b6dSJung-uk Kim }
6861c0e1b6dSJung-uk Kim
6871c0e1b6dSJung-uk Kim /* All other operators, emit an open paren */
6881c0e1b6dSJung-uk Kim
6891c0e1b6dSJung-uk Kim AcpiOsPrintf ("(");
6901c0e1b6dSJung-uk Kim return (TRUE);
6911c0e1b6dSJung-uk Kim }
6921c0e1b6dSJung-uk Kim
6931c0e1b6dSJung-uk Kim
6941c0e1b6dSJung-uk Kim /*******************************************************************************
6951c0e1b6dSJung-uk Kim *
6961cc50d6bSJung-uk Kim * FUNCTION: AcpiDmIsOptimizationIgnored
6971cc50d6bSJung-uk Kim *
6981cc50d6bSJung-uk Kim * PARAMETERS: StoreOp - Store operator parse object
6991cc50d6bSJung-uk Kim * StoreArgument - Target associate with the Op
7001cc50d6bSJung-uk Kim *
7011cc50d6bSJung-uk Kim * RETURN: TRUE if this Store operator should not be converted/removed.
7021cc50d6bSJung-uk Kim *
7031cc50d6bSJung-uk Kim * DESCRIPTION: The following function implements "Do not optimize if a
7041cc50d6bSJung-uk Kim * store is immediately followed by a math/bit operator that
7051cc50d6bSJung-uk Kim * has no target".
7061cc50d6bSJung-uk Kim *
7071cc50d6bSJung-uk Kim * Function is ignored if DoDisassemblerOptimizations is TRUE.
7081cc50d6bSJung-uk Kim * This is the default, ignore this function.
7091cc50d6bSJung-uk Kim *
7101cc50d6bSJung-uk Kim * Disables these types of optimizations, and simply emits
7111cc50d6bSJung-uk Kim * legacy ASL code:
7121cc50d6bSJung-uk Kim * Store (Add (INT1, 4), INT2) --> Add (INT1, 4, INT2)
7131cc50d6bSJung-uk Kim * --> INT2 = INT1 + 4
7141cc50d6bSJung-uk Kim *
7151cc50d6bSJung-uk Kim * Store (Not (INT1), INT2) --> Not (INT1, INT2)
7161cc50d6bSJung-uk Kim * --> INT2 = ~INT1
7171cc50d6bSJung-uk Kim *
7181cc50d6bSJung-uk Kim * Used only for the ASL test suite. For the test suite, we
7191cc50d6bSJung-uk Kim * don't want to perform some optimizations to ensure binary
7201cc50d6bSJung-uk Kim * compatibility with the generation of the legacy ASL->AML.
7211cc50d6bSJung-uk Kim * In other words, for all test modules we want exactly:
7221cc50d6bSJung-uk Kim * (ASL+ -> AML) == (ASL- -> AML)
7231cc50d6bSJung-uk Kim *
7241cc50d6bSJung-uk Kim ******************************************************************************/
7251cc50d6bSJung-uk Kim
7261cc50d6bSJung-uk Kim static BOOLEAN
AcpiDmIsOptimizationIgnored(ACPI_PARSE_OBJECT * StoreOp,ACPI_PARSE_OBJECT * StoreArgument)7271cc50d6bSJung-uk Kim AcpiDmIsOptimizationIgnored (
7281cc50d6bSJung-uk Kim ACPI_PARSE_OBJECT *StoreOp,
7291cc50d6bSJung-uk Kim ACPI_PARSE_OBJECT *StoreArgument)
7301cc50d6bSJung-uk Kim {
7311cc50d6bSJung-uk Kim ACPI_PARSE_OBJECT *Argument1;
7321cc50d6bSJung-uk Kim ACPI_PARSE_OBJECT *Argument2;
7331cc50d6bSJung-uk Kim ACPI_PARSE_OBJECT *Target;
7341cc50d6bSJung-uk Kim
7351cc50d6bSJung-uk Kim
7361cc50d6bSJung-uk Kim /* No optimizations/folding for the typical case */
7371cc50d6bSJung-uk Kim
7381cc50d6bSJung-uk Kim if (AcpiGbl_DoDisassemblerOptimizations)
7391cc50d6bSJung-uk Kim {
7401cc50d6bSJung-uk Kim return (FALSE);
7411cc50d6bSJung-uk Kim }
7421cc50d6bSJung-uk Kim
7431cc50d6bSJung-uk Kim /*
7441cc50d6bSJung-uk Kim * Only a small subset of ASL/AML operators can be optimized.
7451cc50d6bSJung-uk Kim * Can only optimize/fold if there is no target (or targets)
7461cc50d6bSJung-uk Kim * specified for the operator. And of course, the operator
747f15e9afbSJung-uk Kim * is surrounded by a Store() operator.
7481cc50d6bSJung-uk Kim */
7491cc50d6bSJung-uk Kim switch (StoreArgument->Common.AmlOpcode)
7501cc50d6bSJung-uk Kim {
7511cc50d6bSJung-uk Kim case AML_ADD_OP:
7521cc50d6bSJung-uk Kim case AML_SUBTRACT_OP:
7531cc50d6bSJung-uk Kim case AML_MULTIPLY_OP:
7541cc50d6bSJung-uk Kim case AML_MOD_OP:
7551cc50d6bSJung-uk Kim case AML_SHIFT_LEFT_OP:
7561cc50d6bSJung-uk Kim case AML_SHIFT_RIGHT_OP:
7571cc50d6bSJung-uk Kim case AML_BIT_AND_OP:
7581cc50d6bSJung-uk Kim case AML_BIT_OR_OP:
7591cc50d6bSJung-uk Kim case AML_BIT_XOR_OP:
7601cc50d6bSJung-uk Kim case AML_INDEX_OP:
7611cc50d6bSJung-uk Kim
7621cc50d6bSJung-uk Kim /* These operators have two arguments and one target */
7631cc50d6bSJung-uk Kim
7641cc50d6bSJung-uk Kim Argument1 = StoreArgument->Common.Value.Arg;
7651cc50d6bSJung-uk Kim Argument2 = Argument1->Common.Next;
7661cc50d6bSJung-uk Kim Target = Argument2->Common.Next;
7671cc50d6bSJung-uk Kim
7681cc50d6bSJung-uk Kim if (!AcpiDmIsValidTarget (Target))
7691cc50d6bSJung-uk Kim {
7701cc50d6bSJung-uk Kim StoreOp->Common.DisasmFlags |= ACPI_PARSEOP_LEGACY_ASL_ONLY;
7711cc50d6bSJung-uk Kim return (TRUE);
7721cc50d6bSJung-uk Kim }
7731cc50d6bSJung-uk Kim break;
7741cc50d6bSJung-uk Kim
7751cc50d6bSJung-uk Kim case AML_DIVIDE_OP:
7761cc50d6bSJung-uk Kim
7771cc50d6bSJung-uk Kim /* This operator has two arguments and two targets */
7781cc50d6bSJung-uk Kim
7791cc50d6bSJung-uk Kim Argument1 = StoreArgument->Common.Value.Arg;
7801cc50d6bSJung-uk Kim Argument2 = Argument1->Common.Next;
7811cc50d6bSJung-uk Kim Target = Argument2->Common.Next;
7821cc50d6bSJung-uk Kim
7831cc50d6bSJung-uk Kim if (!AcpiDmIsValidTarget (Target) ||
7841cc50d6bSJung-uk Kim !AcpiDmIsValidTarget (Target->Common.Next))
7851cc50d6bSJung-uk Kim {
7861cc50d6bSJung-uk Kim StoreOp->Common.DisasmFlags |= ACPI_PARSEOP_LEGACY_ASL_ONLY;
7871cc50d6bSJung-uk Kim return (TRUE);
7881cc50d6bSJung-uk Kim }
7891cc50d6bSJung-uk Kim break;
7901cc50d6bSJung-uk Kim
7911cc50d6bSJung-uk Kim case AML_BIT_NOT_OP:
7921cc50d6bSJung-uk Kim
7931cc50d6bSJung-uk Kim /* This operator has one operand and one target */
7941cc50d6bSJung-uk Kim
7951cc50d6bSJung-uk Kim Argument1 = StoreArgument->Common.Value.Arg;
7961cc50d6bSJung-uk Kim Target = Argument1->Common.Next;
7971cc50d6bSJung-uk Kim
7981cc50d6bSJung-uk Kim if (!AcpiDmIsValidTarget (Target))
7991cc50d6bSJung-uk Kim {
8001cc50d6bSJung-uk Kim StoreOp->Common.DisasmFlags |= ACPI_PARSEOP_LEGACY_ASL_ONLY;
8011cc50d6bSJung-uk Kim return (TRUE);
8021cc50d6bSJung-uk Kim }
8031cc50d6bSJung-uk Kim break;
8041cc50d6bSJung-uk Kim
8051cc50d6bSJung-uk Kim default:
8061cc50d6bSJung-uk Kim break;
8071cc50d6bSJung-uk Kim }
8081cc50d6bSJung-uk Kim
8091cc50d6bSJung-uk Kim return (FALSE);
8101cc50d6bSJung-uk Kim }
8111cc50d6bSJung-uk Kim
8121cc50d6bSJung-uk Kim
8131cc50d6bSJung-uk Kim /*******************************************************************************
8141cc50d6bSJung-uk Kim *
8151c0e1b6dSJung-uk Kim * FUNCTION: AcpiDmCloseOperator
8161c0e1b6dSJung-uk Kim *
8171c0e1b6dSJung-uk Kim * PARAMETERS: Op - Current parse object
8181c0e1b6dSJung-uk Kim *
8191c0e1b6dSJung-uk Kim * RETURN: None
8201c0e1b6dSJung-uk Kim *
8211c0e1b6dSJung-uk Kim * DESCRIPTION: Closes an operator by adding a closing parentheses if and
8221c0e1b6dSJung-uk Kim * when necessary. Called during ascending phase of the
8231c0e1b6dSJung-uk Kim * parse tree walk.
8241c0e1b6dSJung-uk Kim *
8251c0e1b6dSJung-uk Kim ******************************************************************************/
8261c0e1b6dSJung-uk Kim
8271c0e1b6dSJung-uk Kim void
AcpiDmCloseOperator(ACPI_PARSE_OBJECT * Op)8281c0e1b6dSJung-uk Kim AcpiDmCloseOperator (
8291c0e1b6dSJung-uk Kim ACPI_PARSE_OBJECT *Op)
8301c0e1b6dSJung-uk Kim {
831493deb39SJung-uk Kim
8321c0e1b6dSJung-uk Kim /* Always emit paren if ASL+ disassembly disabled */
8331c0e1b6dSJung-uk Kim
8341c0e1b6dSJung-uk Kim if (!AcpiGbl_CstyleDisassembly)
8351c0e1b6dSJung-uk Kim {
8361c0e1b6dSJung-uk Kim AcpiOsPrintf (")");
8370d84335fSJung-uk Kim ASL_CV_PRINT_ONE_COMMENT (Op, AML_COMMENT_END_NODE, NULL, 0);
8381c0e1b6dSJung-uk Kim return;
8391c0e1b6dSJung-uk Kim }
8401c0e1b6dSJung-uk Kim
841493deb39SJung-uk Kim if (Op->Common.DisasmFlags & ACPI_PARSEOP_LEGACY_ASL_ONLY)
842493deb39SJung-uk Kim {
843493deb39SJung-uk Kim AcpiOsPrintf (")");
8440d84335fSJung-uk Kim ASL_CV_PRINT_ONE_COMMENT (Op, AML_COMMENT_END_NODE, NULL, 0);
845493deb39SJung-uk Kim return;
846493deb39SJung-uk Kim }
847493deb39SJung-uk Kim
8481c0e1b6dSJung-uk Kim /* Check if we need to add an additional closing paren */
8491c0e1b6dSJung-uk Kim
8501c0e1b6dSJung-uk Kim switch (Op->Common.AmlOpcode)
8511c0e1b6dSJung-uk Kim {
8521c0e1b6dSJung-uk Kim case AML_ADD_OP:
8531c0e1b6dSJung-uk Kim case AML_SUBTRACT_OP:
8541c0e1b6dSJung-uk Kim case AML_MULTIPLY_OP:
8551c0e1b6dSJung-uk Kim case AML_DIVIDE_OP:
8561c0e1b6dSJung-uk Kim case AML_MOD_OP:
8571c0e1b6dSJung-uk Kim case AML_SHIFT_LEFT_OP:
8581c0e1b6dSJung-uk Kim case AML_SHIFT_RIGHT_OP:
8591c0e1b6dSJung-uk Kim case AML_BIT_AND_OP:
8601c0e1b6dSJung-uk Kim case AML_BIT_OR_OP:
8611c0e1b6dSJung-uk Kim case AML_BIT_XOR_OP:
8620d84335fSJung-uk Kim case AML_LOGICAL_AND_OP:
8630d84335fSJung-uk Kim case AML_LOGICAL_EQUAL_OP:
8640d84335fSJung-uk Kim case AML_LOGICAL_GREATER_OP:
8650d84335fSJung-uk Kim case AML_LOGICAL_LESS_OP:
8660d84335fSJung-uk Kim case AML_LOGICAL_OR_OP:
8671c0e1b6dSJung-uk Kim
8681c0e1b6dSJung-uk Kim /* Emit paren only if this is not a compound assignment */
8691c0e1b6dSJung-uk Kim
870f8146b88SJung-uk Kim if (Op->Common.DisasmFlags & ACPI_PARSEOP_COMPOUND_ASSIGNMENT)
8711c0e1b6dSJung-uk Kim {
8720d84335fSJung-uk Kim ASL_CV_PRINT_ONE_COMMENT (Op, AML_COMMENT_END_NODE, NULL, 0);
8731c0e1b6dSJung-uk Kim return;
8741c0e1b6dSJung-uk Kim }
8751c0e1b6dSJung-uk Kim
8761c0e1b6dSJung-uk Kim /* Emit extra close paren for assignment within an expression */
8771c0e1b6dSJung-uk Kim
8781c0e1b6dSJung-uk Kim if (Op->Common.DisasmFlags & ACPI_PARSEOP_ASSIGNMENT)
8791c0e1b6dSJung-uk Kim {
8801c0e1b6dSJung-uk Kim AcpiOsPrintf (")");
8811c0e1b6dSJung-uk Kim }
8821c0e1b6dSJung-uk Kim break;
8831c0e1b6dSJung-uk Kim
884f8146b88SJung-uk Kim case AML_INDEX_OP:
885f8146b88SJung-uk Kim
886f8146b88SJung-uk Kim /* This is case for unsupported Index() source constants */
887f8146b88SJung-uk Kim
888f8146b88SJung-uk Kim if (Op->Common.DisasmFlags & ACPI_PARSEOP_CLOSING_PAREN)
889f8146b88SJung-uk Kim {
890f8146b88SJung-uk Kim AcpiOsPrintf (")");
891f8146b88SJung-uk Kim }
8920d84335fSJung-uk Kim ASL_CV_PRINT_ONE_COMMENT (Op, AML_COMMENT_END_NODE, NULL, 0);
893f8146b88SJung-uk Kim return;
8941c0e1b6dSJung-uk Kim
8951c0e1b6dSJung-uk Kim /* No need for parens for these */
8961c0e1b6dSJung-uk Kim
8971c0e1b6dSJung-uk Kim case AML_DECREMENT_OP:
8981c0e1b6dSJung-uk Kim case AML_INCREMENT_OP:
8990d84335fSJung-uk Kim case AML_LOGICAL_NOT_OP:
9001c0e1b6dSJung-uk Kim case AML_BIT_NOT_OP:
9011c0e1b6dSJung-uk Kim case AML_STORE_OP:
9020d84335fSJung-uk Kim ASL_CV_PRINT_ONE_COMMENT (Op, AML_COMMENT_END_NODE, NULL, 0);
9031c0e1b6dSJung-uk Kim return;
9041c0e1b6dSJung-uk Kim
9051c0e1b6dSJung-uk Kim default:
9061c0e1b6dSJung-uk Kim
9071c0e1b6dSJung-uk Kim /* Always emit paren for non-ASL+ operators */
9081c0e1b6dSJung-uk Kim break;
9091c0e1b6dSJung-uk Kim }
9101c0e1b6dSJung-uk Kim
9111c0e1b6dSJung-uk Kim AcpiOsPrintf (")");
9120d84335fSJung-uk Kim ASL_CV_PRINT_ONE_COMMENT (Op, AML_COMMENT_END_NODE, NULL, 0);
9130d84335fSJung-uk Kim
9140d84335fSJung-uk Kim return;
9151c0e1b6dSJung-uk Kim }
9161c0e1b6dSJung-uk Kim
9171c0e1b6dSJung-uk Kim
9181c0e1b6dSJung-uk Kim /*******************************************************************************
9191c0e1b6dSJung-uk Kim *
9201c0e1b6dSJung-uk Kim * FUNCTION: AcpiDmGetCompoundSymbol
9211c0e1b6dSJung-uk Kim *
9221c0e1b6dSJung-uk Kim * PARAMETERS: AslOpcode
9231c0e1b6dSJung-uk Kim *
9241c0e1b6dSJung-uk Kim * RETURN: String containing the compound assignment symbol
9251c0e1b6dSJung-uk Kim *
9261c0e1b6dSJung-uk Kim * DESCRIPTION: Detect opcodes that can be converted to compound assignment,
9271c0e1b6dSJung-uk Kim * return the appropriate operator string.
9281c0e1b6dSJung-uk Kim *
9291c0e1b6dSJung-uk Kim ******************************************************************************/
9301c0e1b6dSJung-uk Kim
9311c0e1b6dSJung-uk Kim static char *
AcpiDmGetCompoundSymbol(UINT16 AmlOpcode)9321c0e1b6dSJung-uk Kim AcpiDmGetCompoundSymbol (
9331c0e1b6dSJung-uk Kim UINT16 AmlOpcode)
9341c0e1b6dSJung-uk Kim {
9351c0e1b6dSJung-uk Kim char *Symbol;
9361c0e1b6dSJung-uk Kim
9371c0e1b6dSJung-uk Kim
9381c0e1b6dSJung-uk Kim switch (AmlOpcode)
9391c0e1b6dSJung-uk Kim {
9401c0e1b6dSJung-uk Kim case AML_ADD_OP:
9411c0e1b6dSJung-uk Kim Symbol = " += ";
9421c0e1b6dSJung-uk Kim break;
9431c0e1b6dSJung-uk Kim
9441c0e1b6dSJung-uk Kim case AML_SUBTRACT_OP:
9451c0e1b6dSJung-uk Kim Symbol = " -= ";
9461c0e1b6dSJung-uk Kim break;
9471c0e1b6dSJung-uk Kim
9481c0e1b6dSJung-uk Kim case AML_MULTIPLY_OP:
9491c0e1b6dSJung-uk Kim Symbol = " *= ";
9501c0e1b6dSJung-uk Kim break;
9511c0e1b6dSJung-uk Kim
9521c0e1b6dSJung-uk Kim case AML_DIVIDE_OP:
9531c0e1b6dSJung-uk Kim Symbol = " /= ";
9541c0e1b6dSJung-uk Kim break;
9551c0e1b6dSJung-uk Kim
9561c0e1b6dSJung-uk Kim case AML_MOD_OP:
9571c0e1b6dSJung-uk Kim Symbol = " %= ";
9581c0e1b6dSJung-uk Kim break;
9591c0e1b6dSJung-uk Kim
9601c0e1b6dSJung-uk Kim case AML_SHIFT_LEFT_OP:
9611c0e1b6dSJung-uk Kim Symbol = " <<= ";
9621c0e1b6dSJung-uk Kim break;
9631c0e1b6dSJung-uk Kim
9641c0e1b6dSJung-uk Kim case AML_SHIFT_RIGHT_OP:
9651c0e1b6dSJung-uk Kim Symbol = " >>= ";
9661c0e1b6dSJung-uk Kim break;
9671c0e1b6dSJung-uk Kim
9681c0e1b6dSJung-uk Kim case AML_BIT_AND_OP:
9691c0e1b6dSJung-uk Kim Symbol = " &= ";
9701c0e1b6dSJung-uk Kim break;
9711c0e1b6dSJung-uk Kim
9721c0e1b6dSJung-uk Kim case AML_BIT_OR_OP:
9731c0e1b6dSJung-uk Kim Symbol = " |= ";
9741c0e1b6dSJung-uk Kim break;
9751c0e1b6dSJung-uk Kim
9761c0e1b6dSJung-uk Kim case AML_BIT_XOR_OP:
9771c0e1b6dSJung-uk Kim Symbol = " ^= ";
9781c0e1b6dSJung-uk Kim break;
9791c0e1b6dSJung-uk Kim
9801c0e1b6dSJung-uk Kim default:
9811c0e1b6dSJung-uk Kim
9821c0e1b6dSJung-uk Kim /* No operator string for all other opcodes */
983f8146b88SJung-uk Kim
9841c0e1b6dSJung-uk Kim return (NULL);
9851c0e1b6dSJung-uk Kim }
9861c0e1b6dSJung-uk Kim
9871c0e1b6dSJung-uk Kim return (Symbol);
9881c0e1b6dSJung-uk Kim }
9891c0e1b6dSJung-uk Kim
9901c0e1b6dSJung-uk Kim
9911c0e1b6dSJung-uk Kim /*******************************************************************************
9921c0e1b6dSJung-uk Kim *
9931c0e1b6dSJung-uk Kim * FUNCTION: AcpiDmPromoteTarget
9941c0e1b6dSJung-uk Kim *
9951c0e1b6dSJung-uk Kim * PARAMETERS: Op - Operator parse object
9961c0e1b6dSJung-uk Kim * Target - Target associate with the Op
9971c0e1b6dSJung-uk Kim *
9981c0e1b6dSJung-uk Kim * RETURN: None
9991c0e1b6dSJung-uk Kim *
10001c0e1b6dSJung-uk Kim * DESCRIPTION: Transform the parse tree by moving the target up to the first
10011c0e1b6dSJung-uk Kim * child of the Op.
10021c0e1b6dSJung-uk Kim *
10031c0e1b6dSJung-uk Kim ******************************************************************************/
10041c0e1b6dSJung-uk Kim
10051c0e1b6dSJung-uk Kim static void
AcpiDmPromoteTarget(ACPI_PARSE_OBJECT * Op,ACPI_PARSE_OBJECT * Target)10061c0e1b6dSJung-uk Kim AcpiDmPromoteTarget (
10071c0e1b6dSJung-uk Kim ACPI_PARSE_OBJECT *Op,
10081c0e1b6dSJung-uk Kim ACPI_PARSE_OBJECT *Target)
10091c0e1b6dSJung-uk Kim {
10101c0e1b6dSJung-uk Kim ACPI_PARSE_OBJECT *Child;
10111c0e1b6dSJung-uk Kim
10121c0e1b6dSJung-uk Kim
10131c0e1b6dSJung-uk Kim /* Link target directly to the Op as first child */
10141c0e1b6dSJung-uk Kim
10151c0e1b6dSJung-uk Kim Child = Op->Common.Value.Arg;
10161c0e1b6dSJung-uk Kim Op->Common.Value.Arg = Target;
10171c0e1b6dSJung-uk Kim Target->Common.Next = Child;
10181c0e1b6dSJung-uk Kim
10191c0e1b6dSJung-uk Kim /* Find the last peer, it is linked to the target. Unlink it. */
10201c0e1b6dSJung-uk Kim
10211c0e1b6dSJung-uk Kim while (Child->Common.Next != Target)
10221c0e1b6dSJung-uk Kim {
10231c0e1b6dSJung-uk Kim Child = Child->Common.Next;
10241c0e1b6dSJung-uk Kim }
10251c0e1b6dSJung-uk Kim
10261c0e1b6dSJung-uk Kim Child->Common.Next = NULL;
10271c0e1b6dSJung-uk Kim }
10281c0e1b6dSJung-uk Kim
10291c0e1b6dSJung-uk Kim
10301c0e1b6dSJung-uk Kim /*******************************************************************************
10311c0e1b6dSJung-uk Kim *
10321c0e1b6dSJung-uk Kim * FUNCTION: AcpiDmIsValidTarget
10331c0e1b6dSJung-uk Kim *
10341c0e1b6dSJung-uk Kim * PARAMETERS: Target - Target Op from the parse tree
10351c0e1b6dSJung-uk Kim *
10361c0e1b6dSJung-uk Kim * RETURN: TRUE if the Target is real. FALSE if it is just a placeholder
10371c0e1b6dSJung-uk Kim * Op that was inserted by the parser.
10381c0e1b6dSJung-uk Kim *
10391c0e1b6dSJung-uk Kim * DESCRIPTION: Determine if a Target Op is a placeholder Op or a real Target.
10401c0e1b6dSJung-uk Kim * In other words, determine if the optional target is used or
10415ef50723SJung-uk Kim * not. Note: If Target is NULL, something is seriously wrong,
10425ef50723SJung-uk Kim * probably with the parse tree.
10431c0e1b6dSJung-uk Kim *
10441c0e1b6dSJung-uk Kim ******************************************************************************/
10451c0e1b6dSJung-uk Kim
10461c0e1b6dSJung-uk Kim static BOOLEAN
AcpiDmIsValidTarget(ACPI_PARSE_OBJECT * Target)10471c0e1b6dSJung-uk Kim AcpiDmIsValidTarget (
10481c0e1b6dSJung-uk Kim ACPI_PARSE_OBJECT *Target)
10491c0e1b6dSJung-uk Kim {
10501c0e1b6dSJung-uk Kim
10515ef50723SJung-uk Kim if (!Target)
10525ef50723SJung-uk Kim {
10535ef50723SJung-uk Kim return (FALSE);
10545ef50723SJung-uk Kim }
10555ef50723SJung-uk Kim
10561c0e1b6dSJung-uk Kim if ((Target->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
10571c0e1b6dSJung-uk Kim (Target->Common.Value.Arg == NULL))
10581c0e1b6dSJung-uk Kim {
10591c0e1b6dSJung-uk Kim return (FALSE);
10601c0e1b6dSJung-uk Kim }
10611c0e1b6dSJung-uk Kim
10621c0e1b6dSJung-uk Kim return (TRUE);
10631c0e1b6dSJung-uk Kim }
10641c0e1b6dSJung-uk Kim
10651c0e1b6dSJung-uk Kim
10661c0e1b6dSJung-uk Kim /*******************************************************************************
10671c0e1b6dSJung-uk Kim *
10681c0e1b6dSJung-uk Kim * FUNCTION: AcpiDmIsTargetAnOperand
10691c0e1b6dSJung-uk Kim *
10701c0e1b6dSJung-uk Kim * PARAMETERS: Target - Target associated with the expression
10711c0e1b6dSJung-uk Kim * Operand - An operand associated with expression
10721c0e1b6dSJung-uk Kim *
10731c0e1b6dSJung-uk Kim * RETURN: TRUE if expression can be converted to a compound assignment.
10741c0e1b6dSJung-uk Kim * FALSE otherwise.
10751c0e1b6dSJung-uk Kim *
10761c0e1b6dSJung-uk Kim * DESCRIPTION: Determine if the Target duplicates the operand, in order to
10771c0e1b6dSJung-uk Kim * detect if the expression can be converted to a compound
1078cd6518c7SJung-uk Kim * assignment. (+=, *=, etc.)
10791c0e1b6dSJung-uk Kim *
10801c0e1b6dSJung-uk Kim ******************************************************************************/
10811c0e1b6dSJung-uk Kim
10821c0e1b6dSJung-uk Kim static BOOLEAN
AcpiDmIsTargetAnOperand(ACPI_PARSE_OBJECT * Target,ACPI_PARSE_OBJECT * Operand,BOOLEAN TopLevel)10831c0e1b6dSJung-uk Kim AcpiDmIsTargetAnOperand (
10841c0e1b6dSJung-uk Kim ACPI_PARSE_OBJECT *Target,
10851c0e1b6dSJung-uk Kim ACPI_PARSE_OBJECT *Operand,
10861c0e1b6dSJung-uk Kim BOOLEAN TopLevel)
10871c0e1b6dSJung-uk Kim {
10881c0e1b6dSJung-uk Kim const ACPI_OPCODE_INFO *OpInfo;
10891c0e1b6dSJung-uk Kim BOOLEAN Same;
10901c0e1b6dSJung-uk Kim
10911c0e1b6dSJung-uk Kim
10921c0e1b6dSJung-uk Kim /*
10931c0e1b6dSJung-uk Kim * Opcodes must match. Note: ignoring the difference between nameseg
10941c0e1b6dSJung-uk Kim * and namepath for now. May be needed later.
10951c0e1b6dSJung-uk Kim */
10961c0e1b6dSJung-uk Kim if (Target->Common.AmlOpcode != Operand->Common.AmlOpcode)
10971c0e1b6dSJung-uk Kim {
10981c0e1b6dSJung-uk Kim return (FALSE);
10991c0e1b6dSJung-uk Kim }
11001c0e1b6dSJung-uk Kim
11011c0e1b6dSJung-uk Kim /* Nodes should match, even if they are NULL */
11021c0e1b6dSJung-uk Kim
11031c0e1b6dSJung-uk Kim if (Target->Common.Node != Operand->Common.Node)
11041c0e1b6dSJung-uk Kim {
11051c0e1b6dSJung-uk Kim return (FALSE);
11061c0e1b6dSJung-uk Kim }
11071c0e1b6dSJung-uk Kim
11081c0e1b6dSJung-uk Kim /* Determine if a child exists */
11091c0e1b6dSJung-uk Kim
11101c0e1b6dSJung-uk Kim OpInfo = AcpiPsGetOpcodeInfo (Operand->Common.AmlOpcode);
11111c0e1b6dSJung-uk Kim if (OpInfo->Flags & AML_HAS_ARGS)
11121c0e1b6dSJung-uk Kim {
11131c0e1b6dSJung-uk Kim Same = AcpiDmIsTargetAnOperand (Target->Common.Value.Arg,
11141c0e1b6dSJung-uk Kim Operand->Common.Value.Arg, FALSE);
11151c0e1b6dSJung-uk Kim if (!Same)
11161c0e1b6dSJung-uk Kim {
11171c0e1b6dSJung-uk Kim return (FALSE);
11181c0e1b6dSJung-uk Kim }
11191c0e1b6dSJung-uk Kim }
11201c0e1b6dSJung-uk Kim
11211c0e1b6dSJung-uk Kim /* Check the next peer, as long as we are not at the top level */
11221c0e1b6dSJung-uk Kim
11231c0e1b6dSJung-uk Kim if ((!TopLevel) &&
11241c0e1b6dSJung-uk Kim Target->Common.Next)
11251c0e1b6dSJung-uk Kim {
11261c0e1b6dSJung-uk Kim Same = AcpiDmIsTargetAnOperand (Target->Common.Next,
11271c0e1b6dSJung-uk Kim Operand->Common.Next, FALSE);
11281c0e1b6dSJung-uk Kim if (!Same)
11291c0e1b6dSJung-uk Kim {
11301c0e1b6dSJung-uk Kim return (FALSE);
11311c0e1b6dSJung-uk Kim }
11321c0e1b6dSJung-uk Kim }
11331c0e1b6dSJung-uk Kim
1134cd6518c7SJung-uk Kim /* Suppress the duplicate operand at the top-level */
11351c0e1b6dSJung-uk Kim
11361c0e1b6dSJung-uk Kim if (TopLevel)
11371c0e1b6dSJung-uk Kim {
11381c0e1b6dSJung-uk Kim Operand->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
11391c0e1b6dSJung-uk Kim }
11401c0e1b6dSJung-uk Kim return (TRUE);
11411c0e1b6dSJung-uk Kim }
1142