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