Regenerate frv-dis.c in order to fix a compile time warning.
[deliverable/binutils-gdb.git] / sim / cris / cris-tmpl.c
1 /* CRIS base simulator support code
2 Copyright (C) 2004, 2005 Free Software Foundation, Inc.
3 Contributed by Axis Communications.
4
5 This file is part of the GNU simulators.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 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
33 USI
34 MY (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
76 int
77 MY (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
87 int
88 MY (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
103 void
104 MY (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];
122 SIM_DESC sd = CPU_STATE (current_cpu);
123
124 cris_trace_printf (sd, current_cpu, "%lx ", (unsigned long) (CPU (h_pc)));
125
126 for (i = 0; i < 15; i++)
127 cris_trace_printf (sd, current_cpu, "%lx ",
128 (unsigned long) (XCONCAT3(crisv,BASENUM,
129 f_h_gr_get) (current_cpu,
130 i)));
131 flags[0] = GET_H_IBIT () != 0 ? 'I' : 'i';
132 flags[1] = GET_H_XBIT () != 0 ? 'X' : 'x';
133 flags[2] = GET_H_NBIT () != 0 ? 'N' : 'n';
134 flags[3] = GET_H_ZBIT () != 0 ? 'Z' : 'z';
135 flags[4] = GET_H_VBIT () != 0 ? 'V' : 'v';
136 flags[5] = GET_H_CBIT () != 0 ? 'C' : 'c';
137 flags[6] = 0;
138
139 /* Emit ACR after flags and cycle count for this insn. */
140 if (BASENUM == 32)
141 cris_trace_printf (sd, current_cpu, "%s %d %lx\n", flags,
142 (int)
143 ((CPU_CRIS_MISC_PROFILE (current_cpu)
144 ->basic_cycle_count
145 - CPU_CRIS_PREV_MISC_PROFILE (current_cpu)
146 ->basic_cycle_count)
147 + (CPU_CRIS_MISC_PROFILE (current_cpu)
148 ->unaligned_mem_dword_count
149 - CPU_CRIS_PREV_MISC_PROFILE (current_cpu)
150 ->unaligned_mem_dword_count)),
151 (unsigned long) (XCONCAT3(crisv,BASENUM,
152 f_h_gr_get) (current_cpu,
153 15)));
154 else
155 cris_trace_printf (sd, current_cpu, "%s %d\n", flags,
156 (int)
157 ((CPU_CRIS_MISC_PROFILE (current_cpu)
158 ->basic_cycle_count
159 - CPU_CRIS_PREV_MISC_PROFILE (current_cpu)
160 ->basic_cycle_count)
161 + (CPU_CRIS_MISC_PROFILE (current_cpu)
162 ->unaligned_mem_dword_count
163 - CPU_CRIS_PREV_MISC_PROFILE (current_cpu)
164 ->unaligned_mem_dword_count)));
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
176 void
177 MY (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;
185 }
186
187 /* Initialize cycle counting for an insn.
188 FIRST_P is non-zero if this is the first insn in a set of parallel
189 insns. */
190
191 void
192 MY (f_model_init_insn_cycles) (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
193 int first_p ATTRIBUTE_UNUSED)
194 {
195 abort ();
196 }
197
198 /* Record the cycles computed for an insn.
199 LAST_P is non-zero if this is the last insn in a set of parallel insns,
200 and we update the total cycle count. */
201
202 void
203 MY (f_model_update_insn_cycles) (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
204 int last_p ATTRIBUTE_UNUSED)
205 {
206 abort ();
207 }
208
209 #if 0
210 void
211 MY (f_model_record_cycles) (SIM_CPU *current_cpu, unsigned long cycles)
212 {
213 abort ();
214 }
215
216 void
217 MY (f_model_mark_get_h_gr) (SIM_CPU *current_cpu, ARGBUF *abuf)
218 {
219 abort ();
220 }
221
222 void
223 MY (f_model_mark_set_h_gr) (SIM_CPU *current_cpu, ARGBUF *abuf)
224 {
225 abort ();
226 }
227 #endif
228 \f
229 /* Create the context for a thread. */
230
231 void *
232 MY (make_thread_cpu_data) (SIM_CPU *current_cpu, void *context)
233 {
234 void *info = xmalloc (current_cpu->thread_cpu_data_size);
235
236 if (context != NULL)
237 memcpy (info,
238 context,
239 current_cpu->thread_cpu_data_size);
240 else
241 memset (info, 0, current_cpu->thread_cpu_data_size),abort();
242 return info;
243 }
244
245 /* Hook function for per-cpu simulator initialization. */
246
247 void
248 MY (f_specific_init) (SIM_CPU *current_cpu)
249 {
250 current_cpu->make_thread_cpu_data = MY (make_thread_cpu_data);
251 current_cpu->thread_cpu_data_size = sizeof (current_cpu->cpu_data);
252 }
253 \f
254 /* Model function for arbitrary single stall cycles. */
255
256 int
257 MY (XCONCAT3 (f_model_crisv,BASENUM,
258 _u_stall)) (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
259 const IDESC *idesc,
260 int unit_num,
261 int referenced ATTRIBUTE_UNUSED)
262 {
263 return idesc->timing->units[unit_num].done;
264 }
265
266 #ifndef SPECIFIC_U_SKIP4_FN
267
268 /* Model function for u-skip4 unit. */
269
270 int
271 MY (XCONCAT3 (f_model_crisv,BASENUM,
272 _u_skip4)) (SIM_CPU *current_cpu,
273 const IDESC *idesc,
274 int unit_num,
275 int referenced ATTRIBUTE_UNUSED)
276 {
277 /* Handle PC not being updated with pbb. FIXME: What if not pbb? */
278 CPU (h_pc) += 4;
279 return idesc->timing->units[unit_num].done;
280 }
281
282 #endif
283
284 #ifndef SPECIFIC_U_EXEC_FN
285
286 /* Model function for u-exec unit. */
287
288 int
289 MY (XCONCAT3 (f_model_crisv,BASENUM,
290 _u_exec)) (SIM_CPU *current_cpu,
291 const IDESC *idesc,
292 int unit_num, int referenced ATTRIBUTE_UNUSED)
293 {
294 /* Handle PC not being updated with pbb. FIXME: What if not pbb? */
295 CPU (h_pc) += 2;
296 return idesc->timing->units[unit_num].done;
297 }
298 #endif
299
300 #ifndef SPECIFIC_U_MEM_FN
301
302 /* Model function for u-mem unit. */
303
304 int
305 MY (XCONCAT3 (f_model_crisv,BASENUM,
306 _u_mem)) (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
307 const IDESC *idesc,
308 int unit_num,
309 int referenced ATTRIBUTE_UNUSED)
310 {
311 return idesc->timing->units[unit_num].done;
312 }
313 #endif
314
315 #ifndef SPECIFIC_U_CONST16_FN
316
317 /* Model function for u-const16 unit. */
318
319 int
320 MY (XCONCAT3 (f_model_crisv,BASENUM,
321 _u_const16)) (SIM_CPU *current_cpu,
322 const IDESC *idesc,
323 int unit_num,
324 int referenced ATTRIBUTE_UNUSED)
325 {
326 CPU (h_pc) += 2;
327 return idesc->timing->units[unit_num].done;
328 }
329 #endif /* SPECIFIC_U_CONST16_FN */
330
331 #ifndef SPECIFIC_U_CONST32_FN
332
333 /* This will be incorrect for early models, where a dword always take
334 two cycles. */
335 #define CRIS_MODEL_MASK_PC_STALL 2
336
337 /* Model function for u-const32 unit. */
338
339 int
340 MY (XCONCAT3 (f_model_crisv,BASENUM,
341 _u_const32)) (SIM_CPU *current_cpu,
342 const IDESC *idesc,
343 int unit_num,
344 int referenced ATTRIBUTE_UNUSED)
345 {
346 int unaligned_extra
347 = (((CPU (h_pc) + 2) & CRIS_MODEL_MASK_PC_STALL)
348 == CRIS_MODEL_MASK_PC_STALL);
349
350 /* Handle PC not being updated with pbb. FIXME: What if not pbb? */
351 CPU_CRIS_MISC_PROFILE (current_cpu)->unaligned_mem_dword_count
352 += unaligned_extra;
353
354 CPU (h_pc) += 4;
355 return idesc->timing->units[unit_num].done;
356 }
357 #endif /* SPECIFIC_U_CONST32_FN */
358
359 #ifndef SPECIFIC_U_MOVEM_FN
360
361 /* Model function for u-movem unit. */
362
363 int
364 MY (XCONCAT3 (f_model_crisv,BASENUM,
365 _u_movem)) (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
366 const IDESC *idesc ATTRIBUTE_UNUSED,
367 int unit_num ATTRIBUTE_UNUSED,
368 int referenced ATTRIBUTE_UNUSED,
369 INT limreg)
370 {
371 /* FIXME: Add cycles for misalignment. */
372
373 if (limreg == -1)
374 abort ();
375
376 /* We don't record movem move cycles in movemsrc_stall_count since
377 those cycles have historically been handled as ordinary cycles. */
378 return limreg + 1;
379 }
380 #endif /* SPECIFIC_U_MOVEM_FN */
381
382 #endif /* WITH_PROFILE_MODEL_P */
This page took 0.05575 seconds and 4 git commands to generate.