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 234e98e3e1Schristos 244e98e3e1Schristos #include "misc.h" 254e98e3e1Schristos #include "lf.h" 264e98e3e1Schristos #include "table.h" 274e98e3e1Schristos #include "filter.h" 284e98e3e1Schristos #include "igen.h" 294e98e3e1Schristos 304e98e3e1Schristos #include "ld-insn.h" 314e98e3e1Schristos #include "ld-decode.h" 324e98e3e1Schristos 334e98e3e1Schristos #include "gen.h" 344e98e3e1Schristos 354e98e3e1Schristos #include "gen-itable.h" 364e98e3e1Schristos 374e98e3e1Schristos 384e98e3e1Schristos typedef struct _itable_info 394e98e3e1Schristos { 404e98e3e1Schristos int sizeof_form; 414e98e3e1Schristos int sizeof_name; 424e98e3e1Schristos int sizeof_file; 434e98e3e1Schristos } 444e98e3e1Schristos itable_info; 454e98e3e1Schristos 464e98e3e1Schristos 474e98e3e1Schristos static void 484e98e3e1Schristos itable_h_insn (lf *file, 494b169a6bSchristos const insn_table *entry, 504b169a6bSchristos const insn_entry *instruction, 514b169a6bSchristos void *data) 524e98e3e1Schristos { 534e98e3e1Schristos int len; 544e98e3e1Schristos itable_info *info = data; 554e98e3e1Schristos lf_print__line_ref (file, instruction->line); 564e98e3e1Schristos lf_printf (file, " "); 574e98e3e1Schristos print_function_name (file, 584e98e3e1Schristos instruction->name, 594e98e3e1Schristos instruction->format_name, 604e98e3e1Schristos NULL, NULL, function_name_prefix_itable); 614e98e3e1Schristos lf_printf (file, ",\n"); 624e98e3e1Schristos /* update summary info */ 634e98e3e1Schristos len = strlen (instruction->format_name); 644e98e3e1Schristos if (info->sizeof_form <= len) 654e98e3e1Schristos info->sizeof_form = len + 1; 664e98e3e1Schristos len = strlen (instruction->name); 674e98e3e1Schristos if (info->sizeof_name <= len) 684e98e3e1Schristos info->sizeof_name = len + 1; 694e98e3e1Schristos len = strlen (filter_filename (instruction->line->file_name)); 704e98e3e1Schristos if (info->sizeof_file <= len) 714e98e3e1Schristos info->sizeof_file = len + 1; 724e98e3e1Schristos } 734e98e3e1Schristos 744e98e3e1Schristos 754e98e3e1Schristos /* print the list of all the different options */ 764e98e3e1Schristos 774e98e3e1Schristos static void 784b169a6bSchristos itable_print_enum (lf *file, const filter *set, const char *name) 794e98e3e1Schristos { 804b169a6bSchristos const char *elem; 814e98e3e1Schristos lf_printf (file, "typedef enum {\n"); 824e98e3e1Schristos lf_indent (file, +2); 834e98e3e1Schristos for (elem = filter_next (set, ""); 844e98e3e1Schristos elem != NULL; elem = filter_next (set, elem)) 854e98e3e1Schristos { 864e98e3e1Schristos lf_printf (file, "%sitable_%s_%s,\n", 874e98e3e1Schristos options.module.itable.prefix.l, name, elem); 884e98e3e1Schristos if (strlen (options.module.itable.prefix.l) > 0) 894e98e3e1Schristos { 904e98e3e1Schristos lf_indent_suppress (file); 914e98e3e1Schristos lf_printf (file, "#define itable_%s_%s %sitable_%s_%s\n", 924e98e3e1Schristos name, elem, options.module.itable.prefix.l, name, elem); 934e98e3e1Schristos } 944e98e3e1Schristos } 954e98e3e1Schristos lf_printf (file, "nr_%sitable_%ss,\n", options.module.itable.prefix.l, 964e98e3e1Schristos name); 974e98e3e1Schristos 984e98e3e1Schristos lf_indent (file, -2); 994e98e3e1Schristos lf_printf (file, "} %sitable_%ss;\n", options.module.itable.prefix.l, name); 1004e98e3e1Schristos if (strlen (options.module.itable.prefix.l) > 0) 1014e98e3e1Schristos { 1024e98e3e1Schristos lf_indent_suppress (file); 1034e98e3e1Schristos lf_printf (file, "#define itable_%ss %sitable_%ss\n", 1044e98e3e1Schristos name, options.module.itable.prefix.l, name); 1054e98e3e1Schristos lf_indent_suppress (file); 1064e98e3e1Schristos lf_printf (file, "#define nr_itable_%ss nr_%sitable_%ss\n", 1074e98e3e1Schristos name, options.module.itable.prefix.l, name); 1084e98e3e1Schristos } 1094e98e3e1Schristos } 1104e98e3e1Schristos 1114e98e3e1Schristos /* print an array of the option names as strings */ 1124e98e3e1Schristos 1134e98e3e1Schristos static void 1144b169a6bSchristos itable_print_names (lf *file, const filter *set, const char *name) 1154e98e3e1Schristos { 1164b169a6bSchristos const char *elem; 117*71f62182Schristos lf_printf (file, 118*71f62182Schristos "const char * const %sitable_%s_names[nr_%sitable_%ss + 1] = {\n", 1194e98e3e1Schristos options.module.itable.prefix.l, name, 1204e98e3e1Schristos options.module.itable.prefix.l, name); 1214e98e3e1Schristos lf_indent (file, +2); 1224e98e3e1Schristos for (elem = filter_next (set, ""); 1234e98e3e1Schristos elem != NULL; elem = filter_next (set, elem)) 1244e98e3e1Schristos { 1254e98e3e1Schristos lf_printf (file, "\"%s\",\n", elem); 1264e98e3e1Schristos } 1274e98e3e1Schristos lf_printf (file, "0,\n"); 1284e98e3e1Schristos lf_indent (file, -2); 1294e98e3e1Schristos lf_printf (file, "};\n"); 1304e98e3e1Schristos } 1314e98e3e1Schristos 1324e98e3e1Schristos extern void 1334b169a6bSchristos gen_itable_h (lf *file, const insn_table *isa) 1344e98e3e1Schristos { 1354e98e3e1Schristos itable_info *info = ZALLOC (itable_info); 1364e98e3e1Schristos 1374e98e3e1Schristos /* output an enumerated type for each instruction */ 1384e98e3e1Schristos lf_printf (file, "typedef enum {\n"); 1394e98e3e1Schristos insn_table_traverse_insn (file, isa, itable_h_insn, info); 1404e98e3e1Schristos lf_printf (file, " nr_%sitable_entries,\n", 1414e98e3e1Schristos options.module.itable.prefix.l); 1424e98e3e1Schristos lf_printf (file, "} %sitable_index;\n", options.module.itable.prefix.l); 1434e98e3e1Schristos lf_printf (file, "\n"); 1444e98e3e1Schristos 1454e98e3e1Schristos /* output an enumeration type for each flag */ 1464e98e3e1Schristos itable_print_enum (file, isa->flags, "flag"); 147*71f62182Schristos lf_printf (file, "extern const char * const %sitable_flag_names[];\n", 1484e98e3e1Schristos options.module.itable.prefix.l); 1494e98e3e1Schristos lf_printf (file, "\n"); 1504e98e3e1Schristos 1514e98e3e1Schristos /* output an enumeration of all the possible options */ 1524e98e3e1Schristos itable_print_enum (file, isa->options, "option"); 153*71f62182Schristos lf_printf (file, "extern const char * const %sitable_option_names[];\n", 1544e98e3e1Schristos options.module.itable.prefix.l); 1554e98e3e1Schristos lf_printf (file, "\n"); 1564e98e3e1Schristos 1574e98e3e1Schristos /* output an enumeration of all the processor models */ 1584e98e3e1Schristos itable_print_enum (file, isa->model->processors, "processor"); 159*71f62182Schristos lf_printf (file, "extern const char * const %sitable_processor_names[];\n", 1604e98e3e1Schristos options.module.itable.prefix.l); 1614e98e3e1Schristos lf_printf (file, "\n"); 1624e98e3e1Schristos 1634e98e3e1Schristos /* output the table that contains the actual instruction info */ 1644e98e3e1Schristos lf_printf (file, "typedef struct _%sitable_instruction_info {\n", 1654e98e3e1Schristos options.module.itable.prefix.l); 1664e98e3e1Schristos lf_printf (file, " %sitable_index nr;\n", options.module.itable.prefix.l); 167*71f62182Schristos lf_printf (file, " const char *format;\n"); 168*71f62182Schristos lf_printf (file, " const char *form;\n"); 169*71f62182Schristos lf_printf (file, " const char *flags;\n"); 1704e98e3e1Schristos 1714e98e3e1Schristos /* nr_itable_* may be zero, so we add 1 to avoid an 1724e98e3e1Schristos illegal zero-sized array. */ 173*71f62182Schristos lf_printf (file, " const char flag[nr_%sitable_flags + 1];\n", 1744e98e3e1Schristos options.module.itable.prefix.l); 175*71f62182Schristos lf_printf (file, " const char *options;\n"); 176*71f62182Schristos lf_printf (file, " const char option[nr_%sitable_options + 1];\n", 1774e98e3e1Schristos options.module.itable.prefix.l); 178*71f62182Schristos lf_printf (file, " const char *processors;\n"); 179*71f62182Schristos lf_printf (file, " const char processor[nr_%sitable_processors + 1];\n", 1804e98e3e1Schristos options.module.itable.prefix.l); 181*71f62182Schristos lf_printf (file, " const char *name;\n"); 182*71f62182Schristos lf_printf (file, " const char *file;\n"); 1834e98e3e1Schristos lf_printf (file, " int line_nr;\n"); 1844e98e3e1Schristos lf_printf (file, "} %sitable_info;\n", options.module.itable.prefix.l); 1854e98e3e1Schristos lf_printf (file, "\n"); 186*71f62182Schristos lf_printf (file, 187*71f62182Schristos "extern const %sitable_info %sitable[nr_%sitable_entries];\n", 1884e98e3e1Schristos options.module.itable.prefix.l, options.module.itable.prefix.l, 1894e98e3e1Schristos options.module.itable.prefix.l); 1904e98e3e1Schristos if (strlen (options.module.itable.prefix.l) > 0) 1914e98e3e1Schristos { 1924e98e3e1Schristos lf_indent_suppress (file); 1934e98e3e1Schristos lf_printf (file, "#define itable %sitable\n", 1944e98e3e1Schristos options.module.itable.prefix.l); 1954e98e3e1Schristos } 1964e98e3e1Schristos lf_printf (file, "\n"); 1974e98e3e1Schristos 1984e98e3e1Schristos /* output an enum defining the max size of various itable members */ 1994e98e3e1Schristos lf_printf (file, "enum {\n"); 2004e98e3e1Schristos lf_printf (file, " sizeof_%sitable_form = %d,\n", 2014e98e3e1Schristos options.module.itable.prefix.l, info->sizeof_form); 2024e98e3e1Schristos lf_printf (file, " sizeof_%sitable_name = %d,\n", 2034e98e3e1Schristos options.module.itable.prefix.l, info->sizeof_name); 2044e98e3e1Schristos lf_printf (file, " sizeof_%sitable_file = %d,\n", 2054e98e3e1Schristos options.module.itable.prefix.l, info->sizeof_file); 2064e98e3e1Schristos lf_printf (file, "};\n"); 2074e98e3e1Schristos } 2084e98e3e1Schristos 2094e98e3e1Schristos 2104e98e3e1Schristos /****************************************************************/ 2114e98e3e1Schristos 2124e98e3e1Schristos static void 2134b169a6bSchristos itable_print_set (lf *file, const filter *set, const filter *members) 2144e98e3e1Schristos { 2154b169a6bSchristos const char *elem; 2164e98e3e1Schristos lf_printf (file, "\""); 2174e98e3e1Schristos elem = filter_next (members, ""); 2184e98e3e1Schristos if (elem != NULL) 2194e98e3e1Schristos { 2204e98e3e1Schristos while (1) 2214e98e3e1Schristos { 2224e98e3e1Schristos lf_printf (file, "%s", elem); 2234e98e3e1Schristos elem = filter_next (members, elem); 2244e98e3e1Schristos if (elem == NULL) 2254e98e3e1Schristos break; 2264e98e3e1Schristos lf_printf (file, ","); 2274e98e3e1Schristos } 2284e98e3e1Schristos } 2294e98e3e1Schristos lf_printf (file, "\",\n"); 2304e98e3e1Schristos 2314e98e3e1Schristos lf_printf (file, "{"); 2324e98e3e1Schristos for (elem = filter_next (set, ""); 2334e98e3e1Schristos elem != NULL; elem = filter_next (set, elem)) 2344e98e3e1Schristos { 2354e98e3e1Schristos if (filter_is_member (members, elem)) 2364e98e3e1Schristos { 2374e98e3e1Schristos lf_printf (file, " 1,"); 2384e98e3e1Schristos } 2394e98e3e1Schristos else 2404e98e3e1Schristos { 2414e98e3e1Schristos lf_printf (file, " 0,"); 2424e98e3e1Schristos } 2434e98e3e1Schristos 2444e98e3e1Schristos } 2454e98e3e1Schristos /* always print a dummy element, to avoid empty initializers. */ 2464e98e3e1Schristos lf_printf (file, " 99 },\n"); 2474e98e3e1Schristos } 2484e98e3e1Schristos 2494e98e3e1Schristos 2504e98e3e1Schristos static void 2514e98e3e1Schristos itable_c_insn (lf *file, 2524b169a6bSchristos const insn_table *isa, 2534b169a6bSchristos const insn_entry *instruction, 2544b169a6bSchristos void *data) 2554e98e3e1Schristos { 2564e98e3e1Schristos lf_printf (file, "{ "); 2574e98e3e1Schristos lf_indent (file, +2); 2584e98e3e1Schristos print_function_name (file, 2594e98e3e1Schristos instruction->name, 2604e98e3e1Schristos instruction->format_name, 2614e98e3e1Schristos NULL, NULL, function_name_prefix_itable); 2624e98e3e1Schristos lf_printf (file, ",\n"); 2634e98e3e1Schristos lf_printf (file, "\""); 2644e98e3e1Schristos print_insn_words (file, instruction); 2654e98e3e1Schristos lf_printf (file, "\",\n"); 2664e98e3e1Schristos lf_printf (file, "\"%s\",\n", instruction->format_name); 2674e98e3e1Schristos 2684e98e3e1Schristos itable_print_set (file, isa->flags, instruction->flags); 2694e98e3e1Schristos itable_print_set (file, isa->options, instruction->options); 2704e98e3e1Schristos itable_print_set (file, isa->model->processors, instruction->processors); 2714e98e3e1Schristos 2724e98e3e1Schristos lf_printf (file, "\"%s\",\n", instruction->name); 2734e98e3e1Schristos lf_printf (file, "\"%s\",\n", 2744e98e3e1Schristos filter_filename (instruction->line->file_name)); 2754e98e3e1Schristos lf_printf (file, "%d,\n", instruction->line->line_nr); 2764e98e3e1Schristos lf_printf (file, "},\n"); 2774e98e3e1Schristos lf_indent (file, -2); 2784e98e3e1Schristos } 2794e98e3e1Schristos 2804e98e3e1Schristos 2814e98e3e1Schristos extern void 2824b169a6bSchristos gen_itable_c (lf *file, const insn_table *isa) 2834e98e3e1Schristos { 2844e98e3e1Schristos /* leader */ 2854e98e3e1Schristos lf_printf (file, "#include \"%sitable.h\"\n", 2864e98e3e1Schristos options.module.itable.prefix.l); 2874e98e3e1Schristos lf_printf (file, "\n"); 2884e98e3e1Schristos 2894e98e3e1Schristos /* FIXME - output model data??? */ 2904e98e3e1Schristos /* FIXME - output assembler data??? */ 2914e98e3e1Schristos 2924e98e3e1Schristos /* output the flag, option and processor name tables */ 2934e98e3e1Schristos itable_print_names (file, isa->flags, "flag"); 2944e98e3e1Schristos itable_print_names (file, isa->options, "option"); 2954e98e3e1Schristos itable_print_names (file, isa->model->processors, "processor"); 2964e98e3e1Schristos 2974e98e3e1Schristos /* output the table that contains the actual instruction info */ 298*71f62182Schristos lf_printf (file, "const %sitable_info %sitable[nr_%sitable_entries] = {\n", 2994e98e3e1Schristos options.module.itable.prefix.l, 3004e98e3e1Schristos options.module.itable.prefix.l, options.module.itable.prefix.l); 3014e98e3e1Schristos insn_table_traverse_insn (file, isa, itable_c_insn, NULL); 3024e98e3e1Schristos 3034e98e3e1Schristos lf_printf (file, "};\n"); 3044e98e3e1Schristos } 305