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