aslcompile.c revision 246849
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>
45246849Sjkim#include <contrib/dev/acpica/compiler/dtcompiler.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
54243347Sjkim/*
55243347Sjkim * Main parser entry
56243347Sjkim * External is here in case the parser emits the same external in the
57243347Sjkim * generated header. (Newer versions of Bison)
58243347Sjkim */
59243347Sjkimint
60243347SjkimAslCompilerparse(
61243347Sjkim    void);
62243347Sjkim
63151937Sjkim/* Local prototypes */
64118611Snjl
65151937Sjkimstatic void
66151937SjkimCmFlushSourceCode (
67151937Sjkim    void);
68151937Sjkim
69212761Sjkimstatic void
70193529SjkimFlConsumeAnsiComment (
71235945Sjkim    FILE                    *Handle,
72193529Sjkim    ASL_FILE_STATUS         *Status);
73151937Sjkim
74212761Sjkimstatic void
75193529SjkimFlConsumeNewComment (
76235945Sjkim    FILE                    *Handle,
77193529Sjkim    ASL_FILE_STATUS         *Status);
78193529Sjkim
79237412Sjkimstatic void
80237412SjkimCmDumpAllEvents (
81237412Sjkim    void);
82193529Sjkim
83237412Sjkim
84118611Snjl/*******************************************************************************
85118611Snjl *
86118611Snjl * FUNCTION:    AslCompilerSignon
87118611Snjl *
88118611Snjl * PARAMETERS:  FileId      - ID of the output file
89118611Snjl *
90118611Snjl * RETURN:      None
91118611Snjl *
92118611Snjl * DESCRIPTION: Display compiler signon
93118611Snjl *
94118611Snjl ******************************************************************************/
95118611Snjl
96118611Snjlvoid
97118611SnjlAslCompilerSignon (
98118611Snjl    UINT32                  FileId)
99118611Snjl{
100118611Snjl    char                    *Prefix = "";
101213806Sjkim    char                    *UtilityName;
102118611Snjl
103118611Snjl
104151937Sjkim    /* Set line prefix depending on the destination file type */
105151937Sjkim
106118611Snjl    switch (FileId)
107118611Snjl    {
108118611Snjl    case ASL_FILE_ASM_SOURCE_OUTPUT:
109118611Snjl    case ASL_FILE_ASM_INCLUDE_OUTPUT:
110118611Snjl
111118611Snjl        Prefix = "; ";
112118611Snjl        break;
113118611Snjl
114118611Snjl    case ASL_FILE_HEX_OUTPUT:
115118611Snjl
116118611Snjl        if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
117118611Snjl        {
118118611Snjl            Prefix = "; ";
119118611Snjl        }
120207344Sjkim        else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
121207344Sjkim                 (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
122118611Snjl        {
123118611Snjl            FlPrintFile (ASL_FILE_HEX_OUTPUT, "/*\n");
124118611Snjl            Prefix = " * ";
125118611Snjl        }
126118611Snjl        break;
127118611Snjl
128118611Snjl    case ASL_FILE_C_SOURCE_OUTPUT:
129118611Snjl    case ASL_FILE_C_INCLUDE_OUTPUT:
130118611Snjl
131118611Snjl        Prefix = " * ";
132118611Snjl        break;
133118611Snjl
134118611Snjl    default:
135118611Snjl        /* No other output types supported */
136118611Snjl        break;
137118611Snjl    }
138118611Snjl
139151937Sjkim    /* Running compiler or disassembler? */
140151937Sjkim
141151937Sjkim    if (Gbl_DisasmFlag)
142151937Sjkim    {
143213806Sjkim        UtilityName = AML_DISASSEMBLER_NAME;
144151937Sjkim    }
145151937Sjkim    else
146151937Sjkim    {
147213806Sjkim        UtilityName = ASL_COMPILER_NAME;
148151937Sjkim    }
149151937Sjkim
150213806Sjkim    /* Compiler signon with copyright */
151151937Sjkim
152213806Sjkim    FlPrintFile (FileId, "%s\n", Prefix);
153213806Sjkim    FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix));
154118611Snjl}
155118611Snjl
156118611Snjl
157118611Snjl/*******************************************************************************
158118611Snjl *
159118611Snjl * FUNCTION:    AslCompilerFileHeader
160118611Snjl *
161118611Snjl * PARAMETERS:  FileId      - ID of the output file
162118611Snjl *
163118611Snjl * RETURN:      None
164118611Snjl *
165118611Snjl * DESCRIPTION: Header used at the beginning of output files
166118611Snjl *
167118611Snjl ******************************************************************************/
168118611Snjl
169118611Snjlvoid
170118611SnjlAslCompilerFileHeader (
171118611Snjl    UINT32                  FileId)
172118611Snjl{
173118611Snjl    struct tm               *NewTime;
174118611Snjl    time_t                  Aclock;
175118611Snjl    char                    *Prefix = "";
176118611Snjl
177118611Snjl
178151937Sjkim    /* Set line prefix depending on the destination file type */
179151937Sjkim
180118611Snjl    switch (FileId)
181118611Snjl    {
182118611Snjl    case ASL_FILE_ASM_SOURCE_OUTPUT:
183118611Snjl    case ASL_FILE_ASM_INCLUDE_OUTPUT:
184118611Snjl
185118611Snjl        Prefix = "; ";
186118611Snjl        break;
187118611Snjl
188118611Snjl    case ASL_FILE_HEX_OUTPUT:
189118611Snjl
190118611Snjl        if (Gbl_HexOutputFlag == HEX_OUTPUT_ASM)
191118611Snjl        {
192118611Snjl            Prefix = "; ";
193118611Snjl        }
194207344Sjkim        else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) ||
195207344Sjkim                 (Gbl_HexOutputFlag == HEX_OUTPUT_ASL))
196118611Snjl        {
197118611Snjl            Prefix = " * ";
198118611Snjl        }
199118611Snjl        break;
200118611Snjl
201118611Snjl    case ASL_FILE_C_SOURCE_OUTPUT:
202118611Snjl    case ASL_FILE_C_INCLUDE_OUTPUT:
203118611Snjl
204118611Snjl        Prefix = " * ";
205118611Snjl        break;
206118611Snjl
207118611Snjl    default:
208118611Snjl        /* No other output types supported */
209118611Snjl        break;
210118611Snjl    }
211118611Snjl
212118611Snjl    /* Compilation header with timestamp */
213118611Snjl
214118611Snjl    (void) time (&Aclock);
215118611Snjl    NewTime = localtime (&Aclock);
216118611Snjl
217118611Snjl    FlPrintFile (FileId,
218118611Snjl        "%sCompilation of \"%s\" - %s%s\n",
219118611Snjl        Prefix, Gbl_Files[ASL_FILE_INPUT].Filename, asctime (NewTime),
220118611Snjl        Prefix);
221118611Snjl
222118611Snjl    switch (FileId)
223118611Snjl    {
224118611Snjl    case ASL_FILE_C_SOURCE_OUTPUT:
225118611Snjl    case ASL_FILE_C_INCLUDE_OUTPUT:
226118611Snjl        FlPrintFile (FileId, " */\n");
227118611Snjl        break;
228118611Snjl
229118611Snjl    default:
230118611Snjl        /* Nothing to do for other output types */
231118611Snjl        break;
232118611Snjl    }
233118611Snjl}
234118611Snjl
235118611Snjl
236118611Snjl/*******************************************************************************
237118611Snjl *
238118611Snjl * FUNCTION:    CmFlushSourceCode
239118611Snjl *
240118611Snjl * PARAMETERS:  None
241118611Snjl *
242118611Snjl * RETURN:      None
243118611Snjl *
244118611Snjl * DESCRIPTION: Read in any remaining source code after the parse tree
245118611Snjl *              has been constructed.
246118611Snjl *
247118611Snjl ******************************************************************************/
248118611Snjl
249151937Sjkimstatic void
250151937SjkimCmFlushSourceCode (
251151937Sjkim    void)
252118611Snjl{
253118611Snjl    char                    Buffer;
254118611Snjl
255118611Snjl
256118611Snjl    while (FlReadFile (ASL_FILE_INPUT, &Buffer, 1) != AE_ERROR)
257118611Snjl    {
258234623Sjkim        AslInsertLineBuffer ((int) Buffer);
259118611Snjl    }
260118611Snjl
261234623Sjkim    AslResetCurrentLineBuffer ();
262118611Snjl}
263118611Snjl
264118611Snjl
265118611Snjl/*******************************************************************************
266118611Snjl *
267167802Sjkim * FUNCTION:    FlConsume*
268167802Sjkim *
269235945Sjkim * PARAMETERS:  Handle              - Open input file
270235945Sjkim *              Status              - File current status struct
271167802Sjkim *
272167802Sjkim * RETURN:      Number of lines consumed
273167802Sjkim *
274167802Sjkim * DESCRIPTION: Step over both types of comment during check for ascii chars
275167802Sjkim *
276167802Sjkim ******************************************************************************/
277167802Sjkim
278212761Sjkimstatic void
279167802SjkimFlConsumeAnsiComment (
280235945Sjkim    FILE                    *Handle,
281167802Sjkim    ASL_FILE_STATUS         *Status)
282167802Sjkim{
283167802Sjkim    UINT8                   Byte;
284167802Sjkim    BOOLEAN                 ClosingComment = FALSE;
285167802Sjkim
286167802Sjkim
287243347Sjkim    while (fread (&Byte, 1, 1, Handle) == 1)
288167802Sjkim    {
289167802Sjkim        /* Scan until comment close is found */
290167802Sjkim
291167802Sjkim        if (ClosingComment)
292167802Sjkim        {
293167802Sjkim            if (Byte == '/')
294167802Sjkim            {
295167802Sjkim                return;
296167802Sjkim            }
297167802Sjkim
298167802Sjkim            if (Byte != '*')
299167802Sjkim            {
300167802Sjkim                /* Reset */
301167802Sjkim
302167802Sjkim                ClosingComment = FALSE;
303167802Sjkim            }
304167802Sjkim        }
305167802Sjkim        else if (Byte == '*')
306167802Sjkim        {
307167802Sjkim            ClosingComment = TRUE;
308167802Sjkim        }
309167802Sjkim
310167802Sjkim        /* Maintain line count */
311167802Sjkim
312167802Sjkim        if (Byte == 0x0A)
313167802Sjkim        {
314167802Sjkim            Status->Line++;
315167802Sjkim        }
316167802Sjkim
317167802Sjkim        Status->Offset++;
318167802Sjkim    }
319167802Sjkim}
320167802Sjkim
321167802Sjkim
322212761Sjkimstatic void
323167802SjkimFlConsumeNewComment (
324235945Sjkim    FILE                    *Handle,
325167802Sjkim    ASL_FILE_STATUS         *Status)
326167802Sjkim{
327167802Sjkim    UINT8                   Byte;
328167802Sjkim
329167802Sjkim
330243347Sjkim    while (fread (&Byte, 1, 1, Handle) == 1)
331167802Sjkim    {
332167802Sjkim        Status->Offset++;
333167802Sjkim
334167802Sjkim        /* Comment ends at newline */
335167802Sjkim
336167802Sjkim        if (Byte == 0x0A)
337167802Sjkim        {
338167802Sjkim            Status->Line++;
339167802Sjkim            return;
340167802Sjkim        }
341167802Sjkim    }
342167802Sjkim}
343167802Sjkim
344167802Sjkim
345167802Sjkim/*******************************************************************************
346167802Sjkim *
347246849Sjkim * FUNCTION:    FlCheckForAcpiTable
348246849Sjkim *
349246849Sjkim * PARAMETERS:  Handle              - Open input file
350246849Sjkim *
351246849Sjkim * RETURN:      Status
352246849Sjkim *
353246849Sjkim * DESCRIPTION: Determine if a file seems to be a binary ACPI table, via the
354246849Sjkim *              following checks on what would be the table header:
355246849Sjkim *              0) File must be at least as long as an ACPI_TABLE_HEADER
356246849Sjkim *              1) The header length field must match the file size
357246849Sjkim *              2) Signature, OemId, OemTableId, AslCompilerId must be ASCII
358246849Sjkim *
359246849Sjkim ******************************************************************************/
360246849Sjkim
361246849SjkimACPI_STATUS
362246849SjkimFlCheckForAcpiTable (
363246849Sjkim    FILE                    *Handle)
364246849Sjkim{
365246849Sjkim    ACPI_TABLE_HEADER       Table;
366246849Sjkim    UINT32                  FileSize;
367246849Sjkim    size_t                  Actual;
368246849Sjkim    UINT32                  i;
369246849Sjkim
370246849Sjkim
371246849Sjkim    /* Read a potential table header */
372246849Sjkim
373246849Sjkim    Actual = fread (&Table, 1, sizeof (ACPI_TABLE_HEADER), Handle);
374246849Sjkim    fseek (Handle, 0, SEEK_SET);
375246849Sjkim
376246849Sjkim    if (Actual < sizeof (ACPI_TABLE_HEADER))
377246849Sjkim    {
378246849Sjkim        return (AE_ERROR);
379246849Sjkim    }
380246849Sjkim
381246849Sjkim    /* Header length field must match the file size */
382246849Sjkim
383246849Sjkim    FileSize = DtGetFileSize (Handle);
384246849Sjkim    if (Table.Length != FileSize)
385246849Sjkim    {
386246849Sjkim        return (AE_ERROR);
387246849Sjkim    }
388246849Sjkim
389246849Sjkim    /*
390246849Sjkim     * These fields must be ASCII:
391246849Sjkim     * Signature, OemId, OemTableId, AslCompilerId.
392246849Sjkim     * We allow a NULL terminator in OemId and OemTableId.
393246849Sjkim     */
394246849Sjkim    for (i = 0; i < ACPI_NAME_SIZE; i++)
395246849Sjkim    {
396246849Sjkim        if (!ACPI_IS_ASCII ((UINT8) Table.Signature[i]))
397246849Sjkim        {
398246849Sjkim            return (AE_ERROR);
399246849Sjkim        }
400246849Sjkim
401246849Sjkim        if (!ACPI_IS_ASCII ((UINT8) Table.AslCompilerId[i]))
402246849Sjkim        {
403246849Sjkim            return (AE_ERROR);
404246849Sjkim        }
405246849Sjkim    }
406246849Sjkim
407246849Sjkim    for (i = 0; (i < ACPI_OEM_ID_SIZE) && (Table.OemId[i]); i++)
408246849Sjkim    {
409246849Sjkim        if (!ACPI_IS_ASCII ((UINT8) Table.OemId[i]))
410246849Sjkim        {
411246849Sjkim            return (AE_ERROR);
412246849Sjkim        }
413246849Sjkim    }
414246849Sjkim
415246849Sjkim    for (i = 0; (i < ACPI_OEM_TABLE_ID_SIZE) && (Table.OemTableId[i]); i++)
416246849Sjkim    {
417246849Sjkim        if (!ACPI_IS_ASCII ((UINT8) Table.OemTableId[i]))
418246849Sjkim        {
419246849Sjkim            return (AE_ERROR);
420246849Sjkim        }
421246849Sjkim    }
422246849Sjkim
423246849Sjkim    printf ("Binary file appears to be a valid ACPI table, disassembling\n");
424246849Sjkim    return (AE_OK);
425246849Sjkim}
426246849Sjkim
427246849Sjkim
428246849Sjkim/*******************************************************************************
429246849Sjkim *
430123315Snjl * FUNCTION:    FlCheckForAscii
431123315Snjl *
432235945Sjkim * PARAMETERS:  Handle              - Open input file
433235945Sjkim *              Filename            - Input filename
434235945Sjkim *              DisplayErrors       - TRUE if error messages desired
435123315Snjl *
436151937Sjkim * RETURN:      Status
437123315Snjl *
438167802Sjkim * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters
439167802Sjkim *              within comments. Note: does not handle nested comments and does
440167802Sjkim *              not handle comment delimiters within string literals. However,
441167802Sjkim *              on the rare chance this happens and an invalid character is
442167802Sjkim *              missed, the parser will catch the error by failing in some
443167802Sjkim *              spectactular manner.
444123315Snjl *
445123315Snjl ******************************************************************************/
446123315Snjl
447209746SjkimACPI_STATUS
448123315SnjlFlCheckForAscii (
449235945Sjkim    FILE                    *Handle,
450235945Sjkim    char                    *Filename,
451235945Sjkim    BOOLEAN                 DisplayErrors)
452123315Snjl{
453123315Snjl    UINT8                   Byte;
454123315Snjl    ACPI_SIZE               BadBytes = 0;
455167802Sjkim    BOOLEAN                 OpeningComment = FALSE;
456167802Sjkim    ASL_FILE_STATUS         Status;
457123315Snjl
458123315Snjl
459167802Sjkim    Status.Line = 1;
460167802Sjkim    Status.Offset = 0;
461167802Sjkim
462123315Snjl    /* Read the entire file */
463123315Snjl
464243347Sjkim    while (fread (&Byte, 1, 1, Handle) == 1)
465123315Snjl    {
466167802Sjkim        /* Ignore comment fields (allow non-ascii within) */
467167802Sjkim
468167802Sjkim        if (OpeningComment)
469167802Sjkim        {
470167802Sjkim            /* Check for second comment open delimiter */
471167802Sjkim
472167802Sjkim            if (Byte == '*')
473167802Sjkim            {
474235945Sjkim                FlConsumeAnsiComment (Handle, &Status);
475167802Sjkim            }
476167802Sjkim
477167802Sjkim            if (Byte == '/')
478167802Sjkim            {
479235945Sjkim                FlConsumeNewComment (Handle, &Status);
480167802Sjkim            }
481167802Sjkim
482167802Sjkim            /* Reset */
483167802Sjkim
484167802Sjkim            OpeningComment = FALSE;
485167802Sjkim        }
486167802Sjkim        else if (Byte == '/')
487167802Sjkim        {
488167802Sjkim            OpeningComment = TRUE;
489167802Sjkim        }
490167802Sjkim
491123315Snjl        /* Check for an ASCII character */
492123315Snjl
493193529Sjkim        if (!ACPI_IS_ASCII (Byte))
494123315Snjl        {
495235945Sjkim            if ((BadBytes < 10) && (DisplayErrors))
496123315Snjl            {
497151937Sjkim                AcpiOsPrintf (
498167802Sjkim                    "Non-ASCII character [0x%2.2X] found in line %u, file offset 0x%.2X\n",
499167802Sjkim                    Byte, Status.Line, Status.Offset);
500123315Snjl            }
501167802Sjkim
502123315Snjl            BadBytes++;
503123315Snjl        }
504167802Sjkim
505167802Sjkim        /* Update line counter */
506167802Sjkim
507167802Sjkim        else if (Byte == 0x0A)
508167802Sjkim        {
509167802Sjkim            Status.Line++;
510167802Sjkim        }
511167802Sjkim
512167802Sjkim        Status.Offset++;
513123315Snjl    }
514123315Snjl
515151937Sjkim    /* Seek back to the beginning of the source file */
516151937Sjkim
517235945Sjkim    fseek (Handle, 0, SEEK_SET);
518151937Sjkim
519123315Snjl    /* Were there any non-ASCII characters in the file? */
520123315Snjl
521123315Snjl    if (BadBytes)
522123315Snjl    {
523235945Sjkim        if (DisplayErrors)
524235945Sjkim        {
525235945Sjkim            AcpiOsPrintf (
526235945Sjkim                "%u non-ASCII characters found in input source text, could be a binary file\n",
527235945Sjkim                BadBytes);
528235945Sjkim            AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename);
529235945Sjkim        }
530235945Sjkim
531123315Snjl        return (AE_BAD_CHARACTER);
532123315Snjl    }
533123315Snjl
534235945Sjkim    /* File is OK (100% ASCII) */
535123315Snjl
536123315Snjl    return (AE_OK);
537123315Snjl}
538123315Snjl
539123315Snjl
540123315Snjl/*******************************************************************************
541123315Snjl *
542118611Snjl * FUNCTION:    CmDoCompile
543118611Snjl *
544118611Snjl * PARAMETERS:  None
545118611Snjl *
546118611Snjl * RETURN:      Status (0 = OK)
547118611Snjl *
548118611Snjl * DESCRIPTION: This procedure performs the entire compile
549118611Snjl *
550118611Snjl ******************************************************************************/
551118611Snjl
552118611Snjlint
553151937SjkimCmDoCompile (
554151937Sjkim    void)
555118611Snjl{
556118611Snjl    ACPI_STATUS             Status;
557151937Sjkim    UINT8                   FullCompile;
558151937Sjkim    UINT8                   Event;
559118611Snjl
560118611Snjl
561151937Sjkim    FullCompile = UtBeginEvent ("*** Total Compile time ***");
562151937Sjkim    Event = UtBeginEvent ("Open input and output files");
563151937Sjkim    UtEndEvent (Event);
564118611Snjl
565233250Sjkim    Event = UtBeginEvent ("Preprocess input file");
566234623Sjkim    if (Gbl_PreprocessFlag)
567233250Sjkim    {
568234623Sjkim        /* Preprocessor */
569234623Sjkim
570234623Sjkim        PrDoPreprocess ();
571234623Sjkim        if (Gbl_PreprocessOnly)
572234623Sjkim        {
573234623Sjkim            UtEndEvent (Event);
574234623Sjkim            CmCleanupAndExit ();
575241973Sjkim            return (0);
576234623Sjkim        }
577233250Sjkim    }
578234623Sjkim    UtEndEvent (Event);
579233250Sjkim
580118611Snjl    /* Build the parse tree */
581118611Snjl
582151937Sjkim    Event = UtBeginEvent ("Parse source code and build parse tree");
583118611Snjl    AslCompilerparse();
584151937Sjkim    UtEndEvent (Event);
585118611Snjl
586118611Snjl    /* Flush out any remaining source after parse tree is complete */
587118611Snjl
588151937Sjkim    Event = UtBeginEvent ("Flush source input");
589118611Snjl    CmFlushSourceCode ();
590118611Snjl
591118611Snjl    /* Did the parse tree get successfully constructed? */
592118611Snjl
593118611Snjl    if (!RootNode)
594118611Snjl    {
595234623Sjkim        /*
596234623Sjkim         * If there are no errors, then we have some sort of
597234623Sjkim         * internal problem.
598234623Sjkim         */
599234623Sjkim        Status = AslCheckForErrorExit ();
600234623Sjkim        if (Status == AE_OK)
601234623Sjkim        {
602234623Sjkim            AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
603234623Sjkim                NULL, "- Could not resolve parse tree root node");
604234623Sjkim        }
605234623Sjkim
606233250Sjkim        goto ErrorExit;
607118611Snjl    }
608118611Snjl
609167802Sjkim    /* Optional parse tree dump, compiler debug output only */
610167802Sjkim
611167802Sjkim    LsDumpParseTree ();
612167802Sjkim
613118611Snjl    OpcGetIntegerWidth (RootNode);
614151937Sjkim    UtEndEvent (Event);
615118611Snjl
616118611Snjl    /* Pre-process parse tree for any operator transforms */
617118611Snjl
618151937Sjkim    Event = UtBeginEvent ("Parse tree transforms");
619118611Snjl    DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n");
620151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
621151937Sjkim        TrAmlTransformWalk, NULL, NULL);
622151937Sjkim    UtEndEvent (Event);
623118611Snjl
624118611Snjl    /* Generate AML opcodes corresponding to the parse tokens */
625118611Snjl
626151937Sjkim    Event = UtBeginEvent ("Generate AML opcodes");
627118611Snjl    DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating AML opcodes\n\n");
628151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
629151937Sjkim        OpcAmlOpcodeWalk, NULL);
630151937Sjkim    UtEndEvent (Event);
631118611Snjl
632118611Snjl    /*
633118611Snjl     * Now that the input is parsed, we can open the AML output file.
634118611Snjl     * Note: by default, the name of this file comes from the table descriptor
635118611Snjl     * within the input file.
636118611Snjl     */
637151937Sjkim    Event = UtBeginEvent ("Open AML output file");
638118611Snjl    Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
639233250Sjkim    UtEndEvent (Event);
640118611Snjl    if (ACPI_FAILURE (Status))
641118611Snjl    {
642118611Snjl        AePrintErrorLog (ASL_FILE_STDERR);
643241973Sjkim        return (-1);
644118611Snjl    }
645118611Snjl
646118611Snjl    /* Interpret and generate all compile-time constants */
647118611Snjl
648151937Sjkim    Event = UtBeginEvent ("Constant folding via AML interpreter");
649151937Sjkim    DbgPrint (ASL_DEBUG_OUTPUT,
650151937Sjkim        "\nInterpreting compile-time constant expressions\n\n");
651151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
652151937Sjkim        OpcAmlConstantWalk, NULL, NULL);
653151937Sjkim    UtEndEvent (Event);
654118611Snjl
655151937Sjkim    /* Update AML opcodes if necessary, after constant folding */
656151937Sjkim
657151937Sjkim    Event = UtBeginEvent ("Updating AML opcodes after constant folding");
658151937Sjkim    DbgPrint (ASL_DEBUG_OUTPUT,
659151937Sjkim        "\nUpdating AML opcodes after constant folding\n\n");
660151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
661151937Sjkim        NULL, OpcAmlOpcodeUpdateWalk, NULL);
662151937Sjkim    UtEndEvent (Event);
663151937Sjkim
664118611Snjl    /* Calculate all AML package lengths */
665118611Snjl
666151937Sjkim    Event = UtBeginEvent ("Generate AML package lengths");
667118611Snjl    DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
668151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
669151937Sjkim        LnPackageLengthWalk, NULL);
670151937Sjkim    UtEndEvent (Event);
671118611Snjl
672118611Snjl    if (Gbl_ParseOnlyFlag)
673118611Snjl    {
674234623Sjkim        AePrintErrorLog (ASL_FILE_STDERR);
675234623Sjkim        UtDisplaySummary (ASL_FILE_STDERR);
676118611Snjl        if (Gbl_DebugFlag)
677118611Snjl        {
678234623Sjkim            /* Print error summary to the stdout also */
679118611Snjl
680234623Sjkim            AePrintErrorLog (ASL_FILE_STDOUT);
681234623Sjkim            UtDisplaySummary (ASL_FILE_STDOUT);
682118611Snjl        }
683233250Sjkim        UtEndEvent (FullCompile);
684241973Sjkim        return (0);
685118611Snjl    }
686118611Snjl
687118611Snjl    /*
688118611Snjl     * Create an internal namespace and use it as a symbol table
689118611Snjl     */
690118611Snjl
691118611Snjl    /* Namespace loading */
692118611Snjl
693151937Sjkim    Event = UtBeginEvent ("Create ACPI Namespace");
694118611Snjl    Status = LdLoadNamespace (RootNode);
695151937Sjkim    UtEndEvent (Event);
696118611Snjl    if (ACPI_FAILURE (Status))
697118611Snjl    {
698233250Sjkim        goto ErrorExit;
699118611Snjl    }
700118611Snjl
701167802Sjkim    /* Namespace cross-reference */
702118611Snjl
703151937Sjkim    AslGbl_NamespaceEvent = UtBeginEvent ("Cross reference parse tree and Namespace");
704245582Sjkim    Status = XfCrossReferenceNamespace ();
705118611Snjl    if (ACPI_FAILURE (Status))
706118611Snjl    {
707233250Sjkim        goto ErrorExit;
708118611Snjl    }
709118611Snjl
710167802Sjkim    /* Namespace - Check for non-referenced objects */
711167802Sjkim
712167802Sjkim    LkFindUnreferencedObjects ();
713167802Sjkim    UtEndEvent (AslGbl_NamespaceEvent);
714167802Sjkim
715118611Snjl    /*
716241973Sjkim     * Semantic analysis. This can happen only after the
717118611Snjl     * namespace has been loaded and cross-referenced.
718118611Snjl     *
719118611Snjl     * part one - check control methods
720118611Snjl     */
721151937Sjkim    Event = UtBeginEvent ("Analyze control method return types");
722118611Snjl    AnalysisWalkInfo.MethodStack = NULL;
723118611Snjl
724118611Snjl    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method analysis\n\n");
725151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
726245582Sjkim        MtMethodAnalysisWalkBegin,
727245582Sjkim        MtMethodAnalysisWalkEnd, &AnalysisWalkInfo);
728151937Sjkim    UtEndEvent (Event);
729118611Snjl
730118611Snjl    /* Semantic error checking part two - typing of method returns */
731118611Snjl
732151937Sjkim    Event = UtBeginEvent ("Determine object types returned by methods");
733151937Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n");
734218590Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
735218590Sjkim        NULL, AnMethodTypingWalkEnd, NULL);
736151937Sjkim    UtEndEvent (Event);
737118611Snjl
738118611Snjl    /* Semantic error checking part three - operand type checking */
739118611Snjl
740151937Sjkim    Event = UtBeginEvent ("Analyze AML operand types");
741151937Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n");
742218590Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
743218590Sjkim        NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo);
744151937Sjkim    UtEndEvent (Event);
745118611Snjl
746118611Snjl    /* Semantic error checking part four - other miscellaneous checks */
747118611Snjl
748151937Sjkim    Event = UtBeginEvent ("Miscellaneous analysis");
749151937Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n");
750218590Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
751151937Sjkim        AnOtherSemanticAnalysisWalkBegin,
752218590Sjkim        NULL, &AnalysisWalkInfo);
753151937Sjkim    UtEndEvent (Event);
754118611Snjl
755118611Snjl    /* Calculate all AML package lengths */
756118611Snjl
757151937Sjkim    Event = UtBeginEvent ("Finish AML package length generation");
758118611Snjl    DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
759151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
760151937Sjkim        LnInitLengthsWalk, NULL);
761151937Sjkim    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
762151937Sjkim        LnPackageLengthWalk, NULL);
763151937Sjkim    UtEndEvent (Event);
764118611Snjl
765118611Snjl    /* Code generation - emit the AML */
766118611Snjl
767151937Sjkim    Event = UtBeginEvent ("Generate AML code and write output files");
768118611Snjl    CgGenerateAmlOutput ();
769151937Sjkim    UtEndEvent (Event);
770118611Snjl
771151937Sjkim    Event = UtBeginEvent ("Write optional output files");
772118611Snjl    CmDoOutputFiles ();
773151937Sjkim    UtEndEvent (Event);
774118611Snjl
775151937Sjkim    UtEndEvent (FullCompile);
776118611Snjl    CmCleanupAndExit ();
777241973Sjkim    return (0);
778233250Sjkim
779233250SjkimErrorExit:
780233250Sjkim    UtEndEvent (FullCompile);
781233250Sjkim    CmCleanupAndExit ();
782233250Sjkim    return (-1);
783118611Snjl}
784118611Snjl
785151937Sjkim
786151937Sjkim/*******************************************************************************
787151937Sjkim *
788151937Sjkim * FUNCTION:    CmDoOutputFiles
789151937Sjkim *
790151937Sjkim * PARAMETERS:  None
791151937Sjkim *
792151937Sjkim * RETURN:      None.
793151937Sjkim *
794151937Sjkim * DESCRIPTION: Create all "listing" type files
795151937Sjkim *
796151937Sjkim ******************************************************************************/
797151937Sjkim
798118611Snjlvoid
799151937SjkimCmDoOutputFiles (
800151937Sjkim    void)
801118611Snjl{
802118611Snjl
803118611Snjl    /* Create listings and hex files */
804118611Snjl
805118611Snjl    LsDoListings ();
806245582Sjkim    HxDoHexOutput ();
807118611Snjl
808118611Snjl    /* Dump the namespace to the .nsp file if requested */
809118611Snjl
810245582Sjkim    (void) NsDisplayNamespace ();
811118611Snjl}
812118611Snjl
813118611Snjl
814118611Snjl/*******************************************************************************
815118611Snjl *
816237412Sjkim * FUNCTION:    CmDumpAllEvents
817151937Sjkim *
818237412Sjkim * PARAMETERS:  None
819151937Sjkim *
820151937Sjkim * RETURN:      None.
821151937Sjkim *
822237412Sjkim * DESCRIPTION: Dump all compiler events
823151937Sjkim *
824151937Sjkim ******************************************************************************/
825151937Sjkim
826151937Sjkimstatic void
827237412SjkimCmDumpAllEvents (
828237412Sjkim    void)
829151937Sjkim{
830237412Sjkim    ASL_EVENT_INFO          *Event;
831151937Sjkim    UINT32                  Delta;
832151937Sjkim    UINT32                  USec;
833151937Sjkim    UINT32                  MSec;
834237412Sjkim    UINT32                  i;
835151937Sjkim
836237412Sjkim
837237412Sjkim    Event = AslGbl_Events;
838237412Sjkim
839237412Sjkim    DbgPrint (ASL_DEBUG_OUTPUT, "\n\nElapsed time for major events\n\n");
840237412Sjkim    if (Gbl_CompileTimesFlag)
841151937Sjkim    {
842237412Sjkim        printf ("\nElapsed time for major events\n\n");
843151937Sjkim    }
844151937Sjkim
845237412Sjkim    for (i = 0; i < AslGbl_NextEvent; i++)
846237412Sjkim    {
847237412Sjkim        if (Event->Valid)
848237412Sjkim        {
849237412Sjkim            /* Delta will be in 100-nanosecond units */
850151937Sjkim
851237412Sjkim            Delta = (UINT32) (Event->EndTime - Event->StartTime);
852151937Sjkim
853245582Sjkim            USec = Delta / ACPI_100NSEC_PER_USEC;
854245582Sjkim            MSec = Delta / ACPI_100NSEC_PER_MSEC;
855151937Sjkim
856237412Sjkim            /* Round milliseconds up */
857151937Sjkim
858245582Sjkim            if ((USec - (MSec * ACPI_USEC_PER_MSEC)) >= 500)
859237412Sjkim            {
860237412Sjkim                MSec++;
861237412Sjkim            }
862237412Sjkim
863237412Sjkim            DbgPrint (ASL_DEBUG_OUTPUT, "%8u usec %8u msec - %s\n",
864237412Sjkim                USec, MSec, Event->EventName);
865237412Sjkim
866237412Sjkim            if (Gbl_CompileTimesFlag)
867237412Sjkim            {
868237412Sjkim                printf ("%8u usec %8u msec - %s\n",
869237412Sjkim                    USec, MSec, Event->EventName);
870237412Sjkim            }
871237412Sjkim        }
872237412Sjkim
873237412Sjkim        Event++;
874151937Sjkim    }
875151937Sjkim}
876151937Sjkim
877151937Sjkim
878151937Sjkim/*******************************************************************************
879151937Sjkim *
880118611Snjl * FUNCTION:    CmCleanupAndExit
881118611Snjl *
882118611Snjl * PARAMETERS:  None
883118611Snjl *
884118611Snjl * RETURN:      None.
885118611Snjl *
886118611Snjl * DESCRIPTION: Close all open files and exit the compiler
887118611Snjl *
888118611Snjl ******************************************************************************/
889118611Snjl
890118611Snjlvoid
891151937SjkimCmCleanupAndExit (
892151937Sjkim    void)
893118611Snjl{
894118611Snjl    UINT32                  i;
895240716Sjkim    BOOLEAN                 DeleteAmlFile = FALSE;
896118611Snjl
897118611Snjl
898234623Sjkim    AePrintErrorLog (ASL_FILE_STDERR);
899118611Snjl    if (Gbl_DebugFlag)
900118611Snjl    {
901234623Sjkim        /* Print error summary to stdout also */
902118611Snjl
903234623Sjkim        AePrintErrorLog (ASL_FILE_STDOUT);
904118611Snjl    }
905118611Snjl
906237412Sjkim    /* Emit compile times if enabled */
907118611Snjl
908237412Sjkim    CmDumpAllEvents ();
909237412Sjkim
910118611Snjl    if (Gbl_CompileTimesFlag)
911118611Snjl    {
912118611Snjl        printf ("\nMiscellaneous compile statistics\n\n");
913118611Snjl        printf ("%11u : %s\n", TotalParseNodes, "Parse nodes");
914118611Snjl        printf ("%11u : %s\n", Gbl_NsLookupCount, "Namespace searches");
915118611Snjl        printf ("%11u : %s\n", TotalNamedObjects, "Named objects");
916118611Snjl        printf ("%11u : %s\n", TotalMethods, "Control methods");
917118611Snjl        printf ("%11u : %s\n", TotalAllocations, "Memory Allocations");
918118611Snjl        printf ("%11u : %s\n", TotalAllocated, "Total allocated memory");
919118611Snjl        printf ("%11u : %s\n", TotalFolds, "Constant subtrees folded");
920118611Snjl        printf ("\n");
921118611Snjl    }
922118611Snjl
923118611Snjl    if (Gbl_NsLookupCount)
924118611Snjl    {
925209746Sjkim        DbgPrint (ASL_DEBUG_OUTPUT,
926209746Sjkim            "\n\nMiscellaneous compile statistics\n\n");
927209746Sjkim
928209746Sjkim        DbgPrint (ASL_DEBUG_OUTPUT,
929209746Sjkim            "%32s : %u\n", "Total Namespace searches",
930151937Sjkim            Gbl_NsLookupCount);
931209746Sjkim
932209746Sjkim        DbgPrint (ASL_DEBUG_OUTPUT,
933209746Sjkim            "%32s : %u usec\n", "Time per search", ((UINT32)
934209746Sjkim            (AslGbl_Events[AslGbl_NamespaceEvent].EndTime -
935209746Sjkim                AslGbl_Events[AslGbl_NamespaceEvent].StartTime) / 10) /
936209746Sjkim                Gbl_NsLookupCount);
937118611Snjl    }
938118611Snjl
939118611Snjl    if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
940118611Snjl    {
941209746Sjkim        printf ("\nMaximum error count (%u) exceeded\n",
942209746Sjkim            ASL_MAX_ERROR_COUNT);
943118611Snjl    }
944118611Snjl
945118611Snjl    UtDisplaySummary (ASL_FILE_STDOUT);
946199337Sjkim
947240716Sjkim    /*
948240716Sjkim     * We will delete the AML file if there are errors and the
949240716Sjkim     * force AML output option has not been used.
950240716Sjkim     */
951240716Sjkim    if ((Gbl_ExceptionCount[ASL_ERROR] > 0) && (!Gbl_IgnoreErrors) &&
952240716Sjkim        Gbl_Files[ASL_FILE_AML_OUTPUT].Handle)
953240716Sjkim    {
954240716Sjkim        DeleteAmlFile = TRUE;
955240716Sjkim    }
956240716Sjkim
957199337Sjkim    /* Close all open files */
958199337Sjkim
959233250Sjkim    Gbl_Files[ASL_FILE_PREPROCESSOR].Handle = NULL; /* the .i file is same as source file */
960233250Sjkim
961233250Sjkim    for (i = ASL_FILE_INPUT; i < ASL_MAX_FILE_TYPE; i++)
962199337Sjkim    {
963199337Sjkim        FlCloseFile (i);
964199337Sjkim    }
965200553Sjkim
966200553Sjkim    /* Delete AML file if there are errors */
967200553Sjkim
968240716Sjkim    if (DeleteAmlFile)
969200553Sjkim    {
970240716Sjkim        FlDeleteFile (ASL_FILE_AML_OUTPUT);
971200553Sjkim    }
972200553Sjkim
973233250Sjkim    /* Delete the preprocessor output file (.i) unless -li flag is set */
974233250Sjkim
975234623Sjkim    if (!Gbl_PreprocessorOutputFlag &&
976240716Sjkim        Gbl_PreprocessFlag)
977233250Sjkim    {
978240716Sjkim        FlDeleteFile (ASL_FILE_PREPROCESSOR);
979233250Sjkim    }
980233250Sjkim
981200553Sjkim    /*
982200553Sjkim     * Delete intermediate ("combined") source file (if -ls flag not set)
983209746Sjkim     * This file is created during normal ASL/AML compiles. It is not
984209746Sjkim     * created by the data table compiler.
985200553Sjkim     *
986209746Sjkim     * If the -ls flag is set, then the .SRC file should not be deleted.
987209746Sjkim     * In this case, Gbl_SourceOutputFlag is set to TRUE.
988209746Sjkim     *
989209746Sjkim     * Note: Handles are cleared by FlCloseFile above, so we look at the
990209746Sjkim     * filename instead, to determine if the .SRC file was actually
991209746Sjkim     * created.
992209746Sjkim     *
993200553Sjkim     * TBD: SourceOutput should be .TMP, then rename if we want to keep it?
994200553Sjkim     */
995240716Sjkim    if (!Gbl_SourceOutputFlag)
996200553Sjkim    {
997240716Sjkim        FlDeleteFile (ASL_FILE_SOURCE_OUTPUT);
998200553Sjkim    }
999118611Snjl}
1000