1/* The IGEN simulator generator for GDB, the GNU Debugger. 2 3 Copyright 2002-2020 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#ifndef NULL 35#define NULL 0 36#endif 37 38 39static const name_map decode_type_map[] = { 40 {"normal", normal_decode_rule}, 41 {"boolean", boolean_rule}, 42 {NULL, normal_decode_rule}, 43}; 44 45static const name_map decode_gen_map[] = { 46 {"array", array_gen}, 47 {"switch", switch_gen}, 48 {"padded-switch", padded_switch_gen}, 49 {"goto-switch", goto_switch_gen}, 50 {NULL, -1}, 51}; 52 53static const name_map decode_reserved_map[] = { 54 {"zero-reserved", 1}, 55 {NULL, 0}, 56}; 57 58static const name_map decode_duplicates_map[] = { 59 {"duplicate", 1}, 60 {NULL, 0}, 61}; 62 63static const name_map decode_combine_map[] = { 64 {"combine", 1}, 65 {NULL, 0}, 66}; 67 68static const name_map decode_search_map[] = { 69 {"constants", decode_find_constants}, 70 {"mixed", decode_find_mixed}, 71 {"strings", decode_find_strings}, 72 {NULL, decode_find_mixed}, 73}; 74 75 76static void 77set_bits (int bit[max_insn_bit_size], unsigned64 value) 78{ 79 int bit_nr; 80 for (bit_nr = 0; bit_nr < max_insn_bit_size; bit_nr++) 81 { 82 if (bit_nr < options.insn_bit_size) 83 bit[bit_nr] = (value >> (options.insn_bit_size - bit_nr - 1)) & 1; 84 else 85 bit[bit_nr] = 0; 86 } 87} 88 89decode_table * 90load_decode_table (char *file_name) 91{ 92 table *file = table_open (file_name); 93 table_entry *entry; 94 decode_table *table = NULL; 95 decode_table **curr_rule = &table; 96 while ((entry = table_read (file)) != NULL) 97 { 98 char *decode_options = entry->field[decode_options_field]; 99 decode_table *new_rule = ZALLOC (decode_table); 100 if (entry->nr_fields < min_nr_decode_fields) 101 error (entry->line, "Missing decode table fields\n"); 102 new_rule->line = entry->line; 103 104 /* the options field */ 105 new_rule->type = name2i (decode_options, decode_type_map); 106 if (options.decode.overriding_gen != NULL) 107 new_rule->gen = 108 name2i (options.decode.overriding_gen, decode_gen_map); 109 else 110 new_rule->gen = name2i (decode_options, decode_gen_map); 111 if (new_rule->gen == padded_switch_gen && options.decode.switch_as_goto) 112 new_rule->gen = goto_switch_gen; 113 if (options.decode.zero_reserved) 114 new_rule->with_zero_reserved = 1; 115 else 116 new_rule->with_zero_reserved = 117 name2i (decode_options, decode_reserved_map); 118 if (options.decode.duplicate) 119 new_rule->with_duplicates = 1; 120 else 121 new_rule->with_duplicates = 122 name2i (decode_options, decode_duplicates_map); 123 if (options.decode.combine) 124 new_rule->with_combine = 1; 125 else 126 new_rule->with_combine = name2i (decode_options, decode_combine_map); 127 if (new_rule->type == boolean_rule) 128 { 129 char *chp = decode_options; 130 while (*chp != '\0') 131 { 132 if (isdigit (*chp)) 133 { 134 new_rule->constant = a2i (chp); 135 break; 136 } 137 chp = skip_to_separator (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 290int 291decode_table_max_word_nr (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 311static void 312dump_decode_cond (lf *file, char *prefix, decode_cond *cond, char *suffix) 313{ 314 lf_printf (file, "%s(decode_cond *) 0x%lx", prefix, (long) 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 0x%lx)", (long) cond->mask); 320 lf_printf (file, "\n(value 0x%lx)", (long) cond->value); 321 lf_printf (file, "\n(is_equal 0x%lx)", (long) cond->is_equal); 322 lf_printf (file, "\n(next (decode_cond *) 0%lx)", (long) cond->next); 323 lf_indent (file, -1); 324 } 325 lf_printf (file, "%s", suffix); 326} 327 328 329static void 330dump_decode_conds (lf *file, char *prefix, decode_cond *cond, char *suffix) 331{ 332 lf_printf (file, "%s(decode_cond *) 0x%lx", prefix, (long) cond); 333 while (cond != NULL) 334 { 335 dump_decode_cond (file, "\n(", cond, ")"); 336 cond = cond->next; 337 } 338 lf_printf (file, "%s", suffix); 339} 340 341 342void 343dump_decode_rule (lf *file, char *prefix, decode_table *rule, char *suffix) 344{ 345 lf_printf (file, "%s(decode_table *) 0x%lx", prefix, (long) rule); 346 if (rule != NULL) 347 { 348 lf_indent (file, +1); 349 dump_line_ref (file, "\n(line ", rule->line, ")"); 350 lf_printf (file, "\n(type %s)", i2name (rule->type, decode_type_map)); 351 lf_printf (file, "\n(gen %s)", i2name (rule->gen, decode_gen_map)); 352 lf_printf (file, "\n(first %d)", rule->first); 353 lf_printf (file, "\n(last %d)", rule->last); 354 lf_printf (file, "\n(force_first %d)", rule->force_first); 355 lf_printf (file, "\n(force_last %d)", rule->force_last); 356 dump_filter (file, "\n(constant_field_names \"", 357 rule->constant_field_names, "\")"); 358 lf_printf (file, "\n(constant 0x%x)", rule->constant); 359 lf_printf (file, "\n(word_nr %d)", rule->word_nr); 360 lf_printf (file, "\n(with_zero_reserved %d)", rule->with_zero_reserved); 361 lf_printf (file, "\n(with_duplicates %d)", rule->with_duplicates); 362 lf_printf (file, "\n(with_combine %d)", rule->with_combine); 363 dump_filter (file, "\n(format_names \"", rule->format_names, "\")"); 364 dump_filter (file, "\n(model_names \"", rule->model_names, "\")"); 365 dump_decode_conds (file, "\n(conditions ", rule->conditions, ")"); 366 lf_printf (file, "\n(next 0x%lx)", (long) rule->next); 367 lf_indent (file, -1); 368 } 369 lf_printf (file, "%s", suffix); 370} 371 372 373#ifdef MAIN 374 375static void 376dump_decode_rules (lf *file, char *prefix, decode_table *rule, char *suffix) 377{ 378 lf_printf (file, "%s", prefix); 379 while (rule != NULL) 380 { 381 lf_indent (file, +1); 382 dump_decode_rule (file, "\n(", rule, ")"); 383 lf_indent (file, -1); 384 rule = rule->next; 385 } 386 lf_printf (file, "%s", suffix); 387} 388 389igen_options options; 390 391int 392main (int argc, char **argv) 393{ 394 lf *l; 395 decode_table *rules; 396 397 INIT_OPTIONS (options); 398 399 if (argc != 3) 400 error (NULL, "Usage: decode <decode-file> <hi-bit-nr>\n"); 401 402 options.hi_bit_nr = a2i (argv[2]); 403 rules = load_decode_table (argv[1]); 404 l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn"); 405 dump_decode_rules (l, "(rules ", rules, ")\n"); 406 407 return 0; 408} 409#endif 410