1/* frv simulator fr450 dependent profiling code.
2
3   Copyright (C) 2001-2023 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/* This must come before any other includes.  */
22#include "defs.h"
23
24#define WANT_CPU
25#define WANT_CPU_FRVBF
26
27#include "sim-main.h"
28#include "bfd.h"
29
30#if WITH_PROFILE_MODEL_P
31
32#include "profile.h"
33#include "profile-fr400.h"
34
35int
36frvbf_model_fr450_u_exec (SIM_CPU *cpu, const IDESC *idesc,
37			    int unit_num, int referenced)
38{
39  return idesc->timing->units[unit_num].done;
40}
41
42int
43frvbf_model_fr450_u_integer (SIM_CPU *cpu, const IDESC *idesc,
44			     int unit_num, int referenced,
45			     INT in_GRi, INT in_GRj, INT out_GRk,
46			     INT out_ICCi_1)
47{
48  /* Modelling for this unit is the same as for fr500.  */
49  return frvbf_model_fr500_u_integer (cpu, idesc, unit_num, referenced,
50				      in_GRi, in_GRj, out_GRk, out_ICCi_1);
51}
52
53int
54frvbf_model_fr450_u_imul (SIM_CPU *cpu, const IDESC *idesc,
55			  int unit_num, int referenced,
56			  INT in_GRi, INT in_GRj, INT out_GRk, INT out_ICCi_1)
57{
58  int cycles;
59
60  if (model_insn == FRV_INSN_MODEL_PASS_1)
61    {
62      /* Pass 1 is the same as for fr500.  */
63      return frvbf_model_fr500_u_imul (cpu, idesc, unit_num, referenced,
64				       in_GRi, in_GRj, out_GRk, out_ICCi_1);
65    }
66
67  /* icc0-icc4 are the upper 4 fields of the CCR.  */
68  if (out_ICCi_1 >= 0)
69    out_ICCi_1 += 4;
70
71  /* GRk and IACCi_1 have a latency of 1 cycle.  */
72  cycles = idesc->timing->units[unit_num].done;
73  update_GRdouble_latency (cpu, out_GRk, cycles + 1);
74  update_CCR_latency (cpu, out_ICCi_1, cycles + 1);
75
76  return cycles;
77}
78
79int
80frvbf_model_fr450_u_idiv (SIM_CPU *cpu, const IDESC *idesc,
81			  int unit_num, int referenced,
82			  INT in_GRi, INT in_GRj, INT out_GRk, INT out_ICCi_1)
83{
84  int cycles;
85
86  if (model_insn == FRV_INSN_MODEL_PASS_1)
87    {
88      /* Pass 1 is the same as for fr500.  */
89      return frvbf_model_fr500_u_idiv (cpu, idesc, unit_num, referenced,
90				       in_GRi, in_GRj, out_GRk, out_ICCi_1);
91    }
92
93  /* icc0-icc4 are the upper 4 fields of the CCR.  */
94  if (out_ICCi_1 >= 0)
95    out_ICCi_1 += 4;
96
97  /* GRk, ICCi_1 and the divider have a latency of 18 cycles  */
98  cycles = idesc->timing->units[unit_num].done;
99  update_GR_latency (cpu, out_GRk, cycles + 18);
100  update_CCR_latency (cpu, out_ICCi_1, cycles + 18);
101  update_idiv_resource_latency (cpu, 0, cycles + 18);
102
103  return cycles;
104}
105
106int
107frvbf_model_fr450_u_branch (SIM_CPU *cpu, const IDESC *idesc,
108			    int unit_num, int referenced,
109			    INT in_GRi, INT in_GRj,
110			    INT in_ICCi_2, INT in_ICCi_3)
111{
112  /* Modelling for this unit is the same as for fr400.  */
113  return frvbf_model_fr400_u_branch (cpu, idesc, unit_num, referenced,
114				     in_GRi, in_GRj, in_ICCi_2, in_ICCi_3);
115}
116
117int
118frvbf_model_fr450_u_trap (SIM_CPU *cpu, const IDESC *idesc,
119			  int unit_num, int referenced,
120			  INT in_GRi, INT in_GRj,
121			  INT in_ICCi_2, INT in_FCCi_2)
122{
123  /* Modelling for this unit is the same as for fr500.  */
124  return frvbf_model_fr500_u_trap (cpu, idesc, unit_num, referenced,
125				   in_GRi, in_GRj, in_ICCi_2, in_FCCi_2);
126}
127
128int
129frvbf_model_fr450_u_check (SIM_CPU *cpu, const IDESC *idesc,
130			   int unit_num, int referenced,
131			   INT in_ICCi_3, INT in_FCCi_3)
132{
133  /* Modelling for this unit is the same as for fr500.  */
134  return frvbf_model_fr500_u_check (cpu, idesc, unit_num, referenced,
135				    in_ICCi_3, in_FCCi_3);
136}
137
138int
139frvbf_model_fr450_u_set_hilo (SIM_CPU *cpu, const IDESC *idesc,
140			     int unit_num, int referenced,
141			     INT out_GRkhi, INT out_GRklo)
142{
143  /* Modelling for this unit is the same as for fr500.  */
144  return frvbf_model_fr500_u_set_hilo (cpu, idesc, unit_num, referenced,
145				       out_GRkhi, out_GRklo);
146}
147
148int
149frvbf_model_fr450_u_gr_load (SIM_CPU *cpu, const IDESC *idesc,
150			     int unit_num, int referenced,
151			     INT in_GRi, INT in_GRj,
152			     INT out_GRk, INT out_GRdoublek)
153{
154  int cycles;
155
156  if (model_insn == FRV_INSN_MODEL_PASS_1)
157    {
158      /* Pass 1 is the same as for fr500.  */
159      return frvbf_model_fr500_u_fr_load (cpu, idesc, unit_num, referenced,
160					  in_GRi, in_GRj, out_GRk,
161					  out_GRdoublek);
162    }
163
164  cycles = idesc->timing->units[unit_num].done;
165
166  /* The latency of GRk for a load will depend on how long it takes to retrieve
167     the the data from the cache or memory.  */
168  update_GR_latency_for_load (cpu, out_GRk, cycles);
169  update_GRdouble_latency_for_load (cpu, out_GRdoublek, cycles);
170
171  if (CGEN_ATTR_VALUE(idesc, idesc->attrs, CGEN_INSN_NON_EXCEPTING))
172    {
173      /* GNER has a latency of 2 cycles.  */
174      update_SPR_latency (cpu, GNER_FOR_GR (out_GRk), cycles + 2);
175      update_SPR_latency (cpu, GNER_FOR_GR (out_GRdoublek), cycles + 2);
176    }
177
178  return cycles;
179}
180
181int
182frvbf_model_fr450_u_gr_store (SIM_CPU *cpu, const IDESC *idesc,
183			      int unit_num, int referenced,
184			      INT in_GRi, INT in_GRj,
185			      INT in_GRk, INT in_GRdoublek)
186{
187  /* Modelling for this unit is the same as for fr500.  */
188  return frvbf_model_fr500_u_gr_store (cpu, idesc, unit_num, referenced,
189				       in_GRi, in_GRj, in_GRk, in_GRdoublek);
190}
191
192int
193frvbf_model_fr450_u_fr_load (SIM_CPU *cpu, const IDESC *idesc,
194			     int unit_num, int referenced,
195			     INT in_GRi, INT in_GRj,
196			     INT out_FRk, INT out_FRdoublek)
197{
198  /* Modelling for this unit is the same as for fr400.  */
199  return frvbf_model_fr400_u_fr_load (cpu, idesc, unit_num, referenced,
200				      in_GRi, in_GRj, out_FRk, out_FRdoublek);
201}
202
203int
204frvbf_model_fr450_u_fr_store (SIM_CPU *cpu, const IDESC *idesc,
205			      int unit_num, int referenced,
206			      INT in_GRi, INT in_GRj,
207			      INT in_FRk, INT in_FRdoublek)
208{
209  /* Modelling for this unit is the same as for fr400.  */
210  return frvbf_model_fr400_u_fr_load (cpu, idesc, unit_num, referenced,
211				      in_GRi, in_GRj, in_FRk, in_FRdoublek);
212}
213
214int
215frvbf_model_fr450_u_swap (SIM_CPU *cpu, const IDESC *idesc,
216			  int unit_num, int referenced,
217			  INT in_GRi, INT in_GRj, INT out_GRk)
218{
219  /* Modelling for this unit is the same as for fr500.  */
220  return frvbf_model_fr500_u_swap (cpu, idesc, unit_num, referenced,
221				   in_GRi, in_GRj, out_GRk);
222}
223
224int
225frvbf_model_fr450_u_fr2gr (SIM_CPU *cpu, const IDESC *idesc,
226			   int unit_num, int referenced,
227			   INT in_FRk, INT out_GRj)
228{
229  int cycles;
230
231  if (model_insn == FRV_INSN_MODEL_PASS_1)
232    {
233      /* Pass 1 is the same as for fr400.  */
234      return frvbf_model_fr500_u_fr2gr (cpu, idesc, unit_num, referenced,
235					in_FRk, out_GRj);
236    }
237
238  /* The latency of GRj is 1 cycle.  */
239  cycles = idesc->timing->units[unit_num].done;
240  update_GR_latency (cpu, out_GRj, cycles + 1);
241
242  return cycles;
243}
244
245int
246frvbf_model_fr450_u_spr2gr (SIM_CPU *cpu, const IDESC *idesc,
247			   int unit_num, int referenced,
248			   INT in_spr, INT out_GRj)
249{
250  /* Modelling for this unit is the same as for fr500.  */
251  return frvbf_model_fr500_u_spr2gr (cpu, idesc, unit_num, referenced,
252				     in_spr, out_GRj);
253}
254
255int
256frvbf_model_fr450_u_gr2fr (SIM_CPU *cpu, const IDESC *idesc,
257			   int unit_num, int referenced,
258			   INT in_GRj, INT out_FRk)
259{
260  /* Modelling for this unit is the same as for fr400.  */
261  return frvbf_model_fr400_u_gr2fr (cpu, idesc, unit_num, referenced,
262				    in_GRj, out_FRk);
263}
264
265int
266frvbf_model_fr450_u_gr2spr (SIM_CPU *cpu, const IDESC *idesc,
267			    int unit_num, int referenced,
268			    INT in_GRj, INT out_spr)
269{
270  /* Modelling for this unit is the same as for fr500.  */
271  return frvbf_model_fr500_u_gr2spr (cpu, idesc, unit_num, referenced,
272				     in_GRj, out_spr);
273}
274
275int
276frvbf_model_fr450_u_media_1 (SIM_CPU *cpu, const IDESC *idesc,
277			     int unit_num, int referenced,
278			     INT in_FRi, INT in_FRj,
279			     INT out_FRk)
280{
281  /* Modelling for this unit is the same as for fr400.  */
282  return frvbf_model_fr400_u_media_1 (cpu, idesc, unit_num, referenced,
283				      in_FRi, in_FRj, out_FRk);
284}
285
286int
287frvbf_model_fr450_u_media_1_quad (SIM_CPU *cpu, const IDESC *idesc,
288				  int unit_num, int referenced,
289				  INT in_FRi, INT in_FRj,
290				  INT out_FRk)
291{
292  /* Modelling for this unit is the same as for fr400.  */
293  return frvbf_model_fr400_u_media_1_quad (cpu, idesc, unit_num, referenced,
294					   in_FRi, in_FRj, out_FRk);
295}
296
297int
298frvbf_model_fr450_u_media_hilo (SIM_CPU *cpu, const IDESC *idesc,
299				int unit_num, int referenced,
300				INT out_FRkhi, INT out_FRklo)
301{
302  /* Modelling for this unit is the same as for fr400.  */
303  return frvbf_model_fr400_u_media_hilo (cpu, idesc, unit_num, referenced,
304					 out_FRkhi, out_FRklo);
305}
306
307int
308frvbf_model_fr450_u_media_2 (SIM_CPU *cpu, const IDESC *idesc,
309			     int unit_num, int referenced,
310			     INT in_FRi, INT in_FRj,
311			     INT out_ACC40Sk, INT out_ACC40Uk)
312{
313  /* Modelling for this unit is the same as for fr400.  */
314  return frvbf_model_fr400_u_media_2 (cpu, idesc, unit_num, referenced,
315				      in_FRi, in_FRj, out_ACC40Sk,
316				      out_ACC40Uk);
317}
318
319int
320frvbf_model_fr450_u_media_2_quad (SIM_CPU *cpu, const IDESC *idesc,
321				  int unit_num, int referenced,
322				  INT in_FRi, INT in_FRj,
323				  INT out_ACC40Sk, INT out_ACC40Uk)
324{
325  /* Modelling for this unit is the same as for fr400.  */
326  return frvbf_model_fr400_u_media_2_quad (cpu, idesc, unit_num, referenced,
327					   in_FRi, in_FRj, out_ACC40Sk,
328					   out_ACC40Uk);
329}
330
331int
332frvbf_model_fr450_u_media_2_acc (SIM_CPU *cpu, const IDESC *idesc,
333				 int unit_num, int referenced,
334				 INT in_ACC40Si, INT out_ACC40Sk)
335{
336  /* Modelling for this unit is the same as for fr400.  */
337  return frvbf_model_fr400_u_media_2_acc (cpu, idesc, unit_num, referenced,
338					  in_ACC40Si, out_ACC40Sk);
339}
340
341int
342frvbf_model_fr450_u_media_2_acc_dual (SIM_CPU *cpu, const IDESC *idesc,
343				      int unit_num, int referenced,
344				      INT in_ACC40Si, INT out_ACC40Sk)
345{
346  /* Modelling for this unit is the same as for fr400.  */
347  return frvbf_model_fr400_u_media_2_acc_dual (cpu, idesc, unit_num,
348					       referenced, in_ACC40Si,
349					       out_ACC40Sk);
350}
351
352int
353frvbf_model_fr450_u_media_2_add_sub (SIM_CPU *cpu, const IDESC *idesc,
354				     int unit_num, int referenced,
355				     INT in_ACC40Si, INT out_ACC40Sk)
356{
357  /* Modelling for this unit is the same as for fr400.  */
358  return frvbf_model_fr400_u_media_2_add_sub (cpu, idesc, unit_num,
359					      referenced, in_ACC40Si,
360					      out_ACC40Sk);
361}
362
363int
364frvbf_model_fr450_u_media_2_add_sub_dual (SIM_CPU *cpu, const IDESC *idesc,
365					  int unit_num, int referenced,
366					  INT in_ACC40Si, INT out_ACC40Sk)
367{
368  /* Modelling for this unit is the same as for fr400.  */
369  return frvbf_model_fr400_u_media_2_add_sub_dual (cpu, idesc, unit_num,
370						   referenced, in_ACC40Si,
371						   out_ACC40Sk);
372}
373
374int
375frvbf_model_fr450_u_media_3 (SIM_CPU *cpu, const IDESC *idesc,
376			     int unit_num, int referenced,
377			     INT in_FRi, INT in_FRj,
378			     INT out_FRk)
379{
380  /* Modelling is the same as media unit 1.  */
381  return frvbf_model_fr450_u_media_1 (cpu, idesc, unit_num, referenced,
382				      in_FRi, in_FRj, out_FRk);
383}
384
385int
386frvbf_model_fr450_u_media_3_dual (SIM_CPU *cpu, const IDESC *idesc,
387				  int unit_num, int referenced,
388				  INT in_FRi, INT out_FRk)
389{
390  /* Modelling for this unit is the same as for fr400.  */
391  return frvbf_model_fr400_u_media_3_dual (cpu, idesc, unit_num, referenced,
392					   in_FRi, out_FRk);
393}
394
395int
396frvbf_model_fr450_u_media_3_quad (SIM_CPU *cpu, const IDESC *idesc,
397				  int unit_num, int referenced,
398				  INT in_FRi, INT in_FRj,
399				  INT out_FRk)
400{
401  /* Modelling is the same as media unit 1.  */
402  return frvbf_model_fr450_u_media_1_quad (cpu, idesc, unit_num, referenced,
403					   in_FRi, in_FRj, out_FRk);
404}
405
406int
407frvbf_model_fr450_u_media_4 (SIM_CPU *cpu, const IDESC *idesc,
408			     int unit_num, int referenced,
409			     INT in_ACC40Si, INT in_FRj,
410			     INT out_ACC40Sk, INT out_FRk)
411{
412  /* Modelling for this unit is the same as for fr400.  */
413  return frvbf_model_fr400_u_media_4 (cpu, idesc, unit_num, referenced,
414				      in_ACC40Si, in_FRj,
415				      out_ACC40Sk, out_FRk);
416}
417
418int
419frvbf_model_fr450_u_media_4_accg (SIM_CPU *cpu, const IDESC *idesc,
420				  int unit_num, int referenced,
421				  INT in_ACCGi, INT in_FRinti,
422				  INT out_ACCGk, INT out_FRintk)
423{
424  /* Modelling is the same as media-4 unit except use accumulator guards
425     as input instead of accumulators.  */
426  return frvbf_model_fr450_u_media_4 (cpu, idesc, unit_num, referenced,
427				      in_ACCGi, in_FRinti,
428				      out_ACCGk, out_FRintk);
429}
430
431int
432frvbf_model_fr450_u_media_4_acc_dual (SIM_CPU *cpu, const IDESC *idesc,
433				      int unit_num, int referenced,
434				      INT in_ACC40Si, INT out_FRk)
435{
436  /* Modelling for this unit is the same as for fr400.  */
437  return frvbf_model_fr400_u_media_4_acc_dual (cpu, idesc, unit_num,
438					       referenced, in_ACC40Si,
439					       out_FRk);
440}
441
442int
443frvbf_model_fr450_u_media_4_mclracca (SIM_CPU *cpu, const IDESC *idesc,
444				      int unit_num, int referenced)
445{
446  int cycles;
447  int acc;
448  FRV_PROFILE_STATE *ps;
449
450  if (model_insn == FRV_INSN_MODEL_PASS_1)
451    return 0;
452
453  /* The preprocessing can execute right away.  */
454  cycles = idesc->timing->units[unit_num].done;
455
456  ps = CPU_PROFILE_STATE (cpu);
457
458  /* The post processing must wait for any pending ACC writes.  */
459  ps->post_wait = cycles;
460  for (acc = 0; acc < 4; acc++)
461    post_wait_for_ACC (cpu, acc);
462  for (acc = 8; acc < 12; acc++)
463    post_wait_for_ACC (cpu, acc);
464
465  for (acc = 0; acc < 4; acc++)
466    {
467      update_ACC_latency (cpu, acc, ps->post_wait);
468      update_ACC_ptime (cpu, acc, 2);
469    }
470  for (acc = 8; acc < 12; acc++)
471    {
472      update_ACC_latency (cpu, acc, ps->post_wait);
473      update_ACC_ptime (cpu, acc, 2);
474    }
475
476  return cycles;
477}
478
479int
480frvbf_model_fr450_u_media_6 (SIM_CPU *cpu, const IDESC *idesc,
481			     int unit_num, int referenced,
482			     INT in_FRi, INT out_FRk)
483{
484  /* Modelling for this unit is the same as for fr400.  */
485  return frvbf_model_fr400_u_media_6 (cpu, idesc, unit_num, referenced,
486				      in_FRi, out_FRk);
487}
488
489int
490frvbf_model_fr450_u_media_7 (SIM_CPU *cpu, const IDESC *idesc,
491			     int unit_num, int referenced,
492			     INT in_FRinti, INT in_FRintj,
493			     INT out_FCCk)
494{
495  /* Modelling for this unit is the same as for fr400.  */
496  return frvbf_model_fr400_u_media_7 (cpu, idesc, unit_num, referenced,
497				      in_FRinti, in_FRintj, out_FCCk);
498}
499
500int
501frvbf_model_fr450_u_media_dual_expand (SIM_CPU *cpu, const IDESC *idesc,
502				       int unit_num, int referenced,
503				       INT in_FRi,
504				       INT out_FRk)
505{
506  /* Modelling for this unit is the same as for fr400.  */
507  return frvbf_model_fr400_u_media_dual_expand (cpu, idesc, unit_num,
508						referenced, in_FRi, out_FRk);
509}
510
511int
512frvbf_model_fr450_u_media_dual_htob (SIM_CPU *cpu, const IDESC *idesc,
513				     int unit_num, int referenced,
514				     INT in_FRj,
515				     INT out_FRk)
516{
517  /* Modelling for this unit is the same as for fr400.  */
518  return frvbf_model_fr400_u_media_dual_htob (cpu, idesc, unit_num,
519					      referenced, in_FRj, out_FRk);
520}
521
522int
523frvbf_model_fr450_u_ici (SIM_CPU *cpu, const IDESC *idesc,
524			 int unit_num, int referenced,
525			 INT in_GRi, INT in_GRj)
526{
527  /* Modelling for this unit is the same as for fr500.  */
528  return frvbf_model_fr500_u_ici (cpu, idesc, unit_num, referenced,
529				  in_GRi, in_GRj);
530}
531
532int
533frvbf_model_fr450_u_dci (SIM_CPU *cpu, const IDESC *idesc,
534			 int unit_num, int referenced,
535			 INT in_GRi, INT in_GRj)
536{
537  /* Modelling for this unit is the same as for fr500.  */
538  return frvbf_model_fr500_u_dci (cpu, idesc, unit_num, referenced,
539				  in_GRi, in_GRj);
540}
541
542int
543frvbf_model_fr450_u_dcf (SIM_CPU *cpu, const IDESC *idesc,
544			 int unit_num, int referenced,
545			 INT in_GRi, INT in_GRj)
546{
547  /* Modelling for this unit is the same as for fr500.  */
548  return frvbf_model_fr500_u_dcf (cpu, idesc, unit_num, referenced,
549				  in_GRi, in_GRj);
550}
551
552int
553frvbf_model_fr450_u_icpl (SIM_CPU *cpu, const IDESC *idesc,
554			  int unit_num, int referenced,
555			  INT in_GRi, INT in_GRj)
556{
557  /* Modelling for this unit is the same as for fr500.  */
558  return frvbf_model_fr500_u_icpl (cpu, idesc, unit_num, referenced,
559				   in_GRi, in_GRj);
560}
561
562int
563frvbf_model_fr450_u_dcpl (SIM_CPU *cpu, const IDESC *idesc,
564			  int unit_num, int referenced,
565			  INT in_GRi, INT in_GRj)
566{
567  /* Modelling for this unit is the same as for fr500.  */
568  return frvbf_model_fr500_u_dcpl (cpu, idesc, unit_num, referenced,
569				   in_GRi, in_GRj);
570}
571
572int
573frvbf_model_fr450_u_icul (SIM_CPU *cpu, const IDESC *idesc,
574			  int unit_num, int referenced,
575			  INT in_GRi, INT in_GRj)
576{
577  /* Modelling for this unit is the same as for fr500.  */
578  return frvbf_model_fr500_u_icul (cpu, idesc, unit_num, referenced,
579				   in_GRi, in_GRj);
580}
581
582int
583frvbf_model_fr450_u_dcul (SIM_CPU *cpu, const IDESC *idesc,
584			  int unit_num, int referenced,
585			  INT in_GRi, INT in_GRj)
586{
587  /* Modelling for this unit is the same as for fr500.  */
588  return frvbf_model_fr500_u_dcul (cpu, idesc, unit_num, referenced,
589				   in_GRi, in_GRj);
590}
591
592int
593frvbf_model_fr450_u_barrier (SIM_CPU *cpu, const IDESC *idesc,
594			     int unit_num, int referenced)
595{
596  /* Modelling for this unit is the same as for fr500.  */
597  return frvbf_model_fr500_u_barrier (cpu, idesc, unit_num, referenced);
598}
599
600int
601frvbf_model_fr450_u_membar (SIM_CPU *cpu, const IDESC *idesc,
602			    int unit_num, int referenced)
603{
604  /* Modelling for this unit is the same as for fr500.  */
605  return frvbf_model_fr500_u_membar (cpu, idesc, unit_num, referenced);
606}
607
608#endif /* WITH_PROFILE_MODEL_P */
609