1/* The IGEN simulator generator for GDB, the GNU Debugger. 2 3 Copyright 2002-2023 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#include <getopt.h> 23#include <stdlib.h> 24 25#include "misc.h" 26#include "lf.h" 27#include "table.h" 28#include "filter.h" 29 30#include "igen.h" 31 32#include "ld-insn.h" 33#include "ld-decode.h" 34#include "ld-cache.h" 35 36#include "gen.h" 37 38#include "gen-model.h" 39#include "gen-icache.h" 40#include "gen-itable.h" 41#include "gen-idecode.h" 42#include "gen-semantics.h" 43#include "gen-engine.h" 44#include "gen-support.h" 45#include "gen-engine.h" 46 47 48/****************************************************************/ 49 50 51/* Semantic functions */ 52 53int 54print_semantic_function_formal (lf *file, int nr_prefetched_words) 55{ 56 int nr = 0; 57 int word_nr; 58 if (options.gen.icache || nr_prefetched_words < 0) 59 { 60 nr += lf_printf (file, "SIM_DESC sd,\n"); 61 nr += lf_printf (file, "%sidecode_cache *cache_entry,\n", 62 options.module.global.prefix.l); 63 nr += lf_printf (file, "%sinstruction_address cia", 64 options.module.global.prefix.l); 65 } 66 else if (options.gen.smp) 67 { 68 nr += lf_printf (file, "sim_cpu *cpu,\n"); 69 for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++) 70 { 71 nr += lf_printf (file, "%sinstruction_word instruction_%d,\n", 72 options.module.global.prefix.l, word_nr); 73 } 74 nr += lf_printf (file, "%sinstruction_address cia", 75 options.module.global.prefix.l); 76 } 77 else 78 { 79 nr += lf_printf (file, "SIM_DESC sd,\n"); 80 for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++) 81 { 82 nr += lf_printf (file, "%sinstruction_word instruction_%d,\n", 83 options.module.global.prefix.l, word_nr); 84 } 85 nr += lf_printf (file, "%sinstruction_address cia", 86 options.module.global.prefix.l); 87 } 88 return nr; 89} 90 91int 92print_semantic_function_actual (lf *file, int nr_prefetched_words) 93{ 94 int nr = 0; 95 int word_nr; 96 if (options.gen.icache || nr_prefetched_words < 0) 97 { 98 nr += lf_printf (file, "sd, cache_entry, cia"); 99 } 100 else 101 { 102 if (options.gen.smp) 103 nr += lf_printf (file, "cpu"); 104 else 105 nr += lf_printf (file, "sd"); 106 for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++) 107 nr += lf_printf (file, ", instruction_%d", word_nr); 108 nr += lf_printf (file, ", cia"); 109 } 110 return nr; 111} 112 113int 114print_semantic_function_type (lf *file) 115{ 116 int nr = 0; 117 nr += lf_printf (file, "%sinstruction_address", 118 options.module.global.prefix.l); 119 return nr; 120} 121 122 123/* Idecode functions */ 124 125int 126print_icache_function_formal (lf *file, int nr_prefetched_words) 127{ 128 int nr = 0; 129 int word_nr; 130 if (options.gen.smp) 131 nr += lf_printf (file, "sim_cpu *cpu,\n"); 132 else 133 nr += lf_printf (file, "SIM_DESC sd,\n"); 134 for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++) 135 nr += lf_printf (file, " %sinstruction_word instruction_%d,\n", 136 options.module.global.prefix.l, word_nr); 137 nr += lf_printf (file, " %sinstruction_address cia,\n", 138 options.module.global.prefix.l); 139 nr += lf_printf (file, " %sidecode_cache *cache_entry", 140 options.module.global.prefix.l); 141 return nr; 142} 143 144int 145print_icache_function_actual (lf *file, int nr_prefetched_words) 146{ 147 int nr = 0; 148 int word_nr; 149 if (options.gen.smp) 150 nr += lf_printf (file, "cpu"); 151 else 152 nr += lf_printf (file, "sd"); 153 for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++) 154 nr += lf_printf (file, ", instruction_%d", word_nr); 155 nr += lf_printf (file, ", cia, cache_entry"); 156 return nr; 157} 158 159int 160print_icache_function_type (lf *file) 161{ 162 int nr; 163 if (options.gen.semantic_icache) 164 { 165 nr = print_semantic_function_type (file); 166 } 167 else 168 { 169 nr = lf_printf (file, "%sidecode_semantic *", 170 options.module.global.prefix.l); 171 } 172 return nr; 173} 174 175 176/* Function names */ 177 178static int 179print_opcode_bits (lf *file, const opcode_bits *bits) 180{ 181 int nr = 0; 182 if (bits == NULL) 183 return nr; 184 nr += lf_putchr (file, '_'); 185 nr += lf_putstr (file, bits->field->val_string); 186 if (bits->opcode->is_boolean && bits->value == 0) 187 nr += lf_putint (file, bits->opcode->boolean_constant); 188 else if (!bits->opcode->is_boolean) 189 { 190 if (bits->opcode->last < bits->field->last) 191 nr += 192 lf_putint (file, 193 bits->value << (bits->field->last - bits->opcode->last)); 194 else 195 nr += lf_putint (file, bits->value); 196 } 197 nr += print_opcode_bits (file, bits->next); 198 return nr; 199} 200 201static int 202print_c_name (lf *file, const char *name) 203{ 204 int nr = 0; 205 const char *pos; 206 for (pos = name; *pos != '\0'; pos++) 207 { 208 switch (*pos) 209 { 210 case '/': 211 case '-': 212 break; 213 case ' ': 214 case '.': 215 nr += lf_putchr (file, '_'); 216 break; 217 default: 218 nr += lf_putchr (file, *pos); 219 break; 220 } 221 } 222 return nr; 223} 224 225extern int 226print_function_name (lf *file, 227 const char *basename, 228 const char *format_name, 229 const char *model_name, 230 const opcode_bits *expanded_bits, 231 lf_function_name_prefixes prefix) 232{ 233 int nr = 0; 234 /* the prefix */ 235 switch (prefix) 236 { 237 case function_name_prefix_semantics: 238 nr += lf_printf (file, "%s", options.module.semantics.prefix.l); 239 nr += lf_printf (file, "semantic_"); 240 break; 241 case function_name_prefix_idecode: 242 nr += lf_printf (file, "%s", options.module.idecode.prefix.l); 243 nr += lf_printf (file, "idecode_"); 244 break; 245 case function_name_prefix_itable: 246 nr += lf_printf (file, "%sitable_", options.module.itable.prefix.l); 247 break; 248 case function_name_prefix_icache: 249 nr += lf_printf (file, "%s", options.module.icache.prefix.l); 250 nr += lf_printf (file, "icache_"); 251 break; 252 case function_name_prefix_engine: 253 nr += lf_printf (file, "%s", options.module.engine.prefix.l); 254 nr += lf_printf (file, "engine_"); 255 default: 256 break; 257 } 258 259 if (model_name != NULL) 260 { 261 nr += print_c_name (file, model_name); 262 nr += lf_printf (file, "_"); 263 } 264 265 /* the function name */ 266 nr += print_c_name (file, basename); 267 268 /* the format name if available */ 269 if (format_name != NULL) 270 { 271 nr += lf_printf (file, "_"); 272 nr += print_c_name (file, format_name); 273 } 274 275 /* the suffix */ 276 nr += print_opcode_bits (file, expanded_bits); 277 278 return nr; 279} 280 281 282void 283print_my_defines (lf *file, 284 const char *basename, 285 const char *format_name, 286 const opcode_bits *expanded_bits) 287{ 288 /* #define MY_INDEX xxxxx */ 289 lf_indent_suppress (file); 290 lf_printf (file, "#undef MY_INDEX\n"); 291 lf_indent_suppress (file); 292 lf_printf (file, "#define MY_INDEX "); 293 print_function_name (file, 294 basename, format_name, NULL, 295 NULL, function_name_prefix_itable); 296 lf_printf (file, "\n"); 297 /* #define MY_PREFIX xxxxxx */ 298 lf_indent_suppress (file); 299 lf_printf (file, "#undef "); 300 print_function_name (file, 301 basename, format_name, NULL, 302 expanded_bits, function_name_prefix_none); 303 lf_printf (file, "\n"); 304 lf_indent_suppress (file); 305 lf_printf (file, "#undef MY_PREFIX\n"); 306 lf_indent_suppress (file); 307 lf_printf (file, "#define MY_PREFIX "); 308 print_function_name (file, 309 basename, format_name, NULL, 310 expanded_bits, function_name_prefix_none); 311 lf_printf (file, "\n"); 312 /* #define MY_NAME xxxxxx */ 313 lf_indent_suppress (file); 314 lf_indent_suppress (file); 315 lf_printf (file, "#undef MY_NAME\n"); 316 lf_indent_suppress (file); 317 lf_printf (file, "#define MY_NAME \""); 318 print_function_name (file, 319 basename, format_name, NULL, 320 expanded_bits, function_name_prefix_none); 321 lf_printf (file, "\"\n"); 322} 323 324 325static int 326print_itrace_prefix (lf *file) 327{ 328 const char *prefix = "trace_prefix ("; 329 int indent = strlen (prefix); 330 lf_printf (file, "%sSD, CPU, cia, CIA, TRACE_LINENUM_P (CPU), \\\n", 331 prefix); 332 lf_indent (file, +indent); 333 lf_printf (file, "%sitable[MY_INDEX].file, \\\n", 334 options.module.itable.prefix.l); 335 lf_printf (file, "%sitable[MY_INDEX].line_nr, \\\n", 336 options.module.itable.prefix.l); 337 lf_printf (file, "\""); 338 return indent; 339} 340 341 342static void 343print_itrace_format (lf *file, const insn_mnemonic_entry *assembler) 344{ 345 /* pass=1 is fmt string; pass=2 is arguments */ 346 int pass; 347 /* print the format string */ 348 for (pass = 1; pass <= 2; pass++) 349 { 350 const char *chp = assembler->format; 351 chp++; /* skip the leading quote */ 352 /* write out the format/args */ 353 while (*chp != '\0') 354 { 355 if (chp[0] == '\\' && (chp[1] == '<' || chp[1] == '>')) 356 { 357 if (pass == 1) 358 lf_putchr (file, chp[1]); 359 chp += 2; 360 } 361 else if (chp[0] == '<' || chp[0] == '%') 362 { 363 /* parse [ "%" ... ] "<" [ func "#" ] param ">" */ 364 const char *fmt; 365 const char *func; 366 int strlen_func; 367 const char *param; 368 int strlen_param; 369 /* the "%" ... "<" format */ 370 fmt = chp; 371 while (chp[0] != '<' && chp[0] != '\0') 372 chp++; 373 if (chp[0] != '<') 374 error (assembler->line, "Missing `<' after `%%'\n"); 375 chp++; 376 /* [ "func" # ] OR "param" */ 377 func = chp; 378 param = chp; 379 while (chp[0] != '>' && chp[0] != '#' && chp[0] != '\0') 380 chp++; 381 strlen_func = chp - func; 382 if (chp[0] == '#') 383 { 384 chp++; 385 param = chp; 386 while (chp[0] != '>' && chp[0] != '\0') 387 chp++; 388 } 389 strlen_param = chp - param; 390 if (chp[0] != '>') 391 error (assembler->line, 392 "Missing closing `>' in assembler string\n"); 393 chp++; 394 /* now process it */ 395 if (pass == 2) 396 lf_printf (file, ", \\\n"); 397 if (strncmp (fmt, "<", 1) == 0) 398 /* implicit long int format */ 399 { 400 if (pass == 1) 401 lf_printf (file, "%%ld"); 402 else 403 { 404 lf_printf (file, "(long) "); 405 lf_write (file, param, strlen_param); 406 } 407 } 408 else if (strncmp (fmt, "%<", 2) == 0) 409 /* explicit format */ 410 { 411 if (pass == 1) 412 lf_printf (file, "%%"); 413 else 414 lf_write (file, param, strlen_param); 415 } 416 else if (strncmp (fmt, "%s<", 3) == 0) 417 /* string format */ 418 { 419 if (pass == 1) 420 lf_printf (file, "%%s"); 421 else 422 { 423 lf_printf (file, "%sstr_", 424 options.module.global.prefix.l); 425 lf_write (file, func, strlen_func); 426 lf_printf (file, " (SD_, "); 427 lf_write (file, param, strlen_param); 428 lf_printf (file, ")"); 429 } 430 } 431 else if (strncmp (fmt, "%lx<", 4) == 0) 432 /* simple hex */ 433 { 434 if (pass == 1) 435 lf_printf (file, "%%lx"); 436 else 437 { 438 lf_printf (file, "(unsigned long) "); 439 lf_write (file, param, strlen_param); 440 } 441 } 442 else if (strncmp (fmt, "%#lx<", 5) == 0) 443 /* simple hex with 0x prefix */ 444 { 445 if (pass == 1) 446 lf_printf (file, "%%#lx"); 447 else 448 { 449 lf_printf (file, "(unsigned long) "); 450 lf_write (file, param, strlen_param); 451 } 452 } 453 else if (strncmp (fmt, "%08lx<", 6) == 0) 454 /* simple hex */ 455 { 456 if (pass == 1) 457 lf_printf (file, "%%08lx"); 458 else 459 { 460 lf_printf (file, "(unsigned long) "); 461 lf_write (file, param, strlen_param); 462 } 463 } 464 else 465 error (assembler->line, "Unknown assembler string format\n"); 466 } 467 else 468 { 469 if (pass == 1) 470 lf_putchr (file, chp[0]); 471 chp += 1; 472 } 473 } 474 } 475 lf_printf (file, ");\n"); 476} 477 478 479void 480print_itrace (lf *file, const insn_entry *insn, int idecode) 481{ 482 /* NB: Here we escape each EOLN. This is so that the the compiler 483 treats a trace function call as a single line. Consequently any 484 errors in the line are refered back to the same igen assembler 485 source line */ 486 const char *phase = (idecode) ? "DECODE" : "INSN"; 487 lf_printf (file, "\n"); 488 lf_indent_suppress (file); 489 lf_printf (file, "#if defined (WITH_TRACE)\n"); 490 lf_printf (file, "/* generate a trace prefix if any tracing enabled */\n"); 491 lf_printf (file, "if (TRACE_ANY_P (CPU))\n"); 492 lf_printf (file, " {\n"); 493 lf_indent (file, +4); 494 { 495 if (insn->mnemonics != NULL) 496 { 497 insn_mnemonic_entry *assembler = insn->mnemonics; 498 int is_first = 1; 499 do 500 { 501 if (assembler->condition != NULL) 502 { 503 int indent; 504 lf_printf (file, "%sif (%s)\n", 505 is_first ? "" : "else ", assembler->condition); 506 lf_indent (file, +2); 507 lf_print__line_ref (file, assembler->line); 508 indent = print_itrace_prefix (file); 509 print_itrace_format (file, assembler); 510 lf_print__internal_ref (file); 511 lf_indent (file, -indent); 512 lf_indent (file, -2); 513 if (assembler->next == NULL) 514 error (assembler->line, 515 "Missing final unconditional assembler\n"); 516 } 517 else 518 { 519 int indent; 520 if (!is_first) 521 { 522 lf_printf (file, "else\n"); 523 lf_indent (file, +2); 524 } 525 lf_print__line_ref (file, assembler->line); 526 indent = print_itrace_prefix (file); 527 print_itrace_format (file, assembler); 528 lf_print__internal_ref (file); 529 lf_indent (file, -indent); 530 if (!is_first) 531 lf_indent (file, -2); 532 if (assembler->next != NULL) 533 error (assembler->line, 534 "Unconditional assembler is not last\n"); 535 } 536 is_first = 0; 537 assembler = assembler->next; 538 } 539 while (assembler != NULL); 540 } 541 else 542 { 543 int indent; 544 lf_indent (file, +2); 545 lf_print__line_ref (file, insn->line); 546 indent = print_itrace_prefix (file); 547 lf_printf (file, "%%s\", \\\n"); 548 lf_printf (file, "itable[MY_INDEX].name);\n"); 549 lf_print__internal_ref (file); 550 lf_indent (file, -indent); 551 lf_indent (file, -2); 552 } 553 lf_printf (file, "/* trace the instruction execution if enabled */\n"); 554 lf_printf (file, "if (TRACE_%s_P (CPU))\n", phase); 555 lf_printf (file, 556 " trace_generic (SD, CPU, TRACE_%s_IDX, \" %%s\", itable[MY_INDEX].name);\n", 557 phase); 558 } 559 lf_indent (file, -4); 560 lf_printf (file, " }\n"); 561 lf_indent_suppress (file); 562 lf_printf (file, "#endif\n"); 563} 564 565 566void 567print_sim_engine_abort (lf *file, const char *message) 568{ 569 lf_printf (file, "sim_engine_abort (SD, CPU, cia, "); 570 lf_printf (file, "\"%s\"", message); 571 lf_printf (file, ");\n"); 572} 573 574 575void 576print_include (lf *file, igen_module module) 577{ 578 lf_printf (file, "#include \"%s%s.h\"\n", module.prefix.l, module.suffix.l); 579} 580 581void 582print_include_inline (lf *file, igen_module module) 583{ 584 lf_printf (file, "#if C_REVEALS_MODULE_P (%s_INLINE)\n", module.suffix.u); 585 lf_printf (file, "#include \"%s%s.c\"\n", module.prefix.l, module.suffix.l); 586 lf_printf (file, "#else\n"); 587 print_include (file, module); 588 lf_printf (file, "#endif\n"); 589 lf_printf (file, "\n"); 590} 591 592void 593print_includes (lf *file) 594{ 595 lf_printf (file, "\n"); 596 lf_printf (file, "#include \"sim-inline.c\"\n"); 597 lf_printf (file, "\n"); 598 print_include_inline (file, options.module.itable); 599 print_include_inline (file, options.module.idecode); 600 print_include_inline (file, options.module.support); 601} 602 603 604/****************************************************************/ 605 606 607static void 608gen_semantics_h (lf *file, const insn_list *semantics, int max_nr_words) 609{ 610 int word_nr; 611 const insn_list *semantic; 612 for (word_nr = -1; word_nr <= max_nr_words; word_nr++) 613 { 614 lf_printf (file, "typedef "); 615 print_semantic_function_type (file); 616 lf_printf (file, " %sidecode_semantic", options.module.global.prefix.l); 617 if (word_nr >= 0) 618 lf_printf (file, "_%d", word_nr); 619 lf_printf (file, "\n("); 620 lf_indent (file, +1); 621 print_semantic_function_formal (file, word_nr); 622 lf_indent (file, -1); 623 lf_printf (file, ");\n"); 624 lf_printf (file, "\n"); 625 } 626 switch (options.gen.code) 627 { 628 case generate_calls: 629 for (semantic = semantics; semantic != NULL; semantic = semantic->next) 630 { 631 /* Ignore any special/internal instructions */ 632 if (semantic->insn->nr_words == 0) 633 continue; 634 print_semantic_declaration (file, 635 semantic->insn, 636 semantic->expanded_bits, 637 semantic->opcodes, 638 semantic->nr_prefetched_words); 639 } 640 break; 641 case generate_jumps: 642 lf_print__this_file_is_empty (file, "generating jumps"); 643 break; 644 } 645} 646 647 648static void 649gen_semantics_c (lf *file, const insn_list *semantics, cache_entry *cache_rules) 650{ 651 if (options.gen.code == generate_calls) 652 { 653 const insn_list *semantic; 654 print_includes (file); 655 print_include (file, options.module.semantics); 656 lf_printf (file, "\n"); 657 658 for (semantic = semantics; semantic != NULL; semantic = semantic->next) 659 { 660 /* Ignore any special/internal instructions */ 661 if (semantic->insn->nr_words == 0) 662 continue; 663 print_semantic_definition (file, 664 semantic->insn, 665 semantic->expanded_bits, 666 semantic->opcodes, 667 cache_rules, 668 semantic->nr_prefetched_words); 669 } 670 } 671 else 672 { 673 lf_print__this_file_is_empty (file, "generating jump engine"); 674 } 675} 676 677 678/****************************************************************/ 679 680 681static void 682gen_icache_h (lf *file, 683 const insn_list *semantic, 684 const function_entry *functions, int max_nr_words) 685{ 686 int word_nr; 687 for (word_nr = 0; word_nr <= max_nr_words; word_nr++) 688 { 689 lf_printf (file, "typedef "); 690 print_icache_function_type (file); 691 lf_printf (file, " %sidecode_icache_%d\n(", 692 options.module.global.prefix.l, word_nr); 693 print_icache_function_formal (file, word_nr); 694 lf_printf (file, ");\n"); 695 lf_printf (file, "\n"); 696 } 697 if (options.gen.code == generate_calls && options.gen.icache) 698 { 699 function_entry_traverse (file, functions, 700 print_icache_internal_function_declaration, 701 NULL); 702 while (semantic != NULL) 703 { 704 print_icache_declaration (file, 705 semantic->insn, 706 semantic->expanded_bits, 707 semantic->opcodes, 708 semantic->nr_prefetched_words); 709 semantic = semantic->next; 710 } 711 } 712 else 713 { 714 lf_print__this_file_is_empty (file, "generating jump engine"); 715 } 716} 717 718static void 719gen_icache_c (lf *file, 720 const insn_list *semantic, 721 const function_entry *functions, cache_entry *cache_rules) 722{ 723 /* output `internal' invalid/floating-point unavailable functions 724 where needed */ 725 if (options.gen.code == generate_calls && options.gen.icache) 726 { 727 lf_printf (file, "\n"); 728 lf_printf (file, "#include \"cpu.h\"\n"); 729 lf_printf (file, "#include \"idecode.h\"\n"); 730 lf_printf (file, "#include \"semantics.h\"\n"); 731 lf_printf (file, "#include \"icache.h\"\n"); 732 lf_printf (file, "#include \"support.h\"\n"); 733 lf_printf (file, "\n"); 734 function_entry_traverse (file, functions, 735 print_icache_internal_function_definition, 736 NULL); 737 lf_printf (file, "\n"); 738 while (semantic != NULL) 739 { 740 print_icache_definition (file, 741 semantic->insn, 742 semantic->expanded_bits, 743 semantic->opcodes, 744 cache_rules, 745 semantic->nr_prefetched_words); 746 semantic = semantic->next; 747 } 748 } 749 else 750 { 751 lf_print__this_file_is_empty (file, "generating jump engine"); 752 } 753} 754 755 756/****************************************************************/ 757 758 759static void 760gen_idecode_h (lf *file, 761 const gen_table *gen, 762 const insn_table *insns, 763 cache_entry *cache_rules) 764{ 765 lf_printf (file, "typedef uint%d_t %sinstruction_word;\n", 766 options.insn_bit_size, options.module.global.prefix.l); 767 if (options.gen.delayed_branch) 768 { 769 lf_printf (file, "typedef struct _%sinstruction_address {\n", 770 options.module.global.prefix.l); 771 lf_printf (file, " address_word ip; /* instruction pointer */\n"); 772 lf_printf (file, " address_word dp; /* delayed-slot pointer */\n"); 773 lf_printf (file, "} %sinstruction_address;\n", 774 options.module.global.prefix.l); 775 } 776 else 777 { 778 lf_printf (file, "typedef address_word %sinstruction_address;\n", 779 options.module.global.prefix.l); 780 781 } 782 if (options.gen.nia == nia_is_invalid 783 && strlen (options.module.global.prefix.u) > 0) 784 { 785 lf_indent_suppress (file); 786 lf_printf (file, "#define %sINVALID_INSTRUCTION_ADDRESS ", 787 options.module.global.prefix.u); 788 lf_printf (file, "INVALID_INSTRUCTION_ADDRESS\n"); 789 } 790 lf_printf (file, "\n"); 791 print_icache_struct (file, insns, cache_rules); 792 lf_printf (file, "\n"); 793 if (options.gen.icache) 794 { 795 ERROR ("FIXME - idecode with icache suffering from bit-rot"); 796 } 797 else 798 { 799 gen_list *entry; 800 for (entry = gen->tables; entry != NULL; entry = entry->next) 801 { 802 print_idecode_issue_function_header (file, 803 (options.gen.multi_sim 804 ? entry->model->name 805 : NULL), 806 is_function_declaration, 807 1 /*ALWAYS ONE WORD */ ); 808 } 809 if (options.gen.multi_sim) 810 { 811 print_idecode_issue_function_header (file, 812 NULL, 813 is_function_variable, 814 1 /*ALWAYS ONE WORD */ ); 815 } 816 } 817} 818 819 820static void 821gen_idecode_c (lf *file, 822 const gen_table *gen, 823 const insn_table *isa, 824 cache_entry *cache_rules) 825{ 826 /* the intro */ 827 print_includes (file); 828 print_include_inline (file, options.module.semantics); 829 lf_printf (file, "\n"); 830 831 print_idecode_globals (file); 832 lf_printf (file, "\n"); 833 834 switch (options.gen.code) 835 { 836 case generate_calls: 837 { 838 gen_list *entry; 839 for (entry = gen->tables; entry != NULL; entry = entry->next) 840 { 841 print_idecode_lookups (file, entry->table, cache_rules); 842 843 /* output the main idecode routine */ 844 if (!options.gen.icache) 845 { 846 print_idecode_issue_function_header (file, 847 (options.gen.multi_sim 848 ? entry->model->name 849 : NULL), 850 1 /*is definition */ , 851 1 /*ALWAYS ONE WORD */ ); 852 lf_printf (file, "{\n"); 853 lf_indent (file, +2); 854 lf_printf (file, "%sinstruction_address nia;\n", 855 options.module.global.prefix.l); 856 print_idecode_body (file, entry->table, "nia ="); 857 lf_printf (file, "return nia;"); 858 lf_indent (file, -2); 859 lf_printf (file, "}\n"); 860 } 861 } 862 break; 863 } 864 case generate_jumps: 865 { 866 lf_print__this_file_is_empty (file, "generating a jump engine"); 867 break; 868 } 869 } 870} 871 872 873/****************************************************************/ 874 875 876static void 877gen_run_c (lf *file, const gen_table *gen) 878{ 879 gen_list *entry; 880 lf_printf (file, "#include \"sim-main.h\"\n"); 881 lf_printf (file, "#include \"engine.h\"\n"); 882 lf_printf (file, "#include \"idecode.h\"\n"); 883 lf_printf (file, "#include \"bfd.h\"\n"); 884 lf_printf (file, "\n"); 885 886 if (options.gen.multi_sim) 887 { 888 print_idecode_issue_function_header (file, NULL, is_function_variable, 889 1); 890 lf_printf (file, "\n"); 891 print_engine_run_function_header (file, NULL, is_function_variable); 892 lf_printf (file, "\n"); 893 } 894 895 lf_printf (file, "void\n"); 896 lf_printf (file, "sim_engine_run (SIM_DESC sd,\n"); 897 lf_printf (file, " int next_cpu_nr,\n"); 898 lf_printf (file, " int nr_cpus,\n"); 899 lf_printf (file, " int siggnal)\n"); 900 lf_printf (file, "{\n"); 901 lf_indent (file, +2); 902 if (options.gen.multi_sim) 903 { 904 lf_printf (file, "int mach;\n"); 905 lf_printf (file, "if (STATE_ARCHITECTURE (sd) == NULL)\n"); 906 lf_printf (file, " mach = 0;\n"); 907 lf_printf (file, "else\n"); 908 lf_printf (file, " mach = STATE_ARCHITECTURE (sd)->mach;\n"); 909 lf_printf (file, "switch (mach)\n"); 910 lf_printf (file, " {\n"); 911 lf_indent (file, +2); 912 for (entry = gen->tables; entry != NULL; entry = entry->next) 913 { 914 if (options.gen.default_model != NULL 915 && (strcmp (entry->model->name, options.gen.default_model) == 0 916 || strcmp (entry->model->full_name, 917 options.gen.default_model) == 0)) 918 lf_printf (file, "default:\n"); 919 lf_printf (file, "case bfd_mach_%s:\n", entry->model->full_name); 920 lf_indent (file, +2); 921 print_function_name (file, "issue", NULL, /* format name */ 922 NULL, /* NO processor */ 923 NULL, /* expanded bits */ 924 function_name_prefix_idecode); 925 lf_printf (file, " = "); 926 print_function_name (file, "issue", NULL, /* format name */ 927 entry->model->name, NULL, /* expanded bits */ 928 function_name_prefix_idecode); 929 lf_printf (file, ";\n"); 930 print_function_name (file, "run", NULL, /* format name */ 931 NULL, /* NO processor */ 932 NULL, /* expanded bits */ 933 function_name_prefix_engine); 934 lf_printf (file, " = "); 935 print_function_name (file, "run", NULL, /* format name */ 936 entry->model->name, NULL, /* expanded bits */ 937 function_name_prefix_engine); 938 lf_printf (file, ";\n"); 939 lf_printf (file, "break;\n"); 940 lf_indent (file, -2); 941 } 942 if (options.gen.default_model == NULL) 943 { 944 lf_printf (file, "default:\n"); 945 lf_indent (file, +2); 946 lf_printf (file, "sim_engine_abort (sd, NULL, NULL_CIA,\n"); 947 lf_printf (file, 948 " \"sim_engine_run - unknown machine\");\n"); 949 lf_printf (file, "break;\n"); 950 lf_indent (file, -2); 951 } 952 lf_indent (file, -2); 953 lf_printf (file, " }\n"); 954 } 955 print_function_name (file, "run", NULL, /* format name */ 956 NULL, /* NO processor */ 957 NULL, /* expanded bits */ 958 function_name_prefix_engine); 959 lf_printf (file, " (sd, next_cpu_nr, nr_cpus, siggnal);\n"); 960 lf_indent (file, -2); 961 lf_printf (file, "}\n"); 962} 963 964/****************************************************************/ 965 966static gen_table * 967do_gen (const insn_table *isa, const decode_table *decode_rules) 968{ 969 gen_table *gen; 970 if (decode_rules == NULL) 971 error (NULL, "Must specify a decode table\n"); 972 if (isa == NULL) 973 error (NULL, "Must specify an instruction table\n"); 974 if (decode_table_max_word_nr (decode_rules) > 0) 975 options.gen.multi_word = decode_table_max_word_nr (decode_rules); 976 gen = make_gen_tables (isa, decode_rules); 977 gen_tables_expand_insns (gen); 978 gen_tables_expand_semantics (gen); 979 return gen; 980} 981 982/****************************************************************/ 983 984igen_options options; 985 986int 987main (int argc, char **argv, char **envp) 988{ 989 cache_entry *cache_rules = NULL; 990 lf_file_references file_references = lf_include_references; 991 decode_table *decode_rules = NULL; 992 insn_table *isa = NULL; 993 gen_table *gen = NULL; 994 char *real_file_name = NULL; 995 int is_header = 0; 996 int ch; 997 static const struct option longopts[] = { { 0 } }; 998 lf *standard_out = 999 lf_open ("-", "stdout", lf_omit_references, lf_is_text, "igen"); 1000 1001 INIT_OPTIONS (); 1002 1003 if (argc == 1) 1004 { 1005 printf ("Usage:\n"); 1006 printf ("\n"); 1007 printf (" igen <config-opts> ... <input-opts>... <output-opts>...\n"); 1008 printf ("\n"); 1009 printf ("Config options:\n"); 1010 printf ("\n"); 1011 printf (" -B <bit-size>\n"); 1012 printf ("\t Set the number of bits in an instruction (deprecated).\n"); 1013 printf 1014 ("\t This option can now be set directly in the instruction table.\n"); 1015 printf ("\n"); 1016 printf (" -D <data-structure>\n"); 1017 printf 1018 ("\t Dump the specified data structure to stdout. Valid structures include:\n"); 1019 printf 1020 ("\t processor-names - list the names of all the processors (models)\n"); 1021 printf ("\n"); 1022 printf (" -F <filter-list>\n"); 1023 printf 1024 ("\t Filter out any instructions with a non-empty flags field that contains\n"); 1025 printf ("\t a flag not listed in the <filter-list>.\n"); 1026 printf ("\n"); 1027 printf (" -H <high-bit>\n"); 1028 printf 1029 ("\t Set the number of the high (most significant) instruction bit (deprecated).\n"); 1030 printf 1031 ("\t This option can now be set directly in the instruction table.\n"); 1032 printf ("\n"); 1033 printf (" -I <directory>\n"); 1034 printf 1035 ("\t Add <directory> to the list of directories searched when opening a file\n"); 1036 printf ("\n"); 1037 printf (" -M <model-list>\n"); 1038 printf 1039 ("\t Filter out any instructions that do not support at least one of the listed\n"); 1040 printf 1041 ("\t models (An instructions with no model information is considered to support\n"); 1042 printf ("\t all models.).\n"); 1043 printf ("\n"); 1044 printf (" -N <nr-cpus>\n"); 1045 printf ("\t Generate a simulator supporting <nr-cpus>\n"); 1046 printf 1047 ("\t Specify `-N 0' to disable generation of the SMP. Specifying `-N 1' will\n"); 1048 printf 1049 ("\t still generate an SMP enabled simulator but will only support one CPU.\n"); 1050 printf ("\n"); 1051 printf (" -T <mechanism>\n"); 1052 printf 1053 ("\t Override the decode mechanism specified by the decode rules\n"); 1054 printf ("\n"); 1055 printf (" -P <prefix>\n"); 1056 printf 1057 ("\t Prepend global names (except itable) with the string <prefix>.\n"); 1058 printf 1059 ("\t Specify -P <module>=<prefix> to set a specific <module>'s prefix.\n"); 1060 printf ("\n"); 1061 printf (" -S <suffix>\n"); 1062 printf 1063 ("\t Replace a global name (suffix) (except itable) with the string <suffix>.\n"); 1064 printf 1065 ("\t Specify -S <module>=<suffix> to change a specific <module>'s name (suffix).\n"); 1066 printf ("\n"); 1067 printf (" -Werror\n"); 1068 printf ("\t Make warnings errors\n"); 1069 printf (" -Wnodiscard\n"); 1070 printf 1071 ("\t Suppress warnings about discarded functions and instructions\n"); 1072 printf (" -Wnowidth\n"); 1073 printf 1074 ("\t Suppress warnings about instructions with invalid widths\n"); 1075 printf (" -Wnounimplemented\n"); 1076 printf ("\t Suppress warnings about unimplemented instructions\n"); 1077 printf ("\n"); 1078 printf (" -G [!]<gen-option>\n"); 1079 printf ("\t Any of the following options:\n"); 1080 printf ("\n"); 1081 printf 1082 ("\t decode-duplicate - Override the decode rules, forcing the duplication of\n"); 1083 printf ("\t semantic functions\n"); 1084 printf 1085 ("\t decode-combine - Combine any duplicated entries within a table\n"); 1086 printf 1087 ("\t decode-zero-reserved - Override the decode rules, forcing reserved bits to be\n"); 1088 printf ("\t treated as zero.\n"); 1089 printf 1090 ("\t decode-switch-is-goto - Overfide the padded-switch code type as a goto-switch\n"); 1091 printf ("\n"); 1092 printf 1093 ("\t gen-conditional-issue - conditionally issue each instruction\n"); 1094 printf 1095 ("\t gen-delayed-branch - need both cia and nia passed around\n"); 1096 printf 1097 ("\t gen-direct-access - use #defines to directly access values\n"); 1098 printf 1099 ("\t gen-zero-r<N> - arch assumes GPR(<N>) == 0, keep it that way\n"); 1100 printf 1101 ("\t gen-icache[=<N> - generate an instruction cracking cache of size <N>\n"); 1102 printf ("\t Default size is %d\n", 1103 options.gen.icache_size); 1104 printf 1105 ("\t gen-insn-in-icache - save original instruction when cracking\n"); 1106 printf 1107 ("\t gen-multi-sim[=MODEL] - generate multiple simulators - one per model\n"); 1108 printf 1109 ("\t If specified MODEL is made the default architecture.\n"); 1110 printf 1111 ("\t By default, a single simulator that will\n"); 1112 printf 1113 ("\t execute any instruction is generated\n"); 1114 printf 1115 ("\t gen-multi-word - generate code allowing for multi-word insns\n"); 1116 printf 1117 ("\t gen-semantic-icache - include semantic code in cracking functions\n"); 1118 printf 1119 ("\t gen-slot-verification - perform slot verification as part of decode\n"); 1120 printf ("\t gen-nia-invalid - NIA defaults to nia_invalid\n"); 1121 printf ("\t gen-nia-void - do not compute/return NIA\n"); 1122 printf ("\n"); 1123 printf 1124 ("\t trace-combine - report combined entries a rule application\n"); 1125 printf 1126 ("\t trace-entries - report entries after a rules application\n"); 1127 printf ("\t trace-rule-rejection - report each rule as rejected\n"); 1128 printf ("\t trace-rule-selection - report each rule as selected\n"); 1129 printf 1130 ("\t trace-insn-insertion - report each instruction as it is inserted into a decode table\n"); 1131 printf 1132 ("\t trace-rule-expansion - report each instruction as it is expanded (before insertion into a decode table)\n"); 1133 printf ("\t trace-all - enable all trace options\n"); 1134 printf ("\n"); 1135 printf 1136 ("\t field-widths - instruction formats specify widths (deprecated)\n"); 1137 printf 1138 ("\t By default, an instruction format specifies bit\n"); 1139 printf ("\t positions\n"); 1140 printf 1141 ("\t This option can now be set directly in the\n"); 1142 printf ("\t instruction table\n"); 1143 printf 1144 ("\t jumps - use jumps instead of function calls\n"); 1145 printf 1146 ("\t omit-line-numbers - do not include line number information in the output\n"); 1147 printf ("\n"); 1148 printf ("Input options:\n"); 1149 printf ("\n"); 1150 printf (" -k <cache-rules> (deprecated)\n"); 1151 printf (" -o <decode-rules>\n"); 1152 printf (" -i <instruction-table>\n"); 1153 printf ("\n"); 1154 printf ("Output options:\n"); 1155 printf ("\n"); 1156 printf (" -x Perform expansion (required)\n"); 1157 printf 1158 (" -n <real-name> Specify the real name of the next output file\n"); 1159 printf 1160 (" -h Generate the header (.h) file rather than the body (.c)\n"); 1161 printf (" -c <output-file> output icache\n"); 1162 printf (" -d <output-file> output idecode\n"); 1163 printf (" -e <output-file> output engine\n"); 1164 printf (" -f <output-file> output support functions\n"); 1165 printf (" -m <output-file> output model\n"); 1166 printf (" -r <output-file> output multi-sim run\n"); 1167 printf (" -s <output-file> output schematic\n"); 1168 printf (" -t <output-file> output itable\n"); 1169 } 1170 1171 while ((ch = getopt_long (argc, argv, 1172 "B:D:F:G:H:I:M:N:P:T:W:o:k:i:n:hc:d:e:m:r:s:t:f:x", 1173 longopts, NULL)) 1174 != -1) 1175 { 1176#if 0 /* For debugging. */ 1177 fprintf (stderr, " -%c ", ch); 1178 if (optarg) 1179 fprintf (stderr, "%s ", optarg); 1180 fprintf (stderr, "\\\n"); 1181#endif 1182 1183 switch (ch) 1184 { 1185 1186 case 'M': 1187 filter_parse (&options.model_filter, optarg); 1188 break; 1189 1190 case 'D': 1191 if (strcmp (optarg, "processor-names")) 1192 { 1193 const char *processor; 1194 for (processor = filter_next (options.model_filter, ""); 1195 processor != NULL; 1196 processor = filter_next (options.model_filter, processor)) 1197 lf_printf (standard_out, "%s\n", processor); 1198 } 1199 else 1200 error (NULL, "Unknown data structure %s, not dumped\n", optarg); 1201 break; 1202 1203 case 'F': 1204 filter_parse (&options.flags_filter, optarg); 1205 break; 1206 1207 case 'I': 1208 { 1209 table_include **dir = &options.include; 1210 while ((*dir) != NULL) 1211 dir = &(*dir)->next; 1212 (*dir) = ZALLOC (table_include); 1213 (*dir)->dir = strdup (optarg); 1214 } 1215 break; 1216 1217 case 'B': 1218 options.insn_bit_size = a2i (optarg); 1219 if (options.insn_bit_size <= 0 1220 || options.insn_bit_size > max_insn_bit_size) 1221 { 1222 error (NULL, "Instruction bitsize must be in range 1..%d\n", 1223 max_insn_bit_size); 1224 } 1225 if (options.hi_bit_nr != options.insn_bit_size - 1 1226 && options.hi_bit_nr != 0) 1227 { 1228 error (NULL, "Conflict betweem hi-bit-nr and insn-bit-size\n"); 1229 } 1230 break; 1231 1232 case 'H': 1233 options.hi_bit_nr = a2i (optarg); 1234 if (options.hi_bit_nr != options.insn_bit_size - 1 1235 && options.hi_bit_nr != 0) 1236 { 1237 error (NULL, "Conflict between hi-bit-nr and insn-bit-size\n"); 1238 } 1239 break; 1240 1241 case 'N': 1242 options.gen.smp = a2i (optarg); 1243 break; 1244 1245 case 'P': 1246 case 'S': 1247 { 1248 igen_module *names; 1249 igen_name *name; 1250 char *chp; 1251 chp = strchr (optarg, '='); 1252 if (chp == NULL) 1253 { 1254 names = &options.module.global; 1255 chp = optarg; 1256 } 1257 else 1258 { 1259 chp = chp + 1; /* skip `=' */ 1260 names = NULL; 1261 if (strncmp (optarg, "global=", chp - optarg) == 0) 1262 { 1263 names = &options.module.global; 1264 } 1265 if (strncmp (optarg, "engine=", chp - optarg) == 0) 1266 { 1267 names = &options.module.engine; 1268 } 1269 if (strncmp (optarg, "icache=", chp - optarg) == 0) 1270 { 1271 names = &options.module.icache; 1272 } 1273 if (strncmp (optarg, "idecode=", chp - optarg) == 0) 1274 { 1275 names = &options.module.idecode; 1276 } 1277 if (strncmp (optarg, "itable=", chp - optarg) == 0) 1278 { 1279 names = &options.module.itable; 1280 } 1281 if (strncmp (optarg, "semantics=", chp - optarg) == 0) 1282 { 1283 names = &options.module.semantics; 1284 } 1285 if (strncmp (optarg, "support=", chp - optarg) == 0) 1286 { 1287 names = &options.module.support; 1288 } 1289 if (names == NULL) 1290 { 1291 error (NULL, "Prefix `%s' unreconized\n", optarg); 1292 } 1293 } 1294 switch (ch) 1295 { 1296 case 'P': 1297 name = &names->prefix; 1298 break; 1299 case 'S': 1300 name = &names->suffix; 1301 break; 1302 default: 1303 abort (); /* Bad switch. */ 1304 } 1305 name->u = strdup (chp); 1306 name->l = strdup (chp); 1307 chp = name->u; 1308 while (*chp) 1309 { 1310 if (islower (*chp)) 1311 *chp = toupper (*chp); 1312 chp++; 1313 } 1314 if (name == &options.module.global.prefix) 1315 { 1316 options.module.engine.prefix = options.module.global.prefix; 1317 options.module.icache.prefix = options.module.global.prefix; 1318 options.module.idecode.prefix = options.module.global.prefix; 1319 /* options.module.itable.prefix = options.module.global.prefix; */ 1320 options.module.semantics.prefix = 1321 options.module.global.prefix; 1322 options.module.support.prefix = options.module.global.prefix; 1323 } 1324 if (name == &options.module.global.suffix) 1325 { 1326 options.module.engine.suffix = options.module.global.suffix; 1327 options.module.icache.suffix = options.module.global.suffix; 1328 options.module.idecode.suffix = options.module.global.suffix; 1329 /* options.module.itable.suffix = options.module.global.suffix; */ 1330 options.module.semantics.suffix = 1331 options.module.global.suffix; 1332 options.module.support.suffix = options.module.global.suffix; 1333 } 1334 break; 1335 } 1336 1337 case 'W': 1338 { 1339 if (strcmp (optarg, "error") == 0) 1340 options.warning = error; 1341 else if (strcmp (optarg, "nodiscard") == 0) 1342 options.warn.discard = 0; 1343 else if (strcmp (optarg, "discard") == 0) 1344 options.warn.discard = 1; 1345 else if (strcmp (optarg, "nowidth") == 0) 1346 options.warn.width = 0; 1347 else if (strcmp (optarg, "width") == 0) 1348 options.warn.width = 1; 1349 else if (strcmp (optarg, "nounimplemented") == 0) 1350 options.warn.unimplemented = 0; 1351 else if (strcmp (optarg, "unimplemented") == 0) 1352 options.warn.unimplemented = 1; 1353 else 1354 error (NULL, "Unknown -W argument `%s'\n", optarg); 1355 break; 1356 } 1357 1358 1359 case 'G': 1360 { 1361 int enable_p; 1362 char *argp; 1363 if (strncmp (optarg, "no-", strlen ("no-")) == 0) 1364 { 1365 argp = optarg + strlen ("no-"); 1366 enable_p = 0; 1367 } 1368 else if (strncmp (optarg, "!", strlen ("!")) == 0) 1369 { 1370 argp = optarg + strlen ("no-"); 1371 enable_p = 0; 1372 } 1373 else 1374 { 1375 argp = optarg; 1376 enable_p = 1; 1377 } 1378 if (strcmp (argp, "decode-duplicate") == 0) 1379 { 1380 options.decode.duplicate = enable_p; 1381 } 1382 else if (strcmp (argp, "decode-combine") == 0) 1383 { 1384 options.decode.combine = enable_p; 1385 } 1386 else if (strcmp (argp, "decode-zero-reserved") == 0) 1387 { 1388 options.decode.zero_reserved = enable_p; 1389 } 1390 1391 else if (strcmp (argp, "gen-conditional-issue") == 0) 1392 { 1393 options.gen.conditional_issue = enable_p; 1394 } 1395 else if (strcmp (argp, "conditional-issue") == 0) 1396 { 1397 options.gen.conditional_issue = enable_p; 1398 options.warning (NULL, 1399 "Option conditional-issue replaced by gen-conditional-issue\n"); 1400 } 1401 else if (strcmp (argp, "gen-delayed-branch") == 0) 1402 { 1403 options.gen.delayed_branch = enable_p; 1404 } 1405 else if (strcmp (argp, "delayed-branch") == 0) 1406 { 1407 options.gen.delayed_branch = enable_p; 1408 options.warning (NULL, 1409 "Option delayed-branch replaced by gen-delayed-branch\n"); 1410 } 1411 else if (strcmp (argp, "gen-direct-access") == 0) 1412 { 1413 options.gen.direct_access = enable_p; 1414 } 1415 else if (strcmp (argp, "direct-access") == 0) 1416 { 1417 options.gen.direct_access = enable_p; 1418 options.warning (NULL, 1419 "Option direct-access replaced by gen-direct-access\n"); 1420 } 1421 else if (strncmp (argp, "gen-zero-r", strlen ("gen-zero-r")) == 0) 1422 { 1423 options.gen.zero_reg = enable_p; 1424 options.gen.zero_reg_nr = atoi (argp + strlen ("gen-zero-r")); 1425 } 1426 else if (strncmp (argp, "zero-r", strlen ("zero-r")) == 0) 1427 { 1428 options.gen.zero_reg = enable_p; 1429 options.gen.zero_reg_nr = atoi (argp + strlen ("zero-r")); 1430 options.warning (NULL, 1431 "Option zero-r<N> replaced by gen-zero-r<N>\n"); 1432 } 1433 else if (strncmp (argp, "gen-icache", strlen ("gen-icache")) == 0) 1434 { 1435 switch (argp[strlen ("gen-icache")]) 1436 { 1437 case '=': 1438 options.gen.icache_size = 1439 atoi (argp + strlen ("gen-icache") + 1); 1440 options.gen.icache = enable_p; 1441 break; 1442 case '\0': 1443 options.gen.icache = enable_p; 1444 break; 1445 default: 1446 error (NULL, 1447 "Expecting -Ggen-icache or -Ggen-icache=<N>\n"); 1448 } 1449 } 1450 else if (strcmp (argp, "gen-insn-in-icache") == 0) 1451 { 1452 options.gen.insn_in_icache = enable_p; 1453 } 1454 else if (strncmp (argp, "gen-multi-sim", strlen ("gen-multi-sim")) 1455 == 0) 1456 { 1457 char *arg = &argp[strlen ("gen-multi-sim")]; 1458 switch (arg[0]) 1459 { 1460 case '=': 1461 options.gen.multi_sim = enable_p; 1462 options.gen.default_model = arg + 1; 1463 if (!filter_is_member 1464 (options.model_filter, options.gen.default_model)) 1465 error (NULL, "multi-sim model %s unknown\n", 1466 options.gen.default_model); 1467 break; 1468 case '\0': 1469 options.gen.multi_sim = enable_p; 1470 options.gen.default_model = NULL; 1471 break; 1472 default: 1473 error (NULL, 1474 "Expecting -Ggen-multi-sim or -Ggen-multi-sim=<MODEL>\n"); 1475 break; 1476 } 1477 } 1478 else if (strcmp (argp, "gen-multi-word") == 0) 1479 { 1480 options.gen.multi_word = enable_p; 1481 } 1482 else if (strcmp (argp, "gen-semantic-icache") == 0) 1483 { 1484 options.gen.semantic_icache = enable_p; 1485 } 1486 else if (strcmp (argp, "gen-slot-verification") == 0) 1487 { 1488 options.gen.slot_verification = enable_p; 1489 } 1490 else if (strcmp (argp, "verify-slot") == 0) 1491 { 1492 options.gen.slot_verification = enable_p; 1493 options.warning (NULL, 1494 "Option verify-slot replaced by gen-slot-verification\n"); 1495 } 1496 else if (strcmp (argp, "gen-nia-invalid") == 0) 1497 { 1498 options.gen.nia = nia_is_invalid; 1499 } 1500 else if (strcmp (argp, "default-nia-minus-one") == 0) 1501 { 1502 options.gen.nia = nia_is_invalid; 1503 options.warning (NULL, 1504 "Option default-nia-minus-one replaced by gen-nia-invalid\n"); 1505 } 1506 else if (strcmp (argp, "gen-nia-void") == 0) 1507 { 1508 options.gen.nia = nia_is_void; 1509 } 1510 else if (strcmp (argp, "trace-all") == 0) 1511 { 1512 memset (&options.trace, enable_p, sizeof (options.trace)); 1513 } 1514 else if (strcmp (argp, "trace-combine") == 0) 1515 { 1516 options.trace.combine = enable_p; 1517 } 1518 else if (strcmp (argp, "trace-entries") == 0) 1519 { 1520 options.trace.entries = enable_p; 1521 } 1522 else if (strcmp (argp, "trace-rule-rejection") == 0) 1523 { 1524 options.trace.rule_rejection = enable_p; 1525 } 1526 else if (strcmp (argp, "trace-rule-selection") == 0) 1527 { 1528 options.trace.rule_selection = enable_p; 1529 } 1530 else if (strcmp (argp, "trace-insn-insertion") == 0) 1531 { 1532 options.trace.insn_insertion = enable_p; 1533 } 1534 else if (strcmp (argp, "trace-insn-expansion") == 0) 1535 { 1536 options.trace.insn_expansion = enable_p; 1537 } 1538 else if (strcmp (argp, "jumps") == 0) 1539 { 1540 options.gen.code = generate_jumps; 1541 } 1542 else if (strcmp (argp, "field-widths") == 0) 1543 { 1544 options.insn_specifying_widths = enable_p; 1545 } 1546 else if (strcmp (argp, "omit-line-numbers") == 0) 1547 { 1548 file_references = lf_omit_references; 1549 } 1550 else 1551 { 1552 error (NULL, "Unknown option %s\n", optarg); 1553 } 1554 break; 1555 } 1556 1557 case 'i': 1558 isa = load_insn_table (optarg, cache_rules); 1559 if (isa->illegal_insn == NULL) 1560 error (NULL, "illegal-instruction missing from insn table\n"); 1561 break; 1562 1563 case 'x': 1564 gen = do_gen (isa, decode_rules); 1565 break; 1566 1567 case 'o': 1568 decode_rules = load_decode_table (optarg); 1569 break; 1570 1571 case 'k': 1572 if (isa != NULL) 1573 error (NULL, "Cache file must appear before the insn file\n"); 1574 cache_rules = load_cache_table (optarg); 1575 break; 1576 1577 case 'n': 1578 real_file_name = strdup (optarg); 1579 break; 1580 1581 case 'h': 1582 is_header = 1; 1583 break; 1584 1585 case 'c': 1586 case 'd': 1587 case 'e': 1588 case 'f': 1589 case 'm': 1590 case 'r': 1591 case 's': 1592 case 't': 1593 { 1594 lf *file = lf_open (optarg, real_file_name, file_references, 1595 (is_header ? lf_is_h : lf_is_c), 1596 argv[0]); 1597 if (gen == NULL && ch != 't' && ch != 'm' && ch != 'f') 1598 { 1599 options.warning (NULL, 1600 "Explicitly generate tables with -x option\n"); 1601 gen = do_gen (isa, decode_rules); 1602 } 1603 lf_print__file_start (file); 1604 switch (ch) 1605 { 1606 case 'm': 1607 if (is_header) 1608 gen_model_h (file, isa); 1609 else 1610 gen_model_c (file, isa); 1611 break; 1612 case 't': 1613 if (is_header) 1614 gen_itable_h (file, isa); 1615 else 1616 gen_itable_c (file, isa); 1617 break; 1618 case 'f': 1619 if (is_header) 1620 gen_support_h (file, isa); 1621 else 1622 gen_support_c (file, isa); 1623 break; 1624 case 'r': 1625 if (is_header) 1626 options.warning (NULL, "-hr option ignored\n"); 1627 else 1628 gen_run_c (file, gen); 1629 break; 1630 case 's': 1631 if (is_header) 1632 gen_semantics_h (file, gen->semantics, isa->max_nr_words); 1633 else 1634 gen_semantics_c (file, gen->semantics, isa->caches); 1635 break; 1636 case 'd': 1637 if (is_header) 1638 gen_idecode_h (file, gen, isa, cache_rules); 1639 else 1640 gen_idecode_c (file, gen, isa, cache_rules); 1641 break; 1642 case 'e': 1643 if (is_header) 1644 gen_engine_h (file, gen, isa, cache_rules); 1645 else 1646 gen_engine_c (file, gen, isa, cache_rules); 1647 break; 1648 case 'c': 1649 if (is_header) 1650 gen_icache_h (file, 1651 gen->semantics, 1652 isa->functions, isa->max_nr_words); 1653 else 1654 gen_icache_c (file, 1655 gen->semantics, isa->functions, cache_rules); 1656 break; 1657 } 1658 lf_print__file_finish (file); 1659 lf_close (file); 1660 is_header = 0; 1661 } 1662 real_file_name = NULL; 1663 break; 1664 default: 1665 ERROR ("Bad switch"); 1666 } 1667 } 1668 return (0); 1669} 1670