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 #include "misc.h" 24 #include "lf.h" 25 #include "table.h" 26 #include "filter.h" 27 #include "igen.h" 28 29 #include "ld-insn.h" 30 #include "ld-decode.h" 31 32 #include "gen.h" 33 34 #include "gen-idecode.h" 35 #include "gen-icache.h" 36 #include "gen-semantics.h" 37 38 39 40 static void 41 lf_print_opcodes (lf *file, const gen_entry *table) 42 { 43 if (table !=NULL) 44 { 45 while (1) 46 { 47 ASSERT (table->opcode != NULL); 48 lf_printf (file, "_%d_%d", 49 table->opcode->first, table->opcode->last); 50 if (table->parent == NULL) 51 break; 52 lf_printf (file, "__%d", table->opcode_nr); 53 table = table->parent; 54 } 55 } 56 } 57 58 59 60 61 static void 62 print_idecode_ifetch (lf *file, 63 int previous_nr_prefetched_words, 64 int current_nr_prefetched_words) 65 { 66 int word_nr; 67 for (word_nr = previous_nr_prefetched_words; 68 word_nr < current_nr_prefetched_words; word_nr++) 69 { 70 lf_printf (file, 71 "instruction_word instruction_%d = IMEM%d_IMMED (cia, %d);\n", 72 word_nr, options.insn_bit_size, word_nr); 73 74 } 75 } 76 77 78 79 /****************************************************************/ 80 81 82 static void 83 lf_print_table_name (lf *file, const gen_entry *table) 84 { 85 lf_printf (file, "idecode_table"); 86 lf_print_opcodes (file, table); 87 } 88 89 90 91 static void 92 print_idecode_table (lf *file, const gen_entry *entry, const char *result) 93 { 94 lf_printf (file, "/* prime the search */\n"); 95 lf_printf (file, "idecode_table_entry *table = "); 96 lf_print_table_name (file, entry); 97 lf_printf (file, ";\n"); 98 lf_printf (file, "int opcode = EXTRACTED%d (instruction, %d, %d);\n", 99 options.insn_bit_size, 100 i2target (options.hi_bit_nr, entry->opcode->first), 101 i2target (options.hi_bit_nr, entry->opcode->last)); 102 lf_printf (file, "idecode_table_entry *table_entry = table + opcode;\n"); 103 104 lf_printf (file, "\n"); 105 lf_printf (file, "/* iterate until a leaf */\n"); 106 lf_printf (file, "while (1) {\n"); 107 lf_printf (file, " signed shift = table_entry->shift;\n"); 108 lf_printf (file, "if (shift == function_entry) break;\n"); 109 lf_printf (file, " if (shift >= 0) {\n"); 110 lf_printf (file, " table = ((idecode_table_entry*)\n"); 111 lf_printf (file, " table_entry->function_or_table);\n"); 112 lf_printf (file, " opcode = ((instruction & table_entry->mask)\n"); 113 lf_printf (file, " >> shift);\n"); 114 lf_printf (file, " table_entry = table + opcode;\n"); 115 lf_printf (file, " }\n"); 116 lf_printf (file, " else {\n"); 117 lf_printf (file, " /* must be a boolean */\n"); 118 lf_printf (file, " ASSERT(table_entry->shift == boolean_entry);\n"); 119 lf_printf (file, " opcode = ((instruction & table_entry->mask)\n"); 120 lf_printf (file, " != table_entry->value);\n"); 121 lf_printf (file, " table = ((idecode_table_entry*)\n"); 122 lf_printf (file, " table_entry->function_or_table);\n"); 123 lf_printf (file, " table_entry = table + opcode;\n"); 124 lf_printf (file, " }\n"); 125 lf_printf (file, "}\n"); 126 127 lf_printf (file, "\n"); 128 lf_printf (file, "/* call the leaf code */\n"); 129 if (options.gen.code == generate_jumps) 130 { 131 lf_printf (file, "goto *table_entry->function_or_table;\n"); 132 } 133 else 134 { 135 lf_printf (file, "%s ", result); 136 if (options.gen.icache) 137 { 138 lf_printf (file, 139 "(((idecode_icache*)table_entry->function_or_table)\n"); 140 lf_printf (file, " ("); 141 print_icache_function_actual (file, 1); 142 lf_printf (file, "));\n"); 143 } 144 else 145 { 146 lf_printf (file, 147 "((idecode_semantic*)table_entry->function_or_table)\n"); 148 lf_printf (file, " ("); 149 print_semantic_function_actual (file, 1); 150 lf_printf (file, ");\n"); 151 } 152 } 153 } 154 155 156 static void 157 print_idecode_table_start (lf *file, 158 const gen_entry *table, int depth, void *data) 159 { 160 ASSERT (depth == 0); 161 /* start of the table */ 162 if (table->opcode_rule->gen == array_gen) 163 { 164 lf_printf (file, "\n"); 165 lf_printf (file, "static idecode_table_entry "); 166 lf_print_table_name (file, table); 167 lf_printf (file, "[] = {\n"); 168 } 169 } 170 171 static void 172 print_idecode_table_leaf (lf *file, 173 const gen_entry *entry, int depth, void *data) 174 { 175 const gen_entry *master_entry; 176 ASSERT (entry->parent != NULL); 177 ASSERT (depth == 0); 178 if (entry->combined_parent == NULL) 179 master_entry = entry; 180 else 181 master_entry = entry->combined_parent; 182 183 /* add an entry to the table */ 184 if (entry->parent->opcode_rule->gen == array_gen) 185 { 186 lf_printf (file, " /*%d*/ { ", entry->opcode_nr); 187 if (entry->opcode == NULL) 188 { 189 ASSERT (entry->nr_insns == 1); 190 /* table leaf entry */ 191 lf_printf (file, "function_entry, 0, 0, "); 192 if (options.gen.code == generate_jumps) 193 { 194 lf_printf (file, "&&"); 195 } 196 print_function_name (file, 197 entry->insns->insn->name, 198 entry->insns->insn->format_name, 199 NULL, 200 master_entry->expanded_bits, 201 (options.gen.icache 202 ? function_name_prefix_icache 203 : function_name_prefix_semantics)); 204 } 205 else if (entry->opcode_rule->gen == switch_gen 206 || entry->opcode_rule->gen == goto_switch_gen 207 || entry->opcode_rule->gen == padded_switch_gen) 208 { 209 /* table calling switch statement */ 210 lf_printf (file, "function_entry, 0, 0, "); 211 if (options.gen.code == generate_jumps) 212 { 213 lf_printf (file, "&&"); 214 } 215 lf_print_table_name (file, entry); 216 } 217 else if (entry->opcode->is_boolean) 218 { 219 /* table `calling' boolean table */ 220 lf_printf (file, "boolean_entry, "); 221 lf_printf (file, "MASK32(%d, %d), ", 222 i2target (options.hi_bit_nr, entry->opcode->first), 223 i2target (options.hi_bit_nr, entry->opcode->last)); 224 lf_printf (file, "INSERTED32(%d, %d, %d), ", 225 entry->opcode->boolean_constant, 226 i2target (options.hi_bit_nr, entry->opcode->first), 227 i2target (options.hi_bit_nr, entry->opcode->last)); 228 lf_print_table_name (file, entry); 229 } 230 else 231 { 232 /* table `calling' another table */ 233 lf_printf (file, "%d, ", 234 options.insn_bit_size - entry->opcode->last - 1); 235 lf_printf (file, "MASK%d(%d,%d), ", options.insn_bit_size, 236 i2target (options.hi_bit_nr, entry->opcode->first), 237 i2target (options.hi_bit_nr, entry->opcode->last)); 238 lf_printf (file, "0, "); 239 lf_print_table_name (file, entry); 240 } 241 lf_printf (file, " },\n"); 242 } 243 } 244 245 static void 246 print_idecode_table_end (lf *file, 247 const gen_entry *table, int depth, void *data) 248 { 249 ASSERT (depth == 0); 250 if (table->opcode_rule->gen == array_gen) 251 { 252 lf_printf (file, "};\n"); 253 } 254 } 255 256 /****************************************************************/ 257 258 259 static void 260 print_goto_switch_name (lf *file, const gen_entry *entry) 261 { 262 lf_printf (file, "case_"); 263 if (entry->opcode == NULL) 264 { 265 print_function_name (file, 266 entry->insns->insn->name, 267 entry->insns->insn->format_name, 268 NULL, 269 entry->expanded_bits, 270 (options.gen.icache 271 ? function_name_prefix_icache 272 : function_name_prefix_semantics)); 273 } 274 else 275 { 276 lf_print_table_name (file, entry); 277 } 278 } 279 280 static void 281 print_goto_switch_table_leaf (lf *file, 282 const gen_entry *entry, int depth, void *data) 283 { 284 ASSERT (entry->parent != NULL); 285 ASSERT (depth == 0); 286 ASSERT (entry->parent->opcode_rule->gen == goto_switch_gen); 287 ASSERT (entry->parent->opcode); 288 289 lf_printf (file, "/* %d */ &&", entry->opcode_nr); 290 if (entry->combined_parent != NULL) 291 print_goto_switch_name (file, entry->combined_parent); 292 else 293 print_goto_switch_name (file, entry); 294 lf_printf (file, ",\n"); 295 } 296 297 static void 298 print_goto_switch_break (lf *file, const gen_entry *entry) 299 { 300 lf_printf (file, "goto break_"); 301 lf_print_table_name (file, entry->parent); 302 lf_printf (file, ";\n"); 303 } 304 305 306 static void 307 print_goto_switch_table (lf *file, const gen_entry *table) 308 { 309 lf_printf (file, "const static void *"); 310 lf_print_table_name (file, table); 311 lf_printf (file, "[] = {\n"); 312 lf_indent (file, +2); 313 gen_entry_traverse_tree (file, table, 0, NULL /*start */ , 314 print_goto_switch_table_leaf, NULL /*end */ , 315 NULL /*data */ ); 316 lf_indent (file, -2); 317 lf_printf (file, "};\n"); 318 } 319 320 321 void print_idecode_switch 322 (lf *file, const gen_entry *table, const char *result); 323 324 static void 325 print_idecode_switch_start (lf *file, 326 const gen_entry *table, int depth, void *data) 327 { 328 /* const char *result = data; */ 329 ASSERT (depth == 0); 330 ASSERT (table->opcode_rule->gen == switch_gen 331 || table->opcode_rule->gen == goto_switch_gen 332 || table->opcode_rule->gen == padded_switch_gen); 333 334 if (table->opcode->is_boolean 335 || table->opcode_rule->gen == switch_gen 336 || table->opcode_rule->gen == padded_switch_gen) 337 { 338 lf_printf (file, "switch (EXTRACTED%d (instruction_%d, %d, %d))\n", 339 options.insn_bit_size, 340 table->opcode_rule->word_nr, 341 i2target (options.hi_bit_nr, table->opcode->first), 342 i2target (options.hi_bit_nr, table->opcode->last)); 343 lf_indent (file, +2); 344 lf_printf (file, "{\n"); 345 } 346 else if (table->opcode_rule->gen == goto_switch_gen) 347 { 348 if (table->parent != NULL 349 && (table->parent->opcode_rule->gen == switch_gen 350 || table->parent->opcode_rule->gen == goto_switch_gen 351 || table->parent->opcode_rule->gen == padded_switch_gen)) 352 { 353 lf_printf (file, "{\n"); 354 lf_indent (file, +2); 355 } 356 print_goto_switch_table (file, table); 357 lf_printf (file, "ASSERT (EXTRACTED%d (instruction_%d, %d, %d)\n", 358 options.insn_bit_size, 359 table->opcode->word_nr, 360 i2target (options.hi_bit_nr, table->opcode->first), 361 i2target (options.hi_bit_nr, table->opcode->last)); 362 lf_printf (file, " < (sizeof ("); 363 lf_print_table_name (file, table); 364 lf_printf (file, ") / sizeof(void*)));\n"); 365 lf_printf (file, "goto *"); 366 lf_print_table_name (file, table); 367 lf_printf (file, "[EXTRACTED%d (instruction_%d, %d, %d)];\n", 368 options.insn_bit_size, 369 table->opcode->word_nr, 370 i2target (options.hi_bit_nr, table->opcode->first), 371 i2target (options.hi_bit_nr, table->opcode->last)); 372 } 373 else 374 { 375 ASSERT ("bad switch" == NULL); 376 } 377 } 378 379 380 static void 381 print_idecode_switch_leaf (lf *file, 382 const gen_entry *entry, int depth, void *data) 383 { 384 const char *result = data; 385 ASSERT (entry->parent != NULL); 386 ASSERT (depth == 0); 387 ASSERT (entry->parent->opcode_rule->gen == switch_gen 388 || entry->parent->opcode_rule->gen == goto_switch_gen 389 || entry->parent->opcode_rule->gen == padded_switch_gen); 390 ASSERT (entry->parent->opcode); 391 392 /* skip over any instructions combined into another entry */ 393 if (entry->combined_parent != NULL) 394 return; 395 396 if (entry->parent->opcode->is_boolean && entry->opcode_nr == 0) 397 { 398 /* case: boolean false target */ 399 lf_printf (file, "case %d:\n", entry->parent->opcode->boolean_constant); 400 } 401 else if (entry->parent->opcode->is_boolean && entry->opcode_nr != 0) 402 { 403 /* case: boolean true case */ 404 lf_printf (file, "default:\n"); 405 } 406 else if (entry->parent->opcode_rule->gen == switch_gen 407 || entry->parent->opcode_rule->gen == padded_switch_gen) 408 { 409 /* case: <opcode-nr> - switch */ 410 const gen_entry *cob; 411 for (cob = entry; cob != NULL; cob = cob->combined_next) 412 lf_printf (file, "case %d:\n", cob->opcode_nr); 413 } 414 else if (entry->parent->opcode_rule->gen == goto_switch_gen) 415 { 416 /* case: <opcode-nr> - goto-switch */ 417 print_goto_switch_name (file, entry); 418 lf_printf (file, ":\n"); 419 } 420 else 421 { 422 ERROR ("bad switch"); 423 } 424 lf_printf (file, " {\n"); 425 lf_indent (file, +4); 426 { 427 if (entry->opcode == NULL) 428 { 429 /* switch calling leaf */ 430 ASSERT (entry->nr_insns == 1); 431 print_idecode_ifetch (file, entry->nr_prefetched_words, 432 entry->insns->semantic->nr_prefetched_words); 433 switch (options.gen.code) 434 { 435 case generate_jumps: 436 lf_printf (file, "goto "); 437 break; 438 case generate_calls: 439 lf_printf (file, "%s", result); 440 break; 441 } 442 print_function_name (file, 443 entry->insns->insn->name, 444 entry->insns->insn->format_name, 445 NULL, 446 entry->expanded_bits, 447 (options.gen.icache 448 ? function_name_prefix_icache 449 : function_name_prefix_semantics)); 450 if (options.gen.code == generate_calls) 451 { 452 lf_printf (file, " ("); 453 print_semantic_function_actual (file, 454 entry->insns->semantic-> 455 nr_prefetched_words); 456 lf_printf (file, ")"); 457 } 458 lf_printf (file, ";\n"); 459 } 460 else if (entry->opcode_rule->gen == switch_gen 461 || entry->opcode_rule->gen == goto_switch_gen 462 || entry->opcode_rule->gen == padded_switch_gen) 463 { 464 /* switch calling switch */ 465 lf_printf (file, "{\n"); 466 lf_indent (file, +2); 467 print_idecode_ifetch (file, entry->parent->nr_prefetched_words, 468 entry->nr_prefetched_words); 469 print_idecode_switch (file, entry, result); 470 lf_indent (file, -2); 471 lf_printf (file, "}\n"); 472 } 473 else 474 { 475 /* switch looking up a table */ 476 lf_printf (file, "{\n"); 477 lf_indent (file, +2); 478 print_idecode_ifetch (file, entry->parent->nr_prefetched_words, 479 entry->nr_prefetched_words); 480 print_idecode_table (file, entry, result); 481 lf_indent (file, -2); 482 lf_printf (file, "}\n"); 483 } 484 if (entry->parent->opcode->is_boolean 485 || entry->parent->opcode_rule->gen == switch_gen 486 || entry->parent->opcode_rule->gen == padded_switch_gen) 487 { 488 lf_printf (file, "break;\n"); 489 } 490 else if (entry->parent->opcode_rule->gen == goto_switch_gen) 491 { 492 print_goto_switch_break (file, entry); 493 } 494 else 495 { 496 ERROR ("bad switch"); 497 } 498 } 499 lf_indent (file, -4); 500 lf_printf (file, " }\n"); 501 } 502 503 504 static void 505 print_idecode_switch_illegal (lf *file, const char *result) 506 { 507 lf_indent (file, +2); 508 print_idecode_invalid (file, result, invalid_illegal); 509 lf_printf (file, "break;\n"); 510 lf_indent (file, -2); 511 } 512 513 static void 514 print_idecode_switch_end (lf *file, 515 const gen_entry *table, int depth, void *data) 516 { 517 const char *result = data; 518 ASSERT (depth == 0); 519 ASSERT (table->opcode_rule->gen == switch_gen 520 || table->opcode_rule->gen == goto_switch_gen 521 || table->opcode_rule->gen == padded_switch_gen); 522 ASSERT (table->opcode); 523 524 if (table->opcode->is_boolean) 525 { 526 lf_printf (file, "}\n"); 527 lf_indent (file, -2); 528 } 529 else if (table->opcode_rule->gen == switch_gen 530 || table->opcode_rule->gen == padded_switch_gen) 531 { 532 lf_printf (file, "default:\n"); 533 lf_indent (file, +2); 534 if (table->nr_entries == table->opcode->nr_opcodes) 535 { 536 print_sim_engine_abort (file, 537 "Internal error - bad switch generated"); 538 lf_printf (file, "%sNULL_CIA;\n", result); 539 lf_printf (file, "break;\n"); 540 } 541 else 542 { 543 print_idecode_switch_illegal (file, result); 544 } 545 lf_indent (file, -2); 546 lf_printf (file, "}\n"); 547 lf_indent (file, -2); 548 } 549 else if (table->opcode_rule->gen == goto_switch_gen) 550 { 551 lf_printf (file, "illegal_"); 552 lf_print_table_name (file, table); 553 lf_printf (file, ":\n"); 554 print_idecode_invalid (file, result, invalid_illegal); 555 lf_printf (file, "break_"); 556 lf_print_table_name (file, table); 557 lf_printf (file, ":;\n"); 558 if (table->parent != NULL 559 && (table->parent->opcode_rule->gen == switch_gen 560 || table->parent->opcode_rule->gen == goto_switch_gen 561 || table->parent->opcode_rule->gen == padded_switch_gen)) 562 { 563 lf_indent (file, -2); 564 lf_printf (file, "}\n"); 565 } 566 } 567 else 568 { 569 ERROR ("bad switch"); 570 } 571 } 572 573 574 void 575 print_idecode_switch (lf *file, const gen_entry *table, const char *result) 576 { 577 gen_entry_traverse_tree (file, table, 578 0, 579 print_idecode_switch_start, 580 print_idecode_switch_leaf, 581 print_idecode_switch_end, (void *) result); 582 } 583 584 585 static void 586 print_idecode_switch_function_header (lf *file, 587 const gen_entry *table, 588 int is_function_definition, 589 int nr_prefetched_words) 590 { 591 lf_printf (file, "\n"); 592 if (options.gen.code == generate_calls) 593 { 594 lf_printf (file, "static "); 595 if (options.gen.icache) 596 { 597 lf_printf (file, "idecode_semantic *"); 598 } 599 else 600 { 601 lf_printf (file, "unsigned_word"); 602 } 603 if (is_function_definition) 604 { 605 lf_printf (file, "\n"); 606 } 607 else 608 { 609 lf_printf (file, " "); 610 } 611 lf_print_table_name (file, table); 612 lf_printf (file, "\n("); 613 print_icache_function_formal (file, nr_prefetched_words); 614 lf_printf (file, ")"); 615 if (!is_function_definition) 616 { 617 lf_printf (file, ";"); 618 } 619 lf_printf (file, "\n"); 620 } 621 if (options.gen.code == generate_jumps && is_function_definition) 622 { 623 lf_indent (file, -1); 624 lf_print_table_name (file, table); 625 lf_printf (file, ":\n"); 626 lf_indent (file, +1); 627 } 628 } 629 630 631 static void 632 idecode_declare_if_switch (lf *file, 633 const gen_entry *table, int depth, void *data) 634 { 635 if ((table->opcode_rule->gen == switch_gen || table->opcode_rule->gen == goto_switch_gen || table->opcode_rule->gen == padded_switch_gen) &&table->parent != NULL /* don't declare the top one yet */ 636 && table->parent->opcode_rule->gen == array_gen) 637 { 638 print_idecode_switch_function_header (file, 639 table, 640 0 /*isnt function definition */ , 641 0); 642 } 643 } 644 645 646 static void 647 idecode_expand_if_switch (lf *file, 648 const gen_entry *table, int depth, void *data) 649 { 650 if ((table->opcode_rule->gen == switch_gen || table->opcode_rule->gen == goto_switch_gen || table->opcode_rule->gen == padded_switch_gen) &&table->parent != NULL /* don't expand the top one yet */ 651 && table->parent->opcode_rule->gen == array_gen) 652 { 653 print_idecode_switch_function_header (file, 654 table, 655 1 /*is function definition */ , 656 0); 657 if (options.gen.code == generate_calls) 658 { 659 lf_printf (file, "{\n"); 660 lf_indent (file, +2); 661 } 662 print_idecode_switch (file, table, "return"); 663 if (options.gen.code == generate_calls) 664 { 665 lf_indent (file, -2); 666 lf_printf (file, "}\n"); 667 } 668 } 669 } 670 671 672 /****************************************************************/ 673 674 675 void 676 print_idecode_lookups (lf *file, 677 const gen_entry *table, 678 cache_entry *cache_rules) 679 { 680 int depth; 681 682 /* output switch function declarations where needed by tables */ 683 gen_entry_traverse_tree (file, table, 1, idecode_declare_if_switch, /* START */ 684 NULL, NULL, NULL); 685 686 /* output tables where needed */ 687 for (depth = gen_entry_depth (table); depth > 0; depth--) 688 { 689 gen_entry_traverse_tree (file, table, 690 1 - depth, 691 print_idecode_table_start, 692 print_idecode_table_leaf, 693 print_idecode_table_end, NULL); 694 } 695 696 /* output switch functions where needed */ 697 gen_entry_traverse_tree (file, table, 1, idecode_expand_if_switch, /* START */ 698 NULL, NULL, NULL); 699 } 700 701 702 void 703 print_idecode_body (lf *file, const gen_entry *table, const char *result) 704 { 705 if (table->opcode_rule->gen == switch_gen 706 || table->opcode_rule->gen == goto_switch_gen 707 || table->opcode_rule->gen == padded_switch_gen) 708 { 709 print_idecode_switch (file, table, result); 710 } 711 else 712 { 713 print_idecode_table (file, table, result); 714 } 715 } 716 717 718 /****************************************************************/ 719 720 /* Output code to do any final checks on the decoded instruction. 721 This includes things like verifying any on decoded fields have the 722 correct value and checking that (for floating point) floating point 723 hardware isn't disabled */ 724 725 void 726 print_idecode_validate (lf *file, 727 const insn_entry *instruction, 728 const insn_opcodes *opcode_paths) 729 { 730 /* Validate: unchecked instruction fields 731 732 If any constant fields in the instruction were not checked by the 733 idecode tables, output code to check that they have the correct 734 value here */ 735 { 736 int nr_checks = 0; 737 int word_nr; 738 lf_printf (file, "\n"); 739 lf_indent_suppress (file); 740 lf_printf (file, "#if defined (WITH_RESERVED_BITS)\n"); 741 lf_printf (file, "/* validate: "); 742 print_insn_words (file, instruction); 743 lf_printf (file, " */\n"); 744 for (word_nr = 0; word_nr < instruction->nr_words; word_nr++) 745 { 746 insn_uint check_mask = 0; 747 insn_uint check_val = 0; 748 insn_word_entry *word = instruction->word[word_nr]; 749 int bit_nr; 750 751 /* form check_mask/check_val containing what needs to be checked 752 in the instruction */ 753 for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++) 754 { 755 insn_bit_entry *bit = word->bit[bit_nr]; 756 insn_field_entry *field = bit->field; 757 758 /* Make space for the next bit */ 759 check_mask <<= 1; 760 check_val <<= 1; 761 762 /* Only need to validate constant (and reserved) 763 bits. Skip any others */ 764 if (field->type != insn_field_int 765 && field->type != insn_field_reserved 766 /* Consider a named field equal to a value to be just as 767 constant as an integer field. */ 768 && (field->type != insn_field_string 769 || field->conditions == NULL 770 || field->conditions->test != insn_field_cond_eq 771 || field->conditions->type != insn_field_cond_value)) 772 continue; 773 774 /* Look through the list of opcode paths that lead to this 775 instruction. See if any have failed to check the 776 relevant bit */ 777 if (opcode_paths != NULL) 778 { 779 const insn_opcodes *entry; 780 for (entry = opcode_paths; entry != NULL; entry = entry->next) 781 { 782 opcode_field *opcode; 783 for (opcode = entry->opcode; 784 opcode != NULL; opcode = opcode->parent) 785 { 786 if (opcode->word_nr == word_nr 787 && opcode->first <= bit_nr 788 && opcode->last >= bit_nr) 789 /* we've decoded on this bit */ 790 break; 791 } 792 if (opcode == NULL) 793 /* the bit wasn't decoded on */ 794 break; 795 } 796 if (entry == NULL) 797 /* all the opcode paths decoded on BIT_NR, no need 798 to check it */ 799 continue; 800 } 801 802 check_mask |= 1; 803 check_val |= bit->value; 804 } 805 806 /* if any bits not checked by opcode tables, output code to check them */ 807 if (check_mask) 808 { 809 if (nr_checks == 0) 810 { 811 lf_printf (file, "if (WITH_RESERVED_BITS)\n"); 812 lf_printf (file, " {\n"); 813 lf_indent (file, +4); 814 } 815 nr_checks++; 816 if (options.insn_bit_size > 32) 817 { 818 lf_printf (file, "if ((instruction_%d\n", word_nr); 819 lf_printf (file, " & UNSIGNED64 (0x%08lx%08lx))\n", 820 (unsigned long) (check_mask >> 32), 821 (unsigned long) (check_mask)); 822 lf_printf (file, " != UNSIGNED64 (0x%08lx%08lx))\n", 823 (unsigned long) (check_val >> 32), 824 (unsigned long) (check_val)); 825 } 826 else 827 { 828 lf_printf (file, 829 "if ((instruction_%d & 0x%08lx) != 0x%08lx)\n", 830 word_nr, (unsigned long) (check_mask), 831 (unsigned long) (check_val)); 832 } 833 lf_indent (file, +2); 834 print_idecode_invalid (file, "return", invalid_illegal); 835 lf_indent (file, -2); 836 } 837 } 838 if (nr_checks > 0) 839 { 840 lf_indent (file, -4); 841 lf_printf (file, " }\n"); 842 } 843 lf_indent_suppress (file); 844 lf_printf (file, "#endif\n"); 845 } 846 847 /* Validate: Floating Point hardware 848 849 If the simulator is being built with out floating point hardware 850 (different to it being disabled in the MSR) then floating point 851 instructions are invalid */ 852 { 853 if (filter_is_member (instruction->flags, "f")) 854 { 855 lf_printf (file, "\n"); 856 lf_indent_suppress (file); 857 lf_printf (file, "#if defined(CURRENT_FLOATING_POINT)\n"); 858 lf_printf (file, "/* Validate: FP hardware exists */\n"); 859 lf_printf (file, 860 "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT) {\n"); 861 lf_indent (file, +2); 862 print_idecode_invalid (file, "return", invalid_illegal); 863 lf_indent (file, -2); 864 lf_printf (file, "}\n"); 865 lf_indent_suppress (file); 866 lf_printf (file, "#endif\n"); 867 } 868 } 869 870 /* Validate: Floating Point available 871 872 If floating point is not available, we enter a floating point 873 unavailable interrupt into the cache instead of the instruction 874 proper. 875 876 The PowerPC spec requires a CSI after MSR[FP] is changed and when 877 ever a CSI occures we flush the instruction cache. */ 878 879 { 880 if (filter_is_member (instruction->flags, "f")) 881 { 882 lf_printf (file, "\n"); 883 lf_indent_suppress (file); 884 lf_printf (file, "#if defined(IS_FP_AVAILABLE)\n"); 885 lf_printf (file, "/* Validate: FP available according to cpu */\n"); 886 lf_printf (file, "if (!IS_FP_AVAILABLE) {\n"); 887 lf_indent (file, +2); 888 print_idecode_invalid (file, "return", invalid_fp_unavailable); 889 lf_indent (file, -2); 890 lf_printf (file, "}\n"); 891 lf_indent_suppress (file); 892 lf_printf (file, "#endif\n"); 893 } 894 } 895 896 /* Validate: Validate Instruction in correct slot 897 898 Some architectures place restrictions on the slot that an 899 instruction can be issued in */ 900 901 { 902 if (filter_is_member (instruction->options, "s") 903 || options.gen.slot_verification) 904 { 905 lf_printf (file, "\n"); 906 lf_indent_suppress (file); 907 lf_printf (file, "#if defined(IS_WRONG_SLOT)\n"); 908 lf_printf (file, 909 "/* Validate: Instruction issued in correct slot */\n"); 910 lf_printf (file, "if (IS_WRONG_SLOT) {\n"); 911 lf_indent (file, +2); 912 print_idecode_invalid (file, "return", invalid_wrong_slot); 913 lf_indent (file, -2); 914 lf_printf (file, "}\n"); 915 lf_indent_suppress (file); 916 lf_printf (file, "#endif\n"); 917 } 918 } 919 920 } 921 922 923 /****************************************************************/ 924 925 926 void 927 print_idecode_issue_function_header (lf *file, 928 const char *processor, 929 function_decl_type decl_type, 930 int nr_prefetched_words) 931 { 932 int indent; 933 lf_printf (file, "\n"); 934 switch (decl_type) 935 { 936 case is_function_declaration: 937 lf_print__function_type_function (file, print_semantic_function_type, 938 "INLINE_IDECODE", " "); 939 break; 940 case is_function_definition: 941 lf_print__function_type_function (file, print_semantic_function_type, 942 "INLINE_IDECODE", "\n"); 943 break; 944 case is_function_variable: 945 if (lf_get_file_type (file) == lf_is_h) 946 lf_printf (file, "extern "); 947 print_semantic_function_type (file); 948 lf_printf (file, " (*"); 949 break; 950 } 951 indent = print_function_name (file, 952 "issue", 953 NULL, 954 processor, 955 NULL, function_name_prefix_idecode); 956 switch (decl_type) 957 { 958 case is_function_definition: 959 indent += lf_printf (file, " ("); 960 break; 961 case is_function_declaration: 962 lf_putstr (file, "\n("); 963 indent = 1; 964 break; 965 case is_function_variable: 966 lf_putstr (file, ")\n("); 967 indent = 1; 968 break; 969 } 970 lf_indent (file, +indent); 971 print_semantic_function_formal (file, nr_prefetched_words); 972 lf_putstr (file, ")"); 973 lf_indent (file, -indent); 974 switch (decl_type) 975 { 976 case is_function_definition: 977 lf_printf (file, "\n"); 978 break; 979 case is_function_declaration: 980 case is_function_variable: 981 lf_putstr (file, ";\n"); 982 break; 983 } 984 } 985 986 987 988 void 989 print_idecode_globals (lf *file) 990 { 991 lf_printf (file, "enum {\n"); 992 lf_printf (file, " /* greater or equal to zero => table */\n"); 993 lf_printf (file, " function_entry = -1,\n"); 994 lf_printf (file, " boolean_entry = -2,\n"); 995 lf_printf (file, "};\n"); 996 lf_printf (file, "\n"); 997 lf_printf (file, "typedef struct _idecode_table_entry {\n"); 998 lf_printf (file, " int shift;\n"); 999 lf_printf (file, " uint%d_t mask;\n", options.insn_bit_size); 1000 lf_printf (file, " uint%d_t value;\n", options.insn_bit_size); 1001 lf_printf (file, " void *function_or_table;\n"); 1002 lf_printf (file, "} idecode_table_entry;\n"); 1003 } 1004