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