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