1/* SH5 simulator support code 2 Copyright (C) 2000, 2001, 2006 Free Software Foundation, Inc. 3 Contributed by Red Hat, Inc. 4 5This file is part of the GNU simulators. 6 7This program is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 3 of the License, or 10(at your option) any later version. 11 12This program is distributed in the hope that it will be useful, 13but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15GNU General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20#define WANT_CPU 21#define WANT_CPU_SH64 22 23#include "sim-main.h" 24#include "sim-fpu.h" 25#include "cgen-mem.h" 26#include "cgen-ops.h" 27 28#include "gdb/callback.h" 29#include "defs-compact.h" 30 31#include "bfd.h" 32/* From include/gdb/. */ 33#include "gdb/sim-sh.h" 34 35#define SYS_exit 1 36#define SYS_read 3 37#define SYS_write 4 38#define SYS_open 5 39#define SYS_close 6 40#define SYS_lseek 19 41#define SYS_time 23 42#define SYS_argc 172 43#define SYS_argnlen 173 44#define SYS_argn 174 45 46IDESC * sh64_idesc_media; 47IDESC * sh64_idesc_compact; 48 49BI 50sh64_endian (SIM_CPU *current_cpu) 51{ 52 return (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN); 53} 54 55SF 56sh64_fldi0 (SIM_CPU *current_cpu) 57{ 58 SF result; 59 sim_fpu_to32 (&result, &sim_fpu_zero); 60 return result; 61} 62 63SF 64sh64_fldi1 (SIM_CPU *current_cpu) 65{ 66 SF result; 67 sim_fpu_to32 (&result, &sim_fpu_one); 68 return result; 69} 70 71DF 72sh64_fabsd(SIM_CPU *current_cpu, DF drgh) 73{ 74 DF result; 75 sim_fpu f, fres; 76 77 sim_fpu_64to (&f, drgh); 78 sim_fpu_abs (&fres, &f); 79 sim_fpu_to64 (&result, &fres); 80 return result; 81} 82 83SF 84sh64_fabss(SIM_CPU *current_cpu, SF frgh) 85{ 86 SF result; 87 sim_fpu f, fres; 88 89 sim_fpu_32to (&f, frgh); 90 sim_fpu_abs (&fres, &f); 91 sim_fpu_to32 (&result, &fres); 92 return result; 93} 94 95DF 96sh64_faddd(SIM_CPU *current_cpu, DF drg, DF drh) 97{ 98 DF result; 99 sim_fpu f1, f2, fres; 100 101 sim_fpu_64to (&f1, drg); 102 sim_fpu_64to (&f2, drh); 103 sim_fpu_add (&fres, &f1, &f2); 104 sim_fpu_to64 (&result, &fres); 105 return result; 106} 107 108SF 109sh64_fadds(SIM_CPU *current_cpu, SF frg, SF frh) 110{ 111 SF result; 112 sim_fpu f1, f2, fres; 113 114 sim_fpu_32to (&f1, frg); 115 sim_fpu_32to (&f2, frh); 116 sim_fpu_add (&fres, &f1, &f2); 117 sim_fpu_to32 (&result, &fres); 118 return result; 119} 120 121BI 122sh64_fcmpeqd(SIM_CPU *current_cpu, DF drg, DF drh) 123{ 124 sim_fpu f1, f2; 125 126 sim_fpu_64to (&f1, drg); 127 sim_fpu_64to (&f2, drh); 128 return sim_fpu_is_eq (&f1, &f2); 129} 130 131BI 132sh64_fcmpeqs(SIM_CPU *current_cpu, SF frg, SF frh) 133{ 134 sim_fpu f1, f2; 135 136 sim_fpu_32to (&f1, frg); 137 sim_fpu_32to (&f2, frh); 138 return sim_fpu_is_eq (&f1, &f2); 139} 140 141BI 142sh64_fcmpged(SIM_CPU *current_cpu, DF drg, DF drh) 143{ 144 sim_fpu f1, f2; 145 146 sim_fpu_64to (&f1, drg); 147 sim_fpu_64to (&f2, drh); 148 return sim_fpu_is_ge (&f1, &f2); 149} 150 151BI 152sh64_fcmpges(SIM_CPU *current_cpu, SF frg, SF frh) 153{ 154 sim_fpu f1, f2; 155 156 sim_fpu_32to (&f1, frg); 157 sim_fpu_32to (&f2, frh); 158 return sim_fpu_is_ge (&f1, &f2); 159} 160 161BI 162sh64_fcmpgtd(SIM_CPU *current_cpu, DF drg, DF drh) 163{ 164 sim_fpu f1, f2; 165 166 sim_fpu_64to (&f1, drg); 167 sim_fpu_64to (&f2, drh); 168 return sim_fpu_is_gt (&f1, &f2); 169} 170 171BI 172sh64_fcmpgts(SIM_CPU *current_cpu, SF frg, SF frh) 173{ 174 sim_fpu f1, f2; 175 176 sim_fpu_32to (&f1, frg); 177 sim_fpu_32to (&f2, frh); 178 return sim_fpu_is_gt (&f1, &f2); 179} 180 181BI 182sh64_fcmpund(SIM_CPU *current_cpu, DF drg, DF drh) 183{ 184 sim_fpu f1, f2; 185 186 sim_fpu_64to (&f1, drg); 187 sim_fpu_64to (&f2, drh); 188 return (sim_fpu_is_nan (&f1) || sim_fpu_is_nan (&f2)); 189} 190 191BI 192sh64_fcmpuns(SIM_CPU *current_cpu, SF frg, SF frh) 193{ 194 sim_fpu f1, f2; 195 196 sim_fpu_32to (&f1, frg); 197 sim_fpu_32to (&f2, frh); 198 return (sim_fpu_is_nan (&f1) || sim_fpu_is_nan (&f2)); 199} 200 201SF 202sh64_fcnvds(SIM_CPU *current_cpu, DF drgh) 203{ 204 union { 205 unsigned long long ll; 206 double d; 207 } f1; 208 209 union { 210 unsigned long l; 211 float f; 212 } f2; 213 214 f1.ll = drgh; 215 f2.f = (float) f1.d; 216 217 return (SF) f2.l; 218} 219 220DF 221sh64_fcnvsd(SIM_CPU *current_cpu, SF frgh) 222{ 223 DF result; 224 sim_fpu f; 225 226 sim_fpu_32to (&f, frgh); 227 sim_fpu_to64 (&result, &f); 228 return result; 229} 230 231DF 232sh64_fdivd(SIM_CPU *current_cpu, DF drg, DF drh) 233{ 234 DF result; 235 sim_fpu f1, f2, fres; 236 237 sim_fpu_64to (&f1, drg); 238 sim_fpu_64to (&f2, drh); 239 sim_fpu_div (&fres, &f1, &f2); 240 sim_fpu_to64 (&result, &fres); 241 return result; 242} 243 244SF 245sh64_fdivs(SIM_CPU *current_cpu, SF frg, SF frh) 246{ 247 SF result; 248 sim_fpu f1, f2, fres; 249 250 sim_fpu_32to (&f1, frg); 251 sim_fpu_32to (&f2, frh); 252 sim_fpu_div (&fres, &f1, &f2); 253 sim_fpu_to32 (&result, &fres); 254 return result; 255} 256 257DF 258sh64_floatld(SIM_CPU *current_cpu, SF frgh) 259{ 260 DF result; 261 sim_fpu f; 262 263 sim_fpu_i32to (&f, frgh, sim_fpu_round_default); 264 sim_fpu_to64 (&result, &f); 265 return result; 266} 267 268SF 269sh64_floatls(SIM_CPU *current_cpu, SF frgh) 270{ 271 SF result; 272 sim_fpu f; 273 274 sim_fpu_i32to (&f, frgh, sim_fpu_round_default); 275 sim_fpu_to32 (&result, &f); 276 return result; 277} 278 279DF 280sh64_floatqd(SIM_CPU *current_cpu, DF drgh) 281{ 282 DF result; 283 sim_fpu f; 284 285 sim_fpu_i64to (&f, drgh, sim_fpu_round_default); 286 sim_fpu_to64 (&result, &f); 287 return result; 288} 289 290SF 291sh64_floatqs(SIM_CPU *current_cpu, DF drgh) 292{ 293 SF result; 294 sim_fpu f; 295 296 sim_fpu_i64to (&f, drgh, sim_fpu_round_default); 297 sim_fpu_to32 (&result, &f); 298 return result; 299} 300 301SF 302sh64_fmacs(SIM_CPU *current_cpu, SF fr0, SF frm, SF frn) 303{ 304 SF result; 305 sim_fpu m1, m2, a1, fres; 306 307 sim_fpu_32to (&m1, fr0); 308 sim_fpu_32to (&m2, frm); 309 sim_fpu_32to (&a1, frn); 310 311 sim_fpu_mul (&fres, &m1, &m2); 312 sim_fpu_add (&fres, &fres, &a1); 313 314 sim_fpu_to32 (&result, &fres); 315 return result; 316} 317 318DF 319sh64_fmuld(SIM_CPU *current_cpu, DF drg, DF drh) 320{ 321 DF result; 322 sim_fpu f1, f2, fres; 323 324 sim_fpu_64to (&f1, drg); 325 sim_fpu_64to (&f2, drh); 326 sim_fpu_mul (&fres, &f1, &f2); 327 sim_fpu_to64 (&result, &fres); 328 return result; 329} 330 331SF 332sh64_fmuls(SIM_CPU *current_cpu, SF frg, SF frh) 333{ 334 SF result; 335 sim_fpu f1, f2, fres; 336 337 sim_fpu_32to (&f1, frg); 338 sim_fpu_32to (&f2, frh); 339 sim_fpu_mul (&fres, &f1, &f2); 340 sim_fpu_to32 (&result, &fres); 341 return result; 342} 343 344DF 345sh64_fnegd(SIM_CPU *current_cpu, DF drgh) 346{ 347 DF result; 348 sim_fpu f1, f2; 349 350 sim_fpu_64to (&f1, drgh); 351 sim_fpu_neg (&f2, &f1); 352 sim_fpu_to64 (&result, &f2); 353 return result; 354} 355 356SF 357sh64_fnegs(SIM_CPU *current_cpu, SF frgh) 358{ 359 SF result; 360 sim_fpu f, fres; 361 362 sim_fpu_32to (&f, frgh); 363 sim_fpu_neg (&fres, &f); 364 sim_fpu_to32 (&result, &fres); 365 return result; 366} 367 368DF 369sh64_fsqrtd(SIM_CPU *current_cpu, DF drgh) 370{ 371 DF result; 372 sim_fpu f, fres; 373 374 sim_fpu_64to (&f, drgh); 375 sim_fpu_sqrt (&fres, &f); 376 sim_fpu_to64 (&result, &fres); 377 return result; 378} 379 380SF 381sh64_fsqrts(SIM_CPU *current_cpu, SF frgh) 382{ 383 SF result; 384 sim_fpu f, fres; 385 386 sim_fpu_32to (&f, frgh); 387 sim_fpu_sqrt (&fres, &f); 388 sim_fpu_to32 (&result, &fres); 389 return result; 390} 391 392DF 393sh64_fsubd(SIM_CPU *current_cpu, DF drg, DF drh) 394{ 395 DF result; 396 sim_fpu f1, f2, fres; 397 398 sim_fpu_64to (&f1, drg); 399 sim_fpu_64to (&f2, drh); 400 sim_fpu_sub (&fres, &f1, &f2); 401 sim_fpu_to64 (&result, &fres); 402 return result; 403} 404 405SF 406sh64_fsubs(SIM_CPU *current_cpu, SF frg, SF frh) 407{ 408 SF result; 409 sim_fpu f1, f2, fres; 410 411 sim_fpu_32to (&f1, frg); 412 sim_fpu_32to (&f2, frh); 413 sim_fpu_sub (&fres, &f1, &f2); 414 sim_fpu_to32 (&result, &fres); 415 return result; 416} 417 418SF 419sh64_ftrcdl(SIM_CPU *current_cpu, DF drgh) 420{ 421 SI result; 422 sim_fpu f; 423 424 sim_fpu_64to (&f, drgh); 425 sim_fpu_to32i (&result, &f, sim_fpu_round_zero); 426 return (SF) result; 427} 428 429SF 430sh64_ftrcsl(SIM_CPU *current_cpu, SF frgh) 431{ 432 SI result; 433 sim_fpu f; 434 435 sim_fpu_32to (&f, frgh); 436 sim_fpu_to32i (&result, &f, sim_fpu_round_zero); 437 return (SF) result; 438} 439 440DF 441sh64_ftrcdq(SIM_CPU *current_cpu, DF drgh) 442{ 443 DI result; 444 sim_fpu f; 445 446 sim_fpu_64to (&f, drgh); 447 sim_fpu_to64i (&result, &f, sim_fpu_round_zero); 448 return (DF) result; 449} 450 451DF 452sh64_ftrcsq(SIM_CPU *current_cpu, SF frgh) 453{ 454 DI result; 455 sim_fpu f; 456 457 sim_fpu_32to (&f, frgh); 458 sim_fpu_to64i (&result, &f, sim_fpu_round_zero); 459 return (DF) result; 460} 461 462VOID 463sh64_ftrvs(SIM_CPU *cpu, unsigned g, unsigned h, unsigned f) 464{ 465 int i, j; 466 467 for (i = 0; i < 4; i++) 468 { 469 SF result; 470 sim_fpu sum; 471 sim_fpu_32to (&sum, 0); 472 473 for (j = 0; j < 4; j++) 474 { 475 sim_fpu f1, f2, temp; 476 sim_fpu_32to (&f1, sh64_h_fr_get (cpu, (g + i) + (j * 4))); 477 sim_fpu_32to (&f2, sh64_h_fr_get (cpu, h + j)); 478 sim_fpu_mul (&temp, &f1, &f2); 479 sim_fpu_add (&sum, &sum, &temp); 480 } 481 sim_fpu_to32 (&result, &sum); 482 sh64_h_fr_set (cpu, f + i, result); 483 } 484} 485 486VOID 487sh64_fipr (SIM_CPU *cpu, unsigned m, unsigned n) 488{ 489 SF result = sh64_fmuls (cpu, sh64_h_fvc_get (cpu, m), sh64_h_fvc_get (cpu, n)); 490 result = sh64_fadds (cpu, result, sh64_fmuls (cpu, sh64_h_frc_get (cpu, m + 1), sh64_h_frc_get (cpu, n + 1))); 491 result = sh64_fadds (cpu, result, sh64_fmuls (cpu, sh64_h_frc_get (cpu, m + 2), sh64_h_frc_get (cpu, n + 2))); 492 result = sh64_fadds (cpu, result, sh64_fmuls (cpu, sh64_h_frc_get (cpu, m + 3), sh64_h_frc_get (cpu, n + 3))); 493 sh64_h_frc_set (cpu, n + 3, result); 494} 495 496SF 497sh64_fiprs (SIM_CPU *cpu, unsigned g, unsigned h) 498{ 499 SF temp = sh64_fmuls (cpu, sh64_h_fr_get (cpu, g), sh64_h_fr_get (cpu, h)); 500 temp = sh64_fadds (cpu, temp, sh64_fmuls (cpu, sh64_h_fr_get (cpu, g + 1), sh64_h_fr_get (cpu, h + 1))); 501 temp = sh64_fadds (cpu, temp, sh64_fmuls (cpu, sh64_h_fr_get (cpu, g + 2), sh64_h_fr_get (cpu, h + 2))); 502 temp = sh64_fadds (cpu, temp, sh64_fmuls (cpu, sh64_h_fr_get (cpu, g + 3), sh64_h_fr_get (cpu, h + 3))); 503 return temp; 504} 505 506VOID 507sh64_fldp (SIM_CPU *cpu, PCADDR pc, DI rm, DI rn, unsigned f) 508{ 509 sh64_h_fr_set (cpu, f, GETMEMSF (cpu, pc, rm + rn)); 510 sh64_h_fr_set (cpu, f + 1, GETMEMSF (cpu, pc, rm + rn + 4)); 511} 512 513VOID 514sh64_fstp (SIM_CPU *cpu, PCADDR pc, DI rm, DI rn, unsigned f) 515{ 516 SETMEMSF (cpu, pc, rm + rn, sh64_h_fr_get (cpu, f)); 517 SETMEMSF (cpu, pc, rm + rn + 4, sh64_h_fr_get (cpu, f + 1)); 518} 519 520VOID 521sh64_ftrv (SIM_CPU *cpu, UINT ignored) 522{ 523 /* TODO: Unimplemented. */ 524} 525 526VOID 527sh64_pref (SIM_CPU *cpu, SI addr) 528{ 529 /* TODO: Unimplemented. */ 530} 531 532/* Count the number of arguments. */ 533static int 534count_argc (cpu) 535 SIM_CPU *cpu; 536{ 537 int i = 0; 538 539 if (! STATE_PROG_ARGV (CPU_STATE (cpu))) 540 return -1; 541 542 while (STATE_PROG_ARGV (CPU_STATE (cpu)) [i] != NULL) 543 ++i; 544 545 return i; 546} 547 548/* Read a null terminated string from memory, return in a buffer */ 549static char * 550fetch_str (current_cpu, pc, addr) 551 SIM_CPU *current_cpu; 552 PCADDR pc; 553 DI addr; 554{ 555 char *buf; 556 int nr = 0; 557 while (sim_core_read_1 (current_cpu, 558 pc, read_map, addr + nr) != 0) 559 nr++; 560 buf = NZALLOC (char, nr + 1); 561 sim_read (CPU_STATE (current_cpu), addr, buf, nr); 562 return buf; 563} 564 565static void 566trap_handler (SIM_CPU *current_cpu, int shmedia_abi_p, UQI trapnum, PCADDR pc) 567{ 568 char ch; 569 switch (trapnum) 570 { 571 case 1: 572 ch = GET_H_GRC (0); 573 sim_io_write_stdout (CPU_STATE (current_cpu), &ch, 1); 574 fflush (stdout); 575 break; 576 case 2: 577 sim_engine_halt (CPU_STATE (current_cpu), current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP); 578 break; 579 case 34: 580 { 581 int i; 582 int ret_reg = (shmedia_abi_p) ? 2 : 0; 583 char *buf; 584 DI PARM1 = GET_H_GR ((shmedia_abi_p) ? 3 : 5); 585 DI PARM2 = GET_H_GR ((shmedia_abi_p) ? 4 : 6); 586 DI PARM3 = GET_H_GR ((shmedia_abi_p) ? 5 : 7); 587 588 switch (GET_H_GR ((shmedia_abi_p) ? 2 : 4)) 589 { 590 case SYS_write: 591 buf = zalloc (PARM3); 592 sim_read (CPU_STATE (current_cpu), PARM2, buf, PARM3); 593 SET_H_GR (ret_reg, 594 sim_io_write (CPU_STATE (current_cpu), 595 PARM1, buf, PARM3)); 596 zfree (buf); 597 break; 598 599 case SYS_lseek: 600 SET_H_GR (ret_reg, 601 sim_io_lseek (CPU_STATE (current_cpu), 602 PARM1, PARM2, PARM3)); 603 break; 604 605 case SYS_exit: 606 sim_engine_halt (CPU_STATE (current_cpu), current_cpu, 607 NULL, pc, sim_exited, PARM1); 608 break; 609 610 case SYS_read: 611 buf = zalloc (PARM3); 612 SET_H_GR (ret_reg, 613 sim_io_read (CPU_STATE (current_cpu), 614 PARM1, buf, PARM3)); 615 sim_write (CPU_STATE (current_cpu), PARM2, buf, PARM3); 616 zfree (buf); 617 break; 618 619 case SYS_open: 620 buf = fetch_str (current_cpu, pc, PARM1); 621 SET_H_GR (ret_reg, 622 sim_io_open (CPU_STATE (current_cpu), 623 buf, PARM2)); 624 zfree (buf); 625 break; 626 627 case SYS_close: 628 SET_H_GR (ret_reg, 629 sim_io_close (CPU_STATE (current_cpu), PARM1)); 630 break; 631 632 case SYS_time: 633 SET_H_GR (ret_reg, time (0)); 634 break; 635 636 case SYS_argc: 637 SET_H_GR (ret_reg, count_argc (current_cpu)); 638 break; 639 640 case SYS_argnlen: 641 if (PARM1 < count_argc (current_cpu)) 642 SET_H_GR (ret_reg, 643 strlen (STATE_PROG_ARGV (CPU_STATE (current_cpu)) [PARM1])); 644 else 645 SET_H_GR (ret_reg, -1); 646 break; 647 648 case SYS_argn: 649 if (PARM1 < count_argc (current_cpu)) 650 { 651 /* Include the NULL byte. */ 652 i = strlen (STATE_PROG_ARGV (CPU_STATE (current_cpu)) [PARM1]) + 1; 653 sim_write (CPU_STATE (current_cpu), 654 PARM2, 655 STATE_PROG_ARGV (CPU_STATE (current_cpu)) [PARM1], 656 i); 657 658 /* Just for good measure. */ 659 SET_H_GR (ret_reg, i); 660 break; 661 } 662 else 663 SET_H_GR (ret_reg, -1); 664 break; 665 666 default: 667 SET_H_GR (ret_reg, -1); 668 } 669 } 670 break; 671 case 253: 672 puts ("pass"); 673 exit (0); 674 case 254: 675 puts ("fail"); 676 exit (1); 677 case 0xc3: 678 /* fall through. */ 679 case 255: 680 sim_engine_halt (CPU_STATE (current_cpu), current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP); 681 break; 682 } 683} 684 685void 686sh64_trapa (SIM_CPU *current_cpu, DI rm, PCADDR pc) 687{ 688 trap_handler (current_cpu, 1, (UQI) rm & 0xff, pc); 689} 690 691void 692sh64_compact_trapa (SIM_CPU *current_cpu, UQI trapnum, PCADDR pc) 693{ 694 int mach_sh5_p; 695 696 /* If this is an SH5 executable, this is SHcompact code running in 697 the SHmedia ABI. */ 698 699 mach_sh5_p = 700 (bfd_get_mach (STATE_PROG_BFD (CPU_STATE (current_cpu))) == bfd_mach_sh5); 701 702 trap_handler (current_cpu, mach_sh5_p, trapnum, pc); 703} 704 705DI 706sh64_nsb (SIM_CPU *current_cpu, DI rm) 707{ 708 int result = 0, count; 709 UDI source = (UDI) rm; 710 711 if ((source >> 63)) 712 source = ~source; 713 source <<= 1; 714 715 for (count = 32; count; count >>= 1) 716 { 717 UDI newval = source << count; 718 719 if ((newval >> count) == source) 720 { 721 result |= count; 722 source = newval; 723 } 724 } 725 726 return result; 727} 728 729void 730sh64_break (SIM_CPU *current_cpu, PCADDR pc) 731{ 732 SIM_DESC sd = CPU_STATE (current_cpu); 733 sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP); 734} 735 736SI 737sh64_movua (SIM_CPU *current_cpu, PCADDR pc, SI rn) 738{ 739 SI v; 740 int i; 741 742 /* Move the data one byte at a time to avoid alignment problems. 743 Be aware of endianness. */ 744 v = 0; 745 for (i = 0; i < 4; ++i) 746 v = (v << 8) | (GETMEMQI (current_cpu, pc, rn + i) & 0xff); 747 748 v = T2H_4 (v); 749 return v; 750} 751 752void 753set_isa (SIM_CPU *current_cpu, int mode) 754{ 755 /* Do nothing. */ 756} 757 758/* The semantic code invokes this for invalid (unrecognized) instructions. */ 759 760SEM_PC 761sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc) 762{ 763 SIM_DESC sd = CPU_STATE (current_cpu); 764 sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL); 765 766 return vpc; 767} 768 769 770/* Process an address exception. */ 771 772void 773sh64_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia, 774 unsigned int map, int nr_bytes, address_word addr, 775 transfer_type transfer, sim_core_signals sig) 776{ 777 sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr, 778 transfer, sig); 779} 780 781 782/* Initialize cycle counting for an insn. 783 FIRST_P is non-zero if this is the first insn in a set of parallel 784 insns. */ 785 786void 787sh64_compact_model_insn_before (SIM_CPU *cpu, int first_p) 788{ 789 /* Do nothing. */ 790} 791 792void 793sh64_media_model_insn_before (SIM_CPU *cpu, int first_p) 794{ 795 /* Do nothing. */ 796} 797 798/* Record the cycles computed for an insn. 799 LAST_P is non-zero if this is the last insn in a set of parallel insns, 800 and we update the total cycle count. 801 CYCLES is the cycle count of the insn. */ 802 803void 804sh64_compact_model_insn_after(SIM_CPU *cpu, int last_p, int cycles) 805{ 806 /* Do nothing. */ 807} 808 809void 810sh64_media_model_insn_after(SIM_CPU *cpu, int last_p, int cycles) 811{ 812 /* Do nothing. */ 813} 814 815int 816sh64_fetch_register (SIM_CPU *cpu, int nr, unsigned char *buf, int len) 817{ 818 /* Fetch general purpose registers. */ 819 if (nr >= SIM_SH64_R0_REGNUM 820 && nr < (SIM_SH64_R0_REGNUM + SIM_SH64_NR_R_REGS) 821 && len == 8) 822 { 823 *((unsigned64*) buf) = 824 H2T_8 (sh64_h_gr_get (cpu, nr - SIM_SH64_R0_REGNUM)); 825 return len; 826 } 827 828 /* Fetch PC. */ 829 if (nr == SIM_SH64_PC_REGNUM && len == 8) 830 { 831 *((unsigned64*) buf) = H2T_8 (sh64_h_pc_get (cpu) | sh64_h_ism_get (cpu)); 832 return len; 833 } 834 835 /* Fetch status register (SR). */ 836 if (nr == SIM_SH64_SR_REGNUM && len == 8) 837 { 838 *((unsigned64*) buf) = H2T_8 (sh64_h_sr_get (cpu)); 839 return len; 840 } 841 842 /* Fetch saved status register (SSR) and PC (SPC). */ 843 if ((nr == SIM_SH64_SSR_REGNUM || nr == SIM_SH64_SPC_REGNUM) 844 && len == 8) 845 { 846 *((unsigned64*) buf) = 0; 847 return len; 848 } 849 850 /* Fetch target registers. */ 851 if (nr >= SIM_SH64_TR0_REGNUM 852 && nr < (SIM_SH64_TR0_REGNUM + SIM_SH64_NR_TR_REGS) 853 && len == 8) 854 { 855 *((unsigned64*) buf) = 856 H2T_8 (sh64_h_tr_get (cpu, nr - SIM_SH64_TR0_REGNUM)); 857 return len; 858 } 859 860 /* Fetch floating point registers. */ 861 if (nr >= SIM_SH64_FR0_REGNUM 862 && nr < (SIM_SH64_FR0_REGNUM + SIM_SH64_NR_FP_REGS) 863 && len == 4) 864 { 865 *((unsigned32*) buf) = 866 H2T_4 (sh64_h_fr_get (cpu, nr - SIM_SH64_FR0_REGNUM)); 867 return len; 868 } 869 870 /* We should never get here. */ 871 return 0; 872} 873 874int 875sh64_store_register (SIM_CPU *cpu, int nr, unsigned char *buf, int len) 876{ 877 /* Store general purpose registers. */ 878 if (nr >= SIM_SH64_R0_REGNUM 879 && nr < (SIM_SH64_R0_REGNUM + SIM_SH64_NR_R_REGS) 880 && len == 8) 881 { 882 sh64_h_gr_set (cpu, nr - SIM_SH64_R0_REGNUM, T2H_8 (*((unsigned64*)buf))); 883 return len; 884 } 885 886 /* Store PC. */ 887 if (nr == SIM_SH64_PC_REGNUM && len == 8) 888 { 889 unsigned64 new_pc = T2H_8 (*((unsigned64*)buf)); 890 sh64_h_pc_set (cpu, new_pc); 891 return len; 892 } 893 894 /* Store status register (SR). */ 895 if (nr == SIM_SH64_SR_REGNUM && len == 8) 896 { 897 sh64_h_sr_set (cpu, T2H_8 (*((unsigned64*)buf))); 898 return len; 899 } 900 901 /* Store saved status register (SSR) and PC (SPC). */ 902 if (nr == SIM_SH64_SSR_REGNUM || nr == SIM_SH64_SPC_REGNUM) 903 { 904 /* Do nothing. */ 905 return len; 906 } 907 908 /* Store target registers. */ 909 if (nr >= SIM_SH64_TR0_REGNUM 910 && nr < (SIM_SH64_TR0_REGNUM + SIM_SH64_NR_TR_REGS) 911 && len == 8) 912 { 913 sh64_h_tr_set (cpu, nr - SIM_SH64_TR0_REGNUM, T2H_8 (*((unsigned64*)buf))); 914 return len; 915 } 916 917 /* Store floating point registers. */ 918 if (nr >= SIM_SH64_FR0_REGNUM 919 && nr < (SIM_SH64_FR0_REGNUM + SIM_SH64_NR_FP_REGS) 920 && len == 4) 921 { 922 sh64_h_fr_set (cpu, nr - SIM_SH64_FR0_REGNUM, T2H_4 (*((unsigned32*)buf))); 923 return len; 924 } 925 926 /* We should never get here. */ 927 return 0; 928} 929 930void 931sh64_engine_run_full(SIM_CPU *cpu) 932{ 933 if (sh64_h_ism_get (cpu) == ISM_MEDIA) 934 { 935 if (!sh64_idesc_media) 936 { 937 sh64_media_init_idesc_table (cpu); 938 sh64_idesc_media = CPU_IDESC (cpu); 939 } 940 else 941 CPU_IDESC (cpu) = sh64_idesc_media; 942 sh64_media_engine_run_full (cpu); 943 } 944 else 945 { 946 if (!sh64_idesc_compact) 947 { 948 sh64_compact_init_idesc_table (cpu); 949 sh64_idesc_compact = CPU_IDESC (cpu); 950 } 951 else 952 CPU_IDESC (cpu) = sh64_idesc_compact; 953 sh64_compact_engine_run_full (cpu); 954 } 955} 956 957void 958sh64_engine_run_fast (SIM_CPU *cpu) 959{ 960 if (sh64_h_ism_get (cpu) == ISM_MEDIA) 961 { 962 if (!sh64_idesc_media) 963 { 964 sh64_media_init_idesc_table (cpu); 965 sh64_idesc_media = CPU_IDESC (cpu); 966 } 967 else 968 CPU_IDESC (cpu) = sh64_idesc_media; 969 sh64_media_engine_run_fast (cpu); 970 } 971 else 972 { 973 if (!sh64_idesc_compact) 974 { 975 sh64_compact_init_idesc_table (cpu); 976 sh64_idesc_compact = CPU_IDESC (cpu); 977 } 978 else 979 CPU_IDESC (cpu) = sh64_idesc_compact; 980 sh64_compact_engine_run_fast (cpu); 981 } 982} 983 984static void 985sh64_prepare_run (SIM_CPU *cpu) 986{ 987 /* Nothing. */ 988} 989 990static const CGEN_INSN * 991sh64_get_idata (SIM_CPU *cpu, int inum) 992{ 993 return CPU_IDESC (cpu) [inum].idata; 994} 995 996static void 997sh64_init_cpu (SIM_CPU *cpu) 998{ 999 CPU_REG_FETCH (cpu) = sh64_fetch_register; 1000 CPU_REG_STORE (cpu) = sh64_store_register; 1001 CPU_PC_FETCH (cpu) = sh64_h_pc_get; 1002 CPU_PC_STORE (cpu) = sh64_h_pc_set; 1003 CPU_GET_IDATA (cpu) = sh64_get_idata; 1004 /* Only used by profiling. 0 disables it. */ 1005 CPU_MAX_INSNS (cpu) = 0; 1006 CPU_INSN_NAME (cpu) = cgen_insn_name; 1007 CPU_FULL_ENGINE_FN (cpu) = sh64_engine_run_full; 1008#if WITH_FAST 1009 CPU_FAST_ENGINE_FN (cpu) = sh64_engine_run_fast; 1010#else 1011 CPU_FAST_ENGINE_FN (cpu) = sh64_engine_run_full; 1012#endif 1013} 1014 1015static void 1016shmedia_init_cpu (SIM_CPU *cpu) 1017{ 1018 sh64_init_cpu (cpu); 1019} 1020 1021static void 1022shcompact_init_cpu (SIM_CPU *cpu) 1023{ 1024 sh64_init_cpu (cpu); 1025} 1026 1027static void 1028sh64_model_init() 1029{ 1030 /* Do nothing. */ 1031} 1032 1033static const MODEL sh_models [] = 1034{ 1035 { "sh2", & sh2_mach, MODEL_SH5, NULL, sh64_model_init }, 1036 { "sh2e", & sh2e_mach, MODEL_SH5, NULL, sh64_model_init }, 1037 { "sh2a", & sh2a_fpu_mach, MODEL_SH5, NULL, sh64_model_init }, 1038 { "sh2a_nofpu", & sh2a_nofpu_mach, MODEL_SH5, NULL, sh64_model_init }, 1039 { "sh3", & sh3_mach, MODEL_SH5, NULL, sh64_model_init }, 1040 { "sh3e", & sh3_mach, MODEL_SH5, NULL, sh64_model_init }, 1041 { "sh4", & sh4_mach, MODEL_SH5, NULL, sh64_model_init }, 1042 { "sh4_nofpu", & sh4_nofpu_mach, MODEL_SH5, NULL, sh64_model_init }, 1043 { "sh4a", & sh4a_mach, MODEL_SH5, NULL, sh64_model_init }, 1044 { "sh4a_nofpu", & sh4a_nofpu_mach, MODEL_SH5, NULL, sh64_model_init }, 1045 { "sh4al", & sh4al_mach, MODEL_SH5, NULL, sh64_model_init }, 1046 { "sh5", & sh5_mach, MODEL_SH5, NULL, sh64_model_init }, 1047 { 0 } 1048}; 1049 1050static const MACH_IMP_PROPERTIES sh5_imp_properties = 1051{ 1052 sizeof (SIM_CPU), 1053#if WITH_SCACHE 1054 sizeof (SCACHE) 1055#else 1056 0 1057#endif 1058}; 1059 1060const MACH sh2_mach = 1061{ 1062 "sh2", "sh2", MACH_SH5, 1063 16, 16, &sh_models[0], &sh5_imp_properties, 1064 shcompact_init_cpu, 1065 sh64_prepare_run 1066}; 1067 1068const MACH sh2e_mach = 1069{ 1070 "sh2e", "sh2e", MACH_SH5, 1071 16, 16, &sh_models[1], &sh5_imp_properties, 1072 shcompact_init_cpu, 1073 sh64_prepare_run 1074}; 1075 1076const MACH sh2a_fpu_mach = 1077{ 1078 "sh2a", "sh2a", MACH_SH5, 1079 16, 16, &sh_models[2], &sh5_imp_properties, 1080 shcompact_init_cpu, 1081 sh64_prepare_run 1082}; 1083 1084const MACH sh2a_nofpu_mach = 1085{ 1086 "sh2a_nofpu", "sh2a_nofpu", MACH_SH5, 1087 16, 16, &sh_models[3], &sh5_imp_properties, 1088 shcompact_init_cpu, 1089 sh64_prepare_run 1090}; 1091 1092const MACH sh3_mach = 1093{ 1094 "sh3", "sh3", MACH_SH5, 1095 16, 16, &sh_models[4], &sh5_imp_properties, 1096 shcompact_init_cpu, 1097 sh64_prepare_run 1098}; 1099 1100const MACH sh3e_mach = 1101{ 1102 "sh3e", "sh3e", MACH_SH5, 1103 16, 16, &sh_models[5], &sh5_imp_properties, 1104 shcompact_init_cpu, 1105 sh64_prepare_run 1106}; 1107 1108const MACH sh4_mach = 1109{ 1110 "sh4", "sh4", MACH_SH5, 1111 16, 16, &sh_models[6], &sh5_imp_properties, 1112 shcompact_init_cpu, 1113 sh64_prepare_run 1114}; 1115 1116const MACH sh4_nofpu_mach = 1117{ 1118 "sh4_nofpu", "sh4_nofpu", MACH_SH5, 1119 16, 16, &sh_models[7], &sh5_imp_properties, 1120 shcompact_init_cpu, 1121 sh64_prepare_run 1122}; 1123 1124const MACH sh4a_mach = 1125{ 1126 "sh4a", "sh4a", MACH_SH5, 1127 16, 16, &sh_models[8], &sh5_imp_properties, 1128 shcompact_init_cpu, 1129 sh64_prepare_run 1130}; 1131 1132const MACH sh4a_nofpu_mach = 1133{ 1134 "sh4a_nofpu", "sh4a_nofpu", MACH_SH5, 1135 16, 16, &sh_models[9], &sh5_imp_properties, 1136 shcompact_init_cpu, 1137 sh64_prepare_run 1138}; 1139 1140const MACH sh4al_mach = 1141{ 1142 "sh4al", "sh4al", MACH_SH5, 1143 16, 16, &sh_models[10], &sh5_imp_properties, 1144 shcompact_init_cpu, 1145 sh64_prepare_run 1146}; 1147 1148const MACH sh5_mach = 1149{ 1150 "sh5", "sh5", MACH_SH5, 1151 32, 32, &sh_models[11], &sh5_imp_properties, 1152 shmedia_init_cpu, 1153 sh64_prepare_run 1154}; 1155