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