📄 igen.c
字号:
/* The IGEN simulator generator for GDB, the GNU Debugger. Copyright 2002 Free Software Foundation, Inc. Contributed by Andrew Cagney. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <getopt.h>#include "misc.h"#include "lf.h"#include "table.h"#include "config.h"#include "filter.h"#include "igen.h"#include "ld-insn.h"#include "ld-decode.h"#include "ld-cache.h"#include "gen.h"#include "gen-model.h"#include "gen-icache.h"#include "gen-itable.h"#include "gen-idecode.h"#include "gen-semantics.h"#include "gen-engine.h"#include "gen-support.h"#include "gen-engine.h"/****************************************************************//* Semantic functions */intprint_semantic_function_formal (lf *file, int nr_prefetched_words){ int nr = 0; int word_nr; if (options.gen.icache || nr_prefetched_words < 0) { nr += lf_printf (file, "SIM_DESC sd,\n"); nr += lf_printf (file, "%sidecode_cache *cache_entry,\n", options.module.global.prefix.l); nr += lf_printf (file, "%sinstruction_address cia", options.module.global.prefix.l); } else if (options.gen.smp) { nr += lf_printf (file, "sim_cpu *cpu,\n"); for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++) { nr += lf_printf (file, "%sinstruction_word instruction_%d,\n", options.module.global.prefix.l, word_nr); } nr += lf_printf (file, "%sinstruction_address cia", options.module.global.prefix.l); } else { nr += lf_printf (file, "SIM_DESC sd,\n"); for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++) { nr += lf_printf (file, "%sinstruction_word instruction_%d,\n", options.module.global.prefix.l, word_nr); } nr += lf_printf (file, "%sinstruction_address cia", options.module.global.prefix.l); } return nr;}intprint_semantic_function_actual (lf *file, int nr_prefetched_words){ int nr = 0; int word_nr; if (options.gen.icache || nr_prefetched_words < 0) { nr += lf_printf (file, "sd, cache_entry, cia"); } else { if (options.gen.smp) nr += lf_printf (file, "cpu"); else nr += lf_printf (file, "sd"); for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++) nr += lf_printf (file, ", instruction_%d", word_nr); nr += lf_printf (file, ", cia"); } return nr;}intprint_semantic_function_type (lf *file){ int nr = 0; nr += lf_printf (file, "%sinstruction_address", options.module.global.prefix.l); return nr;}/* Idecode functions */intprint_icache_function_formal (lf *file, int nr_prefetched_words){ int nr = 0; int word_nr; if (options.gen.smp) nr += lf_printf (file, "sim_cpu *cpu,\n"); else nr += lf_printf (file, "SIM_DESC sd,\n"); for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++) nr += lf_printf (file, " %sinstruction_word instruction_%d,\n", options.module.global.prefix.l, word_nr); nr += lf_printf (file, " %sinstruction_address cia,\n", options.module.global.prefix.l); nr += lf_printf (file, " %sidecode_cache *cache_entry", options.module.global.prefix.l); return nr;}intprint_icache_function_actual (lf *file, int nr_prefetched_words){ int nr = 0; int word_nr; if (options.gen.smp) nr += lf_printf (file, "cpu"); else nr += lf_printf (file, "sd"); for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++) nr += lf_printf (file, ", instruction_%d", word_nr); nr += lf_printf (file, ", cia, cache_entry"); return nr;}intprint_icache_function_type (lf *file){ int nr; if (options.gen.semantic_icache) { nr = print_semantic_function_type (file); } else { nr = lf_printf (file, "%sidecode_semantic *", options.module.global.prefix.l); } return nr;}/* Function names */static intprint_opcode_bits (lf *file, opcode_bits *bits){ int nr = 0; if (bits == NULL) return nr; nr += lf_putchr (file, '_'); nr += lf_putstr (file, bits->field->val_string); if (bits->opcode->is_boolean && bits->value == 0) nr += lf_putint (file, bits->opcode->boolean_constant); else if (!bits->opcode->is_boolean) { if (bits->opcode->last < bits->field->last) nr += lf_putint (file, bits->value << (bits->field->last - bits->opcode->last)); else nr += lf_putint (file, bits->value); } nr += print_opcode_bits (file, bits->next); return nr;}static intprint_c_name (lf *file, const char *name){ int nr = 0; const char *pos; for (pos = name; *pos != '\0'; pos++) { switch (*pos) { case '/': case '-': break; case ' ': case '.': nr += lf_putchr (file, '_'); break; default: nr += lf_putchr (file, *pos); break; } } return nr;}extern intprint_function_name (lf *file, const char *basename, const char *format_name, const char *model_name, opcode_bits *expanded_bits, lf_function_name_prefixes prefix){ int nr = 0; /* the prefix */ switch (prefix) { case function_name_prefix_semantics: nr += lf_printf (file, "%s", options.module.semantics.prefix.l); nr += lf_printf (file, "semantic_"); break; case function_name_prefix_idecode: nr += lf_printf (file, "%s", options.module.idecode.prefix.l); nr += lf_printf (file, "idecode_"); break; case function_name_prefix_itable: nr += lf_printf (file, "%sitable_", options.module.itable.prefix.l); break; case function_name_prefix_icache: nr += lf_printf (file, "%s", options.module.icache.prefix.l); nr += lf_printf (file, "icache_"); break; case function_name_prefix_engine: nr += lf_printf (file, "%s", options.module.engine.prefix.l); nr += lf_printf (file, "engine_"); default: break; } if (model_name != NULL) { nr += print_c_name (file, model_name); nr += lf_printf (file, "_"); } /* the function name */ nr += print_c_name (file, basename); /* the format name if available */ if (format_name != NULL) { nr += lf_printf (file, "_"); nr += print_c_name (file, format_name); } /* the suffix */ nr += print_opcode_bits (file, expanded_bits); return nr;}voidprint_my_defines (lf *file, const char *basename, const char *format_name, opcode_bits *expanded_bits){ /* #define MY_INDEX xxxxx */ lf_indent_suppress (file); lf_printf (file, "#undef MY_INDEX\n"); lf_indent_suppress (file); lf_printf (file, "#define MY_INDEX "); print_function_name (file, basename, format_name, NULL, NULL, function_name_prefix_itable); lf_printf (file, "\n"); /* #define MY_PREFIX xxxxxx */ lf_indent_suppress (file); lf_printf (file, "#undef "); print_function_name (file, basename, format_name, NULL, expanded_bits, function_name_prefix_none); lf_printf (file, "\n"); lf_indent_suppress (file); lf_printf (file, "#undef MY_PREFIX\n"); lf_indent_suppress (file); lf_printf (file, "#define MY_PREFIX "); print_function_name (file, basename, format_name, NULL, expanded_bits, function_name_prefix_none); lf_printf (file, "\n"); /* #define MY_NAME xxxxxx */ lf_indent_suppress (file); lf_indent_suppress (file); lf_printf (file, "#undef MY_NAME\n"); lf_indent_suppress (file); lf_printf (file, "#define MY_NAME \""); print_function_name (file, basename, format_name, NULL, expanded_bits, function_name_prefix_none); lf_printf (file, "\"\n");}static intprint_itrace_prefix (lf *file){ const char *prefix = "trace_prefix ("; int indent = strlen (prefix); lf_printf (file, "%sSD, CPU, cia, CIA, TRACE_LINENUM_P (CPU), \\\n", prefix); lf_indent (file, +indent); lf_printf (file, "%sitable[MY_INDEX].file, \\\n", options.module.itable.prefix.l); lf_printf (file, "%sitable[MY_INDEX].line_nr, \\\n", options.module.itable.prefix.l); lf_printf (file, "\""); return indent;}static voidprint_itrace_format (lf *file, insn_mnemonic_entry *assembler){ /* pass=1 is fmt string; pass=2 is arguments */ int pass; /* print the format string */ for (pass = 1; pass <= 2; pass++) { const char *chp = assembler->format; chp++; /* skip the leading quote */ /* write out the format/args */ while (*chp != '\0') { if (chp[0] == '\\' && (chp[1] == '<' || chp[1] == '>')) { if (pass == 1) lf_putchr (file, chp[1]); chp += 2; } else if (chp[0] == '<' || chp[0] == '%') { /* parse [ "%" ... ] "<" [ func "#" ] param ">" */ const char *fmt; const char *func; int strlen_func; const char *param; int strlen_param; /* the "%" ... "<" format */ fmt = chp; while (chp[0] != '<' && chp[0] != '\0') chp++; if (chp[0] != '<') error (assembler->line, "Missing `<' after `%%'\n"); chp++; /* [ "func" # ] OR "param" */ func = chp; param = chp; while (chp[0] != '>' && chp[0] != '#' && chp[0] != '\0') chp++; strlen_func = chp - func; if (chp[0] == '#') { chp++; param = chp; while (chp[0] != '>' && chp[0] != '\0') chp++; } strlen_param = chp - param; if (chp[0] != '>') error (assembler->line, "Missing closing `>' in assembler string\n"); chp++; /* now process it */ if (pass == 2) lf_printf (file, ", \\\n"); if (strncmp (fmt, "<", 1) == 0) /* implicit long int format */ { if (pass == 1) lf_printf (file, "%%ld"); else { lf_printf (file, "(long) "); lf_write (file, param, strlen_param); } } else if (strncmp (fmt, "%<", 2) == 0) /* explicit format */ { if (pass == 1) lf_printf (file, "%%"); else lf_write (file, param, strlen_param);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -