xref: /freebsd/sys/contrib/dev/acpica/compiler/aslcompile.c (revision 1e413cf93298b5b97441a21d9a50fdcd0ee9945e)
1 
2 /******************************************************************************
3  *
4  * Module Name: aslcompile - top level compile module
5  *              $Revision: 1.97 $
6  *
7  *****************************************************************************/
8 
9 /******************************************************************************
10  *
11  * 1. Copyright Notice
12  *
13  * Some or all of this work - Copyright (c) 1999 - 2007, Intel Corp.
14  * All rights reserved.
15  *
16  * 2. License
17  *
18  * 2.1. This is your license from Intel Corp. under its intellectual property
19  * rights.  You may have additional license terms from the party that provided
20  * you this software, covering your right to use that party's intellectual
21  * property rights.
22  *
23  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24  * copy of the source code appearing in this file ("Covered Code") an
25  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26  * base code distributed originally by Intel ("Original Intel Code") to copy,
27  * make derivatives, distribute, use and display any portion of the Covered
28  * Code in any form, with the right to sublicense such rights; and
29  *
30  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31  * license (with the right to sublicense), under only those claims of Intel
32  * patents that are infringed by the Original Intel Code, to make, use, sell,
33  * offer to sell, and import the Covered Code and derivative works thereof
34  * solely to the minimum extent necessary to exercise the above copyright
35  * license, and in no event shall the patent license extend to any additions
36  * to or modifications of the Original Intel Code.  No other license or right
37  * is granted directly or by implication, estoppel or otherwise;
38  *
39  * The above copyright and patent license is granted only if the following
40  * conditions are met:
41  *
42  * 3. Conditions
43  *
44  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45  * Redistribution of source code of any substantial portion of the Covered
46  * Code or modification with rights to further distribute source must include
47  * the above Copyright Notice, the above License, this list of Conditions,
48  * and the following Disclaimer and Export Compliance provision.  In addition,
49  * Licensee must cause all Covered Code to which Licensee contributes to
50  * contain a file documenting the changes Licensee made to create that Covered
51  * Code and the date of any change.  Licensee must include in that file the
52  * documentation of any changes made by any predecessor Licensee.  Licensee
53  * must include a prominent statement that the modification is derived,
54  * directly or indirectly, from Original Intel Code.
55  *
56  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57  * Redistribution of source code of any substantial portion of the Covered
58  * Code or modification without rights to further distribute source must
59  * include the following Disclaimer and Export Compliance provision in the
60  * documentation and/or other materials provided with distribution.  In
61  * addition, Licensee may not authorize further sublicense of source of any
62  * portion of the Covered Code, and must include terms to the effect that the
63  * license from Licensee to its licensee is limited to the intellectual
64  * property embodied in the software Licensee provides to its licensee, and
65  * not to intellectual property embodied in modifications its licensee may
66  * make.
67  *
68  * 3.3. Redistribution of Executable. Redistribution in executable form of any
69  * substantial portion of the Covered Code or modification must reproduce the
70  * above Copyright Notice, and the following Disclaimer and Export Compliance
71  * provision in the documentation and/or other materials provided with the
72  * distribution.
73  *
74  * 3.4. Intel retains all right, title, and interest in and to the Original
75  * Intel Code.
76  *
77  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78  * Intel shall be used in advertising or otherwise to promote the sale, use or
79  * other dealings in products derived from or relating to the Covered Code
80  * without prior written authorization from Intel.
81  *
82  * 4. Disclaimer and Export Compliance
83  *
84  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
88  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
89  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90  * PARTICULAR PURPOSE.
91  *
92  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
98  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99  * LIMITED REMEDY.
100  *
101  * 4.3. Licensee shall not export, either directly or indirectly, any of this
102  * software or system incorporating such software without first obtaining any
103  * required license or other approval from the U. S. Department of Commerce or
104  * any other agency or department of the United States Government.  In the
105  * event Licensee exports any such software from the United States or
106  * re-exports any such software from a foreign destination, Licensee shall
107  * ensure that the distribution and export/re-export of the software is in
108  * compliance with all laws, regulations, orders, or other restrictions of the
109  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110  * any of its subsidiaries will export/re-export any technical data, process,
111  * software, or service, directly or indirectly, to any country for which the
112  * United States government or any agency thereof requires an export license,
113  * other governmental approval, or letter of assurance, without first obtaining
114  * such license, approval or letter.
115  *
116  *****************************************************************************/
117 
118 #include <stdio.h>
119 #include <time.h>
120 #include <contrib/dev/acpica/compiler/aslcompiler.h>
121 
122 #define _COMPONENT          ACPI_COMPILER
123         ACPI_MODULE_NAME    ("aslcompile")
124 
125 /* Local prototypes */
126 
127 static void
128 CmFlushSourceCode (
129     void);
130 
131 static ACPI_STATUS
132 FlCheckForAscii (
133     ASL_FILE_INFO           *FileInfo);
134 
135 
136 /*******************************************************************************
137  *
138  * FUNCTION:    AslCompilerSignon
139  *
140  * PARAMETERS:  FileId      - ID of the output file
141  *
142  * RETURN:      None
143  *
144  * DESCRIPTION: Display compiler signon
145  *
146  ******************************************************************************/
147 
148 void
149 AslCompilerSignon (
150     UINT32                  FileId)
151 {
152     char                    *Prefix = "";
153 
154 
155     /* Set line prefix depending on the destination file type */
156 
157     switch (FileId)
158     {
159     case ASL_FILE_ASM_SOURCE_OUTPUT:
160     case ASL_FILE_ASM_INCLUDE_OUTPUT:
161 
162         Prefix = "; ";
163         break;
164 
165     case ASL_FILE_HEX_OUTPUT:
166 
167         if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
168         {
169             Prefix = "; ";
170         }
171         else if (Gbl_HexOutputFlag == HEX_OUTPUT_C)
172         {
173             FlPrintFile (ASL_FILE_HEX_OUTPUT, "/*\n");
174             Prefix = " * ";
175         }
176         break;
177 
178     case ASL_FILE_C_SOURCE_OUTPUT:
179     case ASL_FILE_C_INCLUDE_OUTPUT:
180 
181         Prefix = " * ";
182         break;
183 
184     default:
185         /* No other output types supported */
186         break;
187     }
188 
189     /*
190      * Compiler signon with copyright
191      */
192     FlPrintFile (FileId,
193         "%s\n%s%s\n%s",
194         Prefix,
195         Prefix, IntelAcpiCA,
196         Prefix);
197 
198     /* Running compiler or disassembler? */
199 
200     if (Gbl_DisasmFlag)
201     {
202         FlPrintFile (FileId,
203             "%s", DisassemblerId);
204     }
205     else
206     {
207         FlPrintFile (FileId,
208             "%s", CompilerId);
209     }
210 
211     /* Version, build date, copyright, compliance */
212 
213     FlPrintFile (FileId,
214         " version %X [%s]\n%s%s\n%s%s\n%s\n",
215         (UINT32) ACPI_CA_VERSION, __DATE__,
216         Prefix, CompilerCopyright,
217         Prefix, CompilerCompliance,
218         Prefix);
219 }
220 
221 
222 /*******************************************************************************
223  *
224  * FUNCTION:    AslCompilerFileHeader
225  *
226  * PARAMETERS:  FileId      - ID of the output file
227  *
228  * RETURN:      None
229  *
230  * DESCRIPTION: Header used at the beginning of output files
231  *
232  ******************************************************************************/
233 
234 void
235 AslCompilerFileHeader (
236     UINT32                  FileId)
237 {
238     struct tm               *NewTime;
239     time_t                  Aclock;
240     char                    *Prefix = "";
241 
242 
243     /* Set line prefix depending on the destination file type */
244 
245     switch (FileId)
246     {
247     case ASL_FILE_ASM_SOURCE_OUTPUT:
248     case ASL_FILE_ASM_INCLUDE_OUTPUT:
249 
250         Prefix = "; ";
251         break;
252 
253     case ASL_FILE_HEX_OUTPUT:
254 
255         if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
256         {
257             Prefix = "; ";
258         }
259         else if (Gbl_HexOutputFlag == HEX_OUTPUT_C)
260         {
261             Prefix = " * ";
262         }
263         break;
264 
265     case ASL_FILE_C_SOURCE_OUTPUT:
266     case ASL_FILE_C_INCLUDE_OUTPUT:
267 
268         Prefix = " * ";
269         break;
270 
271     default:
272         /* No other output types supported */
273         break;
274     }
275 
276     /* Compilation header with timestamp */
277 
278     (void) time (&Aclock);
279     NewTime = localtime (&Aclock);
280 
281     FlPrintFile (FileId,
282         "%sCompilation of \"%s\" - %s%s\n",
283         Prefix, Gbl_Files[ASL_FILE_INPUT].Filename, asctime (NewTime),
284         Prefix);
285 
286     switch (FileId)
287     {
288     case ASL_FILE_C_SOURCE_OUTPUT:
289     case ASL_FILE_C_INCLUDE_OUTPUT:
290         FlPrintFile (FileId, " */\n");
291         break;
292 
293     default:
294         /* Nothing to do for other output types */
295         break;
296     }
297 }
298 
299 
300 /*******************************************************************************
301  *
302  * FUNCTION:    CmFlushSourceCode
303  *
304  * PARAMETERS:  None
305  *
306  * RETURN:      None
307  *
308  * DESCRIPTION: Read in any remaining source code after the parse tree
309  *              has been constructed.
310  *
311  ******************************************************************************/
312 
313 static void
314 CmFlushSourceCode (
315     void)
316 {
317     char                    Buffer;
318 
319 
320     while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR)
321     {
322         InsertLineBuffer ((int) Buffer);
323     }
324 
325     ResetCurrentLineBuffer ();
326 }
327 
328 
329 /*******************************************************************************
330  *
331  * FUNCTION:    FlConsume*
332  *
333  * PARAMETERS:  FileInfo        - Points to an open input file
334  *
335  * RETURN:      Number of lines consumed
336  *
337  * DESCRIPTION: Step over both types of comment during check for ascii chars
338  *
339  ******************************************************************************/
340 
341 void
342 FlConsumeAnsiComment (
343     ASL_FILE_INFO           *FileInfo,
344     ASL_FILE_STATUS         *Status)
345 {
346     UINT8                   Byte;
347     BOOLEAN                 ClosingComment = FALSE;
348 
349 
350     while (fread (&Byte, 1, 1, FileInfo->Handle))
351     {
352         /* Scan until comment close is found */
353 
354         if (ClosingComment)
355         {
356             if (Byte == '/')
357             {
358                 return;
359             }
360 
361             if (Byte != '*')
362             {
363                 /* Reset */
364 
365                 ClosingComment = FALSE;
366             }
367         }
368         else if (Byte == '*')
369         {
370             ClosingComment = TRUE;
371         }
372 
373         /* Maintain line count */
374 
375         if (Byte == 0x0A)
376         {
377             Status->Line++;
378         }
379 
380         Status->Offset++;
381     }
382 }
383 
384 
385 void
386 FlConsumeNewComment (
387     ASL_FILE_INFO           *FileInfo,
388     ASL_FILE_STATUS         *Status)
389 {
390     UINT8                   Byte;
391 
392 
393     while (fread (&Byte, 1, 1, FileInfo->Handle))
394     {
395         Status->Offset++;
396 
397         /* Comment ends at newline */
398 
399         if (Byte == 0x0A)
400         {
401             Status->Line++;
402             return;
403         }
404     }
405 }
406 
407 
408 /*******************************************************************************
409  *
410  * FUNCTION:    FlCheckForAscii
411  *
412  * PARAMETERS:  FileInfo        - Points to an open input file
413  *
414  * RETURN:      Status
415  *
416  * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters
417  *              within comments. Note: does not handle nested comments and does
418  *              not handle comment delimiters within string literals. However,
419  *              on the rare chance this happens and an invalid character is
420  *              missed, the parser will catch the error by failing in some
421  *              spectactular manner.
422  *
423  ******************************************************************************/
424 
425 static ACPI_STATUS
426 FlCheckForAscii (
427     ASL_FILE_INFO           *FileInfo)
428 {
429     UINT8                   Byte;
430     ACPI_SIZE               BadBytes = 0;
431     BOOLEAN                 OpeningComment = FALSE;
432     ASL_FILE_STATUS         Status;
433 
434 
435     Status.Line = 1;
436     Status.Offset = 0;
437 
438     /* Read the entire file */
439 
440     while (fread (&Byte, 1, 1, FileInfo->Handle))
441     {
442         /* Ignore comment fields (allow non-ascii within) */
443 
444         if (OpeningComment)
445         {
446             /* Check for second comment open delimiter */
447 
448             if (Byte == '*')
449             {
450                 FlConsumeAnsiComment (FileInfo, &Status);
451             }
452 
453             if (Byte == '/')
454             {
455                 FlConsumeNewComment (FileInfo, &Status);
456             }
457 
458             /* Reset */
459 
460             OpeningComment = FALSE;
461         }
462         else if (Byte == '/')
463         {
464             OpeningComment = TRUE;
465         }
466 
467         /* Check for an ASCII character */
468 
469         if (!isascii (Byte))
470         {
471             if (BadBytes < 10)
472             {
473                 AcpiOsPrintf (
474                     "Non-ASCII character [0x%2.2X] found in line %u, file offset 0x%.2X\n",
475                     Byte, Status.Line, Status.Offset);
476             }
477 
478             BadBytes++;
479         }
480 
481         /* Update line counter */
482 
483         else if (Byte == 0x0A)
484         {
485             Status.Line++;
486         }
487 
488         Status.Offset++;
489     }
490 
491     /* Seek back to the beginning of the source file */
492 
493     fseek (FileInfo->Handle, 0, SEEK_SET);
494 
495     /* Were there any non-ASCII characters in the file? */
496 
497     if (BadBytes)
498     {
499         AcpiOsPrintf (
500             "%u non-ASCII characters found in input source text, could be a binary file\n",
501             BadBytes);
502         AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, FileInfo->Filename);
503         return (AE_BAD_CHARACTER);
504     }
505 
506     /* File is OK */
507 
508     return (AE_OK);
509 }
510 
511 
512 /*******************************************************************************
513  *
514  * FUNCTION:    CmDoCompile
515  *
516  * PARAMETERS:  None
517  *
518  * RETURN:      Status (0 = OK)
519  *
520  * DESCRIPTION: This procedure performs the entire compile
521  *
522  ******************************************************************************/
523 
524 int
525 CmDoCompile (
526     void)
527 {
528     ACPI_STATUS             Status;
529     UINT8                   FullCompile;
530     UINT8                   Event;
531 
532 
533     FullCompile = UtBeginEvent ("*** Total Compile time ***");
534     Event = UtBeginEvent ("Open input and output files");
535 
536     /* Open the required input and output files */
537 
538     Status = FlOpenInputFile (Gbl_Files[ASL_FILE_INPUT].Filename);
539     if (ACPI_FAILURE (Status))
540     {
541         AePrintErrorLog (ASL_FILE_STDERR);
542         return -1;
543     }
544 
545     /* Check for 100% ASCII source file (comments are ignored) */
546 
547     Status = FlCheckForAscii (&Gbl_Files[ASL_FILE_INPUT]);
548     if (ACPI_FAILURE (Status))
549     {
550         AePrintErrorLog (ASL_FILE_STDERR);
551         return -1;
552     }
553 
554     Status = FlOpenMiscOutputFiles (Gbl_OutputFilenamePrefix);
555     if (ACPI_FAILURE (Status))
556     {
557         AePrintErrorLog (ASL_FILE_STDERR);
558         return -1;
559     }
560     UtEndEvent (Event);
561 
562     /* Build the parse tree */
563 
564     Event = UtBeginEvent ("Parse source code and build parse tree");
565     AslCompilerparse();
566     UtEndEvent (Event);
567 
568     /* Flush out any remaining source after parse tree is complete */
569 
570     Event = UtBeginEvent ("Flush source input");
571     CmFlushSourceCode ();
572 
573     /* Did the parse tree get successfully constructed? */
574 
575     if (!RootNode)
576     {
577         CmCleanupAndExit ();
578         return -1;
579     }
580 
581     /* Optional parse tree dump, compiler debug output only */
582 
583     LsDumpParseTree ();
584 
585     OpcGetIntegerWidth (RootNode);
586     UtEndEvent (Event);
587 
588     /* Pre-process parse tree for any operator transforms */
589 
590     Event = UtBeginEvent ("Parse tree transforms");
591     DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n");
592     TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
593         TrAmlTransformWalk, NULL, NULL);
594     UtEndEvent (Event);
595 
596     /* Generate AML opcodes corresponding to the parse tokens */
597 
598     Event = UtBeginEvent ("Generate AML opcodes");
599     DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating AML opcodes\n\n");
600     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
601         OpcAmlOpcodeWalk, NULL);
602     UtEndEvent (Event);
603 
604     /*
605      * Now that the input is parsed, we can open the AML output file.
606      * Note: by default, the name of this file comes from the table descriptor
607      * within the input file.
608      */
609     Event = UtBeginEvent ("Open AML output file");
610     Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
611     if (ACPI_FAILURE (Status))
612     {
613         AePrintErrorLog (ASL_FILE_STDERR);
614         return -1;
615     }
616     UtEndEvent (Event);
617 
618     /* Interpret and generate all compile-time constants */
619 
620     Event = UtBeginEvent ("Constant folding via AML interpreter");
621     DbgPrint (ASL_DEBUG_OUTPUT,
622         "\nInterpreting compile-time constant expressions\n\n");
623     TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
624         OpcAmlConstantWalk, NULL, NULL);
625     UtEndEvent (Event);
626 
627     /* Update AML opcodes if necessary, after constant folding */
628 
629     Event = UtBeginEvent ("Updating AML opcodes after constant folding");
630     DbgPrint (ASL_DEBUG_OUTPUT,
631         "\nUpdating AML opcodes after constant folding\n\n");
632     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
633         NULL, OpcAmlOpcodeUpdateWalk, NULL);
634     UtEndEvent (Event);
635 
636     /* Calculate all AML package lengths */
637 
638     Event = UtBeginEvent ("Generate AML package lengths");
639     DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
640     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
641         LnPackageLengthWalk, NULL);
642     UtEndEvent (Event);
643 
644     if (Gbl_ParseOnlyFlag)
645     {
646         AePrintErrorLog (ASL_FILE_STDOUT);
647         UtDisplaySummary (ASL_FILE_STDOUT);
648         if (Gbl_DebugFlag)
649         {
650             /* Print error summary to the debug file */
651 
652             AePrintErrorLog (ASL_FILE_STDERR);
653             UtDisplaySummary (ASL_FILE_STDERR);
654         }
655         return 0;
656     }
657 
658     /*
659      * Create an internal namespace and use it as a symbol table
660      */
661 
662     /* Namespace loading */
663 
664     Event = UtBeginEvent ("Create ACPI Namespace");
665     Status = LdLoadNamespace (RootNode);
666     UtEndEvent (Event);
667     if (ACPI_FAILURE (Status))
668     {
669         return -1;
670     }
671 
672     /* Namespace cross-reference */
673 
674     AslGbl_NamespaceEvent = UtBeginEvent ("Cross reference parse tree and Namespace");
675     Status = LkCrossReferenceNamespace ();
676     if (ACPI_FAILURE (Status))
677     {
678         return -1;
679     }
680 
681     /* Namespace - Check for non-referenced objects */
682 
683     LkFindUnreferencedObjects ();
684     UtEndEvent (AslGbl_NamespaceEvent);
685 
686     /*
687      * Semantic analysis.  This can happen only after the
688      * namespace has been loaded and cross-referenced.
689      *
690      * part one - check control methods
691      */
692     Event = UtBeginEvent ("Analyze control method return types");
693     AnalysisWalkInfo.MethodStack = NULL;
694 
695     DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method analysis\n\n");
696     TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
697         AnMethodAnalysisWalkBegin,
698         AnMethodAnalysisWalkEnd, &AnalysisWalkInfo);
699     UtEndEvent (Event);
700 
701     /* Semantic error checking part two - typing of method returns */
702 
703     Event = UtBeginEvent ("Determine object types returned by methods");
704     DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n");
705     TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
706         AnMethodTypingWalkBegin,
707         AnMethodTypingWalkEnd, NULL);
708     UtEndEvent (Event);
709 
710     /* Semantic error checking part three - operand type checking */
711 
712     Event = UtBeginEvent ("Analyze AML operand types");
713     DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n");
714     TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
715         AnOperandTypecheckWalkBegin,
716         AnOperandTypecheckWalkEnd, &AnalysisWalkInfo);
717     UtEndEvent (Event);
718 
719     /* Semantic error checking part four - other miscellaneous checks */
720 
721     Event = UtBeginEvent ("Miscellaneous analysis");
722     DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n");
723     TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
724         AnOtherSemanticAnalysisWalkBegin,
725         AnOtherSemanticAnalysisWalkEnd, &AnalysisWalkInfo);
726     UtEndEvent (Event);
727 
728     /* Calculate all AML package lengths */
729 
730     Event = UtBeginEvent ("Finish AML package length generation");
731     DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
732     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
733         LnInitLengthsWalk, NULL);
734     TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
735         LnPackageLengthWalk, NULL);
736     UtEndEvent (Event);
737 
738     /* Code generation - emit the AML */
739 
740     Event = UtBeginEvent ("Generate AML code and write output files");
741     CgGenerateAmlOutput ();
742     UtEndEvent (Event);
743 
744     Event = UtBeginEvent ("Write optional output files");
745     CmDoOutputFiles ();
746     UtEndEvent (Event);
747 
748     UtEndEvent (FullCompile);
749     CmCleanupAndExit ();
750     return 0;
751 }
752 
753 
754 /*******************************************************************************
755  *
756  * FUNCTION:    CmDoOutputFiles
757  *
758  * PARAMETERS:  None
759  *
760  * RETURN:      None.
761  *
762  * DESCRIPTION: Create all "listing" type files
763  *
764  ******************************************************************************/
765 
766 void
767 CmDoOutputFiles (
768     void)
769 {
770 
771     /* Create listings and hex files */
772 
773     LsDoListings ();
774     LsDoHexOutput ();
775 
776     /* Dump the namespace to the .nsp file if requested */
777 
778     (void) LsDisplayNamespace ();
779 }
780 
781 
782 /*******************************************************************************
783  *
784  * FUNCTION:    CmDumpEvent
785  *
786  * PARAMETERS:  Event           - A compiler event struct
787  *
788  * RETURN:      None.
789  *
790  * DESCRIPTION: Dump a compiler event struct
791  *
792  ******************************************************************************/
793 
794 static void
795 CmDumpEvent (
796     ASL_EVENT_INFO          *Event)
797 {
798     UINT32                  Delta;
799     UINT32                  USec;
800     UINT32                  MSec;
801 
802     if (!Event->Valid)
803     {
804         return;
805     }
806 
807     /* Delta will be in 100-nanosecond units */
808 
809     Delta = (UINT32) (Event->EndTime - Event->StartTime);
810 
811     USec = Delta / 10;
812     MSec = Delta / 10000;
813 
814     /* Round milliseconds up */
815 
816     if ((USec - (MSec * 1000)) >= 500)
817     {
818         MSec++;
819     }
820 
821     DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n",
822         USec, MSec, Event->EventName);
823 }
824 
825 
826 /*******************************************************************************
827  *
828  * FUNCTION:    CmCleanupAndExit
829  *
830  * PARAMETERS:  None
831  *
832  * RETURN:      None.
833  *
834  * DESCRIPTION: Close all open files and exit the compiler
835  *
836  ******************************************************************************/
837 
838 void
839 CmCleanupAndExit (
840     void)
841 {
842     UINT32                  i;
843 
844 
845     AePrintErrorLog (ASL_FILE_STDOUT);
846     if (Gbl_DebugFlag)
847     {
848         /* Print error summary to the debug file */
849 
850         AePrintErrorLog (ASL_FILE_STDERR);
851     }
852 
853     DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n");
854     for (i = 0; i < AslGbl_NextEvent; i++)
855     {
856         CmDumpEvent (&AslGbl_Events[i]);
857     }
858 
859     if (Gbl_CompileTimesFlag)
860     {
861         printf ("\nElapsed time for major events\n\n");
862         for (i = 0; i < AslGbl_NextEvent; i++)
863         {
864             CmDumpEvent (&AslGbl_Events[i]);
865         }
866 
867         printf ("\nMiscellaneous compile statistics\n\n");
868         printf ("%11u : %s\n", TotalParseNodes, "Parse nodes");
869         printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches");
870         printf ("%11u : %s\n", TotalNamedObjects, "Named objects");
871         printf ("%11u : %s\n", TotalMethods, "Control methods");
872         printf ("%11u : %s\n", TotalAllocations, "Memory Allocations");
873         printf ("%11u : %s\n", TotalAllocated, "Total allocated memory");
874         printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded");
875         printf ("\n");
876     }
877 
878     if (Gbl_NsLookupCount)
879     {
880         DbgPrint (ASL_DEBUG_OUTPUT, "\n\nMiscellaneous compile statistics\n\n");
881         DbgPrint (ASL_DEBUG_OUTPUT, "%32s : %d\n", "Total Namespace searches",
882             Gbl_NsLookupCount);
883         DbgPrint (ASL_DEBUG_OUTPUT, "%32s : %d usec\n", "Time per search",
884             ((UINT32) (AslGbl_Events[AslGbl_NamespaceEvent].EndTime -
885                         AslGbl_Events[AslGbl_NamespaceEvent].StartTime) /
886                         10) / Gbl_NsLookupCount);
887     }
888 
889     /* Close all open files */
890 
891     for (i = 2; i < ASL_MAX_FILE_TYPE; i++)
892     {
893         FlCloseFile (i);
894     }
895 
896     /*
897      * TBD: SourceOutput should be .TMP, then rename if we want to keep it?
898      */
899     if (!Gbl_SourceOutputFlag)
900     {
901         remove (Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
902     }
903 
904     /* Delete AML file if there are errors */
905 
906     if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors))
907     {
908         remove (Gbl_Files[ASL_FILE_AML_OUTPUT].Filename);
909     }
910 
911     if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
912     {
913         printf ("\nMaximum error count (%d) exceeded\n", ASL_MAX_ERROR_COUNT);
914     }
915 
916     UtDisplaySummary (ASL_FILE_STDOUT);
917 
918     /*
919      * Return non-zero exit code if there have been errors, unless the
920      * global ignore error flag has been set
921      */
922     if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors))
923     {
924         exit (1);
925     }
926     exit (0);
927 }
928 
929 
930