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