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