aslcompile.c revision 217365
1118611Snjl
2118611Snjl/******************************************************************************
3118611Snjl *
4118611Snjl * Module Name: aslcompile - top level compile module
5118611Snjl *
6118611Snjl *****************************************************************************/
7118611Snjl
8217365Sjkim/*
9217365Sjkim * Copyright (C) 2000 - 2011, 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 (
62193529Sjkim    ASL_FILE_INFO           *FileInfo,
63193529Sjkim    ASL_FILE_STATUS         *Status);
64151937Sjkim
65212761Sjkimstatic void
66193529SjkimFlConsumeNewComment (
67193529Sjkim    ASL_FILE_INFO           *FileInfo,
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    {
245118611Snjl        InsertLineBuffer ((int) Buffer);
246118611Snjl    }
247118611Snjl
248118611Snjl    ResetCurrentLineBuffer ();
249118611Snjl}
250118611Snjl
251118611Snjl
252118611Snjl/*******************************************************************************
253118611Snjl *
254167802Sjkim * FUNCTION:    FlConsume*
255167802Sjkim *
256167802Sjkim * PARAMETERS:  FileInfo        - Points to an open input file
257167802Sjkim *
258167802Sjkim * RETURN:      Number of lines consumed
259167802Sjkim *
260167802Sjkim * DESCRIPTION: Step over both types of comment during check for ascii chars
261167802Sjkim *
262167802Sjkim ******************************************************************************/
263167802Sjkim
264212761Sjkimstatic void
265167802SjkimFlConsumeAnsiComment (
266167802Sjkim    ASL_FILE_INFO           *FileInfo,
267167802Sjkim    ASL_FILE_STATUS         *Status)
268167802Sjkim{
269167802Sjkim    UINT8                   Byte;
270167802Sjkim    BOOLEAN                 ClosingComment = FALSE;
271167802Sjkim
272167802Sjkim
273167802Sjkim    while (fread (&Byte, 1, 1, FileInfo->Handle))
274167802Sjkim    {
275167802Sjkim        /* Scan until comment close is found */
276167802Sjkim
277167802Sjkim        if (ClosingComment)
278167802Sjkim        {
279167802Sjkim            if (Byte == '/')
280167802Sjkim            {
281167802Sjkim                return;
282167802Sjkim            }
283167802Sjkim
284167802Sjkim            if (Byte != '*')
285167802Sjkim            {
286167802Sjkim                /* Reset */
287167802Sjkim
288167802Sjkim                ClosingComment = FALSE;
289167802Sjkim            }
290167802Sjkim        }
291167802Sjkim        else if (Byte == '*')
292167802Sjkim        {
293167802Sjkim            ClosingComment = TRUE;
294167802Sjkim        }
295167802Sjkim
296167802Sjkim        /* Maintain line count */
297167802Sjkim
298167802Sjkim        if (Byte == 0x0A)
299167802Sjkim        {
300167802Sjkim            Status->Line++;
301167802Sjkim        }
302167802Sjkim
303167802Sjkim        Status->Offset++;
304167802Sjkim    }
305167802Sjkim}
306167802Sjkim
307167802Sjkim
308212761Sjkimstatic void
309167802SjkimFlConsumeNewComment (
310167802Sjkim    ASL_FILE_INFO           *FileInfo,
311167802Sjkim    ASL_FILE_STATUS         *Status)
312167802Sjkim{
313167802Sjkim    UINT8                   Byte;
314167802Sjkim
315167802Sjkim
316167802Sjkim    while (fread (&Byte, 1, 1, FileInfo->Handle))
317167802Sjkim    {
318167802Sjkim        Status->Offset++;
319167802Sjkim
320167802Sjkim        /* Comment ends at newline */
321167802Sjkim
322167802Sjkim        if (Byte == 0x0A)
323167802Sjkim        {
324167802Sjkim            Status->Line++;
325167802Sjkim            return;
326167802Sjkim        }
327167802Sjkim    }
328167802Sjkim}
329167802Sjkim
330167802Sjkim
331167802Sjkim/*******************************************************************************
332167802Sjkim *
333123315Snjl * FUNCTION:    FlCheckForAscii
334123315Snjl *
335123315Snjl * PARAMETERS:  FileInfo        - Points to an open input file
336123315Snjl *
337151937Sjkim * RETURN:      Status
338123315Snjl *
339167802Sjkim * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters
340167802Sjkim *              within comments. Note: does not handle nested comments and does
341167802Sjkim *              not handle comment delimiters within string literals. However,
342167802Sjkim *              on the rare chance this happens and an invalid character is
343167802Sjkim *              missed, the parser will catch the error by failing in some
344167802Sjkim *              spectactular manner.
345123315Snjl *
346123315Snjl ******************************************************************************/
347123315Snjl
348209746SjkimACPI_STATUS
349123315SnjlFlCheckForAscii (
350123315Snjl    ASL_FILE_INFO           *FileInfo)
351123315Snjl{
352123315Snjl    UINT8                   Byte;
353123315Snjl    ACPI_SIZE               BadBytes = 0;
354167802Sjkim    BOOLEAN                 OpeningComment = FALSE;
355167802Sjkim    ASL_FILE_STATUS         Status;
356123315Snjl
357123315Snjl
358167802Sjkim    Status.Line = 1;
359167802Sjkim    Status.Offset = 0;
360167802Sjkim
361123315Snjl    /* Read the entire file */
362123315Snjl
363123315Snjl    while (fread (&Byte, 1, 1, FileInfo->Handle))
364123315Snjl    {
365167802Sjkim        /* Ignore comment fields (allow non-ascii within) */
366167802Sjkim
367167802Sjkim        if (OpeningComment)
368167802Sjkim        {
369167802Sjkim            /* Check for second comment open delimiter */
370167802Sjkim
371167802Sjkim            if (Byte == '*')
372167802Sjkim            {
373167802Sjkim                FlConsumeAnsiComment (FileInfo, &Status);
374167802Sjkim            }
375167802Sjkim
376167802Sjkim            if (Byte == '/')
377167802Sjkim            {
378167802Sjkim                FlConsumeNewComment (FileInfo, &Status);
379167802Sjkim            }
380167802Sjkim
381167802Sjkim            /* Reset */
382167802Sjkim
383167802Sjkim            OpeningComment = FALSE;
384167802Sjkim        }
385167802Sjkim        else if (Byte == '/')
386167802Sjkim        {
387167802Sjkim            OpeningComment = TRUE;
388167802Sjkim        }
389167802Sjkim
390123315Snjl        /* Check for an ASCII character */
391123315Snjl
392193529Sjkim        if (!ACPI_IS_ASCII (Byte))
393123315Snjl        {
394123315Snjl            if (BadBytes < 10)
395123315Snjl            {
396151937Sjkim                AcpiOsPrintf (
397167802Sjkim                    "Non-ASCII character [0x%2.2X] found in line %u, file offset 0x%.2X\n",
398167802Sjkim                    Byte, Status.Line, Status.Offset);
399123315Snjl            }
400167802Sjkim
401123315Snjl            BadBytes++;
402123315Snjl        }
403167802Sjkim
404167802Sjkim        /* Update line counter */
405167802Sjkim
406167802Sjkim        else if (Byte == 0x0A)
407167802Sjkim        {
408167802Sjkim            Status.Line++;
409167802Sjkim        }
410167802Sjkim
411167802Sjkim        Status.Offset++;
412123315Snjl    }
413123315Snjl
414151937Sjkim    /* Seek back to the beginning of the source file */
415151937Sjkim
416151937Sjkim    fseek (FileInfo->Handle, 0, SEEK_SET);
417151937Sjkim
418123315Snjl    /* Were there any non-ASCII characters in the file? */
419123315Snjl
420123315Snjl    if (BadBytes)
421123315Snjl    {
422151937Sjkim        AcpiOsPrintf (
423167802Sjkim            "%u non-ASCII characters found in input source text, could be a binary file\n",
424151937Sjkim            BadBytes);
425167802Sjkim        AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, FileInfo->Filename);
426123315Snjl        return (AE_BAD_CHARACTER);
427123315Snjl    }
428123315Snjl
429151937Sjkim    /* File is OK */
430123315Snjl
431123315Snjl    return (AE_OK);
432123315Snjl}
433123315Snjl
434123315Snjl
435123315Snjl/*******************************************************************************
436123315Snjl *
437118611Snjl * FUNCTION:    CmDoCompile
438118611Snjl *
439118611Snjl * PARAMETERS:  None
440118611Snjl *
441118611Snjl * RETURN:      Status (0 = OK)
442118611Snjl *
443118611Snjl * DESCRIPTION: This procedure performs the entire compile
444118611Snjl *
445118611Snjl ******************************************************************************/
446118611Snjl
447118611Snjlint
448151937SjkimCmDoCompile (
449151937Sjkim    void)
450118611Snjl{
451118611Snjl    ACPI_STATUS             Status;
452151937Sjkim    UINT8                   FullCompile;
453151937Sjkim    UINT8                   Event;
454118611Snjl
455118611Snjl
456151937Sjkim    FullCompile = UtBeginEvent ("*** Total Compile time ***");
457151937Sjkim    Event = UtBeginEvent ("Open input and output files");
458151937Sjkim    UtEndEvent (Event);
459118611Snjl
460118611Snjl    /* Build the parse tree */
461118611Snjl
462151937Sjkim    Event = UtBeginEvent ("Parse source code and build parse tree");
463118611Snjl    AslCompilerparse();
464151937Sjkim    UtEndEvent (Event);
465118611Snjl
466118611Snjl    /* Flush out any remaining source after parse tree is complete */
467118611Snjl
468151937Sjkim    Event = UtBeginEvent ("Flush source input");
469118611Snjl    CmFlushSourceCode ();
470118611Snjl
471118611Snjl    /* Did the parse tree get successfully constructed? */
472118611Snjl
473118611Snjl    if (!RootNode)
474118611Snjl    {
475118611Snjl        CmCleanupAndExit ();
476118611Snjl        return -1;
477118611Snjl    }
478118611Snjl
479167802Sjkim    /* Optional parse tree dump, compiler debug output only */
480167802Sjkim
481167802Sjkim    LsDumpParseTree ();
482167802Sjkim
483118611Snjl    OpcGetIntegerWidth (RootNode);
484151937Sjkim    UtEndEvent (Event);
485118611Snjl
486118611Snjl    /* Pre-process parse tree for any operator transforms */
487118611Snjl
488151937Sjkim    Event = UtBeginEvent ("Parse tree transforms");
489118611Snjl    DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n");
490151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
491151937Sjkim        TrAmlTransformWalk, NULL, NULL);
492151937Sjkim    UtEndEvent (Event);
493118611Snjl
494118611Snjl    /* Generate AML opcodes corresponding to the parse tokens */
495118611Snjl
496151937Sjkim    Event = UtBeginEvent ("Generate AML opcodes");
497118611Snjl    DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating AML opcodes\n\n");
498151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
499151937Sjkim        OpcAmlOpcodeWalk, NULL);
500151937Sjkim    UtEndEvent (Event);
501118611Snjl
502118611Snjl    /*
503118611Snjl     * Now that the input is parsed, we can open the AML output file.
504118611Snjl     * Note: by default, the name of this file comes from the table descriptor
505118611Snjl     * within the input file.
506118611Snjl     */
507151937Sjkim    Event = UtBeginEvent ("Open AML output file");
508118611Snjl    Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
509118611Snjl    if (ACPI_FAILURE (Status))
510118611Snjl    {
511118611Snjl        AePrintErrorLog (ASL_FILE_STDERR);
512118611Snjl        return -1;
513118611Snjl    }
514151937Sjkim    UtEndEvent (Event);
515118611Snjl
516118611Snjl    /* Interpret and generate all compile-time constants */
517118611Snjl
518151937Sjkim    Event = UtBeginEvent ("Constant folding via AML interpreter");
519151937Sjkim    DbgPrint (ASL_DEBUG_OUTPUT,
520151937Sjkim        "\nInterpreting compile-time constant expressions\n\n");
521151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
522151937Sjkim        OpcAmlConstantWalk, NULL, NULL);
523151937Sjkim    UtEndEvent (Event);
524118611Snjl
525151937Sjkim    /* Update AML opcodes if necessary, after constant folding */
526151937Sjkim
527151937Sjkim    Event = UtBeginEvent ("Updating AML opcodes after constant folding");
528151937Sjkim    DbgPrint (ASL_DEBUG_OUTPUT,
529151937Sjkim        "\nUpdating AML opcodes after constant folding\n\n");
530151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
531151937Sjkim        NULL, OpcAmlOpcodeUpdateWalk, NULL);
532151937Sjkim    UtEndEvent (Event);
533151937Sjkim
534118611Snjl    /* Calculate all AML package lengths */
535118611Snjl
536151937Sjkim    Event = UtBeginEvent ("Generate AML package lengths");
537118611Snjl    DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
538151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
539151937Sjkim        LnPackageLengthWalk, NULL);
540151937Sjkim    UtEndEvent (Event);
541118611Snjl
542118611Snjl    if (Gbl_ParseOnlyFlag)
543118611Snjl    {
544118611Snjl        AePrintErrorLog (ASL_FILE_STDOUT);
545118611Snjl        UtDisplaySummary (ASL_FILE_STDOUT);
546118611Snjl        if (Gbl_DebugFlag)
547118611Snjl        {
548118611Snjl            /* Print error summary to the debug file */
549118611Snjl
550118611Snjl            AePrintErrorLog (ASL_FILE_STDERR);
551118611Snjl            UtDisplaySummary (ASL_FILE_STDERR);
552118611Snjl        }
553118611Snjl        return 0;
554118611Snjl    }
555118611Snjl
556118611Snjl    /*
557118611Snjl     * Create an internal namespace and use it as a symbol table
558118611Snjl     */
559118611Snjl
560118611Snjl    /* Namespace loading */
561118611Snjl
562151937Sjkim    Event = UtBeginEvent ("Create ACPI Namespace");
563118611Snjl    Status = LdLoadNamespace (RootNode);
564151937Sjkim    UtEndEvent (Event);
565118611Snjl    if (ACPI_FAILURE (Status))
566118611Snjl    {
567118611Snjl        return -1;
568118611Snjl    }
569118611Snjl
570167802Sjkim    /* Namespace cross-reference */
571118611Snjl
572151937Sjkim    AslGbl_NamespaceEvent = UtBeginEvent ("Cross reference parse tree and Namespace");
573118611Snjl    Status = LkCrossReferenceNamespace ();
574118611Snjl    if (ACPI_FAILURE (Status))
575118611Snjl    {
576118611Snjl        return -1;
577118611Snjl    }
578118611Snjl
579167802Sjkim    /* Namespace - Check for non-referenced objects */
580167802Sjkim
581167802Sjkim    LkFindUnreferencedObjects ();
582167802Sjkim    UtEndEvent (AslGbl_NamespaceEvent);
583167802Sjkim
584118611Snjl    /*
585118611Snjl     * Semantic analysis.  This can happen only after the
586118611Snjl     * namespace has been loaded and cross-referenced.
587118611Snjl     *
588118611Snjl     * part one - check control methods
589118611Snjl     */
590151937Sjkim    Event = UtBeginEvent ("Analyze control method return types");
591118611Snjl    AnalysisWalkInfo.MethodStack = NULL;
592118611Snjl
593118611Snjl    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method analysis\n\n");
594151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
595151937Sjkim        AnMethodAnalysisWalkBegin,
596151937Sjkim        AnMethodAnalysisWalkEnd, &AnalysisWalkInfo);
597151937Sjkim    UtEndEvent (Event);
598118611Snjl
599118611Snjl    /* Semantic error checking part two - typing of method returns */
600118611Snjl
601151937Sjkim    Event = UtBeginEvent ("Determine object types returned by methods");
602151937Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n");
603151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
604151937Sjkim        AnMethodTypingWalkBegin,
605151937Sjkim        AnMethodTypingWalkEnd, NULL);
606151937Sjkim    UtEndEvent (Event);
607118611Snjl
608118611Snjl    /* Semantic error checking part three - operand type checking */
609118611Snjl
610151937Sjkim    Event = UtBeginEvent ("Analyze AML operand types");
611151937Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n");
612151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
613151937Sjkim        AnOperandTypecheckWalkBegin,
614151937Sjkim        AnOperandTypecheckWalkEnd, &AnalysisWalkInfo);
615151937Sjkim    UtEndEvent (Event);
616118611Snjl
617118611Snjl    /* Semantic error checking part four - other miscellaneous checks */
618118611Snjl
619151937Sjkim    Event = UtBeginEvent ("Miscellaneous analysis");
620151937Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n");
621151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
622151937Sjkim        AnOtherSemanticAnalysisWalkBegin,
623151937Sjkim        AnOtherSemanticAnalysisWalkEnd, &AnalysisWalkInfo);
624151937Sjkim    UtEndEvent (Event);
625118611Snjl
626118611Snjl    /* Calculate all AML package lengths */
627118611Snjl
628151937Sjkim    Event = UtBeginEvent ("Finish AML package length generation");
629118611Snjl    DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
630151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
631151937Sjkim        LnInitLengthsWalk, NULL);
632151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
633151937Sjkim        LnPackageLengthWalk, NULL);
634151937Sjkim    UtEndEvent (Event);
635118611Snjl
636118611Snjl    /* Code generation - emit the AML */
637118611Snjl
638151937Sjkim    Event = UtBeginEvent ("Generate AML code and write output files");
639118611Snjl    CgGenerateAmlOutput ();
640151937Sjkim    UtEndEvent (Event);
641118611Snjl
642151937Sjkim    Event = UtBeginEvent ("Write optional output files");
643118611Snjl    CmDoOutputFiles ();
644151937Sjkim    UtEndEvent (Event);
645118611Snjl
646151937Sjkim    UtEndEvent (FullCompile);
647118611Snjl    CmCleanupAndExit ();
648118611Snjl    return 0;
649118611Snjl}
650118611Snjl
651151937Sjkim
652151937Sjkim/*******************************************************************************
653151937Sjkim *
654151937Sjkim * FUNCTION:    CmDoOutputFiles
655151937Sjkim *
656151937Sjkim * PARAMETERS:  None
657151937Sjkim *
658151937Sjkim * RETURN:      None.
659151937Sjkim *
660151937Sjkim * DESCRIPTION: Create all "listing" type files
661151937Sjkim *
662151937Sjkim ******************************************************************************/
663151937Sjkim
664118611Snjlvoid
665151937SjkimCmDoOutputFiles (
666151937Sjkim    void)
667118611Snjl{
668118611Snjl
669118611Snjl    /* Create listings and hex files */
670118611Snjl
671118611Snjl    LsDoListings ();
672118611Snjl    LsDoHexOutput ();
673118611Snjl
674118611Snjl    /* Dump the namespace to the .nsp file if requested */
675118611Snjl
676151937Sjkim    (void) LsDisplayNamespace ();
677118611Snjl}
678118611Snjl
679118611Snjl
680118611Snjl/*******************************************************************************
681118611Snjl *
682151937Sjkim * FUNCTION:    CmDumpEvent
683151937Sjkim *
684151937Sjkim * PARAMETERS:  Event           - A compiler event struct
685151937Sjkim *
686151937Sjkim * RETURN:      None.
687151937Sjkim *
688151937Sjkim * DESCRIPTION: Dump a compiler event struct
689151937Sjkim *
690151937Sjkim ******************************************************************************/
691151937Sjkim
692151937Sjkimstatic void
693151937SjkimCmDumpEvent (
694151937Sjkim    ASL_EVENT_INFO          *Event)
695151937Sjkim{
696151937Sjkim    UINT32                  Delta;
697151937Sjkim    UINT32                  USec;
698151937Sjkim    UINT32                  MSec;
699151937Sjkim
700151937Sjkim    if (!Event->Valid)
701151937Sjkim    {
702151937Sjkim        return;
703151937Sjkim    }
704151937Sjkim
705151937Sjkim    /* Delta will be in 100-nanosecond units */
706151937Sjkim
707151937Sjkim    Delta = (UINT32) (Event->EndTime - Event->StartTime);
708151937Sjkim
709151937Sjkim    USec = Delta / 10;
710151937Sjkim    MSec = Delta / 10000;
711151937Sjkim
712151937Sjkim    /* Round milliseconds up */
713151937Sjkim
714151937Sjkim    if ((USec - (MSec * 1000)) >= 500)
715151937Sjkim    {
716151937Sjkim        MSec++;
717151937Sjkim    }
718151937Sjkim
719151937Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n",
720151937Sjkim        USec, MSec, Event->EventName);
721151937Sjkim}
722151937Sjkim
723151937Sjkim
724151937Sjkim/*******************************************************************************
725151937Sjkim *
726118611Snjl * FUNCTION:    CmCleanupAndExit
727118611Snjl *
728118611Snjl * PARAMETERS:  None
729118611Snjl *
730118611Snjl * RETURN:      None.
731118611Snjl *
732118611Snjl * DESCRIPTION: Close all open files and exit the compiler
733118611Snjl *
734118611Snjl ******************************************************************************/
735118611Snjl
736118611Snjlvoid
737151937SjkimCmCleanupAndExit (
738151937Sjkim    void)
739118611Snjl{
740118611Snjl    UINT32                  i;
741118611Snjl
742118611Snjl
743118611Snjl    AePrintErrorLog (ASL_FILE_STDOUT);
744118611Snjl    if (Gbl_DebugFlag)
745118611Snjl    {
746118611Snjl        /* Print error summary to the debug file */
747118611Snjl
748118611Snjl        AePrintErrorLog (ASL_FILE_STDERR);
749118611Snjl    }
750118611Snjl
751118611Snjl    DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n");
752151937Sjkim    for (i = 0; i < AslGbl_NextEvent; i++)
753118611Snjl    {
754151937Sjkim        CmDumpEvent (&AslGbl_Events[i]);
755118611Snjl    }
756118611Snjl
757118611Snjl    if (Gbl_CompileTimesFlag)
758118611Snjl    {
759118611Snjl        printf ("\nElapsed time for major events\n\n");
760151937Sjkim        for (i = 0; i < AslGbl_NextEvent; i++)
761118611Snjl        {
762151937Sjkim            CmDumpEvent (&AslGbl_Events[i]);
763118611Snjl        }
764151937Sjkim
765118611Snjl        printf ("\nMiscellaneous compile statistics\n\n");
766118611Snjl        printf ("%11u : %s\n", TotalParseNodes, "Parse nodes");
767118611Snjl        printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches");
768118611Snjl        printf ("%11u : %s\n", TotalNamedObjects, "Named objects");
769118611Snjl        printf ("%11u : %s\n", TotalMethods, "Control methods");
770118611Snjl        printf ("%11u : %s\n", TotalAllocations, "Memory Allocations");
771118611Snjl        printf ("%11u : %s\n", TotalAllocated, "Total allocated memory");
772118611Snjl        printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded");
773118611Snjl        printf ("\n");
774118611Snjl    }
775118611Snjl
776118611Snjl    if (Gbl_NsLookupCount)
777118611Snjl    {
778209746Sjkim        DbgPrint (ASL_DEBUG_OUTPUT,
779209746Sjkim            "\n\nMiscellaneous compile statistics\n\n");
780209746Sjkim
781209746Sjkim        DbgPrint (ASL_DEBUG_OUTPUT,
782209746Sjkim            "%32s : %u\n", "Total Namespace searches",
783151937Sjkim            Gbl_NsLookupCount);
784209746Sjkim
785209746Sjkim        DbgPrint (ASL_DEBUG_OUTPUT,
786209746Sjkim            "%32s : %u usec\n", "Time per search", ((UINT32)
787209746Sjkim            (AslGbl_Events[AslGbl_NamespaceEvent].EndTime -
788209746Sjkim                AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) /
789209746Sjkim                Gbl_NsLookupCount);
790118611Snjl    }
791118611Snjl
792118611Snjl    if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
793118611Snjl    {
794209746Sjkim        printf ("\nMaximum error count (%u) exceeded\n",
795209746Sjkim            ASL_MAX_ERROR_COUNT);
796118611Snjl    }
797118611Snjl
798118611Snjl    UtDisplaySummary (ASL_FILE_STDOUT);
799199337Sjkim
800199337Sjkim    /* Close all open files */
801199337Sjkim
802199337Sjkim    for (i = 2; i < ASL_MAX_FILE_TYPE; i++)
803199337Sjkim    {
804199337Sjkim        FlCloseFile (i);
805199337Sjkim    }
806200553Sjkim
807200553Sjkim    /* Delete AML file if there are errors */
808200553Sjkim
809209746Sjkim    if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors) &&
810209746Sjkim        Gbl_Files[ASL_FILE_AML_OUTPUT].Handle)
811200553Sjkim    {
812209746Sjkim        if (remove (Gbl_Files[ASL_FILE_AML_OUTPUT].Filename))
813209746Sjkim        {
814209746Sjkim            printf ("%s: ",
815209746Sjkim                Gbl_Files[ASL_FILE_AML_OUTPUT].Filename);
816209746Sjkim            perror ("Could not delete AML file");
817209746Sjkim        }
818200553Sjkim    }
819200553Sjkim
820200553Sjkim    /*
821200553Sjkim     * Delete intermediate ("combined") source file (if -ls flag not set)
822209746Sjkim     * This file is created during normal ASL/AML compiles. It is not
823209746Sjkim     * created by the data table compiler.
824200553Sjkim     *
825209746Sjkim     * If the -ls flag is set, then the .SRC file should not be deleted.
826209746Sjkim     * In this case, Gbl_SourceOutputFlag is set to TRUE.
827209746Sjkim     *
828209746Sjkim     * Note: Handles are cleared by FlCloseFile above, so we look at the
829209746Sjkim     * filename instead, to determine if the .SRC file was actually
830209746Sjkim     * created.
831209746Sjkim     *
832200553Sjkim     * TBD: SourceOutput should be .TMP, then rename if we want to keep it?
833200553Sjkim     */
834209746Sjkim    if (!Gbl_SourceOutputFlag && Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename)
835200553Sjkim    {
836200553Sjkim        if (remove (Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename))
837200553Sjkim        {
838209746Sjkim            printf ("%s: ",
839200553Sjkim                Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
840209746Sjkim            perror ("Could not delete SRC file");
841200553Sjkim        }
842200553Sjkim    }
843118611Snjl}
844118611Snjl
845118611Snjl
846