sim: callback: convert time interface to 64-bit
[deliverable/binutils-gdb.git] / sim / cris / cris-tmpl.c
CommitLineData
f6bcefef 1/* CRIS base simulator support code
3666a048 2 Copyright (C) 2004-2021 Free Software Foundation, Inc.
f6bcefef
HPN
3 Contributed by Axis Communications.
4
5This file is part of the GNU simulators.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
4744ac1b
JB
9the Free Software Foundation; either version 3 of the License, or
10(at your option) any later version.
f6bcefef
HPN
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
4744ac1b
JB
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>. */
f6bcefef
HPN
19
20/* The infrastructure is based on that of i960.c. */
21
22#define WANT_CPU
23
24#include "sim-main.h"
25#include "cgen-mem.h"
26#include "cgen-ops.h"
27
32a046ab
TT
28#include <stdlib.h>
29
f6bcefef
HPN
30#define MY(f) XCONCAT3(crisv,BASENUM,f)
31
32/* Dispatcher for break insn. */
33
34USI
35MY (f_break_handler) (SIM_CPU *cpu, USI breaknum, USI pc)
36{
37 SIM_DESC sd = CPU_STATE (cpu);
38 USI ret = pc + 2;
39
40 MY (f_h_pc_set) (cpu, ret);
41
42 /* FIXME: Error out if IBR or ERP set. */
43 switch (breaknum)
44 {
45 case 13:
46 MY (f_h_gr_set (cpu, 10,
47 cris_break_13_handler (cpu,
48 MY (f_h_gr_get (cpu, 9)),
49 MY (f_h_gr_get (cpu, 10)),
50 MY (f_h_gr_get (cpu, 11)),
51 MY (f_h_gr_get (cpu, 12)),
52 MY (f_h_gr_get (cpu, 13)),
53 MY (f_h_sr_get (cpu, 7)),
54 MY (f_h_sr_get (cpu, 11)),
55 pc)));
56 break;
57
58 case 14:
59 sim_io_printf (sd, "%x\n", MY (f_h_gr_get (cpu, 3)));
60 break;
61
62 case 15:
63 /* Re-use the Linux exit call. */
64 cris_break_13_handler (cpu, /* TARGET_SYS_exit */ 1, 0,
65 0, 0, 0, 0, 0, pc);
66
67 default:
68 abort ();
69 }
70
71 return MY (f_h_pc_get) (cpu);
72}
73
74/* Accessor function for simulator internal use.
75 Note the contents of BUF are in target byte order. */
76
77int
78MY (f_fetch_register) (SIM_CPU *current_cpu, int rn,
79 unsigned char *buf, int len ATTRIBUTE_UNUSED)
80{
81 SETTSI (buf, XCONCAT3(crisv,BASENUM,f_h_gr_get) (current_cpu, rn));
82 return -1;
83}
84
85/* Accessor function for simulator internal use.
86 Note the contents of BUF are in target byte order. */
87
88int
89MY (f_store_register) (SIM_CPU *current_cpu, int rn,
90 unsigned char *buf, int len ATTRIBUTE_UNUSED)
91{
92 XCONCAT3(crisv,BASENUM,f_h_gr_set) (current_cpu, rn, GETTSI (buf));
93 return -1;
94}
95\f
96#if WITH_PROFILE_MODEL_P
97
98/* FIXME: Some of these should be inline or macros. Later. */
99
100/* Initialize cycle counting for an insn.
101 FIRST_P is non-zero if this is the first insn in a set of parallel
102 insns. */
103
104void
105MY (f_model_insn_before) (SIM_CPU *current_cpu, int first_p ATTRIBUTE_UNUSED)
106{
107 /* To give the impression that we actually know what PC is, we have to
108 dump register contents *before* the *next* insn, not after the
109 *previous* insn. Uhh... */
110
111 /* FIXME: Move this to separate, overridable function. */
112 if ((CPU_CRIS_MISC_PROFILE (current_cpu)->flags
113 & FLAG_CRIS_MISC_PROFILE_XSIM_TRACE)
114#ifdef GET_H_INSN_PREFIXED_P
115 /* For versions with prefixed insns, trace the combination as
116 one insn. */
117 && !GET_H_INSN_PREFIXED_P ()
118#endif
119 && 1)
120 {
121 int i;
122 char flags[7];
4fc9958a
HPN
123 unsigned64 cycle_count;
124
f6bcefef
HPN
125 SIM_DESC sd = CPU_STATE (current_cpu);
126
ae81c235
HPN
127 cris_trace_printf (sd, current_cpu, "%lx ",
128 0xffffffffUL & (unsigned long) (CPU (h_pc)));
f6bcefef
HPN
129
130 for (i = 0; i < 15; i++)
131 cris_trace_printf (sd, current_cpu, "%lx ",
ae81c235
HPN
132 0xffffffffUL
133 & (unsigned long) (XCONCAT3(crisv,BASENUM,
134 f_h_gr_get) (current_cpu,
135 i)));
f6bcefef
HPN
136 flags[0] = GET_H_IBIT () != 0 ? 'I' : 'i';
137 flags[1] = GET_H_XBIT () != 0 ? 'X' : 'x';
138 flags[2] = GET_H_NBIT () != 0 ? 'N' : 'n';
139 flags[3] = GET_H_ZBIT () != 0 ? 'Z' : 'z';
140 flags[4] = GET_H_VBIT () != 0 ? 'V' : 'v';
141 flags[5] = GET_H_CBIT () != 0 ? 'C' : 'c';
142 flags[6] = 0;
143
4fc9958a
HPN
144 /* For anything else than basic tracing we'd add stall cycles for
145 e.g. unaligned accesses. FIXME: add --cris-trace=x options to
146 match --cris-cycles=x. */
147 cycle_count
148 = (CPU_CRIS_MISC_PROFILE (current_cpu)->basic_cycle_count
149 - CPU_CRIS_PREV_MISC_PROFILE (current_cpu)->basic_cycle_count);
150
f6bcefef
HPN
151 /* Emit ACR after flags and cycle count for this insn. */
152 if (BASENUM == 32)
153 cris_trace_printf (sd, current_cpu, "%s %d %lx\n", flags,
4fc9958a 154 (int) cycle_count,
ae81c235
HPN
155 0xffffffffUL
156 & (unsigned long) (XCONCAT3(crisv,BASENUM,
157 f_h_gr_get) (current_cpu,
158 15)));
f6bcefef
HPN
159 else
160 cris_trace_printf (sd, current_cpu, "%s %d\n", flags,
4fc9958a 161 (int) cycle_count);
f6bcefef
HPN
162
163 CPU_CRIS_PREV_MISC_PROFILE (current_cpu)[0]
164 = CPU_CRIS_MISC_PROFILE (current_cpu)[0];
165 }
166}
167
168/* Record the cycles computed for an insn.
169 LAST_P is non-zero if this is the last insn in a set of parallel insns,
170 and we update the total cycle count.
171 CYCLES is the cycle count of the insn. */
172
173void
174MY (f_model_insn_after) (SIM_CPU *current_cpu, int last_p ATTRIBUTE_UNUSED,
175 int cycles)
176{
177 PROFILE_DATA *p = CPU_PROFILE_DATA (current_cpu);
178
179 PROFILE_MODEL_TOTAL_CYCLES (p) += cycles;
180 CPU_CRIS_MISC_PROFILE (current_cpu)->basic_cycle_count += cycles;
181 PROFILE_MODEL_CUR_INSN_CYCLES (p) = cycles;
aad3b3cb
HPN
182
183#if WITH_HW
184 /* For some reason, we don't get to the sim_events_tick call in
185 cgen-run.c:engine_run_1. Besides, more than one cycle has
186 passed, so we want sim_events_tickn anyway. The "events we want
187 to process" is usually to initiate an interrupt, but might also
188 be other events. We can't do the former until the main loop is
189 at point where it accepts changing the PC without internal
190 inconsistency, so just set a flag and wait. */
191 if (sim_events_tickn (CPU_STATE (current_cpu), cycles))
192 STATE_EVENTS (CPU_STATE (current_cpu))->work_pending = 1;
193#endif
f6bcefef
HPN
194}
195
196/* Initialize cycle counting for an insn.
197 FIRST_P is non-zero if this is the first insn in a set of parallel
198 insns. */
199
200void
201MY (f_model_init_insn_cycles) (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
202 int first_p ATTRIBUTE_UNUSED)
203{
204 abort ();
205}
206
207/* Record the cycles computed for an insn.
208 LAST_P is non-zero if this is the last insn in a set of parallel insns,
209 and we update the total cycle count. */
210
211void
212MY (f_model_update_insn_cycles) (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
213 int last_p ATTRIBUTE_UNUSED)
214{
215 abort ();
216}
217
218#if 0
219void
220MY (f_model_record_cycles) (SIM_CPU *current_cpu, unsigned long cycles)
221{
222 abort ();
223}
224
225void
226MY (f_model_mark_get_h_gr) (SIM_CPU *current_cpu, ARGBUF *abuf)
227{
228 abort ();
229}
230
231void
232MY (f_model_mark_set_h_gr) (SIM_CPU *current_cpu, ARGBUF *abuf)
233{
234 abort ();
235}
236#endif
237\f
ddf2c972
HPN
238/* Set the thread register contents. */
239
240void
241MY (set_target_thread_data) (SIM_CPU *current_cpu, USI val)
242{
243 (CPU (XCONCAT2 (h_sr_v, BASENUM) [CRIS_TLS_REGISTER])) = val;
244}
245
f6bcefef
HPN
246/* Create the context for a thread. */
247
248void *
249MY (make_thread_cpu_data) (SIM_CPU *current_cpu, void *context)
250{
251 void *info = xmalloc (current_cpu->thread_cpu_data_size);
252
253 if (context != NULL)
254 memcpy (info,
255 context,
256 current_cpu->thread_cpu_data_size);
257 else
258 memset (info, 0, current_cpu->thread_cpu_data_size),abort();
259 return info;
260}
261
262/* Hook function for per-cpu simulator initialization. */
263
264void
265MY (f_specific_init) (SIM_CPU *current_cpu)
266{
267 current_cpu->make_thread_cpu_data = MY (make_thread_cpu_data);
268 current_cpu->thread_cpu_data_size = sizeof (current_cpu->cpu_data);
ddf2c972 269 current_cpu->set_target_thread_data = MY (set_target_thread_data);
aad3b3cb
HPN
270#if WITH_HW
271 current_cpu->deliver_interrupt = MY (deliver_interrupt);
272#endif
f6bcefef
HPN
273}
274\f
275/* Model function for arbitrary single stall cycles. */
276
277int
278MY (XCONCAT3 (f_model_crisv,BASENUM,
279 _u_stall)) (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
280 const IDESC *idesc,
281 int unit_num,
282 int referenced ATTRIBUTE_UNUSED)
283{
284 return idesc->timing->units[unit_num].done;
285}
286
287#ifndef SPECIFIC_U_SKIP4_FN
288
289/* Model function for u-skip4 unit. */
290
291int
292MY (XCONCAT3 (f_model_crisv,BASENUM,
293 _u_skip4)) (SIM_CPU *current_cpu,
294 const IDESC *idesc,
295 int unit_num,
296 int referenced ATTRIBUTE_UNUSED)
297{
298 /* Handle PC not being updated with pbb. FIXME: What if not pbb? */
299 CPU (h_pc) += 4;
300 return idesc->timing->units[unit_num].done;
301}
302
303#endif
304
305#ifndef SPECIFIC_U_EXEC_FN
306
307/* Model function for u-exec unit. */
308
309int
310MY (XCONCAT3 (f_model_crisv,BASENUM,
311 _u_exec)) (SIM_CPU *current_cpu,
312 const IDESC *idesc,
313 int unit_num, int referenced ATTRIBUTE_UNUSED)
314{
315 /* Handle PC not being updated with pbb. FIXME: What if not pbb? */
316 CPU (h_pc) += 2;
317 return idesc->timing->units[unit_num].done;
318}
319#endif
320
321#ifndef SPECIFIC_U_MEM_FN
322
323/* Model function for u-mem unit. */
324
325int
326MY (XCONCAT3 (f_model_crisv,BASENUM,
327 _u_mem)) (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
328 const IDESC *idesc,
329 int unit_num,
330 int referenced ATTRIBUTE_UNUSED)
331{
332 return idesc->timing->units[unit_num].done;
333}
334#endif
335
336#ifndef SPECIFIC_U_CONST16_FN
337
338/* Model function for u-const16 unit. */
339
340int
341MY (XCONCAT3 (f_model_crisv,BASENUM,
342 _u_const16)) (SIM_CPU *current_cpu,
343 const IDESC *idesc,
344 int unit_num,
345 int referenced ATTRIBUTE_UNUSED)
346{
347 CPU (h_pc) += 2;
348 return idesc->timing->units[unit_num].done;
349}
350#endif /* SPECIFIC_U_CONST16_FN */
351
352#ifndef SPECIFIC_U_CONST32_FN
353
354/* This will be incorrect for early models, where a dword always take
355 two cycles. */
356#define CRIS_MODEL_MASK_PC_STALL 2
357
358/* Model function for u-const32 unit. */
359
360int
361MY (XCONCAT3 (f_model_crisv,BASENUM,
362 _u_const32)) (SIM_CPU *current_cpu,
363 const IDESC *idesc,
364 int unit_num,
365 int referenced ATTRIBUTE_UNUSED)
366{
367 int unaligned_extra
368 = (((CPU (h_pc) + 2) & CRIS_MODEL_MASK_PC_STALL)
369 == CRIS_MODEL_MASK_PC_STALL);
370
371 /* Handle PC not being updated with pbb. FIXME: What if not pbb? */
372 CPU_CRIS_MISC_PROFILE (current_cpu)->unaligned_mem_dword_count
373 += unaligned_extra;
374
375 CPU (h_pc) += 4;
376 return idesc->timing->units[unit_num].done;
377}
378#endif /* SPECIFIC_U_CONST32_FN */
379
380#ifndef SPECIFIC_U_MOVEM_FN
381
382/* Model function for u-movem unit. */
383
384int
385MY (XCONCAT3 (f_model_crisv,BASENUM,
386 _u_movem)) (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
387 const IDESC *idesc ATTRIBUTE_UNUSED,
388 int unit_num ATTRIBUTE_UNUSED,
389 int referenced ATTRIBUTE_UNUSED,
390 INT limreg)
391{
392 /* FIXME: Add cycles for misalignment. */
393
394 if (limreg == -1)
395 abort ();
396
397 /* We don't record movem move cycles in movemsrc_stall_count since
398 those cycles have historically been handled as ordinary cycles. */
399 return limreg + 1;
400}
401#endif /* SPECIFIC_U_MOVEM_FN */
402
403#endif /* WITH_PROFILE_MODEL_P */
This page took 0.735771 seconds and 4 git commands to generate.