1118611Snjl/******************************************************************************
2118611Snjl *
3118611Snjl * Module Name: aslcompile - top level compile module
4118611Snjl *
5118611Snjl *****************************************************************************/
6118611Snjl
7217365Sjkim/*
8298714Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
9118611Snjl * All rights reserved.
10118611Snjl *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
25118611Snjl *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
29118611Snjl *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
43118611Snjl
44217365Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
45246849Sjkim#include <contrib/dev/acpica/compiler/dtcompiler.h>
46272444Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
47217365Sjkim
48118611Snjl#include <stdio.h>
49151937Sjkim#include <time.h>
50213806Sjkim#include <contrib/dev/acpica/include/acapps.h>
51118611Snjl
52118611Snjl#define _COMPONENT          ACPI_COMPILER
53118611Snjl        ACPI_MODULE_NAME    ("aslcompile")
54118611Snjl
55243347Sjkim/*
56243347Sjkim * Main parser entry
57243347Sjkim * External is here in case the parser emits the same external in the
58243347Sjkim * generated header. (Newer versions of Bison)
59243347Sjkim */
60243347Sjkimint
61243347SjkimAslCompilerparse(
62243347Sjkim    void);
63243347Sjkim
64151937Sjkim/* Local prototypes */
65118611Snjl
66151937Sjkimstatic void
67151937SjkimCmFlushSourceCode (
68151937Sjkim    void);
69151937Sjkim
70212761Sjkimstatic void
71237412SjkimCmDumpAllEvents (
72237412Sjkim    void);
73193529Sjkim
74237412Sjkim
75118611Snjl/*******************************************************************************
76118611Snjl *
77118611Snjl * FUNCTION:    CmDoCompile
78118611Snjl *
79118611Snjl * PARAMETERS:  None
80118611Snjl *
81118611Snjl * RETURN:      Status (0 = OK)
82118611Snjl *
83118611Snjl * DESCRIPTION: This procedure performs the entire compile
84118611Snjl *
85118611Snjl ******************************************************************************/
86118611Snjl
87118611Snjlint
88151937SjkimCmDoCompile (
89151937Sjkim    void)
90118611Snjl{
91118611Snjl    ACPI_STATUS             Status;
92151937Sjkim    UINT8                   FullCompile;
93151937Sjkim    UINT8                   Event;
94118611Snjl
95118611Snjl
96151937Sjkim    FullCompile = UtBeginEvent ("*** Total Compile time ***");
97151937Sjkim    Event = UtBeginEvent ("Open input and output files");
98151937Sjkim    UtEndEvent (Event);
99118611Snjl
100233250Sjkim    Event = UtBeginEvent ("Preprocess input file");
101234623Sjkim    if (Gbl_PreprocessFlag)
102233250Sjkim    {
103285797Sjkim        /* Enter compiler name as a #define */
104285797Sjkim
105285797Sjkim        PrAddDefine (ASL_DEFINE, "", FALSE);
106285797Sjkim
107234623Sjkim        /* Preprocessor */
108234623Sjkim
109234623Sjkim        PrDoPreprocess ();
110284583Sjkim        Gbl_CurrentLineNumber = 1;
111284583Sjkim        Gbl_LogicalLineNumber = 1;
112284583Sjkim
113234623Sjkim        if (Gbl_PreprocessOnly)
114234623Sjkim        {
115234623Sjkim            UtEndEvent (Event);
116234623Sjkim            CmCleanupAndExit ();
117241973Sjkim            return (0);
118234623Sjkim        }
119233250Sjkim    }
120234623Sjkim    UtEndEvent (Event);
121233250Sjkim
122284583Sjkim
123118611Snjl    /* Build the parse tree */
124118611Snjl
125151937Sjkim    Event = UtBeginEvent ("Parse source code and build parse tree");
126118611Snjl    AslCompilerparse();
127151937Sjkim    UtEndEvent (Event);
128118611Snjl
129278970Sjkim    /* Check for parser-detected syntax errors */
130118611Snjl
131278970Sjkim    if (Gbl_SyntaxError)
132254745Sjkim    {
133298714Sjkim        fprintf (stderr,
134298714Sjkim            "Compiler aborting due to parser-detected syntax error(s)\n");
135254745Sjkim        LsDumpParseTree ();
136254745Sjkim        goto ErrorExit;
137254745Sjkim    }
138118611Snjl
139118611Snjl    /* Did the parse tree get successfully constructed? */
140118611Snjl
141298714Sjkim    if (!Gbl_ParseTreeRoot)
142118611Snjl    {
143234623Sjkim        /*
144234623Sjkim         * If there are no errors, then we have some sort of
145234623Sjkim         * internal problem.
146234623Sjkim         */
147254745Sjkim        AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
148254745Sjkim            NULL, "- Could not resolve parse tree root node");
149234623Sjkim
150233250Sjkim        goto ErrorExit;
151118611Snjl    }
152118611Snjl
153254745Sjkim    /* Flush out any remaining source after parse tree is complete */
154254745Sjkim
155254745Sjkim    Event = UtBeginEvent ("Flush source input");
156254745Sjkim    CmFlushSourceCode ();
157254745Sjkim
158278970Sjkim    /* Prune the parse tree if requested (debug purposes only) */
159278970Sjkim
160278970Sjkim    if (Gbl_PruneParseTree)
161278970Sjkim    {
162278970Sjkim        AslPruneParseTree (Gbl_PruneDepth, Gbl_PruneType);
163278970Sjkim    }
164278970Sjkim
165167802Sjkim    /* Optional parse tree dump, compiler debug output only */
166167802Sjkim
167167802Sjkim    LsDumpParseTree ();
168167802Sjkim
169298714Sjkim    OpcGetIntegerWidth (Gbl_ParseTreeRoot->Asl.Child);
170151937Sjkim    UtEndEvent (Event);
171118611Snjl
172118611Snjl    /* Pre-process parse tree for any operator transforms */
173118611Snjl
174151937Sjkim    Event = UtBeginEvent ("Parse tree transforms");
175118611Snjl    DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n");
176298714Sjkim    TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE,
177298714Sjkim        TrAmlTransformWalkBegin, TrAmlTransformWalkEnd, NULL);
178151937Sjkim    UtEndEvent (Event);
179118611Snjl
180118611Snjl    /* Generate AML opcodes corresponding to the parse tokens */
181118611Snjl
182151937Sjkim    Event = UtBeginEvent ("Generate AML opcodes");
183298714Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "Generating AML opcodes\n\n");
184298714Sjkim    TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL,
185151937Sjkim        OpcAmlOpcodeWalk, NULL);
186151937Sjkim    UtEndEvent (Event);
187118611Snjl
188118611Snjl    /*
189118611Snjl     * Now that the input is parsed, we can open the AML output file.
190298714Sjkim     * Note: by default, the name of this file comes from the table
191298714Sjkim     * descriptor within the input file.
192118611Snjl     */
193151937Sjkim    Event = UtBeginEvent ("Open AML output file");
194118611Snjl    Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
195233250Sjkim    UtEndEvent (Event);
196118611Snjl    if (ACPI_FAILURE (Status))
197118611Snjl    {
198118611Snjl        AePrintErrorLog (ASL_FILE_STDERR);
199241973Sjkim        return (-1);
200118611Snjl    }
201118611Snjl
202118611Snjl    /* Interpret and generate all compile-time constants */
203118611Snjl
204151937Sjkim    Event = UtBeginEvent ("Constant folding via AML interpreter");
205151937Sjkim    DbgPrint (ASL_DEBUG_OUTPUT,
206298714Sjkim        "Interpreting compile-time constant expressions\n\n");
207281396Sjkim
208281396Sjkim    if (Gbl_FoldConstants)
209281396Sjkim    {
210298714Sjkim        TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD,
211298714Sjkim            NULL, OpcAmlConstantWalk, NULL);
212281396Sjkim    }
213281396Sjkim    else
214281396Sjkim    {
215281396Sjkim        DbgPrint (ASL_PARSE_OUTPUT, "    Optional folding disabled\n");
216281396Sjkim    }
217151937Sjkim    UtEndEvent (Event);
218118611Snjl
219151937Sjkim    /* Update AML opcodes if necessary, after constant folding */
220151937Sjkim
221151937Sjkim    Event = UtBeginEvent ("Updating AML opcodes after constant folding");
222151937Sjkim    DbgPrint (ASL_DEBUG_OUTPUT,
223298714Sjkim        "Updating AML opcodes after constant folding\n\n");
224298714Sjkim    TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD,
225151937Sjkim        NULL, OpcAmlOpcodeUpdateWalk, NULL);
226151937Sjkim    UtEndEvent (Event);
227151937Sjkim
228118611Snjl    /* Calculate all AML package lengths */
229118611Snjl
230151937Sjkim    Event = UtBeginEvent ("Generate AML package lengths");
231298714Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "Generating Package lengths\n\n");
232298714Sjkim    TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL,
233151937Sjkim        LnPackageLengthWalk, NULL);
234151937Sjkim    UtEndEvent (Event);
235118611Snjl
236118611Snjl    if (Gbl_ParseOnlyFlag)
237118611Snjl    {
238234623Sjkim        AePrintErrorLog (ASL_FILE_STDERR);
239234623Sjkim        UtDisplaySummary (ASL_FILE_STDERR);
240118611Snjl        if (Gbl_DebugFlag)
241118611Snjl        {
242234623Sjkim            /* Print error summary to the stdout also */
243118611Snjl
244234623Sjkim            AePrintErrorLog (ASL_FILE_STDOUT);
245234623Sjkim            UtDisplaySummary (ASL_FILE_STDOUT);
246118611Snjl        }
247233250Sjkim        UtEndEvent (FullCompile);
248241973Sjkim        return (0);
249118611Snjl    }
250118611Snjl
251118611Snjl    /*
252118611Snjl     * Create an internal namespace and use it as a symbol table
253118611Snjl     */
254118611Snjl
255118611Snjl    /* Namespace loading */
256118611Snjl
257151937Sjkim    Event = UtBeginEvent ("Create ACPI Namespace");
258298714Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "Creating ACPI Namespace\n\n");
259298714Sjkim    Status = LdLoadNamespace (Gbl_ParseTreeRoot);
260151937Sjkim    UtEndEvent (Event);
261118611Snjl    if (ACPI_FAILURE (Status))
262118611Snjl    {
263233250Sjkim        goto ErrorExit;
264118611Snjl    }
265118611Snjl
266167802Sjkim    /* Namespace cross-reference */
267118611Snjl
268298714Sjkim    AslGbl_NamespaceEvent = UtBeginEvent (
269298714Sjkim        "Cross reference parse tree and Namespace");
270298714Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "Cross referencing namespace\n\n");
271245582Sjkim    Status = XfCrossReferenceNamespace ();
272118611Snjl    if (ACPI_FAILURE (Status))
273118611Snjl    {
274233250Sjkim        goto ErrorExit;
275118611Snjl    }
276118611Snjl
277167802Sjkim    /* Namespace - Check for non-referenced objects */
278167802Sjkim
279167802Sjkim    LkFindUnreferencedObjects ();
280167802Sjkim    UtEndEvent (AslGbl_NamespaceEvent);
281167802Sjkim
282298714Sjkim    /* Resolve External Declarations */
283298714Sjkim
284298714Sjkim    if (Gbl_DoExternals)
285298714Sjkim    {
286298714Sjkim        Event = UtBeginEvent ("Resolve all Externals");
287298714Sjkim        DbgPrint (ASL_DEBUG_OUTPUT, "\nResolve Externals\n\n");
288298714Sjkim        TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE,
289298714Sjkim            ExAmlExternalWalkBegin, ExAmlExternalWalkEnd, NULL);
290298714Sjkim        UtEndEvent (Event);
291298714Sjkim    }
292298714Sjkim
293118611Snjl    /*
294241973Sjkim     * Semantic analysis. This can happen only after the
295118611Snjl     * namespace has been loaded and cross-referenced.
296118611Snjl     *
297118611Snjl     * part one - check control methods
298118611Snjl     */
299151937Sjkim    Event = UtBeginEvent ("Analyze control method return types");
300118611Snjl    AnalysisWalkInfo.MethodStack = NULL;
301118611Snjl
302298714Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - Method analysis\n\n");
303298714Sjkim
304298714Sjkim    if (Gbl_CrossReferenceOutput)
305298714Sjkim    {
306298714Sjkim        OtPrintHeaders ("Part 1: Object Reference Map "
307298714Sjkim            "(Object references from within each control method)");
308298714Sjkim    }
309298714Sjkim
310298714Sjkim    TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE,
311245582Sjkim        MtMethodAnalysisWalkBegin,
312245582Sjkim        MtMethodAnalysisWalkEnd, &AnalysisWalkInfo);
313151937Sjkim    UtEndEvent (Event);
314118611Snjl
315298714Sjkim    /* Generate the object cross-reference file if requested */
316298714Sjkim
317298714Sjkim    Event = UtBeginEvent ("Generate cross-reference file");
318298714Sjkim    OtCreateXrefFile ();
319298714Sjkim    UtEndEvent (Event);
320298714Sjkim
321118611Snjl    /* Semantic error checking part two - typing of method returns */
322118611Snjl
323151937Sjkim    Event = UtBeginEvent ("Determine object types returned by methods");
324298714Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - Method typing\n\n");
325298714Sjkim    TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD,
326218590Sjkim        NULL, AnMethodTypingWalkEnd, NULL);
327151937Sjkim    UtEndEvent (Event);
328118611Snjl
329118611Snjl    /* Semantic error checking part three - operand type checking */
330118611Snjl
331151937Sjkim    Event = UtBeginEvent ("Analyze AML operand types");
332298714Sjkim    DbgPrint (ASL_DEBUG_OUTPUT,
333298714Sjkim        "Semantic analysis - Operand type checking\n\n");
334298714Sjkim    if (Gbl_DoTypechecking)
335298714Sjkim    {
336298714Sjkim        TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD,
337298714Sjkim            NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo);
338298714Sjkim    }
339151937Sjkim    UtEndEvent (Event);
340118611Snjl
341118611Snjl    /* Semantic error checking part four - other miscellaneous checks */
342118611Snjl
343151937Sjkim    Event = UtBeginEvent ("Miscellaneous analysis");
344298714Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - miscellaneous\n\n");
345298714Sjkim    TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
346151937Sjkim        AnOtherSemanticAnalysisWalkBegin,
347218590Sjkim        NULL, &AnalysisWalkInfo);
348151937Sjkim    UtEndEvent (Event);
349118611Snjl
350118611Snjl    /* Calculate all AML package lengths */
351118611Snjl
352151937Sjkim    Event = UtBeginEvent ("Finish AML package length generation");
353298714Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "Generating Package lengths\n\n");
354298714Sjkim    TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL,
355151937Sjkim        LnInitLengthsWalk, NULL);
356298714Sjkim    TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL,
357151937Sjkim        LnPackageLengthWalk, NULL);
358151937Sjkim    UtEndEvent (Event);
359118611Snjl
360118611Snjl    /* Code generation - emit the AML */
361118611Snjl
362151937Sjkim    Event = UtBeginEvent ("Generate AML code and write output files");
363298714Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "Writing AML byte code\n\n");
364118611Snjl    CgGenerateAmlOutput ();
365151937Sjkim    UtEndEvent (Event);
366118611Snjl
367151937Sjkim    Event = UtBeginEvent ("Write optional output files");
368118611Snjl    CmDoOutputFiles ();
369151937Sjkim    UtEndEvent (Event);
370118611Snjl
371151937Sjkim    UtEndEvent (FullCompile);
372118611Snjl    CmCleanupAndExit ();
373241973Sjkim    return (0);
374233250Sjkim
375233250SjkimErrorExit:
376233250Sjkim    UtEndEvent (FullCompile);
377233250Sjkim    CmCleanupAndExit ();
378233250Sjkim    return (-1);
379118611Snjl}
380118611Snjl
381151937Sjkim
382151937Sjkim/*******************************************************************************
383151937Sjkim *
384272444Sjkim * FUNCTION:    AslCompilerSignon
385272444Sjkim *
386272444Sjkim * PARAMETERS:  FileId      - ID of the output file
387272444Sjkim *
388272444Sjkim * RETURN:      None
389272444Sjkim *
390272444Sjkim * DESCRIPTION: Display compiler signon
391272444Sjkim *
392272444Sjkim ******************************************************************************/
393272444Sjkim
394272444Sjkimvoid
395272444SjkimAslCompilerSignon (
396272444Sjkim    UINT32                  FileId)
397272444Sjkim{
398272444Sjkim    char                    *Prefix = "";
399272444Sjkim    char                    *UtilityName;
400272444Sjkim
401272444Sjkim
402272444Sjkim    /* Set line prefix depending on the destination file type */
403272444Sjkim
404272444Sjkim    switch (FileId)
405272444Sjkim    {
406272444Sjkim    case ASL_FILE_ASM_SOURCE_OUTPUT:
407272444Sjkim    case ASL_FILE_ASM_INCLUDE_OUTPUT:
408272444Sjkim
409272444Sjkim        Prefix = "; ";
410272444Sjkim        break;
411272444Sjkim
412272444Sjkim    case ASL_FILE_HEX_OUTPUT:
413272444Sjkim
414272444Sjkim        if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
415272444Sjkim        {
416272444Sjkim            Prefix = "; ";
417272444Sjkim        }
418272444Sjkim        else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
419272444Sjkim                 (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
420272444Sjkim        {
421272444Sjkim            FlPrintFile (ASL_FILE_HEX_OUTPUT, "/*\n");
422272444Sjkim            Prefix = " * ";
423272444Sjkim        }
424272444Sjkim        break;
425272444Sjkim
426272444Sjkim    case ASL_FILE_C_SOURCE_OUTPUT:
427272444Sjkim    case ASL_FILE_C_OFFSET_OUTPUT:
428272444Sjkim    case ASL_FILE_C_INCLUDE_OUTPUT:
429272444Sjkim
430272444Sjkim        Prefix = " * ";
431272444Sjkim        break;
432272444Sjkim
433272444Sjkim    default:
434272444Sjkim
435272444Sjkim        /* No other output types supported */
436272444Sjkim
437272444Sjkim        break;
438272444Sjkim    }
439272444Sjkim
440272444Sjkim    /* Running compiler or disassembler? */
441272444Sjkim
442272444Sjkim    if (Gbl_DisasmFlag)
443272444Sjkim    {
444272444Sjkim        UtilityName = AML_DISASSEMBLER_NAME;
445272444Sjkim    }
446272444Sjkim    else
447272444Sjkim    {
448272444Sjkim        UtilityName = ASL_COMPILER_NAME;
449272444Sjkim    }
450272444Sjkim
451272444Sjkim    /* Compiler signon with copyright */
452272444Sjkim
453272444Sjkim    FlPrintFile (FileId, "%s\n", Prefix);
454272444Sjkim    FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix));
455272444Sjkim}
456272444Sjkim
457272444Sjkim
458272444Sjkim/*******************************************************************************
459272444Sjkim *
460272444Sjkim * FUNCTION:    AslCompilerFileHeader
461272444Sjkim *
462272444Sjkim * PARAMETERS:  FileId      - ID of the output file
463272444Sjkim *
464272444Sjkim * RETURN:      None
465272444Sjkim *
466272444Sjkim * DESCRIPTION: Header used at the beginning of output files
467272444Sjkim *
468272444Sjkim ******************************************************************************/
469272444Sjkim
470272444Sjkimvoid
471272444SjkimAslCompilerFileHeader (
472272444Sjkim    UINT32                  FileId)
473272444Sjkim{
474272444Sjkim    struct tm               *NewTime;
475272444Sjkim    time_t                  Aclock;
476272444Sjkim    char                    *Prefix = "";
477272444Sjkim
478272444Sjkim
479272444Sjkim    /* Set line prefix depending on the destination file type */
480272444Sjkim
481272444Sjkim    switch (FileId)
482272444Sjkim    {
483272444Sjkim    case ASL_FILE_ASM_SOURCE_OUTPUT:
484272444Sjkim    case ASL_FILE_ASM_INCLUDE_OUTPUT:
485272444Sjkim
486272444Sjkim        Prefix = "; ";
487272444Sjkim        break;
488272444Sjkim
489272444Sjkim    case ASL_FILE_HEX_OUTPUT:
490272444Sjkim
491272444Sjkim        if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
492272444Sjkim        {
493272444Sjkim            Prefix = "; ";
494272444Sjkim        }
495272444Sjkim        else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
496272444Sjkim                 (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
497272444Sjkim        {
498272444Sjkim            Prefix = " * ";
499272444Sjkim        }
500272444Sjkim        break;
501272444Sjkim
502272444Sjkim    case ASL_FILE_C_SOURCE_OUTPUT:
503272444Sjkim    case ASL_FILE_C_OFFSET_OUTPUT:
504272444Sjkim    case ASL_FILE_C_INCLUDE_OUTPUT:
505272444Sjkim
506272444Sjkim        Prefix = " * ";
507272444Sjkim        break;
508272444Sjkim
509272444Sjkim    default:
510272444Sjkim
511272444Sjkim        /* No other output types supported */
512272444Sjkim
513272444Sjkim        break;
514272444Sjkim    }
515272444Sjkim
516272444Sjkim    /* Compilation header with timestamp */
517272444Sjkim
518272444Sjkim    (void) time (&Aclock);
519272444Sjkim    NewTime = localtime (&Aclock);
520272444Sjkim
521272444Sjkim    FlPrintFile (FileId,
522272444Sjkim        "%sCompilation of \"%s\" - %s%s\n",
523272444Sjkim        Prefix, Gbl_Files[ASL_FILE_INPUT].Filename, asctime (NewTime),
524272444Sjkim        Prefix);
525272444Sjkim
526272444Sjkim    switch (FileId)
527272444Sjkim    {
528272444Sjkim    case ASL_FILE_C_SOURCE_OUTPUT:
529272444Sjkim    case ASL_FILE_C_OFFSET_OUTPUT:
530272444Sjkim    case ASL_FILE_C_INCLUDE_OUTPUT:
531272444Sjkim
532272444Sjkim        FlPrintFile (FileId, " */\n");
533272444Sjkim        break;
534272444Sjkim
535272444Sjkim    default:
536272444Sjkim
537272444Sjkim        /* Nothing to do for other output types */
538272444Sjkim
539272444Sjkim        break;
540272444Sjkim    }
541272444Sjkim}
542272444Sjkim
543272444Sjkim
544272444Sjkim/*******************************************************************************
545272444Sjkim *
546272444Sjkim * FUNCTION:    CmFlushSourceCode
547272444Sjkim *
548272444Sjkim * PARAMETERS:  None
549272444Sjkim *
550272444Sjkim * RETURN:      None
551272444Sjkim *
552272444Sjkim * DESCRIPTION: Read in any remaining source code after the parse tree
553272444Sjkim *              has been constructed.
554272444Sjkim *
555272444Sjkim ******************************************************************************/
556272444Sjkim
557272444Sjkimstatic void
558272444SjkimCmFlushSourceCode (
559272444Sjkim    void)
560272444Sjkim{
561272444Sjkim    char                    Buffer;
562272444Sjkim
563272444Sjkim
564272444Sjkim    while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR)
565272444Sjkim    {
566272444Sjkim        AslInsertLineBuffer ((int) Buffer);
567272444Sjkim    }
568272444Sjkim
569272444Sjkim    AslResetCurrentLineBuffer ();
570272444Sjkim}
571272444Sjkim
572272444Sjkim
573272444Sjkim/*******************************************************************************
574272444Sjkim *
575151937Sjkim * FUNCTION:    CmDoOutputFiles
576151937Sjkim *
577151937Sjkim * PARAMETERS:  None
578151937Sjkim *
579151937Sjkim * RETURN:      None.
580151937Sjkim *
581151937Sjkim * DESCRIPTION: Create all "listing" type files
582151937Sjkim *
583151937Sjkim ******************************************************************************/
584151937Sjkim
585118611Snjlvoid
586151937SjkimCmDoOutputFiles (
587151937Sjkim    void)
588118611Snjl{
589118611Snjl
590118611Snjl    /* Create listings and hex files */
591118611Snjl
592118611Snjl    LsDoListings ();
593245582Sjkim    HxDoHexOutput ();
594118611Snjl
595118611Snjl    /* Dump the namespace to the .nsp file if requested */
596118611Snjl
597245582Sjkim    (void) NsDisplayNamespace ();
598272444Sjkim
599272444Sjkim    /* Dump the device mapping file */
600272444Sjkim
601272444Sjkim    MpEmitMappingInfo ();
602118611Snjl}
603118611Snjl
604118611Snjl
605118611Snjl/*******************************************************************************
606118611Snjl *
607237412Sjkim * FUNCTION:    CmDumpAllEvents
608151937Sjkim *
609237412Sjkim * PARAMETERS:  None
610151937Sjkim *
611151937Sjkim * RETURN:      None.
612151937Sjkim *
613237412Sjkim * DESCRIPTION: Dump all compiler events
614151937Sjkim *
615151937Sjkim ******************************************************************************/
616151937Sjkim
617151937Sjkimstatic void
618237412SjkimCmDumpAllEvents (
619237412Sjkim    void)
620151937Sjkim{
621237412Sjkim    ASL_EVENT_INFO          *Event;
622151937Sjkim    UINT32                  Delta;
623298714Sjkim    UINT32                  MicroSeconds;
624298714Sjkim    UINT32                  MilliSeconds;
625237412Sjkim    UINT32                  i;
626151937Sjkim
627237412Sjkim
628237412Sjkim    Event = AslGbl_Events;
629237412Sjkim
630237412Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n");
631237412Sjkim    if (Gbl_CompileTimesFlag)
632151937Sjkim    {
633237412Sjkim        printf ("\nElapsed time for major events\n\n");
634151937Sjkim    }
635151937Sjkim
636237412Sjkim    for (i = 0; i < AslGbl_NextEvent; i++)
637237412Sjkim    {
638237412Sjkim        if (Event->Valid)
639237412Sjkim        {
640237412Sjkim            /* Delta will be in 100-nanosecond units */
641151937Sjkim
642237412Sjkim            Delta = (UINT32) (Event->EndTime - Event->StartTime);
643151937Sjkim
644298714Sjkim            MicroSeconds = Delta / ACPI_100NSEC_PER_USEC;
645298714Sjkim            MilliSeconds = Delta / ACPI_100NSEC_PER_MSEC;
646151937Sjkim
647237412Sjkim            /* Round milliseconds up */
648151937Sjkim
649298714Sjkim            if ((MicroSeconds - (MilliSeconds * ACPI_USEC_PER_MSEC)) >= 500)
650237412Sjkim            {
651298714Sjkim                MilliSeconds++;
652237412Sjkim            }
653237412Sjkim
654237412Sjkim            DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n",
655298714Sjkim                MicroSeconds, MilliSeconds, Event->EventName);
656237412Sjkim
657237412Sjkim            if (Gbl_CompileTimesFlag)
658237412Sjkim            {
659237412Sjkim                printf ("%8u usec %8u msec - %s\n",
660298714Sjkim                    MicroSeconds, MilliSeconds, Event->EventName);
661237412Sjkim            }
662237412Sjkim        }
663237412Sjkim
664237412Sjkim        Event++;
665151937Sjkim    }
666151937Sjkim}
667151937Sjkim
668151937Sjkim
669151937Sjkim/*******************************************************************************
670151937Sjkim *
671118611Snjl * FUNCTION:    CmCleanupAndExit
672118611Snjl *
673118611Snjl * PARAMETERS:  None
674118611Snjl *
675118611Snjl * RETURN:      None.
676118611Snjl *
677118611Snjl * DESCRIPTION: Close all open files and exit the compiler
678118611Snjl *
679118611Snjl ******************************************************************************/
680118611Snjl
681118611Snjlvoid
682151937SjkimCmCleanupAndExit (
683151937Sjkim    void)
684118611Snjl{
685118611Snjl    UINT32                  i;
686240716Sjkim    BOOLEAN                 DeleteAmlFile = FALSE;
687118611Snjl
688118611Snjl
689234623Sjkim    AePrintErrorLog (ASL_FILE_STDERR);
690118611Snjl    if (Gbl_DebugFlag)
691118611Snjl    {
692234623Sjkim        /* Print error summary to stdout also */
693118611Snjl
694234623Sjkim        AePrintErrorLog (ASL_FILE_STDOUT);
695118611Snjl    }
696118611Snjl
697237412Sjkim    /* Emit compile times if enabled */
698118611Snjl
699237412Sjkim    CmDumpAllEvents ();
700237412Sjkim
701118611Snjl    if (Gbl_CompileTimesFlag)
702118611Snjl    {
703118611Snjl        printf ("\nMiscellaneous compile statistics\n\n");
704118611Snjl        printf ("%11u : %s\n", TotalParseNodes, "Parse nodes");
705118611Snjl        printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches");
706118611Snjl        printf ("%11u : %s\n", TotalNamedObjects, "Named objects");
707118611Snjl        printf ("%11u : %s\n", TotalMethods, "Control methods");
708118611Snjl        printf ("%11u : %s\n", TotalAllocations, "Memory Allocations");
709118611Snjl        printf ("%11u : %s\n", TotalAllocated, "Total allocated memory");
710118611Snjl        printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded");
711118611Snjl        printf ("\n");
712118611Snjl    }
713118611Snjl
714118611Snjl    if (Gbl_NsLookupCount)
715118611Snjl    {
716209746Sjkim        DbgPrint (ASL_DEBUG_OUTPUT,
717209746Sjkim            "\n\nMiscellaneous compile statistics\n\n");
718209746Sjkim
719209746Sjkim        DbgPrint (ASL_DEBUG_OUTPUT,
720209746Sjkim            "%32s : %u\n", "Total Namespace searches",
721151937Sjkim            Gbl_NsLookupCount);
722209746Sjkim
723209746Sjkim        DbgPrint (ASL_DEBUG_OUTPUT,
724209746Sjkim            "%32s : %u usec\n", "Time per search", ((UINT32)
725209746Sjkim            (AslGbl_Events[AslGbl_NamespaceEvent].EndTime -
726209746Sjkim                AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) /
727209746Sjkim                Gbl_NsLookupCount);
728118611Snjl    }
729118611Snjl
730118611Snjl    if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
731118611Snjl    {
732209746Sjkim        printf ("\nMaximum error count (%u) exceeded\n",
733209746Sjkim            ASL_MAX_ERROR_COUNT);
734118611Snjl    }
735118611Snjl
736118611Snjl    UtDisplaySummary (ASL_FILE_STDOUT);
737199337Sjkim
738240716Sjkim    /*
739240716Sjkim     * We will delete the AML file if there are errors and the
740240716Sjkim     * force AML output option has not been used.
741240716Sjkim     */
742272444Sjkim    if ((Gbl_ExceptionCount[ASL_ERROR] > 0) &&
743272444Sjkim        (!Gbl_IgnoreErrors) &&
744240716Sjkim        Gbl_Files[ASL_FILE_AML_OUTPUT].Handle)
745240716Sjkim    {
746240716Sjkim        DeleteAmlFile = TRUE;
747240716Sjkim    }
748240716Sjkim
749199337Sjkim    /* Close all open files */
750199337Sjkim
751252279Sjkim    /*
752284583Sjkim     * Take care with the preprocessor file (.pre), it might be the same
753252279Sjkim     * as the "input" file, depending on where the compiler has terminated
754252279Sjkim     * or aborted. Prevent attempt to close the same file twice in
755252279Sjkim     * loop below.
756252279Sjkim     */
757252279Sjkim    if (Gbl_Files[ASL_FILE_PREPROCESSOR].Handle ==
758252279Sjkim        Gbl_Files[ASL_FILE_INPUT].Handle)
759252279Sjkim    {
760252279Sjkim        Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL;
761252279Sjkim    }
762233250Sjkim
763252279Sjkim    /* Close the standard I/O files */
764252279Sjkim
765233250Sjkim    for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++)
766199337Sjkim    {
767199337Sjkim        FlCloseFile (i);
768199337Sjkim    }
769200553Sjkim
770200553Sjkim    /* Delete AML file if there are errors */
771200553Sjkim
772240716Sjkim    if (DeleteAmlFile)
773200553Sjkim    {
774240716Sjkim        FlDeleteFile (ASL_FILE_AML_OUTPUT);
775200553Sjkim    }
776200553Sjkim
777284583Sjkim    /* Delete the preprocessor temp file unless full debug was specified */
778233250Sjkim
779284583Sjkim    if (Gbl_PreprocessFlag && !Gbl_KeepPreprocessorTempFile)
780233250Sjkim    {
781240716Sjkim        FlDeleteFile (ASL_FILE_PREPROCESSOR);
782233250Sjkim    }
783233250Sjkim
784200553Sjkim    /*
785200553Sjkim     * Delete intermediate ("combined") source file (if -ls flag not set)
786209746Sjkim     * This file is created during normal ASL/AML compiles. It is not
787209746Sjkim     * created by the data table compiler.
788200553Sjkim     *
789209746Sjkim     * If the -ls flag is set, then the .SRC file should not be deleted.
790209746Sjkim     * In this case, Gbl_SourceOutputFlag is set to TRUE.
791209746Sjkim     *
792209746Sjkim     * Note: Handles are cleared by FlCloseFile above, so we look at the
793209746Sjkim     * filename instead, to determine if the .SRC file was actually
794209746Sjkim     * created.
795200553Sjkim     */
796240716Sjkim    if (!Gbl_SourceOutputFlag)
797200553Sjkim    {
798240716Sjkim        FlDeleteFile (ASL_FILE_SOURCE_OUTPUT);
799200553Sjkim    }
800272444Sjkim
801272444Sjkim    /* Final cleanup after compiling one file */
802272444Sjkim
803272444Sjkim    CmDeleteCaches ();
804118611Snjl}
805272444Sjkim
806272444Sjkim
807272444Sjkim/*******************************************************************************
808272444Sjkim *
809272444Sjkim * FUNCTION:    CmDeleteCaches
810272444Sjkim *
811272444Sjkim * PARAMETERS:  None
812272444Sjkim *
813272444Sjkim * RETURN:      None
814272444Sjkim *
815272444Sjkim * DESCRIPTION: Delete all local cache buffer blocks
816272444Sjkim *
817272444Sjkim ******************************************************************************/
818272444Sjkim
819272444Sjkimvoid
820272444SjkimCmDeleteCaches (
821272444Sjkim    void)
822272444Sjkim{
823272444Sjkim    UINT32                  BufferCount;
824272444Sjkim    ASL_CACHE_INFO          *Next;
825272444Sjkim
826272444Sjkim
827272444Sjkim    /* Parse Op cache */
828272444Sjkim
829272444Sjkim    BufferCount = 0;
830272444Sjkim    while (Gbl_ParseOpCacheList)
831272444Sjkim    {
832272444Sjkim        Next = Gbl_ParseOpCacheList->Next;
833272444Sjkim        ACPI_FREE (Gbl_ParseOpCacheList);
834272444Sjkim        Gbl_ParseOpCacheList = Next;
835272444Sjkim        BufferCount++;
836272444Sjkim    }
837272444Sjkim
838272444Sjkim    DbgPrint (ASL_DEBUG_OUTPUT,
839272444Sjkim        "%u ParseOps, Buffer size: %u ops (%u bytes), %u Buffers\n",
840272444Sjkim        Gbl_ParseOpCount, ASL_PARSEOP_CACHE_SIZE,
841272444Sjkim        (sizeof (ACPI_PARSE_OBJECT) * ASL_PARSEOP_CACHE_SIZE), BufferCount);
842272444Sjkim
843272444Sjkim    Gbl_ParseOpCount = 0;
844272444Sjkim    Gbl_ParseOpCacheNext = NULL;
845272444Sjkim    Gbl_ParseOpCacheLast = NULL;
846298714Sjkim    Gbl_ParseTreeRoot = NULL;
847272444Sjkim
848272444Sjkim    /* Generic string cache */
849272444Sjkim
850272444Sjkim    BufferCount = 0;
851272444Sjkim    while (Gbl_StringCacheList)
852272444Sjkim    {
853272444Sjkim        Next = Gbl_StringCacheList->Next;
854272444Sjkim        ACPI_FREE (Gbl_StringCacheList);
855272444Sjkim        Gbl_StringCacheList = Next;
856272444Sjkim        BufferCount++;
857272444Sjkim    }
858272444Sjkim
859272444Sjkim    DbgPrint (ASL_DEBUG_OUTPUT,
860272444Sjkim        "%u Strings (%u bytes), Buffer size: %u bytes, %u Buffers\n",
861272444Sjkim        Gbl_StringCount, Gbl_StringSize, ASL_STRING_CACHE_SIZE, BufferCount);
862272444Sjkim
863272444Sjkim    Gbl_StringSize = 0;
864272444Sjkim    Gbl_StringCount = 0;
865272444Sjkim    Gbl_StringCacheNext = NULL;
866272444Sjkim    Gbl_StringCacheLast = NULL;
867272444Sjkim}
868