xref: /freebsd/sys/contrib/dev/acpica/components/disassembler/dmcstyle.c (revision 804fe2660352e090f4481f2c1d646b508859e79a)
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