📄 gen-idecode.c
字号:
lf_putstr(file, "\n"); lf_putstr(file, "\n"); lf_putstr(file, "/* now add restart target as ready to run */\n"); lf_putstr(file, "psim_set_halt_and_restart(system, &halt, &restart);\n"); lf_putstr(file, "if (setjmp(restart)) {\n"); lf_putstr(file, " if (WITH_EVENTS) {\n"); lf_putstr(file, " /* when restart, cpu must have been last, clock next */\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, " }\n"); lf_putstr(file, "}\n"); lf_putstr(file, "\n"); lf_putstr(file, "/* prime the main loop */\n"); lf_putstr(file, "processor = processors[0];\n"); lf_putstr(file, "cia = cpu_get_program_counter(processor);\n"); lf_putstr(file, "\n"); lf_putstr(file, "while (1) {\n"); lf_indent(file, +2); if (!(code & generate_with_icache)) { lf_putstr(file, "instruction_word instruction =\n"); lf_putstr(file, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n"); lf_putstr(file, "\n"); print_idecode_body(file, table, "cia =");; } if ((code & generate_with_icache)) { lf_putstr(file, "idecode_cache *cache_entry =\n"); lf_putstr(file, " cpu_icache_entry(processor, cia);\n"); lf_putstr(file, "if (cache_entry->address == cia) {\n"); lf_putstr(file, " /* cache hit */\n"); lf_putstr(file, " idecode_semantic *const semantic = cache_entry->semantic;\n"); lf_putstr(file, " cia = semantic(processor, cache_entry, cia);\n"); /* tail */ if (can_stop) { lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n"); lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore*/);\n"); } lf_putstr(file, "}\n"); lf_putstr(file, "else {\n"); lf_putstr(file, " /* cache miss */\n"); if (!(code & generate_with_semantic_icache)) { lf_indent(file, +2); lf_putstr(file, "idecode_semantic *semantic;\n"); lf_indent(file, -2); } lf_putstr(file, " instruction_word instruction =\n"); lf_putstr(file, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n"); lf_putstr(file, " if (WITH_MON != 0)\n"); lf_putstr(file, " mon_event(mon_event_icache_miss, processor, cia);\n"); if ((code & generate_with_semantic_icache)) { lf_putstr(file, "{\n"); lf_indent(file, +2); print_idecode_body(file, table, "cia ="); lf_indent(file, -2); lf_putstr(file, "}\n"); } else { print_idecode_body(file, table, "semantic ="); lf_putstr(file, " cia = semantic(processor, cache_entry, cia);\n"); } lf_putstr(file, "}\n"); } /* events */ lf_putstr(file, "\n"); lf_putstr(file, "/* process any events */\n"); lf_putstr(file, "if (WITH_EVENTS) {\n"); lf_putstr(file, " if (event_queue_tick(events)) {\n"); lf_putstr(file, " cpu_set_program_counter(processor, cia);\n"); lf_putstr(file, " event_queue_process(events);\n"); lf_putstr(file, " cia = cpu_get_program_counter(processor);\n"); lf_putstr(file, " }\n"); lf_putstr(file, "}\n"); /* tail */ if (can_stop) { lf_putstr(file, "\n"); lf_putstr(file, "/* abort if necessary */\n"); lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n"); lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*not important*/);\n"); } lf_indent(file, -2); lf_putstr(file, "}\n"); } if (generate_smp) { lf_putstr(file, "\n\/* CASE 2: SMP (With or without ICACHE)\n\\n\ The complexity here comes from needing to correctly restart the\n\ system when it is aborted. In particular if cpu0 requests a\n\ restart, the next cpu is still cpu1. Cpu0 being restarted after\n\ all the other CPU's and the event queue have been processed */"); lf_putstr(file, "\n"); lf_putstr(file, "\n"); lf_putstr(file, "/* now establish the restart target */\n"); lf_putstr(file, "psim_set_halt_and_restart(system, &halt, &restart);\n"); lf_putstr(file, "if (setjmp(restart)) {\n"); lf_putstr(file, " current_cpu = psim_last_cpu(system);\n"); lf_putstr(file, " ASSERT(current_cpu >= 0 && current_cpu < nr_cpus);\n"); lf_putstr(file, "}\n"); lf_putstr(file, "else {\n"); lf_putstr(file, " current_cpu = last_cpu;\n"); lf_putstr(file, " ASSERT(current_cpu >= -1 && current_cpu < nr_cpus);\n"); lf_putstr(file, "}\n"); lf_putstr(file, "\n"); lf_putstr(file, "while (1) {\n"); lf_indent(file, +2); lf_putstr(file, "\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, "\n"); lf_putstr(file, "{\n"); lf_indent(file, +2); lf_putstr(file, "cpu *processor = processors[current_cpu];\n"); lf_putstr(file, "unsigned_word cia =\n"); lf_putstr(file, " cpu_get_program_counter(processor);\n"); if (!(code & generate_with_icache)) { lf_putstr(file, "instruction_word instruction =\n"); lf_putstr(file, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n"); print_idecode_body(file, table, "cia ="); if (can_stop) { lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n"); lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore*/);\n"); } lf_putstr(file, "cpu_set_program_counter(processor, cia);\n"); } if ((code & generate_with_icache)) { lf_putstr(file, "idecode_cache *cache_entry =\n"); lf_putstr(file, " cpu_icache_entry(processor, cia);\n"); lf_putstr(file, "\n"); lf_putstr(file, "if (cache_entry->address == cia) {\n"); { lf_indent(file, +2); lf_putstr(file, "\n"); lf_putstr(file, "/* cache hit */\n"); lf_putstr(file, "idecode_semantic *semantic = cache_entry->semantic;\n"); lf_putstr(file, "cia = semantic(processor, cache_entry, cia);\n"); /* tail */ if (can_stop) { lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n"); lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore-signal*/);\n"); } lf_putstr(file, "cpu_set_program_counter(processor, cia);\n"); lf_putstr(file, "\n"); lf_indent(file, -2); } lf_putstr(file, "}\n"); lf_putstr(file, "else {\n"); { lf_indent(file, +2); lf_putstr(file, "\n"); lf_putstr(file, "/* cache miss */\n"); if (!(code & generate_with_semantic_icache)) { lf_putstr(file, "idecode_semantic *semantic;\n"); } lf_putstr(file, "instruction_word instruction =\n"); lf_putstr(file, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n"); lf_putstr(file, "if (WITH_MON != 0)\n"); lf_putstr(file, " mon_event(mon_event_icache_miss, processors[current_cpu], cia);\n"); if ((code & generate_with_semantic_icache)) { lf_putstr(file, "{\n"); lf_indent(file, +2); print_idecode_body(file, table, "cia ="); lf_indent(file, -2); lf_putstr(file, "}\n"); } else { print_idecode_body(file, table, "semantic = "); lf_putstr(file, "cia = semantic(processor, cache_entry, cia);\n"); } /* tail */ if (can_stop) { lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n"); lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore-signal*/);\n"); } lf_putstr(file, "cpu_set_program_counter(processor, cia);\n"); lf_putstr(file, "\n"); lf_indent(file, -2); } lf_putstr(file, "}\n"); } /* close */ lf_indent(file, -2); lf_putstr(file, "}\n"); /* tail */ lf_indent(file, -2); lf_putstr(file, "}\n"); } lf_indent(file, -2); lf_putstr(file, "}\n");}/****************************************************************/static 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(processor, nia, was_continuing, 0/*na*/);\n"); } if (!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(processor, nia);\n"); lf_putstr(file, " event_queue_process(events);\n"); lf_putstr(file, " nia = cpu_get_program_counter(processor);\n"); lf_putstr(file, " }\n"); lf_putstr(file, "}\n"); } if (generate_smp) { if (is_tail) lf_putstr(file, "cpu_set_program_counter(processor, 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, "processor = processors[current_cpu];\n"); lf_putstr(file, "nia = cpu_get_program_counter(processor);\n"); } if ((code & generate_with_icache)) { lf_putstr(file, "cache_entry = cpu_icache_entry(processor, 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 (!(code & generate_with_icache) && is_tail) { lf_printf(file, "goto idecode;\n"); }}static voidprint_jump_insn(lf *file, insn *instruction, insn_bits *expanded_bits, opcode_field *opcodes, cache_table *cache_rules){ /* what we are for the moment */ lf_printf(file, "\n"); print_my_defines(file, expanded_bits, instruction->file_entry); /* output the icache entry */ if ((code & generate_with_icache)) { lf_printf(file, "\n"); lf_indent(file, -1); print_function_name(file, instruction->file_entry->fields[insn_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->file_entry, 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->file_entry->fields[insn_name], expanded_bits, function_name_prefix_semantics); lf_printf(file, ";\n"); if ((code & generate_with_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->file_entry->fields[insn_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->file_entry->fields[insn_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, ((code & generate_with_direct_access) ? define_variables : declare_variables), ((code & generate_with_icache) ? get_values_from_icache : do_not_use_icache)); print_semantic_body(file, instruction, expanded_bits, opcodes); if (code & generate_with_direct_access) print_icache_body(file, instruction, expanded_bits, cache_rules, undef_variables, ((code & generate_with_icache) ? get_values_from_icache : do_not_use_icache)); print_jump(file, 1/*is tail*/); lf_indent(file, -2); lf_printf(file, "}\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -