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