示例#1
0
#endif



typedef unsigned char byte;
typedef unsigned short int word;

#define FMT(a,b) a, b
#define PTRS_PER_FORMAT 2

static const char *arith[4] = { "*" , "*-" , "*+" , "??" } ;
static const char *nextar[4] = { ",AR0" , ",AR1" , "" , "" } ;


static const char *TMS32010Formats[] = {
	FMT("0000ssss0aaaaaaa", "add  %A%S"),
	FMT("0000ssss10mmn00n", "add  %M%S%N"),
	FMT("0001ssss0aaaaaaa", "sub  %A%S"),
	FMT("0001ssss10mmn00n", "sub  %M%S%N"),
	FMT("0010ssss0aaaaaaa", "lac  %A%S"),
	FMT("0010ssss10mmn00n", "lac  %M%S%N"),
	FMT("0011000r0aaaaaaa", "sar  %R,%A"),
	FMT("0011000r10mmn00n", "sar  %R%M%N"),
	FMT("0011100r0aaaaaaa", "lar  %R,%A"),
	FMT("0011100r10mmn00n", "lar  %R%M%N"),
	FMT("01000ppp0aaaaaaa", "in   %A,%P"),
	FMT("01000ppp10mmn00n", "in   %M,%P%N"),
	FMT("01001ppp0aaaaaaa", "out  %A,%P"),
	FMT("01001ppp10mmn00n", "out  %M,%P%N"),
	FMT("01010sss0aaaaaaa", "sacl %A"),		/* This instruction has a shift but */
	FMT("01010sss10mmn00n", "sacl %M%N"),	/* is documented as not performed */
示例#2
0


typedef unsigned char byte;
typedef unsigned short int word;

#define FMT(a,b) a, b
#define PTRS_PER_FORMAT 2

static const char *arith[8] = { "*", "*-", "*+", "??", "BR0-", "*0-", "*0+", "*BR0+" } ;
static const char *nextar[16] = { "", "", "", "", "", "", "", "", ",AR0", ",AR1", ",AR2", ",AR3", ",AR4", ",AR5", ",AR6", ",AR7" } ;
static const char *cmpmode[4] = { "0 (ARx = AR0)" , "1 (ARx < AR0)" , "2 (ARx > AR0)" , "3 (ARx <> AR0)" } ;


static const char *TMS32025Formats[] = {
	FMT("0000tttt0aaaaaaa", "add  %A,%T"),	/* 0xxx */
	FMT("0000tttt1mmmnnnn", "add  %M,%T%N"),
	FMT("0001tttt0aaaaaaa", "sub  %A,%T"),	/* 1xxx */
	FMT("0001tttt1mmmnnnn", "sub  %M,%T%N"),
	FMT("0010tttt0aaaaaaa", "lac  %A,%T"),	/* 2xxx */
	FMT("0010tttt1mmmnnnn", "lac  %M,%T%N"),
	FMT("00110rrr0aaaaaaa", "lar  %R,%A"),	/* 3xxx */
	FMT("00110rrr1mmmnnnn", "lar  %R%M%N"),
	FMT("001110000aaaaaaa", "mpy  %A"),		/* 38xx */
	FMT("001110001mmmnnnn", "mpy  %M%N"),
	FMT("001110010aaaaaaa", "sqra %A"),		/* 39xx */
	FMT("001110011mmmnnnn", "sqra %M%N"),
	FMT("001110100aaaaaaa", "mpya %A"),		/* 3Axx */
	FMT("001110101mmmnnnn", "mpya %M%N"),
	FMT("001110110aaaaaaa", "mpys %A"),		/* 3Bxx */
	FMT("001110111mmmnnnn", "mpys %M%N"),
示例#3
0
/// main!
int main(int argc, char *argv[])
{
    init_debug_list();
    ProgramParams   params(argc, argv);

    // Set up cfg values
    Cfg_SetValue("rust_compiler", "mrustc");
    Cfg_SetValueCb("feature", [&params](const ::std::string& s) {
        return params.features.count(s) != 0;
        });
    CompilePhaseV("Target Load", [&]() {
        Target_SetCfg(params.target);
        });

    if( params.target_saveback != "")
    {
        Target_ExportCurSpec(params.target_saveback);
        return 0;
    }

    if( params.infile == "" )
    {
        ::std::cerr << "No input file passed" << ::std::endl;
        return 1;
    }

    if( params.test_harness )
    {
        Cfg_SetFlag("test");
    }

    try
    {
        // Parse the crate into AST
        AST::Crate crate = CompilePhase<AST::Crate>("Parse", [&]() {
            return Parse_Crate(params.infile);
            });
        crate.m_test_harness = params.test_harness;
        crate.m_crate_name_suffix = params.crate_name_suffix;

        if( params.last_stage == ProgramParams::STAGE_PARSE ) {
            return 0;
        }

        // Load external crates.
        CompilePhaseV("LoadCrates", [&]() {
            // Hacky!
            AST::g_crate_overrides = params.crate_overrides;
            for(const auto& ld : params.lib_search_dirs)
            {
                AST::g_crate_load_dirs.push_back(ld);
            }
            crate.load_externs();
            });

        // Iterate all items in the AST, applying syntax extensions
        CompilePhaseV("Expand", [&]() {
            Expand(crate);
            });

        if( params.test_harness )
        {
            Expand_TestHarness(crate);
        }

        // Extract the crate type and name from the crate attributes
        auto crate_type = params.crate_type;
        if( crate_type == ::AST::Crate::Type::Unknown ) {
            crate_type = crate.m_crate_type;
        }
        if( crate_type == ::AST::Crate::Type::Unknown ) {
            // Assume to be executable
            crate_type = ::AST::Crate::Type::Executable;
        }
        crate.m_crate_type = crate_type;

        if( crate.m_crate_type == ::AST::Crate::Type::ProcMacro )
        {
            Expand_ProcMacro(crate);
        }

        auto crate_name = params.crate_name;
        if( crate_name == "" )
        {
            crate_name = crate.m_crate_name;
        }
        if( crate_name == "" ) {
            auto s = params.infile.find_last_of('/');
            if( s == ::std::string::npos )
                s = 0;
            else
                s += 1;
            auto e = params.infile.find_first_of('.', s);
            if( e == ::std::string::npos )
                e = params.infile.size() - s;

            crate_name = ::std::string(params.infile.begin() + s, params.infile.begin() + e);
            for(auto& b : crate_name)
            {
                if ('0' <= b && b <= '9') {
                }
                else if ('A' <= b && b <= 'Z') {
                }
                else if (b == '_') {
                }
                else if (b == '-') {
                    b = '_';
                }
                else {
                    // TODO: Error?
                }
            }
        }
        crate.m_crate_name = crate_name;
        if( params.test_harness )
        {
            crate.m_crate_name += "$test";
        }

        if( params.outfile == "" ) {
            switch( crate.m_crate_type )
            {
            case ::AST::Crate::Type::RustLib:
                params.outfile = FMT(params.output_dir << "lib" << crate.m_crate_name << ".hir");
                break;
            case ::AST::Crate::Type::Executable:
                params.outfile = FMT(params.output_dir << crate.m_crate_name);
                break;
            default:
                params.outfile = FMT(params.output_dir << crate.m_crate_name << ".o");
                break;
            }
            DEBUG("params.outfile = " << params.outfile);
        }

        if( params.debug.dump_ast )
        {
            CompilePhaseV("Dump Expanded", [&]() {
                Dump_Rust( FMT(params.outfile << "_1_ast.rs").c_str(), crate );
                });
        }

        if( params.last_stage == ProgramParams::STAGE_EXPAND ) {
            return 0;
        }

        // Allocator and panic strategies
        CompilePhaseV("Implicit Crates", [&]() {
            if( params.test_harness )
            {
                crate.load_extern_crate(Span(), "test");
            }
            if( crate.m_crate_type == ::AST::Crate::Type::Executable || params.test_harness || crate.m_crate_type == ::AST::Crate::Type::ProcMacro )
            {
                bool allocator_crate_loaded = false;
                ::std::string   alloc_crate_name;
                bool panic_runtime_loaded = false;
                ::std::string   panic_crate_name;
                bool panic_runtime_needed = false;
                for(const auto& ec : crate.m_extern_crates)
                {
                    ::std::ostringstream    ss;
                    for(const auto& e : ec.second.m_hir->m_lang_items)
                        ss << e << ",";
                    DEBUG("Looking at lang items from " << ec.first << " : " << ss.str());
                    if(ec.second.m_hir->m_lang_items.count("mrustc-allocator"))
                    {
                        if( allocator_crate_loaded ) {
                            ERROR(Span(), E0000, "Multiple allocator crates loaded - " << alloc_crate_name << " and " << ec.first);
                        }
                        alloc_crate_name = ec.first;
                        allocator_crate_loaded = true;
                    }
                    if(ec.second.m_hir->m_lang_items.count("mrustc-panic_runtime"))
                    {
                        if( panic_runtime_loaded ) {
                            ERROR(Span(), E0000, "Multiple panic_runtime crates loaded - " << panic_crate_name << " and " << ec.first);
                        }
                        panic_crate_name = ec.first;
                        panic_runtime_loaded = true;
                    }
                    if(ec.second.m_hir->m_lang_items.count("mrustc-needs_panic_runtime"))
                    {
                        panic_runtime_needed = true;
                    }
                }
                if( !allocator_crate_loaded )
                {
                    crate.load_extern_crate(Span(), "alloc_system");
                }

                if( panic_runtime_needed && !panic_runtime_loaded )
                {
                    // TODO: Get a panic method from the command line
                    // - Fall back to abort by default, because mrustc doesn't do unwinding yet.
                    crate.load_extern_crate(Span(), "panic_abort");
                }

                // - `mrustc-main` lang item default
                crate.m_lang_items.insert(::std::make_pair( ::std::string("mrustc-main"), ::AST::Path("", {AST::PathNode("main")}) ));
            }
            });

        if( params.emit_depfile != "" )
        {
            ::std::ofstream of { params.emit_depfile };
            of << params.outfile << ":";
            // - Iterate all loaded files for modules
            struct H {
                ::std::ofstream& of;
                H(::std::ofstream& of): of(of) {}
                void visit_module(::AST::Module& mod) {
                    if( mod.m_file_info.path != "!" && mod.m_file_info.path.back() != '/' ) {
                        of << " " << mod.m_file_info.path;
                    }
                    // TODO: Should we check anon modules?
                    //for(auto& amod : mod.anon_mods()) {
                    //    this->visit_module(*amod);
                    //}
                    for(auto& i : mod.items()) {
                        if(i.data.is_Module()) {
                            this->visit_module(i.data.as_Module());
                        }
                    }
                }
            };
            H(of).visit_module(crate.m_root_module);
            // - Iterate all loaded crates files
            for(const auto& ec : crate.m_extern_crates)
            {
                of << " " << ec.second.m_filename;
            }
            // - Iterate all extra files (include! and friends)
        }

        // Resolve names to be absolute names (include references to the relevant struct/global/function)
        // - This does name checking on types and free functions.
        // - Resolves all identifiers/paths to references
        CompilePhaseV("Resolve Use", [&]() {
            Resolve_Use(crate); // - Absolutise and resolve use statements
            });
        CompilePhaseV("Resolve Index", [&]() {
            Resolve_Index(crate); // - Build up a per-module index of avalable names (faster and simpler later resolve)
            });
        CompilePhaseV("Resolve Absolute", [&]() {
            Resolve_Absolutise(crate);  // - Convert all paths to Absolute or UFCS, and resolve variables
            });

        if( params.debug.dump_ast )
        {
            CompilePhaseV("Temp output - Resolved", [&]() {
                Dump_Rust( FMT(params.outfile << "_1_ast.rs").c_str(), crate );
                });
        }

        if( params.last_stage == ProgramParams::STAGE_RESOLVE ) {
            return 0;
        }

        // --------------------------------------
        // HIR Section
        // --------------------------------------
        // Construc the HIR from the AST
        ::HIR::CratePtr hir_crate = CompilePhase< ::HIR::CratePtr>("HIR Lower", [&]() {
            return LowerHIR_FromAST(mv$( crate ));
            });
        // Deallocate the original crate
        crate = ::AST::Crate();

        // Replace type aliases (`type`) into the actual type
        // - Also inserts defaults in trait impls
        CompilePhaseV("Resolve Type Aliases", [&]() {
            ConvertHIR_ExpandAliases(*hir_crate);
            });
        // Set up bindings and other useful information.
        CompilePhaseV("Resolve Bind", [&]() {
            ConvertHIR_Bind(*hir_crate);
            });
        // Enumerate marker impls on types and other useful metadata
        CompilePhaseV("Resolve HIR Markings", [&]() {
            ConvertHIR_Markings(*hir_crate);
            });
        // Determine what trait to use for <T>::Foo (and does some associated type expansion)
        CompilePhaseV("Resolve UFCS paths", [&]() {
            ConvertHIR_ResolveUFCS(*hir_crate);
            });
        // Basic constant evalulation (intergers/floats only)
        CompilePhaseV("Constant Evaluate", [&]() {
            ConvertHIR_ConstantEvaluate(*hir_crate);
            });

        if( params.debug.dump_hir )
        {
            // DUMP after initial consteval
            CompilePhaseV("Dump HIR", [&]() {
                ::std::ofstream os (FMT(params.outfile << "_2_hir.rs"));
                HIR_Dump( os, *hir_crate );
                });
        }

        // === Type checking ===
        // - This can recurse and call the MIR lower to evaluate constants

        // Check outer items first (types of constants/functions/statics/impls/...)
        // - Doesn't do any expressions except those in types
        CompilePhaseV("Typecheck Outer", [&]() {
            Typecheck_ModuleLevel(*hir_crate);
            });
        // Check the rest of the expressions (including function bodies)
        CompilePhaseV("Typecheck Expressions", [&]() {
            Typecheck_Expressions(*hir_crate);
            });
        // === HIR Expansion ===
        // Annotate how each node's result is used
        CompilePhaseV("Expand HIR Annotate", [&]() {
            HIR_Expand_AnnotateUsage(*hir_crate);
            });
        // - Now that all types are known, closures can be desugared
        CompilePhaseV("Expand HIR Closures", [&]() {
            HIR_Expand_Closures(*hir_crate);
            });
        // - Construct VTables for all traits and impls.
        //  TODO: How early can this be done?
        CompilePhaseV("Expand HIR VTables", [&]() {
            HIR_Expand_VTables(*hir_crate);
            });
        // - And calls can be turned into UFCS
        CompilePhaseV("Expand HIR Calls", [&]() {
            HIR_Expand_UfcsEverything(*hir_crate);
            });
        CompilePhaseV("Expand HIR Reborrows", [&]() {
            HIR_Expand_Reborrows(*hir_crate);
            });
        CompilePhaseV("Expand HIR ErasedType", [&]() {
            HIR_Expand_ErasedType(*hir_crate);
            });
        if( params.debug.dump_hir )
        {
            // DUMP after typecheck (before validation)
            CompilePhaseV("Dump HIR", [&]() {
                ::std::ofstream os (FMT(params.outfile << "_2_hir.rs"));
                HIR_Dump( os, *hir_crate );
                });
        }
        // - Ensure that typeck worked (including Fn trait call insertion etc)
        CompilePhaseV("Typecheck Expressions (validate)", [&]() {
            Typecheck_Expressions_Validate(*hir_crate);
            });

        if( params.last_stage == ProgramParams::STAGE_TYPECK ) {
            return 0;
        }

        // Lower expressions into MIR
        CompilePhaseV("Lower MIR", [&]() {
            HIR_GenerateMIR(*hir_crate);
            });

        if( params.debug.dump_mir )
        {
            // DUMP after generation
            CompilePhaseV("Dump MIR", [&]() {
                ::std::ofstream os (FMT(params.outfile << "_3_mir.rs"));
                MIR_Dump( os, *hir_crate );
                });
        }

        // Validate the MIR
        CompilePhaseV("MIR Validate", [&]() {
            MIR_CheckCrate(*hir_crate);
            });

        if( params.debug.dump_hir )
        {
            // DUMP after consteval (full HIR again)
            CompilePhaseV("Dump HIR", [&]() {
                ::std::ofstream os (FMT(params.outfile << "_2_hir.rs"));
                HIR_Dump( os, *hir_crate );
                });
        }

        // - Expand constants in HIR and virtualise calls
        CompilePhaseV("MIR Cleanup", [&]() {
            MIR_CleanupCrate(*hir_crate);
            });
        if( params.debug.full_validate_early || getenv("MRUSTC_FULL_VALIDATE_PREOPT") )
        {
            CompilePhaseV("MIR Validate Full Early", [&]() {
                MIR_CheckCrate_Full(*hir_crate);
                });
        }

        // Optimise the MIR
        CompilePhaseV("MIR Optimise", [&]() {
            MIR_OptimiseCrate(*hir_crate, params.debug.disable_mir_optimisations);
            });

        if( params.debug.dump_mir )
        {
            // DUMP: After optimisation
            CompilePhaseV("Dump MIR", [&]() {
                ::std::ofstream os (FMT(params.outfile << "_3_mir.rs"));
                MIR_Dump( os, *hir_crate );
                });
        }
        CompilePhaseV("MIR Validate PO", [&]() {
            MIR_CheckCrate(*hir_crate);
            });
        // - Exhaustive MIR validation (follows every code path and checks variable validity)
        // > DEBUGGING ONLY
        CompilePhaseV("MIR Validate Full", [&]() {
            if( params.debug.full_validate || getenv("MRUSTC_FULL_VALIDATE") )
                MIR_CheckCrate_Full(*hir_crate);
            });

        if( params.last_stage == ProgramParams::STAGE_MIR ) {
            return 0;
        }

        // TODO: Pass to mark items that are..
        // - Signature Exportable (public)
        // - MIR Exportable (public generic, #[inline], or used by a either of those)
        // - Require codegen (public or used by an exported function)
        TransOptions    trans_opt;
        trans_opt.mode = params.codegen.codegen_type == "" ? "c" : params.codegen.codegen_type;
        trans_opt.build_command_file = params.codegen.emit_build_command;
        trans_opt.opt_level = params.opt_level;
        for(const char* libdir : params.lib_search_dirs ) {
            // Store these paths for use in final linking.
            hir_crate->m_link_paths.push_back( libdir );
        }
        for(const char* libname : params.libraries ) {
            hir_crate->m_ext_libs.push_back(::HIR::ExternLibrary { libname });
        }
        trans_opt.emit_debug_info = params.emit_debug_info;

        // Generate code for non-generic public items (if requested)
        if( params.test_harness )
        {
            // If the test harness is enabled, override crate type to "Executable"
            crate_type = ::AST::Crate::Type::Executable;
        }

        // Enumerate items to be passed to codegen
        TransList items = CompilePhase<TransList>("Trans Enumerate", [&]() {
            switch( crate_type )
            {
            case ::AST::Crate::Type::Unknown:
                ::std::cerr << "BUG? Unknown crate type" << ::std::endl;
                exit(1);
                break;
            case ::AST::Crate::Type::RustLib:
            case ::AST::Crate::Type::RustDylib:
            case ::AST::Crate::Type::CDylib:
                return Trans_Enumerate_Public(*hir_crate);
            case ::AST::Crate::Type::ProcMacro:
                // TODO: proc macros enumerate twice, once as a library (why?) and again as an executable
                return Trans_Enumerate_Public(*hir_crate);
            case ::AST::Crate::Type::Executable:
                return Trans_Enumerate_Main(*hir_crate);
            }
            throw ::std::runtime_error("Invalid crate_type value");
            });
        // - Generate monomorphised versions of all functions
        CompilePhaseV("Trans Monomorph", [&]() { Trans_Monomorphise_List(*hir_crate, items); });
        // - Do post-monomorph inlining
        CompilePhaseV("MIR Optimise Inline", [&]() { MIR_OptimiseCrate_Inlining(*hir_crate, items); });
        // - Clean up no-unused functions
        //CompilePhaseV("Trans Enumerate Cleanup", [&]() { Trans_Enumerate_Cleanup(*hir_crate, items); });

        switch(crate_type)
        {
        case ::AST::Crate::Type::Unknown:
            throw "";
        case ::AST::Crate::Type::RustLib:
            // Generate a loadable .o
            CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile + ".o", trans_opt, *hir_crate, items, /*is_executable=*/false); });
            // Save a loadable HIR dump
            CompilePhaseV("HIR Serialise", [&]() { HIR_Serialise(params.outfile, *hir_crate); });
            // TODO: Link metatdata and object into a .rlib
            //Trans_Link(params.outfile, params.outfile + ".hir", params.outfile + ".o", CodegenOutput::StaticLibrary);
            break;
        case ::AST::Crate::Type::RustDylib:
            // Generate a .so
            //CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile + ".so", trans_opt, *hir_crate, items, CodegenOutput::DynamicLibrary); });
            CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile + ".o", trans_opt, *hir_crate, items, /*is_executable=*/false); });
            // Save a loadable HIR dump
            CompilePhaseV("HIR Serialise", [&]() { HIR_Serialise(params.outfile, *hir_crate); });
            // TODO: Add the metadata to the .so as a non-loadable segment
            //Trans_Link(params.outfile, params.outfile + ".hir", params.outfile + ".o", CodegenOutput::DynamicLibrary);
            break;
        case ::AST::Crate::Type::CDylib:
            // Generate a .so/.dll
            CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile, trans_opt, *hir_crate, items, /*is_executable=*/false); });
            // - No metadata file
            //Trans_Link(params.outfile, "", params.outfile + ".o", CodegenOutput::DynamicLibrary);
            break;
        case ::AST::Crate::Type::ProcMacro: {
            // Needs: An executable (the actual macro handler), metadata (for `extern crate foo;`)

            // 1. Generate code for the .o file
            // TODO: Is the .o actually needed for proc macros?
            CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile + ".o", trans_opt, *hir_crate, items, /*is_executable=*/false); });

            // 2. Generate code for the plugin itself
            TransList items2 = CompilePhase<TransList>("Trans Enumerate", [&]() { return Trans_Enumerate_Main(*hir_crate); });
            CompilePhaseV("Trans Monomorph", [&]() { Trans_Monomorphise_List(*hir_crate, items2); });
            CompilePhaseV("MIR Optimise Inline", [&]() { MIR_OptimiseCrate_Inlining(*hir_crate, items2); });
            CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile + "-plugin", trans_opt, *hir_crate, items2, /*is_executable=*/true); });

            // - Save a very basic HIR dump, making sure that there's no lang items in it (e.g. `mrustc-main`)
            hir_crate->m_lang_items.clear();
            CompilePhaseV("HIR Serialise", [&]() { HIR_Serialise(params.outfile, *hir_crate); });
            //Trans_Link(params.outfile, params.outfile + ".hir", params.outfile + ".o", CodegenOutput::StaticLibrary);
            //Trans_Link(params.outfile+"-plugin", "", params.outfile + "-plugin.o", CodegenOutput::StaticLibrary);
            break; }
        case ::AST::Crate::Type::Executable:
            CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile, trans_opt, *hir_crate, items, /*is_executable=*/true); });
            //Trans_Link(params.outfile, "", params.outfile + ".o", CodegenOutput::Executable);
            break;
        }
    }
    catch(unsigned int) {}
    //catch(const CompileError::Base& e)
    //{
    //    ::std::cerr << "Parser Error: " << e.what() << ::std::endl;
    //    return 2;
    //}
    //catch(const ::std::exception& e)
    //{
    //    ::std::cerr << "Misc Error: " << e.what() << ::std::endl;
    //    return 2;
    //}
    //catch(const char* e)
    //{
    //    ::std::cerr << "Internal Compiler Error: " << e << ::std::endl;
    //    return 2;
    //}

    return 0;
}
示例#4
0
/* Registers bank 0/1 */
static const char *const regfile[32] = { "Reg$00 (INDF)",    "Reg$01 (TMR0/OPTION)",    "Reg$02 (PCL)",  "Reg$03 (STATUS)", "Reg$04 (FSR)", "Reg$05 (PORTA/TRISA)", "Reg$06 (PORTB/TRISB)", "Reg$07",
									"Reg$08", "Reg$09", "Reg$0A (PCLATH)", "Reg$0B (INTCON)", "Reg$0C (PIR1/PIE1)", "Reg$0D", "Reg$0E (none/PCON)", "Reg$0F",
									"Reg$10", "Reg$11", "Reg$12", "Reg$13", "Reg$14", "Reg$15", "Reg$16", "Reg$17",
									"Reg$18", "Reg$19", "Reg$1A", "Reg$1B", "Reg$1C", "Reg$1D", "Reg$1E", "Reg$1F (CMCON/VRCON)" };
/* Registers bank 1 */
/*static const char *const regfile1[32] = { "Reg$00 (INDF)",    "Reg$01 (OPTION)",    "Reg$02 (PCL)",  "Reg$03 (STATUS)", "Reg$04 (FSR)", "Reg$05 (TRISA)", "Reg$06 (TRISB)", "Reg$07",
                                 "Reg$08", "Reg$09", "Reg$0A (PCLATH)", "Reg$0B (INTCON)", "Reg$0C (PIE1)", "Reg$0D", "Reg$0E (PCON)", "Reg$0F",
                                 "Reg$10", "Reg$11", "Reg$12", "Reg$13", "Reg$14", "Reg$15", "Reg$16", "Reg$17",
                                 "Reg$18", "Reg$19", "Reg$1A", "Reg$1B", "Reg$1C", "Reg$1D", "Reg$1E", "Reg$1F (VRCON)" };
static const char **regfile[2] = { regfile0, regfile1 };*/

static const char *const dest[2] = { "W", "Reg" };

static const char *const PIC16C62xFormats[] = {
	FMT("0000000xx00000", "nop"),
	FMT("00000000001000", "return"),
	FMT("00000000001001", "retfie"),
	FMT("00000001100011", "sleep"),
	FMT("00000001100100", "clrwdt"),
	FMT("0000001fffffff", "movwf  %F"),
	FMT("00000100000011", "clrw"),
	FMT("0000011fffffff", "clrf   %F"),
	FMT("000010dfffffff", "subwf  %F,%D"),
	FMT("000011dfffffff", "decf   %F,%D"),
	FMT("000100dfffffff", "iorwf  %F,%D"),
	FMT("000101dfffffff", "andwf  %F,%D"),
	FMT("000110dfffffff", "xorwf  %F,%D"),
	FMT("000111dfffffff", "addwf  %F,%D"),
	FMT("001000dfffffff", "movf   %F,%D"),
	FMT("001001dfffffff", "comf   %F,%D"),
		.bpc_a = BPC ## a ## A,                          \
		.bpc_r = BPC ## r,                               \
		.bpc_g = BPC ## g,                               \
		.bpc_b = BPC ## b,                               \
		.unpack = { e0, e1, e2, e3 },                    \
		.alpha_enable = alpha,                           \
		.unpack_tight = tight,                           \
		.cpp = c,                                        \
		.unpack_count = cnt,                             \
	}

#define BPC0A 0

static const struct mdp4_format formats[] = {
	/*  name      a  r  g  b   e0 e1 e2 e3  alpha   tight  cpp cnt */
	FMT(ARGB8888, 8, 8, 8, 8,  1, 0, 2, 3,  true,   true,  4,  4),
	FMT(XRGB8888, 8, 8, 8, 8,  1, 0, 2, 3,  false,  true,  4,  4),
	FMT(RGB888,   0, 8, 8, 8,  1, 0, 2, 0,  false,  true,  3,  3),
	FMT(BGR888,   0, 8, 8, 8,  2, 0, 1, 0,  false,  true,  3,  3),
	FMT(RGB565,   0, 5, 6, 5,  1, 0, 2, 0,  false,  true,  2,  3),
	FMT(BGR565,   0, 5, 6, 5,  2, 0, 1, 0,  false,  true,  2,  3),
};

uint32_t mdp4_get_formats(enum mdp4_pipe pipe_id, uint32_t *pixel_formats,
		uint32_t max_formats)
{
	uint32_t i;
	for (i = 0; i < ARRAY_SIZE(formats); i++) {
		const struct mdp4_format *f = &formats[i];

		if (i == max_formats)