14e98e3e1Schristos /* The IGEN simulator generator for GDB, the GNU Debugger. 24e98e3e1Schristos 3*71f62182Schristos Copyright 2002-2024 Free Software Foundation, Inc. 44e98e3e1Schristos 54e98e3e1Schristos Contributed by Andrew Cagney. 64e98e3e1Schristos 74e98e3e1Schristos This file is part of GDB. 84e98e3e1Schristos 94e98e3e1Schristos This program is free software; you can redistribute it and/or modify 104e98e3e1Schristos it under the terms of the GNU General Public License as published by 114e98e3e1Schristos the Free Software Foundation; either version 3 of the License, or 124e98e3e1Schristos (at your option) any later version. 134e98e3e1Schristos 144e98e3e1Schristos This program is distributed in the hope that it will be useful, 154e98e3e1Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 164e98e3e1Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 174e98e3e1Schristos GNU General Public License for more details. 184e98e3e1Schristos 194e98e3e1Schristos You should have received a copy of the GNU General Public License 204e98e3e1Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 214e98e3e1Schristos 224e98e3e1Schristos #include "misc.h" 234e98e3e1Schristos #include "lf.h" 244e98e3e1Schristos #include "table.h" 254e98e3e1Schristos #include "filter.h" 264e98e3e1Schristos 274e98e3e1Schristos #include "igen.h" 284e98e3e1Schristos 294e98e3e1Schristos #include "ld-insn.h" 304e98e3e1Schristos #include "ld-decode.h" 314e98e3e1Schristos 324e98e3e1Schristos #include "gen.h" 334e98e3e1Schristos 344e98e3e1Schristos #include "gen-idecode.h" 354e98e3e1Schristos #include "gen-engine.h" 364e98e3e1Schristos #include "gen-icache.h" 374e98e3e1Schristos #include "gen-semantics.h" 384e98e3e1Schristos 394e98e3e1Schristos 404e98e3e1Schristos static void 414e98e3e1Schristos print_engine_issue_prefix_hook (lf *file) 424e98e3e1Schristos { 434e98e3e1Schristos lf_printf (file, "\n"); 444e98e3e1Schristos lf_indent_suppress (file); 454e98e3e1Schristos lf_printf (file, "#if defined (ENGINE_ISSUE_PREFIX_HOOK)\n"); 464e98e3e1Schristos lf_printf (file, "ENGINE_ISSUE_PREFIX_HOOK();\n"); 474e98e3e1Schristos lf_indent_suppress (file); 484e98e3e1Schristos lf_printf (file, "#endif\n"); 494e98e3e1Schristos lf_printf (file, "\n"); 504e98e3e1Schristos } 514e98e3e1Schristos 524e98e3e1Schristos static void 534e98e3e1Schristos print_engine_issue_postfix_hook (lf *file) 544e98e3e1Schristos { 554e98e3e1Schristos lf_printf (file, "\n"); 564e98e3e1Schristos lf_indent_suppress (file); 574e98e3e1Schristos lf_printf (file, "#if defined (ENGINE_ISSUE_POSTFIX_HOOK)\n"); 584e98e3e1Schristos lf_printf (file, "ENGINE_ISSUE_POSTFIX_HOOK();\n"); 594e98e3e1Schristos lf_indent_suppress (file); 604e98e3e1Schristos lf_printf (file, "#endif\n"); 614e98e3e1Schristos lf_printf (file, "\n"); 624e98e3e1Schristos } 634e98e3e1Schristos 644e98e3e1Schristos 654e98e3e1Schristos static void 664b169a6bSchristos print_run_body (lf *file, const gen_entry *table) 674e98e3e1Schristos { 684e98e3e1Schristos /* Output the function to execute real code: 694e98e3e1Schristos 704e98e3e1Schristos Unfortunatly, there are multiple cases to consider vis: 714e98e3e1Schristos 724e98e3e1Schristos <icache> X <smp> 734e98e3e1Schristos 744e98e3e1Schristos Consequently this function is written in multiple different ways */ 754e98e3e1Schristos 764e98e3e1Schristos lf_printf (file, "{\n"); 774e98e3e1Schristos lf_indent (file, +2); 784e98e3e1Schristos if (!options.gen.smp) 794e98e3e1Schristos { 804e98e3e1Schristos lf_printf (file, "%sinstruction_address cia;\n", 814e98e3e1Schristos options.module.global.prefix.l); 824e98e3e1Schristos } 834e98e3e1Schristos lf_printf (file, "int current_cpu = next_cpu_nr;\n"); 844e98e3e1Schristos 854e98e3e1Schristos if (options.gen.icache) 864e98e3e1Schristos { 874e98e3e1Schristos lf_printf (file, "/* flush the icache of a possible break insn */\n"); 884e98e3e1Schristos lf_printf (file, "{\n"); 894e98e3e1Schristos lf_printf (file, " int cpu_nr;\n"); 904e98e3e1Schristos lf_printf (file, " for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n"); 914e98e3e1Schristos lf_printf (file, " cpu_flush_icache (STATE_CPU (sd, cpu_nr));\n"); 924e98e3e1Schristos lf_printf (file, "}\n"); 934e98e3e1Schristos } 944e98e3e1Schristos 954e98e3e1Schristos if (!options.gen.smp) 964e98e3e1Schristos { 974e98e3e1Schristos 984e98e3e1Schristos lf_putstr (file, "\ 994e98e3e1Schristos /* CASE 1: NO SMP (with or with out instruction cache).\n\ 1004e98e3e1Schristos \n\ 1014e98e3e1Schristos In this case, we can take advantage of the fact that the current\n\ 1024e98e3e1Schristos instruction address (CIA) does not need to be read from / written to\n\ 1034e98e3e1Schristos the CPU object after the execution of an instruction.\n\ 1044e98e3e1Schristos \n\ 1054e98e3e1Schristos Instead, CIA is only saved when the main loop exits. This occures\n\ 1064e98e3e1Schristos when either sim_engine_halt or sim_engine_restart is called. Both of\n\ 1074e98e3e1Schristos these functions save the current instruction address before halting /\n\ 1084e98e3e1Schristos restarting the simulator.\n\ 1094e98e3e1Schristos \n\ 1104e98e3e1Schristos As a variation, there may also be support for an instruction cracking\n\ 1114e98e3e1Schristos cache. */\n\ 1124e98e3e1Schristos \n\ 1134e98e3e1Schristos "); 1144e98e3e1Schristos 1154e98e3e1Schristos lf_putstr (file, "\n"); 1164e98e3e1Schristos lf_putstr (file, "/* prime the main loop */\n"); 1174e98e3e1Schristos lf_putstr (file, "SIM_ASSERT (current_cpu == 0);\n"); 1184e98e3e1Schristos lf_putstr (file, "SIM_ASSERT (nr_cpus == 1);\n"); 119212397c6Schristos lf_putstr (file, "cia = CPU_PC_GET (CPU);\n"); 1204e98e3e1Schristos 1214e98e3e1Schristos lf_putstr (file, "\n"); 1224e98e3e1Schristos lf_putstr (file, "while (1)\n"); 1234e98e3e1Schristos lf_putstr (file, " {\n"); 1244e98e3e1Schristos lf_indent (file, +4); 1254e98e3e1Schristos 1264e98e3e1Schristos lf_printf (file, "%sinstruction_address nia;\n", 1274e98e3e1Schristos options.module.global.prefix.l); 1284e98e3e1Schristos 1294e98e3e1Schristos lf_printf (file, "\n"); 1304e98e3e1Schristos if (!options.gen.icache) 1314e98e3e1Schristos { 1324e98e3e1Schristos lf_printf (file, 1334e98e3e1Schristos "%sinstruction_word instruction_0 = IMEM%d (cia);\n", 1344e98e3e1Schristos options.module.global.prefix.l, options.insn_bit_size); 1354e98e3e1Schristos print_engine_issue_prefix_hook (file); 1364e98e3e1Schristos print_idecode_body (file, table, "nia = "); 1374e98e3e1Schristos print_engine_issue_postfix_hook (file); 1384e98e3e1Schristos } 1394e98e3e1Schristos else 1404e98e3e1Schristos { 1414e98e3e1Schristos lf_putstr (file, "idecode_cache *cache_entry =\n"); 1424e98e3e1Schristos lf_putstr (file, " cpu_icache_entry (cpu, cia);\n"); 1434e98e3e1Schristos lf_putstr (file, "if (cache_entry->address == cia)\n"); 1444e98e3e1Schristos lf_putstr (file, " {\n"); 1454e98e3e1Schristos lf_indent (file, -4); 1464e98e3e1Schristos lf_putstr (file, "/* cache hit */\n"); 1474e98e3e1Schristos lf_putstr (file, 1484e98e3e1Schristos "idecode_semantic *const semantic = cache_entry->semantic;\n"); 1494e98e3e1Schristos lf_putstr (file, "cia = semantic (cpu, cache_entry, cia);\n"); 1504e98e3e1Schristos /* tail */ 1514e98e3e1Schristos lf_indent (file, -4); 1524e98e3e1Schristos lf_putstr (file, " }\n"); 1534e98e3e1Schristos lf_putstr (file, "else\n"); 1544e98e3e1Schristos lf_putstr (file, " {\n"); 1554e98e3e1Schristos lf_indent (file, +4); 1564e98e3e1Schristos lf_putstr (file, "/* cache miss */\n"); 1574e98e3e1Schristos if (!options.gen.semantic_icache) 1584e98e3e1Schristos { 1594e98e3e1Schristos lf_putstr (file, "idecode_semantic *semantic;\n"); 1604e98e3e1Schristos } 1614e98e3e1Schristos lf_printf (file, "instruction_word instruction = IMEM%d (cia);\n", 1624e98e3e1Schristos options.insn_bit_size); 1634e98e3e1Schristos lf_putstr (file, "if (WITH_MON != 0)\n"); 1644e98e3e1Schristos lf_putstr (file, 1654e98e3e1Schristos " mon_event (mon_event_icache_miss, cpu, cia);\n"); 1664e98e3e1Schristos if (options.gen.semantic_icache) 1674e98e3e1Schristos { 1684e98e3e1Schristos lf_putstr (file, "{\n"); 1694e98e3e1Schristos lf_indent (file, +2); 1704e98e3e1Schristos print_engine_issue_prefix_hook (file); 1714e98e3e1Schristos print_idecode_body (file, table, "nia ="); 1724e98e3e1Schristos print_engine_issue_postfix_hook (file); 1734e98e3e1Schristos lf_indent (file, -2); 1744e98e3e1Schristos lf_putstr (file, "}\n"); 1754e98e3e1Schristos } 1764e98e3e1Schristos else 1774e98e3e1Schristos { 1784e98e3e1Schristos print_engine_issue_prefix_hook (file); 1794e98e3e1Schristos print_idecode_body (file, table, "semantic ="); 1804e98e3e1Schristos lf_putstr (file, "nia = semantic (cpu, cache_entry, cia);\n"); 1814e98e3e1Schristos print_engine_issue_postfix_hook (file); 1824e98e3e1Schristos } 1834e98e3e1Schristos lf_indent (file, -4); 1844e98e3e1Schristos lf_putstr (file, " }\n"); 1854e98e3e1Schristos } 1864e98e3e1Schristos 1874e98e3e1Schristos /* update the cpu if necessary */ 1884e98e3e1Schristos switch (options.gen.nia) 1894e98e3e1Schristos { 1904e98e3e1Schristos case nia_is_cia_plus_one: 1914e98e3e1Schristos lf_printf (file, "\n"); 1924e98e3e1Schristos lf_printf (file, "/* Update the instruction address */\n"); 1934e98e3e1Schristos lf_printf (file, "cia = nia;\n"); 1944e98e3e1Schristos break; 1954e98e3e1Schristos case nia_is_void: 1964e98e3e1Schristos case nia_is_invalid: 1974e98e3e1Schristos ERROR ("engine gen when NIA complex"); 1984e98e3e1Schristos } 1994e98e3e1Schristos 2004e98e3e1Schristos /* events */ 2014e98e3e1Schristos lf_putstr (file, "\n"); 2024e98e3e1Schristos lf_putstr (file, "/* process any events */\n"); 2034e98e3e1Schristos lf_putstr (file, "if (sim_events_tick (sd))\n"); 2044e98e3e1Schristos lf_putstr (file, " {\n"); 205212397c6Schristos lf_putstr (file, " CPU_PC_SET (CPU, cia);\n"); 2064e98e3e1Schristos lf_putstr (file, " sim_events_process (sd);\n"); 207212397c6Schristos lf_putstr (file, " cia = CPU_PC_GET (CPU);\n"); 2084e98e3e1Schristos lf_putstr (file, " }\n"); 2094e98e3e1Schristos 2104e98e3e1Schristos lf_indent (file, -4); 2114e98e3e1Schristos lf_printf (file, " }\n"); 2124e98e3e1Schristos } 2134e98e3e1Schristos 2144e98e3e1Schristos if (options.gen.smp) 2154e98e3e1Schristos { 2164e98e3e1Schristos 2174e98e3e1Schristos lf_putstr (file, "\ 2184e98e3e1Schristos /* CASE 2: SMP (With or without ICACHE)\n\ 2194e98e3e1Schristos \n\ 2204e98e3e1Schristos The complexity here comes from needing to correctly halt the simulator\n\ 2214e98e3e1Schristos when it is aborted. For instance, if cpu0 requests a restart then\n\ 2224e98e3e1Schristos cpu1 will normally be the next cpu that is run. Cpu0 being restarted\n\ 2234e98e3e1Schristos after all the other CPU's and the event queue have been processed */\n\ 2244e98e3e1Schristos \n\ 2254e98e3e1Schristos "); 2264e98e3e1Schristos 2274e98e3e1Schristos lf_putstr (file, "\n"); 2284e98e3e1Schristos lf_printf (file, 2294e98e3e1Schristos "/* have ensured that the event queue is NOT next */\n"); 2304e98e3e1Schristos lf_printf (file, "SIM_ASSERT (current_cpu >= 0);\n"); 2314e98e3e1Schristos lf_printf (file, "SIM_ASSERT (current_cpu <= nr_cpus - 1);\n"); 2324e98e3e1Schristos lf_printf (file, "SIM_ASSERT (nr_cpus <= MAX_NR_PROCESSORS);\n"); 2334e98e3e1Schristos 2344e98e3e1Schristos lf_putstr (file, "\n"); 2354e98e3e1Schristos lf_putstr (file, "while (1)\n"); 2364e98e3e1Schristos lf_putstr (file, " {\n"); 2374e98e3e1Schristos lf_indent (file, +4); 2384e98e3e1Schristos lf_putstr (file, "sim_cpu *cpu = STATE_CPU (sd, current_cpu);\n"); 239212397c6Schristos lf_putstr (file, "instruction_address cia = CPU_PC_GET (cpu);\n"); 2404e98e3e1Schristos lf_putstr (file, "\n"); 2414e98e3e1Schristos 2424e98e3e1Schristos if (!options.gen.icache) 2434e98e3e1Schristos { 2444e98e3e1Schristos lf_printf (file, "instruction_word instruction_0 = IMEM%d (cia);\n", 2454e98e3e1Schristos options.insn_bit_size); 2464e98e3e1Schristos print_engine_issue_prefix_hook (file); 2474e98e3e1Schristos print_idecode_body (file, table, "cia ="); 248212397c6Schristos lf_putstr (file, "CPU_PC_SET (cpu, cia);\n"); 2494e98e3e1Schristos print_engine_issue_postfix_hook (file); 2504e98e3e1Schristos } 2514e98e3e1Schristos 2524e98e3e1Schristos if (options.gen.icache) 2534e98e3e1Schristos { 2544e98e3e1Schristos lf_putstr (file, "engine_cache *cache_entry =\n"); 2554e98e3e1Schristos lf_putstr (file, " cpu_icache_entry(processor, cia);\n"); 2564e98e3e1Schristos lf_putstr (file, "\n"); 2574e98e3e1Schristos lf_putstr (file, "if (cache_entry->address == cia) {\n"); 2584e98e3e1Schristos { 2594e98e3e1Schristos lf_indent (file, +2); 2604e98e3e1Schristos lf_putstr (file, "\n"); 2614e98e3e1Schristos lf_putstr (file, "/* cache hit */\n"); 2624e98e3e1Schristos lf_putstr (file, 2634e98e3e1Schristos "engine_semantic *semantic = cache_entry->semantic;\n"); 2644e98e3e1Schristos lf_putstr (file, 2654e98e3e1Schristos "cia = semantic(processor, cache_entry, cia);\n"); 2664e98e3e1Schristos /* tail */ 2674e98e3e1Schristos lf_putstr (file, "cpu_set_program_counter(processor, cia);\n"); 2684e98e3e1Schristos lf_putstr (file, "\n"); 2694e98e3e1Schristos lf_indent (file, -2); 2704e98e3e1Schristos } 2714e98e3e1Schristos lf_putstr (file, "}\n"); 2724e98e3e1Schristos lf_putstr (file, "else {\n"); 2734e98e3e1Schristos { 2744e98e3e1Schristos lf_indent (file, +2); 2754e98e3e1Schristos lf_putstr (file, "\n"); 2764e98e3e1Schristos lf_putstr (file, "/* cache miss */\n"); 2774e98e3e1Schristos if (!options.gen.semantic_icache) 2784e98e3e1Schristos { 2794e98e3e1Schristos lf_putstr (file, "engine_semantic *semantic;\n"); 2804e98e3e1Schristos } 2814e98e3e1Schristos lf_printf (file, "instruction_word instruction = IMEM%d (cia);\n", 2824e98e3e1Schristos options.insn_bit_size); 2834e98e3e1Schristos lf_putstr (file, "if (WITH_MON != 0)\n"); 2844e98e3e1Schristos lf_putstr (file, 2854e98e3e1Schristos " mon_event(mon_event_icache_miss, processors[current_cpu], cia);\n"); 2864e98e3e1Schristos if (options.gen.semantic_icache) 2874e98e3e1Schristos { 2884e98e3e1Schristos lf_putstr (file, "{\n"); 2894e98e3e1Schristos lf_indent (file, +2); 2904e98e3e1Schristos print_engine_issue_prefix_hook (file); 2914e98e3e1Schristos print_idecode_body (file, table, "cia ="); 2924e98e3e1Schristos print_engine_issue_postfix_hook (file); 2934e98e3e1Schristos lf_indent (file, -2); 2944e98e3e1Schristos lf_putstr (file, "}\n"); 2954e98e3e1Schristos } 2964e98e3e1Schristos else 2974e98e3e1Schristos { 2984e98e3e1Schristos print_engine_issue_prefix_hook (file); 2994e98e3e1Schristos print_idecode_body (file, table, "semantic = "); 3004e98e3e1Schristos lf_putstr (file, 3014e98e3e1Schristos "cia = semantic(processor, cache_entry, cia);\n"); 3024e98e3e1Schristos print_engine_issue_postfix_hook (file); 3034e98e3e1Schristos } 3044e98e3e1Schristos /* tail */ 3054e98e3e1Schristos lf_putstr (file, "cpu_set_program_counter(processor, cia);\n"); 3064e98e3e1Schristos lf_putstr (file, "\n"); 3074e98e3e1Schristos lf_indent (file, -2); 3084e98e3e1Schristos } 3094e98e3e1Schristos lf_putstr (file, "}\n"); 3104e98e3e1Schristos } 3114e98e3e1Schristos 3124e98e3e1Schristos lf_putstr (file, "\n"); 3134e98e3e1Schristos lf_putstr (file, "current_cpu += 1;\n"); 3144e98e3e1Schristos lf_putstr (file, "if (current_cpu == nr_cpus)\n"); 3154e98e3e1Schristos lf_putstr (file, " {\n"); 3164e98e3e1Schristos lf_putstr (file, " if (sim_events_tick (sd))\n"); 3174e98e3e1Schristos lf_putstr (file, " {\n"); 3184e98e3e1Schristos lf_putstr (file, " sim_events_process (sd);\n"); 3194e98e3e1Schristos lf_putstr (file, " }\n"); 3204e98e3e1Schristos lf_putstr (file, " current_cpu = 0;\n"); 3214e98e3e1Schristos lf_putstr (file, " }\n"); 3224e98e3e1Schristos 3234e98e3e1Schristos /* tail */ 3244e98e3e1Schristos lf_indent (file, -4); 3254e98e3e1Schristos lf_putstr (file, " }\n"); 3264e98e3e1Schristos } 3274e98e3e1Schristos 3284e98e3e1Schristos 3294e98e3e1Schristos lf_indent (file, -2); 3304e98e3e1Schristos lf_putstr (file, "}\n"); 3314e98e3e1Schristos } 3324e98e3e1Schristos 3334e98e3e1Schristos 3344e98e3e1Schristos /****************************************************************/ 3354e98e3e1Schristos 3364e98e3e1Schristos void 3374e98e3e1Schristos print_engine_run_function_header (lf *file, 3384b169a6bSchristos const char *processor, 3394e98e3e1Schristos function_decl_type decl_type) 3404e98e3e1Schristos { 3414e98e3e1Schristos int indent; 3424e98e3e1Schristos lf_printf (file, "\n"); 3434e98e3e1Schristos switch (decl_type) 3444e98e3e1Schristos { 3454e98e3e1Schristos case is_function_declaration: 3464e98e3e1Schristos lf_print__function_type (file, "void", "INLINE_ENGINE", "\n"); 3474e98e3e1Schristos break; 3484e98e3e1Schristos case is_function_definition: 3494e98e3e1Schristos lf_print__function_type (file, "void", "INLINE_ENGINE", " "); 3504e98e3e1Schristos break; 3514e98e3e1Schristos case is_function_variable: 3524e98e3e1Schristos lf_printf (file, "void (*"); 3534e98e3e1Schristos break; 3544e98e3e1Schristos } 3554e98e3e1Schristos indent = print_function_name (file, "run", NULL, /* format name */ 3564e98e3e1Schristos processor, NULL, /* expanded bits */ 3574e98e3e1Schristos function_name_prefix_engine); 3584e98e3e1Schristos switch (decl_type) 3594e98e3e1Schristos { 3604e98e3e1Schristos case is_function_definition: 3614e98e3e1Schristos lf_putstr (file, "\n("); 3624e98e3e1Schristos indent = 1; 3634e98e3e1Schristos break; 3644e98e3e1Schristos case is_function_declaration: 3654e98e3e1Schristos indent += lf_printf (file, " ("); 3664e98e3e1Schristos break; 3674e98e3e1Schristos case is_function_variable: 3684e98e3e1Schristos lf_putstr (file, ")\n("); 3694e98e3e1Schristos indent = 1; 3704e98e3e1Schristos break; 3714e98e3e1Schristos } 3724e98e3e1Schristos lf_indent (file, +indent); 3734e98e3e1Schristos lf_printf (file, "SIM_DESC sd,\n"); 3744e98e3e1Schristos lf_printf (file, "int next_cpu_nr,\n"); 3754e98e3e1Schristos lf_printf (file, "int nr_cpus,\n"); 3764e98e3e1Schristos lf_printf (file, "int siggnal)"); 3774e98e3e1Schristos lf_indent (file, -indent); 3784e98e3e1Schristos switch (decl_type) 3794e98e3e1Schristos { 3804e98e3e1Schristos case is_function_definition: 3814e98e3e1Schristos lf_putstr (file, "\n"); 3824e98e3e1Schristos break; 3834e98e3e1Schristos case is_function_variable: 3844e98e3e1Schristos case is_function_declaration: 3854e98e3e1Schristos lf_putstr (file, ";\n"); 3864e98e3e1Schristos break; 3874e98e3e1Schristos } 3884e98e3e1Schristos } 3894e98e3e1Schristos 3904e98e3e1Schristos 3914e98e3e1Schristos void 3924e98e3e1Schristos gen_engine_h (lf *file, 3934b169a6bSchristos const gen_table *gen, 3944b169a6bSchristos const insn_table *isa, 3954b169a6bSchristos cache_entry *cache_rules) 3964e98e3e1Schristos { 3974e98e3e1Schristos gen_list *entry; 3984e98e3e1Schristos for (entry = gen->tables; entry != NULL; entry = entry->next) 3994e98e3e1Schristos { 4004e98e3e1Schristos print_engine_run_function_header (file, 4014e98e3e1Schristos (options.gen.multi_sim 4024e98e3e1Schristos ? entry->model->name 4034e98e3e1Schristos : NULL), is_function_declaration); 4044e98e3e1Schristos } 4054e98e3e1Schristos } 4064e98e3e1Schristos 4074e98e3e1Schristos 4084e98e3e1Schristos void 4094e98e3e1Schristos gen_engine_c (lf *file, 4104b169a6bSchristos const gen_table *gen, 4114b169a6bSchristos const insn_table *isa, 4124b169a6bSchristos cache_entry *cache_rules) 4134e98e3e1Schristos { 4144b169a6bSchristos const gen_list *entry; 4154e98e3e1Schristos /* the intro */ 4164e98e3e1Schristos print_includes (file); 4174e98e3e1Schristos print_include_inline (file, options.module.semantics); 4184e98e3e1Schristos print_include (file, options.module.engine); 4194e98e3e1Schristos lf_printf (file, "\n"); 4204e98e3e1Schristos lf_printf (file, "#include \"sim-assert.h\"\n"); 4214e98e3e1Schristos lf_printf (file, "\n"); 4224e98e3e1Schristos print_idecode_globals (file); 4234e98e3e1Schristos lf_printf (file, "\n"); 4244e98e3e1Schristos 4254e98e3e1Schristos for (entry = gen->tables; entry != NULL; entry = entry->next) 4264e98e3e1Schristos { 4274e98e3e1Schristos switch (options.gen.code) 4284e98e3e1Schristos { 4294e98e3e1Schristos case generate_calls: 4304e98e3e1Schristos print_idecode_lookups (file, entry->table, cache_rules); 4314e98e3e1Schristos 4324e98e3e1Schristos /* output the main engine routine */ 4334e98e3e1Schristos print_engine_run_function_header (file, 4344e98e3e1Schristos (options.gen.multi_sim 4354e98e3e1Schristos ? entry->model->name 4364e98e3e1Schristos : NULL), is_function_definition); 4374e98e3e1Schristos print_run_body (file, entry->table); 4384e98e3e1Schristos break; 4394e98e3e1Schristos 4404e98e3e1Schristos case generate_jumps: 4414e98e3e1Schristos ERROR ("Jumps currently unimplemented"); 4424e98e3e1Schristos break; 4434e98e3e1Schristos } 4444e98e3e1Schristos } 4454e98e3e1Schristos } 446