aslcompile.c revision 235945
1118611Snjl 2118611Snjl/****************************************************************************** 3118611Snjl * 4118611Snjl * Module Name: aslcompile - top level compile module 5118611Snjl * 6118611Snjl *****************************************************************************/ 7118611Snjl 8217365Sjkim/* 9229989Sjkim * Copyright (C) 2000 - 2012, Intel Corp. 10118611Snjl * All rights reserved. 11118611Snjl * 12217365Sjkim * Redistribution and use in source and binary forms, with or without 13217365Sjkim * modification, are permitted provided that the following conditions 14217365Sjkim * are met: 15217365Sjkim * 1. Redistributions of source code must retain the above copyright 16217365Sjkim * notice, this list of conditions, and the following disclaimer, 17217365Sjkim * without modification. 18217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 20217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 21217365Sjkim * including a substantially similar Disclaimer requirement for further 22217365Sjkim * binary redistribution. 23217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 24217365Sjkim * of any contributors may be used to endorse or promote products derived 25217365Sjkim * from this software without specific prior written permission. 26118611Snjl * 27217365Sjkim * Alternatively, this software may be distributed under the terms of the 28217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 29217365Sjkim * Software Foundation. 30118611Snjl * 31217365Sjkim * NO WARRANTY 32217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 43217365Sjkim */ 44118611Snjl 45217365Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 46217365Sjkim 47118611Snjl#include <stdio.h> 48151937Sjkim#include <time.h> 49213806Sjkim#include <contrib/dev/acpica/include/acapps.h> 50118611Snjl 51118611Snjl#define _COMPONENT ACPI_COMPILER 52118611Snjl ACPI_MODULE_NAME ("aslcompile") 53118611Snjl 54151937Sjkim/* Local prototypes */ 55118611Snjl 56151937Sjkimstatic void 57151937SjkimCmFlushSourceCode ( 58151937Sjkim void); 59151937Sjkim 60212761Sjkimstatic void 61193529SjkimFlConsumeAnsiComment ( 62235945Sjkim FILE *Handle, 63193529Sjkim ASL_FILE_STATUS *Status); 64151937Sjkim 65212761Sjkimstatic void 66193529SjkimFlConsumeNewComment ( 67235945Sjkim FILE *Handle, 68193529Sjkim ASL_FILE_STATUS *Status); 69193529Sjkim 70193529Sjkim 71118611Snjl/******************************************************************************* 72118611Snjl * 73118611Snjl * FUNCTION: AslCompilerSignon 74118611Snjl * 75118611Snjl * PARAMETERS: FileId - ID of the output file 76118611Snjl * 77118611Snjl * RETURN: None 78118611Snjl * 79118611Snjl * DESCRIPTION: Display compiler signon 80118611Snjl * 81118611Snjl ******************************************************************************/ 82118611Snjl 83118611Snjlvoid 84118611SnjlAslCompilerSignon ( 85118611Snjl UINT32 FileId) 86118611Snjl{ 87118611Snjl char *Prefix = ""; 88213806Sjkim char *UtilityName; 89118611Snjl 90118611Snjl 91151937Sjkim /* Set line prefix depending on the destination file type */ 92151937Sjkim 93118611Snjl switch (FileId) 94118611Snjl { 95118611Snjl case ASL_FILE_ASM_SOURCE_OUTPUT: 96118611Snjl case ASL_FILE_ASM_INCLUDE_OUTPUT: 97118611Snjl 98118611Snjl Prefix = "; "; 99118611Snjl break; 100118611Snjl 101118611Snjl case ASL_FILE_HEX_OUTPUT: 102118611Snjl 103118611Snjl if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM) 104118611Snjl { 105118611Snjl Prefix = "; "; 106118611Snjl } 107207344Sjkim else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) || 108207344Sjkim (Gbl_HexOutputFlag == HEX_OUTPUT_ASL)) 109118611Snjl { 110118611Snjl FlPrintFile (ASL_FILE_HEX_OUTPUT, "/*\n"); 111118611Snjl Prefix = " * "; 112118611Snjl } 113118611Snjl break; 114118611Snjl 115118611Snjl case ASL_FILE_C_SOURCE_OUTPUT: 116118611Snjl case ASL_FILE_C_INCLUDE_OUTPUT: 117118611Snjl 118118611Snjl Prefix = " * "; 119118611Snjl break; 120118611Snjl 121118611Snjl default: 122118611Snjl /* No other output types supported */ 123118611Snjl break; 124118611Snjl } 125118611Snjl 126151937Sjkim /* Running compiler or disassembler? */ 127151937Sjkim 128151937Sjkim if (Gbl_DisasmFlag) 129151937Sjkim { 130213806Sjkim UtilityName = AML_DISASSEMBLER_NAME; 131151937Sjkim } 132151937Sjkim else 133151937Sjkim { 134213806Sjkim UtilityName = ASL_COMPILER_NAME; 135151937Sjkim } 136151937Sjkim 137213806Sjkim /* Compiler signon with copyright */ 138151937Sjkim 139213806Sjkim FlPrintFile (FileId, "%s\n", Prefix); 140213806Sjkim FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix)); 141118611Snjl} 142118611Snjl 143118611Snjl 144118611Snjl/******************************************************************************* 145118611Snjl * 146118611Snjl * FUNCTION: AslCompilerFileHeader 147118611Snjl * 148118611Snjl * PARAMETERS: FileId - ID of the output file 149118611Snjl * 150118611Snjl * RETURN: None 151118611Snjl * 152118611Snjl * DESCRIPTION: Header used at the beginning of output files 153118611Snjl * 154118611Snjl ******************************************************************************/ 155118611Snjl 156118611Snjlvoid 157118611SnjlAslCompilerFileHeader ( 158118611Snjl UINT32 FileId) 159118611Snjl{ 160118611Snjl struct tm *NewTime; 161118611Snjl time_t Aclock; 162118611Snjl char *Prefix = ""; 163118611Snjl 164118611Snjl 165151937Sjkim /* Set line prefix depending on the destination file type */ 166151937Sjkim 167118611Snjl switch (FileId) 168118611Snjl { 169118611Snjl case ASL_FILE_ASM_SOURCE_OUTPUT: 170118611Snjl case ASL_FILE_ASM_INCLUDE_OUTPUT: 171118611Snjl 172118611Snjl Prefix = "; "; 173118611Snjl break; 174118611Snjl 175118611Snjl case ASL_FILE_HEX_OUTPUT: 176118611Snjl 177118611Snjl if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM) 178118611Snjl { 179118611Snjl Prefix = "; "; 180118611Snjl } 181207344Sjkim else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) || 182207344Sjkim (Gbl_HexOutputFlag == HEX_OUTPUT_ASL)) 183118611Snjl { 184118611Snjl Prefix = " * "; 185118611Snjl } 186118611Snjl break; 187118611Snjl 188118611Snjl case ASL_FILE_C_SOURCE_OUTPUT: 189118611Snjl case ASL_FILE_C_INCLUDE_OUTPUT: 190118611Snjl 191118611Snjl Prefix = " * "; 192118611Snjl break; 193118611Snjl 194118611Snjl default: 195118611Snjl /* No other output types supported */ 196118611Snjl break; 197118611Snjl } 198118611Snjl 199118611Snjl /* Compilation header with timestamp */ 200118611Snjl 201118611Snjl (void) time (&Aclock); 202118611Snjl NewTime = localtime (&Aclock); 203118611Snjl 204118611Snjl FlPrintFile (FileId, 205118611Snjl "%sCompilation of \"%s\" - %s%s\n", 206118611Snjl Prefix, Gbl_Files[ASL_FILE_INPUT].Filename, asctime (NewTime), 207118611Snjl Prefix); 208118611Snjl 209118611Snjl switch (FileId) 210118611Snjl { 211118611Snjl case ASL_FILE_C_SOURCE_OUTPUT: 212118611Snjl case ASL_FILE_C_INCLUDE_OUTPUT: 213118611Snjl FlPrintFile (FileId, " */\n"); 214118611Snjl break; 215118611Snjl 216118611Snjl default: 217118611Snjl /* Nothing to do for other output types */ 218118611Snjl break; 219118611Snjl } 220118611Snjl} 221118611Snjl 222118611Snjl 223118611Snjl/******************************************************************************* 224118611Snjl * 225118611Snjl * FUNCTION: CmFlushSourceCode 226118611Snjl * 227118611Snjl * PARAMETERS: None 228118611Snjl * 229118611Snjl * RETURN: None 230118611Snjl * 231118611Snjl * DESCRIPTION: Read in any remaining source code after the parse tree 232118611Snjl * has been constructed. 233118611Snjl * 234118611Snjl ******************************************************************************/ 235118611Snjl 236151937Sjkimstatic void 237151937SjkimCmFlushSourceCode ( 238151937Sjkim void) 239118611Snjl{ 240118611Snjl char Buffer; 241118611Snjl 242118611Snjl 243118611Snjl while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR) 244118611Snjl { 245234623Sjkim AslInsertLineBuffer ((int) Buffer); 246118611Snjl } 247118611Snjl 248234623Sjkim AslResetCurrentLineBuffer (); 249118611Snjl} 250118611Snjl 251118611Snjl 252118611Snjl/******************************************************************************* 253118611Snjl * 254167802Sjkim * FUNCTION: FlConsume* 255167802Sjkim * 256235945Sjkim * PARAMETERS: Handle - Open input file 257235945Sjkim * Status - File current status struct 258167802Sjkim * 259167802Sjkim * RETURN: Number of lines consumed 260167802Sjkim * 261167802Sjkim * DESCRIPTION: Step over both types of comment during check for ascii chars 262167802Sjkim * 263167802Sjkim ******************************************************************************/ 264167802Sjkim 265212761Sjkimstatic void 266167802SjkimFlConsumeAnsiComment ( 267235945Sjkim FILE *Handle, 268167802Sjkim ASL_FILE_STATUS *Status) 269167802Sjkim{ 270167802Sjkim UINT8 Byte; 271167802Sjkim BOOLEAN ClosingComment = FALSE; 272167802Sjkim 273167802Sjkim 274235945Sjkim while (fread (&Byte, 1, 1, Handle)) 275167802Sjkim { 276167802Sjkim /* Scan until comment close is found */ 277167802Sjkim 278167802Sjkim if (ClosingComment) 279167802Sjkim { 280167802Sjkim if (Byte == '/') 281167802Sjkim { 282167802Sjkim return; 283167802Sjkim } 284167802Sjkim 285167802Sjkim if (Byte != '*') 286167802Sjkim { 287167802Sjkim /* Reset */ 288167802Sjkim 289167802Sjkim ClosingComment = FALSE; 290167802Sjkim } 291167802Sjkim } 292167802Sjkim else if (Byte == '*') 293167802Sjkim { 294167802Sjkim ClosingComment = TRUE; 295167802Sjkim } 296167802Sjkim 297167802Sjkim /* Maintain line count */ 298167802Sjkim 299167802Sjkim if (Byte == 0x0A) 300167802Sjkim { 301167802Sjkim Status->Line++; 302167802Sjkim } 303167802Sjkim 304167802Sjkim Status->Offset++; 305167802Sjkim } 306167802Sjkim} 307167802Sjkim 308167802Sjkim 309212761Sjkimstatic void 310167802SjkimFlConsumeNewComment ( 311235945Sjkim FILE *Handle, 312167802Sjkim ASL_FILE_STATUS *Status) 313167802Sjkim{ 314167802Sjkim UINT8 Byte; 315167802Sjkim 316167802Sjkim 317235945Sjkim while (fread (&Byte, 1, 1, Handle)) 318167802Sjkim { 319167802Sjkim Status->Offset++; 320167802Sjkim 321167802Sjkim /* Comment ends at newline */ 322167802Sjkim 323167802Sjkim if (Byte == 0x0A) 324167802Sjkim { 325167802Sjkim Status->Line++; 326167802Sjkim return; 327167802Sjkim } 328167802Sjkim } 329167802Sjkim} 330167802Sjkim 331167802Sjkim 332167802Sjkim/******************************************************************************* 333167802Sjkim * 334123315Snjl * FUNCTION: FlCheckForAscii 335123315Snjl * 336235945Sjkim * PARAMETERS: Handle - Open input file 337235945Sjkim * Filename - Input filename 338235945Sjkim * DisplayErrors - TRUE if error messages desired 339123315Snjl * 340151937Sjkim * RETURN: Status 341123315Snjl * 342167802Sjkim * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters 343167802Sjkim * within comments. Note: does not handle nested comments and does 344167802Sjkim * not handle comment delimiters within string literals. However, 345167802Sjkim * on the rare chance this happens and an invalid character is 346167802Sjkim * missed, the parser will catch the error by failing in some 347167802Sjkim * spectactular manner. 348123315Snjl * 349123315Snjl ******************************************************************************/ 350123315Snjl 351209746SjkimACPI_STATUS 352123315SnjlFlCheckForAscii ( 353235945Sjkim FILE *Handle, 354235945Sjkim char *Filename, 355235945Sjkim BOOLEAN DisplayErrors) 356123315Snjl{ 357123315Snjl UINT8 Byte; 358123315Snjl ACPI_SIZE BadBytes = 0; 359167802Sjkim BOOLEAN OpeningComment = FALSE; 360167802Sjkim ASL_FILE_STATUS Status; 361123315Snjl 362123315Snjl 363167802Sjkim Status.Line = 1; 364167802Sjkim Status.Offset = 0; 365167802Sjkim 366123315Snjl /* Read the entire file */ 367123315Snjl 368235945Sjkim while (fread (&Byte, 1, 1, Handle)) 369123315Snjl { 370167802Sjkim /* Ignore comment fields (allow non-ascii within) */ 371167802Sjkim 372167802Sjkim if (OpeningComment) 373167802Sjkim { 374167802Sjkim /* Check for second comment open delimiter */ 375167802Sjkim 376167802Sjkim if (Byte == '*') 377167802Sjkim { 378235945Sjkim FlConsumeAnsiComment (Handle, &Status); 379167802Sjkim } 380167802Sjkim 381167802Sjkim if (Byte == '/') 382167802Sjkim { 383235945Sjkim FlConsumeNewComment (Handle, &Status); 384167802Sjkim } 385167802Sjkim 386167802Sjkim /* Reset */ 387167802Sjkim 388167802Sjkim OpeningComment = FALSE; 389167802Sjkim } 390167802Sjkim else if (Byte == '/') 391167802Sjkim { 392167802Sjkim OpeningComment = TRUE; 393167802Sjkim } 394167802Sjkim 395123315Snjl /* Check for an ASCII character */ 396123315Snjl 397193529Sjkim if (!ACPI_IS_ASCII (Byte)) 398123315Snjl { 399235945Sjkim if ((BadBytes < 10) && (DisplayErrors)) 400123315Snjl { 401151937Sjkim AcpiOsPrintf ( 402167802Sjkim "Non-ASCII character [0x%2.2X] found in line %u, file offset 0x%.2X\n", 403167802Sjkim Byte, Status.Line, Status.Offset); 404123315Snjl } 405167802Sjkim 406123315Snjl BadBytes++; 407123315Snjl } 408167802Sjkim 409167802Sjkim /* Update line counter */ 410167802Sjkim 411167802Sjkim else if (Byte == 0x0A) 412167802Sjkim { 413167802Sjkim Status.Line++; 414167802Sjkim } 415167802Sjkim 416167802Sjkim Status.Offset++; 417123315Snjl } 418123315Snjl 419151937Sjkim /* Seek back to the beginning of the source file */ 420151937Sjkim 421235945Sjkim fseek (Handle, 0, SEEK_SET); 422151937Sjkim 423123315Snjl /* Were there any non-ASCII characters in the file? */ 424123315Snjl 425123315Snjl if (BadBytes) 426123315Snjl { 427235945Sjkim if (DisplayErrors) 428235945Sjkim { 429235945Sjkim AcpiOsPrintf ( 430235945Sjkim "%u non-ASCII characters found in input source text, could be a binary file\n", 431235945Sjkim BadBytes); 432235945Sjkim AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename); 433235945Sjkim } 434235945Sjkim 435123315Snjl return (AE_BAD_CHARACTER); 436123315Snjl } 437123315Snjl 438235945Sjkim /* File is OK (100% ASCII) */ 439123315Snjl 440123315Snjl return (AE_OK); 441123315Snjl} 442123315Snjl 443123315Snjl 444123315Snjl/******************************************************************************* 445123315Snjl * 446118611Snjl * FUNCTION: CmDoCompile 447118611Snjl * 448118611Snjl * PARAMETERS: None 449118611Snjl * 450118611Snjl * RETURN: Status (0 = OK) 451118611Snjl * 452118611Snjl * DESCRIPTION: This procedure performs the entire compile 453118611Snjl * 454118611Snjl ******************************************************************************/ 455118611Snjl 456118611Snjlint 457151937SjkimCmDoCompile ( 458151937Sjkim void) 459118611Snjl{ 460118611Snjl ACPI_STATUS Status; 461151937Sjkim UINT8 FullCompile; 462151937Sjkim UINT8 Event; 463118611Snjl 464118611Snjl 465151937Sjkim FullCompile = UtBeginEvent ("*** Total Compile time ***"); 466151937Sjkim Event = UtBeginEvent ("Open input and output files"); 467151937Sjkim UtEndEvent (Event); 468118611Snjl 469233250Sjkim Event = UtBeginEvent ("Preprocess input file"); 470234623Sjkim if (Gbl_PreprocessFlag) 471233250Sjkim { 472234623Sjkim /* Preprocessor */ 473234623Sjkim 474234623Sjkim PrDoPreprocess (); 475234623Sjkim if (Gbl_PreprocessOnly) 476234623Sjkim { 477234623Sjkim UtEndEvent (Event); 478234623Sjkim CmCleanupAndExit (); 479234623Sjkim return 0; 480234623Sjkim } 481233250Sjkim } 482234623Sjkim UtEndEvent (Event); 483233250Sjkim 484118611Snjl /* Build the parse tree */ 485118611Snjl 486151937Sjkim Event = UtBeginEvent ("Parse source code and build parse tree"); 487118611Snjl AslCompilerparse(); 488151937Sjkim UtEndEvent (Event); 489118611Snjl 490118611Snjl /* Flush out any remaining source after parse tree is complete */ 491118611Snjl 492151937Sjkim Event = UtBeginEvent ("Flush source input"); 493118611Snjl CmFlushSourceCode (); 494118611Snjl 495118611Snjl /* Did the parse tree get successfully constructed? */ 496118611Snjl 497118611Snjl if (!RootNode) 498118611Snjl { 499234623Sjkim /* 500234623Sjkim * If there are no errors, then we have some sort of 501234623Sjkim * internal problem. 502234623Sjkim */ 503234623Sjkim Status = AslCheckForErrorExit (); 504234623Sjkim if (Status == AE_OK) 505234623Sjkim { 506234623Sjkim AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, 507234623Sjkim NULL, "- Could not resolve parse tree root node"); 508234623Sjkim } 509234623Sjkim 510233250Sjkim goto ErrorExit; 511118611Snjl } 512118611Snjl 513167802Sjkim /* Optional parse tree dump, compiler debug output only */ 514167802Sjkim 515167802Sjkim LsDumpParseTree (); 516167802Sjkim 517118611Snjl OpcGetIntegerWidth (RootNode); 518151937Sjkim UtEndEvent (Event); 519118611Snjl 520118611Snjl /* Pre-process parse tree for any operator transforms */ 521118611Snjl 522151937Sjkim Event = UtBeginEvent ("Parse tree transforms"); 523118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n"); 524151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 525151937Sjkim TrAmlTransformWalk, NULL, NULL); 526151937Sjkim UtEndEvent (Event); 527118611Snjl 528118611Snjl /* Generate AML opcodes corresponding to the parse tokens */ 529118611Snjl 530151937Sjkim Event = UtBeginEvent ("Generate AML opcodes"); 531118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating AML opcodes\n\n"); 532151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 533151937Sjkim OpcAmlOpcodeWalk, NULL); 534151937Sjkim UtEndEvent (Event); 535118611Snjl 536118611Snjl /* 537118611Snjl * Now that the input is parsed, we can open the AML output file. 538118611Snjl * Note: by default, the name of this file comes from the table descriptor 539118611Snjl * within the input file. 540118611Snjl */ 541151937Sjkim Event = UtBeginEvent ("Open AML output file"); 542118611Snjl Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix); 543233250Sjkim UtEndEvent (Event); 544118611Snjl if (ACPI_FAILURE (Status)) 545118611Snjl { 546118611Snjl AePrintErrorLog (ASL_FILE_STDERR); 547118611Snjl return -1; 548118611Snjl } 549118611Snjl 550118611Snjl /* Interpret and generate all compile-time constants */ 551118611Snjl 552151937Sjkim Event = UtBeginEvent ("Constant folding via AML interpreter"); 553151937Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 554151937Sjkim "\nInterpreting compile-time constant expressions\n\n"); 555151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 556151937Sjkim OpcAmlConstantWalk, NULL, NULL); 557151937Sjkim UtEndEvent (Event); 558118611Snjl 559151937Sjkim /* Update AML opcodes if necessary, after constant folding */ 560151937Sjkim 561151937Sjkim Event = UtBeginEvent ("Updating AML opcodes after constant folding"); 562151937Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 563151937Sjkim "\nUpdating AML opcodes after constant folding\n\n"); 564151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 565151937Sjkim NULL, OpcAmlOpcodeUpdateWalk, NULL); 566151937Sjkim UtEndEvent (Event); 567151937Sjkim 568118611Snjl /* Calculate all AML package lengths */ 569118611Snjl 570151937Sjkim Event = UtBeginEvent ("Generate AML package lengths"); 571118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n"); 572151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 573151937Sjkim LnPackageLengthWalk, NULL); 574151937Sjkim UtEndEvent (Event); 575118611Snjl 576118611Snjl if (Gbl_ParseOnlyFlag) 577118611Snjl { 578234623Sjkim AePrintErrorLog (ASL_FILE_STDERR); 579234623Sjkim UtDisplaySummary (ASL_FILE_STDERR); 580118611Snjl if (Gbl_DebugFlag) 581118611Snjl { 582234623Sjkim /* Print error summary to the stdout also */ 583118611Snjl 584234623Sjkim AePrintErrorLog (ASL_FILE_STDOUT); 585234623Sjkim UtDisplaySummary (ASL_FILE_STDOUT); 586118611Snjl } 587233250Sjkim UtEndEvent (FullCompile); 588118611Snjl return 0; 589118611Snjl } 590118611Snjl 591118611Snjl /* 592118611Snjl * Create an internal namespace and use it as a symbol table 593118611Snjl */ 594118611Snjl 595118611Snjl /* Namespace loading */ 596118611Snjl 597151937Sjkim Event = UtBeginEvent ("Create ACPI Namespace"); 598118611Snjl Status = LdLoadNamespace (RootNode); 599151937Sjkim UtEndEvent (Event); 600118611Snjl if (ACPI_FAILURE (Status)) 601118611Snjl { 602233250Sjkim goto ErrorExit; 603118611Snjl } 604118611Snjl 605167802Sjkim /* Namespace cross-reference */ 606118611Snjl 607151937Sjkim AslGbl_NamespaceEvent = UtBeginEvent ("Cross reference parse tree and Namespace"); 608118611Snjl Status = LkCrossReferenceNamespace (); 609118611Snjl if (ACPI_FAILURE (Status)) 610118611Snjl { 611233250Sjkim goto ErrorExit; 612118611Snjl } 613118611Snjl 614167802Sjkim /* Namespace - Check for non-referenced objects */ 615167802Sjkim 616167802Sjkim LkFindUnreferencedObjects (); 617167802Sjkim UtEndEvent (AslGbl_NamespaceEvent); 618167802Sjkim 619118611Snjl /* 620118611Snjl * Semantic analysis. This can happen only after the 621118611Snjl * namespace has been loaded and cross-referenced. 622118611Snjl * 623118611Snjl * part one - check control methods 624118611Snjl */ 625151937Sjkim Event = UtBeginEvent ("Analyze control method return types"); 626118611Snjl AnalysisWalkInfo.MethodStack = NULL; 627118611Snjl 628118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method analysis\n\n"); 629151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, 630151937Sjkim AnMethodAnalysisWalkBegin, 631151937Sjkim AnMethodAnalysisWalkEnd, &AnalysisWalkInfo); 632151937Sjkim UtEndEvent (Event); 633118611Snjl 634118611Snjl /* Semantic error checking part two - typing of method returns */ 635118611Snjl 636151937Sjkim Event = UtBeginEvent ("Determine object types returned by methods"); 637151937Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n"); 638218590Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 639218590Sjkim NULL, AnMethodTypingWalkEnd, NULL); 640151937Sjkim UtEndEvent (Event); 641118611Snjl 642118611Snjl /* Semantic error checking part three - operand type checking */ 643118611Snjl 644151937Sjkim Event = UtBeginEvent ("Analyze AML operand types"); 645151937Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n"); 646218590Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, 647218590Sjkim NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo); 648151937Sjkim UtEndEvent (Event); 649118611Snjl 650118611Snjl /* Semantic error checking part four - other miscellaneous checks */ 651118611Snjl 652151937Sjkim Event = UtBeginEvent ("Miscellaneous analysis"); 653151937Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n"); 654218590Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, 655151937Sjkim AnOtherSemanticAnalysisWalkBegin, 656218590Sjkim NULL, &AnalysisWalkInfo); 657151937Sjkim UtEndEvent (Event); 658118611Snjl 659118611Snjl /* Calculate all AML package lengths */ 660118611Snjl 661151937Sjkim Event = UtBeginEvent ("Finish AML package length generation"); 662118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n"); 663151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 664151937Sjkim LnInitLengthsWalk, NULL); 665151937Sjkim TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL, 666151937Sjkim LnPackageLengthWalk, NULL); 667151937Sjkim UtEndEvent (Event); 668118611Snjl 669118611Snjl /* Code generation - emit the AML */ 670118611Snjl 671151937Sjkim Event = UtBeginEvent ("Generate AML code and write output files"); 672118611Snjl CgGenerateAmlOutput (); 673151937Sjkim UtEndEvent (Event); 674118611Snjl 675151937Sjkim Event = UtBeginEvent ("Write optional output files"); 676118611Snjl CmDoOutputFiles (); 677151937Sjkim UtEndEvent (Event); 678118611Snjl 679151937Sjkim UtEndEvent (FullCompile); 680118611Snjl CmCleanupAndExit (); 681118611Snjl return 0; 682233250Sjkim 683233250SjkimErrorExit: 684233250Sjkim UtEndEvent (FullCompile); 685233250Sjkim CmCleanupAndExit (); 686233250Sjkim return (-1); 687118611Snjl} 688118611Snjl 689151937Sjkim 690151937Sjkim/******************************************************************************* 691151937Sjkim * 692151937Sjkim * FUNCTION: CmDoOutputFiles 693151937Sjkim * 694151937Sjkim * PARAMETERS: None 695151937Sjkim * 696151937Sjkim * RETURN: None. 697151937Sjkim * 698151937Sjkim * DESCRIPTION: Create all "listing" type files 699151937Sjkim * 700151937Sjkim ******************************************************************************/ 701151937Sjkim 702118611Snjlvoid 703151937SjkimCmDoOutputFiles ( 704151937Sjkim void) 705118611Snjl{ 706118611Snjl 707118611Snjl /* Create listings and hex files */ 708118611Snjl 709118611Snjl LsDoListings (); 710118611Snjl LsDoHexOutput (); 711118611Snjl 712118611Snjl /* Dump the namespace to the .nsp file if requested */ 713118611Snjl 714151937Sjkim (void) LsDisplayNamespace (); 715118611Snjl} 716118611Snjl 717118611Snjl 718118611Snjl/******************************************************************************* 719118611Snjl * 720151937Sjkim * FUNCTION: CmDumpEvent 721151937Sjkim * 722151937Sjkim * PARAMETERS: Event - A compiler event struct 723151937Sjkim * 724151937Sjkim * RETURN: None. 725151937Sjkim * 726151937Sjkim * DESCRIPTION: Dump a compiler event struct 727151937Sjkim * 728151937Sjkim ******************************************************************************/ 729151937Sjkim 730151937Sjkimstatic void 731151937SjkimCmDumpEvent ( 732151937Sjkim ASL_EVENT_INFO *Event) 733151937Sjkim{ 734151937Sjkim UINT32 Delta; 735151937Sjkim UINT32 USec; 736151937Sjkim UINT32 MSec; 737151937Sjkim 738151937Sjkim if (!Event->Valid) 739151937Sjkim { 740151937Sjkim return; 741151937Sjkim } 742151937Sjkim 743151937Sjkim /* Delta will be in 100-nanosecond units */ 744151937Sjkim 745151937Sjkim Delta = (UINT32) (Event->EndTime - Event->StartTime); 746151937Sjkim 747151937Sjkim USec = Delta / 10; 748151937Sjkim MSec = Delta / 10000; 749151937Sjkim 750151937Sjkim /* Round milliseconds up */ 751151937Sjkim 752151937Sjkim if ((USec - (MSec * 1000)) >= 500) 753151937Sjkim { 754151937Sjkim MSec++; 755151937Sjkim } 756151937Sjkim 757151937Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n", 758151937Sjkim USec, MSec, Event->EventName); 759151937Sjkim} 760151937Sjkim 761151937Sjkim 762151937Sjkim/******************************************************************************* 763151937Sjkim * 764118611Snjl * FUNCTION: CmCleanupAndExit 765118611Snjl * 766118611Snjl * PARAMETERS: None 767118611Snjl * 768118611Snjl * RETURN: None. 769118611Snjl * 770118611Snjl * DESCRIPTION: Close all open files and exit the compiler 771118611Snjl * 772118611Snjl ******************************************************************************/ 773118611Snjl 774118611Snjlvoid 775151937SjkimCmCleanupAndExit ( 776151937Sjkim void) 777118611Snjl{ 778118611Snjl UINT32 i; 779118611Snjl 780118611Snjl 781234623Sjkim AePrintErrorLog (ASL_FILE_STDERR); 782118611Snjl if (Gbl_DebugFlag) 783118611Snjl { 784234623Sjkim /* Print error summary to stdout also */ 785118611Snjl 786234623Sjkim AePrintErrorLog (ASL_FILE_STDOUT); 787118611Snjl } 788118611Snjl 789118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n"); 790151937Sjkim for (i = 0; i < AslGbl_NextEvent; i++) 791118611Snjl { 792151937Sjkim CmDumpEvent (&AslGbl_Events[i]); 793118611Snjl } 794118611Snjl 795118611Snjl if (Gbl_CompileTimesFlag) 796118611Snjl { 797118611Snjl printf ("\nElapsed time for major events\n\n"); 798151937Sjkim for (i = 0; i < AslGbl_NextEvent; i++) 799118611Snjl { 800151937Sjkim CmDumpEvent (&AslGbl_Events[i]); 801118611Snjl } 802151937Sjkim 803118611Snjl printf ("\nMiscellaneous compile statistics\n\n"); 804118611Snjl printf ("%11u : %s\n", TotalParseNodes, "Parse nodes"); 805118611Snjl printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches"); 806118611Snjl printf ("%11u : %s\n", TotalNamedObjects, "Named objects"); 807118611Snjl printf ("%11u : %s\n", TotalMethods, "Control methods"); 808118611Snjl printf ("%11u : %s\n", TotalAllocations, "Memory Allocations"); 809118611Snjl printf ("%11u : %s\n", TotalAllocated, "Total allocated memory"); 810118611Snjl printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded"); 811118611Snjl printf ("\n"); 812118611Snjl } 813118611Snjl 814118611Snjl if (Gbl_NsLookupCount) 815118611Snjl { 816209746Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 817209746Sjkim "\n\nMiscellaneous compile statistics\n\n"); 818209746Sjkim 819209746Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 820209746Sjkim "%32s : %u\n", "Total Namespace searches", 821151937Sjkim Gbl_NsLookupCount); 822209746Sjkim 823209746Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 824209746Sjkim "%32s : %u usec\n", "Time per search", ((UINT32) 825209746Sjkim (AslGbl_Events[AslGbl_NamespaceEvent].EndTime - 826209746Sjkim AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) / 827209746Sjkim Gbl_NsLookupCount); 828118611Snjl } 829118611Snjl 830118611Snjl if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT) 831118611Snjl { 832209746Sjkim printf ("\nMaximum error count (%u) exceeded\n", 833209746Sjkim ASL_MAX_ERROR_COUNT); 834118611Snjl } 835118611Snjl 836118611Snjl UtDisplaySummary (ASL_FILE_STDOUT); 837199337Sjkim 838199337Sjkim /* Close all open files */ 839199337Sjkim 840233250Sjkim Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; /* the .i file is same as source file */ 841233250Sjkim 842233250Sjkim for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++) 843199337Sjkim { 844199337Sjkim FlCloseFile (i); 845199337Sjkim } 846200553Sjkim 847200553Sjkim /* Delete AML file if there are errors */ 848200553Sjkim 849209746Sjkim if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors) && 850209746Sjkim Gbl_Files[ASL_FILE_AML_OUTPUT].Handle) 851200553Sjkim { 852209746Sjkim if (remove (Gbl_Files[ASL_FILE_AML_OUTPUT].Filename)) 853209746Sjkim { 854209746Sjkim printf ("%s: ", 855209746Sjkim Gbl_Files[ASL_FILE_AML_OUTPUT].Filename); 856209746Sjkim perror ("Could not delete AML file"); 857209746Sjkim } 858200553Sjkim } 859200553Sjkim 860233250Sjkim /* Delete the preprocessor output file (.i) unless -li flag is set */ 861233250Sjkim 862234623Sjkim if (!Gbl_PreprocessorOutputFlag && 863234623Sjkim Gbl_PreprocessFlag && 864234623Sjkim Gbl_Files[ASL_FILE_PREPROCESSOR].Filename) 865233250Sjkim { 866233250Sjkim if (remove (Gbl_Files[ASL_FILE_PREPROCESSOR].Filename)) 867233250Sjkim { 868233250Sjkim printf ("%s: ", 869233250Sjkim Gbl_Files[ASL_FILE_PREPROCESSOR].Filename); 870233250Sjkim perror ("Could not delete preprocessor .i file"); 871233250Sjkim } 872233250Sjkim } 873233250Sjkim 874200553Sjkim /* 875200553Sjkim * Delete intermediate ("combined") source file (if -ls flag not set) 876209746Sjkim * This file is created during normal ASL/AML compiles. It is not 877209746Sjkim * created by the data table compiler. 878200553Sjkim * 879209746Sjkim * If the -ls flag is set, then the .SRC file should not be deleted. 880209746Sjkim * In this case, Gbl_SourceOutputFlag is set to TRUE. 881209746Sjkim * 882209746Sjkim * Note: Handles are cleared by FlCloseFile above, so we look at the 883209746Sjkim * filename instead, to determine if the .SRC file was actually 884209746Sjkim * created. 885209746Sjkim * 886200553Sjkim * TBD: SourceOutput should be .TMP, then rename if we want to keep it? 887200553Sjkim */ 888209746Sjkim if (!Gbl_SourceOutputFlag && Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename) 889200553Sjkim { 890200553Sjkim if (remove (Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename)) 891200553Sjkim { 892209746Sjkim printf ("%s: ", 893200553Sjkim Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename); 894209746Sjkim perror ("Could not delete SRC file"); 895200553Sjkim } 896200553Sjkim } 897118611Snjl} 898118611Snjl 899118611Snjl 900