📄 igen.c
字号:
} else if (strncmp (fmt, "%s<", 3) == 0) /* string format */ { if (pass == 1) lf_printf (file, "%%s"); else { lf_printf (file, "%sstr_", options.module.global.prefix.l); lf_write (file, func, strlen_func); lf_printf (file, " (SD_, "); lf_write (file, param, strlen_param); lf_printf (file, ")"); } } else if (strncmp (fmt, "%lx<", 4) == 0) /* simple hex */ { if (pass == 1) lf_printf (file, "%%lx"); else { lf_printf (file, "(unsigned long) "); lf_write (file, param, strlen_param); } } else if (strncmp (fmt, "%#lx<", 5) == 0) /* simple hex with 0x prefix */ { if (pass == 1) lf_printf (file, "%%#lx"); else { lf_printf (file, "(unsigned long) "); lf_write (file, param, strlen_param); } } else if (strncmp (fmt, "%08lx<", 6) == 0) /* simple hex */ { if (pass == 1) lf_printf (file, "%%08lx"); else { lf_printf (file, "(unsigned long) "); lf_write (file, param, strlen_param); } } else error (assembler->line, "Unknown assembler string format\n"); } else { if (pass == 1) lf_putchr (file, chp[0]); chp += 1; } } } lf_printf (file, ");\n");}voidprint_itrace (lf *file, insn_entry * insn, int idecode){ /* NB: Here we escape each EOLN. This is so that the the compiler treats a trace function call as a single line. Consequently any errors in the line are refered back to the same igen assembler source line */ const char *phase = (idecode) ? "DECODE" : "INSN"; lf_printf (file, "\n"); lf_indent_suppress (file); lf_printf (file, "#if defined (WITH_TRACE)\n"); lf_printf (file, "/* generate a trace prefix if any tracing enabled */\n"); lf_printf (file, "if (TRACE_ANY_P (CPU))\n"); lf_printf (file, " {\n"); lf_indent (file, +4); { if (insn->mnemonics != NULL) { insn_mnemonic_entry *assembler = insn->mnemonics; int is_first = 1; do { if (assembler->condition != NULL) { int indent; lf_printf (file, "%sif (%s)\n", is_first ? "" : "else ", assembler->condition); lf_indent (file, +2); lf_print__line_ref (file, assembler->line); indent = print_itrace_prefix (file); print_itrace_format (file, assembler); lf_print__internal_ref (file); lf_indent (file, -indent); lf_indent (file, -2); if (assembler->next == NULL) error (assembler->line, "Missing final unconditional assembler\n"); } else { int indent; if (!is_first) { lf_printf (file, "else\n"); lf_indent (file, +2); } lf_print__line_ref (file, assembler->line); indent = print_itrace_prefix (file); print_itrace_format (file, assembler); lf_print__internal_ref (file); lf_indent (file, -indent); if (!is_first) lf_indent (file, -2); if (assembler->next != NULL) error (assembler->line, "Unconditional assembler is not last\n"); } is_first = 0; assembler = assembler->next; } while (assembler != NULL); } else { int indent; lf_indent (file, +2); lf_print__line_ref (file, insn->line); indent = print_itrace_prefix (file); lf_printf (file, "%%s\", \\\n"); lf_printf (file, "itable[MY_INDEX].name);\n"); lf_print__internal_ref (file); lf_indent (file, -indent); lf_indent (file, -2); } lf_printf (file, "/* trace the instruction execution if enabled */\n"); lf_printf (file, "if (TRACE_%s_P (CPU))\n", phase); lf_printf (file, " trace_generic (SD, CPU, TRACE_%s_IDX, \" %%s\", itable[MY_INDEX].name);\n", phase); } lf_indent (file, -4); lf_printf (file, " }\n"); lf_indent_suppress (file); lf_printf (file, "#endif\n");}voidprint_sim_engine_abort (lf *file, const char *message){ lf_printf (file, "sim_engine_abort (SD, CPU, cia, "); lf_printf (file, "\"%s\"", message); lf_printf (file, ");\n");}voidprint_include (lf *file, igen_module module){ lf_printf (file, "#include \"%s%s.h\"\n", module.prefix.l, module.suffix.l);}voidprint_include_inline (lf *file, igen_module module){ lf_printf (file, "#if C_REVEALS_MODULE_P (%s_INLINE)\n", module.suffix.u); lf_printf (file, "#include \"%s%s.c\"\n", module.prefix.l, module.suffix.l); lf_printf (file, "#else\n"); print_include (file, module); lf_printf (file, "#endif\n"); lf_printf (file, "\n");}voidprint_includes (lf *file){ lf_printf (file, "\n"); lf_printf (file, "#include \"sim-inline.c\"\n"); lf_printf (file, "\n"); print_include_inline (file, options.module.itable); print_include_inline (file, options.module.idecode); print_include_inline (file, options.module.support);}/****************************************************************/static voidgen_semantics_h (lf *file, insn_list *semantics, int max_nr_words){ int word_nr; insn_list *semantic; for (word_nr = -1; word_nr <= max_nr_words; word_nr++) { lf_printf (file, "typedef "); print_semantic_function_type (file); lf_printf (file, " %sidecode_semantic", options.module.global.prefix.l); if (word_nr >= 0) lf_printf (file, "_%d", word_nr); lf_printf (file, "\n("); lf_indent (file, +1); print_semantic_function_formal (file, word_nr); lf_indent (file, -1); lf_printf (file, ");\n"); lf_printf (file, "\n"); } switch (options.gen.code) { case generate_calls: for (semantic = semantics; semantic != NULL; semantic = semantic->next) { /* Ignore any special/internal instructions */ if (semantic->insn->nr_words == 0) continue; print_semantic_declaration (file, semantic->insn, semantic->expanded_bits, semantic->opcodes, semantic->nr_prefetched_words); } break; case generate_jumps: lf_print__this_file_is_empty (file, "generating jumps"); break; }}static voidgen_semantics_c (lf *file, insn_list *semantics, cache_entry *cache_rules){ if (options.gen.code == generate_calls) { insn_list *semantic; print_includes (file); print_include (file, options.module.semantics); lf_printf (file, "\n"); for (semantic = semantics; semantic != NULL; semantic = semantic->next) { /* Ignore any special/internal instructions */ if (semantic->insn->nr_words == 0) continue; print_semantic_definition (file, semantic->insn, semantic->expanded_bits, semantic->opcodes, cache_rules, semantic->nr_prefetched_words); } } else { lf_print__this_file_is_empty (file, "generating jump engine"); }}/****************************************************************/static voidgen_icache_h (lf *file, insn_list *semantic, function_entry * functions, int max_nr_words){ int word_nr; for (word_nr = 0; word_nr <= max_nr_words; word_nr++) { lf_printf (file, "typedef "); print_icache_function_type (file); lf_printf (file, " %sidecode_icache_%d\n(", options.module.global.prefix.l, word_nr); print_icache_function_formal (file, word_nr); lf_printf (file, ");\n"); lf_printf (file, "\n"); } if (options.gen.code == generate_calls && options.gen.icache) { function_entry_traverse (file, functions, print_icache_internal_function_declaration, NULL); while (semantic != NULL) { print_icache_declaration (file, semantic->insn, semantic->expanded_bits, semantic->opcodes, semantic->nr_prefetched_words); semantic = semantic->next; } } else { lf_print__this_file_is_empty (file, "generating jump engine"); }}static voidgen_icache_c (lf *file, insn_list *semantic, function_entry * functions, cache_entry *cache_rules){ /* output `internal' invalid/floating-point unavailable functions where needed */ if (options.gen.code == generate_calls && options.gen.icache) { lf_printf (file, "\n"); lf_printf (file, "#include \"cpu.h\"\n"); lf_printf (file, "#include \"idecode.h\"\n"); lf_printf (file, "#include \"semantics.h\"\n"); lf_printf (file, "#include \"icache.h\"\n"); lf_printf (file, "#include \"support.h\"\n"); lf_printf (file, "\n"); function_entry_traverse (file, functions, print_icache_internal_function_definition, NULL); lf_printf (file, "\n"); while (semantic != NULL) { print_icache_definition (file, semantic->insn, semantic->expanded_bits, semantic->opcodes, cache_rules, semantic->nr_prefetched_words); semantic = semantic->next; } } else { lf_print__this_file_is_empty (file, "generating jump engine"); }}/****************************************************************/static voidgen_idecode_h (lf *file, gen_table *gen, insn_table *insns, cache_entry *cache_rules){ lf_printf (file, "typedef unsigned%d %sinstruction_word;\n", options.insn_bit_size, options.module.global.prefix.l); if (options.gen.delayed_branch) { lf_printf (file, "typedef struct _%sinstruction_address {\n", options.module.global.prefix.l); lf_printf (file, " address_word ip; /* instruction pointer */\n"); lf_printf (file, " address_word dp; /* delayed-slot pointer */\n"); lf_printf (file, "} %sinstruction_address;\n", options.module.global.prefix.l); } else { lf_printf (file, "typedef address_word %sinstruction_address;\n", options.module.global.prefix.l); } if (options.gen.nia == nia_is_invalid && strlen (options.module.global.prefix.u) > 0) { lf_indent_suppress (file); lf_printf (file, "#define %sINVALID_INSTRUCTION_ADDRESS ", options.module.global.prefix.u); lf_printf (file, "INVALID_INSTRUCTION_ADDRESS\n"); } lf_printf (file, "\n"); print_icache_struct (file, insns, cache_rules); lf_printf (file, "\n"); if (options.gen.icache) { ERROR ("FIXME - idecode with icache suffering from bit-rot"); } else { gen_list *entry; for (entry = gen->tables; entry != NULL; entry = entry->next) { print_idecode_issue_function_header (file, (options.gen.multi_sim ? entry->model->name : NULL), is_function_declaration, 1 /*ALWAYS ONE WORD */ ); } if (options.gen.multi_sim) { print_idecode_issue_function_header (file, NULL, is_function_variable, 1 /*ALWAYS ONE WORD */ ); } }}static voidgen_idecode_c (lf *file, gen_table *gen, insn_table *isa, cache_entry *cache_rules){ /* the intro */ print_includes (file); print_include_inline (file, options.module.semantics); lf_printf (file, "\n"); print_idecode_globals (file); lf_printf (file, "\n"); switch (options.gen.code) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -