PowerPC64 --plt-align
[platform/upstream/binutils.git] / sim / frv / profile.c
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 */