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