OSDN Git Service

Copyright updates for 2007.
[pf3gnuchains/pf3gnuchains4x.git] / sim / frv / profile-fr550.c
1 /* frv simulator fr550 dependent profiling code.
2
3    Copyright (C) 2003, 2007 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-fr550.h"
33
34 /* Initialize cycle counting for an insn.
35    FIRST_P is non-zero if this is the first insn in a set of parallel
36    insns.  */
37 void
38 fr550_model_insn_before (SIM_CPU *cpu, int first_p)
39 {
40   if (first_p)
41     {
42       MODEL_FR550_DATA *d = CPU_MODEL_DATA (cpu);
43       d->cur_fr_load      = d->prev_fr_load;
44       d->cur_fr_complex_1 = d->prev_fr_complex_1;
45       d->cur_fr_complex_2 = d->prev_fr_complex_2;
46       d->cur_ccr_complex  = d->prev_ccr_complex;
47       d->cur_acc_mmac     = d->prev_acc_mmac;
48     }
49 }
50
51 /* Record the cycles computed for an insn.
52    LAST_P is non-zero if this is the last insn in a set of parallel insns,
53    and we update the total cycle count.
54    CYCLES is the cycle count of the insn.  */
55 void
56 fr550_model_insn_after (SIM_CPU *cpu, int last_p, int cycles)
57 {
58   if (last_p)
59     {
60       MODEL_FR550_DATA *d = CPU_MODEL_DATA (cpu);
61       d->prev_fr_load      = d->cur_fr_load;
62       d->prev_fr_complex_1 = d->cur_fr_complex_1;
63       d->prev_fr_complex_2 = d->cur_fr_complex_2;
64       d->prev_ccr_complex  = d->cur_ccr_complex;
65       d->prev_acc_mmac     = d->cur_acc_mmac;
66     }
67 }
68
69 static void fr550_reset_fr_flags (SIM_CPU *cpu, INT fr);
70 static void fr550_reset_ccr_flags (SIM_CPU *cpu, INT ccr);
71 static void fr550_reset_acc_flags (SIM_CPU *cpu, INT acc);
72
73 static void
74 set_use_is_fr_load (SIM_CPU *cpu, INT fr)
75 {
76   MODEL_FR550_DATA *d = CPU_MODEL_DATA (cpu);
77   fr550_reset_fr_flags (cpu, (fr));
78   d->cur_fr_load |= (((DI)1) << (fr));
79 }
80
81 static void
82 set_use_not_fr_load (SIM_CPU *cpu, INT fr)
83 {
84   MODEL_FR550_DATA *d = CPU_MODEL_DATA (cpu);
85   d->cur_fr_load &= ~(((DI)1) << (fr));
86 }
87
88 static int
89 use_is_fr_load (SIM_CPU *cpu, INT fr)
90 {
91   MODEL_FR550_DATA *d = CPU_MODEL_DATA (cpu);
92   return d->prev_fr_load & (((DI)1) << (fr));
93 }
94
95 static void
96 set_use_is_fr_complex_1 (SIM_CPU *cpu, INT fr)
97 {
98   MODEL_FR550_DATA *d = CPU_MODEL_DATA (cpu);
99   fr550_reset_fr_flags (cpu, (fr));
100   d->cur_fr_complex_1 |= (((DI)1) << (fr));
101 }
102
103 static void
104 set_use_not_fr_complex_1 (SIM_CPU *cpu, INT fr)
105 {
106   MODEL_FR550_DATA *d = CPU_MODEL_DATA (cpu);
107   d->cur_fr_complex_1 &= ~(((DI)1) << (fr));
108 }
109
110 static int
111 use_is_fr_complex_1 (SIM_CPU *cpu, INT fr)
112 {
113   MODEL_FR550_DATA *d = CPU_MODEL_DATA (cpu);
114   return d->prev_fr_complex_1 & (((DI)1) << (fr));
115 }
116
117 static void
118 set_use_is_fr_complex_2 (SIM_CPU *cpu, INT fr)
119 {
120   MODEL_FR550_DATA *d = CPU_MODEL_DATA (cpu);
121   fr550_reset_fr_flags (cpu, (fr));
122   d->cur_fr_complex_2 |= (((DI)1) << (fr));
123 }
124
125 static void
126 set_use_not_fr_complex_2 (SIM_CPU *cpu, INT fr)
127 {
128   MODEL_FR550_DATA *d = CPU_MODEL_DATA (cpu);
129   d->cur_fr_complex_2 &= ~(((DI)1) << (fr));
130 }
131
132 static int
133 use_is_fr_complex_2 (SIM_CPU *cpu, INT fr)
134 {
135   MODEL_FR550_DATA *d = CPU_MODEL_DATA (cpu);
136   return d->prev_fr_complex_2 & (((DI)1) << (fr));
137 }
138
139 static void
140 set_use_is_ccr_complex (SIM_CPU *cpu, INT ccr)
141 {
142   MODEL_FR550_DATA *d = CPU_MODEL_DATA (cpu);
143   fr550_reset_ccr_flags (cpu, (ccr));
144   d->cur_ccr_complex |= (((SI)1) << (ccr));
145 }
146
147 static void
148 set_use_not_ccr_complex (SIM_CPU *cpu, INT ccr)
149 {
150   MODEL_FR550_DATA *d = CPU_MODEL_DATA (cpu);
151   d->cur_ccr_complex &= ~(((SI)1) << (ccr));
152 }
153
154 static int
155 use_is_ccr_complex (SIM_CPU *cpu, INT ccr)
156 {
157   MODEL_FR550_DATA *d = CPU_MODEL_DATA (cpu);
158   return d->prev_ccr_complex & (((SI)1) << (ccr));
159 }
160
161 static void
162 set_use_is_acc_mmac (SIM_CPU *cpu, INT acc)
163 {
164   MODEL_FR550_DATA *d = CPU_MODEL_DATA (cpu);
165   fr550_reset_acc_flags (cpu, (acc));
166   d->cur_acc_mmac |= (((DI)1) << (acc));
167 }
168
169 static void
170 set_use_not_acc_mmac (SIM_CPU *cpu, INT acc)
171 {
172   MODEL_FR550_DATA *d = CPU_MODEL_DATA (cpu);
173   d->cur_acc_mmac &= ~(((DI)1) << (acc));
174 }
175
176 static int
177 use_is_acc_mmac (SIM_CPU *cpu, INT acc)
178 {
179   MODEL_FR550_DATA *d = CPU_MODEL_DATA (cpu);
180   return d->prev_acc_mmac & (((DI)1) << (acc));
181 }
182
183 static void
184 fr550_reset_fr_flags (SIM_CPU *cpu, INT fr)
185 {
186   set_use_not_fr_load (cpu, fr);
187   set_use_not_fr_complex_1 (cpu, fr);
188   set_use_not_fr_complex_2 (cpu, fr);
189 }
190
191 static void
192 fr550_reset_ccr_flags (SIM_CPU *cpu, INT ccr)
193 {
194   set_use_not_ccr_complex (cpu, ccr);
195 }
196
197 static void
198 fr550_reset_acc_flags (SIM_CPU *cpu, INT acc)
199 {
200   set_use_not_acc_mmac (cpu, acc);
201 }
202
203 /* Detect overlap between two register ranges. Works if one of the registers
204    is -1 with width 1 (i.e. undefined), but not both.  */
205 #define REG_OVERLAP(r1, w1, r2, w2) ( \
206   (r1) + (w1) - 1 >= (r2) && (r2) + (w2) - 1 >= (r1) \
207 )
208
209 /* Latency of floating point registers may be less than recorded when followed
210    by another floating point insn.  */
211 static void
212 adjust_float_register_busy (SIM_CPU *cpu,
213                             INT in_FRi, int iwidth,
214                             INT in_FRj, int jwidth,
215                             INT out_FRk, int kwidth)
216 {
217   int i;
218   /* The latency of FRk may be less than previously recorded.
219      See Table 14-15 in the LSI.  */
220   if (in_FRi >= 0)
221     {
222       for (i = 0; i < iwidth; ++i)
223         {
224           if (! REG_OVERLAP (in_FRi + i, 1, out_FRk, kwidth))
225             if (use_is_fr_load (cpu, in_FRi + i))
226               decrease_FR_busy (cpu, in_FRi + i, 1);
227             else
228               enforce_full_fr_latency (cpu, in_FRi + i);
229         }
230     }
231
232   if (in_FRj >= 0)
233     {
234       for (i = 0; i < jwidth; ++i)
235         {
236           if (! REG_OVERLAP (in_FRj + i, 1, in_FRi, iwidth)
237               && ! REG_OVERLAP (in_FRj + i, 1, out_FRk, kwidth))
238             if (use_is_fr_load (cpu, in_FRj + i))
239               decrease_FR_busy (cpu, in_FRj + i, 1);
240             else
241               enforce_full_fr_latency (cpu, in_FRj + i);
242         }
243     }
244
245   if (out_FRk >= 0)
246     {
247       for (i = 0; i < kwidth; ++i)
248         {
249           if (! REG_OVERLAP (out_FRk + i, 1, in_FRi, iwidth)
250               && ! REG_OVERLAP (out_FRk + i, 1, in_FRj, jwidth))
251             {
252               if (use_is_fr_complex_1 (cpu, out_FRk + i))
253                 decrease_FR_busy (cpu, out_FRk + i, 1);
254               else if (use_is_fr_complex_2 (cpu, out_FRk + i))
255                 decrease_FR_busy (cpu, out_FRk + i, 2);
256               else
257                 enforce_full_fr_latency (cpu, out_FRk + i);
258             }
259         }
260     }
261 }
262
263 static void
264 restore_float_register_busy (SIM_CPU *cpu,
265                              INT in_FRi, int iwidth,
266                              INT in_FRj, int jwidth,
267                              INT out_FRk, int kwidth)
268 {
269   int i;
270   /* The latency of FRk may be less than previously recorded.
271      See Table 14-15 in the LSI.  */
272   if (in_FRi >= 0)
273     {
274       for (i = 0; i < iwidth; ++i)
275         {
276           if (! REG_OVERLAP (in_FRi + i, 1, out_FRk, kwidth))
277             if (use_is_fr_load (cpu, in_FRi + i))
278               increase_FR_busy (cpu, in_FRi + i, 1);
279         }
280     }
281
282   if (in_FRj >= 0)
283     {
284       for (i = 0; i < jwidth; ++i)
285         {
286           if (! REG_OVERLAP (in_FRj + i, 1, in_FRi, iwidth)
287               && ! REG_OVERLAP (in_FRj + i, 1, out_FRk, kwidth))
288             if (use_is_fr_load (cpu, in_FRj + i))
289               increase_FR_busy (cpu, in_FRj + i, 1);
290         }
291     }
292
293   if (out_FRk >= 0)
294     {
295       for (i = 0; i < kwidth; ++i)
296         {
297           if (! REG_OVERLAP (out_FRk + i, 1, in_FRi, iwidth)
298               && ! REG_OVERLAP (out_FRk + i, 1, in_FRj, jwidth))
299             {
300               if (use_is_fr_complex_1 (cpu, out_FRk + i))
301                 increase_FR_busy (cpu, out_FRk + i, 1);
302               else if (use_is_fr_complex_2 (cpu, out_FRk + i))
303                 increase_FR_busy (cpu, out_FRk + i, 2);
304             }
305         }
306     }
307 }
308
309 /* Latency of floating point registers may be less than recorded when used in a
310    media insns and followed by another media insn.  */
311 static void
312 adjust_float_register_busy_for_media (SIM_CPU *cpu,
313                                       INT in_FRi, int iwidth,
314                                       INT in_FRj, int jwidth,
315                                       INT out_FRk, int kwidth)
316 {
317   int i;
318   /* The latency of FRk may be less than previously recorded.
319      See Table 14-15 in the LSI.  */
320   if (out_FRk >= 0)
321     {
322       for (i = 0; i < kwidth; ++i)
323         {
324           if (! REG_OVERLAP (out_FRk + i, 1, in_FRi, iwidth)
325               && ! REG_OVERLAP (out_FRk + i, 1, in_FRj, jwidth))
326             {
327               if (use_is_fr_complex_1 (cpu, out_FRk + i))
328                 decrease_FR_busy (cpu, out_FRk + i, 1);
329               else
330                 enforce_full_fr_latency (cpu, out_FRk + i);
331             }
332         }
333     }
334 }
335
336 static void
337 restore_float_register_busy_for_media (SIM_CPU *cpu,
338                                        INT in_FRi, int iwidth,
339                                        INT in_FRj, int jwidth,
340                                        INT out_FRk, int kwidth)
341 {
342   int i;
343   if (out_FRk >= 0)
344     {
345       for (i = 0; i < kwidth; ++i)
346         {
347           if (! REG_OVERLAP (out_FRk + i, 1, in_FRi, iwidth)
348               && ! REG_OVERLAP (out_FRk + i, 1, in_FRj, jwidth))
349             {
350               if (use_is_fr_complex_1 (cpu, out_FRk + i))
351                 increase_FR_busy (cpu, out_FRk + i, 1);
352             }
353         }
354     }
355 }
356
357 /* Latency of accumulator registers may be less than recorded when used in a
358    media insns and followed by another media insn.  */
359 static void
360 adjust_acc_busy_for_mmac (SIM_CPU *cpu,
361                           INT in_ACC, int inwidth,
362                           INT out_ACC, int outwidth)
363 {
364   int i;
365   /* The latency of an accumulator may be less than previously recorded.
366      See Table 14-15 in the LSI.  */
367   if (in_ACC >= 0)
368     {
369       for (i = 0; i < inwidth; ++i)
370         {
371           if (use_is_acc_mmac (cpu, in_ACC + i))
372             decrease_ACC_busy (cpu, in_ACC + i, 1);
373           else
374             enforce_full_acc_latency (cpu, in_ACC + i);
375         }
376     }
377   if (out_ACC >= 0)
378     {
379       for (i = 0; i < outwidth; ++i)
380         {
381           if (! REG_OVERLAP (out_ACC + i, 1, in_ACC, inwidth))
382             {
383               if (use_is_acc_mmac (cpu, out_ACC + i))
384                 decrease_ACC_busy (cpu, out_ACC + i, 1);
385               else
386                 enforce_full_acc_latency (cpu, out_ACC + i);
387             }
388         }
389     }
390 }
391
392 static void
393 restore_acc_busy_for_mmac (SIM_CPU *cpu,
394                            INT in_ACC, int inwidth,
395                            INT out_ACC, int outwidth)
396 {
397   int i;
398   if (in_ACC >= 0)
399     {
400       for (i = 0; i < inwidth; ++i)
401         {
402           if (use_is_acc_mmac (cpu, in_ACC + i))
403             increase_ACC_busy (cpu, in_ACC + i, 1);
404         }
405     }
406   if (out_ACC >= 0)
407     {
408       for (i = 0; i < outwidth; ++i)
409         {
410           if (! REG_OVERLAP (out_ACC + i, 1, in_ACC, inwidth))
411             {
412               if (use_is_acc_mmac (cpu, out_ACC + i))
413                 increase_ACC_busy (cpu, out_ACC + i, 1);
414             }
415         }
416     }
417 }
418
419 int
420 frvbf_model_fr550_u_exec (SIM_CPU *cpu, const IDESC *idesc,
421                           int unit_num, int referenced)
422 {
423   return idesc->timing->units[unit_num].done;
424 }
425
426 int
427 frvbf_model_fr550_u_integer (SIM_CPU *cpu, const IDESC *idesc,
428                              int unit_num, int referenced,
429                              INT in_GRi, INT in_GRj, INT out_GRk,
430                              INT out_ICCi_1)
431 {
432   int cycles;
433
434   /* icc0-icc4 are the upper 4 fields of the CCR.  */
435   if (out_ICCi_1 >= 0)
436     out_ICCi_1 += 4;
437
438   if (model_insn == FRV_INSN_MODEL_PASS_1)
439     {
440       /* The entire VLIW insn must wait if there is a dependency on a register
441          which is not ready yet.  */
442       vliw_wait_for_GR (cpu, in_GRi);
443       vliw_wait_for_GR (cpu, in_GRj);
444       vliw_wait_for_GR (cpu, out_GRk);
445       vliw_wait_for_CCR (cpu, out_ICCi_1);
446       handle_resource_wait (cpu);
447       load_wait_for_GR (cpu, in_GRi);
448       load_wait_for_GR (cpu, in_GRj);
449       load_wait_for_GR (cpu, out_GRk);
450       trace_vliw_wait_cycles (cpu);
451       return 0;
452     }
453
454   fr550_reset_ccr_flags (cpu, out_ICCi_1);
455
456   /* GRk is available immediately to the next VLIW insn as is ICCi_1.  */
457   cycles = idesc->timing->units[unit_num].done;
458   return cycles;
459 }
460
461 int
462 frvbf_model_fr550_u_imul (SIM_CPU *cpu, const IDESC *idesc,
463                           int unit_num, int referenced,
464                           INT in_GRi, INT in_GRj, INT out_GRk, INT out_ICCi_1)
465 {
466   int cycles;
467   /* icc0-icc4 are the upper 4 fields of the CCR.  */
468   if (out_ICCi_1 >= 0)
469     out_ICCi_1 += 4;
470
471   if (model_insn == FRV_INSN_MODEL_PASS_1)
472     {
473       /* The entire VLIW insn must wait if there is a dependency on a register
474          which is not ready yet.  */
475       vliw_wait_for_GR (cpu, in_GRi);
476       vliw_wait_for_GR (cpu, in_GRj);
477       vliw_wait_for_GRdouble (cpu, out_GRk);
478       vliw_wait_for_CCR (cpu, out_ICCi_1);
479       handle_resource_wait (cpu);
480       load_wait_for_GR (cpu, in_GRi);
481       load_wait_for_GR (cpu, in_GRj);
482       load_wait_for_GRdouble (cpu, out_GRk);
483       trace_vliw_wait_cycles (cpu);
484       return 0;
485     }
486
487   /* GRk has a latency of 1 cycles.  */
488   cycles = idesc->timing->units[unit_num].done;
489   update_GRdouble_latency (cpu, out_GRk, cycles + 1);
490
491   /* ICCi_1 has a latency of 1 cycle.  */
492   update_CCR_latency (cpu, out_ICCi_1, cycles + 1);
493
494   fr550_reset_ccr_flags (cpu, out_ICCi_1);
495
496   return cycles;
497 }
498
499 int
500 frvbf_model_fr550_u_idiv (SIM_CPU *cpu, const IDESC *idesc,
501                           int unit_num, int referenced,
502                           INT in_GRi, INT in_GRj, INT out_GRk, INT out_ICCi_1)
503 {
504   int cycles;
505   FRV_VLIW *vliw;
506   int slot;
507
508   /* icc0-icc4 are the upper 4 fields of the CCR.  */
509   if (out_ICCi_1 >= 0)
510     out_ICCi_1 += 4;
511
512   vliw = CPU_VLIW (cpu);
513   slot = vliw->next_slot - 1;
514   slot = (*vliw->current_vliw)[slot] - UNIT_I0;
515
516   if (model_insn == FRV_INSN_MODEL_PASS_1)
517     {
518       /* The entire VLIW insn must wait if there is a dependency on a register
519          which is not ready yet.  */
520       vliw_wait_for_GR (cpu, in_GRi);
521       vliw_wait_for_GR (cpu, in_GRj);
522       vliw_wait_for_GR (cpu, out_GRk);
523       vliw_wait_for_CCR (cpu, out_ICCi_1);
524       vliw_wait_for_idiv_resource (cpu, slot);
525       handle_resource_wait (cpu);
526       load_wait_for_GR (cpu, in_GRi);
527       load_wait_for_GR (cpu, in_GRj);
528       load_wait_for_GR (cpu, out_GRk);
529       trace_vliw_wait_cycles (cpu);
530       return 0;
531     }
532
533   /* GRk has a latency of 18 cycles!  */
534   cycles = idesc->timing->units[unit_num].done;
535   update_GR_latency (cpu, out_GRk, cycles + 18);
536
537   /* ICCi_1 has a latency of 18 cycles.  */
538   update_CCR_latency (cpu, out_ICCi_1, cycles + 18);
539
540   if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
541     {
542       /* GNER has a latency of 18 cycles.  */
543       update_SPR_latency (cpu, GNER_FOR_GR (out_GRk), cycles + 18);
544     }
545
546   /* the idiv resource has a latency of 18 cycles!  */
547   update_idiv_resource_latency (cpu, slot, cycles + 18);
548
549   fr550_reset_ccr_flags (cpu, out_ICCi_1);
550
551   return cycles;
552 }
553
554 int
555 frvbf_model_fr550_u_branch (SIM_CPU *cpu, const IDESC *idesc,
556                             int unit_num, int referenced,
557                             INT in_GRi, INT in_GRj,
558                             INT in_ICCi_2, INT in_FCCi_2)
559 {
560   int cycles;
561   FRV_PROFILE_STATE *ps;
562
563   if (model_insn == FRV_INSN_MODEL_PASS_1)
564     {
565       /* icc0-icc4 are the upper 4 fields of the CCR.  */
566       if (in_ICCi_2 >= 0)
567         in_ICCi_2 += 4;
568
569       /* The entire VLIW insn must wait if there is a dependency on a register
570          which is not ready yet.  */
571       vliw_wait_for_GR (cpu, in_GRi);
572       vliw_wait_for_GR (cpu, in_GRj);
573       vliw_wait_for_CCR (cpu, in_ICCi_2);
574       vliw_wait_for_CCR (cpu, in_FCCi_2);
575       handle_resource_wait (cpu);
576       load_wait_for_GR (cpu, in_GRi);
577       load_wait_for_GR (cpu, in_GRj);
578       trace_vliw_wait_cycles (cpu);
579       return 0;
580     }
581
582   /* When counting branches taken or not taken, don't consider branches after
583      the first taken branch in a vliw insn.  */
584   ps = CPU_PROFILE_STATE (cpu);
585   if (! ps->vliw_branch_taken)
586     {
587       /* (1 << 4): The pc is the 5th element in inputs, outputs.
588          ??? can be cleaned up */
589       PROFILE_DATA *p = CPU_PROFILE_DATA (cpu);
590       int taken = (referenced & (1 << 4)) != 0;
591       if (taken)
592         {
593           ++PROFILE_MODEL_TAKEN_COUNT (p);
594           ps->vliw_branch_taken = 1;
595         }
596       else
597         ++PROFILE_MODEL_UNTAKEN_COUNT (p);
598     }
599
600   cycles = idesc->timing->units[unit_num].done;
601   return cycles;
602 }
603
604 int
605 frvbf_model_fr550_u_trap (SIM_CPU *cpu, const IDESC *idesc,
606                           int unit_num, int referenced,
607                           INT in_GRi, INT in_GRj,
608                           INT in_ICCi_2, INT in_FCCi_2)
609 {
610   int cycles;
611
612   if (model_insn == FRV_INSN_MODEL_PASS_1)
613     {
614       /* icc0-icc4 are the upper 4 fields of the CCR.  */
615       if (in_ICCi_2 >= 0)
616         in_ICCi_2 += 4;
617
618       /* The entire VLIW insn must wait if there is a dependency on a register
619          which is not ready yet.  */
620       vliw_wait_for_GR (cpu, in_GRi);
621       vliw_wait_for_GR (cpu, in_GRj);
622       vliw_wait_for_CCR (cpu, in_ICCi_2);
623       vliw_wait_for_CCR (cpu, in_FCCi_2);
624       handle_resource_wait (cpu);
625       load_wait_for_GR (cpu, in_GRi);
626       load_wait_for_GR (cpu, in_GRj);
627       trace_vliw_wait_cycles (cpu);
628       return 0;
629     }
630
631   cycles = idesc->timing->units[unit_num].done;
632   return cycles;
633 }
634
635 int
636 frvbf_model_fr550_u_check (SIM_CPU *cpu, const IDESC *idesc,
637                            int unit_num, int referenced,
638                            INT in_ICCi_3, INT in_FCCi_3)
639 {
640   /* Modelling for this unit is the same as for fr500.  */
641   return frvbf_model_fr500_u_check (cpu, idesc, unit_num, referenced,
642                                     in_ICCi_3, in_FCCi_3);
643 }
644
645 int
646 frvbf_model_fr550_u_set_hilo (SIM_CPU *cpu, const IDESC *idesc,
647                              int unit_num, int referenced,
648                              INT out_GRkhi, INT out_GRklo)
649 {
650   int cycles;
651
652   if (model_insn == FRV_INSN_MODEL_PASS_1)
653     {
654       /* The entire VLIW insn must wait if there is a dependency on a GR
655          which is not ready yet.  */
656       vliw_wait_for_GR (cpu, out_GRkhi);
657       vliw_wait_for_GR (cpu, out_GRklo);
658       handle_resource_wait (cpu);
659       load_wait_for_GR (cpu, out_GRkhi);
660       load_wait_for_GR (cpu, out_GRklo);
661       trace_vliw_wait_cycles (cpu);
662       return 0;
663     }
664
665   /* GRk is available immediately to the next VLIW insn.  */
666   cycles = idesc->timing->units[unit_num].done;
667
668   return cycles;
669 }
670
671 int
672 frvbf_model_fr550_u_gr_load (SIM_CPU *cpu, const IDESC *idesc,
673                              int unit_num, int referenced,
674                              INT in_GRi, INT in_GRj,
675                              INT out_GRk, INT out_GRdoublek)
676 {
677   int cycles;
678
679   if (model_insn == FRV_INSN_MODEL_PASS_1)
680     {
681       /* The entire VLIW insn must wait if there is a dependency on a register
682          which is not ready yet.  */
683       vliw_wait_for_GR (cpu, in_GRi);
684       vliw_wait_for_GR (cpu, in_GRj);
685       vliw_wait_for_GR (cpu, out_GRk);
686       vliw_wait_for_GRdouble (cpu, out_GRdoublek);
687       handle_resource_wait (cpu);
688       load_wait_for_GR (cpu, in_GRi);
689       load_wait_for_GR (cpu, in_GRj);
690       load_wait_for_GR (cpu, out_GRk);
691       load_wait_for_GRdouble (cpu, out_GRdoublek);
692       trace_vliw_wait_cycles (cpu);
693       return 0;
694     }
695
696   cycles = idesc->timing->units[unit_num].done;
697
698   /* The latency of GRk for a load will depend on how long it takes to retrieve
699      the the data from the cache or memory.  */
700   update_GR_latency_for_load (cpu, out_GRk, cycles);
701   update_GRdouble_latency_for_load (cpu, out_GRdoublek, cycles);
702
703   if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
704     {
705       /* GNER has a latency of 2 cycles.  */
706       update_SPR_latency (cpu, GNER_FOR_GR (out_GRk), cycles + 2);
707       update_SPR_latency (cpu, GNER_FOR_GR (out_GRdoublek), cycles + 2);
708     }
709
710   return cycles;
711 }
712
713 int
714 frvbf_model_fr550_u_gr_store (SIM_CPU *cpu, const IDESC *idesc,
715                               int unit_num, int referenced,
716                               INT in_GRi, INT in_GRj,
717                               INT in_GRk, INT in_GRdoublek)
718 {
719   int cycles;
720
721   if (model_insn == FRV_INSN_MODEL_PASS_1)
722     {
723       /* The entire VLIW insn must wait if there is a dependency on a register
724          which is not ready yet.  */
725       vliw_wait_for_GR (cpu, in_GRi);
726       vliw_wait_for_GR (cpu, in_GRj);
727       vliw_wait_for_GR (cpu, in_GRk);
728       vliw_wait_for_GRdouble (cpu, in_GRdoublek);
729       handle_resource_wait (cpu);
730       load_wait_for_GR (cpu, in_GRi);
731       load_wait_for_GR (cpu, in_GRj);
732       load_wait_for_GR (cpu, in_GRk);
733       load_wait_for_GRdouble (cpu, in_GRdoublek);
734       trace_vliw_wait_cycles (cpu);
735       return 0;
736     }
737
738   /* The target register is available immediately.  */
739   cycles = idesc->timing->units[unit_num].done;
740
741   return cycles;
742 }
743
744 int
745 frvbf_model_fr550_u_fr_load (SIM_CPU *cpu, const IDESC *idesc,
746                              int unit_num, int referenced,
747                              INT in_GRi, INT in_GRj,
748                              INT out_FRk, INT out_FRdoublek)
749 {
750   int cycles;
751   if (model_insn == FRV_INSN_MODEL_PASS_1)
752     {
753       /* The entire VLIW insn must wait if there is a dependency on a register
754          which is not ready yet.
755          The latency of the registers may be less than previously recorded,
756          depending on how they were used previously.
757          See Table 13-8 in the LSI.  */
758       adjust_float_register_busy (cpu, -1, 1, -1, 1, out_FRk, 1);
759       adjust_float_register_busy (cpu, -1, 1, -1, 1, out_FRdoublek, 2);
760       vliw_wait_for_GR (cpu, in_GRi);
761       vliw_wait_for_GR (cpu, in_GRj);
762       vliw_wait_for_FR (cpu, out_FRk);
763       vliw_wait_for_FRdouble (cpu, out_FRdoublek);
764       if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
765         {
766           vliw_wait_for_SPR (cpu, FNER_FOR_FR (out_FRk));
767           vliw_wait_for_SPR (cpu, FNER_FOR_FR (out_FRdoublek));
768         }
769       handle_resource_wait (cpu);
770       load_wait_for_GR (cpu, in_GRi);
771       load_wait_for_GR (cpu, in_GRj);
772       load_wait_for_FR (cpu, out_FRk);
773       load_wait_for_FRdouble (cpu, out_FRdoublek);
774       trace_vliw_wait_cycles (cpu);
775       return 0;
776     }
777
778   cycles = idesc->timing->units[unit_num].done;
779
780   /* The latency of FRk for a load will depend on how long it takes to retrieve
781      the the data from the cache or memory.  */
782   update_FR_latency_for_load (cpu, out_FRk, cycles);
783   update_FRdouble_latency_for_load (cpu, out_FRdoublek, cycles);
784
785   if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
786     {
787       /* FNER has a latency of 3 cycles.  */
788       update_SPR_latency (cpu, FNER_FOR_FR (out_FRk), cycles + 3);
789       update_SPR_latency (cpu, FNER_FOR_FR (out_FRdoublek), cycles + 3);
790     }
791
792   if (out_FRk >= 0)
793     set_use_is_fr_load (cpu, out_FRk);
794   if (out_FRdoublek >= 0)
795     {
796       set_use_is_fr_load (cpu, out_FRdoublek);
797       set_use_is_fr_load (cpu, out_FRdoublek + 1);
798     }
799
800   return cycles;
801 }
802
803 int
804 frvbf_model_fr550_u_fr_store (SIM_CPU *cpu, const IDESC *idesc,
805                               int unit_num, int referenced,
806                               INT in_GRi, INT in_GRj,
807                               INT in_FRk, INT in_FRdoublek)
808 {
809   int cycles;
810
811   if (model_insn == FRV_INSN_MODEL_PASS_1)
812     {
813       /* The entire VLIW insn must wait if there is a dependency on a register
814          which is not ready yet.  */
815       adjust_float_register_busy (cpu, in_FRk, 1, -1, 1, -1, 1);
816       adjust_float_register_busy (cpu, in_FRdoublek, 2, -1, 1, -1, 1);
817       vliw_wait_for_GR (cpu, in_GRi);
818       vliw_wait_for_GR (cpu, in_GRj);
819       vliw_wait_for_FR (cpu, in_FRk);
820       vliw_wait_for_FRdouble (cpu, in_FRdoublek);
821       handle_resource_wait (cpu);
822       load_wait_for_GR (cpu, in_GRi);
823       load_wait_for_GR (cpu, in_GRj);
824       load_wait_for_FR (cpu, in_FRk);
825       load_wait_for_FRdouble (cpu, in_FRdoublek);
826       trace_vliw_wait_cycles (cpu);
827       return 0;
828     }
829
830   /* The target register is available immediately.  */
831   cycles = idesc->timing->units[unit_num].done;
832
833   return cycles;
834 }
835
836 int
837 frvbf_model_fr550_u_ici (SIM_CPU *cpu, const IDESC *idesc,
838                          int unit_num, int referenced,
839                          INT in_GRi, INT in_GRj)
840 {
841   int cycles;
842
843   if (model_insn == FRV_INSN_MODEL_PASS_1)
844     {
845       /* The entire VLIW insn must wait if there is a dependency on a register
846          which is not ready yet.  */
847       vliw_wait_for_GR (cpu, in_GRi);
848       vliw_wait_for_GR (cpu, in_GRj);
849       handle_resource_wait (cpu);
850       load_wait_for_GR (cpu, in_GRi);
851       load_wait_for_GR (cpu, in_GRj);
852       trace_vliw_wait_cycles (cpu);
853       return 0;
854     }
855
856   cycles = idesc->timing->units[unit_num].done;
857   request_cache_invalidate (cpu, CPU_INSN_CACHE (cpu), cycles);
858   return cycles;
859 }
860
861 int
862 frvbf_model_fr550_u_dci (SIM_CPU *cpu, const IDESC *idesc,
863                          int unit_num, int referenced,
864                          INT in_GRi, INT in_GRj)
865 {
866   int cycles;
867
868   if (model_insn == FRV_INSN_MODEL_PASS_1)
869     {
870       /* The entire VLIW insn must wait if there is a dependency on a register
871          which is not ready yet.  */
872       vliw_wait_for_GR (cpu, in_GRi);
873       vliw_wait_for_GR (cpu, in_GRj);
874       handle_resource_wait (cpu);
875       load_wait_for_GR (cpu, in_GRi);
876       load_wait_for_GR (cpu, in_GRj);
877       trace_vliw_wait_cycles (cpu);
878       return 0;
879     }
880
881   cycles = idesc->timing->units[unit_num].done;
882   request_cache_invalidate (cpu, CPU_DATA_CACHE (cpu), cycles);
883   return cycles;
884 }
885
886 int
887 frvbf_model_fr550_u_dcf (SIM_CPU *cpu, const IDESC *idesc,
888                          int unit_num, int referenced,
889                          INT in_GRi, INT in_GRj)
890 {
891   int cycles;
892
893   if (model_insn == FRV_INSN_MODEL_PASS_1)
894     {
895       /* The entire VLIW insn must wait if there is a dependency on a register
896          which is not ready yet.  */
897       vliw_wait_for_GR (cpu, in_GRi);
898       vliw_wait_for_GR (cpu, in_GRj);
899       handle_resource_wait (cpu);
900       load_wait_for_GR (cpu, in_GRi);
901       load_wait_for_GR (cpu, in_GRj);
902       trace_vliw_wait_cycles (cpu);
903       return 0;
904     }
905
906   cycles = idesc->timing->units[unit_num].done;
907   request_cache_flush (cpu, CPU_DATA_CACHE (cpu), cycles);
908   return cycles;
909 }
910
911 int
912 frvbf_model_fr550_u_icpl (SIM_CPU *cpu, const IDESC *idesc,
913                           int unit_num, int referenced,
914                           INT in_GRi, INT in_GRj)
915 {
916   int cycles;
917
918   if (model_insn == FRV_INSN_MODEL_PASS_1)
919     {
920       /* The entire VLIW insn must wait if there is a dependency on a register
921          which is not ready yet.  */
922       vliw_wait_for_GR (cpu, in_GRi);
923       vliw_wait_for_GR (cpu, in_GRj);
924       handle_resource_wait (cpu);
925       load_wait_for_GR (cpu, in_GRi);
926       load_wait_for_GR (cpu, in_GRj);
927       trace_vliw_wait_cycles (cpu);
928       return 0;
929     }
930
931   cycles = idesc->timing->units[unit_num].done;
932   request_cache_preload (cpu, CPU_INSN_CACHE (cpu), cycles);
933   return cycles;
934 }
935
936 int
937 frvbf_model_fr550_u_dcpl (SIM_CPU *cpu, const IDESC *idesc,
938                           int unit_num, int referenced,
939                           INT in_GRi, INT in_GRj)
940 {
941   int cycles;
942
943   if (model_insn == FRV_INSN_MODEL_PASS_1)
944     {
945       /* The entire VLIW insn must wait if there is a dependency on a register
946          which is not ready yet.  */
947       vliw_wait_for_GR (cpu, in_GRi);
948       vliw_wait_for_GR (cpu, in_GRj);
949       handle_resource_wait (cpu);
950       load_wait_for_GR (cpu, in_GRi);
951       load_wait_for_GR (cpu, in_GRj);
952       trace_vliw_wait_cycles (cpu);
953       return 0;
954     }
955
956   cycles = idesc->timing->units[unit_num].done;
957   request_cache_preload (cpu, CPU_DATA_CACHE (cpu), cycles);
958   return cycles;
959 }
960
961 int
962 frvbf_model_fr550_u_icul (SIM_CPU *cpu, const IDESC *idesc,
963                           int unit_num, int referenced,
964                           INT in_GRi, INT in_GRj)
965 {
966   int cycles;
967
968   if (model_insn == FRV_INSN_MODEL_PASS_1)
969     {
970       /* The entire VLIW insn must wait if there is a dependency on a register
971          which is not ready yet.  */
972       vliw_wait_for_GR (cpu, in_GRi);
973       vliw_wait_for_GR (cpu, in_GRj);
974       handle_resource_wait (cpu);
975       load_wait_for_GR (cpu, in_GRi);
976       load_wait_for_GR (cpu, in_GRj);
977       trace_vliw_wait_cycles (cpu);
978       return 0;
979     }
980
981   cycles = idesc->timing->units[unit_num].done;
982   request_cache_unlock (cpu, CPU_INSN_CACHE (cpu), cycles);
983   return cycles;
984 }
985
986 int
987 frvbf_model_fr550_u_dcul (SIM_CPU *cpu, const IDESC *idesc,
988                           int unit_num, int referenced,
989                           INT in_GRi, INT in_GRj)
990 {
991   int cycles;
992
993   if (model_insn == FRV_INSN_MODEL_PASS_1)
994     {
995       /* The entire VLIW insn must wait if there is a dependency on a register
996          which is not ready yet.  */
997       vliw_wait_for_GR (cpu, in_GRi);
998       vliw_wait_for_GR (cpu, in_GRj);
999       handle_resource_wait (cpu);
1000       load_wait_for_GR (cpu, in_GRi);
1001       load_wait_for_GR (cpu, in_GRj);
1002       trace_vliw_wait_cycles (cpu);
1003       return 0;
1004     }
1005
1006   cycles = idesc->timing->units[unit_num].done;
1007   request_cache_unlock (cpu, CPU_DATA_CACHE (cpu), cycles);
1008   return cycles;
1009 }
1010
1011 int
1012 frvbf_model_fr550_u_float_arith (SIM_CPU *cpu, const IDESC *idesc,
1013                                  int unit_num, int referenced,
1014                                  INT in_FRi, INT in_FRj,
1015                                  INT in_FRdoublei, INT in_FRdoublej,
1016                                  INT out_FRk, INT out_FRdoublek)
1017 {
1018   int cycles;
1019   FRV_PROFILE_STATE *ps;
1020   FRV_VLIW *vliw;
1021   int slot;
1022
1023   if (model_insn == FRV_INSN_MODEL_PASS_1)
1024     return 0;
1025
1026   /* The preprocessing can execute right away.  */
1027   cycles = idesc->timing->units[unit_num].done;
1028
1029   /* The post processing must wait if there is a dependency on a FR
1030      which is not ready yet.  */
1031   adjust_float_register_busy (cpu, in_FRi, 1, in_FRj, 1, out_FRk, 1);
1032   adjust_float_register_busy (cpu, in_FRdoublei, 2, in_FRdoublej, 2, out_FRdoublek, 2);
1033   ps = CPU_PROFILE_STATE (cpu);
1034   ps->post_wait = cycles;
1035   vliw = CPU_VLIW (cpu);
1036   slot = vliw->next_slot - 1;
1037   slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
1038   post_wait_for_float (cpu, slot);
1039   post_wait_for_FR (cpu, in_FRi);
1040   post_wait_for_FR (cpu, in_FRj);
1041   post_wait_for_FR (cpu, out_FRk);
1042   post_wait_for_FRdouble (cpu, in_FRdoublei);
1043   post_wait_for_FRdouble (cpu, in_FRdoublej);
1044   post_wait_for_FRdouble (cpu, out_FRdoublek);
1045   if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
1046     {
1047       post_wait_for_SPR (cpu, FNER_FOR_FR (out_FRk));
1048       post_wait_for_SPR (cpu, FNER_FOR_FR (out_FRdoublek));
1049     }
1050   restore_float_register_busy (cpu, in_FRi, 1, in_FRj, 1, out_FRk, 1);
1051   restore_float_register_busy (cpu, in_FRdoublei, 2, in_FRdoublej, 2, out_FRdoublek, 2);
1052
1053   /* The latency of FRk will be at least the latency of the other inputs.  */
1054   update_FR_latency (cpu, out_FRk, ps->post_wait);
1055   update_FRdouble_latency (cpu, out_FRdoublek, ps->post_wait);
1056
1057   if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
1058     {
1059       update_SPR_latency (cpu, FNER_FOR_FR (out_FRk), ps->post_wait);
1060       update_SPR_latency (cpu, FNER_FOR_FR (out_FRdoublek), ps->post_wait);
1061     }
1062
1063   /* Once initiated, post-processing will take 2 cycles.  */
1064   update_FR_ptime (cpu, out_FRk, 2);
1065   update_FRdouble_ptime (cpu, out_FRdoublek, 2);
1066   if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
1067     {
1068       update_SPR_ptime (cpu, FNER_FOR_FR (out_FRk), 2);
1069       update_SPR_ptime (cpu, FNER_FOR_FR (out_FRdoublek), 2);
1070     }
1071
1072   /* Mark this use of the register as a floating point op.  */
1073   if (out_FRk >= 0)
1074     set_use_is_fr_complex_2 (cpu, out_FRk);
1075   if (out_FRdoublek >= 0)
1076     {
1077       set_use_is_fr_complex_2 (cpu, out_FRdoublek);
1078       if (out_FRdoublek < 63)
1079         set_use_is_fr_complex_2 (cpu, out_FRdoublek + 1);
1080     }
1081
1082   /* the media point unit resource has a latency of 4 cycles  */
1083   update_media_resource_latency (cpu, slot, cycles + 4);
1084
1085   return cycles;
1086 }
1087
1088 int
1089 frvbf_model_fr550_u_float_dual_arith (SIM_CPU *cpu, const IDESC *idesc,
1090                                       int unit_num, int referenced,
1091                                       INT in_FRi, INT in_FRj,
1092                                       INT in_FRdoublei, INT in_FRdoublej,
1093                                       INT out_FRk, INT out_FRdoublek)
1094 {
1095   int cycles;
1096   INT dual_FRi;
1097   INT dual_FRj;
1098   INT dual_FRk;
1099   INT dual_FRdoublei;
1100   INT dual_FRdoublej;
1101   INT dual_FRdoublek;
1102   FRV_PROFILE_STATE *ps;
1103   FRV_VLIW *vliw;
1104   int slot;
1105
1106   if (model_insn == FRV_INSN_MODEL_PASS_1)
1107     return 0;
1108
1109   /* The preprocessing can execute right away.  */
1110   cycles = idesc->timing->units[unit_num].done;
1111
1112   /* The post processing must wait if there is a dependency on a FR
1113      which is not ready yet.  */
1114   dual_FRi = DUAL_REG (in_FRi);
1115   dual_FRj = DUAL_REG (in_FRj);
1116   dual_FRk = DUAL_REG (out_FRk);
1117   dual_FRdoublei = DUAL_DOUBLE (in_FRdoublei);
1118   dual_FRdoublej = DUAL_DOUBLE (in_FRdoublej);
1119   dual_FRdoublek = DUAL_DOUBLE (out_FRdoublek);
1120
1121   adjust_float_register_busy (cpu, in_FRi, 2, in_FRj, 2, out_FRk, 2);
1122   adjust_float_register_busy (cpu, in_FRdoublei, 4, in_FRdoublej, 4, out_FRdoublek, 4);
1123   ps = CPU_PROFILE_STATE (cpu);
1124   ps->post_wait = cycles;
1125   vliw = CPU_VLIW (cpu);
1126   slot = vliw->next_slot - 1;
1127   slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
1128   post_wait_for_float (cpu, slot);
1129   post_wait_for_FR (cpu, in_FRi);
1130   post_wait_for_FR (cpu, in_FRj);
1131   post_wait_for_FR (cpu, out_FRk);
1132   post_wait_for_FR (cpu, dual_FRi);
1133   post_wait_for_FR (cpu, dual_FRj);
1134   post_wait_for_FR (cpu, dual_FRk);
1135   post_wait_for_FRdouble (cpu, in_FRdoublei);
1136   post_wait_for_FRdouble (cpu, in_FRdoublej);
1137   post_wait_for_FRdouble (cpu, out_FRdoublek);
1138   post_wait_for_FRdouble (cpu, dual_FRdoublei);
1139   post_wait_for_FRdouble (cpu, dual_FRdoublej);
1140   post_wait_for_FRdouble (cpu, dual_FRdoublek);
1141   if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
1142     {
1143       post_wait_for_SPR (cpu, FNER_FOR_FR (out_FRk));
1144       post_wait_for_SPR (cpu, FNER_FOR_FR (dual_FRk));
1145       post_wait_for_SPR (cpu, FNER_FOR_FR (out_FRdoublek));
1146       post_wait_for_SPR (cpu, FNER_FOR_FR (dual_FRdoublek));
1147     }
1148   restore_float_register_busy (cpu, in_FRi, 2, in_FRj, 2, out_FRk, 2);
1149   restore_float_register_busy (cpu, in_FRdoublei, 4, in_FRdoublej, 4, out_FRdoublek, 4);
1150
1151   /* The latency of FRk will be at least the latency of the other inputs.  */
1152   update_FR_latency (cpu, out_FRk, ps->post_wait);
1153   update_FR_latency (cpu, dual_FRk, ps->post_wait);
1154   update_FRdouble_latency (cpu, out_FRdoublek, ps->post_wait);
1155   update_FRdouble_latency (cpu, dual_FRdoublek, ps->post_wait);
1156
1157   if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
1158     {
1159       update_SPR_latency (cpu, FNER_FOR_FR (out_FRk), ps->post_wait);
1160       update_SPR_latency (cpu, FNER_FOR_FR (dual_FRk), ps->post_wait);
1161       update_SPR_latency (cpu, FNER_FOR_FR (out_FRdoublek), ps->post_wait);
1162       update_SPR_latency (cpu, FNER_FOR_FR (dual_FRdoublek), ps->post_wait);
1163     }
1164
1165   /* Once initiated, post-processing will take 3 cycles.  */
1166   update_FR_ptime (cpu, out_FRk, 3);
1167   update_FR_ptime (cpu, dual_FRk, 3);
1168   update_FRdouble_ptime (cpu, out_FRdoublek, 3);
1169   update_FRdouble_ptime (cpu, dual_FRdoublek, 3);
1170
1171   if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
1172     {
1173       update_SPR_ptime (cpu, FNER_FOR_FR (out_FRk), 3);
1174       update_SPR_ptime (cpu, FNER_FOR_FR (dual_FRk), 3);
1175       update_SPR_ptime (cpu, FNER_FOR_FR (out_FRdoublek), 3);
1176       update_SPR_ptime (cpu, FNER_FOR_FR (dual_FRdoublek), 3);
1177     }
1178
1179   /* Mark this use of the register as a floating point op.  */
1180   if (out_FRk >= 0)
1181     fr550_reset_fr_flags (cpu, out_FRk);
1182   if (dual_FRk >= 0)
1183     fr550_reset_fr_flags (cpu, dual_FRk);
1184   if (out_FRdoublek >= 0)
1185     {
1186       fr550_reset_fr_flags (cpu, out_FRdoublek);
1187       if (out_FRdoublek < 63)
1188         fr550_reset_fr_flags (cpu, out_FRdoublek + 1);
1189     }
1190   if (dual_FRdoublek >= 0)
1191     {
1192       fr550_reset_fr_flags (cpu, dual_FRdoublek);
1193       if (dual_FRdoublek < 63)
1194         fr550_reset_fr_flags (cpu, dual_FRdoublek + 1);
1195     }
1196
1197   /* the media point unit resource has a latency of 5 cycles  */
1198   update_media_resource_latency (cpu, slot, cycles + 5);
1199
1200   return cycles;
1201 }
1202
1203 int
1204 frvbf_model_fr550_u_float_div (SIM_CPU *cpu, const IDESC *idesc,
1205                                int unit_num, int referenced,
1206                                INT in_FRi, INT in_FRj, INT out_FRk)
1207 {
1208   int cycles;
1209   FRV_VLIW *vliw;
1210   int slot;
1211   FRV_PROFILE_STATE *ps;
1212
1213   if (model_insn == FRV_INSN_MODEL_PASS_1)
1214     return 0;
1215
1216   cycles = idesc->timing->units[unit_num].done;
1217
1218   /* The post processing must wait if there is a dependency on a FR
1219      which is not ready yet.  */
1220   adjust_float_register_busy (cpu, in_FRi, 1, in_FRj, 1, out_FRk, 1);
1221   ps = CPU_PROFILE_STATE (cpu);
1222   ps->post_wait = cycles;
1223   vliw = CPU_VLIW (cpu);
1224   slot = vliw->next_slot - 1;
1225   slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
1226   post_wait_for_float (cpu, slot);
1227   post_wait_for_fdiv (cpu, slot);
1228   post_wait_for_FR (cpu, in_FRi);
1229   post_wait_for_FR (cpu, in_FRj);
1230   post_wait_for_FR (cpu, out_FRk);
1231   if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
1232     post_wait_for_SPR (cpu, FNER_FOR_FR (out_FRk));
1233   restore_float_register_busy (cpu, in_FRi, 1, in_FRj, 1, out_FRk, 1);
1234
1235   /* The latency of FRk will be at least the latency of the other inputs.  */
1236   /* Once initiated, post-processing will take 9 cycles.  */
1237   update_FR_latency (cpu, out_FRk, ps->post_wait);
1238   update_FR_ptime (cpu, out_FRk, 9);
1239
1240   if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
1241     {
1242       /* FNER has a latency of 9 cycles.  */
1243       update_SPR_latency (cpu, FNER_FOR_FR (out_FRk), ps->post_wait);
1244       update_SPR_ptime (cpu, FNER_FOR_FR (out_FRk), 9);
1245     }
1246
1247   /* The latency of the fdiv unit will be at least the latency of the other
1248      inputs.  Once initiated, post-processing will take 9 cycles.  */
1249   update_fdiv_resource_latency (cpu, slot, ps->post_wait + 9);
1250
1251   /* the media point unit resource has a latency of 11 cycles  */
1252   update_media_resource_latency (cpu, slot, cycles + 11);
1253
1254   fr550_reset_fr_flags (cpu, out_FRk);
1255
1256   return cycles;
1257 }
1258
1259 int
1260 frvbf_model_fr550_u_float_sqrt (SIM_CPU *cpu, const IDESC *idesc,
1261                                 int unit_num, int referenced,
1262                                 INT in_FRj, INT in_FRdoublej,
1263                                 INT out_FRk, INT out_FRdoublek)
1264 {
1265   int cycles;
1266   FRV_VLIW *vliw;
1267   int slot;
1268   FRV_PROFILE_STATE *ps;
1269
1270   if (model_insn == FRV_INSN_MODEL_PASS_1)
1271     return 0;
1272
1273   cycles = idesc->timing->units[unit_num].done;
1274
1275   /* The post processing must wait if there is a dependency on a FR
1276      which is not ready yet.  */
1277   adjust_float_register_busy (cpu, -1, 1, in_FRj, 1, out_FRk, 1);
1278   adjust_float_register_busy (cpu, -1, 1, in_FRdoublej, 2, out_FRdoublek, 2);
1279   ps = CPU_PROFILE_STATE (cpu);
1280   ps->post_wait = cycles;
1281   vliw = CPU_VLIW (cpu);
1282   slot = vliw->next_slot - 1;
1283   slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
1284   post_wait_for_float (cpu, slot);
1285   post_wait_for_fsqrt (cpu, slot);
1286   post_wait_for_FR (cpu, in_FRj);
1287   post_wait_for_FR (cpu, out_FRk);
1288   post_wait_for_FRdouble (cpu, in_FRdoublej);
1289   post_wait_for_FRdouble (cpu, out_FRdoublek);
1290   if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
1291     {
1292       post_wait_for_SPR (cpu, FNER_FOR_FR (out_FRk));
1293       post_wait_for_SPR (cpu, FNER_FOR_FR (out_FRdoublek));
1294     }
1295   restore_float_register_busy (cpu, -1, 1, in_FRj, 1, out_FRk, 1);
1296   restore_float_register_busy (cpu, -1, 1, in_FRdoublej, 2, out_FRdoublek, 2);
1297
1298   /* The latency of FRk will be at least the latency of the other inputs.  */
1299   update_FR_latency (cpu, out_FRk, ps->post_wait);
1300   update_FRdouble_latency (cpu, out_FRdoublek, ps->post_wait);
1301
1302   if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
1303     {
1304       /* FNER has a latency of 14 cycles.  */
1305       update_SPR_latency (cpu, FNER_FOR_FR (out_FRk), ps->post_wait);
1306       update_SPR_latency (cpu, FNER_FOR_FR (out_FRdoublek), ps->post_wait);
1307     }
1308
1309   /* Once initiated, post-processing will take 14 cycles.  */
1310   update_FR_ptime (cpu, out_FRk, 14);
1311   update_FRdouble_ptime (cpu, out_FRdoublek, 14);
1312
1313   if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
1314     {
1315       /* FNER has a latency of 14 cycles.  */
1316       update_SPR_ptime (cpu, FNER_FOR_FR (out_FRk), 14);
1317       update_SPR_ptime (cpu, FNER_FOR_FR (out_FRdoublek), 14);
1318     }
1319
1320   /* The latency of the sqrt unit will be the latency of the other
1321      inputs plus 14 cycles.  */
1322   update_fsqrt_resource_latency (cpu, slot, ps->post_wait + 14);
1323
1324   fr550_reset_fr_flags (cpu, out_FRk);
1325   if (out_FRdoublek != -1)
1326     {
1327       fr550_reset_fr_flags (cpu, out_FRdoublek);
1328       fr550_reset_fr_flags (cpu, out_FRdoublek + 1);
1329     }
1330
1331   /* the media point unit resource has a latency of 16 cycles  */
1332   update_media_resource_latency (cpu, slot, cycles + 16);
1333
1334   return cycles;
1335 }
1336
1337 int
1338 frvbf_model_fr550_u_float_compare (SIM_CPU *cpu, const IDESC *idesc,
1339                                    int unit_num, int referenced,
1340                                    INT in_FRi, INT in_FRj,
1341                                    INT in_FRdoublei, INT in_FRdoublej,
1342                                    INT out_FCCi_2)
1343 {
1344   int cycles;
1345   FRV_PROFILE_STATE *ps;
1346   FRV_VLIW *vliw;
1347   int slot;
1348
1349   if (model_insn == FRV_INSN_MODEL_PASS_1)
1350     return 0;
1351
1352   /* The preprocessing can execute right away.  */
1353   cycles = idesc->timing->units[unit_num].done;
1354
1355   /* The post processing must wait if there is a dependency on a FR
1356      which is not ready yet.  */
1357   adjust_float_register_busy (cpu, in_FRi, 1, in_FRj, 1, -1, 1);
1358   adjust_float_register_busy (cpu, in_FRdoublei, 2, in_FRdoublej, 2, -1, 1);
1359   ps = CPU_PROFILE_STATE (cpu);
1360   ps->post_wait = cycles;
1361   vliw = CPU_VLIW (cpu);
1362   slot = vliw->next_slot - 1;
1363   slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
1364   post_wait_for_float (cpu, slot);
1365   post_wait_for_FR (cpu, in_FRi);
1366   post_wait_for_FR (cpu, in_FRj);
1367   post_wait_for_FRdouble (cpu, in_FRdoublei);
1368   post_wait_for_FRdouble (cpu, in_FRdoublej);
1369   post_wait_for_CCR (cpu, out_FCCi_2);
1370   restore_float_register_busy (cpu, in_FRi, 1, in_FRj, 1, -1, 1);
1371   restore_float_register_busy (cpu, in_FRdoublei, 2, in_FRdoublej, 2, -1, 1);
1372
1373   /* The latency of FCCi_2 will be the latency of the other inputs plus 2
1374      cycles.  */
1375   update_CCR_latency (cpu, out_FCCi_2, ps->post_wait + 2);
1376
1377   /* the media point unit resource has a latency of 4 cycles  */
1378   update_media_resource_latency (cpu, slot, cycles + 4);
1379
1380   set_use_is_ccr_complex (cpu, out_FCCi_2);
1381
1382   return cycles;
1383 }
1384
1385 int
1386 frvbf_model_fr550_u_float_dual_compare (SIM_CPU *cpu, const IDESC *idesc,
1387                                         int unit_num, int referenced,
1388                                         INT in_FRi, INT in_FRj,
1389                                         INT out_FCCi_2)
1390 {
1391   int cycles;
1392   INT dual_FRi;
1393   INT dual_FRj;
1394   INT dual_FCCi_2;
1395   FRV_PROFILE_STATE *ps;
1396   FRV_VLIW *vliw;
1397   int slot;
1398
1399   if (model_insn == FRV_INSN_MODEL_PASS_1)
1400     return 0;
1401
1402   /* The preprocessing can execute right away.  */
1403   cycles = idesc->timing->units[unit_num].done;
1404
1405   /* The post processing must wait if there is a dependency on a FR
1406      which is not ready yet.  */
1407   ps = CPU_PROFILE_STATE (cpu);
1408   ps->post_wait = cycles;
1409   dual_FRi = DUAL_REG (in_FRi);
1410   dual_FRj = DUAL_REG (in_FRj);
1411   dual_FCCi_2 = out_FCCi_2 + 1;
1412   adjust_float_register_busy (cpu, in_FRi, 2, in_FRj, 2, -1, 1);
1413   vliw = CPU_VLIW (cpu);
1414   slot = vliw->next_slot - 1;
1415   slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
1416   post_wait_for_float (cpu, slot);
1417   post_wait_for_FR (cpu, in_FRi);
1418   post_wait_for_FR (cpu, in_FRj);
1419   post_wait_for_FR (cpu, dual_FRi);
1420   post_wait_for_FR (cpu, dual_FRj);
1421   post_wait_for_CCR (cpu, out_FCCi_2);
1422   post_wait_for_CCR (cpu, dual_FCCi_2);
1423   restore_float_register_busy (cpu, in_FRi, 2, in_FRj, 2, -1, 1);
1424
1425   /* The latency of FCCi_2 will be the latency of the other inputs plus 3
1426      cycles.  */
1427   update_CCR_latency (cpu, out_FCCi_2, ps->post_wait + 3);
1428   update_CCR_latency (cpu, dual_FCCi_2, ps->post_wait + 3);
1429
1430   set_use_is_ccr_complex (cpu, out_FCCi_2);
1431   if (dual_FCCi_2 >= 0)
1432     set_use_is_ccr_complex (cpu, dual_FCCi_2);
1433
1434   /* the media point unit resource has a latency of 5 cycles  */
1435   update_media_resource_latency (cpu, slot, cycles + 5);
1436
1437   return cycles;
1438 }
1439
1440 int
1441 frvbf_model_fr550_u_float_convert (SIM_CPU *cpu, const IDESC *idesc,
1442                                    int unit_num, int referenced,
1443                                    INT in_FRj, INT in_FRintj, INT in_FRdoublej,
1444                                    INT out_FRk, INT out_FRintk,
1445                                    INT out_FRdoublek)
1446 {
1447   int cycles;
1448   FRV_PROFILE_STATE *ps;
1449   FRV_VLIW *vliw;
1450   int slot;
1451
1452   if (model_insn == FRV_INSN_MODEL_PASS_1)
1453     return 0;
1454
1455   /* The preprocessing can execute right away.  */
1456   cycles = idesc->timing->units[unit_num].done;
1457
1458   /* The post processing must wait if there is a dependency on a FR
1459      which is not ready yet.  */
1460   ps = CPU_PROFILE_STATE (cpu);
1461   ps->post_wait = cycles;
1462   adjust_float_register_busy (cpu, -1, 1, in_FRj, 1, out_FRk, 1);
1463   adjust_float_register_busy (cpu, -1, 1, in_FRintj, 1, out_FRintk, 1);
1464   adjust_float_register_busy (cpu, -1, 1, in_FRdoublej, 2, out_FRdoublek, 2);
1465   vliw = CPU_VLIW (cpu);
1466   slot = vliw->next_slot - 1;
1467   slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
1468   post_wait_for_float (cpu, slot);
1469   post_wait_for_FR (cpu, in_FRj);
1470   post_wait_for_FR (cpu, in_FRintj);
1471   post_wait_for_FRdouble (cpu, in_FRdoublej);
1472   post_wait_for_FR (cpu, out_FRk);
1473   post_wait_for_FR (cpu, out_FRintk);
1474   post_wait_for_FRdouble (cpu, out_FRdoublek);
1475   if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
1476     {
1477       post_wait_for_SPR (cpu, FNER_FOR_FR (out_FRk));
1478       post_wait_for_SPR (cpu, FNER_FOR_FR (out_FRintk));
1479       post_wait_for_SPR (cpu, FNER_FOR_FR (out_FRdoublek));
1480     }
1481   restore_float_register_busy (cpu, -1, 1, in_FRj, 1, out_FRk, 1);
1482   restore_float_register_busy (cpu, -1, 1, in_FRintj, 1, out_FRintk, 1);
1483   restore_float_register_busy (cpu, -1, 1, in_FRdoublej, 2, out_FRdoublek, 2);
1484
1485   /* The latency of FRk will be at least the latency of the other inputs.  */
1486   update_FR_latency (cpu, out_FRk, ps->post_wait);
1487   update_FR_latency (cpu, out_FRintk, ps->post_wait);
1488   update_FRdouble_latency (cpu, out_FRdoublek, ps->post_wait);
1489
1490   if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
1491     {
1492       update_SPR_latency (cpu, FNER_FOR_FR (out_FRk), ps->post_wait);
1493       update_SPR_latency (cpu, FNER_FOR_FR (out_FRintk), ps->post_wait);
1494       update_SPR_latency (cpu, FNER_FOR_FR (out_FRdoublek), ps->post_wait);
1495     }
1496
1497   /* Once initiated, post-processing will take 2 cycles.  */
1498   update_FR_ptime (cpu, out_FRk, 2);
1499   update_FR_ptime (cpu, out_FRintk, 2);
1500   update_FRdouble_ptime (cpu, out_FRdoublek, 2);
1501
1502   if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
1503     {
1504       update_SPR_ptime (cpu, FNER_FOR_FR (out_FRk), 2);
1505       update_SPR_ptime (cpu, FNER_FOR_FR (out_FRintk), 2);
1506       update_SPR_ptime (cpu, FNER_FOR_FR (out_FRdoublek), 2);
1507     }
1508
1509   /* Mark this use of the register as a floating point op.  */
1510   if (out_FRk >= 0)
1511     set_use_is_fr_complex_2 (cpu, out_FRk);
1512   if (out_FRintk >= 0)
1513     set_use_is_fr_complex_2 (cpu, out_FRintk);
1514   if (out_FRdoublek >= 0)
1515     {
1516       set_use_is_fr_complex_2 (cpu, out_FRdoublek);
1517       set_use_is_fr_complex_2 (cpu, out_FRdoublek + 1);
1518     }
1519
1520   /* the media point unit resource has a latency of 4 cycles  */
1521   update_media_resource_latency (cpu, slot, cycles + 4);
1522
1523   return cycles;
1524 }
1525
1526 int
1527 frvbf_model_fr550_u_spr2gr (SIM_CPU *cpu, const IDESC *idesc,
1528                             int unit_num, int referenced,
1529                             INT in_spr, INT out_GRj)
1530 {
1531   /* Modelling for this unit is the same as for fr500.  */
1532   return frvbf_model_fr500_u_spr2gr (cpu, idesc, unit_num, referenced,
1533                                      in_spr, out_GRj);
1534 }
1535
1536 int
1537 frvbf_model_fr550_u_gr2spr (SIM_CPU *cpu, const IDESC *idesc,
1538                             int unit_num, int referenced,
1539                             INT in_GRj, INT out_spr)
1540 {
1541   int cycles;
1542
1543   if (model_insn == FRV_INSN_MODEL_PASS_1)
1544     {
1545       /* The entire VLIW insn must wait if there is a dependency on a register
1546          which is not ready yet.  */
1547       vliw_wait_for_GR (cpu, in_GRj);
1548       vliw_wait_for_SPR (cpu, out_spr);
1549       handle_resource_wait (cpu);
1550       load_wait_for_GR (cpu, in_GRj);
1551       trace_vliw_wait_cycles (cpu);
1552       return 0;
1553     }
1554
1555   cycles = idesc->timing->units[unit_num].done;
1556
1557 #if 0
1558   /* The latency of spr is ? cycles.  */
1559   update_SPR_latency (cpu, out_spr, cycles + ?);
1560 #endif
1561
1562   return cycles;
1563 }
1564
1565 int
1566 frvbf_model_fr550_u_gr2fr (SIM_CPU *cpu, const IDESC *idesc,
1567                            int unit_num, int referenced,
1568                            INT in_GRj, INT out_FRk)
1569 {
1570   int cycles;
1571
1572   if (model_insn == FRV_INSN_MODEL_PASS_1)
1573     {
1574       /* The entire VLIW insn must wait if there is a dependency on a register
1575          which is not ready yet.
1576          The latency of the registers may be less than previously recorded,
1577          depending on how they were used previously.
1578          See Table 14-15 in the LSI.  */
1579       adjust_float_register_busy (cpu, -1, 1, -1, 1, out_FRk, 1);
1580       vliw_wait_for_GR (cpu, in_GRj);
1581       vliw_wait_for_FR (cpu, out_FRk);
1582       handle_resource_wait (cpu);
1583       load_wait_for_GR (cpu, in_GRj);
1584       load_wait_for_FR (cpu, out_FRk);
1585       trace_vliw_wait_cycles (cpu);
1586       return 0;
1587     }
1588
1589   /* The latency of FRk is 1 cycles.  */
1590   cycles = idesc->timing->units[unit_num].done;
1591   update_FR_latency (cpu, out_FRk, cycles + 1);
1592
1593   set_use_is_fr_complex_1 (cpu, out_FRk);
1594
1595   return cycles;
1596 }
1597
1598 int
1599 frvbf_model_fr550_u_swap (SIM_CPU *cpu, const IDESC *idesc,
1600                           int unit_num, int referenced,
1601                           INT in_GRi, INT in_GRj, INT out_GRk)
1602 {
1603   int cycles;
1604
1605   if (model_insn == FRV_INSN_MODEL_PASS_1)
1606     {
1607       /* The entire VLIW insn must wait if there is a dependency on a register
1608          which is not ready yet.  */
1609       vliw_wait_for_GR (cpu, in_GRi);
1610       vliw_wait_for_GR (cpu, in_GRj);
1611       vliw_wait_for_GR (cpu, out_GRk);
1612       handle_resource_wait (cpu);
1613       load_wait_for_GR (cpu, in_GRi);
1614       load_wait_for_GR (cpu, in_GRj);
1615       load_wait_for_GR (cpu, out_GRk);
1616       trace_vliw_wait_cycles (cpu);
1617       return 0;
1618     }
1619
1620   cycles = idesc->timing->units[unit_num].done;
1621
1622   /* The latency of GRk will depend on how long it takes to swap
1623      the the data from the cache or memory.  */
1624   update_GR_latency_for_swap (cpu, out_GRk, cycles);
1625
1626   return cycles;
1627 }
1628
1629 int
1630 frvbf_model_fr550_u_fr2fr (SIM_CPU *cpu, const IDESC *idesc,
1631                            int unit_num, int referenced,
1632                            INT in_FRj, INT out_FRk)
1633 {
1634   int cycles;
1635
1636   if (model_insn == FRV_INSN_MODEL_PASS_1)
1637     {
1638       /* The entire VLIW insn must wait if there is a dependency on a register
1639          which is not ready yet.
1640          The latency of the registers may be less than previously recorded,
1641          depending on how they were used previously.
1642          See Table 14-15 in the LSI.  */
1643       adjust_float_register_busy (cpu, -1, 1, in_FRj, 1, out_FRk, 1);
1644       vliw_wait_for_FR (cpu, in_FRj);
1645       vliw_wait_for_FR (cpu, out_FRk);
1646       handle_resource_wait (cpu);
1647       load_wait_for_FR (cpu, in_FRj);
1648       load_wait_for_FR (cpu, out_FRk);
1649       trace_vliw_wait_cycles (cpu);
1650       return 0;
1651     }
1652
1653   /* The latency of FRj is 2 cycles.  */
1654   cycles = idesc->timing->units[unit_num].done;
1655   update_FR_latency (cpu, out_FRk, cycles + 2);
1656
1657   set_use_is_fr_complex_2 (cpu, out_FRk);
1658
1659   return cycles;
1660 }
1661
1662 int
1663 frvbf_model_fr550_u_fr2gr (SIM_CPU *cpu, const IDESC *idesc,
1664                            int unit_num, int referenced,
1665                            INT in_FRk, INT out_GRj)
1666 {
1667   int cycles;
1668
1669   if (model_insn == FRV_INSN_MODEL_PASS_1)
1670     {
1671       /* The entire VLIW insn must wait if there is a dependency on a register
1672          which is not ready yet.
1673          The latency of the registers may be less than previously recorded,
1674          depending on how they were used previously.
1675          See Table 14-15 in the LSI.  */
1676       adjust_float_register_busy (cpu, in_FRk, 1, -1, 1, -1, 1);
1677       vliw_wait_for_FR (cpu, in_FRk);
1678       vliw_wait_for_GR (cpu, out_GRj);
1679       handle_resource_wait (cpu);
1680       load_wait_for_FR (cpu, in_FRk);
1681       load_wait_for_GR (cpu, out_GRj);
1682       trace_vliw_wait_cycles (cpu);
1683       return 0;
1684     }
1685
1686   /* The latency of GRj is 1 cycle.  */
1687   cycles = idesc->timing->units[unit_num].done;
1688   update_GR_latency (cpu, out_GRj, cycles + 1);
1689
1690   return cycles;
1691 }
1692
1693 int
1694 frvbf_model_fr550_u_clrgr (SIM_CPU *cpu, const IDESC *idesc,
1695                            int unit_num, int referenced,
1696                            INT in_GRk)
1697 {
1698   /* Modelling for this unit is the same as for fr500.  */
1699   return frvbf_model_fr500_u_clrgr (cpu, idesc, unit_num, referenced, in_GRk);
1700 }
1701
1702 int
1703 frvbf_model_fr550_u_clrfr (SIM_CPU *cpu, const IDESC *idesc,
1704                            int unit_num, int referenced,
1705                            INT in_FRk)
1706 {
1707   /* Modelling for this unit is the same as for fr500.  */
1708   return frvbf_model_fr500_u_clrfr (cpu, idesc, unit_num, referenced, in_FRk);
1709 }
1710
1711 int
1712 frvbf_model_fr550_u_commit (SIM_CPU *cpu, const IDESC *idesc,
1713                             int unit_num, int referenced,
1714                             INT in_GRk, INT in_FRk)
1715 {
1716   /* Modelling for this unit is the same as for fr500.  */
1717   return frvbf_model_fr500_u_commit (cpu, idesc, unit_num, referenced,
1718                                      in_GRk, in_FRk);
1719 }
1720
1721 int
1722 frvbf_model_fr550_u_media (SIM_CPU *cpu, const IDESC *idesc,
1723                            int unit_num, int referenced,
1724                            INT in_FRi, INT in_FRj, INT out_FRk)
1725 {
1726   int cycles;
1727   FRV_PROFILE_STATE *ps;
1728   FRV_VLIW *vliw;
1729   int slot;
1730
1731   if (model_insn == FRV_INSN_MODEL_PASS_1)
1732     return 0;
1733
1734   /* The preprocessing can execute right away.  */
1735   cycles = idesc->timing->units[unit_num].done;
1736
1737   /* If the previous use of the registers was a media op,
1738      then their latency may be less than previously recorded.
1739      See Table 14-15 in the LSI.  */
1740   adjust_float_register_busy_for_media (cpu, in_FRi, 1, in_FRj, 1, out_FRk, 1);
1741
1742   /* The post processing must wait if there is a dependency on a FR
1743      which is not ready yet.  */
1744   ps = CPU_PROFILE_STATE (cpu);
1745   ps->post_wait = cycles;
1746   vliw = CPU_VLIW (cpu);
1747   slot = vliw->next_slot - 1;
1748   slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
1749   post_wait_for_media (cpu, slot);
1750   post_wait_for_FR (cpu, in_FRi);
1751   post_wait_for_FR (cpu, in_FRj);
1752   post_wait_for_FR (cpu, out_FRk);
1753
1754   /* Restore the busy cycles of the registers we used.  */
1755   restore_float_register_busy_for_media (cpu, in_FRi, 1, in_FRj, 1, out_FRk, 1);
1756
1757   /* The latency of tht output register will be at least the latency of the
1758      other inputs.  Once initiated, post-processing will take 1 cycle.  */
1759   if (out_FRk >= 0)
1760     {
1761       update_FR_latency (cpu, out_FRk, ps->post_wait);
1762       update_FR_ptime (cpu, out_FRk, 1);
1763       /* Mark this use of the register as a media op.  */
1764       set_use_is_fr_complex_1 (cpu, out_FRk);
1765     }
1766
1767   /* the floating point unit resource has a latency of 3 cycles  */
1768   update_float_resource_latency (cpu, slot, cycles + 3);
1769
1770   return cycles;
1771 }
1772
1773 int
1774 frvbf_model_fr550_u_media_quad (SIM_CPU *cpu, const IDESC *idesc,
1775                                 int unit_num, int referenced,
1776                                 INT in_FRi, INT in_FRj,
1777                                 INT out_FRk)
1778 {
1779   int cycles;
1780   INT dual_FRi;
1781   INT dual_FRj;
1782   INT dual_FRk;
1783   FRV_PROFILE_STATE *ps;
1784   FRV_VLIW *vliw;
1785   int slot;
1786
1787   if (model_insn == FRV_INSN_MODEL_PASS_1)
1788     return 0;
1789
1790   /* The preprocessing can execute right away.  */
1791   cycles = idesc->timing->units[unit_num].done;
1792
1793   dual_FRi = DUAL_REG (in_FRi);
1794   dual_FRj = DUAL_REG (in_FRj);
1795   dual_FRk = DUAL_REG (out_FRk);
1796
1797   /* The latency of the registers may be less than previously recorded,
1798      depending on how they were used previously.
1799      See Table 14-15 in the LSI.  */
1800   adjust_float_register_busy_for_media (cpu, in_FRi, 2, in_FRj, 2, out_FRk, 2);
1801
1802   /* The post processing must wait if there is a dependency on a FR
1803      which is not ready yet.  */
1804   ps = CPU_PROFILE_STATE (cpu);
1805   ps->post_wait = cycles;
1806   vliw = CPU_VLIW (cpu);
1807   slot = vliw->next_slot - 1;
1808   slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
1809   post_wait_for_media (cpu, slot);
1810   post_wait_for_FR (cpu, in_FRi);
1811   post_wait_for_FR (cpu, dual_FRi);
1812   post_wait_for_FR (cpu, in_FRj);
1813   post_wait_for_FR (cpu, dual_FRj);
1814   post_wait_for_FR (cpu, out_FRk);
1815   post_wait_for_FR (cpu, dual_FRk);
1816
1817   /* Restore the busy cycles of the registers we used.  */
1818   restore_float_register_busy_for_media (cpu, in_FRi, 2, in_FRj, 2, out_FRk, 2);
1819
1820   /* The latency of the output register will be at least the latency of the
1821      other inputs.  Once initiated, post-processing take 1 cycle.  */
1822   update_FR_latency (cpu, out_FRk, ps->post_wait);
1823   update_FR_ptime (cpu, out_FRk, 1);
1824   set_use_is_fr_complex_1 (cpu, out_FRk);
1825
1826   if (dual_FRk >= 0)
1827     {
1828       update_FR_latency (cpu, dual_FRk, ps->post_wait);
1829       update_FR_ptime (cpu, dual_FRk, 1);
1830       set_use_is_fr_complex_1 (cpu, dual_FRk);
1831     }
1832
1833   /* the floating point unit resource has a latency of 3 cycles  */
1834   update_float_resource_latency (cpu, slot, cycles + 3);
1835
1836   return cycles;
1837 }
1838
1839 int
1840 frvbf_model_fr550_u_media_dual_expand (SIM_CPU *cpu, const IDESC *idesc,
1841                                        int unit_num, int referenced,
1842                                        INT in_FRi, INT out_FRk)
1843 {
1844   int cycles;
1845   INT dual_FRk;
1846   FRV_PROFILE_STATE *ps;
1847   FRV_VLIW *vliw;
1848   int slot;
1849
1850   if (model_insn == FRV_INSN_MODEL_PASS_1)
1851     return 0;
1852
1853   /* The preprocessing can execute right away.  */
1854   cycles = idesc->timing->units[unit_num].done;
1855
1856   /* If the previous use of the registers was a media op,
1857      then their latency will be less than previously recorded.
1858      See Table 14-15 in the LSI.  */
1859   dual_FRk = DUAL_REG (out_FRk);
1860   adjust_float_register_busy_for_media (cpu, in_FRi, 1, -1, 1, out_FRk, 2);
1861
1862   /* The post processing must wait if there is a dependency on a FR
1863      which is not ready yet.  */
1864   ps = CPU_PROFILE_STATE (cpu);
1865   ps->post_wait = cycles;
1866   vliw = CPU_VLIW (cpu);
1867   slot = vliw->next_slot - 1;
1868   slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
1869   post_wait_for_media (cpu, slot);
1870   post_wait_for_FR (cpu, in_FRi);
1871   post_wait_for_FR (cpu, out_FRk);
1872   post_wait_for_FR (cpu, dual_FRk);
1873
1874   /* Restore the busy cycles of the registers we used.  */
1875   restore_float_register_busy_for_media (cpu, in_FRi, 1, -1, 1, out_FRk, 2);
1876
1877   /* The latency of the output register will be at least the latency of the
1878      other inputs.  Once initiated, post-processing will take 1 cycle.  */
1879   update_FR_latency (cpu, out_FRk, ps->post_wait);
1880   update_FR_ptime (cpu, out_FRk, 1);
1881   set_use_is_fr_complex_1 (cpu, out_FRk);
1882
1883   if (dual_FRk >= 0)
1884     {
1885       update_FR_latency (cpu, dual_FRk, ps->post_wait);
1886       update_FR_ptime (cpu, dual_FRk, 1);
1887       set_use_is_fr_complex_1 (cpu, dual_FRk);
1888     }
1889
1890   /* the floating point unit resource has a latency of 3 cycles  */
1891   update_float_resource_latency (cpu, slot, cycles + 3);
1892
1893   return cycles;
1894 }
1895
1896 int
1897 frvbf_model_fr550_u_media_3_dual (SIM_CPU *cpu, const IDESC *idesc,
1898                                   int unit_num, int referenced,
1899                                   INT in_FRi, INT out_FRk)
1900 {
1901   int cycles;
1902   INT dual_FRi;
1903   FRV_PROFILE_STATE *ps;
1904   FRV_VLIW *vliw;
1905   int slot;
1906
1907   if (model_insn == FRV_INSN_MODEL_PASS_1)
1908     return 0;
1909
1910   /* The preprocessing can execute right away.  */
1911   cycles = idesc->timing->units[unit_num].done;
1912
1913   dual_FRi = DUAL_REG (in_FRi);
1914
1915   /* The latency of the registers may be less than previously recorded,
1916      depending on how they were used previously.
1917      See Table 14-15 in the LSI.  */
1918   adjust_float_register_busy_for_media (cpu, in_FRi, 2, -1, 1, out_FRk, 1);
1919
1920   /* The post processing must wait if there is a dependency on a FR
1921      which is not ready yet.  */
1922   ps = CPU_PROFILE_STATE (cpu);
1923   ps->post_wait = cycles;
1924   vliw = CPU_VLIW (cpu);
1925   slot = vliw->next_slot - 1;
1926   slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
1927   post_wait_for_media (cpu, slot);
1928   post_wait_for_FR (cpu, in_FRi);
1929   post_wait_for_FR (cpu, dual_FRi);
1930   post_wait_for_FR (cpu, out_FRk);
1931
1932   /* Restore the busy cycles of the registers we used.  */
1933   restore_float_register_busy_for_media (cpu, in_FRi, 2, -1, 1, out_FRk, 1);
1934
1935   /* The latency of the output register will be at least the latency of the
1936      other inputs.  Once initiated, post-processing takes 1 cycle.  */
1937   update_FR_latency (cpu, out_FRk, ps->post_wait);
1938   update_FR_ptime (cpu, out_FRk, 1);
1939
1940   set_use_is_fr_complex_1 (cpu, out_FRk);
1941
1942   /* the floating point unit resource has a latency of 3 cycles  */
1943   update_float_resource_latency (cpu, slot, cycles + 3);
1944
1945   return cycles;
1946 }
1947
1948 int
1949 frvbf_model_fr550_u_media_3_acc (SIM_CPU *cpu, const IDESC *idesc,
1950                                  int unit_num, int referenced,
1951                                  INT in_FRj, INT in_ACC40Si,
1952                                  INT out_FRk)
1953 {
1954   int cycles;
1955   FRV_PROFILE_STATE *ps;
1956   FRV_VLIW *vliw;
1957   int slot;
1958
1959   if (model_insn == FRV_INSN_MODEL_PASS_1)
1960     return 0;
1961
1962   /* The preprocessing can execute right away.  */
1963   cycles = idesc->timing->units[unit_num].done;
1964
1965   /* If the previous use of the registers was a media op,
1966      then their latency will be less than previously recorded.
1967      See Table 14-15 in the LSI.  */
1968   adjust_float_register_busy_for_media (cpu, -1, 1, in_FRj, 1, out_FRk, 1);
1969
1970   /* The post processing must wait if there is a dependency on a FR
1971      which is not ready yet.  */
1972   ps = CPU_PROFILE_STATE (cpu);
1973   ps->post_wait = cycles;
1974   vliw = CPU_VLIW (cpu);
1975   slot = vliw->next_slot - 1;
1976   slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
1977   post_wait_for_media (cpu, slot);
1978   post_wait_for_FR (cpu, in_FRj);
1979   post_wait_for_FR (cpu, out_FRk);
1980   post_wait_for_ACC (cpu, in_ACC40Si);
1981
1982   /* Restore the busy cycles of the registers we used.  */
1983   restore_float_register_busy_for_media (cpu, -1, 1, in_FRj, 1, out_FRk, 1);
1984
1985   /* The latency of tht output register will be at least the latency of the
1986      other inputs.  Once initiated, post-processing will take 1 cycle.  */
1987   update_FR_latency (cpu, out_FRk, ps->post_wait);
1988   update_FR_ptime (cpu, out_FRk, 1);
1989
1990   set_use_is_fr_complex_1 (cpu, out_FRk);
1991
1992   /* the floating point unit resource has a latency of 3 cycles  */
1993   update_float_resource_latency (cpu, slot, cycles + 3);
1994
1995   return cycles;
1996 }
1997
1998 int
1999 frvbf_model_fr550_u_media_3_acc_dual (SIM_CPU *cpu, const IDESC *idesc,
2000                                       int unit_num, int referenced,
2001                                       INT in_ACC40Si, INT out_FRk)
2002 {
2003   int cycles;
2004   FRV_PROFILE_STATE *ps;
2005   INT ACC40Si_1;
2006   INT dual_FRk;
2007   FRV_VLIW *vliw;
2008   int slot;
2009
2010   if (model_insn == FRV_INSN_MODEL_PASS_1)
2011     return 0;
2012
2013   /* The preprocessing can execute right away.  */
2014   cycles = idesc->timing->units[unit_num].done;
2015
2016   ACC40Si_1 = DUAL_REG (in_ACC40Si);
2017   dual_FRk = DUAL_REG (out_FRk);
2018
2019   /* If the previous use of the registers was a media op,
2020      then their latency will be less than previously recorded.
2021      See Table 14-15 in the LSI.  */
2022   adjust_float_register_busy_for_media (cpu, -1, 1, -1, 1, out_FRk, 2);
2023
2024   /* The post processing must wait if there is a dependency on a FR
2025      which is not ready yet.  */
2026   ps = CPU_PROFILE_STATE (cpu);
2027   ps->post_wait = cycles;
2028   vliw = CPU_VLIW (cpu);
2029   slot = vliw->next_slot - 1;
2030   slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
2031   post_wait_for_media (cpu, slot);
2032   post_wait_for_ACC (cpu, in_ACC40Si);
2033   post_wait_for_ACC (cpu, ACC40Si_1);
2034   post_wait_for_FR (cpu, out_FRk);
2035   post_wait_for_FR (cpu, dual_FRk);
2036
2037   /* Restore the busy cycles of the registers we used.  */
2038   restore_float_register_busy_for_media (cpu, -1, 1, -1, 1, out_FRk, 2);
2039
2040   /* The latency of the output register will be at least the latency of the
2041      other inputs.  Once initiated, post-processing will take 1 cycle.  */
2042   update_FR_latency (cpu, out_FRk, ps->post_wait);
2043   update_FR_ptime (cpu, out_FRk, 1);
2044   set_use_is_fr_complex_1 (cpu, out_FRk);
2045   if (dual_FRk >= 0)
2046     {
2047       update_FR_latency (cpu, dual_FRk, ps->post_wait);
2048       update_FR_ptime (cpu, dual_FRk, 1);
2049       set_use_is_fr_complex_1 (cpu, dual_FRk);
2050     }
2051
2052   /* the floating point unit resource has a latency of 3 cycles  */
2053   update_float_resource_latency (cpu, slot, cycles + 3);
2054
2055   return cycles;
2056 }
2057
2058 int
2059 frvbf_model_fr550_u_media_3_wtacc (SIM_CPU *cpu, const IDESC *idesc,
2060                                    int unit_num, int referenced,
2061                                    INT in_FRi, INT out_ACC40Sk)
2062 {
2063   int cycles;
2064   FRV_PROFILE_STATE *ps;
2065   FRV_VLIW *vliw;
2066   int slot;
2067
2068   if (model_insn == FRV_INSN_MODEL_PASS_1)
2069     return 0;
2070
2071   /* The preprocessing can execute right away.  */
2072   cycles = idesc->timing->units[unit_num].done;
2073
2074   ps = CPU_PROFILE_STATE (cpu);
2075
2076   /* The latency of the registers may be less than previously recorded,
2077      depending on how they were used previously.
2078      See Table 14-15 in the LSI.  */
2079   adjust_float_register_busy_for_media (cpu, in_FRi, 1, -1, 1, -1, 1);
2080
2081   /* The post processing must wait if there is a dependency on a FR
2082      which is not ready yet.  */
2083   ps->post_wait = cycles;
2084   vliw = CPU_VLIW (cpu);
2085   slot = vliw->next_slot - 1;
2086   slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
2087   post_wait_for_media (cpu, slot);
2088   post_wait_for_FR (cpu, in_FRi);
2089   post_wait_for_ACC (cpu, out_ACC40Sk);
2090
2091   /* Restore the busy cycles of the registers we used.  */
2092   restore_float_register_busy_for_media (cpu, in_FRi, 1, -1, 1, -1, 1);
2093
2094   /* The latency of the output register will be at least the latency of the
2095      other inputs.  Once initiated, post-processing will take 1 cycle.  */
2096   update_ACC_latency (cpu, out_ACC40Sk, ps->post_wait);
2097   update_ACC_ptime (cpu, out_ACC40Sk, 1);
2098   set_use_is_acc_mmac (cpu, out_ACC40Sk);
2099
2100   /* the floating point unit resource has a latency of 3 cycles  */
2101   update_float_resource_latency (cpu, slot, cycles + 3);
2102
2103   return cycles;
2104 }
2105
2106 int
2107 frvbf_model_fr550_u_media_3_mclracc (SIM_CPU *cpu, const IDESC *idesc,
2108                                      int unit_num, int referenced)
2109 {
2110   int cycles;
2111   FRV_PROFILE_STATE *ps;
2112   FRV_VLIW *vliw;
2113   int slot;
2114   int i;
2115
2116   if (model_insn == FRV_INSN_MODEL_PASS_1)
2117     return 0;
2118
2119   /* The preprocessing can execute right away.  */
2120   cycles = idesc->timing->units[unit_num].done;
2121
2122   ps = CPU_PROFILE_STATE (cpu);
2123
2124   /* The post processing must wait if there is a dependency on a FR
2125      which is not ready yet.  */
2126   ps->post_wait = cycles;
2127   vliw = CPU_VLIW (cpu);
2128   slot = vliw->next_slot - 1;
2129   slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
2130   post_wait_for_media (cpu, slot);
2131
2132   /* If A was 1 and the accumulator was ACC0, then we must check all
2133      accumulators. Otherwise just wait for the specified accumulator.  */
2134   if (ps->mclracc_A && ps->mclracc_acc == 0)
2135     {
2136       for (i = 0; i < 8; ++i)
2137         post_wait_for_ACC (cpu, i);
2138     }
2139   else
2140     post_wait_for_ACC (cpu, ps->mclracc_acc);
2141
2142   /* The latency of the output registers will be at least the latency of the
2143      other inputs.  Once initiated, post-processing will take 1 cycle.  */
2144   if (ps->mclracc_A && ps->mclracc_acc == 0)
2145     {
2146       for (i = 0; i < 8; ++i)
2147         {
2148           update_ACC_latency (cpu, i, ps->post_wait);
2149           update_ACC_ptime (cpu, i, 1);
2150           set_use_is_acc_mmac (cpu, i);
2151         }
2152     }
2153   else
2154     {
2155       update_ACC_latency (cpu, ps->mclracc_acc, ps->post_wait);
2156       update_ACC_ptime (cpu, ps->mclracc_acc, 1);
2157       set_use_is_acc_mmac (cpu, ps->mclracc_acc);
2158     }
2159
2160   /* the floating point unit resource has a latency of 3 cycles  */
2161   update_float_resource_latency (cpu, slot, cycles + 3);
2162
2163   return cycles;
2164 }
2165
2166 int
2167 frvbf_model_fr550_u_media_set (SIM_CPU *cpu, const IDESC *idesc,
2168                                int unit_num, int referenced,
2169                                INT out_FRk)
2170 {
2171   int cycles;
2172   FRV_PROFILE_STATE *ps;
2173   FRV_VLIW *vliw;
2174   int slot;
2175
2176   if (model_insn == FRV_INSN_MODEL_PASS_1)
2177     return 0;
2178
2179   /* The preprocessing can execute right away.  */
2180   cycles = idesc->timing->units[unit_num].done;
2181
2182   /* If the previous use of the registers was a media op,
2183      then their latency will be less than previously recorded.
2184      See Table 14-15 in the LSI.  */
2185   adjust_float_register_busy_for_media (cpu, -1, 1, -1, 1, out_FRk, 1);
2186
2187   /* The post processing must wait if there is a dependency on a FR
2188      which is not ready yet.  */
2189   ps = CPU_PROFILE_STATE (cpu);
2190   ps->post_wait = cycles;
2191   vliw = CPU_VLIW (cpu);
2192   slot = vliw->next_slot - 1;
2193   slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
2194   post_wait_for_media (cpu, slot);
2195   post_wait_for_FR (cpu, out_FRk);
2196
2197   /* Restore the busy cycles of the registers we used.  */
2198   restore_float_register_busy_for_media (cpu, -1, 1, -1, 1, out_FRk, 1);
2199
2200   /* The latency of the output register will be at least the latency of the
2201      other inputs.  Once initiated, post-processing takes 1 cycle.  */
2202   update_FR_latency (cpu, out_FRk, ps->post_wait);
2203   update_FR_ptime (cpu, out_FRk, 1);
2204   fr550_reset_acc_flags (cpu, out_FRk);
2205
2206   /* the floating point unit resource has a latency of 3 cycles  */
2207   update_float_resource_latency (cpu, slot, cycles + 3);
2208
2209   return cycles;
2210 }
2211
2212 int
2213 frvbf_model_fr550_u_media_4 (SIM_CPU *cpu, const IDESC *idesc,
2214                              int unit_num, int referenced,
2215                              INT in_FRi, INT in_FRj,
2216                              INT out_ACC40Sk, INT out_ACC40Uk)
2217 {
2218   int cycles;
2219   INT dual_ACC40Sk;
2220   INT dual_ACC40Uk;
2221   FRV_PROFILE_STATE *ps;
2222   FRV_VLIW *vliw;
2223   int slot;
2224
2225   if (model_insn == FRV_INSN_MODEL_PASS_1)
2226     return 0;
2227
2228   /* The preprocessing can execute right away.  */
2229   cycles = idesc->timing->units[unit_num].done;
2230
2231   ps = CPU_PROFILE_STATE (cpu);
2232   dual_ACC40Sk = DUAL_REG (out_ACC40Sk);
2233   dual_ACC40Uk = DUAL_REG (out_ACC40Uk);
2234
2235   /* The latency of the registers may be less than previously recorded,
2236      depending on how they were used previously.
2237      See Table 14-15 in the LSI.  */
2238   adjust_acc_busy_for_mmac (cpu, -1, 1, out_ACC40Sk, 2);
2239   adjust_acc_busy_for_mmac (cpu, -1, 1, out_ACC40Uk, 2);
2240
2241   /* The post processing must wait if there is a dependency on a FR
2242      which is not ready yet.  */
2243   ps->post_wait = cycles;
2244   vliw = CPU_VLIW (cpu);
2245   slot = vliw->next_slot - 1;
2246   slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
2247   post_wait_for_media (cpu, slot);
2248   post_wait_for_FR (cpu, in_FRi);
2249   post_wait_for_FR (cpu, in_FRj);
2250   post_wait_for_ACC (cpu, out_ACC40Sk);
2251   post_wait_for_ACC (cpu, dual_ACC40Sk);
2252   post_wait_for_ACC (cpu, out_ACC40Uk);
2253   post_wait_for_ACC (cpu, dual_ACC40Uk);
2254
2255   /* Restore the busy cycles of the registers we used.  */
2256   restore_acc_busy_for_mmac (cpu, -1, 1, out_ACC40Sk, 2);
2257   restore_acc_busy_for_mmac (cpu, -1, 1, out_ACC40Uk, 2);
2258
2259   /* The latency of the output register will be at least the latency of the
2260      other inputs.  Once initiated, post-processing will take 1 cycles.  */
2261   if (out_ACC40Sk >= 0)
2262     {
2263       update_ACC_latency (cpu, out_ACC40Sk, ps->post_wait + 1);
2264       set_use_is_acc_mmac (cpu, out_ACC40Sk);
2265     }
2266   if (dual_ACC40Sk >= 0)
2267     {
2268       update_ACC_latency (cpu, dual_ACC40Sk, ps->post_wait + 1);
2269       set_use_is_acc_mmac (cpu, dual_ACC40Sk);
2270     }
2271   if (out_ACC40Uk >= 0)
2272     {
2273       update_ACC_latency (cpu, out_ACC40Uk, ps->post_wait + 1);
2274       set_use_is_acc_mmac (cpu, out_ACC40Uk);
2275     }
2276   if (dual_ACC40Uk >= 0)
2277     {
2278       update_ACC_latency (cpu, dual_ACC40Uk, ps->post_wait + 1);
2279       set_use_is_acc_mmac (cpu, dual_ACC40Uk);
2280     }
2281
2282   /* the floating point unit resource has a latency of 3 cycles  */
2283   update_float_resource_latency (cpu, slot, cycles + 3);
2284
2285   return cycles;
2286 }
2287
2288 int
2289 frvbf_model_fr550_u_media_4_acc (SIM_CPU *cpu, const IDESC *idesc,
2290                                  int unit_num, int referenced,
2291                                  INT in_ACC40Si, INT out_ACC40Sk)
2292 {
2293   int cycles;
2294   INT ACC40Si_1;
2295   FRV_PROFILE_STATE *ps;
2296   FRV_VLIW *vliw;
2297   int slot;
2298
2299   if (model_insn == FRV_INSN_MODEL_PASS_1)
2300     return 0;
2301
2302   /* The preprocessing can execute right away.  */
2303   cycles = idesc->timing->units[unit_num].done;
2304
2305   ACC40Si_1 = DUAL_REG (in_ACC40Si);
2306
2307   ps = CPU_PROFILE_STATE (cpu);
2308   /* The latency of the registers may be less than previously recorded,
2309      depending on how they were used previously.
2310      See Table 14-15 in the LSI.  */
2311   adjust_acc_busy_for_mmac (cpu, in_ACC40Si, 2, out_ACC40Sk, 1);
2312
2313   /* The post processing must wait if there is a dependency on a register
2314      which is not ready yet.  */
2315   ps->post_wait = cycles;
2316   vliw = CPU_VLIW (cpu);
2317   slot = vliw->next_slot - 1;
2318   slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
2319   post_wait_for_media (cpu, slot);
2320   post_wait_for_ACC (cpu, in_ACC40Si);
2321   post_wait_for_ACC (cpu, ACC40Si_1);
2322   post_wait_for_ACC (cpu, out_ACC40Sk);
2323
2324   /* Restore the busy cycles of the registers we used.  */
2325   restore_acc_busy_for_mmac (cpu, in_ACC40Si, 2, out_ACC40Sk, 1);
2326
2327   /* The latency of the output register will be at least the latency of the
2328      other inputs.  Once initiated, post-processing will take 1 cycle.  */
2329   update_ACC_latency (cpu, out_ACC40Sk, ps->post_wait + 1);
2330   set_use_is_acc_mmac (cpu, out_ACC40Sk);
2331
2332   /* the floating point unit resource has a latency of 3 cycles  */
2333   update_float_resource_latency (cpu, slot, cycles + 3);
2334
2335   return cycles;
2336 }
2337
2338 int
2339 frvbf_model_fr550_u_media_4_acc_dual (SIM_CPU *cpu, const IDESC *idesc,
2340                                       int unit_num, int referenced,
2341                                       INT in_ACC40Si, INT out_ACC40Sk)
2342 {
2343   int cycles;
2344   INT ACC40Si_1;
2345   INT ACC40Si_2;
2346   INT ACC40Si_3;
2347   INT ACC40Sk_1;
2348   FRV_PROFILE_STATE *ps;
2349   FRV_VLIW *vliw;
2350   int slot;
2351
2352   if (model_insn == FRV_INSN_MODEL_PASS_1)
2353     return 0;
2354
2355   /* The preprocessing can execute right away.  */
2356   cycles = idesc->timing->units[unit_num].done;
2357
2358   ACC40Si_1 = DUAL_REG (in_ACC40Si);
2359   ACC40Si_2 = DUAL_REG (ACC40Si_1);
2360   ACC40Si_3 = DUAL_REG (ACC40Si_2);
2361   ACC40Sk_1 = DUAL_REG (out_ACC40Sk);
2362
2363   ps = CPU_PROFILE_STATE (cpu);
2364   /* The latency of the registers may be less than previously recorded,
2365      depending on how they were used previously.
2366      See Table 14-15 in the LSI.  */
2367   adjust_acc_busy_for_mmac (cpu, in_ACC40Si, 4, out_ACC40Sk, 2);
2368
2369   /* The post processing must wait if there is a dependency on a register
2370      which is not ready yet.  */
2371   ps->post_wait = cycles;
2372   vliw = CPU_VLIW (cpu);
2373   slot = vliw->next_slot - 1;
2374   slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
2375   post_wait_for_media (cpu, slot);
2376   post_wait_for_ACC (cpu, in_ACC40Si);
2377   post_wait_for_ACC (cpu, ACC40Si_1);
2378   post_wait_for_ACC (cpu, ACC40Si_2);
2379   post_wait_for_ACC (cpu, ACC40Si_3);
2380   post_wait_for_ACC (cpu, out_ACC40Sk);
2381   post_wait_for_ACC (cpu, ACC40Sk_1);
2382
2383   /* Restore the busy cycles of the registers we used.  */
2384   restore_acc_busy_for_mmac (cpu, in_ACC40Si, 4, out_ACC40Sk, 2);
2385
2386   /* The latency of the output register will be at least the latency of the
2387      other inputs.  Once initiated, post-processing will take 1 cycle.  */
2388   update_ACC_latency (cpu, out_ACC40Sk, ps->post_wait + 1);
2389   set_use_is_acc_mmac (cpu, out_ACC40Sk);
2390   if (ACC40Sk_1 >= 0)
2391     {
2392       update_ACC_latency (cpu, ACC40Sk_1, ps->post_wait + 1);
2393       set_use_is_acc_mmac (cpu, ACC40Sk_1);
2394     }
2395
2396   /* the floating point unit resource has a latency of 3 cycles  */
2397   update_float_resource_latency (cpu, slot, cycles + 3);
2398
2399   return cycles;
2400 }
2401
2402 int
2403 frvbf_model_fr550_u_media_4_add_sub (SIM_CPU *cpu, const IDESC *idesc,
2404                                      int unit_num, int referenced,
2405                                      INT in_ACC40Si, INT out_ACC40Sk)
2406 {
2407   int cycles;
2408   INT ACC40Si_1;
2409   INT ACC40Sk_1;
2410   FRV_PROFILE_STATE *ps;
2411   FRV_VLIW *vliw;
2412   int slot;
2413
2414   if (model_insn == FRV_INSN_MODEL_PASS_1)
2415     return 0;
2416
2417   /* The preprocessing can execute right away.  */
2418   cycles = idesc->timing->units[unit_num].done;
2419
2420   ACC40Si_1 = DUAL_REG (in_ACC40Si);
2421   ACC40Sk_1 = DUAL_REG (out_ACC40Sk);
2422
2423   ps = CPU_PROFILE_STATE (cpu);
2424   /* The latency of the registers may be less than previously recorded,
2425      depending on how they were used previously.
2426      See Table 14-15 in the LSI.  */
2427   adjust_acc_busy_for_mmac (cpu, in_ACC40Si, 2, out_ACC40Sk, 2);
2428
2429   /* The post processing must wait if there is a dependency on a register
2430      which is not ready yet.  */
2431   ps->post_wait = cycles;
2432   vliw = CPU_VLIW (cpu);
2433   slot = vliw->next_slot - 1;
2434   slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
2435   post_wait_for_media (cpu, slot);
2436   post_wait_for_ACC (cpu, in_ACC40Si);
2437   post_wait_for_ACC (cpu, ACC40Si_1);
2438   post_wait_for_ACC (cpu, out_ACC40Sk);
2439   post_wait_for_ACC (cpu, ACC40Sk_1);
2440
2441   /* Restore the busy cycles of the registers we used.  */
2442   restore_acc_busy_for_mmac (cpu, in_ACC40Si, 2, out_ACC40Sk, 2);
2443
2444   /* The latency of the output register will be at least the latency of the
2445      other inputs.  Once initiated, post-processing will take 1 cycle.  */
2446   update_ACC_latency (cpu, out_ACC40Sk, ps->post_wait + 1);
2447   set_use_is_acc_mmac (cpu, out_ACC40Sk);
2448   if (ACC40Sk_1 >= 0)
2449     {
2450       update_ACC_latency (cpu, ACC40Sk_1, ps->post_wait + 1);
2451       set_use_is_acc_mmac (cpu, ACC40Sk_1);
2452     }
2453
2454   /* the floating point unit resource has a latency of 3 cycles  */
2455   update_float_resource_latency (cpu, slot, cycles + 3);
2456
2457   return cycles;
2458 }
2459
2460 int
2461 frvbf_model_fr550_u_media_4_add_sub_dual (SIM_CPU *cpu, const IDESC *idesc,
2462                                           int unit_num, int referenced,
2463                                           INT in_ACC40Si, INT out_ACC40Sk)
2464 {
2465   int cycles;
2466   INT ACC40Si_1;
2467   INT ACC40Si_2;
2468   INT ACC40Si_3;
2469   INT ACC40Sk_1;
2470   INT ACC40Sk_2;
2471   INT ACC40Sk_3;
2472   FRV_PROFILE_STATE *ps;
2473   FRV_VLIW *vliw;
2474   int slot;
2475
2476   if (model_insn == FRV_INSN_MODEL_PASS_1)
2477     return 0;
2478
2479   /* The preprocessing can execute right away.  */
2480   cycles = idesc->timing->units[unit_num].done;
2481
2482   ACC40Si_1 = DUAL_REG (in_ACC40Si);
2483   ACC40Si_2 = DUAL_REG (ACC40Si_1);
2484   ACC40Si_3 = DUAL_REG (ACC40Si_2);
2485   ACC40Sk_1 = DUAL_REG (out_ACC40Sk);
2486   ACC40Sk_2 = DUAL_REG (ACC40Sk_1);
2487   ACC40Sk_3 = DUAL_REG (ACC40Sk_2);
2488
2489   ps = CPU_PROFILE_STATE (cpu);
2490   /* The latency of the registers may be less than previously recorded,
2491      depending on how they were used previously.
2492      See Table 14-15 in the LSI.  */
2493   adjust_acc_busy_for_mmac (cpu, in_ACC40Si, 4, out_ACC40Sk, 4);
2494
2495   /* The post processing must wait if there is a dependency on a register
2496      which is not ready yet.  */
2497   ps->post_wait = cycles;
2498   vliw = CPU_VLIW (cpu);
2499   slot = vliw->next_slot - 1;
2500   slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
2501   post_wait_for_media (cpu, slot);
2502   post_wait_for_ACC (cpu, in_ACC40Si);
2503   post_wait_for_ACC (cpu, ACC40Si_1);
2504   post_wait_for_ACC (cpu, ACC40Si_2);
2505   post_wait_for_ACC (cpu, ACC40Si_3);
2506   post_wait_for_ACC (cpu, out_ACC40Sk);
2507   post_wait_for_ACC (cpu, ACC40Sk_1);
2508   post_wait_for_ACC (cpu, ACC40Sk_2);
2509   post_wait_for_ACC (cpu, ACC40Sk_3);
2510
2511   /* Restore the busy cycles of the registers we used.  */
2512   restore_acc_busy_for_mmac (cpu, in_ACC40Si, 4, out_ACC40Sk, 4);
2513
2514   /* The latency of the output register will be at least the latency of the
2515      other inputs.  Once initiated, post-processing will take 1 cycle.  */
2516   update_ACC_latency (cpu, out_ACC40Sk, ps->post_wait + 1);
2517   set_use_is_acc_mmac (cpu, out_ACC40Sk);
2518   if (ACC40Sk_1 >= 0)
2519     {
2520       update_ACC_latency (cpu, ACC40Sk_1, ps->post_wait + 1);
2521       set_use_is_acc_mmac (cpu, ACC40Sk_1);
2522     }
2523   if (ACC40Sk_2 >= 0)
2524     {
2525       update_ACC_latency (cpu, ACC40Sk_2, ps->post_wait + 1);
2526       set_use_is_acc_mmac (cpu, ACC40Sk_2);
2527     }
2528   if (ACC40Sk_3 >= 0)
2529     {
2530       update_ACC_latency (cpu, ACC40Sk_3, ps->post_wait + 1);
2531       set_use_is_acc_mmac (cpu, ACC40Sk_3);
2532     }
2533
2534   /* the floating point unit resource has a latency of 3 cycles  */
2535   update_float_resource_latency (cpu, slot, cycles + 3);
2536
2537   return cycles;
2538 }
2539
2540 int
2541 frvbf_model_fr550_u_media_4_quad (SIM_CPU *cpu, const IDESC *idesc,
2542                                   int unit_num, int referenced,
2543                                   INT in_FRi, INT in_FRj,
2544                                   INT out_ACC40Sk, INT out_ACC40Uk)
2545 {
2546   int cycles;
2547   INT dual_FRi;
2548   INT dual_FRj;
2549   INT ACC40Sk_1;
2550   INT ACC40Sk_2;
2551   INT ACC40Sk_3;
2552   INT ACC40Uk_1;
2553   INT ACC40Uk_2;
2554   INT ACC40Uk_3;
2555   FRV_PROFILE_STATE *ps;
2556   FRV_VLIW *vliw;
2557   int slot;
2558
2559   if (model_insn == FRV_INSN_MODEL_PASS_1)
2560     return 0;
2561
2562   /* The preprocessing can execute right away.  */
2563   cycles = idesc->timing->units[unit_num].done;
2564
2565   dual_FRi = DUAL_REG (in_FRi);
2566   dual_FRj = DUAL_REG (in_FRj);
2567   ACC40Sk_1 = DUAL_REG (out_ACC40Sk);
2568   ACC40Sk_2 = DUAL_REG (ACC40Sk_1);
2569   ACC40Sk_3 = DUAL_REG (ACC40Sk_2);
2570   ACC40Uk_1 = DUAL_REG (out_ACC40Uk);
2571   ACC40Uk_2 = DUAL_REG (ACC40Uk_1);
2572   ACC40Uk_3 = DUAL_REG (ACC40Uk_2);
2573
2574   ps = CPU_PROFILE_STATE (cpu);
2575   /* The latency of the registers may be less than previously recorded,
2576      depending on how they were used previously.
2577      See Table 14-15 in the LSI.  */
2578   adjust_float_register_busy_for_media (cpu, in_FRi, 2, in_FRj, 2, -1, 1);
2579   adjust_acc_busy_for_mmac (cpu, -1, 1, out_ACC40Sk, 4);
2580   adjust_acc_busy_for_mmac (cpu, -1, 1, out_ACC40Uk, 4);
2581
2582   /* The post processing must wait if there is a dependency on a FR
2583      which is not ready yet.  */
2584   ps->post_wait = cycles;
2585   vliw = CPU_VLIW (cpu);
2586   slot = vliw->next_slot - 1;
2587   slot = (*vliw->current_vliw)[slot] - UNIT_FM0;
2588   post_wait_for_media (cpu, slot);
2589   post_wait_for_FR (cpu, in_FRi);
2590   post_wait_for_FR (cpu, dual_FRi);
2591   post_wait_for_FR (cpu, in_FRj);
2592   post_wait_for_FR (cpu, dual_FRj);
2593   post_wait_for_ACC (cpu, out_ACC40Sk);
2594   post_wait_for_ACC (cpu, ACC40Sk_1);
2595   post_wait_for_ACC (cpu, ACC40Sk_2);
2596   post_wait_for_ACC (cpu, ACC40Sk_3);
2597   post_wait_for_ACC (cpu, out_ACC40Uk);
2598   post_wait_for_ACC (cpu, ACC40Uk_1);
2599   post_wait_for_ACC (cpu, ACC40Uk_2);
2600   post_wait_for_ACC (cpu, ACC40Uk_3);
2601
2602   /* Restore the busy cycles of the registers we used.  */
2603   restore_float_register_busy_for_media (cpu, in_FRi, 2, in_FRj, 2, -1, 1);
2604   restore_acc_busy_for_mmac (cpu, -1, 1, out_ACC40Sk, 4);
2605   restore_acc_busy_for_mmac (cpu, -1, 1, out_ACC40Uk, 4);
2606
2607   /* The latency of the output register will be at least the latency of the
2608      other inputs.  Once initiated, post-processing will take 1 cycle.  */
2609   if (out_ACC40Sk >= 0)
2610     {
2611       update_ACC_latency (cpu, out_ACC40Sk, ps->post_wait + 1);
2612
2613       set_use_is_acc_mmac (cpu, out_ACC40Sk);
2614       if (ACC40Sk_1 >= 0)
2615         {
2616           update_ACC_latency (cpu, ACC40Sk_1, ps->post_wait + 1);
2617
2618           set_use_is_acc_mmac (cpu, ACC40Sk_1);
2619         }
2620       if (ACC40Sk_2 >= 0)
2621         {
2622           update_ACC_latency (cpu, ACC40Sk_2, ps->post_wait + 1);
2623
2624           set_use_is_acc_mmac (cpu, ACC40Sk_2);
2625         }
2626       if (ACC40Sk_3 >= 0)
2627         {
2628           update_ACC_latency (cpu, ACC40Sk_3, ps->post_wait + 1);
2629
2630           set_use_is_acc_mmac (cpu, ACC40Sk_3);
2631         }
2632     }
2633   else if (out_ACC40Uk >= 0)
2634     {
2635       update_ACC_latency (cpu, out_ACC40Uk, ps->post_wait + 1);
2636
2637       set_use_is_acc_mmac (cpu, out_ACC40Uk);
2638       if (ACC40Uk_1 >= 0)
2639         {
2640           update_ACC_latency (cpu, ACC40Uk_1, ps->post_wait + 1);
2641
2642           set_use_is_acc_mmac (cpu, ACC40Uk_1);
2643         }
2644       if (ACC40Uk_2 >= 0)
2645         {
2646           update_ACC_latency (cpu, ACC40Uk_2, ps->post_wait + 1);
2647
2648           set_use_is_acc_mmac (cpu, ACC40Uk_2);
2649         }
2650       if (ACC40Uk_3 >= 0)
2651         {
2652           update_ACC_latency (cpu, ACC40Uk_3, ps->post_wait + 1);
2653
2654           set_use_is_acc_mmac (cpu, ACC40Uk_3);
2655         }
2656     }
2657
2658   /* the floating point unit resource has a latency of 3 cycles  */
2659   update_float_resource_latency (cpu, slot, cycles + 3);
2660
2661   return cycles;
2662 }
2663
2664 #endif /* WITH_PROFILE_MODEL_P */