2003-09-24 Dave Brolley <brolley@redhat.com>
[external/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   int *spr;
685   /* This loop handles GR, FR and ACC registers.  */
686   for (i = 0; i < 64; ++i)
687     {
688       if (*gr <= cycles)
689         {
690           *gr = 0;
691           reset_gr_flags (cpu, i);
692         }
693       else
694         *gr -= cycles;
695       /* If the busy drops to 0, then mark the register as
696          "not in use".  */
697       if (*fr <= cycles)
698         {
699           int *fr_lat = ps->fr_latency + i;
700           *fr = 0;
701           ps->fr_busy_adjust[i] = 0;
702           /* Only clear flags if this register has no target latency.  */
703           if (*fr_lat == 0)
704             reset_fr_flags (cpu, i);
705         }
706       else
707         *fr -= cycles;
708       /* If the busy drops to 0, then mark the register as
709          "not in use".  */
710       if (*acc <= cycles)
711         {
712           int *acc_lat = ps->acc_latency + i;
713           *acc = 0;
714           ps->acc_busy_adjust[i] = 0;
715           /* Only clear flags if this register has no target latency.  */
716           if (*acc_lat == 0)
717             reset_acc_flags (cpu, i);
718         }
719       else
720         *acc -= cycles;
721       ++gr;
722       ++fr;
723       ++acc;
724     }
725   /* This loop handles CCR registers.  */
726   ccr = ps->ccr_busy;
727   for (i = 0; i < 8; ++i)
728     {
729       if (*ccr <= cycles)
730         {
731           *ccr = 0;
732           reset_cc_flags (cpu, i);
733         }
734       else
735         *ccr -= cycles;
736       ++ccr;
737     }
738   /* This loop handles SPR registers.  */
739   spr = ps->spr_busy;
740   for (i = 0; i < 4096; ++i)
741     {
742       if (*spr <= cycles)
743         *spr = 0;
744       else
745         *spr -= cycles;
746       ++spr;
747     }
748   /* This loop handles resources.  */
749   idiv = ps->idiv_busy;
750   fdiv = ps->fdiv_busy;
751   fsqrt = ps->fsqrt_busy;
752   for (i = 0; i < 2; ++i)
753     {
754       *idiv = (*idiv <= cycles) ? 0 : (*idiv - cycles);
755       *fdiv = (*fdiv <= cycles) ? 0 : (*fdiv - cycles);
756       *fsqrt = (*fsqrt <= cycles) ? 0 : (*fsqrt - cycles);
757       ++idiv;
758       ++fdiv;
759       ++fsqrt;
760     }
761 }
762
763 /* Print information about the wait for the given number of cycles.  */
764 void
765 frv_model_trace_wait_cycles (SIM_CPU *cpu, int cycles, const char *hazard_name)
766 {
767   if (TRACE_INSN_P (cpu) && cycles > 0)
768     {
769       SIM_DESC sd = CPU_STATE (cpu);
770       trace_printf (sd, cpu, "**** %s wait %d cycles ***\n",
771                     hazard_name, cycles);
772     }
773 }
774
775 void
776 trace_vliw_wait_cycles (SIM_CPU *cpu)
777 {
778   if (TRACE_INSN_P (cpu))
779     {
780       FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
781       frv_model_trace_wait_cycles (cpu, ps->vliw_wait, hazard_name);
782     }
783 }
784
785 /* Wait for the given number of cycles.  */
786 void
787 frv_model_advance_cycles (SIM_CPU *cpu, int cycles)
788 {
789   PROFILE_DATA *p = CPU_PROFILE_DATA (cpu);
790   update_latencies (cpu, cycles);
791   run_caches (cpu, cycles);
792   PROFILE_MODEL_TOTAL_CYCLES (p) += cycles;
793 }
794
795 void
796 handle_resource_wait (SIM_CPU *cpu)
797 {
798   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
799   if (ps->vliw_wait != 0)
800     frv_model_advance_cycles (cpu, ps->vliw_wait);
801   if (ps->vliw_load_stall > ps->vliw_wait)
802     ps->vliw_load_stall -= ps->vliw_wait;
803   else
804     ps->vliw_load_stall = 0;
805 }
806
807 /* Account for the number of cycles until these resources will be available
808    again.  */
809 static void
810 update_target_latencies (SIM_CPU *cpu)
811 {
812   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
813   int i;
814   /* update the latencies of the registers.  */
815   int *ccr_lat;
816   int *gr_lat  = ps->gr_latency;
817   int *fr_lat  = ps->fr_latency;
818   int *acc_lat = ps->acc_latency;
819   int *spr_lat;
820   int *ccr;
821   int *gr = ps->gr_busy;
822   int  *fr = ps->fr_busy;
823   int  *acc = ps->acc_busy;
824   int *spr;
825   /* This loop handles GR, FR and ACC registers.  */
826   for (i = 0; i < 64; ++i)
827     {
828       if (*gr_lat)
829         {
830           *gr = *gr_lat;
831           *gr_lat = 0;
832         }
833       if (*fr_lat)
834         {
835           *fr = *fr_lat;
836           *fr_lat = 0;
837         }
838       if (*acc_lat)
839         {
840           *acc = *acc_lat;
841           *acc_lat = 0;
842         }
843       ++gr; ++gr_lat;
844       ++fr; ++fr_lat;
845       ++acc; ++acc_lat;
846     }
847   /* This loop handles CCR registers.  */
848   ccr = ps->ccr_busy;
849   ccr_lat = ps->ccr_latency;
850   for (i = 0; i < 8; ++i)
851     {
852       if (*ccr_lat)
853         {
854           *ccr = *ccr_lat;
855           *ccr_lat = 0;
856         }
857       ++ccr; ++ccr_lat;
858     }
859   /* This loop handles SPR registers.  */
860   spr = ps->spr_busy;
861   spr_lat = ps->spr_latency;
862   for (i = 0; i < 4096; ++i)
863     {
864       if (*spr_lat)
865         {
866           *spr = *spr_lat;
867           *spr_lat = 0;
868         }
869       ++spr; ++spr_lat;
870     }
871 }
872
873 /* Run the caches until all pending cache flushes are complete.  */
874 static void
875 wait_for_flush (SIM_CPU *cpu)
876 {
877   SI address = CPU_LOAD_ADDRESS (cpu);
878   int wait = 0;
879   while (flush_pending_for_address (cpu, address))
880     {
881       frv_model_advance_cycles (cpu, 1);
882       ++wait;
883     }
884   if (TRACE_INSN_P (cpu) && wait)
885     {
886       sprintf (hazard_name, "Data cache flush address %p:", address);
887       frv_model_trace_wait_cycles (cpu, wait, hazard_name);
888     }
889 }
890
891 /* Initialize cycle counting for an insn.
892    FIRST_P is non-zero if this is the first insn in a set of parallel
893    insns.  */
894 void
895 frvbf_model_insn_before (SIM_CPU *cpu, int first_p)
896 {
897   SIM_DESC sd = CPU_STATE (cpu);
898   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
899
900   ps->vliw_wait = 0;
901   ps->post_wait = 0;
902   memset (ps->fr_busy_adjust, 0, sizeof (ps->fr_busy_adjust));
903   memset (ps->acc_busy_adjust, 0, sizeof (ps->acc_busy_adjust));
904
905   if (first_p)
906     {
907       ps->vliw_insns++;
908       ps->vliw_cycles = 0;
909       ps->vliw_branch_taken = 0;
910       ps->vliw_load_stall = 0;
911     }
912
913   switch (STATE_ARCHITECTURE (sd)->mach)
914     {
915     case bfd_mach_fr400:
916       fr400_model_insn_before (cpu, first_p);
917       break;
918     case bfd_mach_fr500:
919       fr500_model_insn_before (cpu, first_p);
920       break;
921     default:
922       break;
923     }
924
925   if (first_p)
926     wait_for_flush (cpu);
927 }
928
929 /* Record the cycles computed for an insn.
930    LAST_P is non-zero if this is the last insn in a set of parallel insns,
931    and we update the total cycle count.
932    CYCLES is the cycle count of the insn.  */
933
934 void
935 frvbf_model_insn_after (SIM_CPU *cpu, int last_p, int cycles)
936 {
937   PROFILE_DATA *p = CPU_PROFILE_DATA (cpu);
938   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
939   SIM_DESC sd = CPU_STATE (cpu);
940
941   PROFILE_MODEL_CUR_INSN_CYCLES (p) = cycles;
942
943   /* The number of cycles for a VLIW insn is the maximum number of cycles
944      used by any individual insn within it.  */
945   if (cycles > ps->vliw_cycles)
946     ps->vliw_cycles = cycles;
947
948   if (last_p)
949     {
950       /*  This is the last insn in a VLIW insn.  */
951       struct frv_interrupt_timer *timer = & frv_interrupt_state.timer;
952
953       activate_cache_requests (cpu); /* before advancing cycles.  */
954       apply_latency_adjustments (cpu); /* must go first.  */ 
955       update_target_latencies (cpu); /* must go next.  */ 
956       frv_model_advance_cycles (cpu, ps->vliw_cycles);
957
958       PROFILE_MODEL_LOAD_STALL_CYCLES (p) += ps->vliw_load_stall;
959
960       /* Check the interrupt timer.  cycles contains the total cycle count.  */
961       if (timer->enabled)
962         {
963           cycles = PROFILE_MODEL_TOTAL_CYCLES (p);
964           if (timer->current % timer->value
965               + (cycles - timer->current) >= timer->value)
966             frv_queue_external_interrupt (cpu, timer->interrupt);
967           timer->current = cycles;
968         }
969
970       ps->past_first_p = 0; /* Next one will be the first in a new VLIW.  */
971       ps->branch_address = -1;
972     }
973   else
974     ps->past_first_p = 1;
975
976   switch (STATE_ARCHITECTURE (sd)->mach)
977     {
978     case bfd_mach_fr400:
979       fr400_model_insn_after (cpu, last_p, cycles);
980       break;
981     case bfd_mach_fr500:
982       fr500_model_insn_after (cpu, last_p, cycles);
983       break;
984     default:
985       break;
986     }
987 }
988
989 USI
990 frvbf_model_branch (SIM_CPU *current_cpu, PCADDR target, int hint)
991 {
992   /* Record the hint and branch address for use in profiling.  */
993   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (current_cpu);
994   ps->branch_hint = hint;
995   ps->branch_address = target;
996 }
997
998 /* Top up the latency of the given GR by the given number of cycles.  */
999 void
1000 update_GR_latency (SIM_CPU *cpu, INT out_GR, int cycles)
1001 {
1002   if (out_GR >= 0)
1003     {
1004       FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1005       int *gr = ps->gr_latency;
1006       if (gr[out_GR] < cycles)
1007         gr[out_GR] = cycles;
1008     }
1009 }
1010
1011 void
1012 decrease_GR_busy (SIM_CPU *cpu, INT in_GR, int cycles)
1013 {
1014   if (in_GR >= 0)
1015     {
1016       FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1017       int *gr = ps->gr_busy;
1018       gr[in_GR] -= cycles;
1019     }
1020 }
1021
1022 /* Top up the latency of the given double GR by the number of cycles.  */
1023 void
1024 update_GRdouble_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       if (out_GR < 63 && gr[out_GR + 1] < cycles)
1033         gr[out_GR + 1] = cycles;
1034     }
1035 }
1036
1037 void
1038 update_GR_latency_for_load (SIM_CPU *cpu, INT out_GR, int cycles)
1039 {
1040   if (out_GR >= 0)
1041     {
1042       FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1043       int *gr = ps->gr_latency;
1044
1045       /* The latency of the GR will be at least the number of cycles used
1046          by the insn.  */
1047       if (gr[out_GR] < cycles)
1048         gr[out_GR] = cycles;
1049
1050       /* The latency will also depend on how long it takes to retrieve the
1051          data from the cache or memory.  Assume that the load is issued
1052          after the last cycle of the insn.  */
1053       request_cache_load (cpu, out_GR, REGTYPE_NONE, cycles);
1054     }
1055 }
1056
1057 void
1058 update_GRdouble_latency_for_load (SIM_CPU *cpu, INT out_GR, int cycles)
1059 {
1060   if (out_GR >= 0)
1061     {
1062       FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1063       int *gr = ps->gr_latency;
1064
1065       /* The latency of the GR will be at least the number of cycles used
1066          by the insn.  */
1067       if (gr[out_GR] < cycles)
1068         gr[out_GR] = cycles;
1069       if (out_GR < 63 && gr[out_GR + 1] < cycles)
1070         gr[out_GR + 1] = cycles;
1071
1072       /* The latency will also depend on how long it takes to retrieve the
1073          data from the cache or memory.  Assume that the load is issued
1074          after the last cycle of the insn.  */
1075       request_cache_load (cpu, out_GR, REGTYPE_NONE, cycles);
1076     }
1077 }
1078
1079 void
1080 update_GR_latency_for_swap (SIM_CPU *cpu, INT out_GR, int cycles)
1081 {
1082   update_GR_latency_for_load (cpu, out_GR, cycles);
1083 }
1084
1085 /* Top up the latency of the given FR by the given number of cycles.  */
1086 void
1087 update_FR_latency (SIM_CPU *cpu, INT out_FR, int cycles)
1088 {
1089   if (out_FR >= 0)
1090     {
1091       FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1092       int *fr = ps->fr_latency;
1093       if (fr[out_FR] < cycles)
1094         fr[out_FR] = cycles;
1095     }
1096 }
1097
1098 /* Top up the latency of the given double FR by the number of cycles.  */
1099 void
1100 update_FRdouble_latency (SIM_CPU *cpu, INT out_FR, int cycles)
1101 {
1102   if (out_FR >= 0)
1103     {
1104       FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1105       int *fr = ps->fr_latency;
1106       if (fr[out_FR] < cycles)
1107         fr[out_FR] = cycles;
1108       if (out_FR < 63 && fr[out_FR + 1] < cycles)
1109         fr[out_FR + 1] = cycles;
1110     }
1111 }
1112
1113 void
1114 update_FR_latency_for_load (SIM_CPU *cpu, INT out_FR, int cycles)
1115 {
1116   if (out_FR >= 0)
1117     {
1118       FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1119       int *fr = ps->fr_latency;
1120
1121       /* The latency of the FR will be at least the number of cycles used
1122          by the insn.  */
1123       if (fr[out_FR] < cycles)
1124         fr[out_FR] = cycles;
1125
1126       /* The latency will also depend on how long it takes to retrieve the
1127          data from the cache or memory.  Assume that the load is issued
1128          after the last cycle of the insn.  */
1129       request_cache_load (cpu, out_FR, REGTYPE_FR, cycles);
1130     }
1131 }
1132
1133 void
1134 update_FRdouble_latency_for_load (SIM_CPU *cpu, INT out_FR, int cycles)
1135 {
1136   if (out_FR >= 0)
1137     {
1138       FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1139       int *fr = ps->fr_latency;
1140           
1141       /* The latency of the FR will be at least the number of cycles used
1142          by the insn.  */
1143       if (fr[out_FR] < cycles)
1144         fr[out_FR] = cycles;
1145       if (out_FR < 63 && fr[out_FR + 1] < cycles)
1146         fr[out_FR + 1] = cycles;
1147
1148       /* The latency will also depend on how long it takes to retrieve the
1149          data from the cache or memory.  Assume that the load is issued
1150          after the last cycle of the insn.  */
1151       request_cache_load (cpu, out_FR, REGTYPE_FR, cycles);
1152     }
1153 }
1154
1155 /* Top up the post-processing time of the given FR by the given number of
1156    cycles.  */
1157 void
1158 update_FR_ptime (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       /* If a load is pending on this register, then add the cycles to
1164          the post processing time for this register. Otherwise apply it
1165          directly to the latency of the register.  */
1166       if (! load_pending_for_register (cpu, out_FR, 1, REGTYPE_FR))
1167         {
1168           int *fr = ps->fr_latency;
1169           fr[out_FR] += cycles;
1170         }
1171       else
1172         ps->fr_ptime[out_FR] += cycles;
1173     }
1174 }
1175
1176 void
1177 update_FRdouble_ptime (SIM_CPU *cpu, INT out_FR, int cycles)
1178 {
1179   if (out_FR >= 0)
1180     {
1181       FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1182       /* If a load is pending on this register, then add the cycles to
1183          the post processing time for this register. Otherwise apply it
1184          directly to the latency of the register.  */
1185       if (! load_pending_for_register (cpu, out_FR, 2, REGTYPE_FR))
1186         {
1187           int *fr = ps->fr_latency;
1188           fr[out_FR] += cycles;
1189           if (out_FR < 63)
1190             fr[out_FR + 1] += cycles;
1191         }
1192       else
1193         {
1194           ps->fr_ptime[out_FR] += cycles;
1195           if (out_FR < 63)
1196             ps->fr_ptime[out_FR + 1] += cycles;
1197         }
1198     }
1199 }
1200
1201 /* Top up the post-processing time of the given ACC by the given number of
1202    cycles.  */
1203 void
1204 update_ACC_ptime (SIM_CPU *cpu, INT out_ACC, int cycles)
1205 {
1206   if (out_ACC >= 0)
1207     {
1208       FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1209       /* No load can be pending on this register. Apply the cycles
1210          directly to the latency of the register.  */
1211       int *acc = ps->acc_latency;
1212       acc[out_ACC] += cycles;
1213     }
1214 }
1215
1216 /* Top up the post-processing time of the given SPR by the given number of
1217    cycles.  */
1218 void
1219 update_SPR_ptime (SIM_CPU *cpu, INT out_SPR, int cycles)
1220 {
1221   if (out_SPR >= 0)
1222     {
1223       FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1224       /* No load can be pending on this register. Apply the cycles
1225          directly to the latency of the register.  */
1226       int *spr = ps->spr_latency;
1227       spr[out_SPR] += cycles;
1228     }
1229 }
1230
1231 void
1232 decrease_ACC_busy (SIM_CPU *cpu, INT out_ACC, int cycles)
1233 {
1234   if (out_ACC >= 0)
1235     {
1236       FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1237       int *acc = ps->acc_busy;
1238       acc[out_ACC] -= cycles;
1239       if (ps->acc_busy_adjust[out_ACC] >= 0
1240           && cycles > ps->acc_busy_adjust[out_ACC])
1241         ps->acc_busy_adjust[out_ACC] = cycles;
1242     }
1243 }
1244
1245 /* start-sanitize-frv */
1246 void
1247 increase_ACC_busy (SIM_CPU *cpu, INT out_ACC, int cycles)
1248 {
1249   if (out_ACC >= 0)
1250     {
1251       FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1252       int *acc = ps->acc_busy;
1253       acc[out_ACC] += cycles;
1254     }
1255 }
1256
1257 void
1258 enforce_full_acc_latency (SIM_CPU *cpu, INT in_ACC)
1259 {
1260   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1261   ps->acc_busy_adjust [in_ACC] = -1;
1262 }
1263
1264 /* end-sanitize-frv */
1265 void
1266 decrease_FR_busy (SIM_CPU *cpu, INT out_FR, int cycles)
1267 {
1268   if (out_FR >= 0)
1269     {
1270       FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1271       int *fr = ps->fr_busy;
1272       fr[out_FR] -= cycles;
1273       if (ps->fr_busy_adjust[out_FR] >= 0
1274           && cycles > ps->fr_busy_adjust[out_FR])
1275         ps->fr_busy_adjust[out_FR] = cycles;
1276     }
1277 }
1278
1279 void
1280 increase_FR_busy (SIM_CPU *cpu, INT out_FR, int cycles)
1281 {
1282   if (out_FR >= 0)
1283     {
1284       FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1285       int *fr = ps->fr_busy;
1286       fr[out_FR] += cycles;
1287     }
1288 }
1289
1290 /* Top up the latency of the given ACC by the given number of cycles.  */
1291 void
1292 update_ACC_latency (SIM_CPU *cpu, INT out_ACC, int cycles)
1293 {
1294   if (out_ACC >= 0)
1295     {
1296       FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1297       int *acc = ps->acc_latency;
1298       if (acc[out_ACC] < cycles)
1299         acc[out_ACC] = cycles;
1300     }
1301 }
1302
1303 /* Top up the latency of the given CCR by the given number of cycles.  */
1304 void
1305 update_CCR_latency (SIM_CPU *cpu, INT out_CCR, int cycles)
1306 {
1307   if (out_CCR >= 0)
1308     {
1309       FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1310       int *ccr = ps->ccr_latency;
1311       if (ccr[out_CCR] < cycles)
1312         ccr[out_CCR] = cycles;
1313     }
1314 }
1315
1316 /* Top up the latency of the given SPR by the given number of cycles.  */
1317 void
1318 update_SPR_latency (SIM_CPU *cpu, INT out_SPR, int cycles)
1319 {
1320   if (out_SPR >= 0)
1321     {
1322       FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1323       int *spr = ps->spr_latency;
1324       if (spr[out_SPR] < cycles)
1325         spr[out_SPR] = cycles;
1326     }
1327 }
1328
1329 /* Top up the latency of the given integer division resource by the given
1330    number of cycles.  */
1331 void
1332 update_idiv_resource_latency (SIM_CPU *cpu, INT in_resource, int cycles)
1333 {
1334   /* operate directly on the busy cycles since each resource can only
1335      be used once in a VLIW insn.  */
1336   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1337   int *r = ps->idiv_busy;
1338   r[in_resource] = cycles;
1339 }
1340
1341 /* Set the latency of the given resource to the given number of cycles.  */
1342 void
1343 update_fdiv_resource_latency (SIM_CPU *cpu, INT in_resource, int cycles)
1344 {
1345   /* operate directly on the busy cycles since each resource can only
1346      be used once in a VLIW insn.  */
1347   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1348   int *r = ps->fdiv_busy;
1349   r[in_resource] = cycles;
1350 }
1351
1352 /* Set the latency of the given resource to the given number of cycles.  */
1353 void
1354 update_fsqrt_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->fsqrt_busy;
1360   r[in_resource] = cycles;
1361 }
1362
1363 /* Set the branch penalty to the given number of cycles.  */
1364 void
1365 update_branch_penalty (SIM_CPU *cpu, int cycles)
1366 {
1367   /* operate directly on the busy cycles since only one branch can occur
1368      in a VLIW insn.  */
1369   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1370   ps->branch_penalty = cycles;
1371 }
1372
1373 /* Check the availability of the given GR register and update the number
1374    of cycles the current VLIW insn must wait until it is available.  */
1375 void
1376 vliw_wait_for_GR (SIM_CPU *cpu, INT in_GR)
1377 {
1378   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1379   int *gr = ps->gr_busy;
1380   /* If the latency of the register is greater than the current wait
1381      then update the current wait.  */
1382   if (in_GR >= 0 && gr[in_GR] > ps->vliw_wait)
1383     {
1384       if (TRACE_INSN_P (cpu))
1385         sprintf (hazard_name, "Data hazard for gr%d:", in_GR);
1386       ps->vliw_wait = gr[in_GR];
1387     }
1388 }
1389
1390 /* Check the availability of the given GR register and update the number
1391    of cycles the current VLIW insn must wait until it is available.  */
1392 void
1393 vliw_wait_for_GRdouble (SIM_CPU *cpu, INT in_GR)
1394 {
1395   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1396   int *gr = ps->gr_busy;
1397   /* If the latency of the register is greater than the current wait
1398      then update the current wait.  */
1399   if (in_GR >= 0)
1400     {
1401       if (gr[in_GR] > ps->vliw_wait)
1402         {
1403           if (TRACE_INSN_P (cpu))
1404             sprintf (hazard_name, "Data hazard for gr%d:", in_GR);
1405           ps->vliw_wait = gr[in_GR];
1406         }
1407       if (in_GR < 63 && gr[in_GR + 1] > ps->vliw_wait)
1408         {
1409           if (TRACE_INSN_P (cpu))
1410             sprintf (hazard_name, "Data hazard for gr%d:", in_GR + 1);
1411           ps->vliw_wait = gr[in_GR + 1];
1412         }
1413     }
1414 }
1415
1416 /* Check the availability of the given FR register and update the number
1417    of cycles the current VLIW insn must wait until it is available.  */
1418 void
1419 vliw_wait_for_FR (SIM_CPU *cpu, INT in_FR)
1420 {
1421   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1422   int *fr = ps->fr_busy;
1423   /* If the latency of the register is greater than the current wait
1424      then update the current wait.  */
1425   if (in_FR >= 0 && fr[in_FR] > ps->vliw_wait)
1426     {
1427       if (TRACE_INSN_P (cpu))
1428         sprintf (hazard_name, "Data hazard for fr%d:", in_FR);
1429       ps->vliw_wait = fr[in_FR];
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_FRdouble (SIM_CPU *cpu, INT in_FR)
1437 {
1438   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1439   int *fr = ps->fr_busy;
1440   /* If the latency of the register is greater than the current wait
1441      then update the current wait.  */
1442   if (in_FR >= 0)
1443     {
1444       if (fr[in_FR] > ps->vliw_wait)
1445         {
1446           if (TRACE_INSN_P (cpu))
1447             sprintf (hazard_name, "Data hazard for fr%d:", in_FR);
1448           ps->vliw_wait = fr[in_FR];
1449         }
1450       if (in_FR < 63 && fr[in_FR + 1] > ps->vliw_wait)
1451         {
1452           if (TRACE_INSN_P (cpu))
1453             sprintf (hazard_name, "Data hazard for fr%d:", in_FR + 1);
1454           ps->vliw_wait = fr[in_FR + 1];
1455         }
1456     }
1457 }
1458
1459 /* Check the availability of the given CCR register and update the number
1460    of cycles the current VLIW insn must wait until it is available.  */
1461 void
1462 vliw_wait_for_CCR (SIM_CPU *cpu, INT in_CCR)
1463 {
1464   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1465   int *ccr = ps->ccr_busy;
1466   /* If the latency of the register is greater than the current wait
1467      then update the current wait.  */
1468   if (in_CCR >= 0 && ccr[in_CCR] > ps->vliw_wait)
1469     {
1470       if (TRACE_INSN_P (cpu))
1471         {
1472           if (in_CCR > 3)
1473             sprintf (hazard_name, "Data hazard for icc%d:", in_CCR-4);
1474           else
1475             sprintf (hazard_name, "Data hazard for fcc%d:", in_CCR);
1476         }
1477       ps->vliw_wait = ccr[in_CCR];
1478     }
1479 }
1480
1481 /* Check the availability of the given ACC register and update the number
1482    of cycles the current VLIW insn must wait until it is available.  */
1483 void
1484 vliw_wait_for_ACC (SIM_CPU *cpu, INT in_ACC)
1485 {
1486   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1487   int *acc = ps->acc_busy;
1488   /* If the latency of the register is greater than the current wait
1489      then update the current wait.  */
1490   if (in_ACC >= 0 && acc[in_ACC] > ps->vliw_wait)
1491     {
1492       if (TRACE_INSN_P (cpu))
1493         sprintf (hazard_name, "Data hazard for acc%d:", in_ACC);
1494       ps->vliw_wait = acc[in_ACC];
1495     }
1496 }
1497
1498 /* Check the availability of the given SPR register and update the number
1499    of cycles the current VLIW insn must wait until it is available.  */
1500 void
1501 vliw_wait_for_SPR (SIM_CPU *cpu, INT in_SPR)
1502 {
1503   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1504   int *spr = ps->spr_busy;
1505   /* If the latency of the register is greater than the current wait
1506      then update the current wait.  */
1507   if (in_SPR >= 0 && spr[in_SPR] > ps->vliw_wait)
1508     {
1509       if (TRACE_INSN_P (cpu))
1510         sprintf (hazard_name, "Data hazard for spr %d:", in_SPR);
1511       ps->vliw_wait = spr[in_SPR];
1512     }
1513 }
1514
1515 /* Check the availability of the given integer division resource and update
1516    the number of cycles the current VLIW insn must wait until it is available.
1517 */
1518 void
1519 vliw_wait_for_idiv_resource (SIM_CPU *cpu, INT in_resource)
1520 {
1521   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1522   int *r = ps->idiv_busy;
1523   /* If the latency of the resource is greater than the current wait
1524      then update the current wait.  */
1525   if (r[in_resource] > ps->vliw_wait)
1526     {
1527       if (TRACE_INSN_P (cpu))
1528         {
1529           sprintf (hazard_name, "Resource hazard for integer division in slot I%d:", in_resource);
1530         }
1531       ps->vliw_wait = r[in_resource];
1532     }
1533 }
1534
1535 /* Check the availability of the given float division resource and update
1536    the number of cycles the current VLIW insn must wait until it is available.
1537 */
1538 void
1539 vliw_wait_for_fdiv_resource (SIM_CPU *cpu, INT in_resource)
1540 {
1541   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1542   int *r = ps->fdiv_busy;
1543   /* If the latency of the resource is greater than the current wait
1544      then update the current wait.  */
1545   if (r[in_resource] > ps->vliw_wait)
1546     {
1547       if (TRACE_INSN_P (cpu))
1548         {
1549           sprintf (hazard_name, "Resource hazard for floating point division in slot F%d:", in_resource);
1550         }
1551       ps->vliw_wait = r[in_resource];
1552     }
1553 }
1554
1555 /* Check the availability of the given float square root resource and update
1556    the number of cycles the current VLIW insn must wait until it is available.
1557 */
1558 void
1559 vliw_wait_for_fsqrt_resource (SIM_CPU *cpu, INT in_resource)
1560 {
1561   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1562   int *r = ps->fsqrt_busy;
1563   /* If the latency of the resource is greater than the current wait
1564      then update the current wait.  */
1565   if (r[in_resource] > ps->vliw_wait)
1566     {
1567       if (TRACE_INSN_P (cpu))
1568         {
1569           sprintf (hazard_name, "Resource hazard for square root in slot F%d:", in_resource);
1570         }
1571       ps->vliw_wait = r[in_resource];
1572     }
1573 }
1574
1575 /* Run the caches until all requests for the given register(s) are satisfied. */
1576 void
1577 load_wait_for_GR (SIM_CPU *cpu, INT in_GR)
1578 {
1579   if (in_GR >= 0)
1580     {
1581       int wait = 0;
1582       while (load_pending_for_register (cpu, in_GR, 1/*words*/, REGTYPE_NONE))
1583         {
1584           frv_model_advance_cycles (cpu, 1);
1585           ++wait;
1586         }
1587       if (wait)
1588         {
1589           FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1590           ps->vliw_wait += wait;
1591           ps->vliw_load_stall += wait;
1592           if (TRACE_INSN_P (cpu))
1593             sprintf (hazard_name, "Data hazard for gr%d:", in_GR);
1594         }
1595     }
1596 }
1597
1598 void
1599 load_wait_for_FR (SIM_CPU *cpu, INT in_FR)
1600 {
1601   if (in_FR >= 0)
1602     {
1603       FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1604       int *fr;
1605       int wait = 0;
1606       while (load_pending_for_register (cpu, in_FR, 1/*words*/, REGTYPE_FR))
1607         {
1608           frv_model_advance_cycles (cpu, 1);
1609           ++wait;
1610         }
1611       /* Post processing time may have been added to the register's
1612          latency after the loads were processed. Account for that too.
1613       */
1614       fr = ps->fr_busy;
1615       if (fr[in_FR])
1616         {
1617           wait += fr[in_FR];
1618           frv_model_advance_cycles (cpu, fr[in_FR]);
1619         }
1620       /* Update the vliw_wait with the number of cycles we waited for the
1621          load and any post-processing.  */
1622       if (wait)
1623         {
1624           ps->vliw_wait += wait;
1625           ps->vliw_load_stall += wait;
1626           if (TRACE_INSN_P (cpu))
1627             sprintf (hazard_name, "Data hazard for fr%d:", in_FR);
1628         }
1629     }
1630 }
1631
1632 void
1633 load_wait_for_GRdouble (SIM_CPU *cpu, INT in_GR)
1634 {
1635   if (in_GR >= 0)
1636     {
1637       int wait = 0;
1638       while (load_pending_for_register (cpu, in_GR, 2/*words*/, REGTYPE_NONE))
1639         {
1640           frv_model_advance_cycles (cpu, 1);
1641           ++wait;
1642         }
1643       if (wait)
1644         {
1645           FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1646           ps->vliw_wait += wait;
1647           ps->vliw_load_stall += wait;
1648           if (TRACE_INSN_P (cpu))
1649             sprintf (hazard_name, "Data hazard for gr%d:", in_GR);
1650         }
1651     }
1652 }
1653
1654 void
1655 load_wait_for_FRdouble (SIM_CPU *cpu, INT in_FR)
1656 {
1657   if (in_FR >= 0)
1658     {
1659       FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1660       int *fr;
1661       int wait = 0;
1662       while (load_pending_for_register (cpu, in_FR, 2/*words*/, REGTYPE_FR))
1663         {
1664           frv_model_advance_cycles (cpu, 1);
1665           ++wait;
1666         }
1667       /* Post processing time may have been added to the registers'
1668          latencies after the loads were processed. Account for that too.
1669       */
1670       fr = ps->fr_busy;
1671       if (fr[in_FR])
1672         {
1673           wait += fr[in_FR];
1674           frv_model_advance_cycles (cpu, fr[in_FR]);
1675         }
1676       if (in_FR < 63)
1677         {
1678           if (fr[in_FR + 1])
1679             {
1680               wait += fr[in_FR + 1];
1681               frv_model_advance_cycles (cpu, fr[in_FR + 1]);
1682             }
1683         }
1684       /* Update the vliw_wait with the number of cycles we waited for the
1685          load and any post-processing.  */
1686       if (wait)
1687         {
1688           ps->vliw_wait += wait;
1689           ps->vliw_load_stall += wait;
1690           if (TRACE_INSN_P (cpu))
1691             sprintf (hazard_name, "Data hazard for fr%d:", in_FR);
1692         }
1693     }
1694 }
1695
1696 void
1697 enforce_full_fr_latency (SIM_CPU *cpu, INT in_FR)
1698 {
1699   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1700   ps->fr_busy_adjust [in_FR] = -1;
1701 }
1702
1703 /* Calculate how long the post processing for a floating point insn must
1704    wait for resources to become available.  */
1705 int
1706 post_wait_for_FR (SIM_CPU *cpu, INT in_FR)
1707 {
1708   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1709   int *fr = ps->fr_busy;
1710
1711   if (in_FR >= 0 && fr[in_FR] > ps->post_wait)
1712     {
1713       ps->post_wait = fr[in_FR];
1714       if (TRACE_INSN_P (cpu))
1715         sprintf (hazard_name, "Data hazard for fr%d:", in_FR);
1716     }
1717 }
1718
1719 /* Calculate how long the post processing for a floating point insn must
1720    wait for resources to become available.  */
1721 int
1722 post_wait_for_FRdouble (SIM_CPU *cpu, INT in_FR)
1723 {
1724   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1725   int *fr = ps->fr_busy;
1726
1727   if (in_FR >= 0)
1728     {
1729       if (fr[in_FR] > ps->post_wait)
1730         {
1731           ps->post_wait = fr[in_FR];
1732           if (TRACE_INSN_P (cpu))
1733             sprintf (hazard_name, "Data hazard for fr%d:", in_FR);
1734         }
1735       if (in_FR < 63 && fr[in_FR + 1] > ps->post_wait)
1736         {
1737           ps->post_wait = fr[in_FR + 1];
1738           if (TRACE_INSN_P (cpu))
1739             sprintf (hazard_name, "Data hazard for fr%d:", in_FR + 1);
1740         }
1741     }
1742 }
1743
1744 int
1745 post_wait_for_ACC (SIM_CPU *cpu, INT in_ACC)
1746 {
1747   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1748   int *acc = ps->acc_busy;
1749
1750   if (in_ACC >= 0 && acc[in_ACC] > ps->post_wait)
1751     {
1752       ps->post_wait = acc[in_ACC];
1753       if (TRACE_INSN_P (cpu))
1754         sprintf (hazard_name, "Data hazard for acc%d:", in_ACC);
1755     }
1756 }
1757
1758 int
1759 post_wait_for_CCR (SIM_CPU *cpu, INT in_CCR)
1760 {
1761   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1762   int *ccr = ps->ccr_busy;
1763
1764   if (in_CCR >= 0 && ccr[in_CCR] > ps->post_wait)
1765     {
1766       ps->post_wait = ccr[in_CCR];
1767       if (TRACE_INSN_P (cpu))
1768         {
1769           if (in_CCR > 3)
1770             sprintf (hazard_name, "Data hazard for icc%d:", in_CCR - 4);
1771           else
1772             sprintf (hazard_name, "Data hazard for fcc%d:", in_CCR);
1773         }
1774     }
1775 }
1776
1777 int
1778 post_wait_for_SPR (SIM_CPU *cpu, INT in_SPR)
1779 {
1780   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1781   int *spr = ps->spr_busy;
1782
1783   if (in_SPR >= 0 && spr[in_SPR] > ps->post_wait)
1784     {
1785       ps->post_wait = spr[in_SPR];
1786       if (TRACE_INSN_P (cpu))
1787         sprintf (hazard_name, "Data hazard for spr[%d]:", in_SPR);
1788     }
1789 }
1790
1791 int
1792 post_wait_for_fdiv (SIM_CPU *cpu, INT slot)
1793 {
1794   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1795   int *fdiv = ps->fdiv_busy;
1796
1797   /* Multiple floating point divisions in the same slot need only wait 1
1798      extra cycle.  */
1799   if (fdiv[slot] > 0 && 1 > ps->post_wait)
1800     {
1801       ps->post_wait = 1;
1802       if (TRACE_INSN_P (cpu))
1803         {
1804           sprintf (hazard_name, "Resource hazard for floating point division in slot F%d:", slot);
1805         }
1806     }
1807 }
1808
1809 int
1810 post_wait_for_fsqrt (SIM_CPU *cpu, INT slot)
1811 {
1812   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1813   int *fsqrt = ps->fsqrt_busy;
1814
1815   /* Multiple floating point square roots in the same slot need only wait 1
1816      extra cycle.  */
1817   if (fsqrt[slot] > 0 && 1 > ps->post_wait)
1818     {
1819       ps->post_wait = 1;
1820       if (TRACE_INSN_P (cpu))
1821         {
1822           sprintf (hazard_name, "Resource hazard for square root in slot F%d:", slot);
1823         }
1824     }
1825 }
1826
1827 /* Print cpu-specific profile information.  */
1828 #define COMMAS(n) sim_add_commas (comma_buf, sizeof (comma_buf), (n))
1829
1830 static void
1831 print_cache (SIM_CPU *cpu, FRV_CACHE *cache, const char *cache_name)
1832 {
1833   SIM_DESC sd = CPU_STATE (cpu);
1834
1835   if (cache != NULL)
1836     {
1837       char comma_buf[20];
1838       unsigned accesses;
1839
1840       sim_io_printf (sd, "  %s Cache\n\n", cache_name);
1841       accesses = cache->statistics.accesses;
1842       sim_io_printf (sd, "    Total accesses:  %s\n", COMMAS (accesses));
1843       if (accesses != 0)
1844         {
1845           float rate;
1846           unsigned hits = cache->statistics.hits;
1847           sim_io_printf (sd, "    Hits:            %s\n", COMMAS (hits));
1848           rate = (float)hits / accesses;
1849           sim_io_printf (sd, "    Hit rate:        %.2f%%\n", rate * 100);
1850         }
1851     }
1852   else
1853     sim_io_printf (sd, "  Model %s has no %s cache\n",
1854                    MODEL_NAME (CPU_MODEL (cpu)), cache_name);
1855
1856   sim_io_printf (sd, "\n");
1857 }
1858
1859 /* This table must correspond to the UNIT_ATTR table in
1860    opcodes/frv-desc.h. Only the units up to UNIT_C need be
1861    listed since the others cannot occur after mapping.  */
1862 static char *
1863 slot_names[] =
1864 {
1865   "none",
1866   "I0", "I1", "I01", "IALL",
1867   "FM0", "FM1", "FM01", "FMALL", "FMLOW",
1868   "B0", "B1", "B01",
1869   "C"
1870 };
1871
1872 static void
1873 print_parallel (SIM_CPU *cpu, int verbose)
1874 {
1875   SIM_DESC sd = CPU_STATE (cpu);
1876   PROFILE_DATA *p = CPU_PROFILE_DATA (cpu);
1877   FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);
1878   unsigned total, vliw;
1879   char comma_buf[20];
1880   float average;
1881
1882   sim_io_printf (sd, "Model %s Parallelization\n\n",
1883                  MODEL_NAME (CPU_MODEL (cpu)));
1884
1885   total = PROFILE_TOTAL_INSN_COUNT (p);
1886   sim_io_printf (sd, "  Total instructions:           %s\n", COMMAS (total));
1887   vliw = ps->vliw_insns;
1888   sim_io_printf (sd, "  VLIW instructions:            %s\n", COMMAS (vliw));
1889   average = (float)total / vliw;
1890   sim_io_printf (sd, "  Average VLIW length:          %.2f\n", average);
1891   average = (float)PROFILE_MODEL_TOTAL_CYCLES (p) / vliw;
1892   sim_io_printf (sd, "  Cycles per VLIW instruction:  %.2f\n", average);
1893   average = (float)total / PROFILE_MODEL_TOTAL_CYCLES (p);
1894   sim_io_printf (sd, "  Instructions per cycle:       %.2f\n", average);
1895
1896   if (verbose)
1897     {
1898       int i;
1899       int max_val = 0;
1900       int max_name_len = 0;
1901       for (i = UNIT_NIL + 1; i < UNIT_NUM_UNITS; ++i)
1902         {
1903           if (INSNS_IN_SLOT (i))
1904             {
1905               int len;
1906               if (INSNS_IN_SLOT (i) > max_val)
1907                 max_val = INSNS_IN_SLOT (i);
1908               len = strlen (slot_names[i]);
1909               if (len > max_name_len)
1910                 max_name_len = len;
1911             }
1912         }
1913       if (max_val > 0)
1914         {
1915           sim_io_printf (sd, "\n");
1916           sim_io_printf (sd, "  Instructions per slot:\n");
1917           sim_io_printf (sd, "\n");
1918           for (i = UNIT_NIL + 1; i < UNIT_NUM_UNITS; ++i)
1919             {
1920               if (INSNS_IN_SLOT (i) != 0)
1921                 {
1922                   sim_io_printf (sd, "  %*s: %*s: ",
1923                                  max_name_len, slot_names[i],
1924                                  max_val < 10000 ? 5 : 10,
1925                                  COMMAS (INSNS_IN_SLOT (i)));
1926                   sim_profile_print_bar (sd, PROFILE_HISTOGRAM_WIDTH,
1927                                          INSNS_IN_SLOT (i),
1928                                          max_val);
1929                   sim_io_printf (sd, "\n");
1930                 }
1931             }
1932         } /* details to print */
1933     } /* verbose */
1934
1935   sim_io_printf (sd, "\n");
1936 }
1937
1938 void
1939 frv_profile_info (SIM_CPU *cpu, int verbose)
1940 {
1941   /* FIXME: Need to add smp support.  */
1942   PROFILE_DATA *p = CPU_PROFILE_DATA (cpu);
1943
1944 #if WITH_PROFILE_PARALLEL_P
1945   if (PROFILE_FLAGS (p) [PROFILE_PARALLEL_IDX])
1946     print_parallel (cpu, verbose);
1947 #endif
1948
1949 #if WITH_PROFILE_CACHE_P
1950   if (PROFILE_FLAGS (p) [PROFILE_CACHE_IDX])
1951     {
1952       SIM_DESC sd = CPU_STATE (cpu);
1953       sim_io_printf (sd, "Model %s Cache Statistics\n\n",
1954                      MODEL_NAME (CPU_MODEL (cpu)));
1955       print_cache (cpu, CPU_INSN_CACHE (cpu), "Instruction");
1956       print_cache (cpu, CPU_DATA_CACHE (cpu), "Data");
1957     }
1958 #endif /* WITH_PROFILE_CACHE_P */
1959 }
1960
1961 /* A hack to get registers referenced for profiling.  */
1962 SI frv_ref_SI (SI ref) {return ref;}
1963 #endif /* WITH_PROFILE_MODEL_P */