1 #include <signal.h> 2 #include "sysdep.h" 3 #include "bfd.h" 4 5 #include "mn10200_sim.h" 6 7 #ifdef NEED_UI_LOOP_HOOK 8 /* How often to run the ui_loop update, when in use */ 9 #define UI_LOOP_POLL_INTERVAL 0x60000 10 11 /* Counter for the ui_loop_hook update */ 12 static long ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL; 13 14 /* Actual hook to call to run through gdb's gui event loop */ 15 extern int (*deprecated_ui_loop_hook) (int); 16 #endif /* NEED_UI_LOOP_HOOK */ 17 18 host_callback *mn10200_callback; 19 int mn10200_debug; 20 static SIM_OPEN_KIND sim_kind; 21 static char *myname; 22 23 static void dispatch PARAMS ((uint32, uint32, int)); 24 static long hash PARAMS ((long)); 25 static void init_system PARAMS ((void)); 26 #define MAX_HASH 127 27 28 struct hash_entry 29 { 30 struct hash_entry *next; 31 long opcode; 32 long mask; 33 struct simops *ops; 34 #ifdef HASH_STAT 35 unsigned long count; 36 #endif 37 }; 38 39 int max_mem = 0; 40 struct hash_entry hash_table[MAX_HASH+1]; 41 42 43 /* This probably doesn't do a very good job at bucket filling, but 44 it's simple... */ 45 static INLINE long 46 hash(insn) 47 long insn; 48 { 49 /* These are one byte insns. */ 50 if ((insn & 0xffffff00) == 0x00) 51 { 52 if ((insn & 0xf0) != 0x80) 53 return ((insn & 0xf0) >> 4) & 0x7f; 54 55 if ((insn & 0xf0) == 0x80 56 && (insn & 0x0c) >> 2 != (insn & 0x03)) 57 return (insn & 0xf0) & 0x7f; 58 59 return (insn & 0xff) & 0x7f; 60 } 61 62 if ((insn & 0xffff0000) == 0) 63 { 64 if ((insn & 0xf000) == 0xd000) 65 return ((insn & 0xfc00) >> 10) & 0x7f; 66 67 if ((insn & 0xf000) == 0xe000) 68 return ((insn & 0xff00) >> 8) & 0x7f; 69 70 if ((insn & 0xf200) == 0xf200) 71 return ((insn & 0xfff0) >> 4) & 0x7f; 72 73 if ((insn & 0xc000) == 0x4000 74 || (insn & 0xf000) == 0x8000) 75 return ((insn & 0xf000) >> 8) & 0x7f; 76 77 if ((insn & 0xf200) == 0xf000) 78 return ((insn & 0xffc0) >> 8) & 0x7f; 79 80 return ((insn & 0xff00) >> 8) & 0x7f; 81 } 82 83 if ((insn & 0xff000000) == 0) 84 { 85 86 if ((insn & 0xf00000) != 0xf00000 87 || (insn & 0xfc0000) == 0xf80000) 88 return ((insn & 0xfc0000) >> 16) & 0x7f; 89 90 if ((insn & 0xff0000) == 0xf50000) 91 return ((insn & 0xfff000) >> 12) & 0x7f; 92 return ((insn & 0xff0000) >> 16) & 0x7f; 93 } 94 95 return ((insn & 0xfff0000) >> 20) & 0x7f; 96 } 97 98 static INLINE void 99 dispatch (insn, extension, length) 100 uint32 insn; 101 uint32 extension; 102 int length; 103 { 104 struct hash_entry *h; 105 106 h = &hash_table[hash(insn)]; 107 108 while ((insn & h->mask) != h->opcode 109 || (length != h->ops->length)) 110 { 111 if (!h->next) 112 { 113 (*mn10200_callback->printf_filtered) (mn10200_callback, 114 "ERROR looking up hash for 0x%x, PC=0x%x\n", insn, PC); 115 exit(1); 116 } 117 h = h->next; 118 } 119 120 121 #ifdef HASH_STAT 122 h->count++; 123 #endif 124 125 /* Now call the right function. */ 126 (h->ops->func)(insn, extension); 127 PC += length; 128 } 129 130 /* FIXME These would more efficient to use than load_mem/store_mem, 131 but need to be changed to use the memory map. */ 132 133 uint32 134 get_word (x) 135 uint8 *x; 136 { 137 uint8 *a = x; 138 return (a[3]<<24) + (a[2]<<16) + (a[1]<<8) + (a[0]); 139 } 140 141 void 142 put_word (addr, data) 143 uint8 *addr; 144 uint32 data; 145 { 146 uint8 *a = addr; 147 a[0] = data & 0xff; 148 a[1] = (data >> 8) & 0xff; 149 a[2] = (data >> 16) & 0xff; 150 a[3] = (data >> 24) & 0xff; 151 } 152 153 void 154 sim_size (power) 155 int power; 156 157 { 158 if (State.mem) 159 free (State.mem); 160 161 max_mem = 1 << power; 162 State.mem = (uint8 *) calloc (1, 1 << power); 163 if (!State.mem) 164 { 165 (*mn10200_callback->printf_filtered) (mn10200_callback, "Allocation of main memory failed.\n"); 166 exit (1); 167 } 168 } 169 170 static void 171 init_system () 172 { 173 if (!State.mem) 174 sim_size(19); 175 } 176 177 int 178 sim_write (sd,addr, buffer, size) 179 SIM_DESC sd; 180 SIM_ADDR addr; 181 unsigned char *buffer; 182 int size; 183 { 184 int i; 185 186 init_system (); 187 188 for (i = 0; i < size; i++) 189 store_byte (addr + i, buffer[i]); 190 191 return size; 192 } 193 194 /* Compare two opcode table entries for qsort. */ 195 static int 196 compare_simops (arg1, arg2) 197 const PTR arg1; 198 const PTR arg2; 199 { 200 unsigned long code1 = ((struct simops *)arg1)->opcode; 201 unsigned long code2 = ((struct simops *)arg2)->opcode; 202 203 if (code1 < code2) 204 return -1; 205 if (code2 < code1) 206 return 1; 207 return 0; 208 } 209 210 SIM_DESC 211 sim_open (kind, cb, abfd, argv) 212 SIM_OPEN_KIND kind; 213 host_callback *cb; 214 struct bfd *abfd; 215 char **argv; 216 { 217 struct simops *s; 218 struct hash_entry *h; 219 char **p; 220 int i; 221 222 mn10200_callback = cb; 223 224 /* Sort the opcode array from smallest opcode to largest. 225 This will generally improve simulator performance as the smaller 226 opcodes are generally preferred to the larger opcodes. */ 227 for (i = 0, s = Simops; s->func; s++, i++) 228 ; 229 qsort (Simops, i, sizeof (Simops[0]), compare_simops); 230 231 sim_kind = kind; 232 myname = argv[0]; 233 234 for (p = argv + 1; *p; ++p) 235 { 236 if (strcmp (*p, "-E") == 0) 237 ++p; /* ignore endian spec */ 238 else 239 #ifdef DEBUG 240 if (strcmp (*p, "-t") == 0) 241 mn10200_debug = DEBUG; 242 else 243 #endif 244 (*mn10200_callback->printf_filtered) (mn10200_callback, "ERROR: unsupported option(s): %s\n",*p); 245 } 246 247 /* put all the opcodes in the hash table */ 248 for (s = Simops; s->func; s++) 249 { 250 h = &hash_table[hash(s->opcode)]; 251 252 /* go to the last entry in the chain */ 253 while (h->next) 254 { 255 /* Don't insert the same opcode more than once. */ 256 if (h->opcode == s->opcode 257 && h->mask == s->mask 258 && h->ops == s) 259 break; 260 else 261 h = h->next; 262 } 263 264 /* Don't insert the same opcode more than once. */ 265 if (h->opcode == s->opcode 266 && h->mask == s->mask 267 && h->ops == s) 268 continue; 269 270 if (h->ops) 271 { 272 h->next = calloc(1,sizeof(struct hash_entry)); 273 h = h->next; 274 } 275 h->ops = s; 276 h->mask = s->mask; 277 h->opcode = s->opcode; 278 #ifdef HASH_STAT 279 h->count = 0; 280 #endif 281 } 282 283 /* fudge our descriptor for now */ 284 return (SIM_DESC) 1; 285 } 286 287 288 void 289 sim_set_profile (n) 290 int n; 291 { 292 (*mn10200_callback->printf_filtered) (mn10200_callback, "sim_set_profile %d\n", n); 293 } 294 295 void 296 sim_set_profile_size (n) 297 int n; 298 { 299 (*mn10200_callback->printf_filtered) (mn10200_callback, "sim_set_profile_size %d\n", n); 300 } 301 302 int 303 sim_stop (sd) 304 SIM_DESC sd; 305 { 306 State.exception = SIGINT; 307 return 1; 308 } 309 310 void 311 sim_resume (sd, step, siggnal) 312 SIM_DESC sd; 313 int step, siggnal; 314 { 315 uint32 inst; 316 317 if (step) 318 State.exception = SIGTRAP; 319 else 320 State.exception = 0; 321 322 State.exited = 0; 323 324 do 325 { 326 unsigned long insn, extension; 327 328 #ifdef NEED_UI_LOOP_HOOK 329 if (deprecated_ui_loop_hook != NULL && ui_loop_hook_counter-- < 0) 330 { 331 ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL; 332 deprecated_ui_loop_hook (0); 333 } 334 #endif /* NEED_UI_LOOP_HOOK */ 335 336 /* Fetch the current instruction, fetch a double word to 337 avoid redundant fetching for the common cases below. */ 338 inst = load_mem_big (PC, 2); 339 340 /* Using a giant case statement may seem like a waste because of the 341 code/rodata size the table itself will consume. However, using 342 a giant case statement speeds up the simulator by 10-15% by avoiding 343 cascading if/else statements or cascading case statements. */ 344 switch ((inst >> 8) & 0xff) 345 { 346 /* All the single byte insns except 0x80, which must 347 be handled specially. */ 348 case 0x00: 349 case 0x01: 350 case 0x02: 351 case 0x03: 352 case 0x04: 353 case 0x05: 354 case 0x06: 355 case 0x07: 356 case 0x08: 357 case 0x09: 358 case 0x0a: 359 case 0x0b: 360 case 0x0c: 361 case 0x0d: 362 case 0x0e: 363 case 0x0f: 364 case 0x10: 365 case 0x11: 366 case 0x12: 367 case 0x13: 368 case 0x14: 369 case 0x15: 370 case 0x16: 371 case 0x17: 372 case 0x18: 373 case 0x19: 374 case 0x1a: 375 case 0x1b: 376 case 0x1c: 377 case 0x1d: 378 case 0x1e: 379 case 0x1f: 380 case 0x20: 381 case 0x21: 382 case 0x22: 383 case 0x23: 384 case 0x24: 385 case 0x25: 386 case 0x26: 387 case 0x27: 388 case 0x28: 389 case 0x29: 390 case 0x2a: 391 case 0x2b: 392 case 0x2c: 393 case 0x2d: 394 case 0x2e: 395 case 0x2f: 396 case 0x30: 397 case 0x31: 398 case 0x32: 399 case 0x33: 400 case 0x34: 401 case 0x35: 402 case 0x36: 403 case 0x37: 404 case 0x38: 405 case 0x39: 406 case 0x3a: 407 case 0x3b: 408 case 0x3c: 409 case 0x3d: 410 case 0x3e: 411 case 0x3f: 412 case 0x90: 413 case 0x91: 414 case 0x92: 415 case 0x93: 416 case 0x94: 417 case 0x95: 418 case 0x96: 419 case 0x97: 420 case 0x98: 421 case 0x99: 422 case 0x9a: 423 case 0x9b: 424 case 0x9c: 425 case 0x9d: 426 case 0x9e: 427 case 0x9f: 428 case 0xa0: 429 case 0xa1: 430 case 0xa2: 431 case 0xa3: 432 case 0xa4: 433 case 0xa5: 434 case 0xa6: 435 case 0xa7: 436 case 0xa8: 437 case 0xa9: 438 case 0xaa: 439 case 0xab: 440 case 0xac: 441 case 0xad: 442 case 0xae: 443 case 0xaf: 444 case 0xb0: 445 case 0xb1: 446 case 0xb2: 447 case 0xb3: 448 case 0xb4: 449 case 0xb5: 450 case 0xb6: 451 case 0xb7: 452 case 0xb8: 453 case 0xb9: 454 case 0xba: 455 case 0xbb: 456 case 0xbc: 457 case 0xbd: 458 case 0xbe: 459 case 0xbf: 460 case 0xeb: 461 case 0xf6: 462 case 0xfe: 463 case 0xff: 464 insn = (inst >> 8) & 0xff; 465 extension = 0; 466 dispatch (insn, extension, 1); 467 break; 468 469 /* Special case as mov dX,dX really means mov imm8,dX. */ 470 case 0x80: 471 case 0x85: 472 case 0x8a: 473 case 0x8f: 474 /* Fetch the full instruction. */ 475 insn = inst; 476 extension = 0; 477 dispatch (insn, extension, 2); 478 break; 479 480 case 0x81: 481 case 0x82: 482 case 0x83: 483 case 0x84: 484 case 0x86: 485 case 0x87: 486 case 0x88: 487 case 0x89: 488 case 0x8b: 489 case 0x8c: 490 case 0x8d: 491 case 0x8e: 492 insn = (inst >> 8) & 0xff; 493 extension = 0; 494 dispatch (insn, extension, 1); 495 break; 496 497 /* And the two byte insns. */ 498 case 0x40: 499 case 0x41: 500 case 0x42: 501 case 0x43: 502 case 0x44: 503 case 0x45: 504 case 0x46: 505 case 0x47: 506 case 0x48: 507 case 0x49: 508 case 0x4a: 509 case 0x4b: 510 case 0x4c: 511 case 0x4d: 512 case 0x4e: 513 case 0x4f: 514 case 0x50: 515 case 0x51: 516 case 0x52: 517 case 0x53: 518 case 0x54: 519 case 0x55: 520 case 0x56: 521 case 0x57: 522 case 0x58: 523 case 0x59: 524 case 0x5a: 525 case 0x5b: 526 case 0x5c: 527 case 0x5d: 528 case 0x5e: 529 case 0x5f: 530 case 0x60: 531 case 0x61: 532 case 0x62: 533 case 0x63: 534 case 0x64: 535 case 0x65: 536 case 0x66: 537 case 0x67: 538 case 0x68: 539 case 0x69: 540 case 0x6a: 541 case 0x6b: 542 case 0x6c: 543 case 0x6d: 544 case 0x6e: 545 case 0x6f: 546 case 0x70: 547 case 0x71: 548 case 0x72: 549 case 0x73: 550 case 0x74: 551 case 0x75: 552 case 0x76: 553 case 0x77: 554 case 0x78: 555 case 0x79: 556 case 0x7a: 557 case 0x7b: 558 case 0x7c: 559 case 0x7d: 560 case 0x7e: 561 case 0x7f: 562 case 0xd0: 563 case 0xd1: 564 case 0xd2: 565 case 0xd3: 566 case 0xd4: 567 case 0xd5: 568 case 0xd6: 569 case 0xd7: 570 case 0xd8: 571 case 0xd9: 572 case 0xda: 573 case 0xdb: 574 case 0xe0: 575 case 0xe1: 576 case 0xe2: 577 case 0xe3: 578 case 0xe4: 579 case 0xe5: 580 case 0xe6: 581 case 0xe7: 582 case 0xe8: 583 case 0xe9: 584 case 0xea: 585 case 0xf0: 586 case 0xf1: 587 case 0xf2: 588 case 0xf3: 589 /* Fetch the full instruction. */ 590 insn = inst; 591 extension = 0; 592 dispatch (insn, extension, 2); 593 break; 594 595 /* And the 3 byte insns with a 16bit operand in little 596 endian format. */ 597 case 0xc0: 598 case 0xc1: 599 case 0xc2: 600 case 0xc3: 601 case 0xc4: 602 case 0xc5: 603 case 0xc6: 604 case 0xc7: 605 case 0xc8: 606 case 0xc9: 607 case 0xca: 608 case 0xcb: 609 case 0xcc: 610 case 0xcd: 611 case 0xce: 612 case 0xcf: 613 case 0xdc: 614 case 0xdd: 615 case 0xde: 616 case 0xdf: 617 case 0xec: 618 case 0xed: 619 case 0xee: 620 case 0xef: 621 case 0xf8: 622 case 0xf9: 623 case 0xfa: 624 case 0xfb: 625 case 0xfc: 626 case 0xfd: 627 insn = load_byte (PC); 628 insn <<= 16; 629 insn |= load_half (PC + 1); 630 extension = 0; 631 dispatch (insn, extension, 3); 632 break; 633 634 /* 3 byte insns without 16bit operand. */ 635 case 0xf5: 636 insn = load_mem_big (PC, 3); 637 extension = 0; 638 dispatch (insn, extension, 3); 639 break; 640 641 /* 4 byte insns. */ 642 case 0xf7: 643 insn = inst; 644 insn <<= 16; 645 insn |= load_half (PC + 2); 646 extension = 0; 647 dispatch (insn, extension, 4); 648 break; 649 650 case 0xf4: 651 insn = inst; 652 insn <<= 16; 653 insn |= load_mem_big (PC + 4, 1) << 8; 654 insn |= load_mem_big (PC + 3, 1); 655 extension = load_mem_big (PC + 2, 1); 656 dispatch (insn, extension, 5); 657 break; 658 659 default: 660 abort (); 661 } 662 } 663 while (!State.exception); 664 665 #ifdef HASH_STAT 666 { 667 int i; 668 for (i = 0; i < MAX_HASH; i++) 669 { 670 struct hash_entry *h; 671 h = &hash_table[i]; 672 673 printf("hash 0x%x:\n", i); 674 675 while (h) 676 { 677 printf("h->opcode = 0x%x, count = 0x%x\n", h->opcode, h->count); 678 h = h->next; 679 } 680 681 printf("\n\n"); 682 } 683 fflush (stdout); 684 } 685 #endif 686 687 } 688 689 690 void 691 sim_close (sd, quitting) 692 SIM_DESC sd; 693 int quitting; 694 { 695 /* nothing to do */ 696 } 697 698 int 699 sim_trace (sd) 700 SIM_DESC sd; 701 { 702 #ifdef DEBUG 703 mn10200_debug = DEBUG; 704 #endif 705 sim_resume (sd, 0, 0); 706 return 1; 707 } 708 709 void 710 sim_info (sd, verbose) 711 SIM_DESC sd; 712 int verbose; 713 { 714 (*mn10200_callback->printf_filtered) (mn10200_callback, "sim_info\n"); 715 } 716 717 SIM_RC 718 sim_create_inferior (sd, abfd, argv, env) 719 SIM_DESC sd; 720 struct bfd *abfd; 721 char **argv; 722 char **env; 723 { 724 if (abfd != NULL) 725 PC = bfd_get_start_address (abfd); 726 else 727 PC = 0; 728 return SIM_RC_OK; 729 } 730 731 void 732 sim_set_callbacks (p) 733 host_callback *p; 734 { 735 mn10200_callback = p; 736 } 737 738 /* All the code for exiting, signals, etc needs to be revamped. 739 740 This is enough to get c-torture limping though. */ 741 742 void 743 sim_stop_reason (sd, reason, sigrc) 744 SIM_DESC sd; 745 enum sim_stop *reason; 746 int *sigrc; 747 { 748 if (State.exited) 749 *reason = sim_exited; 750 else 751 *reason = sim_stopped; 752 if (State.exception == SIGQUIT) 753 *sigrc = 0; 754 else 755 *sigrc = State.exception; 756 } 757 758 int 759 sim_fetch_register (sd, rn, memory, length) 760 SIM_DESC sd; 761 int rn; 762 unsigned char *memory; 763 int length; 764 { 765 put_word (memory, State.regs[rn]); 766 return -1; 767 } 768 769 int 770 sim_store_register (sd, rn, memory, length) 771 SIM_DESC sd; 772 int rn; 773 unsigned char *memory; 774 int length; 775 { 776 State.regs[rn] = get_word (memory); 777 return -1; 778 } 779 780 int 781 sim_read (sd, addr, buffer, size) 782 SIM_DESC sd; 783 SIM_ADDR addr; 784 unsigned char *buffer; 785 int size; 786 { 787 int i; 788 for (i = 0; i < size; i++) 789 buffer[i] = load_byte (addr + i); 790 791 return size; 792 } 793 794 void 795 sim_do_command (sd, cmd) 796 SIM_DESC sd; 797 char *cmd; 798 { 799 (*mn10200_callback->printf_filtered) (mn10200_callback, "\"%s\" is not a valid mn10200 simulator command.\n", cmd); 800 } 801 802 SIM_RC 803 sim_load (sd, prog, abfd, from_tty) 804 SIM_DESC sd; 805 char *prog; 806 bfd *abfd; 807 int from_tty; 808 { 809 extern bfd *sim_load_file (); /* ??? Don't know where this should live. */ 810 bfd *prog_bfd; 811 812 prog_bfd = sim_load_file (sd, myname, mn10200_callback, prog, abfd, 813 sim_kind == SIM_OPEN_DEBUG, 814 0, sim_write); 815 if (prog_bfd == NULL) 816 return SIM_RC_FAIL; 817 if (abfd == NULL) 818 bfd_close (prog_bfd); 819 return SIM_RC_OK; 820 } 821