1/* frv simulator machine independent profiling code. 2 3 Copyright (C) 1998, 1999, 2000, 2001, 2003, 2007 4 Free Software Foundation, Inc. 5 Contributed by Red Hat 6 7This file is part of the GNU simulators. 8 9This program is free software; you can redistribute it and/or modify 10it under the terms of the GNU General Public License as published by 11the Free Software Foundation; either version 3 of the License, or 12(at your option) any later version. 13 14This program is distributed in the hope that it will be useful, 15but WITHOUT ANY WARRANTY; without even the implied warranty of 16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17GNU General Public License for more details. 18 19You should have received a copy of the GNU General Public License 20along with this program. If not, see <http://www.gnu.org/licenses/>. 21 22*/ 23#define WANT_CPU 24#define WANT_CPU_FRVBF 25 26#include "sim-main.h" 27#include "bfd.h" 28 29#if WITH_PROFILE_MODEL_P 30 31#include "profile.h" 32#include "profile-fr400.h" 33#include "profile-fr500.h" 34#include "profile-fr550.h" 35 36static void 37reset_gr_flags (SIM_CPU *cpu, INT gr) 38{ 39 SIM_DESC sd = CPU_STATE (cpu); 40 if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr400 41 || STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr450) 42 fr400_reset_gr_flags (cpu, gr); 43 /* Other machines have no gr flags right now. */ 44} 45 46static void 47reset_fr_flags (SIM_CPU *cpu, INT fr) 48{ 49 SIM_DESC sd = CPU_STATE (cpu); 50 if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr400 51 || STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr450) 52 fr400_reset_fr_flags (cpu, fr); 53 else if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr500) 54 fr500_reset_fr_flags (cpu, fr); 55} 56 57static void 58reset_acc_flags (SIM_CPU *cpu, INT acc) 59{ 60 SIM_DESC sd = CPU_STATE (cpu); 61 if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr400 62 || STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr450) 63 fr400_reset_acc_flags (cpu, acc); 64 /* Other machines have no acc flags right now. */ 65} 66 67static void 68reset_cc_flags (SIM_CPU *cpu, INT cc) 69{ 70 SIM_DESC sd = CPU_STATE (cpu); 71 if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr500) 72 fr500_reset_cc_flags (cpu, cc); 73 /* Other machines have no cc flags. */ 74} 75 76void 77set_use_is_gr_complex (SIM_CPU *cpu, INT gr) 78{ 79 if (gr != -1) 80 { 81 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 82 reset_gr_flags (cpu, gr); 83 ps->cur_gr_complex |= (((DI)1) << gr); 84 } 85} 86 87void 88set_use_not_gr_complex (SIM_CPU *cpu, INT gr) 89{ 90 if (gr != -1) 91 { 92 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 93 ps->cur_gr_complex &= ~(((DI)1) << gr); 94 } 95} 96 97int 98use_is_gr_complex (SIM_CPU *cpu, INT gr) 99{ 100 if (gr != -1) 101 { 102 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 103 return ps->cur_gr_complex & (((DI)1) << gr); 104 } 105 return 0; 106} 107 108/* Globals flag indicates whether this insn is being modeled. */ 109enum FRV_INSN_MODELING model_insn = FRV_INSN_NO_MODELING; 110 111/* static buffer for the name of the currently most restrictive hazard. */ 112static char hazard_name[100] = ""; 113 114/* Print information about the wait applied to an entire VLIW insn. */ 115FRV_INSN_FETCH_BUFFER frv_insn_fetch_buffer[] 116= { 117 {1, NO_REQNO}, {1, NO_REQNO} /* init with impossible address. */ 118}; 119 120enum cache_request 121{ 122 cache_load, 123 cache_invalidate, 124 cache_flush, 125 cache_preload, 126 cache_unlock 127}; 128 129/* A queue of load requests from the data cache. Use to keep track of loads 130 which are still pending. */ 131/* TODO -- some of these are mutually exclusive and can use a union. */ 132typedef struct 133{ 134 FRV_CACHE *cache; 135 unsigned reqno; 136 SI address; 137 int length; 138 int is_signed; 139 int regnum; 140 int cycles; 141 int regtype; 142 int lock; 143 int all; 144 int slot; 145 int active; 146 enum cache_request request; 147} CACHE_QUEUE_ELEMENT; 148 149#define CACHE_QUEUE_SIZE 64 /* TODO -- make queue dynamic */ 150struct 151{ 152 unsigned reqno; 153 int ix; 154 CACHE_QUEUE_ELEMENT q[CACHE_QUEUE_SIZE]; 155} cache_queue = {0, 0}; 156 157/* Queue a request for a load from the cache. The load will be queued as 158 'inactive' and will be requested after the given number 159 of cycles have passed from the point the load is activated. */ 160void 161request_cache_load (SIM_CPU *cpu, INT regnum, int regtype, int cycles) 162{ 163 CACHE_QUEUE_ELEMENT *q; 164 FRV_VLIW *vliw; 165 int slot; 166 167 /* For a conditional load which was not executed, CPU_LOAD_LENGTH will be 168 zero. */ 169 if (CPU_LOAD_LENGTH (cpu) == 0) 170 return; 171 172 if (cache_queue.ix >= CACHE_QUEUE_SIZE) 173 abort (); /* TODO: Make the queue dynamic */ 174 175 q = & cache_queue.q[cache_queue.ix]; 176 ++cache_queue.ix; 177 178 q->reqno = cache_queue.reqno++; 179 q->request = cache_load; 180 q->cache = CPU_DATA_CACHE (cpu); 181 q->address = CPU_LOAD_ADDRESS (cpu); 182 q->length = CPU_LOAD_LENGTH (cpu); 183 q->is_signed = CPU_LOAD_SIGNED (cpu); 184 q->regnum = regnum; 185 q->regtype = regtype; 186 q->cycles = cycles; 187 q->active = 0; 188 189 vliw = CPU_VLIW (cpu); 190 slot = vliw->next_slot - 1; 191 q->slot = (*vliw->current_vliw)[slot]; 192 193 CPU_LOAD_LENGTH (cpu) = 0; 194} 195 196/* Queue a request to flush the cache. The request will be queued as 197 'inactive' and will be requested after the given number 198 of cycles have passed from the point the request is activated. */ 199void 200request_cache_flush (SIM_CPU *cpu, FRV_CACHE *cache, int cycles) 201{ 202 CACHE_QUEUE_ELEMENT *q; 203 FRV_VLIW *vliw; 204 int slot; 205 206 if (cache_queue.ix >= CACHE_QUEUE_SIZE) 207 abort (); /* TODO: Make the queue dynamic */ 208 209 q = & cache_queue.q[cache_queue.ix]; 210 ++cache_queue.ix; 211 212 q->reqno = cache_queue.reqno++; 213 q->request = cache_flush; 214 q->cache = cache; 215 q->address = CPU_LOAD_ADDRESS (cpu); 216 q->all = CPU_PROFILE_STATE (cpu)->all_cache_entries; 217 q->cycles = cycles; 218 q->active = 0; 219 220 vliw = CPU_VLIW (cpu); 221 slot = vliw->next_slot - 1; 222 q->slot = (*vliw->current_vliw)[slot]; 223} 224 225/* Queue a request to invalidate the cache. The request will be queued as 226 'inactive' and will be requested after the given number 227 of cycles have passed from the point the request is activated. */ 228void 229request_cache_invalidate (SIM_CPU *cpu, FRV_CACHE *cache, int cycles) 230{ 231 CACHE_QUEUE_ELEMENT *q; 232 FRV_VLIW *vliw; 233 int slot; 234 235 if (cache_queue.ix >= CACHE_QUEUE_SIZE) 236 abort (); /* TODO: Make the queue dynamic */ 237 238 q = & cache_queue.q[cache_queue.ix]; 239 ++cache_queue.ix; 240 241 q->reqno = cache_queue.reqno++; 242 q->request = cache_invalidate; 243 q->cache = cache; 244 q->address = CPU_LOAD_ADDRESS (cpu); 245 q->all = CPU_PROFILE_STATE (cpu)->all_cache_entries; 246 q->cycles = cycles; 247 q->active = 0; 248 249 vliw = CPU_VLIW (cpu); 250 slot = vliw->next_slot - 1; 251 q->slot = (*vliw->current_vliw)[slot]; 252} 253 254/* Queue a request to preload the cache. The request will be queued as 255 'inactive' and will be requested after the given number 256 of cycles have passed from the point the request is activated. */ 257void 258request_cache_preload (SIM_CPU *cpu, FRV_CACHE *cache, int cycles) 259{ 260 CACHE_QUEUE_ELEMENT *q; 261 FRV_VLIW *vliw; 262 int slot; 263 264 if (cache_queue.ix >= CACHE_QUEUE_SIZE) 265 abort (); /* TODO: Make the queue dynamic */ 266 267 q = & cache_queue.q[cache_queue.ix]; 268 ++cache_queue.ix; 269 270 q->reqno = cache_queue.reqno++; 271 q->request = cache_preload; 272 q->cache = cache; 273 q->address = CPU_LOAD_ADDRESS (cpu); 274 q->length = CPU_LOAD_LENGTH (cpu); 275 q->lock = CPU_LOAD_LOCK (cpu); 276 q->cycles = cycles; 277 q->active = 0; 278 279 vliw = CPU_VLIW (cpu); 280 slot = vliw->next_slot - 1; 281 q->slot = (*vliw->current_vliw)[slot]; 282 283 CPU_LOAD_LENGTH (cpu) = 0; 284} 285 286/* Queue a request to unlock the cache. The request will be queued as 287 'inactive' and will be requested after the given number 288 of cycles have passed from the point the request is activated. */ 289void 290request_cache_unlock (SIM_CPU *cpu, FRV_CACHE *cache, int cycles) 291{ 292 CACHE_QUEUE_ELEMENT *q; 293 FRV_VLIW *vliw; 294 int slot; 295 296 if (cache_queue.ix >= CACHE_QUEUE_SIZE) 297 abort (); /* TODO: Make the queue dynamic */ 298 299 q = & cache_queue.q[cache_queue.ix]; 300 ++cache_queue.ix; 301 302 q->reqno = cache_queue.reqno++; 303 q->request = cache_unlock; 304 q->cache = cache; 305 q->address = CPU_LOAD_ADDRESS (cpu); 306 q->cycles = cycles; 307 q->active = 0; 308 309 vliw = CPU_VLIW (cpu); 310 slot = vliw->next_slot - 1; 311 q->slot = (*vliw->current_vliw)[slot]; 312} 313 314static void 315submit_cache_request (CACHE_QUEUE_ELEMENT *q) 316{ 317 switch (q->request) 318 { 319 case cache_load: 320 frv_cache_request_load (q->cache, q->reqno, q->address, q->slot); 321 break; 322 case cache_flush: 323 frv_cache_request_invalidate (q->cache, q->reqno, q->address, q->slot, 324 q->all, 1/*flush*/); 325 break; 326 case cache_invalidate: 327 frv_cache_request_invalidate (q->cache, q->reqno, q->address, q->slot, 328 q->all, 0/*flush*/); 329 break; 330 case cache_preload: 331 frv_cache_request_preload (q->cache, q->address, q->slot, 332 q->length, q->lock); 333 break; 334 case cache_unlock: 335 frv_cache_request_unlock (q->cache, q->address, q->slot); 336 break; 337 default: 338 abort (); 339 } 340} 341 342/* Activate all inactive load requests. */ 343static void 344activate_cache_requests (SIM_CPU *cpu) 345{ 346 int i; 347 for (i = 0; i < cache_queue.ix; ++i) 348 { 349 CACHE_QUEUE_ELEMENT *q = & cache_queue.q[i]; 350 if (! q->active) 351 { 352 q->active = 1; 353 /* Submit the request now if the cycle count is zero. */ 354 if (q->cycles == 0) 355 submit_cache_request (q); 356 } 357 } 358} 359 360/* Check to see if a load is pending which affects the given register(s). 361 */ 362int 363load_pending_for_register (SIM_CPU *cpu, int regnum, int words, int regtype) 364{ 365 int i; 366 for (i = 0; i < cache_queue.ix; ++i) 367 { 368 CACHE_QUEUE_ELEMENT *q = & cache_queue.q[i]; 369 370 /* Must be the same kind of register. */ 371 if (! q->active || q->request != cache_load || q->regtype != regtype) 372 continue; 373 374 /* If the registers numbers are equal, then we have a match. */ 375 if (q->regnum == regnum) 376 return 1; /* load pending */ 377 378 /* Check for overlap of a load with a multi-word register. */ 379 if (regnum < q->regnum) 380 { 381 if (regnum + words > q->regnum) 382 return 1; 383 } 384 /* Check for overlap of a multi-word load with the register. */ 385 else 386 { 387 int data_words = (q->length + sizeof (SI) - 1) / sizeof (SI); 388 if (q->regnum + data_words > regnum) 389 return 1; 390 } 391 } 392 393 return 0; /* no load pending */ 394} 395 396/* Check to see if a cache flush pending which affects the given address. */ 397static int 398flush_pending_for_address (SIM_CPU *cpu, SI address) 399{ 400 int line_mask = ~(CPU_DATA_CACHE (cpu)->line_size - 1); 401 int i; 402 for (i = 0; i < cache_queue.ix; ++i) 403 { 404 CACHE_QUEUE_ELEMENT *q = & cache_queue.q[i]; 405 406 /* Must be the same kind of request and active. */ 407 if (! q->active || q->request != cache_flush) 408 continue; 409 410 /* If the addresses are equal, then we have a match. */ 411 if ((q->address & line_mask) == (address & line_mask)) 412 return 1; /* flush pending */ 413 } 414 415 return 0; /* no flush pending */ 416} 417 418static void 419remove_cache_queue_element (SIM_CPU *cpu, int i) 420{ 421 /* If we are removing the load of a FR register, then remember which one(s). 422 */ 423 CACHE_QUEUE_ELEMENT q = cache_queue.q[i]; 424 425 for (--cache_queue.ix; i < cache_queue.ix; ++i) 426 cache_queue.q[i] = cache_queue.q[i + 1]; 427 428 /* If we removed a load of a FR register, check to see if any other loads 429 of that register is still queued. If not, then apply the queued post 430 processing time of that register to its latency. Also apply 431 1 extra cycle of latency to the register since it was a floating point 432 load. */ 433 if (q.request == cache_load && q.regtype != REGTYPE_NONE) 434 { 435 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 436 int data_words = (q.length + sizeof (SI) - 1) / sizeof (SI); 437 int j; 438 for (j = 0; j < data_words; ++j) 439 { 440 int regnum = q.regnum + j; 441 if (! load_pending_for_register (cpu, regnum, 1, q.regtype)) 442 { 443 if (q.regtype == REGTYPE_FR) 444 { 445 int *fr = ps->fr_busy; 446 fr[regnum] += 1 + ps->fr_ptime[regnum]; 447 ps->fr_ptime[regnum] = 0; 448 } 449 } 450 } 451 } 452} 453 454/* Copy data from the cache buffer to the target register(s). */ 455static void 456copy_load_data (SIM_CPU *current_cpu, FRV_CACHE *cache, int slot, 457 CACHE_QUEUE_ELEMENT *q) 458{ 459 switch (q->length) 460 { 461 case 1: 462 if (q->regtype == REGTYPE_FR) 463 { 464 if (q->is_signed) 465 { 466 QI value = CACHE_RETURN_DATA (cache, slot, q->address, QI, 1); 467 SET_H_FR (q->regnum, value); 468 } 469 else 470 { 471 UQI value = CACHE_RETURN_DATA (cache, slot, q->address, UQI, 1); 472 SET_H_FR (q->regnum, value); 473 } 474 } 475 else 476 { 477 if (q->is_signed) 478 { 479 QI value = CACHE_RETURN_DATA (cache, slot, q->address, QI, 1); 480 SET_H_GR (q->regnum, value); 481 } 482 else 483 { 484 UQI value = CACHE_RETURN_DATA (cache, slot, q->address, UQI, 1); 485 SET_H_GR (q->regnum, value); 486 } 487 } 488 break; 489 case 2: 490 if (q->regtype == REGTYPE_FR) 491 { 492 if (q->is_signed) 493 { 494 HI value = CACHE_RETURN_DATA (cache, slot, q->address, HI, 2); 495 SET_H_FR (q->regnum, value); 496 } 497 else 498 { 499 UHI value = CACHE_RETURN_DATA (cache, slot, q->address, UHI, 2); 500 SET_H_FR (q->regnum, value); 501 } 502 } 503 else 504 { 505 if (q->is_signed) 506 { 507 HI value = CACHE_RETURN_DATA (cache, slot, q->address, HI, 2); 508 SET_H_GR (q->regnum, value); 509 } 510 else 511 { 512 UHI value = CACHE_RETURN_DATA (cache, slot, q->address, UHI, 2); 513 SET_H_GR (q->regnum, value); 514 } 515 } 516 break; 517 case 4: 518 if (q->regtype == REGTYPE_FR) 519 { 520 SET_H_FR (q->regnum, 521 CACHE_RETURN_DATA (cache, slot, q->address, SF, 4)); 522 } 523 else 524 { 525 SET_H_GR (q->regnum, 526 CACHE_RETURN_DATA (cache, slot, q->address, SI, 4)); 527 } 528 break; 529 case 8: 530 if (q->regtype == REGTYPE_FR) 531 { 532 SET_H_FR_DOUBLE (q->regnum, 533 CACHE_RETURN_DATA (cache, slot, q->address, DF, 8)); 534 } 535 else 536 { 537 SET_H_GR_DOUBLE (q->regnum, 538 CACHE_RETURN_DATA (cache, slot, q->address, DI, 8)); 539 } 540 break; 541 case 16: 542 if (q->regtype == REGTYPE_FR) 543 frvbf_h_fr_quad_set_handler (current_cpu, q->regnum, 544 CACHE_RETURN_DATA_ADDRESS (cache, slot, 545 q->address, 546 16)); 547 else 548 frvbf_h_gr_quad_set_handler (current_cpu, q->regnum, 549 CACHE_RETURN_DATA_ADDRESS (cache, slot, 550 q->address, 551 16)); 552 break; 553 default: 554 abort (); 555 } 556} 557 558static int 559request_complete (SIM_CPU *cpu, CACHE_QUEUE_ELEMENT *q) 560{ 561 FRV_CACHE* cache; 562 if (! q->active || q->cycles > 0) 563 return 0; 564 565 cache = CPU_DATA_CACHE (cpu); 566 switch (q->request) 567 { 568 case cache_load: 569 /* For loads, we must wait until the data is returned from the cache. */ 570 if (frv_cache_data_in_buffer (cache, 0, q->address, q->reqno)) 571 { 572 copy_load_data (cpu, cache, 0, q); 573 return 1; 574 } 575 if (frv_cache_data_in_buffer (cache, 1, q->address, q->reqno)) 576 { 577 copy_load_data (cpu, cache, 1, q); 578 return 1; 579 } 580 break; 581 582 case cache_flush: 583 /* We must wait until the data is flushed. */ 584 if (frv_cache_data_flushed (cache, 0, q->address, q->reqno)) 585 return 1; 586 if (frv_cache_data_flushed (cache, 1, q->address, q->reqno)) 587 return 1; 588 break; 589 590 default: 591 /* All other requests are complete once they've been made. */ 592 return 1; 593 } 594 595 return 0; 596} 597 598/* Run the insn and data caches through the given number of cycles, taking 599 note of load requests which are fullfilled as a result. */ 600static void 601run_caches (SIM_CPU *cpu, int cycles) 602{ 603 FRV_CACHE* data_cache = CPU_DATA_CACHE (cpu); 604 FRV_CACHE* insn_cache = CPU_INSN_CACHE (cpu); 605 int i; 606 /* For each cycle, run the caches, noting which requests have been fullfilled 607 and submitting new requests on their designated cycles. */ 608 for (i = 0; i < cycles; ++i) 609 { 610 int j; 611 /* Run the caches through 1 cycle. */ 612 frv_cache_run (data_cache, 1); 613 frv_cache_run (insn_cache, 1); 614 615 /* Note whether prefetched insn data has been loaded yet. */ 616 for (j = LS; j < FRV_CACHE_PIPELINES; ++j) 617 { 618 if (frv_insn_fetch_buffer[j].reqno != NO_REQNO 619 && frv_cache_data_in_buffer (insn_cache, j, 620 frv_insn_fetch_buffer[j].address, 621 frv_insn_fetch_buffer[j].reqno)) 622 frv_insn_fetch_buffer[j].reqno = NO_REQNO; 623 } 624 625 /* Check to see which requests have been satisfied and which should 626 be submitted now. */ 627 for (j = 0; j < cache_queue.ix; ++j) 628 { 629 CACHE_QUEUE_ELEMENT *q = & cache_queue.q[j]; 630 if (! q->active) 631 continue; 632 633 /* If a load has been satisfied, complete the operation and remove it 634 from the queue. */ 635 if (request_complete (cpu, q)) 636 { 637 remove_cache_queue_element (cpu, j); 638 --j; 639 continue; 640 } 641 642 /* Decrease the cycle count of each queued request. 643 Submit a request for each queued request whose cycle count has 644 become zero. */ 645 --q->cycles; 646 if (q->cycles == 0) 647 submit_cache_request (q); 648 } 649 } 650} 651 652static void 653apply_latency_adjustments (SIM_CPU *cpu) 654{ 655 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 656 int i; 657 /* update the latencies of the registers. */ 658 int *fr = ps->fr_busy; 659 int *acc = ps->acc_busy; 660 for (i = 0; i < 64; ++i) 661 { 662 if (ps->fr_busy_adjust[i] > 0) 663 *fr -= ps->fr_busy_adjust[i]; /* OK if it goes negative. */ 664 if (ps->acc_busy_adjust[i] > 0) 665 *acc -= ps->acc_busy_adjust[i]; /* OK if it goes negative. */ 666 ++fr; 667 ++acc; 668 } 669} 670 671/* Account for the number of cycles which have just passed in the latency of 672 various system elements. Works for negative cycles too so that latency 673 can be extended in the case of insn fetch latency. 674 If negative or zero, then no adjustment is necessary. */ 675static void 676update_latencies (SIM_CPU *cpu, int cycles) 677{ 678 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 679 int i; 680 /* update the latencies of the registers. */ 681 int *fdiv; 682 int *fsqrt; 683 int *idiv; 684 int *flt; 685 int *media; 686 int *ccr; 687 int *gr = ps->gr_busy; 688 int *fr = ps->fr_busy; 689 int *acc = ps->acc_busy; 690 int *spr; 691 /* This loop handles GR, FR and ACC registers. */ 692 for (i = 0; i < 64; ++i) 693 { 694 if (*gr <= cycles) 695 { 696 *gr = 0; 697 reset_gr_flags (cpu, i); 698 } 699 else 700 *gr -= cycles; 701 /* If the busy drops to 0, then mark the register as 702 "not in use". */ 703 if (*fr <= cycles) 704 { 705 int *fr_lat = ps->fr_latency + i; 706 *fr = 0; 707 ps->fr_busy_adjust[i] = 0; 708 /* Only clear flags if this register has no target latency. */ 709 if (*fr_lat == 0) 710 reset_fr_flags (cpu, i); 711 } 712 else 713 *fr -= cycles; 714 /* If the busy drops to 0, then mark the register as 715 "not in use". */ 716 if (*acc <= cycles) 717 { 718 int *acc_lat = ps->acc_latency + i; 719 *acc = 0; 720 ps->acc_busy_adjust[i] = 0; 721 /* Only clear flags if this register has no target latency. */ 722 if (*acc_lat == 0) 723 reset_acc_flags (cpu, i); 724 } 725 else 726 *acc -= cycles; 727 ++gr; 728 ++fr; 729 ++acc; 730 } 731 /* This loop handles CCR registers. */ 732 ccr = ps->ccr_busy; 733 for (i = 0; i < 8; ++i) 734 { 735 if (*ccr <= cycles) 736 { 737 *ccr = 0; 738 reset_cc_flags (cpu, i); 739 } 740 else 741 *ccr -= cycles; 742 ++ccr; 743 } 744 /* This loop handles SPR registers. */ 745 spr = ps->spr_busy; 746 for (i = 0; i < 4096; ++i) 747 { 748 if (*spr <= cycles) 749 *spr = 0; 750 else 751 *spr -= cycles; 752 ++spr; 753 } 754 /* This loop handles resources. */ 755 idiv = ps->idiv_busy; 756 fdiv = ps->fdiv_busy; 757 fsqrt = ps->fsqrt_busy; 758 for (i = 0; i < 2; ++i) 759 { 760 *idiv = (*idiv <= cycles) ? 0 : (*idiv - cycles); 761 *fdiv = (*fdiv <= cycles) ? 0 : (*fdiv - cycles); 762 *fsqrt = (*fsqrt <= cycles) ? 0 : (*fsqrt - cycles); 763 ++idiv; 764 ++fdiv; 765 ++fsqrt; 766 } 767 /* Float and media units can occur in 4 slots on some machines. */ 768 flt = ps->float_busy; 769 media = ps->media_busy; 770 for (i = 0; i < 4; ++i) 771 { 772 *flt = (*flt <= cycles) ? 0 : (*flt - cycles); 773 *media = (*media <= cycles) ? 0 : (*media - cycles); 774 ++flt; 775 ++media; 776 } 777} 778 779/* Print information about the wait for the given number of cycles. */ 780void 781frv_model_trace_wait_cycles (SIM_CPU *cpu, int cycles, const char *hazard_name) 782{ 783 if (TRACE_INSN_P (cpu) && cycles > 0) 784 { 785 SIM_DESC sd = CPU_STATE (cpu); 786 trace_printf (sd, cpu, "**** %s wait %d cycles ***\n", 787 hazard_name, cycles); 788 } 789} 790 791void 792trace_vliw_wait_cycles (SIM_CPU *cpu) 793{ 794 if (TRACE_INSN_P (cpu)) 795 { 796 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 797 frv_model_trace_wait_cycles (cpu, ps->vliw_wait, hazard_name); 798 } 799} 800 801/* Wait for the given number of cycles. */ 802void 803frv_model_advance_cycles (SIM_CPU *cpu, int cycles) 804{ 805 PROFILE_DATA *p = CPU_PROFILE_DATA (cpu); 806 update_latencies (cpu, cycles); 807 run_caches (cpu, cycles); 808 PROFILE_MODEL_TOTAL_CYCLES (p) += cycles; 809} 810 811void 812handle_resource_wait (SIM_CPU *cpu) 813{ 814 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 815 if (ps->vliw_wait != 0) 816 frv_model_advance_cycles (cpu, ps->vliw_wait); 817 if (ps->vliw_load_stall > ps->vliw_wait) 818 ps->vliw_load_stall -= ps->vliw_wait; 819 else 820 ps->vliw_load_stall = 0; 821} 822 823/* Account for the number of cycles until these resources will be available 824 again. */ 825static void 826update_target_latencies (SIM_CPU *cpu) 827{ 828 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 829 int i; 830 /* update the latencies of the registers. */ 831 int *ccr_lat; 832 int *gr_lat = ps->gr_latency; 833 int *fr_lat = ps->fr_latency; 834 int *acc_lat = ps->acc_latency; 835 int *spr_lat; 836 int *ccr; 837 int *gr = ps->gr_busy; 838 int *fr = ps->fr_busy; 839 int *acc = ps->acc_busy; 840 int *spr; 841 /* This loop handles GR, FR and ACC registers. */ 842 for (i = 0; i < 64; ++i) 843 { 844 if (*gr_lat) 845 { 846 *gr = *gr_lat; 847 *gr_lat = 0; 848 } 849 if (*fr_lat) 850 { 851 *fr = *fr_lat; 852 *fr_lat = 0; 853 } 854 if (*acc_lat) 855 { 856 *acc = *acc_lat; 857 *acc_lat = 0; 858 } 859 ++gr; ++gr_lat; 860 ++fr; ++fr_lat; 861 ++acc; ++acc_lat; 862 } 863 /* This loop handles CCR registers. */ 864 ccr = ps->ccr_busy; 865 ccr_lat = ps->ccr_latency; 866 for (i = 0; i < 8; ++i) 867 { 868 if (*ccr_lat) 869 { 870 *ccr = *ccr_lat; 871 *ccr_lat = 0; 872 } 873 ++ccr; ++ccr_lat; 874 } 875 /* This loop handles SPR registers. */ 876 spr = ps->spr_busy; 877 spr_lat = ps->spr_latency; 878 for (i = 0; i < 4096; ++i) 879 { 880 if (*spr_lat) 881 { 882 *spr = *spr_lat; 883 *spr_lat = 0; 884 } 885 ++spr; ++spr_lat; 886 } 887} 888 889/* Run the caches until all pending cache flushes are complete. */ 890static void 891wait_for_flush (SIM_CPU *cpu) 892{ 893 SI address = CPU_LOAD_ADDRESS (cpu); 894 int wait = 0; 895 while (flush_pending_for_address (cpu, address)) 896 { 897 frv_model_advance_cycles (cpu, 1); 898 ++wait; 899 } 900 if (TRACE_INSN_P (cpu) && wait) 901 { 902 sprintf (hazard_name, "Data cache flush address %p:", address); 903 frv_model_trace_wait_cycles (cpu, wait, hazard_name); 904 } 905} 906 907/* Initialize cycle counting for an insn. 908 FIRST_P is non-zero if this is the first insn in a set of parallel 909 insns. */ 910void 911frvbf_model_insn_before (SIM_CPU *cpu, int first_p) 912{ 913 SIM_DESC sd = CPU_STATE (cpu); 914 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 915 916 ps->vliw_wait = 0; 917 ps->post_wait = 0; 918 memset (ps->fr_busy_adjust, 0, sizeof (ps->fr_busy_adjust)); 919 memset (ps->acc_busy_adjust, 0, sizeof (ps->acc_busy_adjust)); 920 921 if (first_p) 922 { 923 ps->vliw_insns++; 924 ps->vliw_cycles = 0; 925 ps->vliw_branch_taken = 0; 926 ps->vliw_load_stall = 0; 927 } 928 929 switch (STATE_ARCHITECTURE (sd)->mach) 930 { 931 case bfd_mach_fr400: 932 case bfd_mach_fr450: 933 fr400_model_insn_before (cpu, first_p); 934 break; 935 case bfd_mach_fr500: 936 fr500_model_insn_before (cpu, first_p); 937 break; 938 case bfd_mach_fr550: 939 fr550_model_insn_before (cpu, first_p); 940 break; 941 default: 942 break; 943 } 944 945 if (first_p) 946 wait_for_flush (cpu); 947} 948 949/* Record the cycles computed for an insn. 950 LAST_P is non-zero if this is the last insn in a set of parallel insns, 951 and we update the total cycle count. 952 CYCLES is the cycle count of the insn. */ 953 954void 955frvbf_model_insn_after (SIM_CPU *cpu, int last_p, int cycles) 956{ 957 PROFILE_DATA *p = CPU_PROFILE_DATA (cpu); 958 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 959 SIM_DESC sd = CPU_STATE (cpu); 960 961 PROFILE_MODEL_CUR_INSN_CYCLES (p) = cycles; 962 963 /* The number of cycles for a VLIW insn is the maximum number of cycles 964 used by any individual insn within it. */ 965 if (cycles > ps->vliw_cycles) 966 ps->vliw_cycles = cycles; 967 968 if (last_p) 969 { 970 /* This is the last insn in a VLIW insn. */ 971 struct frv_interrupt_timer *timer = & frv_interrupt_state.timer; 972 973 activate_cache_requests (cpu); /* before advancing cycles. */ 974 apply_latency_adjustments (cpu); /* must go first. */ 975 update_target_latencies (cpu); /* must go next. */ 976 frv_model_advance_cycles (cpu, ps->vliw_cycles); 977 978 PROFILE_MODEL_LOAD_STALL_CYCLES (p) += ps->vliw_load_stall; 979 980 /* Check the interrupt timer. cycles contains the total cycle count. */ 981 if (timer->enabled) 982 { 983 cycles = PROFILE_MODEL_TOTAL_CYCLES (p); 984 if (timer->current % timer->value 985 + (cycles - timer->current) >= timer->value) 986 frv_queue_external_interrupt (cpu, timer->interrupt); 987 timer->current = cycles; 988 } 989 990 ps->past_first_p = 0; /* Next one will be the first in a new VLIW. */ 991 ps->branch_address = -1; 992 } 993 else 994 ps->past_first_p = 1; 995 996 switch (STATE_ARCHITECTURE (sd)->mach) 997 { 998 case bfd_mach_fr400: 999 case bfd_mach_fr450: 1000 fr400_model_insn_after (cpu, last_p, cycles); 1001 break; 1002 case bfd_mach_fr500: 1003 fr500_model_insn_after (cpu, last_p, cycles); 1004 break; 1005 case bfd_mach_fr550: 1006 fr550_model_insn_after (cpu, last_p, cycles); 1007 break; 1008 default: 1009 break; 1010 } 1011} 1012 1013USI 1014frvbf_model_branch (SIM_CPU *current_cpu, PCADDR target, int hint) 1015{ 1016 /* Record the hint and branch address for use in profiling. */ 1017 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (current_cpu); 1018 ps->branch_hint = hint; 1019 ps->branch_address = target; 1020} 1021 1022/* Top up the latency of the given GR by the given number of cycles. */ 1023void 1024update_GR_latency (SIM_CPU *cpu, INT out_GR, int cycles) 1025{ 1026 if (out_GR >= 0) 1027 { 1028 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1029 int *gr = ps->gr_latency; 1030 if (gr[out_GR] < cycles) 1031 gr[out_GR] = cycles; 1032 } 1033} 1034 1035void 1036decrease_GR_busy (SIM_CPU *cpu, INT in_GR, int cycles) 1037{ 1038 if (in_GR >= 0) 1039 { 1040 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1041 int *gr = ps->gr_busy; 1042 gr[in_GR] -= cycles; 1043 } 1044} 1045 1046/* Top up the latency of the given double GR by the number of cycles. */ 1047void 1048update_GRdouble_latency (SIM_CPU *cpu, INT out_GR, int cycles) 1049{ 1050 if (out_GR >= 0) 1051 { 1052 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1053 int *gr = ps->gr_latency; 1054 if (gr[out_GR] < cycles) 1055 gr[out_GR] = cycles; 1056 if (out_GR < 63 && gr[out_GR + 1] < cycles) 1057 gr[out_GR + 1] = cycles; 1058 } 1059} 1060 1061void 1062update_GR_latency_for_load (SIM_CPU *cpu, INT out_GR, int cycles) 1063{ 1064 if (out_GR >= 0) 1065 { 1066 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1067 int *gr = ps->gr_latency; 1068 1069 /* The latency of the GR will be at least the number of cycles used 1070 by the insn. */ 1071 if (gr[out_GR] < cycles) 1072 gr[out_GR] = cycles; 1073 1074 /* The latency will also depend on how long it takes to retrieve the 1075 data from the cache or memory. Assume that the load is issued 1076 after the last cycle of the insn. */ 1077 request_cache_load (cpu, out_GR, REGTYPE_NONE, cycles); 1078 } 1079} 1080 1081void 1082update_GRdouble_latency_for_load (SIM_CPU *cpu, INT out_GR, int cycles) 1083{ 1084 if (out_GR >= 0) 1085 { 1086 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1087 int *gr = ps->gr_latency; 1088 1089 /* The latency of the GR will be at least the number of cycles used 1090 by the insn. */ 1091 if (gr[out_GR] < cycles) 1092 gr[out_GR] = cycles; 1093 if (out_GR < 63 && gr[out_GR + 1] < cycles) 1094 gr[out_GR + 1] = cycles; 1095 1096 /* The latency will also depend on how long it takes to retrieve the 1097 data from the cache or memory. Assume that the load is issued 1098 after the last cycle of the insn. */ 1099 request_cache_load (cpu, out_GR, REGTYPE_NONE, cycles); 1100 } 1101} 1102 1103void 1104update_GR_latency_for_swap (SIM_CPU *cpu, INT out_GR, int cycles) 1105{ 1106 update_GR_latency_for_load (cpu, out_GR, cycles); 1107} 1108 1109/* Top up the latency of the given FR by the given number of cycles. */ 1110void 1111update_FR_latency (SIM_CPU *cpu, INT out_FR, int cycles) 1112{ 1113 if (out_FR >= 0) 1114 { 1115 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1116 int *fr = ps->fr_latency; 1117 if (fr[out_FR] < cycles) 1118 fr[out_FR] = cycles; 1119 } 1120} 1121 1122/* Top up the latency of the given double FR by the number of cycles. */ 1123void 1124update_FRdouble_latency (SIM_CPU *cpu, INT out_FR, int cycles) 1125{ 1126 if (out_FR >= 0) 1127 { 1128 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1129 int *fr = ps->fr_latency; 1130 if (fr[out_FR] < cycles) 1131 fr[out_FR] = cycles; 1132 if (out_FR < 63 && fr[out_FR + 1] < cycles) 1133 fr[out_FR + 1] = cycles; 1134 } 1135} 1136 1137void 1138update_FR_latency_for_load (SIM_CPU *cpu, INT out_FR, int cycles) 1139{ 1140 if (out_FR >= 0) 1141 { 1142 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1143 int *fr = ps->fr_latency; 1144 1145 /* The latency of the FR will be at least the number of cycles used 1146 by the insn. */ 1147 if (fr[out_FR] < cycles) 1148 fr[out_FR] = cycles; 1149 1150 /* The latency will also depend on how long it takes to retrieve the 1151 data from the cache or memory. Assume that the load is issued 1152 after the last cycle of the insn. */ 1153 request_cache_load (cpu, out_FR, REGTYPE_FR, cycles); 1154 } 1155} 1156 1157void 1158update_FRdouble_latency_for_load (SIM_CPU *cpu, INT out_FR, int cycles) 1159{ 1160 if (out_FR >= 0) 1161 { 1162 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1163 int *fr = ps->fr_latency; 1164 1165 /* The latency of the FR will be at least the number of cycles used 1166 by the insn. */ 1167 if (fr[out_FR] < cycles) 1168 fr[out_FR] = cycles; 1169 if (out_FR < 63 && fr[out_FR + 1] < cycles) 1170 fr[out_FR + 1] = cycles; 1171 1172 /* The latency will also depend on how long it takes to retrieve the 1173 data from the cache or memory. Assume that the load is issued 1174 after the last cycle of the insn. */ 1175 request_cache_load (cpu, out_FR, REGTYPE_FR, cycles); 1176 } 1177} 1178 1179/* Top up the post-processing time of the given FR by the given number of 1180 cycles. */ 1181void 1182update_FR_ptime (SIM_CPU *cpu, INT out_FR, int cycles) 1183{ 1184 if (out_FR >= 0) 1185 { 1186 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1187 /* If a load is pending on this register, then add the cycles to 1188 the post processing time for this register. Otherwise apply it 1189 directly to the latency of the register. */ 1190 if (! load_pending_for_register (cpu, out_FR, 1, REGTYPE_FR)) 1191 { 1192 int *fr = ps->fr_latency; 1193 fr[out_FR] += cycles; 1194 } 1195 else 1196 ps->fr_ptime[out_FR] += cycles; 1197 } 1198} 1199 1200void 1201update_FRdouble_ptime (SIM_CPU *cpu, INT out_FR, int cycles) 1202{ 1203 if (out_FR >= 0) 1204 { 1205 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1206 /* If a load is pending on this register, then add the cycles to 1207 the post processing time for this register. Otherwise apply it 1208 directly to the latency of the register. */ 1209 if (! load_pending_for_register (cpu, out_FR, 2, REGTYPE_FR)) 1210 { 1211 int *fr = ps->fr_latency; 1212 fr[out_FR] += cycles; 1213 if (out_FR < 63) 1214 fr[out_FR + 1] += cycles; 1215 } 1216 else 1217 { 1218 ps->fr_ptime[out_FR] += cycles; 1219 if (out_FR < 63) 1220 ps->fr_ptime[out_FR + 1] += cycles; 1221 } 1222 } 1223} 1224 1225/* Top up the post-processing time of the given ACC by the given number of 1226 cycles. */ 1227void 1228update_ACC_ptime (SIM_CPU *cpu, INT out_ACC, int cycles) 1229{ 1230 if (out_ACC >= 0) 1231 { 1232 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1233 /* No load can be pending on this register. Apply the cycles 1234 directly to the latency of the register. */ 1235 int *acc = ps->acc_latency; 1236 acc[out_ACC] += cycles; 1237 } 1238} 1239 1240/* Top up the post-processing time of the given SPR by the given number of 1241 cycles. */ 1242void 1243update_SPR_ptime (SIM_CPU *cpu, INT out_SPR, int cycles) 1244{ 1245 if (out_SPR >= 0) 1246 { 1247 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1248 /* No load can be pending on this register. Apply the cycles 1249 directly to the latency of the register. */ 1250 int *spr = ps->spr_latency; 1251 spr[out_SPR] += cycles; 1252 } 1253} 1254 1255void 1256decrease_ACC_busy (SIM_CPU *cpu, INT out_ACC, int cycles) 1257{ 1258 if (out_ACC >= 0) 1259 { 1260 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1261 int *acc = ps->acc_busy; 1262 acc[out_ACC] -= cycles; 1263 if (ps->acc_busy_adjust[out_ACC] >= 0 1264 && cycles > ps->acc_busy_adjust[out_ACC]) 1265 ps->acc_busy_adjust[out_ACC] = cycles; 1266 } 1267} 1268 1269void 1270increase_ACC_busy (SIM_CPU *cpu, INT out_ACC, int cycles) 1271{ 1272 if (out_ACC >= 0) 1273 { 1274 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1275 int *acc = ps->acc_busy; 1276 acc[out_ACC] += cycles; 1277 } 1278} 1279 1280void 1281enforce_full_acc_latency (SIM_CPU *cpu, INT in_ACC) 1282{ 1283 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1284 ps->acc_busy_adjust [in_ACC] = -1; 1285} 1286 1287void 1288decrease_FR_busy (SIM_CPU *cpu, INT out_FR, int cycles) 1289{ 1290 if (out_FR >= 0) 1291 { 1292 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1293 int *fr = ps->fr_busy; 1294 fr[out_FR] -= cycles; 1295 if (ps->fr_busy_adjust[out_FR] >= 0 1296 && cycles > ps->fr_busy_adjust[out_FR]) 1297 ps->fr_busy_adjust[out_FR] = cycles; 1298 } 1299} 1300 1301void 1302increase_FR_busy (SIM_CPU *cpu, INT out_FR, int cycles) 1303{ 1304 if (out_FR >= 0) 1305 { 1306 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1307 int *fr = ps->fr_busy; 1308 fr[out_FR] += cycles; 1309 } 1310} 1311 1312/* Top up the latency of the given ACC by the given number of cycles. */ 1313void 1314update_ACC_latency (SIM_CPU *cpu, INT out_ACC, int cycles) 1315{ 1316 if (out_ACC >= 0) 1317 { 1318 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1319 int *acc = ps->acc_latency; 1320 if (acc[out_ACC] < cycles) 1321 acc[out_ACC] = cycles; 1322 } 1323} 1324 1325/* Top up the latency of the given CCR by the given number of cycles. */ 1326void 1327update_CCR_latency (SIM_CPU *cpu, INT out_CCR, int cycles) 1328{ 1329 if (out_CCR >= 0) 1330 { 1331 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1332 int *ccr = ps->ccr_latency; 1333 if (ccr[out_CCR] < cycles) 1334 ccr[out_CCR] = cycles; 1335 } 1336} 1337 1338/* Top up the latency of the given SPR by the given number of cycles. */ 1339void 1340update_SPR_latency (SIM_CPU *cpu, INT out_SPR, int cycles) 1341{ 1342 if (out_SPR >= 0) 1343 { 1344 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1345 int *spr = ps->spr_latency; 1346 if (spr[out_SPR] < cycles) 1347 spr[out_SPR] = cycles; 1348 } 1349} 1350 1351/* Top up the latency of the given integer division resource by the given 1352 number of cycles. */ 1353void 1354update_idiv_resource_latency (SIM_CPU *cpu, INT in_resource, int cycles) 1355{ 1356 /* operate directly on the busy cycles since each resource can only 1357 be used once in a VLIW insn. */ 1358 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1359 int *r = ps->idiv_busy; 1360 r[in_resource] = cycles; 1361} 1362 1363/* Set the latency of the given resource to the given number of cycles. */ 1364void 1365update_fdiv_resource_latency (SIM_CPU *cpu, INT in_resource, int cycles) 1366{ 1367 /* operate directly on the busy cycles since each resource can only 1368 be used once in a VLIW insn. */ 1369 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1370 int *r = ps->fdiv_busy; 1371 r[in_resource] = cycles; 1372} 1373 1374/* Set the latency of the given resource to the given number of cycles. */ 1375void 1376update_fsqrt_resource_latency (SIM_CPU *cpu, INT in_resource, int cycles) 1377{ 1378 /* operate directly on the busy cycles since each resource can only 1379 be used once in a VLIW insn. */ 1380 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1381 int *r = ps->fsqrt_busy; 1382 r[in_resource] = cycles; 1383} 1384 1385/* Set the latency of the given resource to the given number of cycles. */ 1386void 1387update_float_resource_latency (SIM_CPU *cpu, INT in_resource, int cycles) 1388{ 1389 /* operate directly on the busy cycles since each resource can only 1390 be used once in a VLIW insn. */ 1391 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1392 int *r = ps->float_busy; 1393 r[in_resource] = cycles; 1394} 1395 1396void 1397update_media_resource_latency (SIM_CPU *cpu, INT in_resource, int cycles) 1398{ 1399 /* operate directly on the busy cycles since each resource can only 1400 be used once in a VLIW insn. */ 1401 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1402 int *r = ps->media_busy; 1403 r[in_resource] = cycles; 1404} 1405 1406/* Set the branch penalty to the given number of cycles. */ 1407void 1408update_branch_penalty (SIM_CPU *cpu, int cycles) 1409{ 1410 /* operate directly on the busy cycles since only one branch can occur 1411 in a VLIW insn. */ 1412 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1413 ps->branch_penalty = cycles; 1414} 1415 1416/* Check the availability of the given GR register and update the number 1417 of cycles the current VLIW insn must wait until it is available. */ 1418void 1419vliw_wait_for_GR (SIM_CPU *cpu, INT in_GR) 1420{ 1421 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1422 int *gr = ps->gr_busy; 1423 /* If the latency of the register is greater than the current wait 1424 then update the current wait. */ 1425 if (in_GR >= 0 && gr[in_GR] > ps->vliw_wait) 1426 { 1427 if (TRACE_INSN_P (cpu)) 1428 sprintf (hazard_name, "Data hazard for gr%d:", in_GR); 1429 ps->vliw_wait = gr[in_GR]; 1430 } 1431} 1432 1433/* Check the availability of the given GR register and update the number 1434 of cycles the current VLIW insn must wait until it is available. */ 1435void 1436vliw_wait_for_GRdouble (SIM_CPU *cpu, INT in_GR) 1437{ 1438 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1439 int *gr = ps->gr_busy; 1440 /* If the latency of the register is greater than the current wait 1441 then update the current wait. */ 1442 if (in_GR >= 0) 1443 { 1444 if (gr[in_GR] > ps->vliw_wait) 1445 { 1446 if (TRACE_INSN_P (cpu)) 1447 sprintf (hazard_name, "Data hazard for gr%d:", in_GR); 1448 ps->vliw_wait = gr[in_GR]; 1449 } 1450 if (in_GR < 63 && gr[in_GR + 1] > ps->vliw_wait) 1451 { 1452 if (TRACE_INSN_P (cpu)) 1453 sprintf (hazard_name, "Data hazard for gr%d:", in_GR + 1); 1454 ps->vliw_wait = gr[in_GR + 1]; 1455 } 1456 } 1457} 1458 1459/* Check the availability of the given FR register and update the number 1460 of cycles the current VLIW insn must wait until it is available. */ 1461void 1462vliw_wait_for_FR (SIM_CPU *cpu, INT in_FR) 1463{ 1464 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1465 int *fr = ps->fr_busy; 1466 /* If the latency of the register is greater than the current wait 1467 then update the current wait. */ 1468 if (in_FR >= 0 && fr[in_FR] > ps->vliw_wait) 1469 { 1470 if (TRACE_INSN_P (cpu)) 1471 sprintf (hazard_name, "Data hazard for fr%d:", in_FR); 1472 ps->vliw_wait = fr[in_FR]; 1473 } 1474} 1475 1476/* Check the availability of the given GR register and update the number 1477 of cycles the current VLIW insn must wait until it is available. */ 1478void 1479vliw_wait_for_FRdouble (SIM_CPU *cpu, INT in_FR) 1480{ 1481 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1482 int *fr = ps->fr_busy; 1483 /* If the latency of the register is greater than the current wait 1484 then update the current wait. */ 1485 if (in_FR >= 0) 1486 { 1487 if (fr[in_FR] > ps->vliw_wait) 1488 { 1489 if (TRACE_INSN_P (cpu)) 1490 sprintf (hazard_name, "Data hazard for fr%d:", in_FR); 1491 ps->vliw_wait = fr[in_FR]; 1492 } 1493 if (in_FR < 63 && fr[in_FR + 1] > ps->vliw_wait) 1494 { 1495 if (TRACE_INSN_P (cpu)) 1496 sprintf (hazard_name, "Data hazard for fr%d:", in_FR + 1); 1497 ps->vliw_wait = fr[in_FR + 1]; 1498 } 1499 } 1500} 1501 1502/* Check the availability of the given CCR register and update the number 1503 of cycles the current VLIW insn must wait until it is available. */ 1504void 1505vliw_wait_for_CCR (SIM_CPU *cpu, INT in_CCR) 1506{ 1507 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1508 int *ccr = ps->ccr_busy; 1509 /* If the latency of the register is greater than the current wait 1510 then update the current wait. */ 1511 if (in_CCR >= 0 && ccr[in_CCR] > ps->vliw_wait) 1512 { 1513 if (TRACE_INSN_P (cpu)) 1514 { 1515 if (in_CCR > 3) 1516 sprintf (hazard_name, "Data hazard for icc%d:", in_CCR-4); 1517 else 1518 sprintf (hazard_name, "Data hazard for fcc%d:", in_CCR); 1519 } 1520 ps->vliw_wait = ccr[in_CCR]; 1521 } 1522} 1523 1524/* Check the availability of the given ACC register and update the number 1525 of cycles the current VLIW insn must wait until it is available. */ 1526void 1527vliw_wait_for_ACC (SIM_CPU *cpu, INT in_ACC) 1528{ 1529 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1530 int *acc = ps->acc_busy; 1531 /* If the latency of the register is greater than the current wait 1532 then update the current wait. */ 1533 if (in_ACC >= 0 && acc[in_ACC] > ps->vliw_wait) 1534 { 1535 if (TRACE_INSN_P (cpu)) 1536 sprintf (hazard_name, "Data hazard for acc%d:", in_ACC); 1537 ps->vliw_wait = acc[in_ACC]; 1538 } 1539} 1540 1541/* Check the availability of the given SPR register and update the number 1542 of cycles the current VLIW insn must wait until it is available. */ 1543void 1544vliw_wait_for_SPR (SIM_CPU *cpu, INT in_SPR) 1545{ 1546 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1547 int *spr = ps->spr_busy; 1548 /* If the latency of the register is greater than the current wait 1549 then update the current wait. */ 1550 if (in_SPR >= 0 && spr[in_SPR] > ps->vliw_wait) 1551 { 1552 if (TRACE_INSN_P (cpu)) 1553 sprintf (hazard_name, "Data hazard for spr %d:", in_SPR); 1554 ps->vliw_wait = spr[in_SPR]; 1555 } 1556} 1557 1558/* Check the availability of the given integer division resource and update 1559 the number of cycles the current VLIW insn must wait until it is available. 1560*/ 1561void 1562vliw_wait_for_idiv_resource (SIM_CPU *cpu, INT in_resource) 1563{ 1564 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1565 int *r = ps->idiv_busy; 1566 /* If the latency of the resource is greater than the current wait 1567 then update the current wait. */ 1568 if (r[in_resource] > ps->vliw_wait) 1569 { 1570 if (TRACE_INSN_P (cpu)) 1571 { 1572 sprintf (hazard_name, "Resource hazard for integer division in slot I%d:", in_resource); 1573 } 1574 ps->vliw_wait = r[in_resource]; 1575 } 1576} 1577 1578/* Check the availability of the given float division resource and update 1579 the number of cycles the current VLIW insn must wait until it is available. 1580*/ 1581void 1582vliw_wait_for_fdiv_resource (SIM_CPU *cpu, INT in_resource) 1583{ 1584 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1585 int *r = ps->fdiv_busy; 1586 /* If the latency of the resource is greater than the current wait 1587 then update the current wait. */ 1588 if (r[in_resource] > ps->vliw_wait) 1589 { 1590 if (TRACE_INSN_P (cpu)) 1591 { 1592 sprintf (hazard_name, "Resource hazard for floating point division in slot F%d:", in_resource); 1593 } 1594 ps->vliw_wait = r[in_resource]; 1595 } 1596} 1597 1598/* Check the availability of the given float square root resource and update 1599 the number of cycles the current VLIW insn must wait until it is available. 1600*/ 1601void 1602vliw_wait_for_fsqrt_resource (SIM_CPU *cpu, INT in_resource) 1603{ 1604 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1605 int *r = ps->fsqrt_busy; 1606 /* If the latency of the resource is greater than the current wait 1607 then update the current wait. */ 1608 if (r[in_resource] > ps->vliw_wait) 1609 { 1610 if (TRACE_INSN_P (cpu)) 1611 { 1612 sprintf (hazard_name, "Resource hazard for square root in slot F%d:", in_resource); 1613 } 1614 ps->vliw_wait = r[in_resource]; 1615 } 1616} 1617 1618/* Check the availability of the given float unit resource and update 1619 the number of cycles the current VLIW insn must wait until it is available. 1620*/ 1621void 1622vliw_wait_for_float_resource (SIM_CPU *cpu, INT in_resource) 1623{ 1624 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1625 int *r = ps->float_busy; 1626 /* If the latency of the resource is greater than the current wait 1627 then update the current wait. */ 1628 if (r[in_resource] > ps->vliw_wait) 1629 { 1630 if (TRACE_INSN_P (cpu)) 1631 { 1632 sprintf (hazard_name, "Resource hazard for floating point unit in slot F%d:", in_resource); 1633 } 1634 ps->vliw_wait = r[in_resource]; 1635 } 1636} 1637 1638/* Check the availability of the given media unit resource and update 1639 the number of cycles the current VLIW insn must wait until it is available. 1640*/ 1641void 1642vliw_wait_for_media_resource (SIM_CPU *cpu, INT in_resource) 1643{ 1644 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1645 int *r = ps->media_busy; 1646 /* If the latency of the resource is greater than the current wait 1647 then update the current wait. */ 1648 if (r[in_resource] > ps->vliw_wait) 1649 { 1650 if (TRACE_INSN_P (cpu)) 1651 { 1652 sprintf (hazard_name, "Resource hazard for media unit in slot M%d:", in_resource); 1653 } 1654 ps->vliw_wait = r[in_resource]; 1655 } 1656} 1657 1658/* Run the caches until all requests for the given register(s) are satisfied. */ 1659void 1660load_wait_for_GR (SIM_CPU *cpu, INT in_GR) 1661{ 1662 if (in_GR >= 0) 1663 { 1664 int wait = 0; 1665 while (load_pending_for_register (cpu, in_GR, 1/*words*/, REGTYPE_NONE)) 1666 { 1667 frv_model_advance_cycles (cpu, 1); 1668 ++wait; 1669 } 1670 if (wait) 1671 { 1672 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1673 ps->vliw_wait += wait; 1674 ps->vliw_load_stall += wait; 1675 if (TRACE_INSN_P (cpu)) 1676 sprintf (hazard_name, "Data hazard for gr%d:", in_GR); 1677 } 1678 } 1679} 1680 1681void 1682load_wait_for_FR (SIM_CPU *cpu, INT in_FR) 1683{ 1684 if (in_FR >= 0) 1685 { 1686 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1687 int *fr; 1688 int wait = 0; 1689 while (load_pending_for_register (cpu, in_FR, 1/*words*/, REGTYPE_FR)) 1690 { 1691 frv_model_advance_cycles (cpu, 1); 1692 ++wait; 1693 } 1694 /* Post processing time may have been added to the register's 1695 latency after the loads were processed. Account for that too. 1696 */ 1697 fr = ps->fr_busy; 1698 if (fr[in_FR]) 1699 { 1700 wait += fr[in_FR]; 1701 frv_model_advance_cycles (cpu, fr[in_FR]); 1702 } 1703 /* Update the vliw_wait with the number of cycles we waited for the 1704 load and any post-processing. */ 1705 if (wait) 1706 { 1707 ps->vliw_wait += wait; 1708 ps->vliw_load_stall += wait; 1709 if (TRACE_INSN_P (cpu)) 1710 sprintf (hazard_name, "Data hazard for fr%d:", in_FR); 1711 } 1712 } 1713} 1714 1715void 1716load_wait_for_GRdouble (SIM_CPU *cpu, INT in_GR) 1717{ 1718 if (in_GR >= 0) 1719 { 1720 int wait = 0; 1721 while (load_pending_for_register (cpu, in_GR, 2/*words*/, REGTYPE_NONE)) 1722 { 1723 frv_model_advance_cycles (cpu, 1); 1724 ++wait; 1725 } 1726 if (wait) 1727 { 1728 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1729 ps->vliw_wait += wait; 1730 ps->vliw_load_stall += wait; 1731 if (TRACE_INSN_P (cpu)) 1732 sprintf (hazard_name, "Data hazard for gr%d:", in_GR); 1733 } 1734 } 1735} 1736 1737void 1738load_wait_for_FRdouble (SIM_CPU *cpu, INT in_FR) 1739{ 1740 if (in_FR >= 0) 1741 { 1742 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1743 int *fr; 1744 int wait = 0; 1745 while (load_pending_for_register (cpu, in_FR, 2/*words*/, REGTYPE_FR)) 1746 { 1747 frv_model_advance_cycles (cpu, 1); 1748 ++wait; 1749 } 1750 /* Post processing time may have been added to the registers' 1751 latencies after the loads were processed. Account for that too. 1752 */ 1753 fr = ps->fr_busy; 1754 if (fr[in_FR]) 1755 { 1756 wait += fr[in_FR]; 1757 frv_model_advance_cycles (cpu, fr[in_FR]); 1758 } 1759 if (in_FR < 63) 1760 { 1761 if (fr[in_FR + 1]) 1762 { 1763 wait += fr[in_FR + 1]; 1764 frv_model_advance_cycles (cpu, fr[in_FR + 1]); 1765 } 1766 } 1767 /* Update the vliw_wait with the number of cycles we waited for the 1768 load and any post-processing. */ 1769 if (wait) 1770 { 1771 ps->vliw_wait += wait; 1772 ps->vliw_load_stall += wait; 1773 if (TRACE_INSN_P (cpu)) 1774 sprintf (hazard_name, "Data hazard for fr%d:", in_FR); 1775 } 1776 } 1777} 1778 1779void 1780enforce_full_fr_latency (SIM_CPU *cpu, INT in_FR) 1781{ 1782 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1783 ps->fr_busy_adjust [in_FR] = -1; 1784} 1785 1786/* Calculate how long the post processing for a floating point insn must 1787 wait for resources to become available. */ 1788int 1789post_wait_for_FR (SIM_CPU *cpu, INT in_FR) 1790{ 1791 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1792 int *fr = ps->fr_busy; 1793 1794 if (in_FR >= 0 && fr[in_FR] > ps->post_wait) 1795 { 1796 ps->post_wait = fr[in_FR]; 1797 if (TRACE_INSN_P (cpu)) 1798 sprintf (hazard_name, "Data hazard for fr%d:", in_FR); 1799 } 1800} 1801 1802/* Calculate how long the post processing for a floating point insn must 1803 wait for resources to become available. */ 1804int 1805post_wait_for_FRdouble (SIM_CPU *cpu, INT in_FR) 1806{ 1807 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1808 int *fr = ps->fr_busy; 1809 1810 if (in_FR >= 0) 1811 { 1812 if (fr[in_FR] > ps->post_wait) 1813 { 1814 ps->post_wait = fr[in_FR]; 1815 if (TRACE_INSN_P (cpu)) 1816 sprintf (hazard_name, "Data hazard for fr%d:", in_FR); 1817 } 1818 if (in_FR < 63 && fr[in_FR + 1] > ps->post_wait) 1819 { 1820 ps->post_wait = fr[in_FR + 1]; 1821 if (TRACE_INSN_P (cpu)) 1822 sprintf (hazard_name, "Data hazard for fr%d:", in_FR + 1); 1823 } 1824 } 1825} 1826 1827int 1828post_wait_for_ACC (SIM_CPU *cpu, INT in_ACC) 1829{ 1830 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1831 int *acc = ps->acc_busy; 1832 1833 if (in_ACC >= 0 && acc[in_ACC] > ps->post_wait) 1834 { 1835 ps->post_wait = acc[in_ACC]; 1836 if (TRACE_INSN_P (cpu)) 1837 sprintf (hazard_name, "Data hazard for acc%d:", in_ACC); 1838 } 1839} 1840 1841int 1842post_wait_for_CCR (SIM_CPU *cpu, INT in_CCR) 1843{ 1844 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1845 int *ccr = ps->ccr_busy; 1846 1847 if (in_CCR >= 0 && ccr[in_CCR] > ps->post_wait) 1848 { 1849 ps->post_wait = ccr[in_CCR]; 1850 if (TRACE_INSN_P (cpu)) 1851 { 1852 if (in_CCR > 3) 1853 sprintf (hazard_name, "Data hazard for icc%d:", in_CCR - 4); 1854 else 1855 sprintf (hazard_name, "Data hazard for fcc%d:", in_CCR); 1856 } 1857 } 1858} 1859 1860int 1861post_wait_for_SPR (SIM_CPU *cpu, INT in_SPR) 1862{ 1863 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1864 int *spr = ps->spr_busy; 1865 1866 if (in_SPR >= 0 && spr[in_SPR] > ps->post_wait) 1867 { 1868 ps->post_wait = spr[in_SPR]; 1869 if (TRACE_INSN_P (cpu)) 1870 sprintf (hazard_name, "Data hazard for spr[%d]:", in_SPR); 1871 } 1872} 1873 1874int 1875post_wait_for_fdiv (SIM_CPU *cpu, INT slot) 1876{ 1877 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1878 int *fdiv = ps->fdiv_busy; 1879 1880 /* Multiple floating point divisions in the same slot need only wait 1 1881 extra cycle. */ 1882 if (fdiv[slot] > 0 && 1 > ps->post_wait) 1883 { 1884 ps->post_wait = 1; 1885 if (TRACE_INSN_P (cpu)) 1886 { 1887 sprintf (hazard_name, "Resource hazard for floating point division in slot F%d:", slot); 1888 } 1889 } 1890} 1891 1892int 1893post_wait_for_fsqrt (SIM_CPU *cpu, INT slot) 1894{ 1895 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1896 int *fsqrt = ps->fsqrt_busy; 1897 1898 /* Multiple floating point square roots in the same slot need only wait 1 1899 extra cycle. */ 1900 if (fsqrt[slot] > 0 && 1 > ps->post_wait) 1901 { 1902 ps->post_wait = 1; 1903 if (TRACE_INSN_P (cpu)) 1904 { 1905 sprintf (hazard_name, "Resource hazard for square root in slot F%d:", slot); 1906 } 1907 } 1908} 1909 1910int 1911post_wait_for_float (SIM_CPU *cpu, INT slot) 1912{ 1913 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1914 int *flt = ps->float_busy; 1915 1916 /* Multiple floating point square roots in the same slot need only wait 1 1917 extra cycle. */ 1918 if (flt[slot] > ps->post_wait) 1919 { 1920 ps->post_wait = flt[slot]; 1921 if (TRACE_INSN_P (cpu)) 1922 { 1923 sprintf (hazard_name, "Resource hazard for floating point unit in slot F%d:", slot); 1924 } 1925 } 1926} 1927 1928int 1929post_wait_for_media (SIM_CPU *cpu, INT slot) 1930{ 1931 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1932 int *media = ps->media_busy; 1933 1934 /* Multiple floating point square roots in the same slot need only wait 1 1935 extra cycle. */ 1936 if (media[slot] > ps->post_wait) 1937 { 1938 ps->post_wait = media[slot]; 1939 if (TRACE_INSN_P (cpu)) 1940 { 1941 sprintf (hazard_name, "Resource hazard for media unit in slot M%d:", slot); 1942 } 1943 } 1944} 1945 1946/* Print cpu-specific profile information. */ 1947#define COMMAS(n) sim_add_commas (comma_buf, sizeof (comma_buf), (n)) 1948 1949static void 1950print_cache (SIM_CPU *cpu, FRV_CACHE *cache, const char *cache_name) 1951{ 1952 SIM_DESC sd = CPU_STATE (cpu); 1953 1954 if (cache != NULL) 1955 { 1956 char comma_buf[20]; 1957 unsigned accesses; 1958 1959 sim_io_printf (sd, " %s Cache\n\n", cache_name); 1960 accesses = cache->statistics.accesses; 1961 sim_io_printf (sd, " Total accesses: %s\n", COMMAS (accesses)); 1962 if (accesses != 0) 1963 { 1964 float rate; 1965 unsigned hits = cache->statistics.hits; 1966 sim_io_printf (sd, " Hits: %s\n", COMMAS (hits)); 1967 rate = (float)hits / accesses; 1968 sim_io_printf (sd, " Hit rate: %.2f%%\n", rate * 100); 1969 } 1970 } 1971 else 1972 sim_io_printf (sd, " Model %s has no %s cache\n", 1973 MODEL_NAME (CPU_MODEL (cpu)), cache_name); 1974 1975 sim_io_printf (sd, "\n"); 1976} 1977 1978/* This table must correspond to the UNIT_ATTR table in 1979 opcodes/frv-desc.h. Only the units up to UNIT_C need be 1980 listed since the others cannot occur after mapping. */ 1981static char * 1982slot_names[] = 1983{ 1984 "none", 1985 "I0", "I1", "I01", "I2", "I3", "IALL", 1986 "FM0", "FM1", "FM01", "FM2", "FM3", "FMALL", "FMLOW", 1987 "B0", "B1", "B01", 1988 "C" 1989}; 1990 1991static void 1992print_parallel (SIM_CPU *cpu, int verbose) 1993{ 1994 SIM_DESC sd = CPU_STATE (cpu); 1995 PROFILE_DATA *p = CPU_PROFILE_DATA (cpu); 1996 FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); 1997 unsigned total, vliw; 1998 char comma_buf[20]; 1999 float average; 2000 2001 sim_io_printf (sd, "Model %s Parallelization\n\n", 2002 MODEL_NAME (CPU_MODEL (cpu))); 2003 2004 total = PROFILE_TOTAL_INSN_COUNT (p); 2005 sim_io_printf (sd, " Total instructions: %s\n", COMMAS (total)); 2006 vliw = ps->vliw_insns; 2007 sim_io_printf (sd, " VLIW instructions: %s\n", COMMAS (vliw)); 2008 average = (float)total / vliw; 2009 sim_io_printf (sd, " Average VLIW length: %.2f\n", average); 2010 average = (float)PROFILE_MODEL_TOTAL_CYCLES (p) / vliw; 2011 sim_io_printf (sd, " Cycles per VLIW instruction: %.2f\n", average); 2012 average = (float)total / PROFILE_MODEL_TOTAL_CYCLES (p); 2013 sim_io_printf (sd, " Instructions per cycle: %.2f\n", average); 2014 2015 if (verbose) 2016 { 2017 int i; 2018 int max_val = 0; 2019 int max_name_len = 0; 2020 for (i = UNIT_NIL + 1; i < UNIT_NUM_UNITS; ++i) 2021 { 2022 if (INSNS_IN_SLOT (i)) 2023 { 2024 int len; 2025 if (INSNS_IN_SLOT (i) > max_val) 2026 max_val = INSNS_IN_SLOT (i); 2027 len = strlen (slot_names[i]); 2028 if (len > max_name_len) 2029 max_name_len = len; 2030 } 2031 } 2032 if (max_val > 0) 2033 { 2034 sim_io_printf (sd, "\n"); 2035 sim_io_printf (sd, " Instructions per slot:\n"); 2036 sim_io_printf (sd, "\n"); 2037 for (i = UNIT_NIL + 1; i < UNIT_NUM_UNITS; ++i) 2038 { 2039 if (INSNS_IN_SLOT (i) != 0) 2040 { 2041 sim_io_printf (sd, " %*s: %*s: ", 2042 max_name_len, slot_names[i], 2043 max_val < 10000 ? 5 : 10, 2044 COMMAS (INSNS_IN_SLOT (i))); 2045 sim_profile_print_bar (sd, PROFILE_HISTOGRAM_WIDTH, 2046 INSNS_IN_SLOT (i), 2047 max_val); 2048 sim_io_printf (sd, "\n"); 2049 } 2050 } 2051 } /* details to print */ 2052 } /* verbose */ 2053 2054 sim_io_printf (sd, "\n"); 2055} 2056 2057void 2058frv_profile_info (SIM_CPU *cpu, int verbose) 2059{ 2060 /* FIXME: Need to add smp support. */ 2061 PROFILE_DATA *p = CPU_PROFILE_DATA (cpu); 2062 2063#if WITH_PROFILE_PARALLEL_P 2064 if (PROFILE_FLAGS (p) [PROFILE_PARALLEL_IDX]) 2065 print_parallel (cpu, verbose); 2066#endif 2067 2068#if WITH_PROFILE_CACHE_P 2069 if (PROFILE_FLAGS (p) [PROFILE_CACHE_IDX]) 2070 { 2071 SIM_DESC sd = CPU_STATE (cpu); 2072 sim_io_printf (sd, "Model %s Cache Statistics\n\n", 2073 MODEL_NAME (CPU_MODEL (cpu))); 2074 print_cache (cpu, CPU_INSN_CACHE (cpu), "Instruction"); 2075 print_cache (cpu, CPU_DATA_CACHE (cpu), "Data"); 2076 } 2077#endif /* WITH_PROFILE_CACHE_P */ 2078} 2079 2080/* A hack to get registers referenced for profiling. */ 2081SI frv_ref_SI (SI ref) {return ref;} 2082#endif /* WITH_PROFILE_MODEL_P */ 2083