1 1.1 christos /* The IGEN simulator generator for GDB, the GNU Debugger. 2 1.1 christos 3 1.1.1.10 christos Copyright 2002-2024 Free Software Foundation, Inc. 4 1.1 christos 5 1.1 christos Contributed by Andrew Cagney. 6 1.1 christos 7 1.1 christos This file is part of GDB. 8 1.1 christos 9 1.1 christos This program is free software; you can redistribute it and/or modify 10 1.1 christos it under the terms of the GNU General Public License as published by 11 1.1 christos the Free Software Foundation; either version 3 of the License, or 12 1.1 christos (at your option) any later version. 13 1.1 christos 14 1.1 christos This program is distributed in the hope that it will be useful, 15 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 16 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 1.1 christos GNU General Public License for more details. 18 1.1 christos 19 1.1 christos You should have received a copy of the GNU General Public License 20 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 21 1.1 christos 22 1.1 christos 23 1.1 christos /* load the opcode stat structure */ 24 1.1 christos 25 1.1 christos #include "misc.h" 26 1.1 christos #include "lf.h" 27 1.1 christos #include "table.h" 28 1.1 christos #include "filter.h" 29 1.1 christos 30 1.1 christos #include "igen.h" 31 1.1 christos 32 1.1 christos #include "ld-decode.h" 33 1.1 christos 34 1.1 christos 35 1.1 christos static const name_map decode_type_map[] = { 36 1.1 christos {"normal", normal_decode_rule}, 37 1.1 christos {"boolean", boolean_rule}, 38 1.1 christos {NULL, normal_decode_rule}, 39 1.1 christos }; 40 1.1 christos 41 1.1 christos static const name_map decode_gen_map[] = { 42 1.1 christos {"array", array_gen}, 43 1.1 christos {"switch", switch_gen}, 44 1.1 christos {"padded-switch", padded_switch_gen}, 45 1.1 christos {"goto-switch", goto_switch_gen}, 46 1.1 christos {NULL, -1}, 47 1.1 christos }; 48 1.1 christos 49 1.1 christos static const name_map decode_reserved_map[] = { 50 1.1 christos {"zero-reserved", 1}, 51 1.1 christos {NULL, 0}, 52 1.1 christos }; 53 1.1 christos 54 1.1 christos static const name_map decode_duplicates_map[] = { 55 1.1 christos {"duplicate", 1}, 56 1.1 christos {NULL, 0}, 57 1.1 christos }; 58 1.1 christos 59 1.1 christos static const name_map decode_combine_map[] = { 60 1.1 christos {"combine", 1}, 61 1.1 christos {NULL, 0}, 62 1.1 christos }; 63 1.1 christos 64 1.1.1.10 christos #if 0 65 1.1 christos static const name_map decode_search_map[] = { 66 1.1 christos {"constants", decode_find_constants}, 67 1.1 christos {"mixed", decode_find_mixed}, 68 1.1 christos {"strings", decode_find_strings}, 69 1.1 christos {NULL, decode_find_mixed}, 70 1.1 christos }; 71 1.1.1.10 christos #endif 72 1.1 christos 73 1.1 christos 74 1.1 christos static void 75 1.1.1.9 christos set_bits (int bit[max_insn_bit_size], uint64_t value) 76 1.1 christos { 77 1.1 christos int bit_nr; 78 1.1 christos for (bit_nr = 0; bit_nr < max_insn_bit_size; bit_nr++) 79 1.1 christos { 80 1.1 christos if (bit_nr < options.insn_bit_size) 81 1.1 christos bit[bit_nr] = (value >> (options.insn_bit_size - bit_nr - 1)) & 1; 82 1.1 christos else 83 1.1 christos bit[bit_nr] = 0; 84 1.1 christos } 85 1.1 christos } 86 1.1 christos 87 1.1 christos decode_table * 88 1.1.1.9 christos load_decode_table (const char *file_name) 89 1.1 christos { 90 1.1 christos table *file = table_open (file_name); 91 1.1 christos table_entry *entry; 92 1.1 christos decode_table *table = NULL; 93 1.1 christos decode_table **curr_rule = &table; 94 1.1 christos while ((entry = table_read (file)) != NULL) 95 1.1 christos { 96 1.1 christos char *decode_options = entry->field[decode_options_field]; 97 1.1 christos decode_table *new_rule = ZALLOC (decode_table); 98 1.1 christos if (entry->nr_fields < min_nr_decode_fields) 99 1.1 christos error (entry->line, "Missing decode table fields\n"); 100 1.1 christos new_rule->line = entry->line; 101 1.1 christos 102 1.1 christos /* the options field */ 103 1.1 christos new_rule->type = name2i (decode_options, decode_type_map); 104 1.1 christos if (options.decode.overriding_gen != NULL) 105 1.1 christos new_rule->gen = 106 1.1 christos name2i (options.decode.overriding_gen, decode_gen_map); 107 1.1 christos else 108 1.1 christos new_rule->gen = name2i (decode_options, decode_gen_map); 109 1.1 christos if (new_rule->gen == padded_switch_gen && options.decode.switch_as_goto) 110 1.1 christos new_rule->gen = goto_switch_gen; 111 1.1 christos if (options.decode.zero_reserved) 112 1.1 christos new_rule->with_zero_reserved = 1; 113 1.1 christos else 114 1.1 christos new_rule->with_zero_reserved = 115 1.1 christos name2i (decode_options, decode_reserved_map); 116 1.1 christos if (options.decode.duplicate) 117 1.1 christos new_rule->with_duplicates = 1; 118 1.1 christos else 119 1.1 christos new_rule->with_duplicates = 120 1.1 christos name2i (decode_options, decode_duplicates_map); 121 1.1 christos if (options.decode.combine) 122 1.1 christos new_rule->with_combine = 1; 123 1.1 christos else 124 1.1 christos new_rule->with_combine = name2i (decode_options, decode_combine_map); 125 1.1 christos if (new_rule->type == boolean_rule) 126 1.1 christos { 127 1.1 christos char *chp = decode_options; 128 1.1 christos while (*chp != '\0') 129 1.1 christos { 130 1.1 christos if (isdigit (*chp)) 131 1.1 christos { 132 1.1 christos new_rule->constant = a2i (chp); 133 1.1 christos break; 134 1.1 christos } 135 1.1 christos chp = skip_to_separator (chp, ","); 136 1.1.1.9 christos if (*chp == ',') 137 1.1.1.9 christos ++chp; 138 1.1 christos chp = skip_spaces (chp); 139 1.1 christos } 140 1.1 christos } 141 1.1 christos 142 1.1 christos /* First and last */ 143 1.1 christos if (entry->nr_fields > decode_first_field 144 1.1 christos && strlen (entry->field[decode_first_field]) > 0) 145 1.1 christos { 146 1.1 christos new_rule->first = target_a2i (options.hi_bit_nr, 147 1.1 christos entry->field[decode_first_field]); 148 1.1 christos if (new_rule->first < 0 || new_rule->first >= options.insn_bit_size) 149 1.1 christos error (new_rule->line, "First field out of range\n"); 150 1.1 christos } 151 1.1 christos else 152 1.1 christos new_rule->first = 0; 153 1.1 christos if (entry->nr_fields > decode_last_field 154 1.1 christos && strlen (entry->field[decode_last_field]) > 0) 155 1.1 christos { 156 1.1 christos new_rule->last = target_a2i (options.hi_bit_nr, 157 1.1 christos entry->field[decode_last_field]); 158 1.1 christos if (new_rule->last < 0 || new_rule->last >= options.insn_bit_size) 159 1.1 christos error (new_rule->line, "Last field out of range\n"); 160 1.1 christos } 161 1.1 christos else 162 1.1 christos new_rule->last = options.insn_bit_size - 1; 163 1.1 christos if (new_rule->first > new_rule->last) 164 1.1.1.11 christos error (new_rule->line, "First must precede last\n"); 165 1.1 christos 166 1.1 christos /* force first/last, with default values based on first/last */ 167 1.1 christos if (entry->nr_fields > decode_force_first_field 168 1.1 christos && strlen (entry->field[decode_force_first_field]) > 0) 169 1.1 christos { 170 1.1 christos new_rule->force_first = target_a2i (options.hi_bit_nr, 171 1.1 christos entry-> 172 1.1 christos field 173 1.1 christos [decode_force_first_field]); 174 1.1 christos if (new_rule->force_first < new_rule->first 175 1.1 christos || new_rule->force_first > new_rule->last + 1) 176 1.1 christos error (new_rule->line, "Force first out of range\n"); 177 1.1 christos } 178 1.1 christos else 179 1.1 christos new_rule->force_first = new_rule->last + 1; 180 1.1 christos if (entry->nr_fields > decode_force_last_field 181 1.1 christos && strlen (entry->field[decode_force_last_field]) > 0) 182 1.1 christos { 183 1.1 christos new_rule->force_last = target_a2i (options.hi_bit_nr, 184 1.1 christos entry-> 185 1.1 christos field[decode_force_last_field]); 186 1.1 christos if (new_rule->force_last > new_rule->last 187 1.1 christos || new_rule->force_last < new_rule->first - 1) 188 1.1 christos error (new_rule->line, "Force-last out of range\n"); 189 1.1 christos } 190 1.1 christos else 191 1.1 christos new_rule->force_last = new_rule->first - 1; 192 1.1 christos 193 1.1 christos /* fields to be treated as constant */ 194 1.1 christos if (entry->nr_fields > decode_constant_field_names_field) 195 1.1 christos filter_parse (&new_rule->constant_field_names, 196 1.1 christos entry->field[decode_constant_field_names_field]); 197 1.1 christos 198 1.1 christos /* applicable word nr */ 199 1.1 christos if (entry->nr_fields > decode_word_nr_field) 200 1.1 christos new_rule->word_nr = a2i (entry->field[decode_word_nr_field]); 201 1.1 christos 202 1.1 christos /* required instruction format names */ 203 1.1 christos if (entry->nr_fields > decode_format_names_field) 204 1.1 christos filter_parse (&new_rule->format_names, 205 1.1 christos entry->field[decode_format_names_field]); 206 1.1 christos 207 1.1 christos /* required processor models */ 208 1.1 christos if (entry->nr_fields > decode_model_names_field) 209 1.1 christos filter_parse (&new_rule->model_names, 210 1.1 christos entry->field[decode_model_names_field]); 211 1.1 christos 212 1.1 christos /* required paths */ 213 1.1 christos if (entry->nr_fields > decode_paths_field 214 1.1 christos && strlen (entry->field[decode_paths_field]) > 0) 215 1.1 christos { 216 1.1 christos decode_path_list **last = &new_rule->paths; 217 1.1 christos char *chp = entry->field[decode_paths_field]; 218 1.1 christos do 219 1.1 christos { 220 1.1 christos (*last) = ZALLOC (decode_path_list); 221 1.1 christos /* extra root/zero entry */ 222 1.1 christos (*last)->path = ZALLOC (decode_path); 223 1.1 christos do 224 1.1 christos { 225 1.1 christos decode_path *entry = ZALLOC (decode_path); 226 1.1 christos entry->opcode_nr = a2i (chp); 227 1.1 christos entry->parent = (*last)->path; 228 1.1 christos (*last)->path = entry; 229 1.1 christos chp = skip_digits (chp); 230 1.1 christos chp = skip_spaces (chp); 231 1.1 christos } 232 1.1 christos while (*chp == '.'); 233 1.1 christos last = &(*last)->next; 234 1.1 christos } 235 1.1 christos while (*chp == ','); 236 1.1 christos if (*chp != '\0') 237 1.1 christos error (entry->line, "Invalid path field\n"); 238 1.1 christos } 239 1.1 christos 240 1.1 christos /* collect up the list of optional special conditions applicable 241 1.1 christos to the rule */ 242 1.1 christos { 243 1.1 christos int field_nr = nr_decode_fields; 244 1.1 christos while (entry->nr_fields > field_nr) 245 1.1 christos { 246 1.1 christos decode_cond *cond = ZALLOC (decode_cond); 247 1.1 christos decode_cond **last; 248 1.1 christos if (entry->nr_fields > field_nr + decode_cond_mask_field) 249 1.1 christos set_bits (cond->mask, 250 1.1 christos a2i (entry-> 251 1.1 christos field[field_nr + decode_cond_mask_field])); 252 1.1 christos if (entry->nr_fields > field_nr + decode_cond_value_field) 253 1.1 christos { 254 1.1 christos if (entry->field[field_nr + decode_cond_value_field][0] == 255 1.1 christos '!') 256 1.1 christos { 257 1.1 christos cond->is_equal = 0; 258 1.1 christos set_bits (cond->value, 259 1.1 christos a2i (entry-> 260 1.1 christos field[field_nr + decode_cond_value_field] + 261 1.1 christos 1)); 262 1.1 christos } 263 1.1 christos else 264 1.1 christos { 265 1.1 christos cond->is_equal = 1; 266 1.1 christos set_bits (cond->value, 267 1.1 christos a2i (entry-> 268 1.1 christos field[field_nr + 269 1.1 christos decode_cond_value_field])); 270 1.1 christos } 271 1.1 christos } 272 1.1 christos if (entry->nr_fields > field_nr + decode_cond_word_nr_field) 273 1.1 christos cond->word_nr = 274 1.1 christos a2i (entry->field[field_nr + decode_cond_word_nr_field]); 275 1.1 christos field_nr += nr_decode_cond_fields; 276 1.1 christos /* insert it */ 277 1.1 christos last = &new_rule->conditions; 278 1.1 christos while (*last != NULL) 279 1.1 christos last = &(*last)->next; 280 1.1 christos *last = cond; 281 1.1 christos } 282 1.1 christos } 283 1.1 christos *curr_rule = new_rule; 284 1.1 christos curr_rule = &new_rule->next; 285 1.1 christos } 286 1.1 christos return table; 287 1.1 christos } 288 1.1 christos 289 1.1 christos 290 1.1 christos int 291 1.1.1.9 christos decode_table_max_word_nr (const decode_table *entry) 292 1.1 christos { 293 1.1 christos int max_word_nr = 0; 294 1.1 christos while (entry != NULL) 295 1.1 christos { 296 1.1 christos decode_cond *cond; 297 1.1 christos if (entry->word_nr > max_word_nr) 298 1.1 christos max_word_nr = entry->word_nr; 299 1.1 christos for (cond = entry->conditions; cond != NULL; cond = cond->next) 300 1.1 christos { 301 1.1 christos if (cond->word_nr > max_word_nr) 302 1.1 christos max_word_nr = cond->word_nr; 303 1.1 christos } 304 1.1 christos entry = entry->next; 305 1.1 christos } 306 1.1 christos return max_word_nr; 307 1.1 christos } 308 1.1 christos 309 1.1 christos 310 1.1 christos static void 311 1.1.1.9 christos dump_decode_cond (lf *file, const char *prefix, const decode_cond *cond, 312 1.1.1.9 christos const char *suffix) 313 1.1 christos { 314 1.1.1.9 christos lf_printf (file, "%s(decode_cond *) %p", prefix, cond); 315 1.1 christos if (cond != NULL) 316 1.1 christos { 317 1.1 christos lf_indent (file, +1); 318 1.1 christos lf_printf (file, "\n(word_nr %d)", cond->word_nr); 319 1.1.1.9 christos lf_printf (file, "\n(mask %p)", cond->mask); 320 1.1.1.9 christos lf_printf (file, "\n(value %p)", cond->value); 321 1.1.1.9 christos lf_printf (file, "\n(is_equal %d)", cond->is_equal); 322 1.1.1.9 christos lf_printf (file, "\n(next (decode_cond *) %p)", cond->next); 323 1.1 christos lf_indent (file, -1); 324 1.1 christos } 325 1.1 christos lf_printf (file, "%s", suffix); 326 1.1 christos } 327 1.1 christos 328 1.1 christos 329 1.1 christos static void 330 1.1.1.9 christos dump_decode_conds (lf *file, const char *prefix, const decode_cond *cond, 331 1.1.1.9 christos const char *suffix) 332 1.1 christos { 333 1.1.1.9 christos lf_printf (file, "%s(decode_cond *) %p", prefix, cond); 334 1.1 christos while (cond != NULL) 335 1.1 christos { 336 1.1 christos dump_decode_cond (file, "\n(", cond, ")"); 337 1.1 christos cond = cond->next; 338 1.1 christos } 339 1.1 christos lf_printf (file, "%s", suffix); 340 1.1 christos } 341 1.1 christos 342 1.1 christos 343 1.1 christos void 344 1.1.1.9 christos dump_decode_rule (lf *file, const char *prefix, const decode_table *rule, 345 1.1.1.9 christos const char *suffix) 346 1.1 christos { 347 1.1.1.9 christos lf_printf (file, "%s(decode_table *) %p", prefix, rule); 348 1.1 christos if (rule != NULL) 349 1.1 christos { 350 1.1 christos lf_indent (file, +1); 351 1.1 christos dump_line_ref (file, "\n(line ", rule->line, ")"); 352 1.1 christos lf_printf (file, "\n(type %s)", i2name (rule->type, decode_type_map)); 353 1.1 christos lf_printf (file, "\n(gen %s)", i2name (rule->gen, decode_gen_map)); 354 1.1 christos lf_printf (file, "\n(first %d)", rule->first); 355 1.1 christos lf_printf (file, "\n(last %d)", rule->last); 356 1.1 christos lf_printf (file, "\n(force_first %d)", rule->force_first); 357 1.1 christos lf_printf (file, "\n(force_last %d)", rule->force_last); 358 1.1 christos dump_filter (file, "\n(constant_field_names \"", 359 1.1 christos rule->constant_field_names, "\")"); 360 1.1 christos lf_printf (file, "\n(constant 0x%x)", rule->constant); 361 1.1 christos lf_printf (file, "\n(word_nr %d)", rule->word_nr); 362 1.1 christos lf_printf (file, "\n(with_zero_reserved %d)", rule->with_zero_reserved); 363 1.1 christos lf_printf (file, "\n(with_duplicates %d)", rule->with_duplicates); 364 1.1 christos lf_printf (file, "\n(with_combine %d)", rule->with_combine); 365 1.1 christos dump_filter (file, "\n(format_names \"", rule->format_names, "\")"); 366 1.1 christos dump_filter (file, "\n(model_names \"", rule->model_names, "\")"); 367 1.1 christos dump_decode_conds (file, "\n(conditions ", rule->conditions, ")"); 368 1.1.1.9 christos lf_printf (file, "\n(next %p)", rule->next); 369 1.1 christos lf_indent (file, -1); 370 1.1 christos } 371 1.1 christos lf_printf (file, "%s", suffix); 372 1.1 christos } 373 1.1 christos 374 1.1 christos 375 1.1 christos #ifdef MAIN 376 1.1 christos 377 1.1 christos static void 378 1.1.1.9 christos dump_decode_rules (lf *file, 379 1.1.1.9 christos const char *prefix, 380 1.1.1.9 christos const decode_table *rule, 381 1.1.1.9 christos const char *suffix) 382 1.1 christos { 383 1.1 christos lf_printf (file, "%s", prefix); 384 1.1 christos while (rule != NULL) 385 1.1 christos { 386 1.1 christos lf_indent (file, +1); 387 1.1 christos dump_decode_rule (file, "\n(", rule, ")"); 388 1.1 christos lf_indent (file, -1); 389 1.1 christos rule = rule->next; 390 1.1 christos } 391 1.1 christos lf_printf (file, "%s", suffix); 392 1.1 christos } 393 1.1 christos 394 1.1 christos igen_options options; 395 1.1 christos 396 1.1 christos int 397 1.1 christos main (int argc, char **argv) 398 1.1 christos { 399 1.1 christos lf *l; 400 1.1 christos decode_table *rules; 401 1.1 christos 402 1.1.1.9 christos INIT_OPTIONS (); 403 1.1 christos 404 1.1 christos if (argc != 3) 405 1.1 christos error (NULL, "Usage: decode <decode-file> <hi-bit-nr>\n"); 406 1.1 christos 407 1.1 christos options.hi_bit_nr = a2i (argv[2]); 408 1.1 christos rules = load_decode_table (argv[1]); 409 1.1 christos l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn"); 410 1.1 christos dump_decode_rules (l, "(rules ", rules, ")\n"); 411 1.1 christos 412 1.1 christos return 0; 413 1.1 christos } 414 1.1 christos #endif 415