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