📄 gen-idecode.c
字号:
} print_function_name (file, entry->insns->insn->name, entry->insns->insn->format_name, NULL, entry->expanded_bits, (options.gen.icache ? function_name_prefix_icache : function_name_prefix_semantics)); if (options.gen.code == generate_calls) { lf_printf (file, " ("); print_semantic_function_actual (file, entry->insns->semantic-> nr_prefetched_words); lf_printf (file, ")"); } lf_printf (file, ";\n"); } else if (entry->opcode_rule->gen == switch_gen || entry->opcode_rule->gen == goto_switch_gen || entry->opcode_rule->gen == padded_switch_gen) { /* switch calling switch */ lf_printf (file, "{\n"); lf_indent (file, +2); print_idecode_ifetch (file, entry->parent->nr_prefetched_words, entry->nr_prefetched_words); print_idecode_switch (file, entry, result); lf_indent (file, -2); lf_printf (file, "}\n"); } else { /* switch looking up a table */ lf_printf (file, "{\n"); lf_indent (file, +2); print_idecode_ifetch (file, entry->parent->nr_prefetched_words, entry->nr_prefetched_words); print_idecode_table (file, entry, result); lf_indent (file, -2); lf_printf (file, "}\n"); } if (entry->parent->opcode->is_boolean || entry->parent->opcode_rule->gen == switch_gen || entry->parent->opcode_rule->gen == padded_switch_gen) { lf_printf (file, "break;\n"); } else if (entry->parent->opcode_rule->gen == goto_switch_gen) { print_goto_switch_break (file, entry); } else { ERROR ("bad switch"); } } lf_indent (file, -4); lf_printf (file, " }\n");}static voidprint_idecode_switch_illegal (lf *file, const char *result){ lf_indent (file, +2); print_idecode_invalid (file, result, invalid_illegal); lf_printf (file, "break;\n"); lf_indent (file, -2);}static voidprint_idecode_switch_end (lf *file, gen_entry *table, int depth, void *data){ const char *result = data; ASSERT (depth == 0); ASSERT (table->opcode_rule->gen == switch_gen || table->opcode_rule->gen == goto_switch_gen || table->opcode_rule->gen == padded_switch_gen); ASSERT (table->opcode); if (table->opcode->is_boolean) { lf_printf (file, "}\n"); lf_indent (file, -2); } else if (table->opcode_rule->gen == switch_gen || table->opcode_rule->gen == padded_switch_gen) { lf_printf (file, "default:\n"); lf_indent (file, +2); if (table->nr_entries == table->opcode->nr_opcodes) { print_sim_engine_abort (file, "Internal error - bad switch generated"); lf_printf (file, "%sNULL_CIA;\n", result); lf_printf (file, "break;\n"); } else { print_idecode_switch_illegal (file, result); } lf_indent (file, -2); lf_printf (file, "}\n"); lf_indent (file, -2); } else if (table->opcode_rule->gen == goto_switch_gen) { lf_printf (file, "illegal_"); lf_print_table_name (file, table); lf_printf (file, ":\n"); print_idecode_invalid (file, result, invalid_illegal); lf_printf (file, "break_"); lf_print_table_name (file, table); lf_printf (file, ":;\n"); if (table->parent != NULL && (table->parent->opcode_rule->gen == switch_gen || table->parent->opcode_rule->gen == goto_switch_gen || table->parent->opcode_rule->gen == padded_switch_gen)) { lf_indent (file, -2); lf_printf (file, "}\n"); } } else { ERROR ("bad switch"); }}voidprint_idecode_switch (lf *file, gen_entry *table, const char *result){ gen_entry_traverse_tree (file, table, 0, print_idecode_switch_start, print_idecode_switch_leaf, print_idecode_switch_end, (void *) result);}static voidprint_idecode_switch_function_header (lf *file, gen_entry *table, int is_function_definition, int nr_prefetched_words){ lf_printf (file, "\n"); if (options.gen.code == generate_calls) { lf_printf (file, "static "); if (options.gen.icache) { lf_printf (file, "idecode_semantic *"); } else { lf_printf (file, "unsigned_word"); } if (is_function_definition) { lf_printf (file, "\n"); } else { lf_printf (file, " "); } lf_print_table_name (file, table); lf_printf (file, "\n("); print_icache_function_formal (file, nr_prefetched_words); lf_printf (file, ")"); if (!is_function_definition) { lf_printf (file, ";"); } lf_printf (file, "\n"); } if (options.gen.code == generate_jumps && is_function_definition) { lf_indent (file, -1); lf_print_table_name (file, table); lf_printf (file, ":\n"); lf_indent (file, +1); }}static voididecode_declare_if_switch (lf *file, gen_entry *table, int depth, void *data){ if ((table->opcode_rule->gen == switch_gen || table->opcode_rule->gen == goto_switch_gen || table->opcode_rule->gen == padded_switch_gen) &&table->parent != NULL /* don't declare the top one yet */ && table->parent->opcode_rule->gen == array_gen) { print_idecode_switch_function_header (file, table, 0 /*isnt function definition */ , 0); }}static voididecode_expand_if_switch (lf *file, gen_entry *table, int depth, void *data){ if ((table->opcode_rule->gen == switch_gen || table->opcode_rule->gen == goto_switch_gen || table->opcode_rule->gen == padded_switch_gen) &&table->parent != NULL /* don't expand the top one yet */ && table->parent->opcode_rule->gen == array_gen) { print_idecode_switch_function_header (file, table, 1 /*is function definition */ , 0); if (options.gen.code == generate_calls) { lf_printf (file, "{\n"); lf_indent (file, +2); } print_idecode_switch (file, table, "return"); if (options.gen.code == generate_calls) { lf_indent (file, -2); lf_printf (file, "}\n"); } }}/****************************************************************/voidprint_idecode_lookups (lf *file, gen_entry *table, cache_entry *cache_rules){ int depth; /* output switch function declarations where needed by tables */ gen_entry_traverse_tree (file, table, 1, idecode_declare_if_switch, /* START */ NULL, NULL, NULL); /* output tables where needed */ for (depth = gen_entry_depth (table); depth > 0; depth--) { gen_entry_traverse_tree (file, table, 1 - depth, print_idecode_table_start, print_idecode_table_leaf, print_idecode_table_end, NULL); } /* output switch functions where needed */ gen_entry_traverse_tree (file, table, 1, idecode_expand_if_switch, /* START */ NULL, NULL, NULL);}voidprint_idecode_body (lf *file, gen_entry *table, const char *result){ if (table->opcode_rule->gen == switch_gen || table->opcode_rule->gen == goto_switch_gen || table->opcode_rule->gen == padded_switch_gen) { print_idecode_switch (file, table, result); } else { print_idecode_table (file, table, result); }}/****************************************************************/#if 0static voidprint_jump (lf *file, int is_tail){ if (is_tail) { lf_putstr (file, "if (keep_running != NULL && !*keep_running)\n"); lf_putstr (file, " cpu_halt(cpu, nia, was_continuing, 0/*na*/);\n"); } if (!options.generate_smp) { lf_putstr (file, "if (WITH_EVENTS) {\n"); lf_putstr (file, " if (event_queue_tick(events)) {\n"); lf_putstr (file, " cpu_set_program_counter(cpu, nia);\n"); lf_putstr (file, " event_queue_process(events);\n"); lf_putstr (file, " nia = cpu_get_program_counter(cpu);\n"); lf_putstr (file, " }\n"); lf_putstr (file, "}\n"); } if (options.generate_smp) { if (is_tail) { lf_putstr (file, "cpu_set_program_counter(cpu, nia);\n"); } lf_putstr (file, "if (WITH_EVENTS) {\n"); lf_putstr (file, " current_cpu += 1;\n"); lf_putstr (file, " if (current_cpu >= nr_cpus) {\n"); lf_putstr (file, " if (event_queue_tick(events)) {\n"); lf_putstr (file, " event_queue_process(events);\n"); lf_putstr (file, " }\n"); lf_putstr (file, " current_cpu = 0;\n"); lf_putstr (file, " }\n"); lf_putstr (file, "}\n"); lf_putstr (file, "else {\n"); lf_putstr (file, " current_cpu = (current_cpu + 1) % nr_cpus;\n"); lf_putstr (file, "}\n"); lf_putstr (file, "cpu = cpus[current_cpu];\n"); lf_putstr (file, "nia = cpu_get_program_counter(cpu);\n"); } if (options.gen.icache) { lf_putstr (file, "cache_entry = cpu_icache_entry(cpu, nia);\n"); lf_putstr (file, "if (cache_entry->address == nia) {\n"); lf_putstr (file, " /* cache hit */\n"); lf_putstr (file, " goto *cache_entry->semantic;\n"); lf_putstr (file, "}\n"); if (is_tail) { lf_putstr (file, "goto cache_miss;\n"); } } if (!options.gen.icache && is_tail) { lf_printf (file, "goto idecode;\n"); }}#endif#if 0static voidprint_jump_insn (lf *file, insn_entry * instruction, insn_bits * expanded_bits, opcode_field *opcodes, cache_entry *cache_rules){ /* what we are for the moment */ lf_printf (file, "\n"); print_my_defines (file, expanded_bits, instruction->name); /* output the icache entry */ if (options.gen.icache) { lf_printf (file, "\n"); lf_indent (file, -1); print_function_name (file, instruction->name, expanded_bits, function_name_prefix_icache); lf_printf (file, ":\n"); lf_indent (file, +1); lf_printf (file, "{\n"); lf_indent (file, +2); lf_putstr (file, "const unsigned_word cia = nia;\n"); print_itrace (file, instruction, 1 /*putting-value-in-cache */ ); print_idecode_validate (file, instruction, opcodes); lf_printf (file, "\n"); lf_printf (file, "{\n"); lf_indent (file, +2); print_icache_body (file, instruction, expanded_bits, cache_rules, 0, /*use_defines */ put_values_in_icache); lf_printf (file, "cache_entry->address = nia;\n"); lf_printf (file, "cache_entry->semantic = &&"); print_function_name (file, instruction->name, expanded_bits, function_name_prefix_semantics); lf_printf (file, ";\n"); if (options.gen.semantic_icache) { print_semantic_body (file, instruction, expanded_bits, opcodes); print_jump (file, 1 /*is-tail */ ); } else { lf_printf (file, "/* goto "); print_function_name (file, instruction->name, expanded_bits, function_name_prefix_semantics); lf_printf (file, "; */\n"); } lf_indent (file, -2); lf_putstr (file, "}\n"); lf_indent (file, -2); lf_printf (file, "}\n"); } /* print the semantics */ lf_printf (file, "\n"); lf_indent (file, -1); print_function_name (file, instruction->name, expanded_bits, function_name_prefix_semantics); lf_printf (file, ":\n"); lf_indent (file, +1); lf_printf (file, "{\n"); lf_indent (file, +2); lf_putstr (file, "const unsigned_word cia = nia;\n"); print_icache_body (file, instruction, expanded_bits, cache_rules, (options.gen.direct_access ? define_variables : declare_variables), (options.gen.icache ? get_values_from_icache : do_not_use_icache)); print_semantic_body (file, instruction, expanded_bits, opcodes); if (options.gen.direct_access) print_icache_body (file, instruction, expanded_bits, cache_rules, undef_variables, (options.gen.icache ? get_values_from_icache : do_not_use_icache)); print_jump (file, 1 /*is tail */ ); lf_indent (file, -2); lf_printf (file, "}\n");}#endif#if 0static voidprint_jump_definition (lf *file,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -