aslcompile.c revision 245582
1118611Snjl/****************************************************************************** 2118611Snjl * 3118611Snjl * Module Name: aslcompile - top level compile module 4118611Snjl * 5118611Snjl *****************************************************************************/ 6118611Snjl 7217365Sjkim/* 8245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp. 9118611Snjl * All rights reserved. 10118611Snjl * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 25118611Snjl * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 29118611Snjl * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 43118611Snjl 44217365Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 45217365Sjkim 46118611Snjl#include <stdio.h> 47151937Sjkim#include <time.h> 48213806Sjkim#include <contrib/dev/acpica/include/acapps.h> 49118611Snjl 50118611Snjl#define _COMPONENT ACPI_COMPILER 51118611Snjl ACPI_MODULE_NAME ("aslcompile") 52118611Snjl 53243347Sjkim/* 54243347Sjkim * Main parser entry 55243347Sjkim * External is here in case the parser emits the same external in the 56243347Sjkim * generated header. (Newer versions of Bison) 57243347Sjkim */ 58243347Sjkimint 59243347SjkimAslCompilerparse( 60243347Sjkim void); 61243347Sjkim 62151937Sjkim/* Local prototypes */ 63118611Snjl 64151937Sjkimstatic void 65151937SjkimCmFlushSourceCode ( 66151937Sjkim void); 67151937Sjkim 68212761Sjkimstatic void 69193529SjkimFlConsumeAnsiComment ( 70235945Sjkim FILE *Handle, 71193529Sjkim ASL_FILE_STATUS *Status); 72151937Sjkim 73212761Sjkimstatic void 74193529SjkimFlConsumeNewComment ( 75235945Sjkim FILE *Handle, 76193529Sjkim ASL_FILE_STATUS *Status); 77193529Sjkim 78237412Sjkimstatic void 79237412SjkimCmDumpAllEvents ( 80237412Sjkim void); 81193529Sjkim 82237412Sjkim 83118611Snjl/******************************************************************************* 84118611Snjl * 85118611Snjl * FUNCTION: AslCompilerSignon 86118611Snjl * 87118611Snjl * PARAMETERS: FileId - ID of the output file 88118611Snjl * 89118611Snjl * RETURN: None 90118611Snjl * 91118611Snjl * DESCRIPTION: Display compiler signon 92118611Snjl * 93118611Snjl ******************************************************************************/ 94118611Snjl 95118611Snjlvoid 96118611SnjlAslCompilerSignon ( 97118611Snjl UINT32 FileId) 98118611Snjl{ 99118611Snjl char *Prefix = ""; 100213806Sjkim char *UtilityName; 101118611Snjl 102118611Snjl 103151937Sjkim /* Set line prefix depending on the destination file type */ 104151937Sjkim 105118611Snjl switch (FileId) 106118611Snjl { 107118611Snjl case ASL_FILE_ASM_SOURCE_OUTPUT: 108118611Snjl case ASL_FILE_ASM_INCLUDE_OUTPUT: 109118611Snjl 110118611Snjl Prefix = "; "; 111118611Snjl break; 112118611Snjl 113118611Snjl case ASL_FILE_HEX_OUTPUT: 114118611Snjl 115118611Snjl if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM) 116118611Snjl { 117118611Snjl Prefix = "; "; 118118611Snjl } 119207344Sjkim else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) || 120207344Sjkim (Gbl_HexOutputFlag == HEX_OUTPUT_ASL)) 121118611Snjl { 122118611Snjl FlPrintFile (ASL_FILE_HEX_OUTPUT, "/*\n"); 123118611Snjl Prefix = " * "; 124118611Snjl } 125118611Snjl break; 126118611Snjl 127118611Snjl case ASL_FILE_C_SOURCE_OUTPUT: 128118611Snjl case ASL_FILE_C_INCLUDE_OUTPUT: 129118611Snjl 130118611Snjl Prefix = " * "; 131118611Snjl break; 132118611Snjl 133118611Snjl default: 134118611Snjl /* No other output types supported */ 135118611Snjl break; 136118611Snjl } 137118611Snjl 138151937Sjkim /* Running compiler or disassembler? */ 139151937Sjkim 140151937Sjkim if (Gbl_DisasmFlag) 141151937Sjkim { 142213806Sjkim UtilityName = AML_DISASSEMBLER_NAME; 143151937Sjkim } 144151937Sjkim else 145151937Sjkim { 146213806Sjkim UtilityName = ASL_COMPILER_NAME; 147151937Sjkim } 148151937Sjkim 149213806Sjkim /* Compiler signon with copyright */ 150151937Sjkim 151213806Sjkim FlPrintFile (FileId, "%s\n", Prefix); 152213806Sjkim FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix)); 153118611Snjl} 154118611Snjl 155118611Snjl 156118611Snjl/******************************************************************************* 157118611Snjl * 158118611Snjl * FUNCTION: AslCompilerFileHeader 159118611Snjl * 160118611Snjl * PARAMETERS: FileId - ID of the output file 161118611Snjl * 162118611Snjl * RETURN: None 163118611Snjl * 164118611Snjl * DESCRIPTION: Header used at the beginning of output files 165118611Snjl * 166118611Snjl ******************************************************************************/ 167118611Snjl 168118611Snjlvoid 169118611SnjlAslCompilerFileHeader ( 170118611Snjl UINT32 FileId) 171118611Snjl{ 172118611Snjl struct tm *NewTime; 173118611Snjl time_t Aclock; 174118611Snjl char *Prefix = ""; 175118611Snjl 176118611Snjl 177151937Sjkim /* Set line prefix depending on the destination file type */ 178151937Sjkim 179118611Snjl switch (FileId) 180118611Snjl { 181118611Snjl case ASL_FILE_ASM_SOURCE_OUTPUT: 182118611Snjl case ASL_FILE_ASM_INCLUDE_OUTPUT: 183118611Snjl 184118611Snjl Prefix = "; "; 185118611Snjl break; 186118611Snjl 187118611Snjl case ASL_FILE_HEX_OUTPUT: 188118611Snjl 189118611Snjl if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM) 190118611Snjl { 191118611Snjl Prefix = "; "; 192118611Snjl } 193207344Sjkim else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) || 194207344Sjkim (Gbl_HexOutputFlag == HEX_OUTPUT_ASL)) 195118611Snjl { 196118611Snjl Prefix = " * "; 197118611Snjl } 198118611Snjl break; 199118611Snjl 200118611Snjl case ASL_FILE_C_SOURCE_OUTPUT: 201118611Snjl case ASL_FILE_C_INCLUDE_OUTPUT: 202118611Snjl 203118611Snjl Prefix = " * "; 204118611Snjl break; 205118611Snjl 206118611Snjl default: 207118611Snjl /* No other output types supported */ 208118611Snjl break; 209118611Snjl } 210118611Snjl 211118611Snjl /* Compilation header with timestamp */ 212118611Snjl 213118611Snjl (void) time (&Aclock); 214118611Snjl NewTime = localtime (&Aclock); 215118611Snjl 216118611Snjl FlPrintFile (FileId, 217118611Snjl "%sCompilation of \"%s\" - %s%s\n", 218118611Snjl Prefix, Gbl_Files[ASL_FILE_INPUT].Filename, asctime (NewTime), 219118611Snjl Prefix); 220118611Snjl 221118611Snjl switch (FileId) 222118611Snjl { 223118611Snjl case ASL_FILE_C_SOURCE_OUTPUT: 224118611Snjl case ASL_FILE_C_INCLUDE_OUTPUT: 225118611Snjl FlPrintFile (FileId, " */\n"); 226118611Snjl break; 227118611Snjl 228118611Snjl default: 229118611Snjl /* Nothing to do for other output types */ 230118611Snjl break; 231118611Snjl } 232118611Snjl} 233118611Snjl 234118611Snjl 235118611Snjl/******************************************************************************* 236118611Snjl * 237118611Snjl * FUNCTION: CmFlushSourceCode 238118611Snjl * 239118611Snjl * PARAMETERS: None 240118611Snjl * 241118611Snjl * RETURN: None 242118611Snjl * 243118611Snjl * DESCRIPTION: Read in any remaining source code after the parse tree 244118611Snjl * has been constructed. 245118611Snjl * 246118611Snjl ******************************************************************************/ 247118611Snjl 248151937Sjkimstatic void 249151937SjkimCmFlushSourceCode ( 250151937Sjkim void) 251118611Snjl{ 252118611Snjl char Buffer; 253118611Snjl 254118611Snjl 255118611Snjl while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR) 256118611Snjl { 257234623Sjkim AslInsertLineBuffer ((int) Buffer); 258118611Snjl } 259118611Snjl 260234623Sjkim AslResetCurrentLineBuffer (); 261118611Snjl} 262118611Snjl 263118611Snjl 264118611Snjl/******************************************************************************* 265118611Snjl * 266167802Sjkim * FUNCTION: FlConsume* 267167802Sjkim * 268235945Sjkim * PARAMETERS: Handle - Open input file 269235945Sjkim * Status - File current status struct 270167802Sjkim * 271167802Sjkim * RETURN: Number of lines consumed 272167802Sjkim * 273167802Sjkim * DESCRIPTION: Step over both types of comment during check for ascii chars 274167802Sjkim * 275167802Sjkim ******************************************************************************/ 276167802Sjkim 277212761Sjkimstatic void 278167802SjkimFlConsumeAnsiComment ( 279235945Sjkim FILE *Handle, 280167802Sjkim ASL_FILE_STATUS *Status) 281167802Sjkim{ 282167802Sjkim UINT8 Byte; 283167802Sjkim BOOLEAN ClosingComment = FALSE; 284167802Sjkim 285167802Sjkim 286243347Sjkim while (fread (&Byte, 1, 1, Handle) == 1) 287167802Sjkim { 288167802Sjkim /* Scan until comment close is found */ 289167802Sjkim 290167802Sjkim if (ClosingComment) 291167802Sjkim { 292167802Sjkim if (Byte == '/') 293167802Sjkim { 294167802Sjkim return; 295167802Sjkim } 296167802Sjkim 297167802Sjkim if (Byte != '*') 298167802Sjkim { 299167802Sjkim /* Reset */ 300167802Sjkim 301167802Sjkim ClosingComment = FALSE; 302167802Sjkim } 303167802Sjkim } 304167802Sjkim else if (Byte == '*') 305167802Sjkim { 306167802Sjkim ClosingComment = TRUE; 307167802Sjkim } 308167802Sjkim 309167802Sjkim /* Maintain line count */ 310167802Sjkim 311167802Sjkim if (Byte == 0x0A) 312167802Sjkim { 313167802Sjkim Status->Line++; 314167802Sjkim } 315167802Sjkim 316167802Sjkim Status->Offset++; 317167802Sjkim } 318167802Sjkim} 319167802Sjkim 320167802Sjkim 321212761Sjkimstatic void 322167802SjkimFlConsumeNewComment ( 323235945Sjkim FILE *Handle, 324167802Sjkim ASL_FILE_STATUS *Status) 325167802Sjkim{ 326167802Sjkim UINT8 Byte; 327167802Sjkim 328167802Sjkim 329243347Sjkim while (fread (&Byte, 1, 1, Handle) == 1) 330167802Sjkim { 331167802Sjkim Status->Offset++; 332167802Sjkim 333167802Sjkim /* Comment ends at newline */ 334167802Sjkim 335167802Sjkim if (Byte == 0x0A) 336167802Sjkim { 337167802Sjkim Status->Line++; 338167802Sjkim return; 339167802Sjkim } 340167802Sjkim } 341167802Sjkim} 342167802Sjkim 343167802Sjkim 344167802Sjkim/******************************************************************************* 345167802Sjkim * 346123315Snjl * FUNCTION: FlCheckForAscii 347123315Snjl * 348235945Sjkim * PARAMETERS: Handle - Open input file 349235945Sjkim * Filename - Input filename 350235945Sjkim * DisplayErrors - TRUE if error messages desired 351123315Snjl * 352151937Sjkim * RETURN: Status 353123315Snjl * 354167802Sjkim * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters 355167802Sjkim * within comments. Note: does not handle nested comments and does 356167802Sjkim * not handle comment delimiters within string literals. However, 357167802Sjkim * on the rare chance this happens and an invalid character is 358167802Sjkim * missed, the parser will catch the error by failing in some 359167802Sjkim * spectactular manner. 360123315Snjl * 361123315Snjl ******************************************************************************/ 362123315Snjl 363209746SjkimACPI_STATUS 364123315SnjlFlCheckForAscii ( 365235945Sjkim FILE *Handle, 366235945Sjkim char *Filename, 367235945Sjkim BOOLEAN DisplayErrors) 368123315Snjl{ 369123315Snjl UINT8 Byte; 370123315Snjl ACPI_SIZE BadBytes = 0; 371167802Sjkim BOOLEAN OpeningComment = FALSE; 372167802Sjkim ASL_FILE_STATUS Status; 373123315Snjl 374123315Snjl 375167802Sjkim Status.Line = 1; 376167802Sjkim Status.Offset = 0; 377167802Sjkim 378123315Snjl /* Read the entire file */ 379123315Snjl 380243347Sjkim while (fread (&Byte, 1, 1, Handle) == 1) 381123315Snjl { 382167802Sjkim /* Ignore comment fields (allow non-ascii within) */ 383167802Sjkim 384167802Sjkim if (OpeningComment) 385167802Sjkim { 386167802Sjkim /* Check for second comment open delimiter */ 387167802Sjkim 388167802Sjkim if (Byte == '*') 389167802Sjkim { 390235945Sjkim FlConsumeAnsiComment (Handle, &Status); 391167802Sjkim } 392167802Sjkim 393167802Sjkim if (Byte == '/') 394167802Sjkim { 395235945Sjkim FlConsumeNewComment (Handle, &Status); 396167802Sjkim } 397167802Sjkim 398167802Sjkim /* Reset */ 399167802Sjkim 400167802Sjkim OpeningComment = FALSE; 401167802Sjkim } 402167802Sjkim else if (Byte == '/') 403167802Sjkim { 404167802Sjkim OpeningComment = TRUE; 405167802Sjkim } 406167802Sjkim 407123315Snjl /* Check for an ASCII character */ 408123315Snjl 409193529Sjkim if (!ACPI_IS_ASCII (Byte)) 410123315Snjl { 411235945Sjkim if ((BadBytes < 10) && (DisplayErrors)) 412123315Snjl { 413151937Sjkim AcpiOsPrintf ( 414167802Sjkim "Non-ASCII character [0x%2.2X] found in line %u, file offset 0x%.2X\n", 415167802Sjkim Byte, Status.Line, Status.Offset); 416123315Snjl } 417167802Sjkim 418123315Snjl BadBytes++; 419123315Snjl } 420167802Sjkim 421167802Sjkim /* Update line counter */ 422167802Sjkim 423167802Sjkim else if (Byte == 0x0A) 424167802Sjkim { 425167802Sjkim Status.Line++; 426167802Sjkim } 427167802Sjkim 428167802Sjkim Status.Offset++; 429123315Snjl } 430123315Snjl 431151937Sjkim /* Seek back to the beginning of the source file */ 432151937Sjkim 433235945Sjkim fseek (Handle, 0, SEEK_SET); 434151937Sjkim 435123315Snjl /* Were there any non-ASCII characters in the file? */ 436123315Snjl 437123315Snjl if (BadBytes) 438123315Snjl { 439235945Sjkim if (DisplayErrors) 440235945Sjkim { 441235945Sjkim AcpiOsPrintf ( 442235945Sjkim "%u non-ASCII characters found in input source text, could be a binary file\n", 443235945Sjkim BadBytes); 444235945Sjkim AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename); 445235945Sjkim } 446235945Sjkim 447123315Snjl return (AE_BAD_CHARACTER); 448123315Snjl } 449123315Snjl 450235945Sjkim /* File is OK (100% ASCII) */ 451123315Snjl 452123315Snjl return (AE_OK); 453123315Snjl} 454123315Snjl 455123315Snjl 456123315Snjl/******************************************************************************* 457123315Snjl * 458118611Snjl * FUNCTION: CmDoCompile 459118611Snjl * 460118611Snjl * PARAMETERS: None 461118611Snjl * 462118611Snjl * RETURN: Status (0 = OK) 463118611Snjl * 464118611Snjl * DESCRIPTION: This procedure performs the entire compile 465118611Snjl * 466118611Snjl ******************************************************************************/ 467118611Snjl 468118611Snjlint 469151937SjkimCmDoCompile ( 470151937Sjkim void) 471118611Snjl{ 472118611Snjl ACPI_STATUS Status; 473151937Sjkim UINT8 FullCompile; 474151937Sjkim UINT8 Event; 475118611Snjl 476118611Snjl 477151937Sjkim FullCompile = UtBeginEvent ("*** Total Compile time ***"); 478151937Sjkim Event = UtBeginEvent ("Open input and output files"); 479151937Sjkim UtEndEvent (Event); 480118611Snjl 481233250Sjkim Event = UtBeginEvent ("Preprocess input file"); 482234623Sjkim if (Gbl_PreprocessFlag) 483233250Sjkim { 484234623Sjkim /* Preprocessor */ 485234623Sjkim 486234623Sjkim PrDoPreprocess (); 487234623Sjkim if (Gbl_PreprocessOnly) 488234623Sjkim { 489234623Sjkim UtEndEvent (Event); 490234623Sjkim CmCleanupAndExit (); 491241973Sjkim return (0); 492234623Sjkim } 493233250Sjkim } 494234623Sjkim UtEndEvent (Event); 495233250Sjkim 496118611Snjl /* Build the parse tree */ 497118611Snjl 498151937Sjkim Event = UtBeginEvent ("Parse source code and build parse tree"); 499118611Snjl AslCompilerparse(); 500151937Sjkim UtEndEvent (Event); 501118611Snjl 502118611Snjl /* Flush out any remaining source after parse tree is complete */ 503118611Snjl 504151937Sjkim Event = UtBeginEvent ("Flush source input"); 505118611Snjl CmFlushSourceCode (); 506118611Snjl 507118611Snjl /* Did the parse tree get successfully constructed? */ 508118611Snjl 509118611Snjl if (!RootNode) 510118611Snjl { 511234623Sjkim /* 512234623Sjkim * If there are no errors, then we have some sort of 513234623Sjkim * internal problem. 514234623Sjkim */ 515234623Sjkim Status = AslCheckForErrorExit (); 516234623Sjkim if (Status == AE_OK) 517234623Sjkim { 518234623Sjkim AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, 519234623Sjkim NULL, "- Could not resolve parse tree root node"); 520234623Sjkim } 521234623Sjkim 522233250Sjkim goto ErrorExit; 523118611Snjl } 524118611Snjl 525167802Sjkim /* Optional parse tree dump, compiler debug output only */ 526167802Sjkim 527167802Sjkim LsDumpParseTree (); 528167802Sjkim 529118611Snjl OpcGetIntegerWidth (RootNode); 530151937Sjkim UtEndEvent (Event); 531118611Snjl 532118611Snjl /* Pre-process parse tree for any operator transforms */ 533118611Snjl 534151937Sjkim Event = UtBeginEvent ("Parse tree transforms"); 535118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n"); 536151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 537151937Sjkim TrAmlTransformWalk, NULL, NULL); 538151937Sjkim UtEndEvent (Event); 539118611Snjl 540118611Snjl /* Generate AML opcodes corresponding to the parse tokens */ 541118611Snjl 542151937Sjkim Event = UtBeginEvent ("Generate AML opcodes"); 543118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating AML opcodes\n\n"); 544151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 545151937Sjkim OpcAmlOpcodeWalk, NULL); 546151937Sjkim UtEndEvent (Event); 547118611Snjl 548118611Snjl /* 549118611Snjl * Now that the input is parsed, we can open the AML output file. 550118611Snjl * Note: by default, the name of this file comes from the table descriptor 551118611Snjl * within the input file. 552118611Snjl */ 553151937Sjkim Event = UtBeginEvent ("Open AML output file"); 554118611Snjl Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix); 555233250Sjkim UtEndEvent (Event); 556118611Snjl if (ACPI_FAILURE (Status)) 557118611Snjl { 558118611Snjl AePrintErrorLog (ASL_FILE_STDERR); 559241973Sjkim return (-1); 560118611Snjl } 561118611Snjl 562118611Snjl /* Interpret and generate all compile-time constants */ 563118611Snjl 564151937Sjkim Event = UtBeginEvent ("Constant folding via AML interpreter"); 565151937Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 566151937Sjkim "\nInterpreting compile-time constant expressions\n\n"); 567151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 568151937Sjkim OpcAmlConstantWalk, NULL, NULL); 569151937Sjkim UtEndEvent (Event); 570118611Snjl 571151937Sjkim /* Update AML opcodes if necessary, after constant folding */ 572151937Sjkim 573151937Sjkim Event = UtBeginEvent ("Updating AML opcodes after constant folding"); 574151937Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 575151937Sjkim "\nUpdating AML opcodes after constant folding\n\n"); 576151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 577151937Sjkim NULL, OpcAmlOpcodeUpdateWalk, NULL); 578151937Sjkim UtEndEvent (Event); 579151937Sjkim 580118611Snjl /* Calculate all AML package lengths */ 581118611Snjl 582151937Sjkim Event = UtBeginEvent ("Generate AML package lengths"); 583118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n"); 584151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 585151937Sjkim LnPackageLengthWalk, NULL); 586151937Sjkim UtEndEvent (Event); 587118611Snjl 588118611Snjl if (Gbl_ParseOnlyFlag) 589118611Snjl { 590234623Sjkim AePrintErrorLog (ASL_FILE_STDERR); 591234623Sjkim UtDisplaySummary (ASL_FILE_STDERR); 592118611Snjl if (Gbl_DebugFlag) 593118611Snjl { 594234623Sjkim /* Print error summary to the stdout also */ 595118611Snjl 596234623Sjkim AePrintErrorLog (ASL_FILE_STDOUT); 597234623Sjkim UtDisplaySummary (ASL_FILE_STDOUT); 598118611Snjl } 599233250Sjkim UtEndEvent (FullCompile); 600241973Sjkim return (0); 601118611Snjl } 602118611Snjl 603118611Snjl /* 604118611Snjl * Create an internal namespace and use it as a symbol table 605118611Snjl */ 606118611Snjl 607118611Snjl /* Namespace loading */ 608118611Snjl 609151937Sjkim Event = UtBeginEvent ("Create ACPI Namespace"); 610118611Snjl Status = LdLoadNamespace (RootNode); 611151937Sjkim UtEndEvent (Event); 612118611Snjl if (ACPI_FAILURE (Status)) 613118611Snjl { 614233250Sjkim goto ErrorExit; 615118611Snjl } 616118611Snjl 617167802Sjkim /* Namespace cross-reference */ 618118611Snjl 619151937Sjkim AslGbl_NamespaceEvent = UtBeginEvent ("Cross reference parse tree and Namespace"); 620245582Sjkim Status = XfCrossReferenceNamespace (); 621118611Snjl if (ACPI_FAILURE (Status)) 622118611Snjl { 623233250Sjkim goto ErrorExit; 624118611Snjl } 625118611Snjl 626167802Sjkim /* Namespace - Check for non-referenced objects */ 627167802Sjkim 628167802Sjkim LkFindUnreferencedObjects (); 629167802Sjkim UtEndEvent (AslGbl_NamespaceEvent); 630167802Sjkim 631118611Snjl /* 632241973Sjkim * Semantic analysis. This can happen only after the 633118611Snjl * namespace has been loaded and cross-referenced. 634118611Snjl * 635118611Snjl * part one - check control methods 636118611Snjl */ 637151937Sjkim Event = UtBeginEvent ("Analyze control method return types"); 638118611Snjl AnalysisWalkInfo.MethodStack = NULL; 639118611Snjl 640118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method analysis\n\n"); 641151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, 642245582Sjkim MtMethodAnalysisWalkBegin, 643245582Sjkim MtMethodAnalysisWalkEnd, &AnalysisWalkInfo); 644151937Sjkim UtEndEvent (Event); 645118611Snjl 646118611Snjl /* Semantic error checking part two - typing of method returns */ 647118611Snjl 648151937Sjkim Event = UtBeginEvent ("Determine object types returned by methods"); 649151937Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n"); 650218590Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 651218590Sjkim NULL, AnMethodTypingWalkEnd, NULL); 652151937Sjkim UtEndEvent (Event); 653118611Snjl 654118611Snjl /* Semantic error checking part three - operand type checking */ 655118611Snjl 656151937Sjkim Event = UtBeginEvent ("Analyze AML operand types"); 657151937Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n"); 658218590Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 659218590Sjkim NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo); 660151937Sjkim UtEndEvent (Event); 661118611Snjl 662118611Snjl /* Semantic error checking part four - other miscellaneous checks */ 663118611Snjl 664151937Sjkim Event = UtBeginEvent ("Miscellaneous analysis"); 665151937Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n"); 666218590Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 667151937Sjkim AnOtherSemanticAnalysisWalkBegin, 668218590Sjkim NULL, &AnalysisWalkInfo); 669151937Sjkim UtEndEvent (Event); 670118611Snjl 671118611Snjl /* Calculate all AML package lengths */ 672118611Snjl 673151937Sjkim Event = UtBeginEvent ("Finish AML package length generation"); 674118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n"); 675151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 676151937Sjkim LnInitLengthsWalk, NULL); 677151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 678151937Sjkim LnPackageLengthWalk, NULL); 679151937Sjkim UtEndEvent (Event); 680118611Snjl 681118611Snjl /* Code generation - emit the AML */ 682118611Snjl 683151937Sjkim Event = UtBeginEvent ("Generate AML code and write output files"); 684118611Snjl CgGenerateAmlOutput (); 685151937Sjkim UtEndEvent (Event); 686118611Snjl 687151937Sjkim Event = UtBeginEvent ("Write optional output files"); 688118611Snjl CmDoOutputFiles (); 689151937Sjkim UtEndEvent (Event); 690118611Snjl 691151937Sjkim UtEndEvent (FullCompile); 692118611Snjl CmCleanupAndExit (); 693241973Sjkim return (0); 694233250Sjkim 695233250SjkimErrorExit: 696233250Sjkim UtEndEvent (FullCompile); 697233250Sjkim CmCleanupAndExit (); 698233250Sjkim return (-1); 699118611Snjl} 700118611Snjl 701151937Sjkim 702151937Sjkim/******************************************************************************* 703151937Sjkim * 704151937Sjkim * FUNCTION: CmDoOutputFiles 705151937Sjkim * 706151937Sjkim * PARAMETERS: None 707151937Sjkim * 708151937Sjkim * RETURN: None. 709151937Sjkim * 710151937Sjkim * DESCRIPTION: Create all "listing" type files 711151937Sjkim * 712151937Sjkim ******************************************************************************/ 713151937Sjkim 714118611Snjlvoid 715151937SjkimCmDoOutputFiles ( 716151937Sjkim void) 717118611Snjl{ 718118611Snjl 719118611Snjl /* Create listings and hex files */ 720118611Snjl 721118611Snjl LsDoListings (); 722245582Sjkim HxDoHexOutput (); 723118611Snjl 724118611Snjl /* Dump the namespace to the .nsp file if requested */ 725118611Snjl 726245582Sjkim (void) NsDisplayNamespace (); 727118611Snjl} 728118611Snjl 729118611Snjl 730118611Snjl/******************************************************************************* 731118611Snjl * 732237412Sjkim * FUNCTION: CmDumpAllEvents 733151937Sjkim * 734237412Sjkim * PARAMETERS: None 735151937Sjkim * 736151937Sjkim * RETURN: None. 737151937Sjkim * 738237412Sjkim * DESCRIPTION: Dump all compiler events 739151937Sjkim * 740151937Sjkim ******************************************************************************/ 741151937Sjkim 742151937Sjkimstatic void 743237412SjkimCmDumpAllEvents ( 744237412Sjkim void) 745151937Sjkim{ 746237412Sjkim ASL_EVENT_INFO *Event; 747151937Sjkim UINT32 Delta; 748151937Sjkim UINT32 USec; 749151937Sjkim UINT32 MSec; 750237412Sjkim UINT32 i; 751151937Sjkim 752237412Sjkim 753237412Sjkim Event = AslGbl_Events; 754237412Sjkim 755237412Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n"); 756237412Sjkim if (Gbl_CompileTimesFlag) 757151937Sjkim { 758237412Sjkim printf ("\nElapsed time for major events\n\n"); 759151937Sjkim } 760151937Sjkim 761237412Sjkim for (i = 0; i < AslGbl_NextEvent; i++) 762237412Sjkim { 763237412Sjkim if (Event->Valid) 764237412Sjkim { 765237412Sjkim /* Delta will be in 100-nanosecond units */ 766151937Sjkim 767237412Sjkim Delta = (UINT32) (Event->EndTime - Event->StartTime); 768151937Sjkim 769245582Sjkim USec = Delta / ACPI_100NSEC_PER_USEC; 770245582Sjkim MSec = Delta / ACPI_100NSEC_PER_MSEC; 771151937Sjkim 772237412Sjkim /* Round milliseconds up */ 773151937Sjkim 774245582Sjkim if ((USec - (MSec * ACPI_USEC_PER_MSEC)) >= 500) 775237412Sjkim { 776237412Sjkim MSec++; 777237412Sjkim } 778237412Sjkim 779237412Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n", 780237412Sjkim USec, MSec, Event->EventName); 781237412Sjkim 782237412Sjkim if (Gbl_CompileTimesFlag) 783237412Sjkim { 784237412Sjkim printf ("%8u usec %8u msec - %s\n", 785237412Sjkim USec, MSec, Event->EventName); 786237412Sjkim } 787237412Sjkim } 788237412Sjkim 789237412Sjkim Event++; 790151937Sjkim } 791151937Sjkim} 792151937Sjkim 793151937Sjkim 794151937Sjkim/******************************************************************************* 795151937Sjkim * 796118611Snjl * FUNCTION: CmCleanupAndExit 797118611Snjl * 798118611Snjl * PARAMETERS: None 799118611Snjl * 800118611Snjl * RETURN: None. 801118611Snjl * 802118611Snjl * DESCRIPTION: Close all open files and exit the compiler 803118611Snjl * 804118611Snjl ******************************************************************************/ 805118611Snjl 806118611Snjlvoid 807151937SjkimCmCleanupAndExit ( 808151937Sjkim void) 809118611Snjl{ 810118611Snjl UINT32 i; 811240716Sjkim BOOLEAN DeleteAmlFile = FALSE; 812118611Snjl 813118611Snjl 814234623Sjkim AePrintErrorLog (ASL_FILE_STDERR); 815118611Snjl if (Gbl_DebugFlag) 816118611Snjl { 817234623Sjkim /* Print error summary to stdout also */ 818118611Snjl 819234623Sjkim AePrintErrorLog (ASL_FILE_STDOUT); 820118611Snjl } 821118611Snjl 822237412Sjkim /* Emit compile times if enabled */ 823118611Snjl 824237412Sjkim CmDumpAllEvents (); 825237412Sjkim 826118611Snjl if (Gbl_CompileTimesFlag) 827118611Snjl { 828118611Snjl printf ("\nMiscellaneous compile statistics\n\n"); 829118611Snjl printf ("%11u : %s\n", TotalParseNodes, "Parse nodes"); 830118611Snjl printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches"); 831118611Snjl printf ("%11u : %s\n", TotalNamedObjects, "Named objects"); 832118611Snjl printf ("%11u : %s\n", TotalMethods, "Control methods"); 833118611Snjl printf ("%11u : %s\n", TotalAllocations, "Memory Allocations"); 834118611Snjl printf ("%11u : %s\n", TotalAllocated, "Total allocated memory"); 835118611Snjl printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded"); 836118611Snjl printf ("\n"); 837118611Snjl } 838118611Snjl 839118611Snjl if (Gbl_NsLookupCount) 840118611Snjl { 841209746Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 842209746Sjkim "\n\nMiscellaneous compile statistics\n\n"); 843209746Sjkim 844209746Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 845209746Sjkim "%32s : %u\n", "Total Namespace searches", 846151937Sjkim Gbl_NsLookupCount); 847209746Sjkim 848209746Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 849209746Sjkim "%32s : %u usec\n", "Time per search", ((UINT32) 850209746Sjkim (AslGbl_Events[AslGbl_NamespaceEvent].EndTime - 851209746Sjkim AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) / 852209746Sjkim Gbl_NsLookupCount); 853118611Snjl } 854118611Snjl 855118611Snjl if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT) 856118611Snjl { 857209746Sjkim printf ("\nMaximum error count (%u) exceeded\n", 858209746Sjkim ASL_MAX_ERROR_COUNT); 859118611Snjl } 860118611Snjl 861118611Snjl UtDisplaySummary (ASL_FILE_STDOUT); 862199337Sjkim 863240716Sjkim /* 864240716Sjkim * We will delete the AML file if there are errors and the 865240716Sjkim * force AML output option has not been used. 866240716Sjkim */ 867240716Sjkim if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors) && 868240716Sjkim Gbl_Files[ASL_FILE_AML_OUTPUT].Handle) 869240716Sjkim { 870240716Sjkim DeleteAmlFile = TRUE; 871240716Sjkim } 872240716Sjkim 873199337Sjkim /* Close all open files */ 874199337Sjkim 875233250Sjkim Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; /* the .i file is same as source file */ 876233250Sjkim 877233250Sjkim for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++) 878199337Sjkim { 879199337Sjkim FlCloseFile (i); 880199337Sjkim } 881200553Sjkim 882200553Sjkim /* Delete AML file if there are errors */ 883200553Sjkim 884240716Sjkim if (DeleteAmlFile) 885200553Sjkim { 886240716Sjkim FlDeleteFile (ASL_FILE_AML_OUTPUT); 887200553Sjkim } 888200553Sjkim 889233250Sjkim /* Delete the preprocessor output file (.i) unless -li flag is set */ 890233250Sjkim 891234623Sjkim if (!Gbl_PreprocessorOutputFlag && 892240716Sjkim Gbl_PreprocessFlag) 893233250Sjkim { 894240716Sjkim FlDeleteFile (ASL_FILE_PREPROCESSOR); 895233250Sjkim } 896233250Sjkim 897200553Sjkim /* 898200553Sjkim * Delete intermediate ("combined") source file (if -ls flag not set) 899209746Sjkim * This file is created during normal ASL/AML compiles. It is not 900209746Sjkim * created by the data table compiler. 901200553Sjkim * 902209746Sjkim * If the -ls flag is set, then the .SRC file should not be deleted. 903209746Sjkim * In this case, Gbl_SourceOutputFlag is set to TRUE. 904209746Sjkim * 905209746Sjkim * Note: Handles are cleared by FlCloseFile above, so we look at the 906209746Sjkim * filename instead, to determine if the .SRC file was actually 907209746Sjkim * created. 908209746Sjkim * 909200553Sjkim * TBD: SourceOutput should be .TMP, then rename if we want to keep it? 910200553Sjkim */ 911240716Sjkim if (!Gbl_SourceOutputFlag) 912200553Sjkim { 913240716Sjkim FlDeleteFile (ASL_FILE_SOURCE_OUTPUT); 914200553Sjkim } 915118611Snjl} 916