153289f6aSNate Lawson /****************************************************************************** 253289f6aSNate Lawson * 353289f6aSNate Lawson * Module Name: aslfold - Constant folding 453289f6aSNate Lawson * 553289f6aSNate Lawson *****************************************************************************/ 653289f6aSNate Lawson 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. 1253289f6aSNate Lawson * All rights reserved. 1353289f6aSNate Lawson * 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 * 119d244b227SJung-uk Kim * Redistribution and use in source and binary forms, with or without 120d244b227SJung-uk Kim * modification, are permitted provided that the following conditions 121d244b227SJung-uk Kim * are met: 122d244b227SJung-uk Kim * 1. Redistributions of source code must retain the above copyright 123d244b227SJung-uk Kim * notice, this list of conditions, and the following disclaimer, 124d244b227SJung-uk Kim * without modification. 125d244b227SJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126d244b227SJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below 127d244b227SJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon 128d244b227SJung-uk Kim * including a substantially similar Disclaimer requirement for further 129d244b227SJung-uk Kim * binary redistribution. 130d244b227SJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names 131d244b227SJung-uk Kim * of any contributors may be used to endorse or promote products derived 132d244b227SJung-uk Kim * from this software without specific prior written permission. 13353289f6aSNate Lawson * 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 147d244b227SJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free 148d244b227SJung-uk Kim * Software Foundation. 14953289f6aSNate Lawson * 1500d84335fSJung-uk Kim *****************************************************************************/ 15153289f6aSNate Lawson 152ab6f3bf9SJung-uk Kim #include <contrib/dev/acpica/compiler/aslcompiler.h> 15353289f6aSNate Lawson #include "aslcompiler.y.h" 154ab6f3bf9SJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h> 15553289f6aSNate Lawson 156ab6f3bf9SJung-uk Kim #include <contrib/dev/acpica/include/acdispat.h> 157ab6f3bf9SJung-uk Kim #include <contrib/dev/acpica/include/acparser.h> 15853289f6aSNate Lawson 15953289f6aSNate Lawson #define _COMPONENT ACPI_COMPILER 16053289f6aSNate Lawson ACPI_MODULE_NAME ("aslfold") 16153289f6aSNate Lawson 162fba7fc7eSJung-uk Kim /* Local prototypes */ 163fba7fc7eSJung-uk Kim 164fba7fc7eSJung-uk Kim static ACPI_STATUS 165fba7fc7eSJung-uk Kim OpcAmlEvaluationWalk1 ( 166fba7fc7eSJung-uk Kim ACPI_PARSE_OBJECT *Op, 167fba7fc7eSJung-uk Kim UINT32 Level, 168fba7fc7eSJung-uk Kim void *Context); 169fba7fc7eSJung-uk Kim 170fba7fc7eSJung-uk Kim static ACPI_STATUS 171fba7fc7eSJung-uk Kim OpcAmlEvaluationWalk2 ( 172fba7fc7eSJung-uk Kim ACPI_PARSE_OBJECT *Op, 173fba7fc7eSJung-uk Kim UINT32 Level, 174fba7fc7eSJung-uk Kim void *Context); 175fba7fc7eSJung-uk Kim 176fba7fc7eSJung-uk Kim static ACPI_STATUS 177fba7fc7eSJung-uk Kim OpcAmlCheckForConstant ( 178fba7fc7eSJung-uk Kim ACPI_PARSE_OBJECT *Op, 179fba7fc7eSJung-uk Kim UINT32 Level, 180fba7fc7eSJung-uk Kim void *Context); 181fba7fc7eSJung-uk Kim 1821df130f1SJung-uk Kim static void 1831df130f1SJung-uk Kim OpcUpdateIntegerNode ( 1841df130f1SJung-uk Kim ACPI_PARSE_OBJECT *Op, 1851df130f1SJung-uk Kim UINT64 Value); 1861df130f1SJung-uk Kim 1877cf3e94aSJung-uk Kim static ACPI_STATUS 1887cf3e94aSJung-uk Kim TrTransformToStoreOp ( 1897cf3e94aSJung-uk Kim ACPI_PARSE_OBJECT *Op, 1907cf3e94aSJung-uk Kim ACPI_WALK_STATE *WalkState); 19153289f6aSNate Lawson 192fba7fc7eSJung-uk Kim static ACPI_STATUS 1937cf3e94aSJung-uk Kim TrSimpleConstantReduction ( 19453289f6aSNate Lawson ACPI_PARSE_OBJECT *Op, 1957cf3e94aSJung-uk Kim ACPI_WALK_STATE *WalkState); 19653289f6aSNate Lawson 1977cf3e94aSJung-uk Kim static void 1987cf3e94aSJung-uk Kim TrInstallReducedConstant ( 19953289f6aSNate Lawson ACPI_PARSE_OBJECT *Op, 2007cf3e94aSJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc); 20153289f6aSNate Lawson 20253289f6aSNate Lawson 20353289f6aSNate Lawson /******************************************************************************* 20453289f6aSNate Lawson * 20553289f6aSNate Lawson * FUNCTION: OpcAmlConstantWalk 20653289f6aSNate Lawson * 20753289f6aSNate Lawson * PARAMETERS: ASL_WALK_CALLBACK 20853289f6aSNate Lawson * 20953289f6aSNate Lawson * RETURN: Status 21053289f6aSNate Lawson * 211f8146b88SJung-uk Kim * DESCRIPTION: Reduce an Op and its subtree to a constant if possible. 212f8146b88SJung-uk Kim * Called during ascent of the parse tree. 21353289f6aSNate Lawson * 21453289f6aSNate Lawson ******************************************************************************/ 21553289f6aSNate Lawson 21653289f6aSNate Lawson ACPI_STATUS 21753289f6aSNate Lawson OpcAmlConstantWalk ( 21853289f6aSNate Lawson ACPI_PARSE_OBJECT *Op, 21953289f6aSNate Lawson UINT32 Level, 22053289f6aSNate Lawson void *Context) 22153289f6aSNate Lawson { 22253289f6aSNate Lawson ACPI_WALK_STATE *WalkState; 22353289f6aSNate Lawson ACPI_STATUS Status = AE_OK; 22453289f6aSNate Lawson 22553289f6aSNate Lawson 2267cf3e94aSJung-uk Kim if (Op->Asl.CompileFlags == 0) 2277cf3e94aSJung-uk Kim { 2287cf3e94aSJung-uk Kim return (AE_OK); 2297cf3e94aSJung-uk Kim } 2307cf3e94aSJung-uk Kim 23153289f6aSNate Lawson /* 23253289f6aSNate Lawson * Only interested in subtrees that could possibly contain 23353289f6aSNate Lawson * expressions that can be evaluated at this time 23453289f6aSNate Lawson */ 2355f9b24faSJung-uk Kim if ((!(Op->Asl.CompileFlags & OP_COMPILE_TIME_CONST)) || 2365f9b24faSJung-uk Kim (Op->Asl.CompileFlags & OP_IS_TARGET)) 23753289f6aSNate Lawson { 23853289f6aSNate Lawson return (AE_OK); 23953289f6aSNate Lawson } 24053289f6aSNate Lawson 24153289f6aSNate Lawson /* Create a new walk state */ 24253289f6aSNate Lawson 24353289f6aSNate Lawson WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); 24453289f6aSNate Lawson if (!WalkState) 24553289f6aSNate Lawson { 2468ef1a331SJung-uk Kim return (AE_NO_MEMORY); 24753289f6aSNate Lawson } 24853289f6aSNate Lawson 24953289f6aSNate Lawson WalkState->NextOp = NULL; 25053289f6aSNate Lawson WalkState->Params = NULL; 25153289f6aSNate Lawson 252fba7fc7eSJung-uk Kim /* 253fba7fc7eSJung-uk Kim * Examine the entire subtree -- all nodes must be constants 254fba7fc7eSJung-uk Kim * or type 3/4/5 opcodes 255fba7fc7eSJung-uk Kim */ 25653289f6aSNate Lawson Status = TrWalkParseTree (Op, ASL_WALK_VISIT_DOWNWARD, 25753289f6aSNate Lawson OpcAmlCheckForConstant, NULL, WalkState); 25853289f6aSNate Lawson 25953289f6aSNate Lawson /* 2607cf3e94aSJung-uk Kim * Did we find an entire subtree that contains all constants 2617cf3e94aSJung-uk Kim * and type 3/4/5 opcodes? 26253289f6aSNate Lawson */ 2637cf3e94aSJung-uk Kim switch (Status) 26453289f6aSNate Lawson { 2657cf3e94aSJung-uk Kim case AE_OK: 26653289f6aSNate Lawson 2677cf3e94aSJung-uk Kim /* Simple case, like Add(3,4) -> 7 */ 2687cf3e94aSJung-uk Kim 2697cf3e94aSJung-uk Kim Status = TrSimpleConstantReduction (Op, WalkState); 2707cf3e94aSJung-uk Kim break; 2717cf3e94aSJung-uk Kim 2727cf3e94aSJung-uk Kim case AE_CTRL_RETURN_VALUE: 2737cf3e94aSJung-uk Kim 2747cf3e94aSJung-uk Kim /* More complex case, like Add(3,4,Local0) -> Store(7,Local0) */ 2757cf3e94aSJung-uk Kim 2767cf3e94aSJung-uk Kim Status = TrTransformToStoreOp (Op, WalkState); 2777cf3e94aSJung-uk Kim break; 2787cf3e94aSJung-uk Kim 2797cf3e94aSJung-uk Kim case AE_TYPE: 2807cf3e94aSJung-uk Kim 28153289f6aSNate Lawson AcpiDsDeleteWalkState (WalkState); 28253289f6aSNate Lawson return (AE_OK); 2837cf3e94aSJung-uk Kim 2847cf3e94aSJung-uk Kim default: 2857cf3e94aSJung-uk Kim AcpiDsDeleteWalkState (WalkState); 2867cf3e94aSJung-uk Kim break; 28753289f6aSNate Lawson } 28853289f6aSNate Lawson 2897cf3e94aSJung-uk Kim if (ACPI_FAILURE (Status)) 2907cf3e94aSJung-uk Kim { 2917cf3e94aSJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, "Cannot resolve, %s\n", 2927cf3e94aSJung-uk Kim AcpiFormatException (Status)); 29353289f6aSNate Lawson 2947cf3e94aSJung-uk Kim /* We could not resolve the subtree for some reason */ 2957cf3e94aSJung-uk Kim 2967cf3e94aSJung-uk Kim AslError (ASL_ERROR, ASL_MSG_CONSTANT_EVALUATION, Op, 2977cf3e94aSJung-uk Kim (char *) AcpiFormatException (Status)); 2987cf3e94aSJung-uk Kim 2997cf3e94aSJung-uk Kim /* Set the subtree value to ZERO anyway. Eliminates further errors */ 3007cf3e94aSJung-uk Kim 3017cf3e94aSJung-uk Kim OpcUpdateIntegerNode (Op, 0); 3027cf3e94aSJung-uk Kim } 3037cf3e94aSJung-uk Kim 304f8146b88SJung-uk Kim return (AE_OK); 3057cf3e94aSJung-uk Kim } 3067cf3e94aSJung-uk Kim 3077cf3e94aSJung-uk Kim 3087cf3e94aSJung-uk Kim /******************************************************************************* 3097cf3e94aSJung-uk Kim * 3107cf3e94aSJung-uk Kim * FUNCTION: OpcAmlCheckForConstant 3117cf3e94aSJung-uk Kim * 3127cf3e94aSJung-uk Kim * PARAMETERS: ASL_WALK_CALLBACK 3137cf3e94aSJung-uk Kim * 3147cf3e94aSJung-uk Kim * RETURN: Status 3157cf3e94aSJung-uk Kim * 316f8146b88SJung-uk Kim * DESCRIPTION: Check one Op for a reducible type 3/4/5 AML opcode. 317f8146b88SJung-uk Kim * This is performed via an upward walk of the parse subtree. 3187cf3e94aSJung-uk Kim * 3197cf3e94aSJung-uk Kim ******************************************************************************/ 3207cf3e94aSJung-uk Kim 3217cf3e94aSJung-uk Kim static ACPI_STATUS 3227cf3e94aSJung-uk Kim OpcAmlCheckForConstant ( 3237cf3e94aSJung-uk Kim ACPI_PARSE_OBJECT *Op, 3247cf3e94aSJung-uk Kim UINT32 Level, 3257cf3e94aSJung-uk Kim void *Context) 3267cf3e94aSJung-uk Kim { 3277cf3e94aSJung-uk Kim ACPI_WALK_STATE *WalkState = Context; 3287cf3e94aSJung-uk Kim ACPI_STATUS Status = AE_OK; 329f8146b88SJung-uk Kim ACPI_PARSE_OBJECT *NextOp; 330f8146b88SJung-uk Kim const ACPI_OPCODE_INFO *OpInfo; 3317cf3e94aSJung-uk Kim 3327cf3e94aSJung-uk Kim 3337cf3e94aSJung-uk Kim WalkState->Op = Op; 3347cf3e94aSJung-uk Kim WalkState->Opcode = Op->Common.AmlOpcode; 3357cf3e94aSJung-uk Kim WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 3367cf3e94aSJung-uk Kim 3377cf3e94aSJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, "[%.4d] Opcode: %12.12s ", 3387cf3e94aSJung-uk Kim Op->Asl.LogicalLineNumber, Op->Asl.ParseOpName); 3397cf3e94aSJung-uk Kim 3407cf3e94aSJung-uk Kim /* 3417cf3e94aSJung-uk Kim * These opcodes do not appear in the OpcodeInfo table, but 3427cf3e94aSJung-uk Kim * they represent constants, so abort the constant walk now. 3437cf3e94aSJung-uk Kim */ 3447cf3e94aSJung-uk Kim if ((WalkState->Opcode == AML_RAW_DATA_BYTE) || 3457cf3e94aSJung-uk Kim (WalkState->Opcode == AML_RAW_DATA_WORD) || 3467cf3e94aSJung-uk Kim (WalkState->Opcode == AML_RAW_DATA_DWORD) || 3477cf3e94aSJung-uk Kim (WalkState->Opcode == AML_RAW_DATA_QWORD)) 3487cf3e94aSJung-uk Kim { 3497cf3e94aSJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, "RAW DATA"); 3507cf3e94aSJung-uk Kim Status = AE_TYPE; 3517cf3e94aSJung-uk Kim goto CleanupAndExit; 3527cf3e94aSJung-uk Kim } 3537cf3e94aSJung-uk Kim 354f8146b88SJung-uk Kim /* 355f8146b88SJung-uk Kim * Search upwards for a possible Name() operator. This is done 356f8146b88SJung-uk Kim * because a type 3/4/5 opcode within a Name() expression 357f8146b88SJung-uk Kim * MUST be reduced to a simple constant. 358f8146b88SJung-uk Kim */ 359f8146b88SJung-uk Kim NextOp = Op->Asl.Parent; 360f8146b88SJung-uk Kim while (NextOp) 361f8146b88SJung-uk Kim { 362f8146b88SJung-uk Kim /* Finished if we find a Name() opcode */ 363f8146b88SJung-uk Kim 364f8146b88SJung-uk Kim if (NextOp->Asl.AmlOpcode == AML_NAME_OP) 365f8146b88SJung-uk Kim { 366f8146b88SJung-uk Kim break; 367f8146b88SJung-uk Kim } 368f8146b88SJung-uk Kim 369f8146b88SJung-uk Kim /* 370f8146b88SJung-uk Kim * Any "deferred" opcodes contain one or more TermArg parameters, 371f8146b88SJung-uk Kim * and thus are not required to be folded to constants at compile 372f8146b88SJung-uk Kim * time. This affects things like Buffer() and Package() objects. 373f8146b88SJung-uk Kim * We just ignore them here. However, any sub-expressions can and 374f8146b88SJung-uk Kim * will still be typechecked. Note: These are called the 375f8146b88SJung-uk Kim * "deferred" opcodes in the AML interpreter. 376f8146b88SJung-uk Kim */ 377f8146b88SJung-uk Kim OpInfo = AcpiPsGetOpcodeInfo (NextOp->Common.AmlOpcode); 378f8146b88SJung-uk Kim if (OpInfo->Flags & AML_DEFER) 379f8146b88SJung-uk Kim { 380f8146b88SJung-uk Kim NextOp = NULL; 381f8146b88SJung-uk Kim break; 382f8146b88SJung-uk Kim } 383f8146b88SJung-uk Kim 384f8146b88SJung-uk Kim NextOp = NextOp->Asl.Parent; 385f8146b88SJung-uk Kim } 386f8146b88SJung-uk Kim 3877cf3e94aSJung-uk Kim /* Type 3/4/5 opcodes have the AML_CONSTANT flag set */ 3887cf3e94aSJung-uk Kim 3897cf3e94aSJung-uk Kim if (!(WalkState->OpInfo->Flags & AML_CONSTANT)) 3907cf3e94aSJung-uk Kim { 391f8146b88SJung-uk Kim /* 392f8146b88SJung-uk Kim * From the ACPI specification: 393f8146b88SJung-uk Kim * 394f8146b88SJung-uk Kim * "The Type 3/4/5 opcodes return a value and can be used in an 395f8146b88SJung-uk Kim * expression that evaluates to a constant. These opcodes may be 396f8146b88SJung-uk Kim * evaluated at ASL compile-time. To ensure that these opcodes 397f8146b88SJung-uk Kim * will evaluate to a constant, the following rules apply: The 398f8146b88SJung-uk Kim * term cannot have a destination (target) operand, and must have 399f8146b88SJung-uk Kim * either a Type3Opcode, Type4Opcode, Type5Opcode, ConstExprTerm, 400f8146b88SJung-uk Kim * Integer, BufferTerm, Package, or String for all arguments." 401f8146b88SJung-uk Kim */ 402f8146b88SJung-uk Kim 403f8146b88SJung-uk Kim /* 404f8146b88SJung-uk Kim * The value (second) operand for the Name() operator MUST 405f8146b88SJung-uk Kim * reduce to a single constant, as per the ACPI specification 406f8146b88SJung-uk Kim * (the operand is a DataObject). This also implies that there 407f8146b88SJung-uk Kim * can be no target operand. Name() is the only ASL operator 408f8146b88SJung-uk Kim * with a "DataObject" as an operand and is thus special- 409f8146b88SJung-uk Kim * cased here. 410f8146b88SJung-uk Kim */ 411f8146b88SJung-uk Kim if (NextOp) /* Inspect a Name() operator */ 412f8146b88SJung-uk Kim { 413f8146b88SJung-uk Kim /* Error if there is a target operand */ 414f8146b88SJung-uk Kim 4155f9b24faSJung-uk Kim if (Op->Asl.CompileFlags & OP_IS_TARGET) 416f8146b88SJung-uk Kim { 417f8146b88SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_INVALID_TARGET, Op, NULL); 418f8146b88SJung-uk Kim Status = AE_TYPE; 419f8146b88SJung-uk Kim } 420f8146b88SJung-uk Kim 421f8146b88SJung-uk Kim /* Error if expression cannot be reduced (folded) */ 422f8146b88SJung-uk Kim 4235f9b24faSJung-uk Kim if (!(NextOp->Asl.CompileFlags & OP_COULD_NOT_REDUCE)) 424f8146b88SJung-uk Kim { 425f8146b88SJung-uk Kim /* Ensure only one error message per statement */ 426f8146b88SJung-uk Kim 4275f9b24faSJung-uk Kim NextOp->Asl.CompileFlags |= OP_COULD_NOT_REDUCE; 428f8146b88SJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, 429f8146b88SJung-uk Kim "**** Could not reduce operands for NAME opcode ****\n"); 430f8146b88SJung-uk Kim 431f8146b88SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_CONSTANT_REQUIRED, Op, 432f8146b88SJung-uk Kim "Constant is required for Name operator"); 433f8146b88SJung-uk Kim Status = AE_TYPE; 434f8146b88SJung-uk Kim } 435f8146b88SJung-uk Kim } 436f8146b88SJung-uk Kim 437f8146b88SJung-uk Kim if (ACPI_FAILURE (Status)) 438f8146b88SJung-uk Kim { 439f8146b88SJung-uk Kim goto CleanupAndExit; 440f8146b88SJung-uk Kim } 441f8146b88SJung-uk Kim 442f8146b88SJung-uk Kim /* This is not a 3/4/5 opcode, but maybe can convert to STORE */ 4437cf3e94aSJung-uk Kim 4445f9b24faSJung-uk Kim if (Op->Asl.CompileFlags & OP_IS_TARGET) 4457cf3e94aSJung-uk Kim { 4467cf3e94aSJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, 447ff879b07SJung-uk Kim "**** Valid Target, transform to Store or CopyObject ****\n"); 4487cf3e94aSJung-uk Kim return (AE_CTRL_RETURN_VALUE); 4497cf3e94aSJung-uk Kim } 4507cf3e94aSJung-uk Kim 4517cf3e94aSJung-uk Kim /* Expression cannot be reduced */ 4527cf3e94aSJung-uk Kim 4537cf3e94aSJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, 454f8146b88SJung-uk Kim "**** Not a Type 3/4/5 opcode or cannot reduce/fold (%s) ****\n", 4557cf3e94aSJung-uk Kim Op->Asl.ParseOpName); 4567cf3e94aSJung-uk Kim 4577cf3e94aSJung-uk Kim Status = AE_TYPE; 4587cf3e94aSJung-uk Kim goto CleanupAndExit; 4597cf3e94aSJung-uk Kim } 4607cf3e94aSJung-uk Kim 461f8146b88SJung-uk Kim /* 462f8146b88SJung-uk Kim * TBD: Ignore buffer constants for now. The problem is that these 463f8146b88SJung-uk Kim * constants have been transformed into RAW_DATA at this point, from 464f8146b88SJung-uk Kim * the parse tree transform process which currently happens before 465f8146b88SJung-uk Kim * the constant folding process. We may need to defer this transform 466f8146b88SJung-uk Kim * for buffer until after the constant folding. 467f8146b88SJung-uk Kim */ 468f8146b88SJung-uk Kim if (WalkState->Opcode == AML_BUFFER_OP) 469f8146b88SJung-uk Kim { 470f8146b88SJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, 471ff879b07SJung-uk Kim "\nBuffer constant reduction is currently not supported\n"); 472f8146b88SJung-uk Kim 473f8146b88SJung-uk Kim if (NextOp) /* Found a Name() operator, error */ 474f8146b88SJung-uk Kim { 475f8146b88SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_UNSUPPORTED, Op, 476f8146b88SJung-uk Kim "Buffer expression cannot be reduced"); 477f8146b88SJung-uk Kim } 478f8146b88SJung-uk Kim 479f8146b88SJung-uk Kim Status = AE_TYPE; 480f8146b88SJung-uk Kim goto CleanupAndExit; 481f8146b88SJung-uk Kim } 482f8146b88SJung-uk Kim 4837cf3e94aSJung-uk Kim /* Debug output */ 4847cf3e94aSJung-uk Kim 4857cf3e94aSJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, "TYPE_345"); 4867cf3e94aSJung-uk Kim 4875f9b24faSJung-uk Kim if (Op->Asl.CompileFlags & OP_IS_TARGET) 4887cf3e94aSJung-uk Kim { 4897cf3e94aSJung-uk Kim if (Op->Asl.ParseOpcode == PARSEOP_ZERO) 4907cf3e94aSJung-uk Kim { 4917cf3e94aSJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, "%-16s", " NULL TARGET"); 49253289f6aSNate Lawson } 49353289f6aSNate Lawson else 49453289f6aSNate Lawson { 4957cf3e94aSJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, "%-16s", " VALID TARGET"); 4967cf3e94aSJung-uk Kim } 4977cf3e94aSJung-uk Kim } 498f8146b88SJung-uk Kim 4995f9b24faSJung-uk Kim if (Op->Asl.CompileFlags & OP_IS_TERM_ARG) 5007cf3e94aSJung-uk Kim { 5017cf3e94aSJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, "%-16s", " TERMARG"); 5027cf3e94aSJung-uk Kim } 5037cf3e94aSJung-uk Kim 5047cf3e94aSJung-uk Kim CleanupAndExit: 5057cf3e94aSJung-uk Kim 5067cf3e94aSJung-uk Kim /* Dump the node compile flags also */ 5077cf3e94aSJung-uk Kim 5085f9b24faSJung-uk Kim TrPrintOpFlags (Op->Asl.CompileFlags, ASL_PARSE_OUTPUT); 5097cf3e94aSJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, "\n"); 5107cf3e94aSJung-uk Kim return (Status); 5117cf3e94aSJung-uk Kim } 5127cf3e94aSJung-uk Kim 5137cf3e94aSJung-uk Kim 5147cf3e94aSJung-uk Kim /******************************************************************************* 5157cf3e94aSJung-uk Kim * 5167cf3e94aSJung-uk Kim * FUNCTION: TrSimpleConstantReduction 5177cf3e94aSJung-uk Kim * 5187cf3e94aSJung-uk Kim * PARAMETERS: Op - Parent operator to be transformed 5197cf3e94aSJung-uk Kim * WalkState - Current walk state 5207cf3e94aSJung-uk Kim * 5217cf3e94aSJung-uk Kim * RETURN: Status 5227cf3e94aSJung-uk Kim * 5237cf3e94aSJung-uk Kim * DESCRIPTION: Reduce an entire AML operation to a single constant. The 5247cf3e94aSJung-uk Kim * operation must not have a target operand. 5257cf3e94aSJung-uk Kim * 5267cf3e94aSJung-uk Kim * Add (32,64) --> 96 5277cf3e94aSJung-uk Kim * 5287cf3e94aSJung-uk Kim ******************************************************************************/ 5297cf3e94aSJung-uk Kim 5307cf3e94aSJung-uk Kim static ACPI_STATUS 5317cf3e94aSJung-uk Kim TrSimpleConstantReduction ( 5327cf3e94aSJung-uk Kim ACPI_PARSE_OBJECT *Op, 5337cf3e94aSJung-uk Kim ACPI_WALK_STATE *WalkState) 5347cf3e94aSJung-uk Kim { 5357cf3e94aSJung-uk Kim ACPI_PARSE_OBJECT *RootOp; 5367cf3e94aSJung-uk Kim ACPI_PARSE_OBJECT *OriginalParentOp; 5377cf3e94aSJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc; 5387cf3e94aSJung-uk Kim ACPI_STATUS Status; 5397cf3e94aSJung-uk Kim 5407cf3e94aSJung-uk Kim 5417cf3e94aSJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, 5427cf3e94aSJung-uk Kim "Simple subtree constant reduction, operator to constant\n"); 54353289f6aSNate Lawson 54453289f6aSNate Lawson /* Allocate a new temporary root for this subtree */ 54553289f6aSNate Lawson 5465f9b24faSJung-uk Kim RootOp = TrAllocateOp (PARSEOP_INTEGER); 54753289f6aSNate Lawson if (!RootOp) 54853289f6aSNate Lawson { 54953289f6aSNate Lawson return (AE_NO_MEMORY); 55053289f6aSNate Lawson } 55153289f6aSNate Lawson 55253289f6aSNate Lawson RootOp->Common.AmlOpcode = AML_INT_EVAL_SUBTREE_OP; 55353289f6aSNate Lawson 55453289f6aSNate Lawson OriginalParentOp = Op->Common.Parent; 55553289f6aSNate Lawson Op->Common.Parent = RootOp; 55653289f6aSNate Lawson 557fba7fc7eSJung-uk Kim /* Hand off the subtree to the AML interpreter */ 558fba7fc7eSJung-uk Kim 5597cf3e94aSJung-uk Kim WalkState->CallerReturnDesc = &ObjDesc; 5607cf3e94aSJung-uk Kim 561fba7fc7eSJung-uk Kim Status = TrWalkParseTree (Op, ASL_WALK_VISIT_TWICE, 562fba7fc7eSJung-uk Kim OpcAmlEvaluationWalk1, OpcAmlEvaluationWalk2, WalkState); 5637cf3e94aSJung-uk Kim 5647cf3e94aSJung-uk Kim /* Restore original parse tree */ 5657cf3e94aSJung-uk Kim 56653289f6aSNate Lawson Op->Common.Parent = OriginalParentOp; 56753289f6aSNate Lawson 5687cf3e94aSJung-uk Kim if (ACPI_FAILURE (Status)) 56953289f6aSNate Lawson { 5707cf3e94aSJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, 5717cf3e94aSJung-uk Kim "Constant Subtree evaluation(1), %s\n", 5727cf3e94aSJung-uk Kim AcpiFormatException (Status)); 5737cf3e94aSJung-uk Kim return (Status); 5747cf3e94aSJung-uk Kim } 57553289f6aSNate Lawson 57653289f6aSNate Lawson /* Get the final result */ 57753289f6aSNate Lawson 57853289f6aSNate Lawson Status = AcpiDsResultPop (&ObjDesc, WalkState); 5791df130f1SJung-uk Kim if (ACPI_FAILURE (Status)) 5801df130f1SJung-uk Kim { 5817cf3e94aSJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, 5827cf3e94aSJung-uk Kim "Constant Subtree evaluation(2), %s\n", 5837cf3e94aSJung-uk Kim AcpiFormatException (Status)); 5847cf3e94aSJung-uk Kim return (Status); 5857cf3e94aSJung-uk Kim } 5867cf3e94aSJung-uk Kim 5875ef50723SJung-uk Kim /* Disconnect any existing children, install new constant */ 5885ef50723SJung-uk Kim 5895ef50723SJung-uk Kim Op->Asl.Child = NULL; 5907cf3e94aSJung-uk Kim TrInstallReducedConstant (Op, ObjDesc); 5917cf3e94aSJung-uk Kim 5927cf3e94aSJung-uk Kim UtSetParseOpName (Op); 5937cf3e94aSJung-uk Kim return (AE_OK); 5947cf3e94aSJung-uk Kim } 5957cf3e94aSJung-uk Kim 5967cf3e94aSJung-uk Kim 5977cf3e94aSJung-uk Kim /******************************************************************************* 5987cf3e94aSJung-uk Kim * 5997cf3e94aSJung-uk Kim * FUNCTION: TrTransformToStoreOp 6007cf3e94aSJung-uk Kim * 6017cf3e94aSJung-uk Kim * PARAMETERS: Op - Parent operator to be transformed 6027cf3e94aSJung-uk Kim * WalkState - Current walk state 6037cf3e94aSJung-uk Kim * 6047cf3e94aSJung-uk Kim * RETURN: Status 6057cf3e94aSJung-uk Kim * 6067cf3e94aSJung-uk Kim * DESCRIPTION: Transforms a single AML operation with a constant and target 6077cf3e94aSJung-uk Kim * to a simple store operation: 6087cf3e94aSJung-uk Kim * 6097cf3e94aSJung-uk Kim * Add (32,64,DATA) --> Store (96,DATA) 6107cf3e94aSJung-uk Kim * 6117cf3e94aSJung-uk Kim ******************************************************************************/ 6127cf3e94aSJung-uk Kim 6137cf3e94aSJung-uk Kim static ACPI_STATUS 6147cf3e94aSJung-uk Kim TrTransformToStoreOp ( 6157cf3e94aSJung-uk Kim ACPI_PARSE_OBJECT *Op, 6167cf3e94aSJung-uk Kim ACPI_WALK_STATE *WalkState) 6177cf3e94aSJung-uk Kim { 6187cf3e94aSJung-uk Kim ACPI_PARSE_OBJECT *OriginalTarget; 6197cf3e94aSJung-uk Kim ACPI_PARSE_OBJECT *NewTarget; 6207cf3e94aSJung-uk Kim ACPI_PARSE_OBJECT *Child1; 6217cf3e94aSJung-uk Kim ACPI_PARSE_OBJECT *Child2; 6227cf3e94aSJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc; 6237cf3e94aSJung-uk Kim ACPI_PARSE_OBJECT *NewParent; 6247cf3e94aSJung-uk Kim ACPI_PARSE_OBJECT *OriginalParent; 6257cf3e94aSJung-uk Kim ACPI_STATUS Status; 626ff879b07SJung-uk Kim UINT16 NewParseOpcode; 627ff879b07SJung-uk Kim UINT16 NewAmlOpcode; 6287cf3e94aSJung-uk Kim 6297cf3e94aSJung-uk Kim 6307cf3e94aSJung-uk Kim /* Extract the operands */ 6317cf3e94aSJung-uk Kim 6327cf3e94aSJung-uk Kim Child1 = Op->Asl.Child; 6337cf3e94aSJung-uk Kim Child2 = Child1->Asl.Next; 6347cf3e94aSJung-uk Kim 6357cf3e94aSJung-uk Kim /* 6367cf3e94aSJung-uk Kim * Special case for DIVIDE -- it has two targets. The first 6377cf3e94aSJung-uk Kim * is for the remainder and if present, we will not attempt 6387cf3e94aSJung-uk Kim * to reduce the expression. 6397cf3e94aSJung-uk Kim */ 6407cf3e94aSJung-uk Kim if (Op->Asl.ParseOpcode == PARSEOP_DIVIDE) 6417cf3e94aSJung-uk Kim { 6427cf3e94aSJung-uk Kim Child2 = Child2->Asl.Next; 6437cf3e94aSJung-uk Kim if (Child2->Asl.ParseOpcode != PARSEOP_ZERO) 6447cf3e94aSJung-uk Kim { 6457cf3e94aSJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, 6467cf3e94aSJung-uk Kim "Cannot reduce DIVIDE - has two targets\n\n"); 6477cf3e94aSJung-uk Kim return (AE_OK); 6481df130f1SJung-uk Kim } 64953289f6aSNate Lawson } 65053289f6aSNate Lawson 651ff879b07SJung-uk Kim switch (Op->Asl.ParseOpcode) 652ff879b07SJung-uk Kim { 653ff879b07SJung-uk Kim /* 654ff879b07SJung-uk Kim * Folding of the explicit conversion opcodes must use CopyObject 655ff879b07SJung-uk Kim * instead of Store. This can change the object type of the target 656ff879b07SJung-uk Kim * operand, as per the ACPI specification: 657ff879b07SJung-uk Kim * 658ff879b07SJung-uk Kim * "If the ASL operator is one of the explicit conversion operators 659ff879b07SJung-uk Kim * (ToString, ToInteger, etc., and the CopyObject operator), no 660ff879b07SJung-uk Kim * [implicit] conversion is performed. (In other words, the result 661ff879b07SJung-uk Kim * object is stored directly to the target and completely overwrites 662ff879b07SJung-uk Kim * any existing object already stored at the target)" 663ff879b07SJung-uk Kim */ 664ff879b07SJung-uk Kim case PARSEOP_TOINTEGER: 665ff879b07SJung-uk Kim case PARSEOP_TOSTRING: 666ff879b07SJung-uk Kim case PARSEOP_TOBUFFER: 667ff879b07SJung-uk Kim case PARSEOP_TODECIMALSTRING: 668ff879b07SJung-uk Kim case PARSEOP_TOHEXSTRING: 669ff879b07SJung-uk Kim case PARSEOP_TOBCD: 670ff879b07SJung-uk Kim case PARSEOP_FROMBCD: 671ff879b07SJung-uk Kim 672ff879b07SJung-uk Kim NewParseOpcode = PARSEOP_COPYOBJECT; 673ff879b07SJung-uk Kim NewAmlOpcode = AML_COPY_OBJECT_OP; 674ff879b07SJung-uk Kim 675ff879b07SJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, 676ff879b07SJung-uk Kim "Reduction/Transform to CopyObjectOp: CopyObject(%s, %s)\n", 677ff879b07SJung-uk Kim Child1->Asl.ParseOpName, Child2->Asl.ParseOpName); 678ff879b07SJung-uk Kim break; 679ff879b07SJung-uk Kim 680ff879b07SJung-uk Kim default: 681ff879b07SJung-uk Kim 682ff879b07SJung-uk Kim NewParseOpcode = PARSEOP_STORE; 683ff879b07SJung-uk Kim NewAmlOpcode = AML_STORE_OP; 684ff879b07SJung-uk Kim 685f8146b88SJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, 686f8146b88SJung-uk Kim "Reduction/Transform to StoreOp: Store(%s, %s)\n", 687f8146b88SJung-uk Kim Child1->Asl.ParseOpName, Child2->Asl.ParseOpName); 688ff879b07SJung-uk Kim break; 689ff879b07SJung-uk Kim } 690f8146b88SJung-uk Kim 6917cf3e94aSJung-uk Kim /* 6927cf3e94aSJung-uk Kim * Create a NULL (zero) target so that we can use the 6937cf3e94aSJung-uk Kim * interpreter to evaluate the expression. 6947cf3e94aSJung-uk Kim */ 6955f9b24faSJung-uk Kim NewTarget = TrCreateNullTargetOp (); 6967cf3e94aSJung-uk Kim NewTarget->Common.AmlOpcode = AML_INT_NAMEPATH_OP; 6977cf3e94aSJung-uk Kim 6987cf3e94aSJung-uk Kim /* Handle one-operand cases (NOT, TOBCD, etc.) */ 6997cf3e94aSJung-uk Kim 7007cf3e94aSJung-uk Kim if (!Child2->Asl.Next) 7017cf3e94aSJung-uk Kim { 7027cf3e94aSJung-uk Kim Child2 = Child1; 7037cf3e94aSJung-uk Kim } 7047cf3e94aSJung-uk Kim 7057cf3e94aSJung-uk Kim /* Link in new NULL target as the last operand */ 7067cf3e94aSJung-uk Kim 7077cf3e94aSJung-uk Kim OriginalTarget = Child2->Asl.Next; 7087cf3e94aSJung-uk Kim Child2->Asl.Next = NewTarget; 7097cf3e94aSJung-uk Kim NewTarget->Asl.Parent = OriginalTarget->Asl.Parent; 7107cf3e94aSJung-uk Kim 7115f9b24faSJung-uk Kim NewParent = TrAllocateOp (PARSEOP_INTEGER); 7127cf3e94aSJung-uk Kim NewParent->Common.AmlOpcode = AML_INT_EVAL_SUBTREE_OP; 7137cf3e94aSJung-uk Kim 7147cf3e94aSJung-uk Kim OriginalParent = Op->Common.Parent; 7157cf3e94aSJung-uk Kim Op->Common.Parent = NewParent; 7167cf3e94aSJung-uk Kim 7177cf3e94aSJung-uk Kim /* Hand off the subtree to the AML interpreter */ 7187cf3e94aSJung-uk Kim 7197cf3e94aSJung-uk Kim WalkState->CallerReturnDesc = &ObjDesc; 7207cf3e94aSJung-uk Kim 7217cf3e94aSJung-uk Kim Status = TrWalkParseTree (Op, ASL_WALK_VISIT_TWICE, 7227cf3e94aSJung-uk Kim OpcAmlEvaluationWalk1, OpcAmlEvaluationWalk2, WalkState); 72353289f6aSNate Lawson if (ACPI_FAILURE (Status)) 72453289f6aSNate Lawson { 7257cf3e94aSJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, 7267cf3e94aSJung-uk Kim "Constant Subtree evaluation(3), %s\n", 7277cf3e94aSJung-uk Kim AcpiFormatException (Status)); 7287cf3e94aSJung-uk Kim goto EvalError; 72953289f6aSNate Lawson } 7307cf3e94aSJung-uk Kim 7317cf3e94aSJung-uk Kim /* Get the final result */ 7327cf3e94aSJung-uk Kim 7337cf3e94aSJung-uk Kim Status = AcpiDsResultPop (&ObjDesc, WalkState); 7347cf3e94aSJung-uk Kim if (ACPI_FAILURE (Status)) 73553289f6aSNate Lawson { 7367cf3e94aSJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, 7377cf3e94aSJung-uk Kim "Constant Subtree evaluation(4), %s\n", 7387cf3e94aSJung-uk Kim AcpiFormatException (Status)); 7397cf3e94aSJung-uk Kim goto EvalError; 7407cf3e94aSJung-uk Kim } 7417cf3e94aSJung-uk Kim 7425ef50723SJung-uk Kim /* Truncate any subtree expressions, they have been evaluated */ 7435ef50723SJung-uk Kim 7445ef50723SJung-uk Kim Child1->Asl.Child = NULL; 7455ef50723SJung-uk Kim 7467cf3e94aSJung-uk Kim /* Folded constant is in ObjDesc, store into Child1 */ 7477cf3e94aSJung-uk Kim 7487cf3e94aSJung-uk Kim TrInstallReducedConstant (Child1, ObjDesc); 7497cf3e94aSJung-uk Kim 750ff879b07SJung-uk Kim /* Convert operator to STORE or COPYOBJECT */ 7517cf3e94aSJung-uk Kim 752ff879b07SJung-uk Kim Op->Asl.ParseOpcode = NewParseOpcode; 753ff879b07SJung-uk Kim Op->Asl.AmlOpcode = NewAmlOpcode; 7547cf3e94aSJung-uk Kim UtSetParseOpName (Op); 7557cf3e94aSJung-uk Kim Op->Common.Parent = OriginalParent; 7567cf3e94aSJung-uk Kim 7577cf3e94aSJung-uk Kim /* First child is the folded constant */ 7587cf3e94aSJung-uk Kim 7597cf3e94aSJung-uk Kim /* Second child will be the target */ 7607cf3e94aSJung-uk Kim 7617cf3e94aSJung-uk Kim Child1->Asl.Next = OriginalTarget; 7627cf3e94aSJung-uk Kim return (AE_OK); 7637cf3e94aSJung-uk Kim 7647cf3e94aSJung-uk Kim 7657cf3e94aSJung-uk Kim EvalError: 7667cf3e94aSJung-uk Kim 7677cf3e94aSJung-uk Kim /* Restore original links */ 7687cf3e94aSJung-uk Kim 7697cf3e94aSJung-uk Kim Op->Common.Parent = OriginalParent; 7707cf3e94aSJung-uk Kim Child2->Asl.Next = OriginalTarget; 7717cf3e94aSJung-uk Kim return (Status); 7727cf3e94aSJung-uk Kim } 7737cf3e94aSJung-uk Kim 7747cf3e94aSJung-uk Kim 7757cf3e94aSJung-uk Kim /******************************************************************************* 7767cf3e94aSJung-uk Kim * 7777cf3e94aSJung-uk Kim * FUNCTION: TrInstallReducedConstant 7787cf3e94aSJung-uk Kim * 7797cf3e94aSJung-uk Kim * PARAMETERS: Op - Parent operator to be transformed 7807cf3e94aSJung-uk Kim * ObjDesc - Reduced constant to be installed 7817cf3e94aSJung-uk Kim * 7827cf3e94aSJung-uk Kim * RETURN: None 7837cf3e94aSJung-uk Kim * 7847cf3e94aSJung-uk Kim * DESCRIPTION: Transform the original operator to a simple constant. 7857cf3e94aSJung-uk Kim * Handles Integers, Strings, and Buffers. 7867cf3e94aSJung-uk Kim * 7877cf3e94aSJung-uk Kim ******************************************************************************/ 7887cf3e94aSJung-uk Kim 7897cf3e94aSJung-uk Kim static void 7907cf3e94aSJung-uk Kim TrInstallReducedConstant ( 7917cf3e94aSJung-uk Kim ACPI_PARSE_OBJECT *Op, 7927cf3e94aSJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc) 7937cf3e94aSJung-uk Kim { 7945ef50723SJung-uk Kim ACPI_PARSE_OBJECT *LengthOp; 7955ef50723SJung-uk Kim ACPI_PARSE_OBJECT *DataOp; 7967cf3e94aSJung-uk Kim 7977cf3e94aSJung-uk Kim 7986f1f1a63SJung-uk Kim AslGbl_TotalFolds++; 799fba7fc7eSJung-uk Kim AslError (ASL_OPTIMIZATION, ASL_MSG_CONSTANT_FOLDED, Op, 800fba7fc7eSJung-uk Kim Op->Asl.ParseOpName); 80153289f6aSNate Lawson 80253289f6aSNate Lawson /* 80353289f6aSNate Lawson * Because we know we executed type 3/4/5 opcodes above, we know that 80453289f6aSNate Lawson * the result must be either an Integer, String, or Buffer. 80553289f6aSNate Lawson */ 806a9f12690SJung-uk Kim switch (ObjDesc->Common.Type) 80753289f6aSNate Lawson { 80853289f6aSNate Lawson case ACPI_TYPE_INTEGER: 80953289f6aSNate Lawson 8101df130f1SJung-uk Kim OpcUpdateIntegerNode (Op, ObjDesc->Integer.Value); 81153289f6aSNate Lawson 812fba7fc7eSJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, 8137cf3e94aSJung-uk Kim "Constant expression reduced to (%s) %8.8X%8.8X\n\n", 8141df130f1SJung-uk Kim Op->Asl.ParseOpName, 8151df130f1SJung-uk Kim ACPI_FORMAT_UINT64 (Op->Common.Value.Integer)); 81653289f6aSNate Lawson break; 81753289f6aSNate Lawson 81853289f6aSNate Lawson case ACPI_TYPE_STRING: 81953289f6aSNate Lawson 82053289f6aSNate Lawson Op->Asl.ParseOpcode = PARSEOP_STRING_LITERAL; 82153289f6aSNate Lawson Op->Common.AmlOpcode = AML_STRING_OP; 8225ef50723SJung-uk Kim Op->Asl.AmlLength = strlen (ObjDesc->String.Pointer) + 1; 82353289f6aSNate Lawson Op->Common.Value.String = ObjDesc->String.Pointer; 82453289f6aSNate Lawson 825fba7fc7eSJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, 8267cf3e94aSJung-uk Kim "Constant expression reduced to (STRING) %s\n\n", 82753289f6aSNate Lawson Op->Common.Value.String); 82853289f6aSNate Lawson break; 82953289f6aSNate Lawson 83053289f6aSNate Lawson case ACPI_TYPE_BUFFER: 8315ef50723SJung-uk Kim /* 8325ef50723SJung-uk Kim * Create a new parse subtree of the form: 8335ef50723SJung-uk Kim * 8345ef50723SJung-uk Kim * BUFFER (Buffer AML opcode) 8355ef50723SJung-uk Kim * INTEGER (Buffer length in bytes) 8365ef50723SJung-uk Kim * RAW_DATA (Buffer byte data) 8375ef50723SJung-uk Kim */ 83853289f6aSNate Lawson Op->Asl.ParseOpcode = PARSEOP_BUFFER; 83953289f6aSNate Lawson Op->Common.AmlOpcode = AML_BUFFER_OP; 8405f9b24faSJung-uk Kim Op->Asl.CompileFlags = OP_AML_PACKAGE; 84153289f6aSNate Lawson UtSetParseOpName (Op); 84253289f6aSNate Lawson 84353289f6aSNate Lawson /* Child node is the buffer length */ 84453289f6aSNate Lawson 8455f9b24faSJung-uk Kim LengthOp = TrAllocateOp (PARSEOP_INTEGER); 84653289f6aSNate Lawson 8475ef50723SJung-uk Kim LengthOp->Asl.AmlOpcode = AML_DWORD_OP; 8485ef50723SJung-uk Kim LengthOp->Asl.Value.Integer = ObjDesc->Buffer.Length; 8495ef50723SJung-uk Kim LengthOp->Asl.Parent = Op; 8505ef50723SJung-uk Kim (void) OpcSetOptimalIntegerSize (LengthOp); 85153289f6aSNate Lawson 8525ef50723SJung-uk Kim Op->Asl.Child = LengthOp; 85353289f6aSNate Lawson 8545ef50723SJung-uk Kim /* Next child is the raw buffer data */ 85553289f6aSNate Lawson 8565f9b24faSJung-uk Kim DataOp = TrAllocateOp (PARSEOP_RAW_DATA); 8575ef50723SJung-uk Kim DataOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER; 8585ef50723SJung-uk Kim DataOp->Asl.AmlLength = ObjDesc->Buffer.Length; 8595ef50723SJung-uk Kim DataOp->Asl.Value.String = (char *) ObjDesc->Buffer.Pointer; 8605ef50723SJung-uk Kim DataOp->Asl.Parent = Op; 86153289f6aSNate Lawson 8625ef50723SJung-uk Kim LengthOp->Asl.Next = DataOp; 86353289f6aSNate Lawson 864fba7fc7eSJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, 8657cf3e94aSJung-uk Kim "Constant expression reduced to (BUFFER) length %X\n\n", 86653289f6aSNate Lawson ObjDesc->Buffer.Length); 86753289f6aSNate Lawson break; 86853289f6aSNate Lawson 86953289f6aSNate Lawson default: 87053289f6aSNate Lawson break; 87153289f6aSNate Lawson } 87253289f6aSNate Lawson } 87353289f6aSNate Lawson 8741df130f1SJung-uk Kim 8751df130f1SJung-uk Kim /******************************************************************************* 8761df130f1SJung-uk Kim * 8771df130f1SJung-uk Kim * FUNCTION: OpcUpdateIntegerNode 8781df130f1SJung-uk Kim * 8791df130f1SJung-uk Kim * PARAMETERS: Op - Current parse object 8807cf3e94aSJung-uk Kim * Value - Value for the integer op 8811df130f1SJung-uk Kim * 8821df130f1SJung-uk Kim * RETURN: None 8831df130f1SJung-uk Kim * 8847cf3e94aSJung-uk Kim * DESCRIPTION: Update node to the correct Integer type and value 8851df130f1SJung-uk Kim * 8861df130f1SJung-uk Kim ******************************************************************************/ 8871df130f1SJung-uk Kim 8881df130f1SJung-uk Kim static void 8891df130f1SJung-uk Kim OpcUpdateIntegerNode ( 8901df130f1SJung-uk Kim ACPI_PARSE_OBJECT *Op, 8911df130f1SJung-uk Kim UINT64 Value) 8921df130f1SJung-uk Kim { 8931df130f1SJung-uk Kim 8941df130f1SJung-uk Kim Op->Common.Value.Integer = Value; 8951df130f1SJung-uk Kim 8961df130f1SJung-uk Kim /* 8971df130f1SJung-uk Kim * The AmlLength is used by the parser to indicate a constant, 8981df130f1SJung-uk Kim * (if non-zero). Length is either (1/2/4/8) 8991df130f1SJung-uk Kim */ 9001df130f1SJung-uk Kim switch (Op->Asl.AmlLength) 9011df130f1SJung-uk Kim { 9021df130f1SJung-uk Kim case 1: 903a9d8d09cSJung-uk Kim 9045f9b24faSJung-uk Kim TrSetOpIntegerValue (PARSEOP_BYTECONST, Op); 9051df130f1SJung-uk Kim Op->Asl.AmlOpcode = AML_RAW_DATA_BYTE; 9061df130f1SJung-uk Kim break; 9071df130f1SJung-uk Kim 9081df130f1SJung-uk Kim case 2: 909a9d8d09cSJung-uk Kim 9105f9b24faSJung-uk Kim TrSetOpIntegerValue (PARSEOP_WORDCONST, Op); 9111df130f1SJung-uk Kim Op->Asl.AmlOpcode = AML_RAW_DATA_WORD; 9121df130f1SJung-uk Kim break; 9131df130f1SJung-uk Kim 9141df130f1SJung-uk Kim case 4: 915a9d8d09cSJung-uk Kim 9165f9b24faSJung-uk Kim TrSetOpIntegerValue (PARSEOP_DWORDCONST, Op); 9171df130f1SJung-uk Kim Op->Asl.AmlOpcode = AML_RAW_DATA_DWORD; 9181df130f1SJung-uk Kim break; 9191df130f1SJung-uk Kim 9201df130f1SJung-uk Kim case 8: 921a9d8d09cSJung-uk Kim 9225f9b24faSJung-uk Kim TrSetOpIntegerValue (PARSEOP_QWORDCONST, Op); 9231df130f1SJung-uk Kim Op->Asl.AmlOpcode = AML_RAW_DATA_QWORD; 9241df130f1SJung-uk Kim break; 9251df130f1SJung-uk Kim 9261df130f1SJung-uk Kim case 0: 9271df130f1SJung-uk Kim default: 928a9d8d09cSJung-uk Kim 9291df130f1SJung-uk Kim OpcSetOptimalIntegerSize (Op); 9305f9b24faSJung-uk Kim TrSetOpIntegerValue (PARSEOP_INTEGER, Op); 9311df130f1SJung-uk Kim break; 9321df130f1SJung-uk Kim } 9331df130f1SJung-uk Kim 9341df130f1SJung-uk Kim Op->Asl.AmlLength = 0; 9351df130f1SJung-uk Kim } 9367cf3e94aSJung-uk Kim 9377cf3e94aSJung-uk Kim 9387cf3e94aSJung-uk Kim /******************************************************************************* 9397cf3e94aSJung-uk Kim * 9407cf3e94aSJung-uk Kim * FUNCTION: OpcAmlEvaluationWalk1 9417cf3e94aSJung-uk Kim * 9427cf3e94aSJung-uk Kim * PARAMETERS: ASL_WALK_CALLBACK 9437cf3e94aSJung-uk Kim * 9447cf3e94aSJung-uk Kim * RETURN: Status 9457cf3e94aSJung-uk Kim * 9467cf3e94aSJung-uk Kim * DESCRIPTION: Descending callback for AML execution of constant subtrees 9477cf3e94aSJung-uk Kim * 9487cf3e94aSJung-uk Kim ******************************************************************************/ 9497cf3e94aSJung-uk Kim 9507cf3e94aSJung-uk Kim static ACPI_STATUS 9517cf3e94aSJung-uk Kim OpcAmlEvaluationWalk1 ( 9527cf3e94aSJung-uk Kim ACPI_PARSE_OBJECT *Op, 9537cf3e94aSJung-uk Kim UINT32 Level, 9547cf3e94aSJung-uk Kim void *Context) 9557cf3e94aSJung-uk Kim { 9567cf3e94aSJung-uk Kim ACPI_WALK_STATE *WalkState = Context; 9577cf3e94aSJung-uk Kim ACPI_STATUS Status; 9587cf3e94aSJung-uk Kim ACPI_PARSE_OBJECT *OutOp; 9597cf3e94aSJung-uk Kim 9607cf3e94aSJung-uk Kim 9617cf3e94aSJung-uk Kim WalkState->Op = Op; 9627cf3e94aSJung-uk Kim WalkState->Opcode = Op->Common.AmlOpcode; 9637cf3e94aSJung-uk Kim WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 9647cf3e94aSJung-uk Kim 9657cf3e94aSJung-uk Kim /* Copy child pointer to Arg for compatibility with Interpreter */ 9667cf3e94aSJung-uk Kim 9677cf3e94aSJung-uk Kim if (Op->Asl.Child) 9687cf3e94aSJung-uk Kim { 9697cf3e94aSJung-uk Kim Op->Common.Value.Arg = Op->Asl.Child; 9707cf3e94aSJung-uk Kim } 9717cf3e94aSJung-uk Kim 9727cf3e94aSJung-uk Kim /* Call AML dispatcher */ 9737cf3e94aSJung-uk Kim 9747cf3e94aSJung-uk Kim Status = AcpiDsExecBeginOp (WalkState, &OutOp); 9757cf3e94aSJung-uk Kim if (ACPI_FAILURE (Status)) 9767cf3e94aSJung-uk Kim { 9777cf3e94aSJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, 9787cf3e94aSJung-uk Kim "%s Constant interpretation failed (1) - %s\n", 9797cf3e94aSJung-uk Kim Op->Asl.ParseOpName, AcpiFormatException (Status)); 9807cf3e94aSJung-uk Kim } 9817cf3e94aSJung-uk Kim 9827cf3e94aSJung-uk Kim return (Status); 9837cf3e94aSJung-uk Kim } 9847cf3e94aSJung-uk Kim 9857cf3e94aSJung-uk Kim 9867cf3e94aSJung-uk Kim /******************************************************************************* 9877cf3e94aSJung-uk Kim * 9887cf3e94aSJung-uk Kim * FUNCTION: OpcAmlEvaluationWalk2 9897cf3e94aSJung-uk Kim * 9907cf3e94aSJung-uk Kim * PARAMETERS: ASL_WALK_CALLBACK 9917cf3e94aSJung-uk Kim * 9927cf3e94aSJung-uk Kim * RETURN: Status 9937cf3e94aSJung-uk Kim * 9947cf3e94aSJung-uk Kim * DESCRIPTION: Ascending callback for AML execution of constant subtrees 9957cf3e94aSJung-uk Kim * 9967cf3e94aSJung-uk Kim ******************************************************************************/ 9977cf3e94aSJung-uk Kim 9987cf3e94aSJung-uk Kim static ACPI_STATUS 9997cf3e94aSJung-uk Kim OpcAmlEvaluationWalk2 ( 10007cf3e94aSJung-uk Kim ACPI_PARSE_OBJECT *Op, 10017cf3e94aSJung-uk Kim UINT32 Level, 10027cf3e94aSJung-uk Kim void *Context) 10037cf3e94aSJung-uk Kim { 10047cf3e94aSJung-uk Kim ACPI_WALK_STATE *WalkState = Context; 10057cf3e94aSJung-uk Kim ACPI_STATUS Status; 10067cf3e94aSJung-uk Kim 10077cf3e94aSJung-uk Kim 10087cf3e94aSJung-uk Kim WalkState->Op = Op; 10097cf3e94aSJung-uk Kim WalkState->Opcode = Op->Common.AmlOpcode; 10107cf3e94aSJung-uk Kim WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 10117cf3e94aSJung-uk Kim 10127cf3e94aSJung-uk Kim /* Copy child pointer to Arg for compatibility with Interpreter */ 10137cf3e94aSJung-uk Kim 10147cf3e94aSJung-uk Kim if (Op->Asl.Child) 10157cf3e94aSJung-uk Kim { 10167cf3e94aSJung-uk Kim Op->Common.Value.Arg = Op->Asl.Child; 10177cf3e94aSJung-uk Kim } 10187cf3e94aSJung-uk Kim 10197cf3e94aSJung-uk Kim /* Call AML dispatcher */ 10207cf3e94aSJung-uk Kim 10217cf3e94aSJung-uk Kim Status = AcpiDsExecEndOp (WalkState); 10227cf3e94aSJung-uk Kim if (ACPI_FAILURE (Status)) 10237cf3e94aSJung-uk Kim { 10247cf3e94aSJung-uk Kim DbgPrint (ASL_PARSE_OUTPUT, 10257cf3e94aSJung-uk Kim "%s: Constant interpretation failed (2) - %s\n", 10267cf3e94aSJung-uk Kim Op->Asl.ParseOpName, AcpiFormatException (Status)); 10277cf3e94aSJung-uk Kim } 10287cf3e94aSJung-uk Kim 10297cf3e94aSJung-uk Kim return (Status); 10307cf3e94aSJung-uk Kim } 1031