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