asltransform.c revision 138287
1118611Snjl 2118611Snjl/****************************************************************************** 3118611Snjl * 4118611Snjl * Module Name: asltransform - Parse tree transforms 5138287Smarks * $Revision: 25 $ 6118611Snjl * 7118611Snjl *****************************************************************************/ 8118611Snjl 9118611Snjl/****************************************************************************** 10118611Snjl * 11118611Snjl * 1. Copyright Notice 12118611Snjl * 13126372Snjl * Some or all of this work - Copyright (c) 1999 - 2004, Intel Corp. 14118611Snjl * All rights reserved. 15118611Snjl * 16118611Snjl * 2. License 17118611Snjl * 18118611Snjl * 2.1. This is your license from Intel Corp. under its intellectual property 19118611Snjl * rights. You may have additional license terms from the party that provided 20118611Snjl * you this software, covering your right to use that party's intellectual 21118611Snjl * property rights. 22118611Snjl * 23118611Snjl * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24118611Snjl * copy of the source code appearing in this file ("Covered Code") an 25118611Snjl * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26118611Snjl * base code distributed originally by Intel ("Original Intel Code") to copy, 27118611Snjl * make derivatives, distribute, use and display any portion of the Covered 28118611Snjl * Code in any form, with the right to sublicense such rights; and 29118611Snjl * 30118611Snjl * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31118611Snjl * license (with the right to sublicense), under only those claims of Intel 32118611Snjl * patents that are infringed by the Original Intel Code, to make, use, sell, 33118611Snjl * offer to sell, and import the Covered Code and derivative works thereof 34118611Snjl * solely to the minimum extent necessary to exercise the above copyright 35118611Snjl * license, and in no event shall the patent license extend to any additions 36118611Snjl * to or modifications of the Original Intel Code. No other license or right 37118611Snjl * is granted directly or by implication, estoppel or otherwise; 38118611Snjl * 39118611Snjl * The above copyright and patent license is granted only if the following 40118611Snjl * conditions are met: 41118611Snjl * 42118611Snjl * 3. Conditions 43118611Snjl * 44118611Snjl * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45118611Snjl * Redistribution of source code of any substantial portion of the Covered 46118611Snjl * Code or modification with rights to further distribute source must include 47118611Snjl * the above Copyright Notice, the above License, this list of Conditions, 48118611Snjl * and the following Disclaimer and Export Compliance provision. In addition, 49118611Snjl * Licensee must cause all Covered Code to which Licensee contributes to 50118611Snjl * contain a file documenting the changes Licensee made to create that Covered 51118611Snjl * Code and the date of any change. Licensee must include in that file the 52118611Snjl * documentation of any changes made by any predecessor Licensee. Licensee 53118611Snjl * must include a prominent statement that the modification is derived, 54118611Snjl * directly or indirectly, from Original Intel Code. 55118611Snjl * 56118611Snjl * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57118611Snjl * Redistribution of source code of any substantial portion of the Covered 58118611Snjl * Code or modification without rights to further distribute source must 59118611Snjl * include the following Disclaimer and Export Compliance provision in the 60118611Snjl * documentation and/or other materials provided with distribution. In 61118611Snjl * addition, Licensee may not authorize further sublicense of source of any 62118611Snjl * portion of the Covered Code, and must include terms to the effect that the 63118611Snjl * license from Licensee to its licensee is limited to the intellectual 64118611Snjl * property embodied in the software Licensee provides to its licensee, and 65118611Snjl * not to intellectual property embodied in modifications its licensee may 66118611Snjl * make. 67118611Snjl * 68118611Snjl * 3.3. Redistribution of Executable. Redistribution in executable form of any 69118611Snjl * substantial portion of the Covered Code or modification must reproduce the 70118611Snjl * above Copyright Notice, and the following Disclaimer and Export Compliance 71118611Snjl * provision in the documentation and/or other materials provided with the 72118611Snjl * distribution. 73118611Snjl * 74118611Snjl * 3.4. Intel retains all right, title, and interest in and to the Original 75118611Snjl * Intel Code. 76118611Snjl * 77118611Snjl * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78118611Snjl * Intel shall be used in advertising or otherwise to promote the sale, use or 79118611Snjl * other dealings in products derived from or relating to the Covered Code 80118611Snjl * without prior written authorization from Intel. 81118611Snjl * 82118611Snjl * 4. Disclaimer and Export Compliance 83118611Snjl * 84118611Snjl * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85118611Snjl * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86118611Snjl * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87118611Snjl * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 88118611Snjl * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 89118611Snjl * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 90118611Snjl * PARTICULAR PURPOSE. 91118611Snjl * 92118611Snjl * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 93118611Snjl * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 94118611Snjl * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95118611Snjl * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 96118611Snjl * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 97118611Snjl * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 98118611Snjl * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 99118611Snjl * LIMITED REMEDY. 100118611Snjl * 101118611Snjl * 4.3. Licensee shall not export, either directly or indirectly, any of this 102118611Snjl * software or system incorporating such software without first obtaining any 103118611Snjl * required license or other approval from the U. S. Department of Commerce or 104118611Snjl * any other agency or department of the United States Government. In the 105118611Snjl * event Licensee exports any such software from the United States or 106118611Snjl * re-exports any such software from a foreign destination, Licensee shall 107118611Snjl * ensure that the distribution and export/re-export of the software is in 108118611Snjl * compliance with all laws, regulations, orders, or other restrictions of the 109118611Snjl * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110118611Snjl * any of its subsidiaries will export/re-export any technical data, process, 111118611Snjl * software, or service, directly or indirectly, to any country for which the 112118611Snjl * United States government or any agency thereof requires an export license, 113118611Snjl * other governmental approval, or letter of assurance, without first obtaining 114118611Snjl * such license, approval or letter. 115118611Snjl * 116118611Snjl *****************************************************************************/ 117118611Snjl 118118611Snjl 119118611Snjl#include "aslcompiler.h" 120118611Snjl#include "aslcompiler.y.h" 121118611Snjl 122118611Snjl#define _COMPONENT ACPI_COMPILER 123118611Snjl ACPI_MODULE_NAME ("asltransform") 124118611Snjl 125118611Snjl 126118611Snjl/******************************************************************************* 127118611Snjl * 128118611Snjl * FUNCTION: TrAmlGetNextTempName 129118611Snjl * 130118611Snjl * PARAMETERS: NamePath - Where a pointer to the temp name is returned 131118611Snjl * 132118611Snjl * RETURN: A pointer to the second character of the name 133118611Snjl * 134138287Smarks * DESCRIPTION: Generate an ACPI name of the form _T_x. These names are 135118611Snjl * reserved for use by the ASL compiler. 136118611Snjl * 137118611Snjl ******************************************************************************/ 138118611Snjl 139118611Snjlchar * 140118611SnjlTrAmlGetNextTempName ( 141118611Snjl char **NamePath) 142118611Snjl{ 143118611Snjl char *TempName; 144118611Snjl 145118611Snjl 146138287Smarks if (Gbl_TempCount > (9+26+26)) 147118611Snjl { 148118611Snjl /* Too many temps */ 149118611Snjl /* TBD: issue eror message */ 150118611Snjl *NamePath = "ERROR"; 151118611Snjl return ("Error"); 152118611Snjl } 153118611Snjl 154118611Snjl TempName = UtLocalCalloc (6); 155138287Smarks 156138287Smarks if (Gbl_TempCount < 9) 157138287Smarks { 158138287Smarks TempName[4] = (char) (Gbl_TempCount + 0x30); 159138287Smarks } 160138287Smarks else if (Gbl_TempCount < (9 + 26)) 161138287Smarks { 162138287Smarks TempName[4] = (char) (Gbl_TempCount + 0x41); 163138287Smarks } 164138287Smarks else 165138287Smarks { 166138287Smarks TempName[4] = (char) (Gbl_TempCount + 0x61); 167138287Smarks } 168118611Snjl Gbl_TempCount++; 169118611Snjl 170138287Smarks /* First four characters are always "\_T_" */ 171118611Snjl 172118611Snjl TempName[0] = '\\'; 173118611Snjl TempName[1] = '_'; 174118611Snjl TempName[2] = 'T'; 175138287Smarks TempName[3] = '_'; 176118611Snjl 177118611Snjl *NamePath = TempName; 178118611Snjl return (&TempName[1]); 179118611Snjl} 180118611Snjl 181118611Snjl 182118611Snjl/******************************************************************************* 183118611Snjl * 184118611Snjl * FUNCTION: TrAmlInitLineNumbers 185118611Snjl * 186118611Snjl * PARAMETERS: Op - Op to be initialized 187118611Snjl * Neighbor - Op used for initialization values 188118611Snjl * 189118611Snjl * RETURN: None 190118611Snjl * 191118611Snjl * DESCRIPTION: Initialized the various line numbers for a parse node. 192118611Snjl * 193118611Snjl ******************************************************************************/ 194118611Snjl 195118611Snjlvoid 196118611SnjlTrAmlInitLineNumbers ( 197118611Snjl ACPI_PARSE_OBJECT *Op, 198118611Snjl ACPI_PARSE_OBJECT *Neighbor) 199118611Snjl{ 200118611Snjl 201118611Snjl Op->Asl.EndLine = Neighbor->Asl.EndLine; 202118611Snjl Op->Asl.EndLogicalLine = Neighbor->Asl.EndLogicalLine; 203118611Snjl Op->Asl.LineNumber = Neighbor->Asl.LineNumber; 204118611Snjl Op->Asl.LogicalByteOffset = Neighbor->Asl.LogicalByteOffset; 205118611Snjl Op->Asl.LogicalLineNumber = Neighbor->Asl.LogicalLineNumber; 206118611Snjl} 207118611Snjl 208118611Snjl 209118611Snjl/******************************************************************************* 210118611Snjl * 211118611Snjl * FUNCTION: TrAmlInitNode 212118611Snjl * 213118611Snjl * PARAMETERS: Op - Op to be initialized 214118611Snjl * ParseOpcode - Opcode for this node 215118611Snjl * 216118611Snjl * RETURN: None 217118611Snjl * 218118611Snjl * DESCRIPTION: Initialize a node with the parse opcode and opcode name. 219118611Snjl * 220118611Snjl ******************************************************************************/ 221118611Snjl 222118611Snjlvoid 223118611SnjlTrAmlInitNode ( 224118611Snjl ACPI_PARSE_OBJECT *Op, 225118611Snjl UINT16 ParseOpcode) 226118611Snjl{ 227118611Snjl 228118611Snjl Op->Asl.ParseOpcode = ParseOpcode; 229118611Snjl UtSetParseOpName (Op); 230118611Snjl} 231118611Snjl 232118611Snjl 233118611Snjl/******************************************************************************* 234118611Snjl * 235118611Snjl * FUNCTION: TrAmlSetSubtreeParent 236118611Snjl * 237118611Snjl * PARAMETERS: Op - First node in a list of peer nodes 238118611Snjl * Parent - Parent of the subtree 239118611Snjl * 240118611Snjl * RETURN: None 241118611Snjl * 242118611Snjl * DESCRIPTION: Set the parent for all peer nodes in a subtree 243118611Snjl * 244118611Snjl ******************************************************************************/ 245118611Snjl 246118611Snjlvoid 247118611SnjlTrAmlSetSubtreeParent ( 248118611Snjl ACPI_PARSE_OBJECT *Op, 249118611Snjl ACPI_PARSE_OBJECT *Parent) 250118611Snjl{ 251118611Snjl ACPI_PARSE_OBJECT *Next; 252118611Snjl 253118611Snjl 254118611Snjl Next = Op; 255118611Snjl while (Next) 256118611Snjl { 257118611Snjl Next->Asl.Parent = Parent; 258118611Snjl Next = Next->Asl.Next; 259118611Snjl } 260118611Snjl} 261118611Snjl 262118611Snjl 263118611Snjl/******************************************************************************* 264118611Snjl * 265118611Snjl * FUNCTION: TrAmlInsertPeer 266118611Snjl * 267118611Snjl * PARAMETERS: Op - First node in a list of peer nodes 268118611Snjl * NewPeer - Peer node to insert 269118611Snjl * 270118611Snjl * RETURN: None 271118611Snjl * 272118611Snjl * DESCRIPTION: Insert a new peer node into a list of peers. 273118611Snjl * 274118611Snjl ******************************************************************************/ 275118611Snjl 276118611Snjlvoid 277118611SnjlTrAmlInsertPeer ( 278118611Snjl ACPI_PARSE_OBJECT *Op, 279118611Snjl ACPI_PARSE_OBJECT *NewPeer) 280118611Snjl{ 281118611Snjl 282118611Snjl NewPeer->Asl.Next = Op->Asl.Next; 283118611Snjl Op->Asl.Next = NewPeer; 284118611Snjl} 285118611Snjl 286118611Snjl 287118611Snjl/******************************************************************************* 288118611Snjl * 289118611Snjl * FUNCTION: TrAmlTransformWalk 290118611Snjl * 291118611Snjl * PARAMETERS: ASL_WALK_CALLBACK 292118611Snjl * 293118611Snjl * RETURN: None 294118611Snjl * 295118611Snjl * DESCRIPTION: Parse tree walk to generate both the AML opcodes and the AML 296118611Snjl * operands. 297118611Snjl * 298118611Snjl ******************************************************************************/ 299118611Snjl 300118611SnjlACPI_STATUS 301118611SnjlTrAmlTransformWalk ( 302118611Snjl ACPI_PARSE_OBJECT *Op, 303118611Snjl UINT32 Level, 304118611Snjl void *Context) 305118611Snjl{ 306118611Snjl 307118611Snjl TrTransformSubtree (Op); 308118611Snjl return (AE_OK); 309118611Snjl} 310118611Snjl 311118611Snjl 312118611Snjl/******************************************************************************* 313118611Snjl * 314118611Snjl * FUNCTION: TrTransformSubtree 315118611Snjl * 316118611Snjl * PARAMETERS: Op - The parent parse node 317118611Snjl * 318118611Snjl * RETURN: None 319118611Snjl * 320118611Snjl * DESCRIPTION: Prepare nodes to be output as AML data and operands. The more 321118611Snjl * complex AML opcodes require processing of the child nodes 322118611Snjl * (arguments/operands). 323118611Snjl * 324118611Snjl ******************************************************************************/ 325118611Snjl 326118611Snjlvoid 327118611SnjlTrTransformSubtree ( 328118611Snjl ACPI_PARSE_OBJECT *Op) 329118611Snjl{ 330118611Snjl 331118611Snjl if (Op->Asl.AmlOpcode == AML_RAW_DATA_BYTE) 332118611Snjl { 333118611Snjl return; 334118611Snjl } 335118611Snjl 336118611Snjl switch (Op->Asl.ParseOpcode) 337118611Snjl { 338118611Snjl case PARSEOP_DEFINITIONBLOCK: 339118611Snjl TrDoDefinitionBlock (Op); 340118611Snjl break; 341118611Snjl 342118611Snjl case PARSEOP_SWITCH: 343118611Snjl TrDoSwitch (Op); 344118611Snjl break; 345118611Snjl 346118611Snjl default: 347118611Snjl /* Nothing to do here for other opcodes */ 348118611Snjl break; 349118611Snjl } 350118611Snjl} 351118611Snjl 352118611Snjl 353118611Snjl/******************************************************************************* 354118611Snjl * 355118611Snjl * FUNCTION: TrDoDefinitionBlock 356118611Snjl * 357118611Snjl * PARAMETERS: Op - Parse node 358118611Snjl * 359118611Snjl * RETURN: None 360118611Snjl * 361118611Snjl * DESCRIPTION: Find the end of the definition block and set a global to this 362118611Snjl * node. It is used by the compiler to insert compiler-generated 363118611Snjl * names at the root level of the namespace. 364118611Snjl * 365118611Snjl ******************************************************************************/ 366118611Snjl 367118611Snjlvoid 368118611SnjlTrDoDefinitionBlock ( 369118611Snjl ACPI_PARSE_OBJECT *Op) 370118611Snjl{ 371118611Snjl ACPI_PARSE_OBJECT *Next; 372118611Snjl UINT32 i; 373118611Snjl 374118611Snjl 375118611Snjl Next = Op->Asl.Child; 376118611Snjl for (i = 0; i < 5; i++) 377118611Snjl { 378118611Snjl Next = Next->Asl.Next; 379118611Snjl } 380118611Snjl 381118611Snjl Gbl_FirstLevelInsertionNode = Next; 382118611Snjl} 383118611Snjl 384118611Snjl 385118611Snjl/******************************************************************************* 386118611Snjl * 387118611Snjl * FUNCTION: TrDoSwitch 388118611Snjl * 389118611Snjl * PARAMETERS: StartNode - Parse node for SWITCH 390118611Snjl * 391118611Snjl * RETURN: None 392118611Snjl * 393118611Snjl * 394118611Snjl * DESCRIPTION: Translate ASL SWITCH statement to if/else pairs. There is 395118611Snjl * no actual AML opcode for SWITCH -- it must be simulated. 396118611Snjl * 397118611Snjl ******************************************************************************/ 398118611Snjl 399118611Snjlvoid 400118611SnjlTrDoSwitch ( 401118611Snjl ACPI_PARSE_OBJECT *StartNode) 402118611Snjl{ 403118611Snjl ACPI_PARSE_OBJECT *Next; 404118611Snjl ACPI_PARSE_OBJECT *CaseOp = NULL; 405118611Snjl ACPI_PARSE_OBJECT *CaseBlock = NULL; 406118611Snjl ACPI_PARSE_OBJECT *DefaultOp = NULL; 407118611Snjl ACPI_PARSE_OBJECT *CurrentParentNode; 408118611Snjl ACPI_PARSE_OBJECT *Conditional = NULL; 409118611Snjl ACPI_PARSE_OBJECT *Predicate; 410118611Snjl ACPI_PARSE_OBJECT *Peer; 411118611Snjl ACPI_PARSE_OBJECT *NewOp; 412118611Snjl ACPI_PARSE_OBJECT *NewOp2; 413118611Snjl char *PredicateValueName; 414118611Snjl char *PredicateValuePath; 415118611Snjl 416118611Snjl 417118611Snjl CurrentParentNode = StartNode; 418118611Snjl PredicateValueName = TrAmlGetNextTempName (&PredicateValuePath); 419118611Snjl 420118611Snjl /* First child is the predicate */ 421118611Snjl 422118611Snjl Next = StartNode->Asl.Child; 423118611Snjl Peer = Next->Asl.Next; 424118611Snjl 425118611Snjl /* CASE statements start at next child */ 426118611Snjl 427118611Snjl while (Peer) 428118611Snjl { 429118611Snjl Next = Peer; 430118611Snjl Peer = Next->Asl.Next; 431118611Snjl 432118611Snjl if (Next->Asl.ParseOpcode == PARSEOP_CASE) 433118611Snjl { 434118611Snjl if (CaseOp) 435118611Snjl { 436118611Snjl /* Add an ELSE to complete the previous CASE */ 437118611Snjl 438118611Snjl NewOp = TrCreateLeafNode (PARSEOP_ELSE); 439118611Snjl NewOp->Asl.Parent = Conditional->Asl.Parent; 440118611Snjl TrAmlInitLineNumbers (NewOp, NewOp->Asl.Parent); 441118611Snjl 442118611Snjl /* Link ELSE node as a peer to the previous IF */ 443118611Snjl 444118611Snjl TrAmlInsertPeer (Conditional, NewOp); 445118611Snjl CurrentParentNode = NewOp; 446118611Snjl } 447118611Snjl 448118611Snjl CaseOp = Next; 449118611Snjl Conditional = CaseOp; 450118611Snjl CaseBlock = CaseOp->Asl.Child->Asl.Next; 451118611Snjl Conditional->Asl.Child->Asl.Next = NULL; 452138287Smarks Predicate = CaseOp->Asl.Child; 453118611Snjl 454138287Smarks if (Predicate->Asl.ParseOpcode == PARSEOP_PACKAGE) 455138287Smarks { 456138287Smarks AcpiOsPrintf ("Package\n"); 457118611Snjl 458138287Smarks /* 459138287Smarks * Convert the package declaration to this form: 460138287Smarks * 461138287Smarks * If (LNotEqual (Match (Package(){4}, MEQ, _Txx, MTR, 0, 0), Ones)) 462138287Smarks */ 463138287Smarks NewOp2 = TrCreateLeafNode (PARSEOP_MATCHTYPE_MEQ); 464138287Smarks Predicate->Asl.Next = NewOp2; 465138287Smarks TrAmlInitLineNumbers (NewOp2, Conditional); 466118611Snjl 467138287Smarks NewOp = NewOp2; 468138287Smarks NewOp2 = TrCreateValuedLeafNode (PARSEOP_NAMESTRING, 469138287Smarks (ACPI_INTEGER) ACPI_TO_INTEGER (PredicateValuePath)); 470138287Smarks NewOp->Asl.Next = NewOp2; 471138287Smarks TrAmlInitLineNumbers (NewOp2, Predicate); 472118611Snjl 473138287Smarks NewOp = NewOp2; 474138287Smarks NewOp2 = TrCreateLeafNode (PARSEOP_MATCHTYPE_MTR); 475138287Smarks NewOp->Asl.Next = NewOp2; 476138287Smarks TrAmlInitLineNumbers (NewOp2, Predicate); 477118611Snjl 478138287Smarks NewOp = NewOp2; 479138287Smarks NewOp2 = TrCreateLeafNode (PARSEOP_ZERO); 480138287Smarks NewOp->Asl.Next = NewOp2; 481138287Smarks TrAmlInitLineNumbers (NewOp2, Predicate); 482118611Snjl 483138287Smarks NewOp = NewOp2; 484138287Smarks NewOp2 = TrCreateLeafNode (PARSEOP_ZERO); 485138287Smarks NewOp->Asl.Next = NewOp2; 486138287Smarks TrAmlInitLineNumbers (NewOp2, Predicate); 487118611Snjl 488138287Smarks NewOp2 = TrCreateLeafNode (PARSEOP_MATCH); 489138287Smarks NewOp2->Asl.Child = Predicate; /* PARSEOP_PACKAGE */ 490138287Smarks TrAmlInitLineNumbers (NewOp2, Conditional); 491138287Smarks TrAmlSetSubtreeParent (Predicate, NewOp2); 492138287Smarks 493138287Smarks NewOp = NewOp2; 494138287Smarks NewOp2 = TrCreateLeafNode (PARSEOP_ONES); 495138287Smarks NewOp->Asl.Next = NewOp2; 496138287Smarks TrAmlInitLineNumbers (NewOp2, Conditional); 497138287Smarks 498138287Smarks NewOp2 = TrCreateLeafNode (PARSEOP_LEQUAL); 499138287Smarks NewOp2->Asl.Child = NewOp; 500138287Smarks NewOp->Asl.Parent = NewOp2; 501138287Smarks TrAmlInitLineNumbers (NewOp2, Conditional); 502138287Smarks TrAmlSetSubtreeParent (NewOp, NewOp2); 503138287Smarks 504138287Smarks NewOp = NewOp2; 505138287Smarks NewOp2 = TrCreateLeafNode (PARSEOP_LNOT); 506138287Smarks NewOp2->Asl.Child = NewOp; 507138287Smarks NewOp2->Asl.Parent = Conditional; 508138287Smarks NewOp->Asl.Parent = NewOp2; 509138287Smarks TrAmlInitLineNumbers (NewOp2, Conditional); 510138287Smarks 511138287Smarks Conditional->Asl.Child = NewOp2; 512138287Smarks NewOp2->Asl.Next = CaseBlock; 513138287Smarks } 514138287Smarks else 515138287Smarks { 516138287Smarks /* 517138287Smarks * Change CaseOp() to: If (PredicateValue == CaseValue) {...} 518138287Smarks * CaseOp->Child is the case value 519138287Smarks * CaseOp->Child->Peer is the beginning of the case block 520138287Smarks */ 521138287Smarks NewOp = TrCreateValuedLeafNode (PARSEOP_NAMESTRING, 522138287Smarks (ACPI_INTEGER) ACPI_TO_INTEGER (PredicateValuePath)); 523138287Smarks Predicate->Asl.Next = NewOp; 524138287Smarks TrAmlInitLineNumbers (NewOp, Predicate); 525138287Smarks 526138287Smarks NewOp2 = TrCreateLeafNode (PARSEOP_LEQUAL); 527138287Smarks NewOp2->Asl.Parent = Conditional; 528138287Smarks NewOp2->Asl.Child = Predicate; 529138287Smarks TrAmlInitLineNumbers (NewOp2, Conditional); 530138287Smarks 531138287Smarks TrAmlSetSubtreeParent (Predicate, NewOp2); 532138287Smarks 533138287Smarks Predicate = NewOp2; 534138287Smarks Predicate->Asl.Next = CaseBlock; 535138287Smarks 536138287Smarks TrAmlSetSubtreeParent (Predicate, Conditional); 537138287Smarks Conditional->Asl.Child = Predicate; 538138287Smarks } 539138287Smarks 540118611Snjl /* Reinitialize the CASE node to an IF node */ 541118611Snjl 542118611Snjl TrAmlInitNode (Conditional, PARSEOP_IF); 543118611Snjl 544118611Snjl /* 545118611Snjl * The first CASE(IF) is not nested under an ELSE. 546118611Snjl * All other CASEs are children of a parent ELSE. 547118611Snjl */ 548118611Snjl if (CurrentParentNode == StartNode) 549118611Snjl { 550118611Snjl Conditional->Asl.Parent = CurrentParentNode->Asl.Parent; 551118611Snjl 552118611Snjl /* Link IF into the peer list */ 553118611Snjl 554118611Snjl TrAmlInsertPeer (CurrentParentNode, Conditional); 555118611Snjl } 556118611Snjl else 557118611Snjl { 558118611Snjl /* 559118611Snjl * The IF is a child of previous IF/ELSE. It 560118611Snjl * is therefore without peer. 561118611Snjl */ 562118611Snjl CurrentParentNode->Asl.Child = Conditional; 563118611Snjl Conditional->Asl.Parent = CurrentParentNode; 564118611Snjl Conditional->Asl.Next = NULL; 565118611Snjl } 566118611Snjl } 567118611Snjl else if (Next->Asl.ParseOpcode == PARSEOP_DEFAULT) 568118611Snjl { 569118611Snjl if (DefaultOp) 570118611Snjl { 571138287Smarks /* 572138287Smarks * More than one Default 573138287Smarks * (Parser should catch this, should not get here) 574138287Smarks */ 575138287Smarks AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Next, 576138287Smarks "Found more than one Default()"); 577118611Snjl } 578118611Snjl 579118611Snjl /* Save the DEFAULT node for later, after CASEs */ 580118611Snjl 581118611Snjl DefaultOp = Next; 582118611Snjl } 583118611Snjl else 584118611Snjl { 585138287Smarks /* Unknown peer opcode */ 586118611Snjl 587118611Snjl printf ("Unknown parse opcode for switch statement: %s (%d)\n", 588118611Snjl Next->Asl.ParseOpName, Next->Asl.ParseOpcode); 589118611Snjl } 590118611Snjl } 591118611Snjl 592118611Snjl /* 593138287Smarks * Add the default case at the end of the if/else construct 594118611Snjl */ 595118611Snjl if (DefaultOp) 596118611Snjl { 597138287Smarks /* If no CASE statements, this is an error - see below */ 598138287Smarks 599118611Snjl if (CaseOp) 600118611Snjl { 601138287Smarks /* Convert the DEFAULT node to an ELSE */ 602118611Snjl 603118611Snjl TrAmlInitNode (DefaultOp, PARSEOP_ELSE); 604118611Snjl DefaultOp->Asl.Parent = Conditional->Asl.Parent; 605118611Snjl 606138287Smarks /* Link ELSE node as a peer to the previous IF */ 607138287Smarks 608138287Smarks TrAmlInsertPeer (Conditional, DefaultOp); 609118611Snjl } 610118611Snjl } 611118611Snjl 612138287Smarks if (!CaseOp) 613138287Smarks { 614138287Smarks AslError (ASL_ERROR, ASL_MSG_NO_CASES, StartNode, NULL); 615138287Smarks } 616138287Smarks 617118611Snjl /* 618118611Snjl * Add a NAME node for the temp integer 619118611Snjl */ 620118611Snjl NewOp = TrCreateLeafNode (PARSEOP_NAME); 621118611Snjl NewOp->Asl.Parent = Gbl_FirstLevelInsertionNode->Asl.Parent; 622138287Smarks NewOp->Asl.CompileFlags |= NODE_COMPILER_EMITTED; 623118611Snjl 624118611Snjl NewOp2 = TrCreateValuedLeafNode (PARSEOP_NAMESTRING, 625118611Snjl (ACPI_INTEGER) ACPI_TO_INTEGER (PredicateValueName)); 626118611Snjl NewOp->Asl.Child = NewOp2; 627118611Snjl NewOp2->Asl.Next = TrCreateValuedLeafNode (PARSEOP_INTEGER, (ACPI_INTEGER) 0); 628118611Snjl 629118611Snjl TrAmlSetSubtreeParent (NewOp2, NewOp); 630118611Snjl 631118611Snjl /* Insert this node at the global level of the ASL */ 632118611Snjl 633118611Snjl TrAmlInsertPeer (Gbl_FirstLevelInsertionNode, NewOp); 634118611Snjl TrAmlInitLineNumbers (NewOp, Gbl_FirstLevelInsertionNode); 635118611Snjl TrAmlInitLineNumbers (NewOp2, Gbl_FirstLevelInsertionNode); 636118611Snjl TrAmlInitLineNumbers (NewOp2->Asl.Next, Gbl_FirstLevelInsertionNode); 637118611Snjl 638118611Snjl /* 639118611Snjl * Change the SWITCH node to a STORE (predicate value, _Txx) 640118611Snjl */ 641118611Snjl TrAmlInitNode (StartNode, PARSEOP_STORE); 642118611Snjl 643118611Snjl Predicate = StartNode->Asl.Child; 644118611Snjl NewOp = TrCreateValuedLeafNode (PARSEOP_NAMESTRING, 645118611Snjl (ACPI_INTEGER) ACPI_TO_INTEGER (PredicateValuePath)); 646118611Snjl NewOp->Asl.Parent = StartNode; 647118611Snjl Predicate->Asl.Next = NewOp; 648118611Snjl} 649118611Snjl 650118611Snjl 651