1 1.1 christos /* The IGEN simulator generator for GDB, the GNU Debugger. 2 1.1 christos 3 1.11 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 #include "misc.h" 24 1.1 christos #include "lf.h" 25 1.1 christos #include "table.h" 26 1.1 christos #include "filter.h" 27 1.1 christos 28 1.1 christos #include "igen.h" 29 1.1 christos #include "ld-insn.h" 30 1.1 christos #include "ld-decode.h" 31 1.1 christos #include "gen.h" 32 1.1 christos 33 1.1 christos static insn_uint 34 1.1 christos sub_val (insn_uint val, int val_last_pos, int first_pos, int last_pos) 35 1.1 christos { 36 1.1 christos return ((val >> (val_last_pos - last_pos)) 37 1.1 christos & (((insn_uint) 1 << (last_pos - first_pos + 1)) - 1)); 38 1.1 christos } 39 1.1 christos 40 1.1 christos static void 41 1.10 christos update_depth (lf *file, const gen_entry *entry, int depth, void *data) 42 1.1 christos { 43 1.1 christos int *max_depth = (int *) data; 44 1.1 christos if (*max_depth < depth) 45 1.1 christos *max_depth = depth; 46 1.1 christos } 47 1.1 christos 48 1.1 christos 49 1.1 christos int 50 1.10 christos gen_entry_depth (const gen_entry *table) 51 1.1 christos { 52 1.1 christos int depth = 0; 53 1.1 christos gen_entry_traverse_tree (NULL, table, 1, NULL, /*start */ 54 1.1 christos update_depth, NULL, /*end */ 55 1.1 christos &depth); /* data */ 56 1.1 christos return depth; 57 1.1 christos } 58 1.1 christos 59 1.1 christos 60 1.1 christos static void 61 1.10 christos print_gen_entry_path (const line_ref *line, 62 1.10 christos const gen_entry *table, 63 1.10 christos error_func *print) 64 1.1 christos { 65 1.1 christos if (table->parent == NULL) 66 1.1 christos { 67 1.1 christos if (table->top->model != NULL) 68 1.1 christos print (line, "%s", table->top->model->name); 69 1.1 christos else 70 1.11 christos { 71 1.11 christos /* We don't want to output things, but we want the side-effects they 72 1.11 christos might have (e.g. checking line != NULL). */ 73 1.11 christos print (line, "%s", ""); 74 1.11 christos } 75 1.1 christos } 76 1.1 christos else 77 1.1 christos { 78 1.1 christos print_gen_entry_path (line, table->parent, print); 79 1.1 christos print (NULL, ".%d", table->opcode_nr); 80 1.1 christos } 81 1.1 christos } 82 1.1 christos 83 1.1 christos static void 84 1.10 christos print_gen_entry_insns (const gen_entry *table, 85 1.1 christos error_func *print, 86 1.10 christos const char *first_message, 87 1.10 christos const char *next_message) 88 1.1 christos { 89 1.1 christos insn_list *i; 90 1.10 christos const char *message; 91 1.1 christos message = first_message; 92 1.1 christos for (i = table->insns; i != NULL; i = i->next) 93 1.1 christos { 94 1.1 christos insn_entry *insn = i->insn; 95 1.1 christos print_gen_entry_path (insn->line, table, print); 96 1.1 christos print (NULL, ": %s.%s %s\n", insn->format_name, insn->name, message); 97 1.1 christos if (next_message != NULL) 98 1.1 christos message = next_message; 99 1.1 christos } 100 1.1 christos } 101 1.1 christos 102 1.1 christos /* same as strcmp */ 103 1.1 christos static int 104 1.10 christos insn_field_cmp (const insn_word_entry *l, const insn_word_entry *r) 105 1.1 christos { 106 1.1 christos while (1) 107 1.1 christos { 108 1.1 christos int bit_nr; 109 1.1 christos if (l == NULL && r == NULL) 110 1.1 christos return 0; /* all previous fields the same */ 111 1.1 christos if (l == NULL) 112 1.1 christos return -1; /* left shorter than right */ 113 1.1 christos if (r == NULL) 114 1.1 christos return +1; /* left longer than right */ 115 1.1 christos for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++) 116 1.1 christos { 117 1.1 christos if (l->bit[bit_nr]->field->type != insn_field_string) 118 1.1 christos continue; 119 1.1 christos if (r->bit[bit_nr]->field->type != insn_field_string) 120 1.1 christos continue; 121 1.1 christos if (l->bit[bit_nr]->field->conditions == NULL) 122 1.1 christos continue; 123 1.1 christos if (r->bit[bit_nr]->field->conditions == NULL) 124 1.1 christos continue; 125 1.1 christos if (0) 126 1.1 christos printf ("%s%s%s VS %s%s%s\n", 127 1.1 christos l->bit[bit_nr]->field->val_string, 128 1.1 christos l->bit[bit_nr]->field->conditions->test == 129 1.1 christos insn_field_cond_eq ? "=" : "!", 130 1.1 christos l->bit[bit_nr]->field->conditions->string, 131 1.1 christos r->bit[bit_nr]->field->val_string, 132 1.1 christos r->bit[bit_nr]->field->conditions->test == 133 1.1 christos insn_field_cond_eq ? "=" : "!", 134 1.1 christos r->bit[bit_nr]->field->conditions->string); 135 1.1 christos if (l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq 136 1.1 christos && r->bit[bit_nr]->field->conditions->test == 137 1.1 christos insn_field_cond_eq) 138 1.1 christos { 139 1.1 christos if (l->bit[bit_nr]->field->conditions->type == 140 1.1 christos insn_field_cond_field 141 1.1 christos && r->bit[bit_nr]->field->conditions->type == 142 1.1 christos insn_field_cond_field) 143 1.1 christos /* somewhat arbitrary */ 144 1.1 christos { 145 1.1 christos int cmp = strcmp (l->bit[bit_nr]->field->conditions->string, 146 1.1 christos r->bit[bit_nr]->field->conditions-> 147 1.1 christos string); 148 1.1 christos if (cmp != 0) 149 1.1 christos return cmp; 150 1.1 christos else 151 1.1 christos continue; 152 1.1 christos } 153 1.1 christos if (l->bit[bit_nr]->field->conditions->type == 154 1.1 christos insn_field_cond_field) 155 1.1 christos return +1; 156 1.1 christos if (r->bit[bit_nr]->field->conditions->type == 157 1.1 christos insn_field_cond_field) 158 1.1 christos return -1; 159 1.1 christos /* The case of both fields having constant values should have 160 1.1 christos already have been handled because such fields are converted 161 1.1 christos into normal constant fields, but we must not make this 162 1.1 christos an assert, as we wouldn't gracefully handle an (invalid) 163 1.1 christos duplicate insn description. */ 164 1.1 christos continue; 165 1.1 christos } 166 1.1 christos if (l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq) 167 1.1 christos return +1; /* left = only */ 168 1.1 christos if (r->bit[bit_nr]->field->conditions->test == insn_field_cond_eq) 169 1.1 christos return -1; /* right = only */ 170 1.1 christos /* FIXME: Need to some what arbitrarily order conditional lists */ 171 1.1 christos continue; 172 1.1 christos } 173 1.1 christos l = l->next; 174 1.1 christos r = r->next; 175 1.1 christos } 176 1.1 christos } 177 1.1 christos 178 1.1 christos /* same as strcmp */ 179 1.1 christos static int 180 1.10 christos insn_word_cmp (const insn_word_entry *l, const insn_word_entry *r) 181 1.1 christos { 182 1.1 christos while (1) 183 1.1 christos { 184 1.1 christos int bit_nr; 185 1.1 christos if (l == NULL && r == NULL) 186 1.1 christos return 0; /* all previous fields the same */ 187 1.1 christos if (l == NULL) 188 1.1 christos return -1; /* left shorter than right */ 189 1.1 christos if (r == NULL) 190 1.1 christos return +1; /* left longer than right */ 191 1.1 christos for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++) 192 1.1 christos { 193 1.1 christos if (l->bit[bit_nr]->mask < r->bit[bit_nr]->mask) 194 1.1 christos return -1; 195 1.1 christos if (l->bit[bit_nr]->mask > r->bit[bit_nr]->mask) 196 1.1 christos return 1; 197 1.1 christos if (l->bit[bit_nr]->value < r->bit[bit_nr]->value) 198 1.1 christos return -1; 199 1.1 christos if (l->bit[bit_nr]->value > r->bit[bit_nr]->value) 200 1.1 christos return 1; 201 1.1 christos } 202 1.1 christos l = l->next; 203 1.1 christos r = r->next; 204 1.1 christos } 205 1.1 christos } 206 1.1 christos 207 1.1 christos /* same as strcmp */ 208 1.1 christos static int 209 1.10 christos opcode_bit_cmp (const opcode_bits *l, const opcode_bits *r) 210 1.1 christos { 211 1.1 christos if (l == NULL && r == NULL) 212 1.1 christos return 0; /* all previous bits the same */ 213 1.1 christos if (l == NULL) 214 1.1 christos return -1; /* left shorter than right */ 215 1.1 christos if (r == NULL) 216 1.1 christos return +1; /* left longer than right */ 217 1.1 christos /* most significant word */ 218 1.1 christos if (l->field->word_nr < r->field->word_nr) 219 1.1 christos return +1; /* left has more significant word */ 220 1.1 christos if (l->field->word_nr > r->field->word_nr) 221 1.1 christos return -1; /* right has more significant word */ 222 1.1 christos /* most significant bit? */ 223 1.1 christos if (l->first < r->first) 224 1.1 christos return +1; /* left as more significant bit */ 225 1.1 christos if (l->first > r->first) 226 1.1 christos return -1; /* right as more significant bit */ 227 1.1 christos /* nr bits? */ 228 1.1 christos if (l->last < r->last) 229 1.1 christos return +1; /* left as less bits */ 230 1.1 christos if (l->last > r->last) 231 1.1 christos return -1; /* right as less bits */ 232 1.1 christos /* value? */ 233 1.1 christos if (l->value < r->value) 234 1.1 christos return -1; 235 1.1 christos if (l->value > r->value) 236 1.1 christos return 1; 237 1.1 christos return 0; 238 1.1 christos } 239 1.1 christos 240 1.1 christos 241 1.1 christos /* same as strcmp */ 242 1.1 christos static int 243 1.10 christos opcode_bits_cmp (const opcode_bits *l, const opcode_bits *r) 244 1.1 christos { 245 1.1 christos while (1) 246 1.1 christos { 247 1.1 christos int cmp; 248 1.1 christos if (l == NULL && r == NULL) 249 1.1 christos return 0; /* all previous bits the same */ 250 1.1 christos cmp = opcode_bit_cmp (l, r); 251 1.1 christos if (cmp != 0) 252 1.1 christos return cmp; 253 1.1 christos l = l->next; 254 1.1 christos r = r->next; 255 1.1 christos } 256 1.1 christos } 257 1.1 christos 258 1.1 christos /* same as strcmp */ 259 1.1 christos static opcode_bits * 260 1.1 christos new_opcode_bits (opcode_bits *old_bits, 261 1.1 christos int value, 262 1.1 christos int first, 263 1.1 christos int last, insn_field_entry *field, opcode_field *opcode) 264 1.1 christos { 265 1.1 christos opcode_bits *new_bits = ZALLOC (opcode_bits); 266 1.1 christos new_bits->field = field; 267 1.1 christos new_bits->value = value; 268 1.1 christos new_bits->first = first; 269 1.1 christos new_bits->last = last; 270 1.1 christos new_bits->opcode = opcode; 271 1.1 christos 272 1.1 christos if (old_bits != NULL) 273 1.1 christos { 274 1.1 christos opcode_bits *new_list; 275 1.1 christos opcode_bits **last = &new_list; 276 1.1 christos new_list = new_opcode_bits (old_bits->next, 277 1.1 christos old_bits->value, 278 1.1 christos old_bits->first, 279 1.1 christos old_bits->last, 280 1.1 christos old_bits->field, old_bits->opcode); 281 1.1 christos while (*last != NULL) 282 1.1 christos { 283 1.1 christos int cmp = opcode_bit_cmp (new_bits, *last); 284 1.1 christos if (cmp < 0) /* new < new_list */ 285 1.1 christos { 286 1.1 christos break; 287 1.1 christos } 288 1.1 christos if (cmp == 0) 289 1.1 christos { 290 1.1 christos ERROR ("Duplicated insn bits in list"); 291 1.1 christos } 292 1.1 christos last = &(*last)->next; 293 1.1 christos } 294 1.1 christos new_bits->next = *last; 295 1.1 christos *last = new_bits; 296 1.1 christos return new_list; 297 1.1 christos } 298 1.1 christos else 299 1.1 christos { 300 1.1 christos return new_bits; 301 1.1 christos } 302 1.1 christos } 303 1.1 christos 304 1.1 christos /* Same as strcmp(). */ 305 1.1 christos static int 306 1.1 christos name_cmp (const char *l, const char *r) 307 1.1 christos { 308 1.1 christos if (l == NULL && r == NULL) 309 1.1 christos return 0; 310 1.1 christos if (l != NULL && r == NULL) 311 1.1 christos return -1; 312 1.1 christos if (l == NULL && r != NULL) 313 1.1 christos return +1; 314 1.1 christos return strcmp (l, r); 315 1.1 christos } 316 1.1 christos 317 1.1 christos 318 1.1 christos typedef enum 319 1.1 christos { 320 1.1 christos merge_duplicate_insns, 321 1.1 christos report_duplicate_insns, 322 1.1 christos } 323 1.1 christos duplicate_insn_actions; 324 1.1 christos 325 1.1 christos static insn_list * 326 1.1 christos insn_list_insert (insn_list **cur_insn_ptr, 327 1.1 christos int *nr_insns, 328 1.1 christos insn_entry * insn, 329 1.1 christos opcode_bits *expanded_bits, 330 1.1 christos opcode_field *opcodes, 331 1.1 christos int nr_prefetched_words, 332 1.1 christos duplicate_insn_actions duplicate_action) 333 1.1 christos { 334 1.1 christos /* insert it according to the order of the fields & bits */ 335 1.1 christos for (; (*cur_insn_ptr) != NULL; cur_insn_ptr = &(*cur_insn_ptr)->next) 336 1.1 christos { 337 1.1 christos int cmp; 338 1.1 christos 339 1.1 christos /* key#1 sort according to the constant fields of each instruction */ 340 1.1 christos cmp = insn_word_cmp (insn->words, (*cur_insn_ptr)->insn->words); 341 1.1 christos if (cmp < 0) 342 1.1 christos break; 343 1.1 christos else if (cmp > 0) 344 1.1 christos continue; 345 1.1 christos 346 1.1 christos /* key#2 sort according to the expanded bits of each instruction */ 347 1.1 christos cmp = opcode_bits_cmp (expanded_bits, (*cur_insn_ptr)->expanded_bits); 348 1.1 christos if (cmp < 0) 349 1.1 christos break; 350 1.1 christos else if (cmp > 0) 351 1.1 christos continue; 352 1.1 christos 353 1.1 christos /* key#3 sort according to the non-constant fields of each instruction */ 354 1.1 christos cmp = insn_field_cmp (insn->words, (*cur_insn_ptr)->insn->words); 355 1.1 christos if (cmp < 0) 356 1.1 christos break; 357 1.1 christos else if (cmp > 0) 358 1.1 christos continue; 359 1.1 christos 360 1.1 christos if (duplicate_action == merge_duplicate_insns) 361 1.1 christos { 362 1.1 christos /* key#4: If we're going to merge duplicates, also sort 363 1.1 christos according to the format_name. Two instructions with 364 1.1 christos identical decode patterns, but different names, are 365 1.1 christos considered different when merging. Duplicates are only 366 1.1 christos important when creating a decode table (implied by 367 1.1 christos report_duplicate_insns) as such a table only has the 368 1.1 christos instruction's bit code as a way of differentiating 369 1.1 christos between instructions. */ 370 1.1 christos int cmp = name_cmp (insn->format_name, 371 1.1 christos (*cur_insn_ptr)->insn->format_name); 372 1.1 christos if (cmp < 0) 373 1.1 christos break; 374 1.1 christos else if (cmp > 0) 375 1.1 christos continue; 376 1.1 christos } 377 1.1 christos 378 1.1 christos if (duplicate_action == merge_duplicate_insns) 379 1.1 christos { 380 1.1 christos /* key#5: If we're going to merge duplicates, also sort 381 1.1 christos according to the name. See comment above for 382 1.1 christos format_name. */ 383 1.1 christos int cmp = name_cmp (insn->name, (*cur_insn_ptr)->insn->name); 384 1.1 christos if (cmp < 0) 385 1.1 christos break; 386 1.1 christos else if (cmp > 0) 387 1.1 christos continue; 388 1.1 christos } 389 1.1 christos 390 1.1 christos /* duplicate keys, report problem */ 391 1.1 christos switch (duplicate_action) 392 1.1 christos { 393 1.1 christos case report_duplicate_insns: 394 1.1 christos /* It would appear that we have two instructions with the 395 1.1 christos same constant field values across all words and bits. 396 1.1 christos This error can also occure when insn_field_cmp() is 397 1.1 christos failing to differentiate between two instructions that 398 1.1 christos differ only in their conditional fields. */ 399 1.1 christos warning (insn->line, 400 1.1 christos "Two instructions with identical constant fields\n"); 401 1.1 christos error ((*cur_insn_ptr)->insn->line, 402 1.1 christos "Location of duplicate instruction\n"); 403 1.1 christos case merge_duplicate_insns: 404 1.1 christos /* Add the opcode path to the instructions list */ 405 1.1 christos if (options.trace.insn_insertion) 406 1.1 christos { 407 1.1 christos notify ((*cur_insn_ptr)->insn->line, 408 1.1 christos "%s.%s: insert merge %s.%s\n", 409 1.1 christos (*cur_insn_ptr)->insn->format_name, 410 1.1 christos (*cur_insn_ptr)->insn->name, 411 1.1 christos insn->format_name, 412 1.1 christos insn->name); 413 1.1 christos } 414 1.1 christos if (opcodes != NULL) 415 1.1 christos { 416 1.1 christos insn_opcodes **last = &(*cur_insn_ptr)->opcodes; 417 1.1 christos while (*last != NULL) 418 1.1 christos { 419 1.1 christos last = &(*last)->next; 420 1.1 christos } 421 1.1 christos (*last) = ZALLOC (insn_opcodes); 422 1.1 christos (*last)->opcode = opcodes; 423 1.1 christos } 424 1.1 christos /* Use the larger nr_prefetched_words */ 425 1.1 christos if ((*cur_insn_ptr)->nr_prefetched_words < nr_prefetched_words) 426 1.1 christos (*cur_insn_ptr)->nr_prefetched_words = nr_prefetched_words; 427 1.1 christos return (*cur_insn_ptr); 428 1.1 christos } 429 1.1 christos 430 1.1 christos } 431 1.1 christos 432 1.1 christos /* create a new list entry and insert it */ 433 1.1 christos { 434 1.1 christos insn_list *new_insn = ZALLOC (insn_list); 435 1.1 christos if (options.trace.insn_insertion) 436 1.1 christos { 437 1.1 christos notify (insn->line, 438 1.1 christos "%s.%s: insert new\n", 439 1.1 christos insn->format_name, 440 1.1 christos insn->name); 441 1.1 christos } 442 1.1 christos new_insn->insn = insn; 443 1.1 christos new_insn->expanded_bits = expanded_bits; 444 1.1 christos new_insn->next = (*cur_insn_ptr); 445 1.1 christos new_insn->nr_prefetched_words = nr_prefetched_words; 446 1.1 christos if (opcodes != NULL) 447 1.1 christos { 448 1.1 christos new_insn->opcodes = ZALLOC (insn_opcodes); 449 1.1 christos new_insn->opcodes->opcode = opcodes; 450 1.1 christos } 451 1.1 christos (*cur_insn_ptr) = new_insn; 452 1.1 christos } 453 1.1 christos 454 1.1 christos *nr_insns += 1; 455 1.1 christos 456 1.1 christos return (*cur_insn_ptr); 457 1.1 christos } 458 1.1 christos 459 1.1 christos 460 1.1 christos extern void 461 1.1 christos gen_entry_traverse_tree (lf *file, 462 1.10 christos const gen_entry *table, 463 1.1 christos int depth, 464 1.1 christos gen_entry_handler * start, 465 1.1 christos gen_entry_handler * leaf, 466 1.1 christos gen_entry_handler * end, void *data) 467 1.1 christos { 468 1.1 christos gen_entry *entry; 469 1.1 christos 470 1.1 christos ASSERT (table !=NULL); 471 1.1 christos ASSERT (table->opcode != NULL); 472 1.1 christos ASSERT (table->nr_entries > 0); 473 1.1 christos ASSERT (table->entries != 0); 474 1.1 christos 475 1.1 christos /* prefix */ 476 1.1 christos if (start != NULL && depth >= 0) 477 1.1 christos { 478 1.1 christos start (file, table, depth, data); 479 1.1 christos } 480 1.1 christos /* infix leaves */ 481 1.1 christos for (entry = table->entries; entry != NULL; entry = entry->sibling) 482 1.1 christos { 483 1.1 christos if (entry->entries != NULL && depth != 0) 484 1.1 christos { 485 1.1 christos gen_entry_traverse_tree (file, entry, depth + 1, 486 1.1 christos start, leaf, end, data); 487 1.1 christos } 488 1.1 christos else if (depth >= 0) 489 1.1 christos { 490 1.1 christos if (leaf != NULL) 491 1.1 christos { 492 1.1 christos leaf (file, entry, depth, data); 493 1.1 christos } 494 1.1 christos } 495 1.1 christos } 496 1.1 christos /* postfix */ 497 1.1 christos if (end != NULL && depth >= 0) 498 1.1 christos { 499 1.1 christos end (file, table, depth, data); 500 1.1 christos } 501 1.1 christos } 502 1.1 christos 503 1.1 christos 504 1.1 christos 505 1.1 christos /* create a list element containing a single gen_table entry */ 506 1.1 christos 507 1.1 christos static gen_list * 508 1.10 christos make_table (const insn_table *isa, 509 1.10 christos const decode_table *rules, 510 1.10 christos const model_entry *model) 511 1.1 christos { 512 1.1 christos insn_entry *insn; 513 1.1 christos gen_list *entry = ZALLOC (gen_list); 514 1.1 christos entry->table = ZALLOC (gen_entry); 515 1.1 christos entry->table->top = entry; 516 1.1 christos entry->model = model; 517 1.1 christos entry->isa = isa; 518 1.1 christos for (insn = isa->insns; insn != NULL; insn = insn->next) 519 1.1 christos { 520 1.1 christos if (model == NULL 521 1.1 christos || insn->processors == NULL 522 1.1 christos || filter_is_member (insn->processors, model->name)) 523 1.1 christos { 524 1.1 christos insn_list_insert (&entry->table->insns, &entry->table->nr_insns, insn, NULL, /* expanded_bits - none yet */ 525 1.1 christos NULL, /* opcodes - none yet */ 526 1.1 christos 0, /* nr_prefetched_words - none yet */ 527 1.1 christos report_duplicate_insns); 528 1.1 christos } 529 1.1 christos } 530 1.1 christos entry->table->opcode_rule = rules; 531 1.1 christos return entry; 532 1.1 christos } 533 1.1 christos 534 1.1 christos 535 1.1 christos gen_table * 536 1.10 christos make_gen_tables (const insn_table *isa, const decode_table *rules) 537 1.1 christos { 538 1.1 christos gen_table *gen = ZALLOC (gen_table); 539 1.1 christos gen->isa = isa; 540 1.1 christos gen->rules = rules; 541 1.1 christos if (options.gen.multi_sim) 542 1.1 christos { 543 1.1 christos gen_list **last = &gen->tables; 544 1.1 christos model_entry *model; 545 1.1 christos filter *processors; 546 1.1 christos if (options.model_filter != NULL) 547 1.1 christos processors = options.model_filter; 548 1.1 christos else 549 1.1 christos processors = isa->model->processors; 550 1.1 christos for (model = isa->model->models; model != NULL; model = model->next) 551 1.1 christos { 552 1.1 christos if (filter_is_member (processors, model->name)) 553 1.1 christos { 554 1.1 christos *last = make_table (isa, rules, model); 555 1.1 christos last = &(*last)->next; 556 1.1 christos } 557 1.1 christos } 558 1.1 christos } 559 1.1 christos else 560 1.1 christos { 561 1.1 christos gen->tables = make_table (isa, rules, NULL); 562 1.1 christos } 563 1.1 christos return gen; 564 1.1 christos } 565 1.1 christos 566 1.1 christos 567 1.1 christos /****************************************************************/ 568 1.1 christos 569 1.1 christos /* Is the bit, according to the decode rule, identical across all the 570 1.1 christos instructions? */ 571 1.1 christos static int 572 1.10 christos insns_bit_useless (const insn_list *insns, const decode_table *rule, int bit_nr) 573 1.1 christos { 574 1.10 christos const insn_list *entry; 575 1.1 christos int value = -1; 576 1.1 christos int is_useless = 1; /* cleared if something actually found */ 577 1.1 christos 578 1.1 christos /* check the instructions for some constant value in at least one of 579 1.1 christos the bit fields */ 580 1.1 christos for (entry = insns; entry != NULL; entry = entry->next) 581 1.1 christos { 582 1.1 christos insn_word_entry *word = entry->insn->word[rule->word_nr]; 583 1.1 christos insn_bit_entry *bit = word->bit[bit_nr]; 584 1.1 christos switch (bit->field->type) 585 1.1 christos { 586 1.1 christos case insn_field_invalid: 587 1.1 christos ASSERT (0); 588 1.1 christos break; 589 1.1 christos case insn_field_wild: 590 1.1 christos case insn_field_reserved: 591 1.1 christos /* neither useless or useful - ignore */ 592 1.1 christos break; 593 1.1 christos case insn_field_int: 594 1.1 christos switch (rule->search) 595 1.1 christos { 596 1.1 christos case decode_find_strings: 597 1.1 christos /* an integer isn't a string */ 598 1.1 christos return 1; 599 1.1 christos case decode_find_constants: 600 1.1 christos case decode_find_mixed: 601 1.1 christos /* an integer is useful if its value isn't the same 602 1.1 christos between all instructions. The first time through the 603 1.1 christos value is saved, the second time through (if the 604 1.1 christos values differ) it is marked as useful. */ 605 1.1 christos if (value < 0) 606 1.1 christos value = bit->value; 607 1.1 christos else if (value != bit->value) 608 1.1 christos is_useless = 0; 609 1.1 christos break; 610 1.1 christos } 611 1.1 christos break; 612 1.1 christos case insn_field_string: 613 1.1 christos switch (rule->search) 614 1.1 christos { 615 1.1 christos case decode_find_strings: 616 1.1 christos /* at least one string, keep checking */ 617 1.1 christos is_useless = 0; 618 1.1 christos break; 619 1.1 christos case decode_find_constants: 620 1.1 christos case decode_find_mixed: 621 1.1 christos if (filter_is_member (rule->constant_field_names, 622 1.1 christos bit->field->val_string)) 623 1.1 christos /* a string field forced to constant? */ 624 1.1 christos is_useless = 0; 625 1.1 christos else if (bit->field->conditions != NULL 626 1.1 christos && bit->field->conditions->test == insn_field_cond_eq 627 1.1 christos && bit->field->conditions->type == insn_field_cond_value) 628 1.1 christos { 629 1.1 christos int shift = bit->field->last - bit_nr; 630 1.1 christos int bitvalue = (bit->field->conditions->value >> shift) & 1; 631 1.1 christos 632 1.1 christos if (value < 0) 633 1.1 christos value = bitvalue; 634 1.1 christos else if (value != bitvalue) 635 1.1 christos is_useless = 0; 636 1.1 christos } 637 1.1 christos else if (rule->search == decode_find_constants) 638 1.1 christos /* the string field isn't constant */ 639 1.1 christos return 1; 640 1.1 christos break; 641 1.1 christos } 642 1.1 christos } 643 1.1 christos } 644 1.1 christos 645 1.1 christos /* Given only one constant value has been found, check through all 646 1.1 christos the instructions to see if at least one conditional makes it 647 1.1 christos usefull */ 648 1.1 christos if (value >= 0 && is_useless) 649 1.1 christos { 650 1.1 christos for (entry = insns; entry != NULL; entry = entry->next) 651 1.1 christos { 652 1.1 christos insn_word_entry *word = entry->insn->word[rule->word_nr]; 653 1.1 christos insn_bit_entry *bit = word->bit[bit_nr]; 654 1.1 christos switch (bit->field->type) 655 1.1 christos { 656 1.1 christos case insn_field_invalid: 657 1.1 christos ASSERT (0); 658 1.1 christos break; 659 1.1 christos case insn_field_wild: 660 1.1 christos case insn_field_reserved: 661 1.1 christos case insn_field_int: 662 1.1 christos /* already processed */ 663 1.1 christos break; 664 1.1 christos case insn_field_string: 665 1.1 christos switch (rule->search) 666 1.1 christos { 667 1.1 christos case decode_find_strings: 668 1.1 christos case decode_find_constants: 669 1.1 christos /* already processed */ 670 1.1 christos break; 671 1.1 christos case decode_find_mixed: 672 1.1 christos /* string field with conditions. If this condition 673 1.1 christos eliminates the value then the compare is useful */ 674 1.1 christos if (bit->field->conditions != NULL) 675 1.1 christos { 676 1.1 christos insn_field_cond *condition; 677 1.1 christos int shift = bit->field->last - bit_nr; 678 1.1 christos for (condition = bit->field->conditions; 679 1.1 christos condition != NULL; condition = condition->next) 680 1.1 christos { 681 1.1 christos switch (condition->type) 682 1.1 christos { 683 1.1 christos case insn_field_cond_value: 684 1.1 christos switch (condition->test) 685 1.1 christos { 686 1.1 christos case insn_field_cond_ne: 687 1.1 christos if (((condition->value >> shift) & 1) 688 1.1 christos == (unsigned) value) 689 1.1 christos /* conditional field excludes the 690 1.1 christos current value */ 691 1.1 christos is_useless = 0; 692 1.1 christos break; 693 1.1 christos case insn_field_cond_eq: 694 1.1 christos if (((condition->value >> shift) & 1) 695 1.1 christos != (unsigned) value) 696 1.1 christos /* conditional field requires the 697 1.1 christos current value */ 698 1.1 christos is_useless = 0; 699 1.1 christos break; 700 1.1 christos } 701 1.1 christos break; 702 1.1 christos case insn_field_cond_field: 703 1.1 christos /* are these handled separatly? */ 704 1.1 christos break; 705 1.1 christos } 706 1.1 christos } 707 1.1 christos } 708 1.1 christos } 709 1.1 christos } 710 1.1 christos } 711 1.1 christos } 712 1.1 christos 713 1.1 christos return is_useless; 714 1.1 christos } 715 1.1 christos 716 1.1 christos 717 1.1 christos /* go through a gen-table's list of instruction formats looking for a 718 1.1 christos range of bits that meet the decode table RULEs requirements */ 719 1.1 christos 720 1.1 christos static opcode_field * 721 1.1 christos gen_entry_find_opcode_field (insn_list *insns, 722 1.10 christos const decode_table *rule, int string_only) 723 1.1 christos { 724 1.1 christos opcode_field curr_opcode; 725 1.1 christos ASSERT (rule != NULL); 726 1.1 christos 727 1.1 christos memset (&curr_opcode, 0, sizeof (curr_opcode)); 728 1.1 christos curr_opcode.word_nr = rule->word_nr; 729 1.1 christos curr_opcode.first = rule->first; 730 1.1 christos curr_opcode.last = rule->last; 731 1.1 christos 732 1.1 christos /* Try to reduce the size of first..last in accordance with the 733 1.1 christos decode rules */ 734 1.1 christos 735 1.1 christos while (curr_opcode.first <= rule->last) 736 1.1 christos { 737 1.1 christos if (insns_bit_useless (insns, rule, curr_opcode.first)) 738 1.1 christos curr_opcode.first++; 739 1.1 christos else 740 1.1 christos break; 741 1.1 christos } 742 1.1 christos while (curr_opcode.last >= rule->first) 743 1.1 christos { 744 1.1 christos if (insns_bit_useless (insns, rule, curr_opcode.last)) 745 1.1 christos curr_opcode.last--; 746 1.1 christos else 747 1.1 christos break; 748 1.1 christos } 749 1.1 christos 750 1.1 christos /* did the final opcode field end up being empty? */ 751 1.1 christos if (curr_opcode.first > curr_opcode.last) 752 1.1 christos { 753 1.1 christos return NULL; 754 1.1 christos } 755 1.1 christos ASSERT (curr_opcode.last >= rule->first); 756 1.1 christos ASSERT (curr_opcode.first <= rule->last); 757 1.1 christos ASSERT (curr_opcode.first <= curr_opcode.last); 758 1.1 christos 759 1.1 christos /* Ensure that, for the non string only case, the opcode includes 760 1.1 christos the range forced_first .. forced_last */ 761 1.1 christos if (!string_only && curr_opcode.first > rule->force_first) 762 1.1 christos { 763 1.1 christos curr_opcode.first = rule->force_first; 764 1.1 christos } 765 1.1 christos if (!string_only && curr_opcode.last < rule->force_last) 766 1.1 christos { 767 1.1 christos curr_opcode.last = rule->force_last; 768 1.1 christos } 769 1.1 christos 770 1.1 christos /* For the string only case, force just the lower bound (so that the 771 1.1 christos shift can be eliminated) */ 772 1.1 christos if (string_only && rule->force_last == options.insn_bit_size - 1) 773 1.1 christos { 774 1.1 christos curr_opcode.last = options.insn_bit_size - 1; 775 1.1 christos } 776 1.1 christos 777 1.1 christos /* handle any special cases */ 778 1.1 christos switch (rule->type) 779 1.1 christos { 780 1.1 christos case normal_decode_rule: 781 1.1 christos /* let the above apply */ 782 1.1 christos curr_opcode.nr_opcodes = 783 1.1 christos (1 << (curr_opcode.last - curr_opcode.first + 1)); 784 1.1 christos break; 785 1.1 christos case boolean_rule: 786 1.1 christos curr_opcode.is_boolean = 1; 787 1.1 christos curr_opcode.boolean_constant = rule->constant; 788 1.1 christos curr_opcode.nr_opcodes = 2; 789 1.1 christos break; 790 1.1 christos } 791 1.1 christos 792 1.1 christos { 793 1.1 christos opcode_field *new_field = ZALLOC (opcode_field); 794 1.1 christos memcpy (new_field, &curr_opcode, sizeof (opcode_field)); 795 1.1 christos return new_field; 796 1.1 christos } 797 1.1 christos } 798 1.1 christos 799 1.1 christos 800 1.1 christos static void 801 1.1 christos gen_entry_insert_insn (gen_entry *table, 802 1.1 christos insn_entry * old_insn, 803 1.1 christos int new_word_nr, 804 1.1 christos int new_nr_prefetched_words, 805 1.1 christos int new_opcode_nr, opcode_bits *new_bits) 806 1.1 christos { 807 1.1 christos gen_entry **entry = &table->entries; 808 1.1 christos 809 1.1 christos /* find the new table for this entry */ 810 1.1 christos while ((*entry) != NULL && (*entry)->opcode_nr < new_opcode_nr) 811 1.1 christos { 812 1.1 christos entry = &(*entry)->sibling; 813 1.1 christos } 814 1.1 christos 815 1.1 christos if ((*entry) == NULL || (*entry)->opcode_nr != new_opcode_nr) 816 1.1 christos { 817 1.1 christos /* insert the missing entry */ 818 1.1 christos gen_entry *new_entry = ZALLOC (gen_entry); 819 1.1 christos new_entry->sibling = (*entry); 820 1.1 christos (*entry) = new_entry; 821 1.1 christos table->nr_entries++; 822 1.1 christos /* fill it in */ 823 1.1 christos new_entry->top = table->top; 824 1.1 christos new_entry->opcode_nr = new_opcode_nr; 825 1.1 christos new_entry->word_nr = new_word_nr; 826 1.1 christos new_entry->expanded_bits = new_bits; 827 1.1 christos new_entry->opcode_rule = table->opcode_rule->next; 828 1.1 christos new_entry->parent = table; 829 1.1 christos new_entry->nr_prefetched_words = new_nr_prefetched_words; 830 1.1 christos } 831 1.1 christos /* ASSERT new_bits == cur_entry bits */ 832 1.1 christos ASSERT ((*entry) != NULL && (*entry)->opcode_nr == new_opcode_nr); 833 1.1 christos insn_list_insert (&(*entry)->insns, &(*entry)->nr_insns, old_insn, NULL, /* expanded_bits - only in final list */ 834 1.1 christos NULL, /* opcodes - only in final list */ 835 1.1 christos new_nr_prefetched_words, /* for this table */ 836 1.1 christos report_duplicate_insns); 837 1.1 christos } 838 1.1 christos 839 1.1 christos 840 1.1 christos static void 841 1.1 christos gen_entry_expand_opcode (gen_entry *table, 842 1.1 christos insn_entry * instruction, 843 1.1 christos int bit_nr, int opcode_nr, opcode_bits *bits) 844 1.1 christos { 845 1.1 christos if (bit_nr > table->opcode->last) 846 1.1 christos { 847 1.1 christos /* Only include the hardwired bit information with an entry IF 848 1.1 christos that entry (and hence its functions) are being duplicated. */ 849 1.1 christos if (options.trace.insn_expansion) 850 1.1 christos { 851 1.1 christos print_gen_entry_path (table->opcode_rule->line, table, notify); 852 1.1 christos notify (NULL, ": insert %d - %s.%s%s\n", 853 1.1 christos opcode_nr, 854 1.1 christos instruction->format_name, 855 1.1 christos instruction->name, 856 1.1 christos (table->opcode_rule-> 857 1.1 christos with_duplicates ? " (duplicated)" : "")); 858 1.1 christos } 859 1.1 christos if (table->opcode_rule->with_duplicates) 860 1.1 christos { 861 1.1 christos gen_entry_insert_insn (table, instruction, 862 1.1 christos table->opcode->word_nr, 863 1.1 christos table->nr_prefetched_words, opcode_nr, bits); 864 1.1 christos } 865 1.1 christos else 866 1.1 christos { 867 1.1 christos gen_entry_insert_insn (table, instruction, 868 1.1 christos table->opcode->word_nr, 869 1.1 christos table->nr_prefetched_words, opcode_nr, NULL); 870 1.1 christos } 871 1.1 christos } 872 1.1 christos else 873 1.1 christos { 874 1.1 christos insn_word_entry *word = instruction->word[table->opcode->word_nr]; 875 1.1 christos insn_field_entry *field = word->bit[bit_nr]->field; 876 1.1 christos int last_pos = ((field->last < table->opcode->last) 877 1.1 christos ? field->last : table->opcode->last); 878 1.1 christos int first_pos = ((field->first > table->opcode->first) 879 1.1 christos ? field->first : table->opcode->first); 880 1.1 christos int width = last_pos - first_pos + 1; 881 1.1 christos switch (field->type) 882 1.1 christos { 883 1.1 christos case insn_field_int: 884 1.1 christos { 885 1.1 christos int val; 886 1.1 christos val = sub_val (field->val_int, field->last, first_pos, last_pos); 887 1.1 christos gen_entry_expand_opcode (table, instruction, 888 1.1 christos last_pos + 1, 889 1.1 christos ((opcode_nr << width) | val), bits); 890 1.1 christos break; 891 1.1 christos } 892 1.1 christos default: 893 1.1 christos { 894 1.1 christos if (field->type == insn_field_reserved) 895 1.1 christos gen_entry_expand_opcode (table, instruction, 896 1.1 christos last_pos + 1, 897 1.1 christos ((opcode_nr << width)), bits); 898 1.1 christos else 899 1.1 christos { 900 1.1 christos int val; 901 1.1 christos int last_val = (table->opcode->is_boolean ? 2 : (1 << width)); 902 1.1 christos for (val = 0; val < last_val; val++) 903 1.1 christos { 904 1.1 christos /* check to see if the value has been precluded 905 1.1 christos (by a conditional) in some way */ 906 1.1 christos int is_precluded; 907 1.1 christos insn_field_cond *condition; 908 1.1 christos for (condition = field->conditions, is_precluded = 0; 909 1.1 christos condition != NULL && !is_precluded; 910 1.1 christos condition = condition->next) 911 1.1 christos { 912 1.1 christos switch (condition->type) 913 1.1 christos { 914 1.1 christos case insn_field_cond_value: 915 1.1 christos { 916 1.1 christos int value = 917 1.1 christos sub_val (condition->value, field->last, 918 1.1 christos first_pos, last_pos); 919 1.1 christos switch (condition->test) 920 1.1 christos { 921 1.1 christos case insn_field_cond_ne: 922 1.1 christos if (value == val) 923 1.1 christos is_precluded = 1; 924 1.1 christos break; 925 1.1 christos case insn_field_cond_eq: 926 1.1 christos if (value != val) 927 1.1 christos is_precluded = 1; 928 1.1 christos break; 929 1.1 christos } 930 1.1 christos break; 931 1.1 christos } 932 1.1 christos case insn_field_cond_field: 933 1.1 christos { 934 1.1 christos int value = -1; 935 1.1 christos opcode_bits *bit; 936 1.1 christos gen_entry *t = NULL; 937 1.1 christos /* Try to find a value for the 938 1.1 christos conditional by looking back through 939 1.1 christos the previously defined bits for one 940 1.1 christos that covers the designated 941 1.1 christos conditional field */ 942 1.1 christos for (bit = bits; bit != NULL; bit = bit->next) 943 1.1 christos { 944 1.1 christos if (bit->field->word_nr == 945 1.1 christos condition->field->word_nr 946 1.1 christos && bit->first <= condition->field->first 947 1.1 christos && bit->last >= condition->field->last) 948 1.1 christos { 949 1.1 christos /* the bit field fully specified 950 1.1 christos the conditional field's value */ 951 1.1 christos value = sub_val (bit->value, bit->last, 952 1.1 christos condition->field-> 953 1.1 christos first, 954 1.1 christos condition->field-> 955 1.1 christos last); 956 1.1 christos } 957 1.1 christos } 958 1.1 christos /* Try to find a value by looking 959 1.1 christos through this and previous tables */ 960 1.1 christos if (bit == NULL) 961 1.1 christos { 962 1.1 christos for (t = table; 963 1.1 christos t->parent != NULL; t = t->parent) 964 1.1 christos { 965 1.1 christos if (t->parent->opcode->word_nr == 966 1.1 christos condition->field->word_nr 967 1.1 christos && t->parent->opcode->first <= 968 1.1 christos condition->field->first 969 1.1 christos && t->parent->opcode->last >= 970 1.1 christos condition->field->last) 971 1.1 christos { 972 1.1 christos /* the table entry fully 973 1.1 christos specified the condition 974 1.1 christos field's value */ 975 1.1 christos /* extract the field's value 976 1.1 christos from the opcode */ 977 1.1 christos value = 978 1.1 christos sub_val (t->opcode_nr, 979 1.1 christos t->parent->opcode->last, 980 1.1 christos condition->field->first, 981 1.1 christos condition->field->last); 982 1.1 christos /* this is a requirement of 983 1.1 christos a conditonal field 984 1.1 christos refering to another field */ 985 1.1 christos ASSERT ((condition->field->first - 986 1.1 christos condition->field->last) == 987 1.1 christos (first_pos - last_pos)); 988 1.1 christos printf 989 1.1 christos ("value=%d, opcode_nr=%d, last=%d, [%d..%d]\n", 990 1.1 christos value, t->opcode_nr, 991 1.1 christos t->parent->opcode->last, 992 1.1 christos condition->field->first, 993 1.1 christos condition->field->last); 994 1.1 christos } 995 1.1 christos } 996 1.1 christos } 997 1.1 christos if (bit == NULL && t == NULL) 998 1.1 christos error (instruction->line, 999 1.10 christos "Conditional `%s' of field `%s' isn't expanded\n", 1000 1.1 christos condition->string, field->val_string); 1001 1.1 christos switch (condition->test) 1002 1.1 christos { 1003 1.1 christos case insn_field_cond_ne: 1004 1.1 christos if (value == val) 1005 1.1 christos is_precluded = 1; 1006 1.1 christos break; 1007 1.1 christos case insn_field_cond_eq: 1008 1.1 christos if (value != val) 1009 1.1 christos is_precluded = 1; 1010 1.1 christos break; 1011 1.1 christos } 1012 1.1 christos break; 1013 1.1 christos } 1014 1.1 christos } 1015 1.1 christos } 1016 1.1 christos if (!is_precluded) 1017 1.1 christos { 1018 1.1 christos /* Only add additional hardwired bit 1019 1.1 christos information if the entry is not going to 1020 1.1 christos later be combined */ 1021 1.1 christos if (table->opcode_rule->with_combine) 1022 1.1 christos { 1023 1.1 christos gen_entry_expand_opcode (table, instruction, 1024 1.1 christos last_pos + 1, 1025 1.1 christos ((opcode_nr << width) | 1026 1.1 christos val), bits); 1027 1.1 christos } 1028 1.1 christos else 1029 1.1 christos { 1030 1.1 christos opcode_bits *new_bits = 1031 1.1 christos new_opcode_bits (bits, val, 1032 1.1 christos first_pos, last_pos, 1033 1.1 christos field, 1034 1.1 christos table->opcode); 1035 1.1 christos gen_entry_expand_opcode (table, instruction, 1036 1.1 christos last_pos + 1, 1037 1.1 christos ((opcode_nr << width) | 1038 1.1 christos val), new_bits); 1039 1.1 christos } 1040 1.1 christos } 1041 1.1 christos } 1042 1.1 christos } 1043 1.1 christos } 1044 1.1 christos } 1045 1.1 christos } 1046 1.1 christos } 1047 1.1 christos 1048 1.1 christos static void 1049 1.1 christos gen_entry_insert_expanding (gen_entry *table, insn_entry * instruction) 1050 1.1 christos { 1051 1.1 christos gen_entry_expand_opcode (table, 1052 1.1 christos instruction, 1053 1.1 christos table->opcode->first, 0, table->expanded_bits); 1054 1.1 christos } 1055 1.1 christos 1056 1.1 christos 1057 1.1 christos static int 1058 1.1 christos insns_match_format_names (insn_list *insns, filter *format_names) 1059 1.1 christos { 1060 1.1 christos if (format_names != NULL) 1061 1.1 christos { 1062 1.1 christos insn_list *i; 1063 1.1 christos for (i = insns; i != NULL; i = i->next) 1064 1.1 christos { 1065 1.1 christos if (i->insn->format_name != NULL 1066 1.1 christos && !filter_is_member (format_names, i->insn->format_name)) 1067 1.1 christos return 0; 1068 1.1 christos } 1069 1.1 christos } 1070 1.1 christos return 1; 1071 1.1 christos } 1072 1.1 christos 1073 1.1 christos static int 1074 1.1 christos table_matches_path (gen_entry *table, decode_path_list *paths) 1075 1.1 christos { 1076 1.1 christos if (paths == NULL) 1077 1.1 christos return 1; 1078 1.1 christos while (paths != NULL) 1079 1.1 christos { 1080 1.1 christos gen_entry *entry = table; 1081 1.1 christos decode_path *path = paths->path; 1082 1.1 christos while (1) 1083 1.1 christos { 1084 1.1 christos if (entry == NULL && path == NULL) 1085 1.1 christos return 1; 1086 1.1 christos if (entry == NULL || path == NULL) 1087 1.1 christos break; 1088 1.1 christos if (entry->opcode_nr != path->opcode_nr) 1089 1.1 christos break; 1090 1.1 christos entry = entry->parent; 1091 1.1 christos path = path->parent; 1092 1.1 christos } 1093 1.1 christos paths = paths->next; 1094 1.1 christos } 1095 1.1 christos return 0; 1096 1.1 christos } 1097 1.1 christos 1098 1.1 christos 1099 1.1 christos static int 1100 1.1 christos insns_match_conditions (insn_list *insns, decode_cond *conditions) 1101 1.1 christos { 1102 1.1 christos if (conditions != NULL) 1103 1.1 christos { 1104 1.1 christos insn_list *i; 1105 1.1 christos for (i = insns; i != NULL; i = i->next) 1106 1.1 christos { 1107 1.1 christos decode_cond *cond; 1108 1.1 christos for (cond = conditions; cond != NULL; cond = cond->next) 1109 1.1 christos { 1110 1.1 christos int bit_nr; 1111 1.1 christos if (i->insn->nr_words <= cond->word_nr) 1112 1.1 christos return 0; 1113 1.1 christos for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++) 1114 1.1 christos { 1115 1.1 christos if (!cond->mask[bit_nr]) 1116 1.1 christos continue; 1117 1.1 christos if (!i->insn->word[cond->word_nr]->bit[bit_nr]->mask) 1118 1.1 christos return 0; 1119 1.1 christos if ((i->insn->word[cond->word_nr]->bit[bit_nr]->value 1120 1.1 christos == cond->value[bit_nr]) == !cond->is_equal) 1121 1.1 christos return 0; 1122 1.1 christos } 1123 1.1 christos } 1124 1.1 christos } 1125 1.1 christos } 1126 1.1 christos return 1; 1127 1.1 christos } 1128 1.1 christos 1129 1.1 christos static int 1130 1.10 christos insns_match_nr_words (const insn_list *insns, int nr_words) 1131 1.1 christos { 1132 1.10 christos const insn_list *i; 1133 1.1 christos for (i = insns; i != NULL; i = i->next) 1134 1.1 christos { 1135 1.1 christos if (i->insn->nr_words < nr_words) 1136 1.1 christos return 0; 1137 1.1 christos } 1138 1.1 christos return 1; 1139 1.1 christos } 1140 1.1 christos 1141 1.1 christos static int 1142 1.10 christos insn_list_cmp (const insn_list *l, const insn_list *r) 1143 1.1 christos { 1144 1.1 christos while (1) 1145 1.1 christos { 1146 1.10 christos const insn_entry *insn; 1147 1.1 christos if (l == NULL && r == NULL) 1148 1.1 christos return 0; 1149 1.1 christos if (l == NULL) 1150 1.1 christos return -1; 1151 1.1 christos if (r == NULL) 1152 1.1 christos return 1; 1153 1.1 christos if (l->insn != r->insn) 1154 1.1 christos return -1; /* somewhat arbitrary at present */ 1155 1.1 christos /* skip this insn */ 1156 1.1 christos insn = l->insn; 1157 1.1 christos while (l != NULL && l->insn == insn) 1158 1.1 christos l = l->next; 1159 1.1 christos while (r != NULL && r->insn == insn) 1160 1.1 christos r = r->next; 1161 1.1 christos } 1162 1.1 christos } 1163 1.1 christos 1164 1.1 christos 1165 1.1 christos 1166 1.1 christos static void 1167 1.1 christos gen_entry_expand_insns (gen_entry *table) 1168 1.1 christos { 1169 1.10 christos const decode_table *opcode_rule; 1170 1.1 christos 1171 1.1 christos ASSERT (table->nr_insns >= 1); 1172 1.1 christos 1173 1.1 christos /* determine a valid opcode */ 1174 1.1 christos for (opcode_rule = table->opcode_rule; 1175 1.1 christos opcode_rule != NULL; opcode_rule = opcode_rule->next) 1176 1.1 christos { 1177 1.1 christos char *discard_reason; 1178 1.1 christos if (table->top->model != NULL 1179 1.1 christos && opcode_rule->model_names != NULL 1180 1.1 christos && !filter_is_member (opcode_rule->model_names, 1181 1.1 christos table->top->model->name)) 1182 1.1 christos { 1183 1.1 christos /* the rule isn't applicable to this processor */ 1184 1.1 christos discard_reason = "wrong model"; 1185 1.1 christos } 1186 1.1 christos else if (table->nr_insns == 1 && opcode_rule->conditions == NULL) 1187 1.1 christos { 1188 1.1 christos /* for safety, require a pre-codition when attempting to 1189 1.1 christos apply a rule to a single instruction */ 1190 1.1 christos discard_reason = "need pre-condition when nr-insn == 1"; 1191 1.1 christos } 1192 1.1 christos else if (table->nr_insns == 1 && !opcode_rule->with_duplicates) 1193 1.1 christos { 1194 1.1 christos /* Little point in expanding a single instruction when we're 1195 1.1 christos not duplicating the semantic functions that this table 1196 1.1 christos calls */ 1197 1.1 christos discard_reason = "need duplication with nr-insns == 1"; 1198 1.1 christos } 1199 1.1 christos else 1200 1.1 christos if (!insns_match_format_names 1201 1.1 christos (table->insns, opcode_rule->format_names)) 1202 1.1 christos { 1203 1.1 christos discard_reason = "wrong format name"; 1204 1.1 christos } 1205 1.1 christos else if (!insns_match_nr_words (table->insns, opcode_rule->word_nr + 1)) 1206 1.1 christos { 1207 1.1 christos discard_reason = "wrong nr words"; 1208 1.1 christos } 1209 1.1 christos else if (!table_matches_path (table, opcode_rule->paths)) 1210 1.1 christos { 1211 1.1 christos discard_reason = "path failed"; 1212 1.1 christos } 1213 1.1 christos else 1214 1.1 christos if (!insns_match_conditions (table->insns, opcode_rule->conditions)) 1215 1.1 christos { 1216 1.1 christos discard_reason = "condition failed"; 1217 1.1 christos } 1218 1.1 christos else 1219 1.1 christos { 1220 1.1 christos discard_reason = "no opcode field"; 1221 1.1 christos table->opcode = gen_entry_find_opcode_field (table->insns, 1222 1.1 christos opcode_rule, 1223 1.1 christos table->nr_insns == 1 /*string-only */ 1224 1.1 christos ); 1225 1.1 christos if (table->opcode != NULL) 1226 1.1 christos { 1227 1.1 christos table->opcode_rule = opcode_rule; 1228 1.1 christos break; 1229 1.1 christos } 1230 1.1 christos } 1231 1.1 christos 1232 1.1 christos if (options.trace.rule_rejection) 1233 1.1 christos { 1234 1.1 christos print_gen_entry_path (opcode_rule->line, table, notify); 1235 1.1 christos notify (NULL, ": rule discarded - %s\n", discard_reason); 1236 1.1 christos } 1237 1.1 christos } 1238 1.1 christos 1239 1.1 christos /* did we find anything */ 1240 1.1 christos if (opcode_rule == NULL) 1241 1.1 christos { 1242 1.1 christos /* the decode table failed, this set of instructions haven't 1243 1.1 christos been uniquely identified */ 1244 1.1 christos if (table->nr_insns > 1) 1245 1.1 christos { 1246 1.1 christos print_gen_entry_insns (table, warning, 1247 1.1 christos "was not uniquely decoded", 1248 1.1 christos "decodes to the same entry"); 1249 1.11 christos error (NULL, "unrecoverable\n"); 1250 1.1 christos } 1251 1.1 christos return; 1252 1.1 christos } 1253 1.1 christos 1254 1.1 christos /* Determine the number of words that must have been prefetched for 1255 1.1 christos this table to function */ 1256 1.1 christos if (table->parent == NULL) 1257 1.1 christos table->nr_prefetched_words = table->opcode_rule->word_nr + 1; 1258 1.1 christos else if (table->opcode_rule->word_nr + 1 > 1259 1.1 christos table->parent->nr_prefetched_words) 1260 1.1 christos table->nr_prefetched_words = table->opcode_rule->word_nr + 1; 1261 1.1 christos else 1262 1.1 christos table->nr_prefetched_words = table->parent->nr_prefetched_words; 1263 1.1 christos 1264 1.1 christos /* back link what we found to its parent */ 1265 1.1 christos if (table->parent != NULL) 1266 1.1 christos { 1267 1.1 christos ASSERT (table->parent->opcode != NULL); 1268 1.1 christos table->opcode->parent = table->parent->opcode; 1269 1.1 christos } 1270 1.1 christos 1271 1.1 christos /* report the rule being used to expand the instructions */ 1272 1.1 christos if (options.trace.rule_selection) 1273 1.1 christos { 1274 1.1 christos print_gen_entry_path (table->opcode_rule->line, table, notify); 1275 1.1 christos notify (NULL, 1276 1.1 christos ": decode - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d\n", 1277 1.1 christos table->opcode->word_nr, 1278 1.1 christos i2target (options.hi_bit_nr, table->opcode->first), 1279 1.1 christos i2target (options.hi_bit_nr, table->opcode->last), 1280 1.1 christos i2target (options.hi_bit_nr, table->opcode_rule->first), 1281 1.1 christos i2target (options.hi_bit_nr, table->opcode_rule->last), 1282 1.1 christos table->opcode->nr_opcodes, table->nr_entries); 1283 1.1 christos } 1284 1.1 christos 1285 1.1 christos /* expand the raw instructions according to the opcode */ 1286 1.1 christos { 1287 1.1 christos insn_list *entry; 1288 1.1 christos for (entry = table->insns; entry != NULL; entry = entry->next) 1289 1.1 christos { 1290 1.1 christos if (options.trace.insn_expansion) 1291 1.1 christos { 1292 1.1 christos print_gen_entry_path (table->opcode_rule->line, table, notify); 1293 1.1 christos notify (NULL, ": expand - %s.%s\n", 1294 1.1 christos entry->insn->format_name, entry->insn->name); 1295 1.1 christos } 1296 1.1 christos gen_entry_insert_expanding (table, entry->insn); 1297 1.1 christos } 1298 1.1 christos } 1299 1.1 christos 1300 1.1 christos /* dump the results */ 1301 1.1 christos if (options.trace.entries) 1302 1.1 christos { 1303 1.1 christos gen_entry *entry; 1304 1.1 christos for (entry = table->entries; entry != NULL; entry = entry->sibling) 1305 1.1 christos { 1306 1.1 christos insn_list *l; 1307 1.1 christos print_gen_entry_path (table->opcode_rule->line, entry, notify); 1308 1.1 christos notify (NULL, ": %d - entries %d -", 1309 1.1 christos entry->opcode_nr, entry->nr_insns); 1310 1.1 christos for (l = entry->insns; l != NULL; l = l->next) 1311 1.1 christos notify (NULL, " %s.%s", l->insn->format_name, l->insn->name); 1312 1.1 christos notify (NULL, "\n"); 1313 1.1 christos } 1314 1.1 christos } 1315 1.1 christos 1316 1.1 christos /* perform a combine pass if needed */ 1317 1.1 christos if (table->opcode_rule->with_combine) 1318 1.1 christos { 1319 1.1 christos gen_entry *entry; 1320 1.1 christos for (entry = table->entries; entry != NULL; entry = entry->sibling) 1321 1.1 christos { 1322 1.1 christos if (entry->combined_parent == NULL) 1323 1.1 christos { 1324 1.1 christos gen_entry **last = &entry->combined_next; 1325 1.1 christos gen_entry *alt; 1326 1.1 christos for (alt = entry->sibling; alt != NULL; alt = alt->sibling) 1327 1.1 christos { 1328 1.1 christos if (alt->combined_parent == NULL 1329 1.1 christos && insn_list_cmp (entry->insns, alt->insns) == 0) 1330 1.1 christos { 1331 1.1 christos alt->combined_parent = entry; 1332 1.1 christos *last = alt; 1333 1.1 christos last = &alt->combined_next; 1334 1.1 christos } 1335 1.1 christos } 1336 1.1 christos } 1337 1.1 christos } 1338 1.1 christos if (options.trace.combine) 1339 1.1 christos { 1340 1.1 christos int nr_unique = 0; 1341 1.1 christos gen_entry *entry; 1342 1.1 christos for (entry = table->entries; entry != NULL; entry = entry->sibling) 1343 1.1 christos { 1344 1.1 christos if (entry->combined_parent == NULL) 1345 1.1 christos { 1346 1.1 christos insn_list *l; 1347 1.1 christos gen_entry *duplicate; 1348 1.1 christos nr_unique++; 1349 1.1 christos print_gen_entry_path (table->opcode_rule->line, entry, 1350 1.1 christos notify); 1351 1.1 christos for (duplicate = entry->combined_next; duplicate != NULL; 1352 1.1 christos duplicate = duplicate->combined_next) 1353 1.1 christos { 1354 1.1 christos notify (NULL, "+%d", duplicate->opcode_nr); 1355 1.1 christos } 1356 1.1 christos notify (NULL, ": entries %d -", entry->nr_insns); 1357 1.1 christos for (l = entry->insns; l != NULL; l = l->next) 1358 1.1 christos { 1359 1.1 christos notify (NULL, " %s.%s", 1360 1.1 christos l->insn->format_name, l->insn->name); 1361 1.1 christos } 1362 1.1 christos notify (NULL, "\n"); 1363 1.1 christos } 1364 1.1 christos } 1365 1.1 christos print_gen_entry_path (table->opcode_rule->line, table, notify); 1366 1.1 christos notify (NULL, 1367 1.1 christos ": combine - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d, unique %d\n", 1368 1.1 christos table->opcode->word_nr, i2target (options.hi_bit_nr, 1369 1.1 christos table->opcode->first), 1370 1.1 christos i2target (options.hi_bit_nr, table->opcode->last), 1371 1.1 christos i2target (options.hi_bit_nr, table->opcode_rule->first), 1372 1.1 christos i2target (options.hi_bit_nr, table->opcode_rule->last), 1373 1.1 christos table->opcode->nr_opcodes, table->nr_entries, nr_unique); 1374 1.1 christos } 1375 1.1 christos } 1376 1.1 christos 1377 1.1 christos /* Check that the rule did more than re-arange the order of the 1378 1.1 christos instructions */ 1379 1.1 christos { 1380 1.1 christos gen_entry *entry; 1381 1.1 christos for (entry = table->entries; entry != NULL; entry = entry->sibling) 1382 1.1 christos { 1383 1.1 christos if (entry->combined_parent == NULL) 1384 1.1 christos { 1385 1.1 christos if (insn_list_cmp (table->insns, entry->insns) == 0) 1386 1.1 christos { 1387 1.1 christos print_gen_entry_path (table->opcode_rule->line, table, 1388 1.1 christos warning); 1389 1.1 christos warning (NULL, 1390 1.1 christos ": Applying rule just copied all instructions\n"); 1391 1.1 christos print_gen_entry_insns (entry, warning, "Copied", NULL); 1392 1.11 christos error (NULL, "unrecoverable\n"); 1393 1.1 christos } 1394 1.1 christos } 1395 1.1 christos } 1396 1.1 christos } 1397 1.1 christos 1398 1.1 christos /* if some form of expanded table, fill in the missing dots */ 1399 1.1 christos switch (table->opcode_rule->gen) 1400 1.1 christos { 1401 1.1 christos case padded_switch_gen: 1402 1.1 christos case array_gen: 1403 1.1 christos case goto_switch_gen: 1404 1.1 christos if (!table->opcode->is_boolean) 1405 1.1 christos { 1406 1.1 christos gen_entry **entry = &table->entries; 1407 1.1 christos gen_entry *illegals = NULL; 1408 1.1 christos gen_entry **last_illegal = &illegals; 1409 1.1 christos int opcode_nr = 0; 1410 1.1 christos while (opcode_nr < table->opcode->nr_opcodes) 1411 1.1 christos { 1412 1.1 christos if ((*entry) == NULL || (*entry)->opcode_nr != opcode_nr) 1413 1.1 christos { 1414 1.1 christos /* missing - insert it under our feet at *entry */ 1415 1.1 christos gen_entry_insert_insn (table, table->top->isa->illegal_insn, table->opcode->word_nr, 0, /* nr_prefetched_words == 0 for invalid */ 1416 1.1 christos opcode_nr, NULL); 1417 1.1 christos ASSERT ((*entry) != NULL); 1418 1.1 christos ASSERT ((*entry)->opcode_nr == opcode_nr); 1419 1.1 christos (*last_illegal) = *entry; 1420 1.1 christos (*last_illegal)->combined_parent = illegals; 1421 1.1 christos last_illegal = &(*last_illegal)->combined_next; 1422 1.1 christos } 1423 1.1 christos entry = &(*entry)->sibling; 1424 1.1 christos opcode_nr++; 1425 1.1 christos } 1426 1.1 christos /* oops, will have pointed the first illegal insn back to 1427 1.1 christos its self. Fix this */ 1428 1.1 christos if (illegals != NULL) 1429 1.1 christos illegals->combined_parent = NULL; 1430 1.1 christos } 1431 1.1 christos break; 1432 1.1 christos case switch_gen: 1433 1.1 christos case invalid_gen: 1434 1.1 christos /* ignore */ 1435 1.1 christos break; 1436 1.1 christos } 1437 1.1 christos 1438 1.1 christos /* and do the same for the newly created sub entries but *only* 1439 1.1 christos expand entries that haven't been combined. */ 1440 1.1 christos { 1441 1.1 christos gen_entry *entry; 1442 1.1 christos for (entry = table->entries; entry != NULL; entry = entry->sibling) 1443 1.1 christos { 1444 1.1 christos if (entry->combined_parent == NULL) 1445 1.1 christos { 1446 1.1 christos gen_entry_expand_insns (entry); 1447 1.1 christos } 1448 1.1 christos } 1449 1.1 christos } 1450 1.1 christos } 1451 1.1 christos 1452 1.1 christos void 1453 1.1 christos gen_tables_expand_insns (gen_table *gen) 1454 1.1 christos { 1455 1.1 christos gen_list *entry; 1456 1.1 christos for (entry = gen->tables; entry != NULL; entry = entry->next) 1457 1.1 christos { 1458 1.1 christos gen_entry_expand_insns (entry->table); 1459 1.1 christos } 1460 1.1 christos } 1461 1.1 christos 1462 1.1 christos 1463 1.1 christos /* create a list of all the semantic functions that need to be 1464 1.1 christos generated. Eliminate any duplicates. Verify that the decode stage 1465 1.1 christos worked. */ 1466 1.1 christos 1467 1.1 christos static void 1468 1.10 christos make_gen_semantics_list (lf *file, const gen_entry *entry, int depth, void *data) 1469 1.1 christos { 1470 1.1 christos gen_table *gen = (gen_table *) data; 1471 1.1 christos insn_list *insn; 1472 1.1 christos /* Not interested in an entrie that have been combined into some 1473 1.1 christos other entry at the same level */ 1474 1.1 christos if (entry->combined_parent != NULL) 1475 1.1 christos return; 1476 1.1 christos 1477 1.1 christos /* a leaf should contain exactly one instruction. If not the decode 1478 1.1 christos stage failed. */ 1479 1.1 christos ASSERT (entry->nr_insns == 1); 1480 1.1 christos 1481 1.1 christos /* Enter this instruction into the list of semantic functions. */ 1482 1.1 christos insn = insn_list_insert (&gen->semantics, &gen->nr_semantics, 1483 1.1 christos entry->insns->insn, 1484 1.1 christos entry->expanded_bits, 1485 1.1 christos entry->parent->opcode, 1486 1.1 christos entry->insns->nr_prefetched_words, 1487 1.1 christos merge_duplicate_insns); 1488 1.1 christos /* point the table entry at the real semantic function */ 1489 1.1 christos ASSERT (insn != NULL); 1490 1.1 christos entry->insns->semantic = insn; 1491 1.1 christos } 1492 1.1 christos 1493 1.1 christos 1494 1.1 christos void 1495 1.1 christos gen_tables_expand_semantics (gen_table *gen) 1496 1.1 christos { 1497 1.1 christos gen_list *entry; 1498 1.1 christos for (entry = gen->tables; entry != NULL; entry = entry->next) 1499 1.1 christos { 1500 1.1 christos gen_entry_traverse_tree (NULL, entry->table, 1, /* depth */ 1501 1.1 christos NULL, /* start-handler */ 1502 1.1 christos make_gen_semantics_list, /* leaf-handler */ 1503 1.1 christos NULL, /* end-handler */ 1504 1.1 christos gen); /* data */ 1505 1.1 christos } 1506 1.1 christos } 1507 1.1 christos 1508 1.1 christos 1509 1.1 christos 1510 1.1 christos #ifdef MAIN 1511 1.1 christos 1512 1.1 christos 1513 1.1 christos static void 1514 1.1 christos dump_opcode_field (lf *file, 1515 1.1 christos char *prefix, 1516 1.1 christos opcode_field *field, char *suffix, int levels) 1517 1.1 christos { 1518 1.10 christos lf_printf (file, "%s(opcode_field *) %p", prefix, field); 1519 1.1 christos if (levels && field != NULL) 1520 1.1 christos { 1521 1.1 christos lf_indent (file, +1); 1522 1.1 christos lf_printf (file, "\n(first %d)", field->first); 1523 1.1 christos lf_printf (file, "\n(last %d)", field->last); 1524 1.1 christos lf_printf (file, "\n(nr_opcodes %d)", field->nr_opcodes); 1525 1.1 christos lf_printf (file, "\n(is_boolean %d)", field->is_boolean); 1526 1.1 christos lf_printf (file, "\n(boolean_constant %d)", field->boolean_constant); 1527 1.1 christos dump_opcode_field (file, "\n(parent ", field->parent, ")", levels - 1); 1528 1.1 christos lf_indent (file, -1); 1529 1.1 christos } 1530 1.1 christos lf_printf (file, "%s", suffix); 1531 1.1 christos } 1532 1.1 christos 1533 1.1 christos 1534 1.1 christos static void 1535 1.1 christos dump_opcode_bits (lf *file, 1536 1.1 christos char *prefix, opcode_bits *bits, char *suffix, int levels) 1537 1.1 christos { 1538 1.10 christos lf_printf (file, "%s(opcode_bits *) %p", prefix, bits); 1539 1.1 christos 1540 1.1 christos if (levels && bits != NULL) 1541 1.1 christos { 1542 1.1 christos lf_indent (file, +1); 1543 1.1 christos lf_printf (file, "\n(value %d)", bits->value); 1544 1.1 christos dump_opcode_field (file, "\n(opcode ", bits->opcode, ")", 0); 1545 1.1 christos dump_insn_field (file, "\n(field ", bits->field, ")"); 1546 1.1 christos dump_opcode_bits (file, "\n(next ", bits->next, ")", levels - 1); 1547 1.1 christos lf_indent (file, -1); 1548 1.1 christos } 1549 1.1 christos lf_printf (file, "%s", suffix); 1550 1.1 christos } 1551 1.1 christos 1552 1.1 christos 1553 1.1 christos 1554 1.1 christos static void 1555 1.1 christos dump_insn_list (lf *file, char *prefix, insn_list *entry, char *suffix) 1556 1.1 christos { 1557 1.10 christos lf_printf (file, "%s(insn_list *) %p", prefix, entry); 1558 1.1 christos 1559 1.1 christos if (entry != NULL) 1560 1.1 christos { 1561 1.1 christos lf_indent (file, +1); 1562 1.1 christos dump_insn_entry (file, "\n(insn ", entry->insn, ")"); 1563 1.10 christos lf_printf (file, "\n(next %p)", entry->next); 1564 1.1 christos lf_indent (file, -1); 1565 1.1 christos } 1566 1.1 christos lf_printf (file, "%s", suffix); 1567 1.1 christos } 1568 1.1 christos 1569 1.1 christos 1570 1.1 christos static void 1571 1.1 christos dump_insn_word_entry_list_entries (lf *file, 1572 1.1 christos char *prefix, 1573 1.1 christos insn_list *entry, char *suffix) 1574 1.1 christos { 1575 1.1 christos lf_printf (file, "%s", prefix); 1576 1.1 christos while (entry != NULL) 1577 1.1 christos { 1578 1.1 christos dump_insn_list (file, "\n(", entry, ")"); 1579 1.1 christos entry = entry->next; 1580 1.1 christos } 1581 1.1 christos lf_printf (file, "%s", suffix); 1582 1.1 christos } 1583 1.1 christos 1584 1.1 christos 1585 1.1 christos static void 1586 1.1 christos dump_gen_entry (lf *file, 1587 1.1 christos char *prefix, gen_entry *table, char *suffix, int levels) 1588 1.1 christos { 1589 1.1 christos 1590 1.10 christos lf_printf (file, "%s(gen_entry *) %p", prefix, table); 1591 1.1 christos 1592 1.1 christos if (levels && table !=NULL) 1593 1.1 christos { 1594 1.1 christos 1595 1.1 christos lf_indent (file, +1); 1596 1.1 christos lf_printf (file, "\n(opcode_nr %d)", table->opcode_nr); 1597 1.1 christos lf_printf (file, "\n(word_nr %d)", table->word_nr); 1598 1.1 christos dump_opcode_bits (file, "\n(expanded_bits ", table->expanded_bits, ")", 1599 1.1 christos -1); 1600 1.1 christos lf_printf (file, "\n(nr_insns %d)", table->nr_insns); 1601 1.1 christos dump_insn_word_entry_list_entries (file, "\n(insns ", table->insns, 1602 1.1 christos ")"); 1603 1.1 christos dump_decode_rule (file, "\n(opcode_rule ", table->opcode_rule, ")"); 1604 1.1 christos dump_opcode_field (file, "\n(opcode ", table->opcode, ")", 0); 1605 1.1 christos lf_printf (file, "\n(nr_entries %d)", table->nr_entries); 1606 1.1 christos dump_gen_entry (file, "\n(entries ", table->entries, ")", 1607 1.1 christos table->nr_entries); 1608 1.1 christos dump_gen_entry (file, "\n(sibling ", table->sibling, ")", levels - 1); 1609 1.1 christos dump_gen_entry (file, "\n(parent ", table->parent, ")", 0); 1610 1.1 christos lf_indent (file, -1); 1611 1.1 christos } 1612 1.1 christos lf_printf (file, "%s", suffix); 1613 1.1 christos } 1614 1.1 christos 1615 1.1 christos static void 1616 1.1 christos dump_gen_list (lf *file, 1617 1.1 christos char *prefix, gen_list *entry, char *suffix, int levels) 1618 1.1 christos { 1619 1.1 christos while (entry != NULL) 1620 1.1 christos { 1621 1.10 christos lf_printf (file, "%s(gen_list *) %p", prefix, entry); 1622 1.1 christos dump_gen_entry (file, "\n(", entry->table, ")", levels); 1623 1.10 christos lf_printf (file, "\n(next (gen_list *) %p)", entry->next); 1624 1.1 christos lf_printf (file, "%s", suffix); 1625 1.1 christos } 1626 1.1 christos } 1627 1.1 christos 1628 1.1 christos 1629 1.1 christos static void 1630 1.1 christos dump_gen_table (lf *file, 1631 1.1 christos char *prefix, gen_table *gen, char *suffix, int levels) 1632 1.1 christos { 1633 1.10 christos lf_printf (file, "%s(gen_table *) %p", prefix, gen); 1634 1.10 christos lf_printf (file, "\n(isa (insn_table *) %p)", gen->isa); 1635 1.10 christos lf_printf (file, "\n(rules (decode_table *) %p)", gen->rules); 1636 1.1 christos dump_gen_list (file, "\n(", gen->tables, ")", levels); 1637 1.1 christos lf_printf (file, "%s", suffix); 1638 1.1 christos } 1639 1.1 christos 1640 1.1 christos 1641 1.1 christos igen_options options; 1642 1.1 christos 1643 1.1 christos int 1644 1.1 christos main (int argc, char **argv) 1645 1.1 christos { 1646 1.1 christos decode_table *decode_rules; 1647 1.1 christos insn_table *instructions; 1648 1.1 christos gen_table *gen; 1649 1.1 christos lf *l; 1650 1.1 christos 1651 1.1 christos if (argc != 7) 1652 1.1 christos error (NULL, 1653 1.1 christos "Usage: insn <filter-in> <hi-bit-nr> <insn-bit-size> <widths> <decode-table> <insn-table>\n"); 1654 1.1 christos 1655 1.10 christos INIT_OPTIONS (); 1656 1.1 christos 1657 1.1 christos filter_parse (&options.flags_filter, argv[1]); 1658 1.1 christos 1659 1.1 christos options.hi_bit_nr = a2i (argv[2]); 1660 1.1 christos options.insn_bit_size = a2i (argv[3]); 1661 1.1 christos options.insn_specifying_widths = a2i (argv[4]); 1662 1.1 christos ASSERT (options.hi_bit_nr < options.insn_bit_size); 1663 1.1 christos 1664 1.1 christos instructions = load_insn_table (argv[6], NULL); 1665 1.1 christos decode_rules = load_decode_table (argv[5]); 1666 1.1 christos gen = make_gen_tables (instructions, decode_rules); 1667 1.1 christos 1668 1.1 christos gen_tables_expand_insns (gen); 1669 1.1 christos 1670 1.1 christos l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn"); 1671 1.1 christos 1672 1.1 christos dump_gen_table (l, "(", gen, ")\n", -1); 1673 1.1 christos return 0; 1674 1.1 christos } 1675 1.1 christos 1676 1.1 christos #endif 1677