예제 #1
0
int
CmDoAslMiddleAndBackEnd (
    void)
{
    UINT8                   Event;
    ACPI_STATUS             Status;


    /* Interpret and generate all compile-time constants */

    Event = UtBeginEvent ("Constant folding via AML interpreter");
    DbgPrint (ASL_DEBUG_OUTPUT,
        "Interpreting compile-time constant expressions\n\n");

    if (AslGbl_FoldConstants)
    {
        TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD,
            NULL, OpcAmlConstantWalk, NULL);
    }
    else
    {
        DbgPrint (ASL_PARSE_OUTPUT, "    Optional folding disabled\n");
    }
    UtEndEvent (Event);

    /* Update AML opcodes if necessary, after constant folding */

    Event = UtBeginEvent ("Updating AML opcodes after constant folding");
    DbgPrint (ASL_DEBUG_OUTPUT,
        "Updating AML opcodes after constant folding\n\n");
    TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD,
        NULL, OpcAmlOpcodeUpdateWalk, NULL);
    UtEndEvent (Event);

    /* Calculate all AML package lengths */

    Event = UtBeginEvent ("Generate AML package lengths");
    DbgPrint (ASL_DEBUG_OUTPUT, "Generating Package lengths\n\n");
    TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL,
        LnPackageLengthWalk, NULL);
    UtEndEvent (Event);

    if (AslGbl_ParseOnlyFlag)
    {
        AePrintErrorLog (ASL_FILE_STDERR);
        UtDisplaySummary (ASL_FILE_STDERR);
        if (AslGbl_DebugFlag)
        {
            /* Print error summary to the stdout also */

            AePrintErrorLog (ASL_FILE_STDOUT);
            UtDisplaySummary (ASL_FILE_STDOUT);
        }
        return (0);
    }

    /*
     * Create an internal namespace and use it as a symbol table
     */

    /* Namespace loading */

    Event = UtBeginEvent ("Create ACPI Namespace");
    DbgPrint (ASL_DEBUG_OUTPUT, "Creating ACPI Namespace\n\n");
    Status = LdLoadNamespace (AslGbl_ParseTreeRoot);
    UtEndEvent (Event);
    if (ACPI_FAILURE (Status))
    {
        return (-1);
    }

    /* Namespace cross-reference */

    AslGbl_NamespaceEvent = UtBeginEvent (
        "Cross reference parse tree and Namespace");
    DbgPrint (ASL_DEBUG_OUTPUT, "Cross referencing namespace\n\n");
    Status = XfCrossReferenceNamespace ();
    if (ACPI_FAILURE (Status))
    {
        return (-1);
    }

    /* Namespace - Check for non-referenced objects */

    LkFindUnreferencedObjects ();
    UtEndEvent (AslGbl_NamespaceEvent);

    /* Resolve External Declarations */

    Event = UtBeginEvent ("Resolve all Externals");
    DbgPrint (ASL_DEBUG_OUTPUT, "\nResolve Externals\n\n");

    if (AslGbl_DoExternalsInPlace)
    {
        TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
            ExAmlExternalWalkBegin, NULL, NULL);
    }
    else
    {
        TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE,
            ExAmlExternalWalkBegin, ExAmlExternalWalkEnd, NULL);
    }
    UtEndEvent (Event);

    /*
     * Semantic analysis. This can happen only after the
     * namespace has been loaded and cross-referenced.
     *
     * part one - check control methods
     */
    Event = UtBeginEvent ("Analyze control method return types");
    AslGbl_AnalysisWalkInfo.MethodStack = NULL;

    DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - Method analysis\n\n");

    if (AslGbl_CrossReferenceOutput)
    {
        OtPrintHeaders ("Part 1: Object Reference Map "
            "(Object references from within each control method)");
    }

    TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE,
        MtMethodAnalysisWalkBegin,
        MtMethodAnalysisWalkEnd, &AslGbl_AnalysisWalkInfo);
    UtEndEvent (Event);

    /* Generate the object cross-reference file if requested */

    Event = UtBeginEvent ("Generate cross-reference file");
    OtCreateXrefFile ();
    UtEndEvent (Event);

    /* Semantic error checking part two - typing of method returns */

    Event = UtBeginEvent ("Determine object types returned by methods");
    DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - Method typing\n\n");
    TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD,
        NULL, AnMethodTypingWalkEnd, NULL);
    UtEndEvent (Event);

    /* Semantic error checking part three - operand type checking */

    Event = UtBeginEvent ("Analyze AML operand types");
    DbgPrint (ASL_DEBUG_OUTPUT,
        "Semantic analysis - Operand type checking\n\n");
    if (AslGbl_DoTypechecking)
    {
        TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD,
            NULL, AnOperandTypecheckWalkEnd, &AslGbl_AnalysisWalkInfo);
    }
    UtEndEvent (Event);

    /* Semantic error checking part four - other miscellaneous checks */

    Event = UtBeginEvent ("Miscellaneous analysis");
    DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - miscellaneous\n\n");
    TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
        AnOtherSemanticAnalysisWalkBegin,
        NULL, &AslGbl_AnalysisWalkInfo);
    UtEndEvent (Event);

    /*
     * ASL-/ASL+ converter: Gbl_ParseTreeRoot->CommentList contains the
     * very last comment of a given ASL file because it's the last constructed
     * node during compilation. We take the very last comment and save it in a
     * global for it to be used by the disassembler.
     */
    if (AcpiGbl_CaptureComments)
    {
        AcpiGbl_LastListHead = AslGbl_ParseTreeRoot->Asl.CommentList;
        AslGbl_ParseTreeRoot->Asl.CommentList = NULL;
    }

    /* Calculate all AML package lengths */

    Event = UtBeginEvent ("Finish AML package length generation");
    DbgPrint (ASL_DEBUG_OUTPUT, "Generating Package lengths\n\n");
    TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL,
        LnInitLengthsWalk, NULL);
    TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL,
        LnPackageLengthWalk, NULL);
    UtEndEvent (Event);

    /* Code generation - emit the AML */

    Event = UtBeginEvent ("Generate AML code and write output files");
    DbgPrint (ASL_DEBUG_OUTPUT, "Writing AML byte code\n\n");

    AslGbl_CurrentDB = AslGbl_ParseTreeRoot->Asl.Child;

    while (AslGbl_CurrentDB)
    {
        switch  (FlSwitchFileSet(AslGbl_CurrentDB->Asl.Filename))
        {
            case SWITCH_TO_DIFFERENT_FILE:
                /*
                 * Reset these parameters when definition blocks belong in
                 * different files. If they belong in the same file, there is
                 * no need to reset these parameters
                 */
                FlSeekFile (ASL_FILE_SOURCE_OUTPUT, 0);
                AslGbl_SourceLine = 0;
                AslGbl_NextError = AslGbl_ErrorLog;

                /* fall-through */

            case SWITCH_TO_SAME_FILE:

                CgGenerateAmlOutput ();
                CmDoOutputFiles ();
                AslGbl_CurrentDB = AslGbl_CurrentDB->Asl.Next;

                break;

            default: /* FILE_NOT_FOUND */

                /* The requested file could not be found. Get out of here */

                AslGbl_CurrentDB = NULL;
                break;
        }
    }
    UtEndEvent (Event);

    Event = UtBeginEvent ("Write optional output files");
    UtEndEvent (Event);

    return (0);
}
예제 #2
0
int
CmDoCompile (
    void)
{
    ACPI_STATUS             Status;
    UINT8                   FullCompile;
    UINT8                   Event;


    FullCompile = UtBeginEvent ("*** Total Compile time ***");
    Event = UtBeginEvent ("Open input and output files");
    UtEndEvent (Event);

    Event = UtBeginEvent ("Preprocess input file");
    if (Gbl_PreprocessFlag)
    {
        /* Preprocessor */

        PrDoPreprocess ();
        if (Gbl_PreprocessOnly)
        {
            UtEndEvent (Event);
            CmCleanupAndExit ();
            return (0);
        }
    }
    UtEndEvent (Event);

    /* Build the parse tree */

    Event = UtBeginEvent ("Parse source code and build parse tree");
    AslCompilerparse();
    UtEndEvent (Event);

    /* Check for parser-detected syntax errors */

    if (Gbl_SyntaxError)
    {
        fprintf (stderr, "Compiler aborting due to parser-detected syntax error(s)\n");
        LsDumpParseTree ();
        goto ErrorExit;
    }

    /* Did the parse tree get successfully constructed? */

    if (!RootNode)
    {
        /*
         * If there are no errors, then we have some sort of
         * internal problem.
         */
        AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
            NULL, "- Could not resolve parse tree root node");

        goto ErrorExit;
    }

    /* Flush out any remaining source after parse tree is complete */

    Event = UtBeginEvent ("Flush source input");
    CmFlushSourceCode ();

    /* Prune the parse tree if requested (debug purposes only) */

    if (Gbl_PruneParseTree)
    {
        AslPruneParseTree (Gbl_PruneDepth, Gbl_PruneType);
    }

    /* Optional parse tree dump, compiler debug output only */

    LsDumpParseTree ();

    OpcGetIntegerWidth (RootNode);
    UtEndEvent (Event);

    /* Pre-process parse tree for any operator transforms */

    Event = UtBeginEvent ("Parse tree transforms");
    DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n");
    TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
        TrAmlTransformWalk, NULL, NULL);
    UtEndEvent (Event);

    /* Generate AML opcodes corresponding to the parse tokens */

    Event = UtBeginEvent ("Generate AML opcodes");
    DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating AML opcodes\n\n");
    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
        OpcAmlOpcodeWalk, NULL);
    UtEndEvent (Event);

    /*
     * Now that the input is parsed, we can open the AML output file.
     * Note: by default, the name of this file comes from the table descriptor
     * within the input file.
     */
    Event = UtBeginEvent ("Open AML output file");
    Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
    UtEndEvent (Event);
    if (ACPI_FAILURE (Status))
    {
        AePrintErrorLog (ASL_FILE_STDERR);
        return (-1);
    }

    /* Interpret and generate all compile-time constants */

    Event = UtBeginEvent ("Constant folding via AML interpreter");
    DbgPrint (ASL_DEBUG_OUTPUT,
        "\nInterpreting compile-time constant expressions\n\n");

    if (Gbl_FoldConstants)
    {
        TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
            OpcAmlConstantWalk, NULL, NULL);
    }
    else
    {
        DbgPrint (ASL_PARSE_OUTPUT, "    Optional folding disabled\n");
    }
    UtEndEvent (Event);

    /* Update AML opcodes if necessary, after constant folding */

    Event = UtBeginEvent ("Updating AML opcodes after constant folding");
    DbgPrint (ASL_DEBUG_OUTPUT,
        "\nUpdating AML opcodes after constant folding\n\n");
    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
        NULL, OpcAmlOpcodeUpdateWalk, NULL);
    UtEndEvent (Event);

    /* Calculate all AML package lengths */

    Event = UtBeginEvent ("Generate AML package lengths");
    DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
        LnPackageLengthWalk, NULL);
    UtEndEvent (Event);

    if (Gbl_ParseOnlyFlag)
    {
        AePrintErrorLog (ASL_FILE_STDERR);
        UtDisplaySummary (ASL_FILE_STDERR);
        if (Gbl_DebugFlag)
        {
            /* Print error summary to the stdout also */

            AePrintErrorLog (ASL_FILE_STDOUT);
            UtDisplaySummary (ASL_FILE_STDOUT);
        }
        UtEndEvent (FullCompile);
        return (0);
    }

    /*
     * Create an internal namespace and use it as a symbol table
     */

    /* Namespace loading */

    Event = UtBeginEvent ("Create ACPI Namespace");
    Status = LdLoadNamespace (RootNode);
    UtEndEvent (Event);
    if (ACPI_FAILURE (Status))
    {
        goto ErrorExit;
    }

    /* Namespace cross-reference */

    AslGbl_NamespaceEvent = UtBeginEvent ("Cross reference parse tree and Namespace");
    Status = XfCrossReferenceNamespace ();
    if (ACPI_FAILURE (Status))
    {
        goto ErrorExit;
    }

    /* Namespace - Check for non-referenced objects */

    LkFindUnreferencedObjects ();
    UtEndEvent (AslGbl_NamespaceEvent);

    /*
     * Semantic analysis. This can happen only after the
     * namespace has been loaded and cross-referenced.
     *
     * part one - check control methods
     */
    Event = UtBeginEvent ("Analyze control method return types");
    AnalysisWalkInfo.MethodStack = NULL;

    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method analysis\n\n");
    TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE,
        MtMethodAnalysisWalkBegin,
        MtMethodAnalysisWalkEnd, &AnalysisWalkInfo);
    UtEndEvent (Event);

    /* Semantic error checking part two - typing of method returns */

    Event = UtBeginEvent ("Determine object types returned by methods");
    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Method typing\n\n");
    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
        NULL, AnMethodTypingWalkEnd, NULL);
    UtEndEvent (Event);

    /* Semantic error checking part three - operand type checking */

    Event = UtBeginEvent ("Analyze AML operand types");
    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - Operand type checking\n\n");
    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD,
        NULL, AnOperandTypecheckWalkEnd, &AnalysisWalkInfo);
    UtEndEvent (Event);

    /* Semantic error checking part four - other miscellaneous checks */

    Event = UtBeginEvent ("Miscellaneous analysis");
    DbgPrint (ASL_DEBUG_OUTPUT, "\nSemantic analysis - miscellaneous\n\n");
    TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,
        AnOtherSemanticAnalysisWalkBegin,
        NULL, &AnalysisWalkInfo);
    UtEndEvent (Event);

    /* Calculate all AML package lengths */

    Event = UtBeginEvent ("Finish AML package length generation");
    DbgPrint (ASL_DEBUG_OUTPUT, "\nGenerating Package lengths\n\n");
    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
        LnInitLengthsWalk, NULL);
    TrWalkParseTree (RootNode, ASL_WALK_VISIT_UPWARD, NULL,
        LnPackageLengthWalk, NULL);
    UtEndEvent (Event);

    /* Code generation - emit the AML */

    Event = UtBeginEvent ("Generate AML code and write output files");
    CgGenerateAmlOutput ();
    UtEndEvent (Event);

    Event = UtBeginEvent ("Write optional output files");
    CmDoOutputFiles ();
    UtEndEvent (Event);

    UtEndEvent (FullCompile);
    CmCleanupAndExit ();
    return (0);

ErrorExit:
    UtEndEvent (FullCompile);
    CmCleanupAndExit ();
    return (-1);
}