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 <getopt.h> 234b169a6bSchristos #include <stdlib.h> 244e98e3e1Schristos 254e98e3e1Schristos #include "misc.h" 264e98e3e1Schristos #include "lf.h" 274e98e3e1Schristos #include "table.h" 284e98e3e1Schristos #include "filter.h" 294e98e3e1Schristos 304e98e3e1Schristos #include "igen.h" 314e98e3e1Schristos 324e98e3e1Schristos #include "ld-insn.h" 334e98e3e1Schristos #include "ld-decode.h" 344e98e3e1Schristos #include "ld-cache.h" 354e98e3e1Schristos 364e98e3e1Schristos #include "gen.h" 374e98e3e1Schristos 384e98e3e1Schristos #include "gen-model.h" 394e98e3e1Schristos #include "gen-icache.h" 404e98e3e1Schristos #include "gen-itable.h" 414e98e3e1Schristos #include "gen-idecode.h" 424e98e3e1Schristos #include "gen-semantics.h" 434e98e3e1Schristos #include "gen-engine.h" 444e98e3e1Schristos #include "gen-support.h" 454e98e3e1Schristos #include "gen-engine.h" 464e98e3e1Schristos 474e98e3e1Schristos 484e98e3e1Schristos /****************************************************************/ 494e98e3e1Schristos 504e98e3e1Schristos 514e98e3e1Schristos /* Semantic functions */ 524e98e3e1Schristos 534e98e3e1Schristos int 544e98e3e1Schristos print_semantic_function_formal (lf *file, int nr_prefetched_words) 554e98e3e1Schristos { 564e98e3e1Schristos int nr = 0; 574e98e3e1Schristos int word_nr; 584e98e3e1Schristos if (options.gen.icache || nr_prefetched_words < 0) 594e98e3e1Schristos { 604e98e3e1Schristos nr += lf_printf (file, "SIM_DESC sd,\n"); 614e98e3e1Schristos nr += lf_printf (file, "%sidecode_cache *cache_entry,\n", 624e98e3e1Schristos options.module.global.prefix.l); 634e98e3e1Schristos nr += lf_printf (file, "%sinstruction_address cia", 644e98e3e1Schristos options.module.global.prefix.l); 654e98e3e1Schristos } 664e98e3e1Schristos else if (options.gen.smp) 674e98e3e1Schristos { 684e98e3e1Schristos nr += lf_printf (file, "sim_cpu *cpu,\n"); 694e98e3e1Schristos for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++) 704e98e3e1Schristos { 714e98e3e1Schristos nr += lf_printf (file, "%sinstruction_word instruction_%d,\n", 724e98e3e1Schristos options.module.global.prefix.l, word_nr); 734e98e3e1Schristos } 744e98e3e1Schristos nr += lf_printf (file, "%sinstruction_address cia", 754e98e3e1Schristos options.module.global.prefix.l); 764e98e3e1Schristos } 774e98e3e1Schristos else 784e98e3e1Schristos { 794e98e3e1Schristos nr += lf_printf (file, "SIM_DESC sd,\n"); 804e98e3e1Schristos for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++) 814e98e3e1Schristos { 824e98e3e1Schristos nr += lf_printf (file, "%sinstruction_word instruction_%d,\n", 834e98e3e1Schristos options.module.global.prefix.l, word_nr); 844e98e3e1Schristos } 854e98e3e1Schristos nr += lf_printf (file, "%sinstruction_address cia", 864e98e3e1Schristos options.module.global.prefix.l); 874e98e3e1Schristos } 884e98e3e1Schristos return nr; 894e98e3e1Schristos } 904e98e3e1Schristos 914e98e3e1Schristos int 924e98e3e1Schristos print_semantic_function_actual (lf *file, int nr_prefetched_words) 934e98e3e1Schristos { 944e98e3e1Schristos int nr = 0; 954e98e3e1Schristos int word_nr; 964e98e3e1Schristos if (options.gen.icache || nr_prefetched_words < 0) 974e98e3e1Schristos { 984e98e3e1Schristos nr += lf_printf (file, "sd, cache_entry, cia"); 994e98e3e1Schristos } 1004e98e3e1Schristos else 1014e98e3e1Schristos { 1024e98e3e1Schristos if (options.gen.smp) 1034e98e3e1Schristos nr += lf_printf (file, "cpu"); 1044e98e3e1Schristos else 1054e98e3e1Schristos nr += lf_printf (file, "sd"); 1064e98e3e1Schristos for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++) 1074e98e3e1Schristos nr += lf_printf (file, ", instruction_%d", word_nr); 1084e98e3e1Schristos nr += lf_printf (file, ", cia"); 1094e98e3e1Schristos } 1104e98e3e1Schristos return nr; 1114e98e3e1Schristos } 1124e98e3e1Schristos 1134e98e3e1Schristos int 1144e98e3e1Schristos print_semantic_function_type (lf *file) 1154e98e3e1Schristos { 1164e98e3e1Schristos int nr = 0; 1174e98e3e1Schristos nr += lf_printf (file, "%sinstruction_address", 1184e98e3e1Schristos options.module.global.prefix.l); 1194e98e3e1Schristos return nr; 1204e98e3e1Schristos } 1214e98e3e1Schristos 1224e98e3e1Schristos 1234e98e3e1Schristos /* Idecode functions */ 1244e98e3e1Schristos 1254e98e3e1Schristos int 1264e98e3e1Schristos print_icache_function_formal (lf *file, int nr_prefetched_words) 1274e98e3e1Schristos { 1284e98e3e1Schristos int nr = 0; 1294e98e3e1Schristos int word_nr; 1304e98e3e1Schristos if (options.gen.smp) 1314e98e3e1Schristos nr += lf_printf (file, "sim_cpu *cpu,\n"); 1324e98e3e1Schristos else 1334e98e3e1Schristos nr += lf_printf (file, "SIM_DESC sd,\n"); 1344e98e3e1Schristos for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++) 1354e98e3e1Schristos nr += lf_printf (file, " %sinstruction_word instruction_%d,\n", 1364e98e3e1Schristos options.module.global.prefix.l, word_nr); 1374e98e3e1Schristos nr += lf_printf (file, " %sinstruction_address cia,\n", 1384e98e3e1Schristos options.module.global.prefix.l); 1394e98e3e1Schristos nr += lf_printf (file, " %sidecode_cache *cache_entry", 1404e98e3e1Schristos options.module.global.prefix.l); 1414e98e3e1Schristos return nr; 1424e98e3e1Schristos } 1434e98e3e1Schristos 1444e98e3e1Schristos int 1454e98e3e1Schristos print_icache_function_actual (lf *file, int nr_prefetched_words) 1464e98e3e1Schristos { 1474e98e3e1Schristos int nr = 0; 1484e98e3e1Schristos int word_nr; 1494e98e3e1Schristos if (options.gen.smp) 1504e98e3e1Schristos nr += lf_printf (file, "cpu"); 1514e98e3e1Schristos else 1524e98e3e1Schristos nr += lf_printf (file, "sd"); 1534e98e3e1Schristos for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++) 1544e98e3e1Schristos nr += lf_printf (file, ", instruction_%d", word_nr); 1554e98e3e1Schristos nr += lf_printf (file, ", cia, cache_entry"); 1564e98e3e1Schristos return nr; 1574e98e3e1Schristos } 1584e98e3e1Schristos 1594e98e3e1Schristos int 1604e98e3e1Schristos print_icache_function_type (lf *file) 1614e98e3e1Schristos { 1624e98e3e1Schristos int nr; 1634e98e3e1Schristos if (options.gen.semantic_icache) 1644e98e3e1Schristos { 1654e98e3e1Schristos nr = print_semantic_function_type (file); 1664e98e3e1Schristos } 1674e98e3e1Schristos else 1684e98e3e1Schristos { 1694e98e3e1Schristos nr = lf_printf (file, "%sidecode_semantic *", 1704e98e3e1Schristos options.module.global.prefix.l); 1714e98e3e1Schristos } 1724e98e3e1Schristos return nr; 1734e98e3e1Schristos } 1744e98e3e1Schristos 1754e98e3e1Schristos 1764e98e3e1Schristos /* Function names */ 1774e98e3e1Schristos 1784e98e3e1Schristos static int 1794b169a6bSchristos print_opcode_bits (lf *file, const opcode_bits *bits) 1804e98e3e1Schristos { 1814e98e3e1Schristos int nr = 0; 1824e98e3e1Schristos if (bits == NULL) 1834e98e3e1Schristos return nr; 1844e98e3e1Schristos nr += lf_putchr (file, '_'); 1854e98e3e1Schristos nr += lf_putstr (file, bits->field->val_string); 1864e98e3e1Schristos if (bits->opcode->is_boolean && bits->value == 0) 1874e98e3e1Schristos nr += lf_putint (file, bits->opcode->boolean_constant); 1884e98e3e1Schristos else if (!bits->opcode->is_boolean) 1894e98e3e1Schristos { 1904e98e3e1Schristos if (bits->opcode->last < bits->field->last) 1914e98e3e1Schristos nr += 1924e98e3e1Schristos lf_putint (file, 1934e98e3e1Schristos bits->value << (bits->field->last - bits->opcode->last)); 1944e98e3e1Schristos else 1954e98e3e1Schristos nr += lf_putint (file, bits->value); 1964e98e3e1Schristos } 1974e98e3e1Schristos nr += print_opcode_bits (file, bits->next); 1984e98e3e1Schristos return nr; 1994e98e3e1Schristos } 2004e98e3e1Schristos 2014e98e3e1Schristos static int 2024e98e3e1Schristos print_c_name (lf *file, const char *name) 2034e98e3e1Schristos { 2044e98e3e1Schristos int nr = 0; 2054e98e3e1Schristos const char *pos; 2064e98e3e1Schristos for (pos = name; *pos != '\0'; pos++) 2074e98e3e1Schristos { 2084e98e3e1Schristos switch (*pos) 2094e98e3e1Schristos { 2104e98e3e1Schristos case '/': 2114e98e3e1Schristos case '-': 2124e98e3e1Schristos break; 2134e98e3e1Schristos case ' ': 2144e98e3e1Schristos case '.': 2154e98e3e1Schristos nr += lf_putchr (file, '_'); 2164e98e3e1Schristos break; 2174e98e3e1Schristos default: 2184e98e3e1Schristos nr += lf_putchr (file, *pos); 2194e98e3e1Schristos break; 2204e98e3e1Schristos } 2214e98e3e1Schristos } 2224e98e3e1Schristos return nr; 2234e98e3e1Schristos } 2244e98e3e1Schristos 2254e98e3e1Schristos extern int 2264e98e3e1Schristos print_function_name (lf *file, 2274e98e3e1Schristos const char *basename, 2284e98e3e1Schristos const char *format_name, 2294e98e3e1Schristos const char *model_name, 2304b169a6bSchristos const opcode_bits *expanded_bits, 2314e98e3e1Schristos lf_function_name_prefixes prefix) 2324e98e3e1Schristos { 2334e98e3e1Schristos int nr = 0; 2344e98e3e1Schristos /* the prefix */ 2354e98e3e1Schristos switch (prefix) 2364e98e3e1Schristos { 2374e98e3e1Schristos case function_name_prefix_semantics: 2384e98e3e1Schristos nr += lf_printf (file, "%s", options.module.semantics.prefix.l); 2394e98e3e1Schristos nr += lf_printf (file, "semantic_"); 2404e98e3e1Schristos break; 2414e98e3e1Schristos case function_name_prefix_idecode: 2424e98e3e1Schristos nr += lf_printf (file, "%s", options.module.idecode.prefix.l); 2434e98e3e1Schristos nr += lf_printf (file, "idecode_"); 2444e98e3e1Schristos break; 2454e98e3e1Schristos case function_name_prefix_itable: 2464e98e3e1Schristos nr += lf_printf (file, "%sitable_", options.module.itable.prefix.l); 2474e98e3e1Schristos break; 2484e98e3e1Schristos case function_name_prefix_icache: 2494e98e3e1Schristos nr += lf_printf (file, "%s", options.module.icache.prefix.l); 2504e98e3e1Schristos nr += lf_printf (file, "icache_"); 2514e98e3e1Schristos break; 2524e98e3e1Schristos case function_name_prefix_engine: 2534e98e3e1Schristos nr += lf_printf (file, "%s", options.module.engine.prefix.l); 2544e98e3e1Schristos nr += lf_printf (file, "engine_"); 2554e98e3e1Schristos default: 2564e98e3e1Schristos break; 2574e98e3e1Schristos } 2584e98e3e1Schristos 2594e98e3e1Schristos if (model_name != NULL) 2604e98e3e1Schristos { 2614e98e3e1Schristos nr += print_c_name (file, model_name); 2624e98e3e1Schristos nr += lf_printf (file, "_"); 2634e98e3e1Schristos } 2644e98e3e1Schristos 2654e98e3e1Schristos /* the function name */ 2664e98e3e1Schristos nr += print_c_name (file, basename); 2674e98e3e1Schristos 2684e98e3e1Schristos /* the format name if available */ 2694e98e3e1Schristos if (format_name != NULL) 2704e98e3e1Schristos { 2714e98e3e1Schristos nr += lf_printf (file, "_"); 2724e98e3e1Schristos nr += print_c_name (file, format_name); 2734e98e3e1Schristos } 2744e98e3e1Schristos 2754e98e3e1Schristos /* the suffix */ 2764e98e3e1Schristos nr += print_opcode_bits (file, expanded_bits); 2774e98e3e1Schristos 2784e98e3e1Schristos return nr; 2794e98e3e1Schristos } 2804e98e3e1Schristos 2814e98e3e1Schristos 2824e98e3e1Schristos void 2834e98e3e1Schristos print_my_defines (lf *file, 2844e98e3e1Schristos const char *basename, 2854b169a6bSchristos const char *format_name, 2864b169a6bSchristos const opcode_bits *expanded_bits) 2874e98e3e1Schristos { 2884e98e3e1Schristos /* #define MY_INDEX xxxxx */ 2894e98e3e1Schristos lf_indent_suppress (file); 2904e98e3e1Schristos lf_printf (file, "#undef MY_INDEX\n"); 2914e98e3e1Schristos lf_indent_suppress (file); 2924e98e3e1Schristos lf_printf (file, "#define MY_INDEX "); 2934e98e3e1Schristos print_function_name (file, 2944e98e3e1Schristos basename, format_name, NULL, 2954e98e3e1Schristos NULL, function_name_prefix_itable); 2964e98e3e1Schristos lf_printf (file, "\n"); 2974e98e3e1Schristos /* #define MY_PREFIX xxxxxx */ 2984e98e3e1Schristos lf_indent_suppress (file); 2994e98e3e1Schristos lf_printf (file, "#undef "); 3004e98e3e1Schristos print_function_name (file, 3014e98e3e1Schristos basename, format_name, NULL, 3024e98e3e1Schristos expanded_bits, function_name_prefix_none); 3034e98e3e1Schristos lf_printf (file, "\n"); 3044e98e3e1Schristos lf_indent_suppress (file); 3054e98e3e1Schristos lf_printf (file, "#undef MY_PREFIX\n"); 3064e98e3e1Schristos lf_indent_suppress (file); 3074e98e3e1Schristos lf_printf (file, "#define MY_PREFIX "); 3084e98e3e1Schristos print_function_name (file, 3094e98e3e1Schristos basename, format_name, NULL, 3104e98e3e1Schristos expanded_bits, function_name_prefix_none); 3114e98e3e1Schristos lf_printf (file, "\n"); 3124e98e3e1Schristos /* #define MY_NAME xxxxxx */ 3134e98e3e1Schristos lf_indent_suppress (file); 3144e98e3e1Schristos lf_indent_suppress (file); 3154e98e3e1Schristos lf_printf (file, "#undef MY_NAME\n"); 3164e98e3e1Schristos lf_indent_suppress (file); 3174e98e3e1Schristos lf_printf (file, "#define MY_NAME \""); 3184e98e3e1Schristos print_function_name (file, 3194e98e3e1Schristos basename, format_name, NULL, 3204e98e3e1Schristos expanded_bits, function_name_prefix_none); 3214e98e3e1Schristos lf_printf (file, "\"\n"); 3224e98e3e1Schristos } 3234e98e3e1Schristos 3244e98e3e1Schristos 3254e98e3e1Schristos static int 3264e98e3e1Schristos print_itrace_prefix (lf *file) 3274e98e3e1Schristos { 3284e98e3e1Schristos const char *prefix = "trace_prefix ("; 3294e98e3e1Schristos int indent = strlen (prefix); 3304e98e3e1Schristos lf_printf (file, "%sSD, CPU, cia, CIA, TRACE_LINENUM_P (CPU), \\\n", 3314e98e3e1Schristos prefix); 3324e98e3e1Schristos lf_indent (file, +indent); 3334e98e3e1Schristos lf_printf (file, "%sitable[MY_INDEX].file, \\\n", 3344e98e3e1Schristos options.module.itable.prefix.l); 3354e98e3e1Schristos lf_printf (file, "%sitable[MY_INDEX].line_nr, \\\n", 3364e98e3e1Schristos options.module.itable.prefix.l); 3374e98e3e1Schristos lf_printf (file, "\""); 3384e98e3e1Schristos return indent; 3394e98e3e1Schristos } 3404e98e3e1Schristos 3414e98e3e1Schristos 3424e98e3e1Schristos static void 3434b169a6bSchristos print_itrace_format (lf *file, const insn_mnemonic_entry *assembler) 3444e98e3e1Schristos { 3454e98e3e1Schristos /* pass=1 is fmt string; pass=2 is arguments */ 3464e98e3e1Schristos int pass; 3474e98e3e1Schristos /* print the format string */ 3484e98e3e1Schristos for (pass = 1; pass <= 2; pass++) 3494e98e3e1Schristos { 3504e98e3e1Schristos const char *chp = assembler->format; 3514e98e3e1Schristos chp++; /* skip the leading quote */ 3524e98e3e1Schristos /* write out the format/args */ 3534e98e3e1Schristos while (*chp != '\0') 3544e98e3e1Schristos { 3554e98e3e1Schristos if (chp[0] == '\\' && (chp[1] == '<' || chp[1] == '>')) 3564e98e3e1Schristos { 3574e98e3e1Schristos if (pass == 1) 3584e98e3e1Schristos lf_putchr (file, chp[1]); 3594e98e3e1Schristos chp += 2; 3604e98e3e1Schristos } 3614e98e3e1Schristos else if (chp[0] == '<' || chp[0] == '%') 3624e98e3e1Schristos { 3634e98e3e1Schristos /* parse [ "%" ... ] "<" [ func "#" ] param ">" */ 3644e98e3e1Schristos const char *fmt; 3654e98e3e1Schristos const char *func; 3664e98e3e1Schristos int strlen_func; 3674e98e3e1Schristos const char *param; 3684e98e3e1Schristos int strlen_param; 3694e98e3e1Schristos /* the "%" ... "<" format */ 3704e98e3e1Schristos fmt = chp; 3714e98e3e1Schristos while (chp[0] != '<' && chp[0] != '\0') 3724e98e3e1Schristos chp++; 3734e98e3e1Schristos if (chp[0] != '<') 3744e98e3e1Schristos error (assembler->line, "Missing `<' after `%%'\n"); 3754e98e3e1Schristos chp++; 3764e98e3e1Schristos /* [ "func" # ] OR "param" */ 3774e98e3e1Schristos func = chp; 3784e98e3e1Schristos param = chp; 3794e98e3e1Schristos while (chp[0] != '>' && chp[0] != '#' && chp[0] != '\0') 3804e98e3e1Schristos chp++; 3814e98e3e1Schristos strlen_func = chp - func; 3824e98e3e1Schristos if (chp[0] == '#') 3834e98e3e1Schristos { 3844e98e3e1Schristos chp++; 3854e98e3e1Schristos param = chp; 3864e98e3e1Schristos while (chp[0] != '>' && chp[0] != '\0') 3874e98e3e1Schristos chp++; 3884e98e3e1Schristos } 3894e98e3e1Schristos strlen_param = chp - param; 3904e98e3e1Schristos if (chp[0] != '>') 3914e98e3e1Schristos error (assembler->line, 3924e98e3e1Schristos "Missing closing `>' in assembler string\n"); 3934e98e3e1Schristos chp++; 3944e98e3e1Schristos /* now process it */ 3954e98e3e1Schristos if (pass == 2) 3964e98e3e1Schristos lf_printf (file, ", \\\n"); 3974e98e3e1Schristos if (strncmp (fmt, "<", 1) == 0) 3984e98e3e1Schristos /* implicit long int format */ 3994e98e3e1Schristos { 4004e98e3e1Schristos if (pass == 1) 4014e98e3e1Schristos lf_printf (file, "%%ld"); 4024e98e3e1Schristos else 4034e98e3e1Schristos { 4044e98e3e1Schristos lf_printf (file, "(long) "); 4054e98e3e1Schristos lf_write (file, param, strlen_param); 4064e98e3e1Schristos } 4074e98e3e1Schristos } 4084e98e3e1Schristos else if (strncmp (fmt, "%<", 2) == 0) 4094e98e3e1Schristos /* explicit format */ 4104e98e3e1Schristos { 4114e98e3e1Schristos if (pass == 1) 4124e98e3e1Schristos lf_printf (file, "%%"); 4134e98e3e1Schristos else 4144e98e3e1Schristos lf_write (file, param, strlen_param); 4154e98e3e1Schristos } 4164e98e3e1Schristos else if (strncmp (fmt, "%s<", 3) == 0) 4174e98e3e1Schristos /* string format */ 4184e98e3e1Schristos { 4194e98e3e1Schristos if (pass == 1) 4204e98e3e1Schristos lf_printf (file, "%%s"); 4214e98e3e1Schristos else 4224e98e3e1Schristos { 4234e98e3e1Schristos lf_printf (file, "%sstr_", 4244e98e3e1Schristos options.module.global.prefix.l); 4254e98e3e1Schristos lf_write (file, func, strlen_func); 4264e98e3e1Schristos lf_printf (file, " (SD_, "); 4274e98e3e1Schristos lf_write (file, param, strlen_param); 4284e98e3e1Schristos lf_printf (file, ")"); 4294e98e3e1Schristos } 4304e98e3e1Schristos } 4314e98e3e1Schristos else if (strncmp (fmt, "%lx<", 4) == 0) 4324e98e3e1Schristos /* simple hex */ 4334e98e3e1Schristos { 4344e98e3e1Schristos if (pass == 1) 4354e98e3e1Schristos lf_printf (file, "%%lx"); 4364e98e3e1Schristos else 4374e98e3e1Schristos { 4384e98e3e1Schristos lf_printf (file, "(unsigned long) "); 4394e98e3e1Schristos lf_write (file, param, strlen_param); 4404e98e3e1Schristos } 4414e98e3e1Schristos } 4424e98e3e1Schristos else if (strncmp (fmt, "%#lx<", 5) == 0) 4434e98e3e1Schristos /* simple hex with 0x prefix */ 4444e98e3e1Schristos { 4454e98e3e1Schristos if (pass == 1) 4464e98e3e1Schristos lf_printf (file, "%%#lx"); 4474e98e3e1Schristos else 4484e98e3e1Schristos { 4494e98e3e1Schristos lf_printf (file, "(unsigned long) "); 4504e98e3e1Schristos lf_write (file, param, strlen_param); 4514e98e3e1Schristos } 4524e98e3e1Schristos } 4534e98e3e1Schristos else if (strncmp (fmt, "%08lx<", 6) == 0) 4544e98e3e1Schristos /* simple hex */ 4554e98e3e1Schristos { 4564e98e3e1Schristos if (pass == 1) 4574e98e3e1Schristos lf_printf (file, "%%08lx"); 4584e98e3e1Schristos else 4594e98e3e1Schristos { 4604e98e3e1Schristos lf_printf (file, "(unsigned long) "); 4614e98e3e1Schristos lf_write (file, param, strlen_param); 4624e98e3e1Schristos } 4634e98e3e1Schristos } 4644e98e3e1Schristos else 4654e98e3e1Schristos error (assembler->line, "Unknown assembler string format\n"); 4664e98e3e1Schristos } 4674e98e3e1Schristos else 4684e98e3e1Schristos { 4694e98e3e1Schristos if (pass == 1) 4704e98e3e1Schristos lf_putchr (file, chp[0]); 4714e98e3e1Schristos chp += 1; 4724e98e3e1Schristos } 4734e98e3e1Schristos } 4744e98e3e1Schristos } 4754e98e3e1Schristos lf_printf (file, ");\n"); 4764e98e3e1Schristos } 4774e98e3e1Schristos 4784e98e3e1Schristos 4794e98e3e1Schristos void 4804b169a6bSchristos print_itrace (lf *file, const insn_entry *insn, int idecode) 4814e98e3e1Schristos { 4824e98e3e1Schristos /* NB: Here we escape each EOLN. This is so that the the compiler 4834e98e3e1Schristos treats a trace function call as a single line. Consequently any 4844e98e3e1Schristos errors in the line are refered back to the same igen assembler 4854e98e3e1Schristos source line */ 4864e98e3e1Schristos const char *phase = (idecode) ? "DECODE" : "INSN"; 4874e98e3e1Schristos lf_printf (file, "\n"); 4884e98e3e1Schristos lf_indent_suppress (file); 4894e98e3e1Schristos lf_printf (file, "#if defined (WITH_TRACE)\n"); 4904e98e3e1Schristos lf_printf (file, "/* generate a trace prefix if any tracing enabled */\n"); 4914e98e3e1Schristos lf_printf (file, "if (TRACE_ANY_P (CPU))\n"); 4924e98e3e1Schristos lf_printf (file, " {\n"); 4934e98e3e1Schristos lf_indent (file, +4); 4944e98e3e1Schristos { 4954e98e3e1Schristos if (insn->mnemonics != NULL) 4964e98e3e1Schristos { 4974e98e3e1Schristos insn_mnemonic_entry *assembler = insn->mnemonics; 4984e98e3e1Schristos int is_first = 1; 4994e98e3e1Schristos do 5004e98e3e1Schristos { 5014e98e3e1Schristos if (assembler->condition != NULL) 5024e98e3e1Schristos { 5034e98e3e1Schristos int indent; 5044e98e3e1Schristos lf_printf (file, "%sif (%s)\n", 5054e98e3e1Schristos is_first ? "" : "else ", assembler->condition); 5064e98e3e1Schristos lf_indent (file, +2); 5074e98e3e1Schristos lf_print__line_ref (file, assembler->line); 5084e98e3e1Schristos indent = print_itrace_prefix (file); 5094e98e3e1Schristos print_itrace_format (file, assembler); 5104e98e3e1Schristos lf_print__internal_ref (file); 5114e98e3e1Schristos lf_indent (file, -indent); 5124e98e3e1Schristos lf_indent (file, -2); 5134e98e3e1Schristos if (assembler->next == NULL) 5144e98e3e1Schristos error (assembler->line, 5154e98e3e1Schristos "Missing final unconditional assembler\n"); 5164e98e3e1Schristos } 5174e98e3e1Schristos else 5184e98e3e1Schristos { 5194e98e3e1Schristos int indent; 5204e98e3e1Schristos if (!is_first) 5214e98e3e1Schristos { 5224e98e3e1Schristos lf_printf (file, "else\n"); 5234e98e3e1Schristos lf_indent (file, +2); 5244e98e3e1Schristos } 5254e98e3e1Schristos lf_print__line_ref (file, assembler->line); 5264e98e3e1Schristos indent = print_itrace_prefix (file); 5274e98e3e1Schristos print_itrace_format (file, assembler); 5284e98e3e1Schristos lf_print__internal_ref (file); 5294e98e3e1Schristos lf_indent (file, -indent); 5304e98e3e1Schristos if (!is_first) 5314e98e3e1Schristos lf_indent (file, -2); 5324e98e3e1Schristos if (assembler->next != NULL) 5334e98e3e1Schristos error (assembler->line, 5344e98e3e1Schristos "Unconditional assembler is not last\n"); 5354e98e3e1Schristos } 5364e98e3e1Schristos is_first = 0; 5374e98e3e1Schristos assembler = assembler->next; 5384e98e3e1Schristos } 5394e98e3e1Schristos while (assembler != NULL); 5404e98e3e1Schristos } 5414e98e3e1Schristos else 5424e98e3e1Schristos { 5434e98e3e1Schristos int indent; 5444e98e3e1Schristos lf_indent (file, +2); 5454e98e3e1Schristos lf_print__line_ref (file, insn->line); 5464e98e3e1Schristos indent = print_itrace_prefix (file); 5474e98e3e1Schristos lf_printf (file, "%%s\", \\\n"); 5484e98e3e1Schristos lf_printf (file, "itable[MY_INDEX].name);\n"); 5494e98e3e1Schristos lf_print__internal_ref (file); 5504e98e3e1Schristos lf_indent (file, -indent); 5514e98e3e1Schristos lf_indent (file, -2); 5524e98e3e1Schristos } 5534e98e3e1Schristos lf_printf (file, "/* trace the instruction execution if enabled */\n"); 5544e98e3e1Schristos lf_printf (file, "if (TRACE_%s_P (CPU))\n", phase); 5554e98e3e1Schristos lf_printf (file, 5564e98e3e1Schristos " trace_generic (SD, CPU, TRACE_%s_IDX, \" %%s\", itable[MY_INDEX].name);\n", 5574e98e3e1Schristos phase); 5584e98e3e1Schristos } 5594e98e3e1Schristos lf_indent (file, -4); 5604e98e3e1Schristos lf_printf (file, " }\n"); 5614e98e3e1Schristos lf_indent_suppress (file); 5624e98e3e1Schristos lf_printf (file, "#endif\n"); 5634e98e3e1Schristos } 5644e98e3e1Schristos 5654e98e3e1Schristos 5664e98e3e1Schristos void 5674e98e3e1Schristos print_sim_engine_abort (lf *file, const char *message) 5684e98e3e1Schristos { 5694e98e3e1Schristos lf_printf (file, "sim_engine_abort (SD, CPU, cia, "); 5704e98e3e1Schristos lf_printf (file, "\"%s\"", message); 5714e98e3e1Schristos lf_printf (file, ");\n"); 5724e98e3e1Schristos } 5734e98e3e1Schristos 5744e98e3e1Schristos 5754e98e3e1Schristos void 5764e98e3e1Schristos print_include (lf *file, igen_module module) 5774e98e3e1Schristos { 5784e98e3e1Schristos lf_printf (file, "#include \"%s%s.h\"\n", module.prefix.l, module.suffix.l); 5794e98e3e1Schristos } 5804e98e3e1Schristos 5814e98e3e1Schristos void 5824e98e3e1Schristos print_include_inline (lf *file, igen_module module) 5834e98e3e1Schristos { 5844e98e3e1Schristos lf_printf (file, "#if C_REVEALS_MODULE_P (%s_INLINE)\n", module.suffix.u); 5854e98e3e1Schristos lf_printf (file, "#include \"%s%s.c\"\n", module.prefix.l, module.suffix.l); 5864e98e3e1Schristos lf_printf (file, "#else\n"); 5874e98e3e1Schristos print_include (file, module); 5884e98e3e1Schristos lf_printf (file, "#endif\n"); 5894e98e3e1Schristos lf_printf (file, "\n"); 5904e98e3e1Schristos } 5914e98e3e1Schristos 5924e98e3e1Schristos void 5934e98e3e1Schristos print_includes (lf *file) 5944e98e3e1Schristos { 5954e98e3e1Schristos lf_printf (file, "\n"); 5964e98e3e1Schristos lf_printf (file, "#include \"sim-inline.c\"\n"); 5974e98e3e1Schristos lf_printf (file, "\n"); 5984e98e3e1Schristos print_include_inline (file, options.module.itable); 5994e98e3e1Schristos print_include_inline (file, options.module.idecode); 6004e98e3e1Schristos print_include_inline (file, options.module.support); 6014e98e3e1Schristos } 6024e98e3e1Schristos 6034e98e3e1Schristos 6044e98e3e1Schristos /****************************************************************/ 6054e98e3e1Schristos 6064e98e3e1Schristos 6074e98e3e1Schristos static void 6084b169a6bSchristos gen_semantics_h (lf *file, const insn_list *semantics, int max_nr_words) 6094e98e3e1Schristos { 6104e98e3e1Schristos int word_nr; 6114b169a6bSchristos const insn_list *semantic; 6124e98e3e1Schristos for (word_nr = -1; word_nr <= max_nr_words; word_nr++) 6134e98e3e1Schristos { 6144e98e3e1Schristos lf_printf (file, "typedef "); 6154e98e3e1Schristos print_semantic_function_type (file); 6164e98e3e1Schristos lf_printf (file, " %sidecode_semantic", options.module.global.prefix.l); 6174e98e3e1Schristos if (word_nr >= 0) 6184e98e3e1Schristos lf_printf (file, "_%d", word_nr); 6194e98e3e1Schristos lf_printf (file, "\n("); 6204e98e3e1Schristos lf_indent (file, +1); 6214e98e3e1Schristos print_semantic_function_formal (file, word_nr); 6224e98e3e1Schristos lf_indent (file, -1); 6234e98e3e1Schristos lf_printf (file, ");\n"); 6244e98e3e1Schristos lf_printf (file, "\n"); 6254e98e3e1Schristos } 6264e98e3e1Schristos switch (options.gen.code) 6274e98e3e1Schristos { 6284e98e3e1Schristos case generate_calls: 6294e98e3e1Schristos for (semantic = semantics; semantic != NULL; semantic = semantic->next) 6304e98e3e1Schristos { 6314e98e3e1Schristos /* Ignore any special/internal instructions */ 6324e98e3e1Schristos if (semantic->insn->nr_words == 0) 6334e98e3e1Schristos continue; 6344e98e3e1Schristos print_semantic_declaration (file, 6354e98e3e1Schristos semantic->insn, 6364e98e3e1Schristos semantic->expanded_bits, 6374e98e3e1Schristos semantic->opcodes, 6384e98e3e1Schristos semantic->nr_prefetched_words); 6394e98e3e1Schristos } 6404e98e3e1Schristos break; 6414e98e3e1Schristos case generate_jumps: 6424e98e3e1Schristos lf_print__this_file_is_empty (file, "generating jumps"); 6434e98e3e1Schristos break; 6444e98e3e1Schristos } 6454e98e3e1Schristos } 6464e98e3e1Schristos 6474e98e3e1Schristos 6484e98e3e1Schristos static void 6494b169a6bSchristos gen_semantics_c (lf *file, const insn_list *semantics, cache_entry *cache_rules) 6504e98e3e1Schristos { 6514e98e3e1Schristos if (options.gen.code == generate_calls) 6524e98e3e1Schristos { 6534b169a6bSchristos const insn_list *semantic; 6544e98e3e1Schristos print_includes (file); 6554e98e3e1Schristos print_include (file, options.module.semantics); 6564e98e3e1Schristos lf_printf (file, "\n"); 6574e98e3e1Schristos 6584e98e3e1Schristos for (semantic = semantics; semantic != NULL; semantic = semantic->next) 6594e98e3e1Schristos { 6604e98e3e1Schristos /* Ignore any special/internal instructions */ 6614e98e3e1Schristos if (semantic->insn->nr_words == 0) 6624e98e3e1Schristos continue; 6634e98e3e1Schristos print_semantic_definition (file, 6644e98e3e1Schristos semantic->insn, 6654e98e3e1Schristos semantic->expanded_bits, 6664e98e3e1Schristos semantic->opcodes, 6674e98e3e1Schristos cache_rules, 6684e98e3e1Schristos semantic->nr_prefetched_words); 6694e98e3e1Schristos } 6704e98e3e1Schristos } 6714e98e3e1Schristos else 6724e98e3e1Schristos { 6734e98e3e1Schristos lf_print__this_file_is_empty (file, "generating jump engine"); 6744e98e3e1Schristos } 6754e98e3e1Schristos } 6764e98e3e1Schristos 6774e98e3e1Schristos 6784e98e3e1Schristos /****************************************************************/ 6794e98e3e1Schristos 6804e98e3e1Schristos 6814e98e3e1Schristos static void 6824e98e3e1Schristos gen_icache_h (lf *file, 6834b169a6bSchristos const insn_list *semantic, 6844b169a6bSchristos const function_entry *functions, int max_nr_words) 6854e98e3e1Schristos { 6864e98e3e1Schristos int word_nr; 6874e98e3e1Schristos for (word_nr = 0; word_nr <= max_nr_words; word_nr++) 6884e98e3e1Schristos { 6894e98e3e1Schristos lf_printf (file, "typedef "); 6904e98e3e1Schristos print_icache_function_type (file); 6914e98e3e1Schristos lf_printf (file, " %sidecode_icache_%d\n(", 6924e98e3e1Schristos options.module.global.prefix.l, word_nr); 6934e98e3e1Schristos print_icache_function_formal (file, word_nr); 6944e98e3e1Schristos lf_printf (file, ");\n"); 6954e98e3e1Schristos lf_printf (file, "\n"); 6964e98e3e1Schristos } 6974e98e3e1Schristos if (options.gen.code == generate_calls && options.gen.icache) 6984e98e3e1Schristos { 6994e98e3e1Schristos function_entry_traverse (file, functions, 7004e98e3e1Schristos print_icache_internal_function_declaration, 7014e98e3e1Schristos NULL); 7024e98e3e1Schristos while (semantic != NULL) 7034e98e3e1Schristos { 7044e98e3e1Schristos print_icache_declaration (file, 7054e98e3e1Schristos semantic->insn, 7064e98e3e1Schristos semantic->expanded_bits, 7074e98e3e1Schristos semantic->opcodes, 7084e98e3e1Schristos semantic->nr_prefetched_words); 7094e98e3e1Schristos semantic = semantic->next; 7104e98e3e1Schristos } 7114e98e3e1Schristos } 7124e98e3e1Schristos else 7134e98e3e1Schristos { 7144e98e3e1Schristos lf_print__this_file_is_empty (file, "generating jump engine"); 7154e98e3e1Schristos } 7164e98e3e1Schristos } 7174e98e3e1Schristos 7184e98e3e1Schristos static void 7194e98e3e1Schristos gen_icache_c (lf *file, 7204b169a6bSchristos const insn_list *semantic, 7214b169a6bSchristos const function_entry *functions, cache_entry *cache_rules) 7224e98e3e1Schristos { 7234e98e3e1Schristos /* output `internal' invalid/floating-point unavailable functions 7244e98e3e1Schristos where needed */ 7254e98e3e1Schristos if (options.gen.code == generate_calls && options.gen.icache) 7264e98e3e1Schristos { 7274e98e3e1Schristos lf_printf (file, "\n"); 7284e98e3e1Schristos lf_printf (file, "#include \"cpu.h\"\n"); 7294e98e3e1Schristos lf_printf (file, "#include \"idecode.h\"\n"); 7304e98e3e1Schristos lf_printf (file, "#include \"semantics.h\"\n"); 7314e98e3e1Schristos lf_printf (file, "#include \"icache.h\"\n"); 7324e98e3e1Schristos lf_printf (file, "#include \"support.h\"\n"); 7334e98e3e1Schristos lf_printf (file, "\n"); 7344e98e3e1Schristos function_entry_traverse (file, functions, 7354e98e3e1Schristos print_icache_internal_function_definition, 7364e98e3e1Schristos NULL); 7374e98e3e1Schristos lf_printf (file, "\n"); 7384e98e3e1Schristos while (semantic != NULL) 7394e98e3e1Schristos { 7404e98e3e1Schristos print_icache_definition (file, 7414e98e3e1Schristos semantic->insn, 7424e98e3e1Schristos semantic->expanded_bits, 7434e98e3e1Schristos semantic->opcodes, 7444e98e3e1Schristos cache_rules, 7454e98e3e1Schristos semantic->nr_prefetched_words); 7464e98e3e1Schristos semantic = semantic->next; 7474e98e3e1Schristos } 7484e98e3e1Schristos } 7494e98e3e1Schristos else 7504e98e3e1Schristos { 7514e98e3e1Schristos lf_print__this_file_is_empty (file, "generating jump engine"); 7524e98e3e1Schristos } 7534e98e3e1Schristos } 7544e98e3e1Schristos 7554e98e3e1Schristos 7564e98e3e1Schristos /****************************************************************/ 7574e98e3e1Schristos 7584e98e3e1Schristos 7594e98e3e1Schristos static void 7604e98e3e1Schristos gen_idecode_h (lf *file, 7614b169a6bSchristos const gen_table *gen, 7624b169a6bSchristos const insn_table *insns, 7634b169a6bSchristos cache_entry *cache_rules) 7644e98e3e1Schristos { 7654b169a6bSchristos lf_printf (file, "typedef uint%d_t %sinstruction_word;\n", 7664e98e3e1Schristos options.insn_bit_size, options.module.global.prefix.l); 7674e98e3e1Schristos if (options.gen.delayed_branch) 7684e98e3e1Schristos { 7694e98e3e1Schristos lf_printf (file, "typedef struct _%sinstruction_address {\n", 7704e98e3e1Schristos options.module.global.prefix.l); 7714e98e3e1Schristos lf_printf (file, " address_word ip; /* instruction pointer */\n"); 7724e98e3e1Schristos lf_printf (file, " address_word dp; /* delayed-slot pointer */\n"); 7734e98e3e1Schristos lf_printf (file, "} %sinstruction_address;\n", 7744e98e3e1Schristos options.module.global.prefix.l); 7754e98e3e1Schristos } 7764e98e3e1Schristos else 7774e98e3e1Schristos { 7784e98e3e1Schristos lf_printf (file, "typedef address_word %sinstruction_address;\n", 7794e98e3e1Schristos options.module.global.prefix.l); 7804e98e3e1Schristos 7814e98e3e1Schristos } 7824e98e3e1Schristos if (options.gen.nia == nia_is_invalid 7834e98e3e1Schristos && strlen (options.module.global.prefix.u) > 0) 7844e98e3e1Schristos { 7854e98e3e1Schristos lf_indent_suppress (file); 7864e98e3e1Schristos lf_printf (file, "#define %sINVALID_INSTRUCTION_ADDRESS ", 7874e98e3e1Schristos options.module.global.prefix.u); 7884e98e3e1Schristos lf_printf (file, "INVALID_INSTRUCTION_ADDRESS\n"); 7894e98e3e1Schristos } 7904e98e3e1Schristos lf_printf (file, "\n"); 7914e98e3e1Schristos print_icache_struct (file, insns, cache_rules); 7924e98e3e1Schristos lf_printf (file, "\n"); 7934e98e3e1Schristos if (options.gen.icache) 7944e98e3e1Schristos { 7954e98e3e1Schristos ERROR ("FIXME - idecode with icache suffering from bit-rot"); 7964e98e3e1Schristos } 7974e98e3e1Schristos else 7984e98e3e1Schristos { 7994e98e3e1Schristos gen_list *entry; 8004e98e3e1Schristos for (entry = gen->tables; entry != NULL; entry = entry->next) 8014e98e3e1Schristos { 8024e98e3e1Schristos print_idecode_issue_function_header (file, 8034e98e3e1Schristos (options.gen.multi_sim 8044e98e3e1Schristos ? entry->model->name 8054e98e3e1Schristos : NULL), 8064e98e3e1Schristos is_function_declaration, 8074e98e3e1Schristos 1 /*ALWAYS ONE WORD */ ); 8084e98e3e1Schristos } 8094e98e3e1Schristos if (options.gen.multi_sim) 8104e98e3e1Schristos { 8114e98e3e1Schristos print_idecode_issue_function_header (file, 8124e98e3e1Schristos NULL, 8134e98e3e1Schristos is_function_variable, 8144e98e3e1Schristos 1 /*ALWAYS ONE WORD */ ); 8154e98e3e1Schristos } 8164e98e3e1Schristos } 8174e98e3e1Schristos } 8184e98e3e1Schristos 8194e98e3e1Schristos 8204e98e3e1Schristos static void 8214e98e3e1Schristos gen_idecode_c (lf *file, 8224b169a6bSchristos const gen_table *gen, 8234b169a6bSchristos const insn_table *isa, 8244b169a6bSchristos cache_entry *cache_rules) 8254e98e3e1Schristos { 8264e98e3e1Schristos /* the intro */ 8274e98e3e1Schristos print_includes (file); 8284e98e3e1Schristos print_include_inline (file, options.module.semantics); 8294e98e3e1Schristos lf_printf (file, "\n"); 8304e98e3e1Schristos 8314e98e3e1Schristos print_idecode_globals (file); 8324e98e3e1Schristos lf_printf (file, "\n"); 8334e98e3e1Schristos 8344e98e3e1Schristos switch (options.gen.code) 8354e98e3e1Schristos { 8364e98e3e1Schristos case generate_calls: 8374e98e3e1Schristos { 8384e98e3e1Schristos gen_list *entry; 8394e98e3e1Schristos for (entry = gen->tables; entry != NULL; entry = entry->next) 8404e98e3e1Schristos { 8414e98e3e1Schristos print_idecode_lookups (file, entry->table, cache_rules); 8424e98e3e1Schristos 8434e98e3e1Schristos /* output the main idecode routine */ 8444e98e3e1Schristos if (!options.gen.icache) 8454e98e3e1Schristos { 8464e98e3e1Schristos print_idecode_issue_function_header (file, 8474e98e3e1Schristos (options.gen.multi_sim 8484e98e3e1Schristos ? entry->model->name 8494e98e3e1Schristos : NULL), 8504e98e3e1Schristos 1 /*is definition */ , 8514e98e3e1Schristos 1 /*ALWAYS ONE WORD */ ); 8524e98e3e1Schristos lf_printf (file, "{\n"); 8534e98e3e1Schristos lf_indent (file, +2); 8544e98e3e1Schristos lf_printf (file, "%sinstruction_address nia;\n", 8554e98e3e1Schristos options.module.global.prefix.l); 8564e98e3e1Schristos print_idecode_body (file, entry->table, "nia ="); 8574e98e3e1Schristos lf_printf (file, "return nia;"); 8584e98e3e1Schristos lf_indent (file, -2); 8594e98e3e1Schristos lf_printf (file, "}\n"); 8604e98e3e1Schristos } 8614e98e3e1Schristos } 8624e98e3e1Schristos break; 8634e98e3e1Schristos } 8644e98e3e1Schristos case generate_jumps: 8654e98e3e1Schristos { 8664e98e3e1Schristos lf_print__this_file_is_empty (file, "generating a jump engine"); 8674e98e3e1Schristos break; 8684e98e3e1Schristos } 8694e98e3e1Schristos } 8704e98e3e1Schristos } 8714e98e3e1Schristos 8724e98e3e1Schristos 8734e98e3e1Schristos /****************************************************************/ 8744e98e3e1Schristos 8754e98e3e1Schristos 8764e98e3e1Schristos static void 8774b169a6bSchristos gen_run_c (lf *file, const gen_table *gen) 8784e98e3e1Schristos { 8794e98e3e1Schristos gen_list *entry; 8804e98e3e1Schristos lf_printf (file, "#include \"sim-main.h\"\n"); 8814e98e3e1Schristos lf_printf (file, "#include \"engine.h\"\n"); 8824e98e3e1Schristos lf_printf (file, "#include \"idecode.h\"\n"); 8834e98e3e1Schristos lf_printf (file, "#include \"bfd.h\"\n"); 8844e98e3e1Schristos lf_printf (file, "\n"); 8854e98e3e1Schristos 8864e98e3e1Schristos if (options.gen.multi_sim) 8874e98e3e1Schristos { 8884e98e3e1Schristos print_idecode_issue_function_header (file, NULL, is_function_variable, 8894e98e3e1Schristos 1); 8904e98e3e1Schristos lf_printf (file, "\n"); 8914e98e3e1Schristos print_engine_run_function_header (file, NULL, is_function_variable); 8924e98e3e1Schristos lf_printf (file, "\n"); 8934e98e3e1Schristos } 8944e98e3e1Schristos 8954e98e3e1Schristos lf_printf (file, "void\n"); 8964e98e3e1Schristos lf_printf (file, "sim_engine_run (SIM_DESC sd,\n"); 8974e98e3e1Schristos lf_printf (file, " int next_cpu_nr,\n"); 8984e98e3e1Schristos lf_printf (file, " int nr_cpus,\n"); 8994e98e3e1Schristos lf_printf (file, " int siggnal)\n"); 9004e98e3e1Schristos lf_printf (file, "{\n"); 9014e98e3e1Schristos lf_indent (file, +2); 9024e98e3e1Schristos if (options.gen.multi_sim) 9034e98e3e1Schristos { 9044e98e3e1Schristos lf_printf (file, "int mach;\n"); 9054e98e3e1Schristos lf_printf (file, "if (STATE_ARCHITECTURE (sd) == NULL)\n"); 9064e98e3e1Schristos lf_printf (file, " mach = 0;\n"); 9074e98e3e1Schristos lf_printf (file, "else\n"); 9084e98e3e1Schristos lf_printf (file, " mach = STATE_ARCHITECTURE (sd)->mach;\n"); 9094e98e3e1Schristos lf_printf (file, "switch (mach)\n"); 9104e98e3e1Schristos lf_printf (file, " {\n"); 9114e98e3e1Schristos lf_indent (file, +2); 9124e98e3e1Schristos for (entry = gen->tables; entry != NULL; entry = entry->next) 9134e98e3e1Schristos { 9144e98e3e1Schristos if (options.gen.default_model != NULL 9154e98e3e1Schristos && (strcmp (entry->model->name, options.gen.default_model) == 0 9164e98e3e1Schristos || strcmp (entry->model->full_name, 9174e98e3e1Schristos options.gen.default_model) == 0)) 9184e98e3e1Schristos lf_printf (file, "default:\n"); 9194e98e3e1Schristos lf_printf (file, "case bfd_mach_%s:\n", entry->model->full_name); 9204e98e3e1Schristos lf_indent (file, +2); 9214e98e3e1Schristos print_function_name (file, "issue", NULL, /* format name */ 9224e98e3e1Schristos NULL, /* NO processor */ 9234e98e3e1Schristos NULL, /* expanded bits */ 9244e98e3e1Schristos function_name_prefix_idecode); 9254e98e3e1Schristos lf_printf (file, " = "); 9264e98e3e1Schristos print_function_name (file, "issue", NULL, /* format name */ 9274e98e3e1Schristos entry->model->name, NULL, /* expanded bits */ 9284e98e3e1Schristos function_name_prefix_idecode); 9294e98e3e1Schristos lf_printf (file, ";\n"); 9304e98e3e1Schristos print_function_name (file, "run", NULL, /* format name */ 9314e98e3e1Schristos NULL, /* NO processor */ 9324e98e3e1Schristos NULL, /* expanded bits */ 9334e98e3e1Schristos function_name_prefix_engine); 9344e98e3e1Schristos lf_printf (file, " = "); 9354e98e3e1Schristos print_function_name (file, "run", NULL, /* format name */ 9364e98e3e1Schristos entry->model->name, NULL, /* expanded bits */ 9374e98e3e1Schristos function_name_prefix_engine); 9384e98e3e1Schristos lf_printf (file, ";\n"); 9394e98e3e1Schristos lf_printf (file, "break;\n"); 9404e98e3e1Schristos lf_indent (file, -2); 9414e98e3e1Schristos } 9424e98e3e1Schristos if (options.gen.default_model == NULL) 9434e98e3e1Schristos { 9444e98e3e1Schristos lf_printf (file, "default:\n"); 9454e98e3e1Schristos lf_indent (file, +2); 9464e98e3e1Schristos lf_printf (file, "sim_engine_abort (sd, NULL, NULL_CIA,\n"); 9474e98e3e1Schristos lf_printf (file, 9484e98e3e1Schristos " \"sim_engine_run - unknown machine\");\n"); 9494e98e3e1Schristos lf_printf (file, "break;\n"); 9504e98e3e1Schristos lf_indent (file, -2); 9514e98e3e1Schristos } 9524e98e3e1Schristos lf_indent (file, -2); 9534e98e3e1Schristos lf_printf (file, " }\n"); 9544e98e3e1Schristos } 9554e98e3e1Schristos print_function_name (file, "run", NULL, /* format name */ 9564e98e3e1Schristos NULL, /* NO processor */ 9574e98e3e1Schristos NULL, /* expanded bits */ 9584e98e3e1Schristos function_name_prefix_engine); 9594e98e3e1Schristos lf_printf (file, " (sd, next_cpu_nr, nr_cpus, siggnal);\n"); 9604e98e3e1Schristos lf_indent (file, -2); 9614e98e3e1Schristos lf_printf (file, "}\n"); 9624e98e3e1Schristos } 9634e98e3e1Schristos 9644e98e3e1Schristos /****************************************************************/ 9654e98e3e1Schristos 9664e98e3e1Schristos static gen_table * 9674b169a6bSchristos do_gen (const insn_table *isa, const decode_table *decode_rules) 9684e98e3e1Schristos { 9694e98e3e1Schristos gen_table *gen; 9704e98e3e1Schristos if (decode_rules == NULL) 9714e98e3e1Schristos error (NULL, "Must specify a decode table\n"); 9724e98e3e1Schristos if (isa == NULL) 9734e98e3e1Schristos error (NULL, "Must specify an instruction table\n"); 9744e98e3e1Schristos if (decode_table_max_word_nr (decode_rules) > 0) 9754e98e3e1Schristos options.gen.multi_word = decode_table_max_word_nr (decode_rules); 9764e98e3e1Schristos gen = make_gen_tables (isa, decode_rules); 9774e98e3e1Schristos gen_tables_expand_insns (gen); 9784e98e3e1Schristos gen_tables_expand_semantics (gen); 9794e98e3e1Schristos return gen; 9804e98e3e1Schristos } 9814e98e3e1Schristos 9824e98e3e1Schristos /****************************************************************/ 9834e98e3e1Schristos 9844e98e3e1Schristos igen_options options; 9854e98e3e1Schristos 9864e98e3e1Schristos int 9874e98e3e1Schristos main (int argc, char **argv, char **envp) 9884e98e3e1Schristos { 9894e98e3e1Schristos cache_entry *cache_rules = NULL; 9904e98e3e1Schristos lf_file_references file_references = lf_include_references; 9914e98e3e1Schristos decode_table *decode_rules = NULL; 9924e98e3e1Schristos insn_table *isa = NULL; 9934e98e3e1Schristos gen_table *gen = NULL; 9944e98e3e1Schristos char *real_file_name = NULL; 9954e98e3e1Schristos int is_header = 0; 9964e98e3e1Schristos int ch; 9974b169a6bSchristos static const struct option longopts[] = { { 0 } }; 9984e98e3e1Schristos lf *standard_out = 9994e98e3e1Schristos lf_open ("-", "stdout", lf_omit_references, lf_is_text, "igen"); 10004e98e3e1Schristos 10014e98e3e1Schristos INIT_OPTIONS (); 10024e98e3e1Schristos 10034e98e3e1Schristos if (argc == 1) 10044e98e3e1Schristos { 10054e98e3e1Schristos printf ("Usage:\n"); 10064e98e3e1Schristos printf ("\n"); 10074e98e3e1Schristos printf (" igen <config-opts> ... <input-opts>... <output-opts>...\n"); 10084e98e3e1Schristos printf ("\n"); 10094e98e3e1Schristos printf ("Config options:\n"); 10104e98e3e1Schristos printf ("\n"); 10114e98e3e1Schristos printf (" -B <bit-size>\n"); 10124e98e3e1Schristos printf ("\t Set the number of bits in an instruction (deprecated).\n"); 10134e98e3e1Schristos printf 10144e98e3e1Schristos ("\t This option can now be set directly in the instruction table.\n"); 10154e98e3e1Schristos printf ("\n"); 10164e98e3e1Schristos printf (" -D <data-structure>\n"); 10174e98e3e1Schristos printf 10184e98e3e1Schristos ("\t Dump the specified data structure to stdout. Valid structures include:\n"); 10194e98e3e1Schristos printf 10204e98e3e1Schristos ("\t processor-names - list the names of all the processors (models)\n"); 10214e98e3e1Schristos printf ("\n"); 10224e98e3e1Schristos printf (" -F <filter-list>\n"); 10234e98e3e1Schristos printf 10244e98e3e1Schristos ("\t Filter out any instructions with a non-empty flags field that contains\n"); 10254e98e3e1Schristos printf ("\t a flag not listed in the <filter-list>.\n"); 10264e98e3e1Schristos printf ("\n"); 10274e98e3e1Schristos printf (" -H <high-bit>\n"); 10284e98e3e1Schristos printf 10294e98e3e1Schristos ("\t Set the number of the high (most significant) instruction bit (deprecated).\n"); 10304e98e3e1Schristos printf 10314e98e3e1Schristos ("\t This option can now be set directly in the instruction table.\n"); 10324e98e3e1Schristos printf ("\n"); 10334e98e3e1Schristos printf (" -I <directory>\n"); 10344e98e3e1Schristos printf 10354e98e3e1Schristos ("\t Add <directory> to the list of directories searched when opening a file\n"); 10364e98e3e1Schristos printf ("\n"); 10374e98e3e1Schristos printf (" -M <model-list>\n"); 10384e98e3e1Schristos printf 10394e98e3e1Schristos ("\t Filter out any instructions that do not support at least one of the listed\n"); 10404e98e3e1Schristos printf 10414e98e3e1Schristos ("\t models (An instructions with no model information is considered to support\n"); 10424e98e3e1Schristos printf ("\t all models.).\n"); 10434e98e3e1Schristos printf ("\n"); 10444e98e3e1Schristos printf (" -N <nr-cpus>\n"); 10454e98e3e1Schristos printf ("\t Generate a simulator supporting <nr-cpus>\n"); 10464e98e3e1Schristos printf 10474e98e3e1Schristos ("\t Specify `-N 0' to disable generation of the SMP. Specifying `-N 1' will\n"); 10484e98e3e1Schristos printf 10494e98e3e1Schristos ("\t still generate an SMP enabled simulator but will only support one CPU.\n"); 10504e98e3e1Schristos printf ("\n"); 10514e98e3e1Schristos printf (" -T <mechanism>\n"); 10524e98e3e1Schristos printf 10534e98e3e1Schristos ("\t Override the decode mechanism specified by the decode rules\n"); 10544e98e3e1Schristos printf ("\n"); 10554e98e3e1Schristos printf (" -P <prefix>\n"); 10564e98e3e1Schristos printf 10574e98e3e1Schristos ("\t Prepend global names (except itable) with the string <prefix>.\n"); 10584e98e3e1Schristos printf 10594e98e3e1Schristos ("\t Specify -P <module>=<prefix> to set a specific <module>'s prefix.\n"); 10604e98e3e1Schristos printf ("\n"); 10614e98e3e1Schristos printf (" -S <suffix>\n"); 10624e98e3e1Schristos printf 10634e98e3e1Schristos ("\t Replace a global name (suffix) (except itable) with the string <suffix>.\n"); 10644e98e3e1Schristos printf 10654e98e3e1Schristos ("\t Specify -S <module>=<suffix> to change a specific <module>'s name (suffix).\n"); 10664e98e3e1Schristos printf ("\n"); 10674e98e3e1Schristos printf (" -Werror\n"); 10684e98e3e1Schristos printf ("\t Make warnings errors\n"); 10694e98e3e1Schristos printf (" -Wnodiscard\n"); 10704e98e3e1Schristos printf 10714e98e3e1Schristos ("\t Suppress warnings about discarded functions and instructions\n"); 10724e98e3e1Schristos printf (" -Wnowidth\n"); 10734e98e3e1Schristos printf 10744e98e3e1Schristos ("\t Suppress warnings about instructions with invalid widths\n"); 10754e98e3e1Schristos printf (" -Wnounimplemented\n"); 10764e98e3e1Schristos printf ("\t Suppress warnings about unimplemented instructions\n"); 10774e98e3e1Schristos printf ("\n"); 10784e98e3e1Schristos printf (" -G [!]<gen-option>\n"); 10794e98e3e1Schristos printf ("\t Any of the following options:\n"); 10804e98e3e1Schristos printf ("\n"); 10814e98e3e1Schristos printf 10824e98e3e1Schristos ("\t decode-duplicate - Override the decode rules, forcing the duplication of\n"); 10834e98e3e1Schristos printf ("\t semantic functions\n"); 10844e98e3e1Schristos printf 10854e98e3e1Schristos ("\t decode-combine - Combine any duplicated entries within a table\n"); 10864e98e3e1Schristos printf 10874e98e3e1Schristos ("\t decode-zero-reserved - Override the decode rules, forcing reserved bits to be\n"); 10884e98e3e1Schristos printf ("\t treated as zero.\n"); 10894e98e3e1Schristos printf 10904e98e3e1Schristos ("\t decode-switch-is-goto - Overfide the padded-switch code type as a goto-switch\n"); 10914e98e3e1Schristos printf ("\n"); 10924e98e3e1Schristos printf 10934e98e3e1Schristos ("\t gen-conditional-issue - conditionally issue each instruction\n"); 10944e98e3e1Schristos printf 10954e98e3e1Schristos ("\t gen-delayed-branch - need both cia and nia passed around\n"); 10964e98e3e1Schristos printf 10974e98e3e1Schristos ("\t gen-direct-access - use #defines to directly access values\n"); 10984e98e3e1Schristos printf 10994e98e3e1Schristos ("\t gen-zero-r<N> - arch assumes GPR(<N>) == 0, keep it that way\n"); 11004e98e3e1Schristos printf 11014e98e3e1Schristos ("\t gen-icache[=<N> - generate an instruction cracking cache of size <N>\n"); 11024e98e3e1Schristos printf ("\t Default size is %d\n", 11034e98e3e1Schristos options.gen.icache_size); 11044e98e3e1Schristos printf 11054e98e3e1Schristos ("\t gen-insn-in-icache - save original instruction when cracking\n"); 11064e98e3e1Schristos printf 11074e98e3e1Schristos ("\t gen-multi-sim[=MODEL] - generate multiple simulators - one per model\n"); 11084e98e3e1Schristos printf 11094e98e3e1Schristos ("\t If specified MODEL is made the default architecture.\n"); 11104e98e3e1Schristos printf 11114e98e3e1Schristos ("\t By default, a single simulator that will\n"); 11124e98e3e1Schristos printf 11134e98e3e1Schristos ("\t execute any instruction is generated\n"); 11144e98e3e1Schristos printf 11154e98e3e1Schristos ("\t gen-multi-word - generate code allowing for multi-word insns\n"); 11164e98e3e1Schristos printf 11174e98e3e1Schristos ("\t gen-semantic-icache - include semantic code in cracking functions\n"); 11184e98e3e1Schristos printf 11194e98e3e1Schristos ("\t gen-slot-verification - perform slot verification as part of decode\n"); 11204e98e3e1Schristos printf ("\t gen-nia-invalid - NIA defaults to nia_invalid\n"); 11214e98e3e1Schristos printf ("\t gen-nia-void - do not compute/return NIA\n"); 11224e98e3e1Schristos printf ("\n"); 11234e98e3e1Schristos printf 11244e98e3e1Schristos ("\t trace-combine - report combined entries a rule application\n"); 11254e98e3e1Schristos printf 11264e98e3e1Schristos ("\t trace-entries - report entries after a rules application\n"); 11274e98e3e1Schristos printf ("\t trace-rule-rejection - report each rule as rejected\n"); 11284e98e3e1Schristos printf ("\t trace-rule-selection - report each rule as selected\n"); 11294e98e3e1Schristos printf 11304e98e3e1Schristos ("\t trace-insn-insertion - report each instruction as it is inserted into a decode table\n"); 11314e98e3e1Schristos printf 11324e98e3e1Schristos ("\t trace-rule-expansion - report each instruction as it is expanded (before insertion into a decode table)\n"); 11334e98e3e1Schristos printf ("\t trace-all - enable all trace options\n"); 11344e98e3e1Schristos printf ("\n"); 11354e98e3e1Schristos printf 11364e98e3e1Schristos ("\t field-widths - instruction formats specify widths (deprecated)\n"); 11374e98e3e1Schristos printf 11384e98e3e1Schristos ("\t By default, an instruction format specifies bit\n"); 11394e98e3e1Schristos printf ("\t positions\n"); 11404e98e3e1Schristos printf 11414e98e3e1Schristos ("\t This option can now be set directly in the\n"); 11424e98e3e1Schristos printf ("\t instruction table\n"); 11434e98e3e1Schristos printf 11444e98e3e1Schristos ("\t jumps - use jumps instead of function calls\n"); 11454e98e3e1Schristos printf 11464e98e3e1Schristos ("\t omit-line-numbers - do not include line number information in the output\n"); 11474e98e3e1Schristos printf ("\n"); 11484e98e3e1Schristos printf ("Input options:\n"); 11494e98e3e1Schristos printf ("\n"); 11504e98e3e1Schristos printf (" -k <cache-rules> (deprecated)\n"); 11514e98e3e1Schristos printf (" -o <decode-rules>\n"); 11524e98e3e1Schristos printf (" -i <instruction-table>\n"); 11534e98e3e1Schristos printf ("\n"); 11544e98e3e1Schristos printf ("Output options:\n"); 11554e98e3e1Schristos printf ("\n"); 11564e98e3e1Schristos printf (" -x Perform expansion (required)\n"); 11574e98e3e1Schristos printf 11584e98e3e1Schristos (" -n <real-name> Specify the real name of the next output file\n"); 11594e98e3e1Schristos printf 11604e98e3e1Schristos (" -h Generate the header (.h) file rather than the body (.c)\n"); 11614e98e3e1Schristos printf (" -c <output-file> output icache\n"); 11624e98e3e1Schristos printf (" -d <output-file> output idecode\n"); 11634e98e3e1Schristos printf (" -e <output-file> output engine\n"); 11644e98e3e1Schristos printf (" -f <output-file> output support functions\n"); 11654e98e3e1Schristos printf (" -m <output-file> output model\n"); 11664e98e3e1Schristos printf (" -r <output-file> output multi-sim run\n"); 11674e98e3e1Schristos printf (" -s <output-file> output schematic\n"); 11684e98e3e1Schristos printf (" -t <output-file> output itable\n"); 11694e98e3e1Schristos } 11704e98e3e1Schristos 11714b169a6bSchristos while ((ch = getopt_long (argc, argv, 11724b169a6bSchristos "B:D:F:G:H:I:M:N:P:T:W:o:k:i:n:hc:d:e:m:r:s:t:f:x", 11734b169a6bSchristos longopts, NULL)) 11744e98e3e1Schristos != -1) 11754e98e3e1Schristos { 11764b169a6bSchristos #if 0 /* For debugging. */ 11774e98e3e1Schristos fprintf (stderr, " -%c ", ch); 11784e98e3e1Schristos if (optarg) 11794e98e3e1Schristos fprintf (stderr, "%s ", optarg); 11804e98e3e1Schristos fprintf (stderr, "\\\n"); 11814b169a6bSchristos #endif 11824e98e3e1Schristos 11834e98e3e1Schristos switch (ch) 11844e98e3e1Schristos { 11854e98e3e1Schristos 11864e98e3e1Schristos case 'M': 11874e98e3e1Schristos filter_parse (&options.model_filter, optarg); 11884e98e3e1Schristos break; 11894e98e3e1Schristos 11904e98e3e1Schristos case 'D': 11914e98e3e1Schristos if (strcmp (optarg, "processor-names")) 11924e98e3e1Schristos { 11934b169a6bSchristos const char *processor; 11944e98e3e1Schristos for (processor = filter_next (options.model_filter, ""); 11954e98e3e1Schristos processor != NULL; 11964e98e3e1Schristos processor = filter_next (options.model_filter, processor)) 11974e98e3e1Schristos lf_printf (standard_out, "%s\n", processor); 11984e98e3e1Schristos } 11994e98e3e1Schristos else 12004e98e3e1Schristos error (NULL, "Unknown data structure %s, not dumped\n", optarg); 12014e98e3e1Schristos break; 12024e98e3e1Schristos 12034e98e3e1Schristos case 'F': 12044e98e3e1Schristos filter_parse (&options.flags_filter, optarg); 12054e98e3e1Schristos break; 12064e98e3e1Schristos 12074e98e3e1Schristos case 'I': 12084e98e3e1Schristos { 12094e98e3e1Schristos table_include **dir = &options.include; 12104e98e3e1Schristos while ((*dir) != NULL) 12114e98e3e1Schristos dir = &(*dir)->next; 12124e98e3e1Schristos (*dir) = ZALLOC (table_include); 12134e98e3e1Schristos (*dir)->dir = strdup (optarg); 12144e98e3e1Schristos } 12154e98e3e1Schristos break; 12164e98e3e1Schristos 12174e98e3e1Schristos case 'B': 12184e98e3e1Schristos options.insn_bit_size = a2i (optarg); 12194e98e3e1Schristos if (options.insn_bit_size <= 0 12204e98e3e1Schristos || options.insn_bit_size > max_insn_bit_size) 12214e98e3e1Schristos { 12224e98e3e1Schristos error (NULL, "Instruction bitsize must be in range 1..%d\n", 12234e98e3e1Schristos max_insn_bit_size); 12244e98e3e1Schristos } 12254e98e3e1Schristos if (options.hi_bit_nr != options.insn_bit_size - 1 12264e98e3e1Schristos && options.hi_bit_nr != 0) 12274e98e3e1Schristos { 12284e98e3e1Schristos error (NULL, "Conflict betweem hi-bit-nr and insn-bit-size\n"); 12294e98e3e1Schristos } 12304e98e3e1Schristos break; 12314e98e3e1Schristos 12324e98e3e1Schristos case 'H': 12334e98e3e1Schristos options.hi_bit_nr = a2i (optarg); 12344e98e3e1Schristos if (options.hi_bit_nr != options.insn_bit_size - 1 12354e98e3e1Schristos && options.hi_bit_nr != 0) 12364e98e3e1Schristos { 12374e98e3e1Schristos error (NULL, "Conflict between hi-bit-nr and insn-bit-size\n"); 12384e98e3e1Schristos } 12394e98e3e1Schristos break; 12404e98e3e1Schristos 12414e98e3e1Schristos case 'N': 12424e98e3e1Schristos options.gen.smp = a2i (optarg); 12434e98e3e1Schristos break; 12444e98e3e1Schristos 12454e98e3e1Schristos case 'P': 12464e98e3e1Schristos case 'S': 12474e98e3e1Schristos { 12484e98e3e1Schristos igen_module *names; 12494e98e3e1Schristos igen_name *name; 12504e98e3e1Schristos char *chp; 12514e98e3e1Schristos chp = strchr (optarg, '='); 12524e98e3e1Schristos if (chp == NULL) 12534e98e3e1Schristos { 12544e98e3e1Schristos names = &options.module.global; 12554e98e3e1Schristos chp = optarg; 12564e98e3e1Schristos } 12574e98e3e1Schristos else 12584e98e3e1Schristos { 12594e98e3e1Schristos chp = chp + 1; /* skip `=' */ 12604e98e3e1Schristos names = NULL; 12614e98e3e1Schristos if (strncmp (optarg, "global=", chp - optarg) == 0) 12624e98e3e1Schristos { 12634e98e3e1Schristos names = &options.module.global; 12644e98e3e1Schristos } 12654e98e3e1Schristos if (strncmp (optarg, "engine=", chp - optarg) == 0) 12664e98e3e1Schristos { 12674e98e3e1Schristos names = &options.module.engine; 12684e98e3e1Schristos } 12694e98e3e1Schristos if (strncmp (optarg, "icache=", chp - optarg) == 0) 12704e98e3e1Schristos { 12714e98e3e1Schristos names = &options.module.icache; 12724e98e3e1Schristos } 12734e98e3e1Schristos if (strncmp (optarg, "idecode=", chp - optarg) == 0) 12744e98e3e1Schristos { 12754e98e3e1Schristos names = &options.module.idecode; 12764e98e3e1Schristos } 12774e98e3e1Schristos if (strncmp (optarg, "itable=", chp - optarg) == 0) 12784e98e3e1Schristos { 12794e98e3e1Schristos names = &options.module.itable; 12804e98e3e1Schristos } 12814e98e3e1Schristos if (strncmp (optarg, "semantics=", chp - optarg) == 0) 12824e98e3e1Schristos { 12834e98e3e1Schristos names = &options.module.semantics; 12844e98e3e1Schristos } 12854e98e3e1Schristos if (strncmp (optarg, "support=", chp - optarg) == 0) 12864e98e3e1Schristos { 12874e98e3e1Schristos names = &options.module.support; 12884e98e3e1Schristos } 12894e98e3e1Schristos if (names == NULL) 12904e98e3e1Schristos { 12914e98e3e1Schristos error (NULL, "Prefix `%s' unreconized\n", optarg); 12924e98e3e1Schristos } 12934e98e3e1Schristos } 12944e98e3e1Schristos switch (ch) 12954e98e3e1Schristos { 12964e98e3e1Schristos case 'P': 12974e98e3e1Schristos name = &names->prefix; 12984e98e3e1Schristos break; 12994e98e3e1Schristos case 'S': 13004e98e3e1Schristos name = &names->suffix; 13014e98e3e1Schristos break; 13024e98e3e1Schristos default: 13034e98e3e1Schristos abort (); /* Bad switch. */ 13044e98e3e1Schristos } 13054e98e3e1Schristos name->u = strdup (chp); 13064e98e3e1Schristos name->l = strdup (chp); 13074e98e3e1Schristos chp = name->u; 13084e98e3e1Schristos while (*chp) 13094e98e3e1Schristos { 13104e98e3e1Schristos if (islower (*chp)) 13114e98e3e1Schristos *chp = toupper (*chp); 13124e98e3e1Schristos chp++; 13134e98e3e1Schristos } 13144e98e3e1Schristos if (name == &options.module.global.prefix) 13154e98e3e1Schristos { 13164e98e3e1Schristos options.module.engine.prefix = options.module.global.prefix; 13174e98e3e1Schristos options.module.icache.prefix = options.module.global.prefix; 13184e98e3e1Schristos options.module.idecode.prefix = options.module.global.prefix; 13194e98e3e1Schristos /* options.module.itable.prefix = options.module.global.prefix; */ 13204e98e3e1Schristos options.module.semantics.prefix = 13214e98e3e1Schristos options.module.global.prefix; 13224e98e3e1Schristos options.module.support.prefix = options.module.global.prefix; 13234e98e3e1Schristos } 13244e98e3e1Schristos if (name == &options.module.global.suffix) 13254e98e3e1Schristos { 13264e98e3e1Schristos options.module.engine.suffix = options.module.global.suffix; 13274e98e3e1Schristos options.module.icache.suffix = options.module.global.suffix; 13284e98e3e1Schristos options.module.idecode.suffix = options.module.global.suffix; 13294e98e3e1Schristos /* options.module.itable.suffix = options.module.global.suffix; */ 13304e98e3e1Schristos options.module.semantics.suffix = 13314e98e3e1Schristos options.module.global.suffix; 13324e98e3e1Schristos options.module.support.suffix = options.module.global.suffix; 13334e98e3e1Schristos } 13344e98e3e1Schristos break; 13354e98e3e1Schristos } 13364e98e3e1Schristos 13374e98e3e1Schristos case 'W': 13384e98e3e1Schristos { 13394e98e3e1Schristos if (strcmp (optarg, "error") == 0) 13404e98e3e1Schristos options.warning = error; 13414e98e3e1Schristos else if (strcmp (optarg, "nodiscard") == 0) 13424e98e3e1Schristos options.warn.discard = 0; 13434e98e3e1Schristos else if (strcmp (optarg, "discard") == 0) 13444e98e3e1Schristos options.warn.discard = 1; 13454e98e3e1Schristos else if (strcmp (optarg, "nowidth") == 0) 13464e98e3e1Schristos options.warn.width = 0; 13474e98e3e1Schristos else if (strcmp (optarg, "width") == 0) 13484e98e3e1Schristos options.warn.width = 1; 13494e98e3e1Schristos else if (strcmp (optarg, "nounimplemented") == 0) 13504e98e3e1Schristos options.warn.unimplemented = 0; 13514e98e3e1Schristos else if (strcmp (optarg, "unimplemented") == 0) 13524e98e3e1Schristos options.warn.unimplemented = 1; 13534e98e3e1Schristos else 13544e98e3e1Schristos error (NULL, "Unknown -W argument `%s'\n", optarg); 13554e98e3e1Schristos break; 13564e98e3e1Schristos } 13574e98e3e1Schristos 13584e98e3e1Schristos 13594e98e3e1Schristos case 'G': 13604e98e3e1Schristos { 13614e98e3e1Schristos int enable_p; 13624e98e3e1Schristos char *argp; 13634e98e3e1Schristos if (strncmp (optarg, "no-", strlen ("no-")) == 0) 13644e98e3e1Schristos { 13654e98e3e1Schristos argp = optarg + strlen ("no-"); 13664e98e3e1Schristos enable_p = 0; 13674e98e3e1Schristos } 13684e98e3e1Schristos else if (strncmp (optarg, "!", strlen ("!")) == 0) 13694e98e3e1Schristos { 13704e98e3e1Schristos argp = optarg + strlen ("no-"); 13714e98e3e1Schristos enable_p = 0; 13724e98e3e1Schristos } 13734e98e3e1Schristos else 13744e98e3e1Schristos { 13754e98e3e1Schristos argp = optarg; 13764e98e3e1Schristos enable_p = 1; 13774e98e3e1Schristos } 13784e98e3e1Schristos if (strcmp (argp, "decode-duplicate") == 0) 13794e98e3e1Schristos { 13804e98e3e1Schristos options.decode.duplicate = enable_p; 13814e98e3e1Schristos } 13824e98e3e1Schristos else if (strcmp (argp, "decode-combine") == 0) 13834e98e3e1Schristos { 13844e98e3e1Schristos options.decode.combine = enable_p; 13854e98e3e1Schristos } 13864e98e3e1Schristos else if (strcmp (argp, "decode-zero-reserved") == 0) 13874e98e3e1Schristos { 13884e98e3e1Schristos options.decode.zero_reserved = enable_p; 13894e98e3e1Schristos } 13904e98e3e1Schristos 13914e98e3e1Schristos else if (strcmp (argp, "gen-conditional-issue") == 0) 13924e98e3e1Schristos { 13934e98e3e1Schristos options.gen.conditional_issue = enable_p; 13944e98e3e1Schristos } 13954e98e3e1Schristos else if (strcmp (argp, "conditional-issue") == 0) 13964e98e3e1Schristos { 13974e98e3e1Schristos options.gen.conditional_issue = enable_p; 13984e98e3e1Schristos options.warning (NULL, 13994e98e3e1Schristos "Option conditional-issue replaced by gen-conditional-issue\n"); 14004e98e3e1Schristos } 14014e98e3e1Schristos else if (strcmp (argp, "gen-delayed-branch") == 0) 14024e98e3e1Schristos { 14034e98e3e1Schristos options.gen.delayed_branch = enable_p; 14044e98e3e1Schristos } 14054e98e3e1Schristos else if (strcmp (argp, "delayed-branch") == 0) 14064e98e3e1Schristos { 14074e98e3e1Schristos options.gen.delayed_branch = enable_p; 14084e98e3e1Schristos options.warning (NULL, 14094e98e3e1Schristos "Option delayed-branch replaced by gen-delayed-branch\n"); 14104e98e3e1Schristos } 14114e98e3e1Schristos else if (strcmp (argp, "gen-direct-access") == 0) 14124e98e3e1Schristos { 14134e98e3e1Schristos options.gen.direct_access = enable_p; 14144e98e3e1Schristos } 14154e98e3e1Schristos else if (strcmp (argp, "direct-access") == 0) 14164e98e3e1Schristos { 14174e98e3e1Schristos options.gen.direct_access = enable_p; 14184e98e3e1Schristos options.warning (NULL, 14194e98e3e1Schristos "Option direct-access replaced by gen-direct-access\n"); 14204e98e3e1Schristos } 14214e98e3e1Schristos else if (strncmp (argp, "gen-zero-r", strlen ("gen-zero-r")) == 0) 14224e98e3e1Schristos { 14234e98e3e1Schristos options.gen.zero_reg = enable_p; 14244e98e3e1Schristos options.gen.zero_reg_nr = atoi (argp + strlen ("gen-zero-r")); 14254e98e3e1Schristos } 14264e98e3e1Schristos else if (strncmp (argp, "zero-r", strlen ("zero-r")) == 0) 14274e98e3e1Schristos { 14284e98e3e1Schristos options.gen.zero_reg = enable_p; 14294e98e3e1Schristos options.gen.zero_reg_nr = atoi (argp + strlen ("zero-r")); 14304e98e3e1Schristos options.warning (NULL, 14314e98e3e1Schristos "Option zero-r<N> replaced by gen-zero-r<N>\n"); 14324e98e3e1Schristos } 14334e98e3e1Schristos else if (strncmp (argp, "gen-icache", strlen ("gen-icache")) == 0) 14344e98e3e1Schristos { 14354e98e3e1Schristos switch (argp[strlen ("gen-icache")]) 14364e98e3e1Schristos { 14374e98e3e1Schristos case '=': 14384e98e3e1Schristos options.gen.icache_size = 14394e98e3e1Schristos atoi (argp + strlen ("gen-icache") + 1); 14404e98e3e1Schristos options.gen.icache = enable_p; 14414e98e3e1Schristos break; 14424e98e3e1Schristos case '\0': 14434e98e3e1Schristos options.gen.icache = enable_p; 14444e98e3e1Schristos break; 14454e98e3e1Schristos default: 14464e98e3e1Schristos error (NULL, 14474e98e3e1Schristos "Expecting -Ggen-icache or -Ggen-icache=<N>\n"); 14484e98e3e1Schristos } 14494e98e3e1Schristos } 14504e98e3e1Schristos else if (strcmp (argp, "gen-insn-in-icache") == 0) 14514e98e3e1Schristos { 14524e98e3e1Schristos options.gen.insn_in_icache = enable_p; 14534e98e3e1Schristos } 14544e98e3e1Schristos else if (strncmp (argp, "gen-multi-sim", strlen ("gen-multi-sim")) 14554e98e3e1Schristos == 0) 14564e98e3e1Schristos { 14574e98e3e1Schristos char *arg = &argp[strlen ("gen-multi-sim")]; 14584e98e3e1Schristos switch (arg[0]) 14594e98e3e1Schristos { 14604e98e3e1Schristos case '=': 14614e98e3e1Schristos options.gen.multi_sim = enable_p; 14624e98e3e1Schristos options.gen.default_model = arg + 1; 14634e98e3e1Schristos if (!filter_is_member 14644e98e3e1Schristos (options.model_filter, options.gen.default_model)) 14654e98e3e1Schristos error (NULL, "multi-sim model %s unknown\n", 14664e98e3e1Schristos options.gen.default_model); 14674e98e3e1Schristos break; 14684e98e3e1Schristos case '\0': 14694e98e3e1Schristos options.gen.multi_sim = enable_p; 14704e98e3e1Schristos options.gen.default_model = NULL; 14714e98e3e1Schristos break; 14724e98e3e1Schristos default: 14734e98e3e1Schristos error (NULL, 14744e98e3e1Schristos "Expecting -Ggen-multi-sim or -Ggen-multi-sim=<MODEL>\n"); 14754e98e3e1Schristos break; 14764e98e3e1Schristos } 14774e98e3e1Schristos } 14784e98e3e1Schristos else if (strcmp (argp, "gen-multi-word") == 0) 14794e98e3e1Schristos { 14804e98e3e1Schristos options.gen.multi_word = enable_p; 14814e98e3e1Schristos } 14824e98e3e1Schristos else if (strcmp (argp, "gen-semantic-icache") == 0) 14834e98e3e1Schristos { 14844e98e3e1Schristos options.gen.semantic_icache = enable_p; 14854e98e3e1Schristos } 14864e98e3e1Schristos else if (strcmp (argp, "gen-slot-verification") == 0) 14874e98e3e1Schristos { 14884e98e3e1Schristos options.gen.slot_verification = enable_p; 14894e98e3e1Schristos } 14904e98e3e1Schristos else if (strcmp (argp, "verify-slot") == 0) 14914e98e3e1Schristos { 14924e98e3e1Schristos options.gen.slot_verification = enable_p; 14934e98e3e1Schristos options.warning (NULL, 14944e98e3e1Schristos "Option verify-slot replaced by gen-slot-verification\n"); 14954e98e3e1Schristos } 14964e98e3e1Schristos else if (strcmp (argp, "gen-nia-invalid") == 0) 14974e98e3e1Schristos { 14984e98e3e1Schristos options.gen.nia = nia_is_invalid; 14994e98e3e1Schristos } 15004e98e3e1Schristos else if (strcmp (argp, "default-nia-minus-one") == 0) 15014e98e3e1Schristos { 15024e98e3e1Schristos options.gen.nia = nia_is_invalid; 15034e98e3e1Schristos options.warning (NULL, 15044e98e3e1Schristos "Option default-nia-minus-one replaced by gen-nia-invalid\n"); 15054e98e3e1Schristos } 15064e98e3e1Schristos else if (strcmp (argp, "gen-nia-void") == 0) 15074e98e3e1Schristos { 15084e98e3e1Schristos options.gen.nia = nia_is_void; 15094e98e3e1Schristos } 15104e98e3e1Schristos else if (strcmp (argp, "trace-all") == 0) 15114e98e3e1Schristos { 15124e98e3e1Schristos memset (&options.trace, enable_p, sizeof (options.trace)); 15134e98e3e1Schristos } 15144e98e3e1Schristos else if (strcmp (argp, "trace-combine") == 0) 15154e98e3e1Schristos { 15164e98e3e1Schristos options.trace.combine = enable_p; 15174e98e3e1Schristos } 15184e98e3e1Schristos else if (strcmp (argp, "trace-entries") == 0) 15194e98e3e1Schristos { 15204e98e3e1Schristos options.trace.entries = enable_p; 15214e98e3e1Schristos } 15224e98e3e1Schristos else if (strcmp (argp, "trace-rule-rejection") == 0) 15234e98e3e1Schristos { 15244e98e3e1Schristos options.trace.rule_rejection = enable_p; 15254e98e3e1Schristos } 15264e98e3e1Schristos else if (strcmp (argp, "trace-rule-selection") == 0) 15274e98e3e1Schristos { 15284e98e3e1Schristos options.trace.rule_selection = enable_p; 15294e98e3e1Schristos } 15304e98e3e1Schristos else if (strcmp (argp, "trace-insn-insertion") == 0) 15314e98e3e1Schristos { 15324e98e3e1Schristos options.trace.insn_insertion = enable_p; 15334e98e3e1Schristos } 15344e98e3e1Schristos else if (strcmp (argp, "trace-insn-expansion") == 0) 15354e98e3e1Schristos { 15364e98e3e1Schristos options.trace.insn_expansion = enable_p; 15374e98e3e1Schristos } 15384e98e3e1Schristos else if (strcmp (argp, "jumps") == 0) 15394e98e3e1Schristos { 15404e98e3e1Schristos options.gen.code = generate_jumps; 15414e98e3e1Schristos } 15424e98e3e1Schristos else if (strcmp (argp, "field-widths") == 0) 15434e98e3e1Schristos { 15444e98e3e1Schristos options.insn_specifying_widths = enable_p; 15454e98e3e1Schristos } 15464e98e3e1Schristos else if (strcmp (argp, "omit-line-numbers") == 0) 15474e98e3e1Schristos { 15484e98e3e1Schristos file_references = lf_omit_references; 15494e98e3e1Schristos } 15504e98e3e1Schristos else 15514e98e3e1Schristos { 15524e98e3e1Schristos error (NULL, "Unknown option %s\n", optarg); 15534e98e3e1Schristos } 15544e98e3e1Schristos break; 15554e98e3e1Schristos } 15564e98e3e1Schristos 15574e98e3e1Schristos case 'i': 15584e98e3e1Schristos isa = load_insn_table (optarg, cache_rules); 15594e98e3e1Schristos if (isa->illegal_insn == NULL) 15604e98e3e1Schristos error (NULL, "illegal-instruction missing from insn table\n"); 15614e98e3e1Schristos break; 15624e98e3e1Schristos 15634e98e3e1Schristos case 'x': 15644e98e3e1Schristos gen = do_gen (isa, decode_rules); 15654e98e3e1Schristos break; 15664e98e3e1Schristos 15674e98e3e1Schristos case 'o': 15684e98e3e1Schristos decode_rules = load_decode_table (optarg); 15694e98e3e1Schristos break; 15704e98e3e1Schristos 15714e98e3e1Schristos case 'k': 15724e98e3e1Schristos if (isa != NULL) 15734e98e3e1Schristos error (NULL, "Cache file must appear before the insn file\n"); 15744e98e3e1Schristos cache_rules = load_cache_table (optarg); 15754e98e3e1Schristos break; 15764e98e3e1Schristos 15774e98e3e1Schristos case 'n': 15784e98e3e1Schristos real_file_name = strdup (optarg); 15794e98e3e1Schristos break; 15804e98e3e1Schristos 15814e98e3e1Schristos case 'h': 15824e98e3e1Schristos is_header = 1; 15834e98e3e1Schristos break; 15844e98e3e1Schristos 15854e98e3e1Schristos case 'c': 15864e98e3e1Schristos case 'd': 15874e98e3e1Schristos case 'e': 15884e98e3e1Schristos case 'f': 15894e98e3e1Schristos case 'm': 15904e98e3e1Schristos case 'r': 15914e98e3e1Schristos case 's': 15924e98e3e1Schristos case 't': 15934e98e3e1Schristos { 15944e98e3e1Schristos lf *file = lf_open (optarg, real_file_name, file_references, 15954e98e3e1Schristos (is_header ? lf_is_h : lf_is_c), 15964e98e3e1Schristos argv[0]); 15974e98e3e1Schristos if (gen == NULL && ch != 't' && ch != 'm' && ch != 'f') 15984e98e3e1Schristos { 15994e98e3e1Schristos options.warning (NULL, 16004e98e3e1Schristos "Explicitly generate tables with -x option\n"); 16014e98e3e1Schristos gen = do_gen (isa, decode_rules); 16024e98e3e1Schristos } 16034e98e3e1Schristos lf_print__file_start (file); 16044e98e3e1Schristos switch (ch) 16054e98e3e1Schristos { 16064e98e3e1Schristos case 'm': 16074e98e3e1Schristos if (is_header) 16084e98e3e1Schristos gen_model_h (file, isa); 16094e98e3e1Schristos else 16104e98e3e1Schristos gen_model_c (file, isa); 16114e98e3e1Schristos break; 16124e98e3e1Schristos case 't': 16134e98e3e1Schristos if (is_header) 16144e98e3e1Schristos gen_itable_h (file, isa); 16154e98e3e1Schristos else 16164e98e3e1Schristos gen_itable_c (file, isa); 16174e98e3e1Schristos break; 16184e98e3e1Schristos case 'f': 16194e98e3e1Schristos if (is_header) 16204e98e3e1Schristos gen_support_h (file, isa); 16214e98e3e1Schristos else 16224e98e3e1Schristos gen_support_c (file, isa); 16234e98e3e1Schristos break; 16244e98e3e1Schristos case 'r': 16254e98e3e1Schristos if (is_header) 16264e98e3e1Schristos options.warning (NULL, "-hr option ignored\n"); 16274e98e3e1Schristos else 16284e98e3e1Schristos gen_run_c (file, gen); 16294e98e3e1Schristos break; 16304e98e3e1Schristos case 's': 16314e98e3e1Schristos if (is_header) 16324e98e3e1Schristos gen_semantics_h (file, gen->semantics, isa->max_nr_words); 16334e98e3e1Schristos else 16344e98e3e1Schristos gen_semantics_c (file, gen->semantics, isa->caches); 16354e98e3e1Schristos break; 16364e98e3e1Schristos case 'd': 16374e98e3e1Schristos if (is_header) 16384e98e3e1Schristos gen_idecode_h (file, gen, isa, cache_rules); 16394e98e3e1Schristos else 16404e98e3e1Schristos gen_idecode_c (file, gen, isa, cache_rules); 16414e98e3e1Schristos break; 16424e98e3e1Schristos case 'e': 16434e98e3e1Schristos if (is_header) 16444e98e3e1Schristos gen_engine_h (file, gen, isa, cache_rules); 16454e98e3e1Schristos else 16464e98e3e1Schristos gen_engine_c (file, gen, isa, cache_rules); 16474e98e3e1Schristos break; 16484e98e3e1Schristos case 'c': 16494e98e3e1Schristos if (is_header) 16504e98e3e1Schristos gen_icache_h (file, 16514e98e3e1Schristos gen->semantics, 16524e98e3e1Schristos isa->functions, isa->max_nr_words); 16534e98e3e1Schristos else 16544e98e3e1Schristos gen_icache_c (file, 16554e98e3e1Schristos gen->semantics, isa->functions, cache_rules); 16564e98e3e1Schristos break; 16574e98e3e1Schristos } 16584e98e3e1Schristos lf_print__file_finish (file); 16594e98e3e1Schristos lf_close (file); 16604e98e3e1Schristos is_header = 0; 16614e98e3e1Schristos } 16624e98e3e1Schristos real_file_name = NULL; 16634e98e3e1Schristos break; 16644e98e3e1Schristos default: 16654e98e3e1Schristos ERROR ("Bad switch"); 16664e98e3e1Schristos } 16674e98e3e1Schristos } 16684e98e3e1Schristos return (0); 16694e98e3e1Schristos } 1670