]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/frv/profile-fr550.c
Update years in copyright notice for the GDB files.
[thirdparty/binutils-gdb.git] / sim / frv / profile-fr550.c
CommitLineData
e930b1f5
DB
1/* frv simulator fr550 dependent profiling code.
2
8acc9f48 3 Copyright (C) 2003-2013 Free Software Foundation, Inc.
e930b1f5
DB
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
4744ac1b
JB
10the Free Software Foundation; either version 3 of the License, or
11(at your option) any later version.
e930b1f5
DB
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
4744ac1b
JB
18You should have received a copy of the GNU General Public License
19along with this program. If not, see <http://www.gnu.org/licenses/>.
e930b1f5
DB
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 */