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