* sim/cris/c/time2.c: New test.
[deliverable/binutils-gdb.git] / sim / cris / cris-tmpl.c
CommitLineData
f6bcefef 1/* CRIS base simulator support code
8d516ebc 2 Copyright (C) 2004, 2005, 2006 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
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
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
17You should have received a copy of the GNU General Public License along
18with this program; if not, write to the Free Software Foundation, Inc.,
1959 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
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;
181}
182
183/* Initialize cycle counting for an insn.
184 FIRST_P is non-zero if this is the first insn in a set of parallel
185 insns. */
186
187void
188MY (f_model_init_insn_cycles) (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
189 int first_p ATTRIBUTE_UNUSED)
190{
191 abort ();
192}
193
194/* Record the cycles computed for an insn.
195 LAST_P is non-zero if this is the last insn in a set of parallel insns,
196 and we update the total cycle count. */
197
198void
199MY (f_model_update_insn_cycles) (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
200 int last_p ATTRIBUTE_UNUSED)
201{
202 abort ();
203}
204
205#if 0
206void
207MY (f_model_record_cycles) (SIM_CPU *current_cpu, unsigned long cycles)
208{
209 abort ();
210}
211
212void
213MY (f_model_mark_get_h_gr) (SIM_CPU *current_cpu, ARGBUF *abuf)
214{
215 abort ();
216}
217
218void
219MY (f_model_mark_set_h_gr) (SIM_CPU *current_cpu, ARGBUF *abuf)
220{
221 abort ();
222}
223#endif
224\f
225/* Create the context for a thread. */
226
227void *
228MY (make_thread_cpu_data) (SIM_CPU *current_cpu, void *context)
229{
230 void *info = xmalloc (current_cpu->thread_cpu_data_size);
231
232 if (context != NULL)
233 memcpy (info,
234 context,
235 current_cpu->thread_cpu_data_size);
236 else
237 memset (info, 0, current_cpu->thread_cpu_data_size),abort();
238 return info;
239}
240
241/* Hook function for per-cpu simulator initialization. */
242
243void
244MY (f_specific_init) (SIM_CPU *current_cpu)
245{
246 current_cpu->make_thread_cpu_data = MY (make_thread_cpu_data);
247 current_cpu->thread_cpu_data_size = sizeof (current_cpu->cpu_data);
248}
249\f
250/* Model function for arbitrary single stall cycles. */
251
252int
253MY (XCONCAT3 (f_model_crisv,BASENUM,
254 _u_stall)) (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
255 const IDESC *idesc,
256 int unit_num,
257 int referenced ATTRIBUTE_UNUSED)
258{
259 return idesc->timing->units[unit_num].done;
260}
261
262#ifndef SPECIFIC_U_SKIP4_FN
263
264/* Model function for u-skip4 unit. */
265
266int
267MY (XCONCAT3 (f_model_crisv,BASENUM,
268 _u_skip4)) (SIM_CPU *current_cpu,
269 const IDESC *idesc,
270 int unit_num,
271 int referenced ATTRIBUTE_UNUSED)
272{
273 /* Handle PC not being updated with pbb. FIXME: What if not pbb? */
274 CPU (h_pc) += 4;
275 return idesc->timing->units[unit_num].done;
276}
277
278#endif
279
280#ifndef SPECIFIC_U_EXEC_FN
281
282/* Model function for u-exec unit. */
283
284int
285MY (XCONCAT3 (f_model_crisv,BASENUM,
286 _u_exec)) (SIM_CPU *current_cpu,
287 const IDESC *idesc,
288 int unit_num, int referenced ATTRIBUTE_UNUSED)
289{
290 /* Handle PC not being updated with pbb. FIXME: What if not pbb? */
291 CPU (h_pc) += 2;
292 return idesc->timing->units[unit_num].done;
293}
294#endif
295
296#ifndef SPECIFIC_U_MEM_FN
297
298/* Model function for u-mem unit. */
299
300int
301MY (XCONCAT3 (f_model_crisv,BASENUM,
302 _u_mem)) (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
303 const IDESC *idesc,
304 int unit_num,
305 int referenced ATTRIBUTE_UNUSED)
306{
307 return idesc->timing->units[unit_num].done;
308}
309#endif
310
311#ifndef SPECIFIC_U_CONST16_FN
312
313/* Model function for u-const16 unit. */
314
315int
316MY (XCONCAT3 (f_model_crisv,BASENUM,
317 _u_const16)) (SIM_CPU *current_cpu,
318 const IDESC *idesc,
319 int unit_num,
320 int referenced ATTRIBUTE_UNUSED)
321{
322 CPU (h_pc) += 2;
323 return idesc->timing->units[unit_num].done;
324}
325#endif /* SPECIFIC_U_CONST16_FN */
326
327#ifndef SPECIFIC_U_CONST32_FN
328
329/* This will be incorrect for early models, where a dword always take
330 two cycles. */
331#define CRIS_MODEL_MASK_PC_STALL 2
332
333/* Model function for u-const32 unit. */
334
335int
336MY (XCONCAT3 (f_model_crisv,BASENUM,
337 _u_const32)) (SIM_CPU *current_cpu,
338 const IDESC *idesc,
339 int unit_num,
340 int referenced ATTRIBUTE_UNUSED)
341{
342 int unaligned_extra
343 = (((CPU (h_pc) + 2) & CRIS_MODEL_MASK_PC_STALL)
344 == CRIS_MODEL_MASK_PC_STALL);
345
346 /* Handle PC not being updated with pbb. FIXME: What if not pbb? */
347 CPU_CRIS_MISC_PROFILE (current_cpu)->unaligned_mem_dword_count
348 += unaligned_extra;
349
350 CPU (h_pc) += 4;
351 return idesc->timing->units[unit_num].done;
352}
353#endif /* SPECIFIC_U_CONST32_FN */
354
355#ifndef SPECIFIC_U_MOVEM_FN
356
357/* Model function for u-movem unit. */
358
359int
360MY (XCONCAT3 (f_model_crisv,BASENUM,
361 _u_movem)) (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
362 const IDESC *idesc ATTRIBUTE_UNUSED,
363 int unit_num ATTRIBUTE_UNUSED,
364 int referenced ATTRIBUTE_UNUSED,
365 INT limreg)
366{
367 /* FIXME: Add cycles for misalignment. */
368
369 if (limreg == -1)
370 abort ();
371
372 /* We don't record movem move cycles in movemsrc_stall_count since
373 those cycles have historically been handled as ordinary cycles. */
374 return limreg + 1;
375}
376#endif /* SPECIFIC_U_MOVEM_FN */
377
378#endif /* WITH_PROFILE_MODEL_P */
This page took 0.070596 seconds and 4 git commands to generate.