asltransform.c revision 118611
1118611Snjl 2118611Snjl/****************************************************************************** 3118611Snjl * 4118611Snjl * Module Name: asltransform - Parse tree transforms 5118611Snjl * $Revision: 19 $ 6118611Snjl * 7118611Snjl *****************************************************************************/ 8118611Snjl 9118611Snjl/****************************************************************************** 10118611Snjl * 11118611Snjl * 1. Copyright Notice 12118611Snjl * 13118611Snjl * Some or all of this work - Copyright (c) 1999 - 2003, 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 * 134118611Snjl * DESCRIPTION: Generate an ACPI name of the form _Txx. 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 146118611Snjl if (Gbl_TempCount > 255) 147118611Snjl { 148118611Snjl /* Too many temps */ 149118611Snjl /* TBD: issue eror message */ 150118611Snjl *NamePath = "ERROR"; 151118611Snjl return ("Error"); 152118611Snjl } 153118611Snjl 154118611Snjl TempName = UtLocalCalloc (6); 155118611Snjl UtConvertByteToHex ((UINT8) Gbl_TempCount, (UINT8 *) &TempName [1]); 156118611Snjl Gbl_TempCount++; 157118611Snjl 158118611Snjl /* First three characters are always "\_T" */ 159118611Snjl 160118611Snjl TempName[0] = '\\'; 161118611Snjl TempName[1] = '_'; 162118611Snjl TempName[2] = 'T'; 163118611Snjl 164118611Snjl *NamePath = TempName; 165118611Snjl return (&TempName[1]); 166118611Snjl} 167118611Snjl 168118611Snjl 169118611Snjl/******************************************************************************* 170118611Snjl * 171118611Snjl * FUNCTION: TrAmlInitLineNumbers 172118611Snjl * 173118611Snjl * PARAMETERS: Op - Op to be initialized 174118611Snjl * Neighbor - Op used for initialization values 175118611Snjl * 176118611Snjl * RETURN: None 177118611Snjl * 178118611Snjl * DESCRIPTION: Initialized the various line numbers for a parse node. 179118611Snjl * 180118611Snjl ******************************************************************************/ 181118611Snjl 182118611Snjlvoid 183118611SnjlTrAmlInitLineNumbers ( 184118611Snjl ACPI_PARSE_OBJECT *Op, 185118611Snjl ACPI_PARSE_OBJECT *Neighbor) 186118611Snjl{ 187118611Snjl 188118611Snjl Op->Asl.EndLine = Neighbor->Asl.EndLine; 189118611Snjl Op->Asl.EndLogicalLine = Neighbor->Asl.EndLogicalLine; 190118611Snjl Op->Asl.LineNumber = Neighbor->Asl.LineNumber; 191118611Snjl Op->Asl.LogicalByteOffset = Neighbor->Asl.LogicalByteOffset; 192118611Snjl Op->Asl.LogicalLineNumber = Neighbor->Asl.LogicalLineNumber; 193118611Snjl} 194118611Snjl 195118611Snjl 196118611Snjl/******************************************************************************* 197118611Snjl * 198118611Snjl * FUNCTION: TrAmlInitNode 199118611Snjl * 200118611Snjl * PARAMETERS: Op - Op to be initialized 201118611Snjl * ParseOpcode - Opcode for this node 202118611Snjl * 203118611Snjl * RETURN: None 204118611Snjl * 205118611Snjl * DESCRIPTION: Initialize a node with the parse opcode and opcode name. 206118611Snjl * 207118611Snjl ******************************************************************************/ 208118611Snjl 209118611Snjlvoid 210118611SnjlTrAmlInitNode ( 211118611Snjl ACPI_PARSE_OBJECT *Op, 212118611Snjl UINT16 ParseOpcode) 213118611Snjl{ 214118611Snjl 215118611Snjl Op->Asl.ParseOpcode = ParseOpcode; 216118611Snjl UtSetParseOpName (Op); 217118611Snjl} 218118611Snjl 219118611Snjl 220118611Snjl/******************************************************************************* 221118611Snjl * 222118611Snjl * FUNCTION: TrAmlSetSubtreeParent 223118611Snjl * 224118611Snjl * PARAMETERS: Op - First node in a list of peer nodes 225118611Snjl * Parent - Parent of the subtree 226118611Snjl * 227118611Snjl * RETURN: None 228118611Snjl * 229118611Snjl * DESCRIPTION: Set the parent for all peer nodes in a subtree 230118611Snjl * 231118611Snjl ******************************************************************************/ 232118611Snjl 233118611Snjlvoid 234118611SnjlTrAmlSetSubtreeParent ( 235118611Snjl ACPI_PARSE_OBJECT *Op, 236118611Snjl ACPI_PARSE_OBJECT *Parent) 237118611Snjl{ 238118611Snjl ACPI_PARSE_OBJECT *Next; 239118611Snjl 240118611Snjl 241118611Snjl Next = Op; 242118611Snjl while (Next) 243118611Snjl { 244118611Snjl Next->Asl.Parent = Parent; 245118611Snjl Next = Next->Asl.Next; 246118611Snjl } 247118611Snjl} 248118611Snjl 249118611Snjl 250118611Snjl/******************************************************************************* 251118611Snjl * 252118611Snjl * FUNCTION: TrAmlInsertPeer 253118611Snjl * 254118611Snjl * PARAMETERS: Op - First node in a list of peer nodes 255118611Snjl * NewPeer - Peer node to insert 256118611Snjl * 257118611Snjl * RETURN: None 258118611Snjl * 259118611Snjl * DESCRIPTION: Insert a new peer node into a list of peers. 260118611Snjl * 261118611Snjl ******************************************************************************/ 262118611Snjl 263118611Snjlvoid 264118611SnjlTrAmlInsertPeer ( 265118611Snjl ACPI_PARSE_OBJECT *Op, 266118611Snjl ACPI_PARSE_OBJECT *NewPeer) 267118611Snjl{ 268118611Snjl 269118611Snjl NewPeer->Asl.Next = Op->Asl.Next; 270118611Snjl Op->Asl.Next = NewPeer; 271118611Snjl} 272118611Snjl 273118611Snjl 274118611Snjl/******************************************************************************* 275118611Snjl * 276118611Snjl * FUNCTION: TrAmlTransformWalk 277118611Snjl * 278118611Snjl * PARAMETERS: ASL_WALK_CALLBACK 279118611Snjl * 280118611Snjl * RETURN: None 281118611Snjl * 282118611Snjl * DESCRIPTION: Parse tree walk to generate both the AML opcodes and the AML 283118611Snjl * operands. 284118611Snjl * 285118611Snjl ******************************************************************************/ 286118611Snjl 287118611SnjlACPI_STATUS 288118611SnjlTrAmlTransformWalk ( 289118611Snjl ACPI_PARSE_OBJECT *Op, 290118611Snjl UINT32 Level, 291118611Snjl void *Context) 292118611Snjl{ 293118611Snjl 294118611Snjl TrTransformSubtree (Op); 295118611Snjl return (AE_OK); 296118611Snjl} 297118611Snjl 298118611Snjl 299118611Snjl/******************************************************************************* 300118611Snjl * 301118611Snjl * FUNCTION: TrTransformSubtree 302118611Snjl * 303118611Snjl * PARAMETERS: Op - The parent parse node 304118611Snjl * 305118611Snjl * RETURN: None 306118611Snjl * 307118611Snjl * DESCRIPTION: Prepare nodes to be output as AML data and operands. The more 308118611Snjl * complex AML opcodes require processing of the child nodes 309118611Snjl * (arguments/operands). 310118611Snjl * 311118611Snjl ******************************************************************************/ 312118611Snjl 313118611Snjlvoid 314118611SnjlTrTransformSubtree ( 315118611Snjl ACPI_PARSE_OBJECT *Op) 316118611Snjl{ 317118611Snjl 318118611Snjl if (Op->Asl.AmlOpcode == AML_RAW_DATA_BYTE) 319118611Snjl { 320118611Snjl return; 321118611Snjl } 322118611Snjl 323118611Snjl switch (Op->Asl.ParseOpcode) 324118611Snjl { 325118611Snjl case PARSEOP_DEFINITIONBLOCK: 326118611Snjl TrDoDefinitionBlock (Op); 327118611Snjl break; 328118611Snjl 329118611Snjl case PARSEOP_ELSEIF: 330118611Snjl TrDoElseif (Op); 331118611Snjl break; 332118611Snjl 333118611Snjl case PARSEOP_SWITCH: 334118611Snjl TrDoSwitch (Op); 335118611Snjl break; 336118611Snjl 337118611Snjl default: 338118611Snjl /* Nothing to do here for other opcodes */ 339118611Snjl break; 340118611Snjl } 341118611Snjl} 342118611Snjl 343118611Snjl 344118611Snjl/******************************************************************************* 345118611Snjl * 346118611Snjl * FUNCTION: TrDoDefinitionBlock 347118611Snjl * 348118611Snjl * PARAMETERS: Op - Parse node 349118611Snjl * 350118611Snjl * RETURN: None 351118611Snjl * 352118611Snjl * DESCRIPTION: Find the end of the definition block and set a global to this 353118611Snjl * node. It is used by the compiler to insert compiler-generated 354118611Snjl * names at the root level of the namespace. 355118611Snjl * 356118611Snjl ******************************************************************************/ 357118611Snjl 358118611Snjlvoid 359118611SnjlTrDoDefinitionBlock ( 360118611Snjl ACPI_PARSE_OBJECT *Op) 361118611Snjl{ 362118611Snjl ACPI_PARSE_OBJECT *Next; 363118611Snjl UINT32 i; 364118611Snjl 365118611Snjl 366118611Snjl Next = Op->Asl.Child; 367118611Snjl for (i = 0; i < 5; i++) 368118611Snjl { 369118611Snjl Next = Next->Asl.Next; 370118611Snjl } 371118611Snjl 372118611Snjl Gbl_FirstLevelInsertionNode = Next; 373118611Snjl} 374118611Snjl 375118611Snjl 376118611Snjl/******************************************************************************* 377118611Snjl * 378118611Snjl * FUNCTION: TrDoElseif 379118611Snjl * 380118611Snjl * PARAMETERS: Op - Parse node for ELSEIF 381118611Snjl * 382118611Snjl * RETURN: None 383118611Snjl * 384118611Snjl * DESCRIPTION: Transform an Elseif into an Else and If AML opcode pair. 385118611Snjl * There is no AML opcode for ELSEIF -- it must be simulated 386118611Snjl * with an if/else pair. 387118611Snjl * 388118611Snjl ******************************************************************************/ 389118611Snjl 390118611Snjlvoid 391118611SnjlTrDoElseif ( 392118611Snjl ACPI_PARSE_OBJECT *ElseNode) 393118611Snjl{ 394118611Snjl ACPI_PARSE_OBJECT *IfNode = NULL; 395118611Snjl ACPI_PARSE_OBJECT *NextNode; 396118611Snjl 397118611Snjl 398118611Snjl /* Change the ELSEIF into an ELSE */ 399118611Snjl 400118611Snjl TrAmlInitNode (ElseNode, PARSEOP_ELSE); 401118611Snjl 402118611Snjl /* Create a new IF node */ 403118611Snjl 404118611Snjl IfNode = TrCreateLeafNode (PARSEOP_IF); 405118611Snjl IfNode->Asl.Parent = ElseNode; 406118611Snjl TrAmlInitLineNumbers (IfNode, ElseNode); 407118611Snjl 408118611Snjl /* Insert the the IF node first in the ELSE child list */ 409118611Snjl 410118611Snjl IfNode->Asl.Child = ElseNode->Asl.Child; 411118611Snjl ElseNode->Asl.Child = IfNode; 412118611Snjl 413118611Snjl /* Go to the end of the IF <Predicate><TermList> block */ 414118611Snjl 415118611Snjl NextNode = IfNode->Asl.Child; /* Next = Predicate */ 416118611Snjl NextNode = NextNode->Asl.Next; /* Nest = TermList */ 417118611Snjl 418118611Snjl /* Make the next node after the IF the rest of the original tree */ 419118611Snjl 420118611Snjl IfNode->Asl.Next = NextNode->Asl.Next; 421118611Snjl 422118611Snjl /* Terminate the IF subtree and set IF node as the parent for all nodes */ 423118611Snjl 424118611Snjl NextNode->Asl.Next = NULL; 425118611Snjl TrAmlSetSubtreeParent (IfNode->Asl.Child, IfNode); 426118611Snjl} 427118611Snjl 428118611Snjl 429118611Snjl/******************************************************************************* 430118611Snjl * 431118611Snjl * FUNCTION: TrDoSwitch 432118611Snjl * 433118611Snjl * PARAMETERS: StartNode - Parse node for SWITCH 434118611Snjl * 435118611Snjl * RETURN: None 436118611Snjl * 437118611Snjl * 438118611Snjl * DESCRIPTION: Translate ASL SWITCH statement to if/else pairs. There is 439118611Snjl * no actual AML opcode for SWITCH -- it must be simulated. 440118611Snjl * 441118611Snjl ******************************************************************************/ 442118611Snjl 443118611Snjlvoid 444118611SnjlTrDoSwitch ( 445118611Snjl ACPI_PARSE_OBJECT *StartNode) 446118611Snjl{ 447118611Snjl ACPI_PARSE_OBJECT *Next; 448118611Snjl ACPI_PARSE_OBJECT *CaseOp = NULL; 449118611Snjl ACPI_PARSE_OBJECT *CaseBlock = NULL; 450118611Snjl ACPI_PARSE_OBJECT *DefaultOp = NULL; 451118611Snjl ACPI_PARSE_OBJECT *CurrentParentNode; 452118611Snjl ACPI_PARSE_OBJECT *Conditional = NULL; 453118611Snjl ACPI_PARSE_OBJECT *Predicate; 454118611Snjl ACPI_PARSE_OBJECT *Peer; 455118611Snjl ACPI_PARSE_OBJECT *NewOp; 456118611Snjl ACPI_PARSE_OBJECT *NewOp2; 457118611Snjl char *PredicateValueName; 458118611Snjl char *PredicateValuePath; 459118611Snjl 460118611Snjl 461118611Snjl CurrentParentNode = StartNode; 462118611Snjl PredicateValueName = TrAmlGetNextTempName (&PredicateValuePath); 463118611Snjl 464118611Snjl /* First child is the predicate */ 465118611Snjl 466118611Snjl Next = StartNode->Asl.Child; 467118611Snjl Peer = Next->Asl.Next; 468118611Snjl 469118611Snjl /* CASE statements start at next child */ 470118611Snjl 471118611Snjl while (Peer) 472118611Snjl { 473118611Snjl Next = Peer; 474118611Snjl Peer = Next->Asl.Next; 475118611Snjl 476118611Snjl if (Next->Asl.ParseOpcode == PARSEOP_CASE) 477118611Snjl { 478118611Snjl if (CaseOp) 479118611Snjl { 480118611Snjl /* Add an ELSE to complete the previous CASE */ 481118611Snjl 482118611Snjl NewOp = TrCreateLeafNode (PARSEOP_ELSE); 483118611Snjl NewOp->Asl.Parent = Conditional->Asl.Parent; 484118611Snjl TrAmlInitLineNumbers (NewOp, NewOp->Asl.Parent); 485118611Snjl 486118611Snjl /* Link ELSE node as a peer to the previous IF */ 487118611Snjl 488118611Snjl TrAmlInsertPeer (Conditional, NewOp); 489118611Snjl CurrentParentNode = NewOp; 490118611Snjl } 491118611Snjl 492118611Snjl CaseOp = Next; 493118611Snjl Conditional = CaseOp; 494118611Snjl CaseBlock = CaseOp->Asl.Child->Asl.Next; 495118611Snjl Conditional->Asl.Child->Asl.Next = NULL; 496118611Snjl 497118611Snjl /* 498118611Snjl * change CaseOp() to: If (PredicateValue == CaseValue) {...} 499118611Snjl * CaseOp->Child is the case value 500118611Snjl * CaseOp->Child->Peer is the beginning of the case block 501118611Snjl */ 502118611Snjl NewOp = TrCreateValuedLeafNode (PARSEOP_NAMESTRING, 503118611Snjl (ACPI_INTEGER) ACPI_TO_INTEGER (PredicateValuePath)); 504118611Snjl 505118611Snjl Predicate = CaseOp->Asl.Child; 506118611Snjl Predicate->Asl.Next = NewOp; 507118611Snjl TrAmlInitLineNumbers (NewOp, Predicate); 508118611Snjl 509118611Snjl NewOp2 = TrCreateLeafNode (PARSEOP_LEQUAL); 510118611Snjl NewOp2->Asl.Parent = Conditional; 511118611Snjl NewOp2->Asl.Child = Predicate; 512118611Snjl TrAmlInitLineNumbers (NewOp2, Conditional); 513118611Snjl 514118611Snjl TrAmlSetSubtreeParent (Predicate, NewOp2); 515118611Snjl 516118611Snjl Predicate = NewOp2; 517118611Snjl Predicate->Asl.Next = CaseBlock; 518118611Snjl 519118611Snjl TrAmlSetSubtreeParent (Predicate, Conditional); 520118611Snjl 521118611Snjl /* Reinitialize the CASE node to an IF node */ 522118611Snjl 523118611Snjl Conditional->Asl.Child = Predicate; 524118611Snjl TrAmlInitNode (Conditional, PARSEOP_IF); 525118611Snjl 526118611Snjl /* 527118611Snjl * The first CASE(IF) is not nested under an ELSE. 528118611Snjl * All other CASEs are children of a parent ELSE. 529118611Snjl */ 530118611Snjl if (CurrentParentNode == StartNode) 531118611Snjl { 532118611Snjl Conditional->Asl.Parent = CurrentParentNode->Asl.Parent; 533118611Snjl 534118611Snjl /* Link IF into the peer list */ 535118611Snjl 536118611Snjl TrAmlInsertPeer (CurrentParentNode, Conditional); 537118611Snjl } 538118611Snjl else 539118611Snjl { 540118611Snjl /* 541118611Snjl * The IF is a child of previous IF/ELSE. It 542118611Snjl * is therefore without peer. 543118611Snjl */ 544118611Snjl CurrentParentNode->Asl.Child = Conditional; 545118611Snjl Conditional->Asl.Parent = CurrentParentNode; 546118611Snjl Conditional->Asl.Next = NULL; 547118611Snjl } 548118611Snjl } 549118611Snjl else if (Next->Asl.ParseOpcode == PARSEOP_DEFAULT) 550118611Snjl { 551118611Snjl if (DefaultOp) 552118611Snjl { 553118611Snjl /* More than one Default */ 554118611Snjl } 555118611Snjl 556118611Snjl /* Save the DEFAULT node for later, after CASEs */ 557118611Snjl 558118611Snjl DefaultOp = Next; 559118611Snjl } 560118611Snjl else 561118611Snjl { 562118611Snjl /* Unkown peer opcode */ 563118611Snjl 564118611Snjl printf ("Unknown parse opcode for switch statement: %s (%d)\n", 565118611Snjl Next->Asl.ParseOpName, Next->Asl.ParseOpcode); 566118611Snjl } 567118611Snjl } 568118611Snjl 569118611Snjl /* 570118611Snjl * Add the default at the end of the if/else construct 571118611Snjl */ 572118611Snjl if (DefaultOp) 573118611Snjl { 574118611Snjl if (CaseOp) 575118611Snjl { 576118611Snjl /* Add an ELSE first */ 577118611Snjl 578118611Snjl TrAmlInitNode (DefaultOp, PARSEOP_ELSE); 579118611Snjl DefaultOp->Asl.Parent = Conditional->Asl.Parent; 580118611Snjl } 581118611Snjl else 582118611Snjl { 583118611Snjl /* There were no CASE statements, no ELSE needed */ 584118611Snjl 585118611Snjl TrAmlInsertPeer (CurrentParentNode, DefaultOp->Asl.Child); 586118611Snjl } 587118611Snjl } 588118611Snjl 589118611Snjl /* 590118611Snjl * Add a NAME node for the temp integer 591118611Snjl */ 592118611Snjl NewOp = TrCreateLeafNode (PARSEOP_NAME); 593118611Snjl NewOp->Asl.Parent = Gbl_FirstLevelInsertionNode->Asl.Parent; 594118611Snjl 595118611Snjl NewOp2 = TrCreateValuedLeafNode (PARSEOP_NAMESTRING, 596118611Snjl (ACPI_INTEGER) ACPI_TO_INTEGER (PredicateValueName)); 597118611Snjl NewOp->Asl.Child = NewOp2; 598118611Snjl NewOp2->Asl.Next = TrCreateValuedLeafNode (PARSEOP_INTEGER, (ACPI_INTEGER) 0); 599118611Snjl 600118611Snjl TrAmlSetSubtreeParent (NewOp2, NewOp); 601118611Snjl 602118611Snjl /* Insert this node at the global level of the ASL */ 603118611Snjl 604118611Snjl TrAmlInsertPeer (Gbl_FirstLevelInsertionNode, NewOp); 605118611Snjl TrAmlInitLineNumbers (NewOp, Gbl_FirstLevelInsertionNode); 606118611Snjl TrAmlInitLineNumbers (NewOp2, Gbl_FirstLevelInsertionNode); 607118611Snjl TrAmlInitLineNumbers (NewOp2->Asl.Next, Gbl_FirstLevelInsertionNode); 608118611Snjl 609118611Snjl /* 610118611Snjl * Change the SWITCH node to a STORE (predicate value, _Txx) 611118611Snjl */ 612118611Snjl TrAmlInitNode (StartNode, PARSEOP_STORE); 613118611Snjl 614118611Snjl Predicate = StartNode->Asl.Child; 615118611Snjl Predicate->Asl.Child = NULL; 616118611Snjl 617118611Snjl NewOp = TrCreateValuedLeafNode (PARSEOP_NAMESTRING, 618118611Snjl (ACPI_INTEGER) ACPI_TO_INTEGER (PredicateValuePath)); 619118611Snjl NewOp->Asl.Parent = StartNode; 620118611Snjl Predicate->Asl.Next = NewOp; 621118611Snjl} 622118611Snjl 623118611Snjl 624