This commit was generated by cvs2svn to track changes on a CVS vendor
[binutils-gdb.git] / sim / m32r / sim-if.c
1 /* Main simulator entry points for the M32R.
2 Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18
19 #include "sim-main.h"
20 #include <signal.h>
21 #ifdef HAVE_STDLIB_H
22 #include <stdlib.h>
23 #endif
24 #include "libiberty.h"
25 #include "bfd.h"
26 #include "sim-core.h"
27 #include "targ-vals.h"
28
29 static SIM_RC alloc_cpu (SIM_DESC, struct _bfd *, char **);
30 static void free_state (SIM_DESC);
31 static void print_m32r_misc_cpu (SIM_CPU *cpu, int verbose);
32
33 /* Records simulator descriptor so utilities like m32r_dump_regs can be
34 called from gdb. */
35 SIM_DESC current_state;
36 \f
37 /* Scan the args and bfd to see what kind of cpus are in use and allocate
38 space for them. */
39
40 static SIM_RC
41 alloc_cpu (SIM_DESC sd, struct _bfd *abfd, char **argv)
42 {
43 /* Compute the size of the SIM_CPU struct.
44 For now its the max of all the possible sizes. */
45 int size = 0;
46 const MACH *mach;
47
48 for (mach = &machs[0]; MACH_NAME (mach) != NULL; ++mach)
49 {
50 int mach_size = IMP_PROPS_SIM_CPU_SIZE (MACH_IMP_PROPS (mach));
51 size = mach_size > size ? mach_size : size;
52 }
53 if (size == 0)
54 abort ();
55
56 /* `sizeof (SIM_CPU)' is the size of the generic part, and `size' is the
57 size of the cpu-specific part. */
58 STATE_CPU (sd, 0) = zalloc (sizeof (SIM_CPU) + size);
59
60 return SIM_RC_OK;
61 }
62
63 /* Cover function of sim_state_free to free the cpu buffers as well. */
64
65 static void
66 free_state (SIM_DESC sd)
67 {
68 if (STATE_CPU (sd, 0))
69 zfree (STATE_CPU (sd, 0));
70 sim_state_free (sd);
71 }
72
73 /* Create an instance of the simulator. */
74
75 SIM_DESC
76 sim_open (kind, callback, abfd, argv)
77 SIM_OPEN_KIND kind;
78 host_callback *callback;
79 struct _bfd *abfd;
80 char **argv;
81 {
82 SIM_DESC sd = sim_state_alloc (kind, callback);
83
84 /* The cpu data is kept in a separately allocated chunk of memory. */
85 if (alloc_cpu (sd, abfd, argv) != SIM_RC_OK)
86 {
87 free_state (sd);
88 return 0;
89 }
90
91 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
92 {
93 free_state (sd);
94 return 0;
95 }
96
97 #if 0 /* FIXME: 'twould be nice if we could do this */
98 /* These options override any module options.
99 Obviously ambiguity should be avoided, however the caller may wish to
100 augment the meaning of an option. */
101 if (extra_options != NULL)
102 sim_add_option_table (sd, extra_options);
103 #endif
104
105 /* Allocate core managed memory */
106 sim_do_commandf (sd, "memory region 0,0x%lx", M32R_DEFAULT_MEM_SIZE);
107
108 /* Allocate a handler for the MSPR register. */
109 sim_core_attach (sd, NULL,
110 0 /*level*/,
111 access_write,
112 0 /*space ???*/,
113 MSPR_ADDR, 1 /*nr_bytes*/, 0 /*modulo*/,
114 &m32r_mspr_device,
115 NULL /*buffer*/);
116
117 /* getopt will print the error message so we just have to exit if this fails.
118 FIXME: Hmmm... in the case of gdb we need getopt to call
119 print_filtered. */
120 if (sim_parse_args (sd, argv) != SIM_RC_OK)
121 {
122 sim_module_uninstall (sd);
123 free_state (sd);
124 return 0;
125 }
126
127 /* check for/establish the a reference program image */
128 if (sim_analyze_program (sd,
129 (STATE_PROG_ARGV (sd) != NULL
130 ? *STATE_PROG_ARGV (sd)
131 : NULL),
132 abfd) != SIM_RC_OK)
133 {
134 sim_module_uninstall (sd);
135 free_state (sd);
136 return 0;
137 }
138
139 /* Establish any remaining configuration options. */
140 if (sim_config (sd) != SIM_RC_OK)
141 {
142 sim_module_uninstall (sd);
143 free_state (sd);
144 return 0;
145 }
146
147 if (sim_post_argv_init (sd) != SIM_RC_OK)
148 {
149 sim_module_uninstall (sd);
150 free_state (sd);
151 return 0;
152 }
153
154 /* Initialize various cgen things not done by common framework. */
155 cgen_init (sd);
156
157 {
158 int i;
159
160 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
161 {
162 /* Only needed for profiling, but the structure member is small. */
163 memset (& CPU_M32R_MISC_PROFILE (STATE_CPU (sd, i)), 0,
164 sizeof (CPU_M32R_MISC_PROFILE (STATE_CPU (sd, i))));
165 /* Hook in callback for reporting these stats */
166 PROFILE_INFO_CPU_CALLBACK (CPU_PROFILE_DATA (STATE_CPU (sd, i)))
167 = print_m32r_misc_cpu;
168 }
169 }
170
171 /* Store in a global so things like sparc32_dump_regs can be invoked
172 from the gdb command line. */
173 current_state = sd;
174
175 return sd;
176 }
177
178 void
179 sim_close (sd, quitting)
180 SIM_DESC sd;
181 int quitting;
182 {
183 sim_module_uninstall (sd);
184 }
185 \f
186 SIM_RC
187 sim_create_inferior (sd, abfd, argv, envp)
188 SIM_DESC sd;
189 struct _bfd *abfd;
190 char **argv;
191 char **envp;
192 {
193 SIM_CPU *current_cpu = STATE_CPU (sd, 0);
194 SIM_ADDR addr;
195
196 if (abfd != NULL)
197 addr = bfd_get_start_address (abfd);
198 else
199 addr = 0;
200 h_pc_set (current_cpu, addr);
201
202 #if 0
203 STATE_ARGV (sd) = sim_copy_argv (argv);
204 STATE_ENVP (sd) = sim_copy_argv (envp);
205 #endif
206
207 return SIM_RC_OK;
208 }
209
210 int
211 sim_stop (SIM_DESC sd)
212 {
213 switch (STATE_ARCHITECTURE (sd)->mach)
214 {
215 case bfd_mach_m32r :
216 return m32r_engine_stop (sd);
217 /* start-sanitize-m32rx */
218 #ifdef HAVE_CPU_M32RX
219 case bfd_mach_m32rx :
220 return m32rx_engine_stop (sd);
221 #endif
222 /* end-sanitize-m32rx */
223 default :
224 abort ();
225 }
226 }
227
228 void
229 sim_resume (sd, step, siggnal)
230 SIM_DESC sd;
231 int step, siggnal;
232 {
233 switch (STATE_ARCHITECTURE (sd)->mach)
234 {
235 case bfd_mach_m32r :
236 m32r_engine_run (sd, step, siggnal);
237 break;
238 /* start-sanitize-m32rx */
239 #ifdef HAVE_CPU_M32RX
240 case bfd_mach_m32rx :
241 m32rx_engine_run (sd, step, siggnal);
242 break;
243 #endif
244 /* end-sanitize-m32rx */
245 default :
246 abort ();
247 }
248 }
249
250 /* PROFILE_CPU_CALLBACK */
251
252 static void
253 print_m32r_misc_cpu (SIM_CPU *cpu, int verbose)
254 {
255 SIM_DESC sd = CPU_STATE (cpu);
256 char buf[20];
257
258 if (CPU_PROFILE_FLAGS (cpu) [PROFILE_INSN_IDX])
259 {
260 sim_io_printf (sd, "Miscellaneous Statistics\n\n");
261 sim_io_printf (sd, " %-*s %s\n\n",
262 PROFILE_LABEL_WIDTH, "Fill nops:",
263 sim_add_commas (buf, sizeof (buf),
264 CPU_M32R_MISC_PROFILE (cpu).fillnop_count));
265 }
266 }
267
268 /* The contents of BUF are in target byte order. */
269
270 int
271 sim_fetch_register (sd, rn, buf, length)
272 SIM_DESC sd;
273 int rn;
274 unsigned char *buf;
275 int length;
276 {
277 switch (STATE_ARCHITECTURE (sd)->mach)
278 {
279 case bfd_mach_m32r :
280 m32r_fetch_register (sd, rn, buf);
281 break;
282 /* start-sanitize-m32rx */
283 #ifdef HAVE_CPU_M32RX
284 case bfd_mach_m32rx :
285 m32rx_fetch_register (sd, rn, buf);
286 break;
287 #endif
288 /* end-sanitize-m32rx */
289 default :
290 abort ();
291 }
292 return -1;
293 }
294
295 /* The contents of BUF are in target byte order. */
296
297 int
298 sim_store_register (sd, rn, buf, length)
299 SIM_DESC sd;
300 int rn;
301 unsigned char *buf;
302 int length;
303 {
304 switch (STATE_ARCHITECTURE (sd)->mach)
305 {
306 case bfd_mach_m32r :
307 m32r_store_register (sd, rn, buf);
308 break;
309 /* start-sanitize-m32rx */
310 #ifdef HAVE_CPU_M32RX
311 case bfd_mach_m32rx :
312 m32rx_store_register (sd, rn, buf);
313 break;
314 #endif
315 /* end-sanitize-m32rx */
316 default :
317 abort ();
318 }
319 return -1;
320 }
321
322 void
323 sim_do_command (sd, cmd)
324 SIM_DESC sd;
325 char *cmd;
326 {
327 if (sim_args_command (sd, cmd) != SIM_RC_OK)
328 sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
329 }
330 \f
331 /* The semantic code invokes this for illegal (unrecognized) instructions. */
332
333 void
334 sim_engine_illegal_insn (current_cpu, pc)
335 SIM_CPU *current_cpu;
336 PCADDR pc;
337 {
338 sim_engine_halt (CPU_STATE (current_cpu), current_cpu, NULL, pc,
339 sim_stopped, SIM_SIGILL);
340 }
341 \f
342 /* Utility fns to access registers, without knowing the current mach.
343 FIXME: Machine generate? */
344
345 USI
346 h_pc_get (SIM_CPU *current_cpu)
347 {
348 switch (STATE_ARCHITECTURE (CPU_STATE (current_cpu))->mach)
349 {
350 case bfd_mach_m32r :
351 return m32r_h_pc_get (current_cpu);
352 /* start-sanitize-m32rx */
353 #ifdef HAVE_CPU_M32RX
354 case bfd_mach_m32rx :
355 return m32rx_h_pc_get (current_cpu);
356 #endif
357 /* end-sanitize-m32rx */
358 default :
359 abort ();
360 }
361 }
362
363 void
364 h_pc_set (SIM_CPU *current_cpu, USI newval)
365 {
366 switch (STATE_ARCHITECTURE (CPU_STATE (current_cpu))->mach)
367 {
368 case bfd_mach_m32r :
369 m32r_h_pc_set (current_cpu, newval);
370 break;
371 /* start-sanitize-m32rx */
372 #ifdef HAVE_CPU_M32RX
373 case bfd_mach_m32rx :
374 m32rx_h_pc_set (current_cpu, newval);
375 break;
376 #endif
377 /* end-sanitize-m32rx */
378 default :
379 abort ();
380 }
381 }
382
383 SI
384 h_gr_get (SIM_CPU *current_cpu, UINT regno)
385 {
386 switch (STATE_ARCHITECTURE (CPU_STATE (current_cpu))->mach)
387 {
388 case bfd_mach_m32r :
389 return m32r_h_gr_get (current_cpu, regno);
390 /* start-sanitize-m32rx */
391 #ifdef HAVE_CPU_M32RX
392 case bfd_mach_m32rx :
393 return m32rx_h_gr_get (current_cpu, regno);
394 #endif
395 /* end-sanitize-m32rx */
396 default :
397 abort ();
398 }
399 }
400
401 void
402 h_gr_set (SIM_CPU *current_cpu, UINT regno, SI newval)
403 {
404 switch (STATE_ARCHITECTURE (CPU_STATE (current_cpu))->mach)
405 {
406 case bfd_mach_m32r :
407 m32r_h_gr_set (current_cpu, regno, newval);
408 break;
409 /* start-sanitize-m32rx */
410 #ifdef HAVE_CPU_M32RX
411 case bfd_mach_m32rx :
412 m32rx_h_gr_set (current_cpu, regno, newval);
413 break;
414 #endif
415 /* end-sanitize-m32rx */
416 default :
417 abort ();
418 }
419 }
420 \f
421 /* Read/write functions for system call interface. */
422
423 static int
424 syscall_read_mem (host_callback *cb, struct cb_syscall *sc,
425 unsigned long taddr, char *buf, int bytes)
426 {
427 SIM_DESC sd = (SIM_DESC) sc->p1;
428 SIM_CPU *cpu = (SIM_CPU *) sc->p2;
429
430 return sim_core_read_buffer (sd, cpu, sim_core_read_map, buf, taddr, bytes);
431 }
432
433 static int
434 syscall_write_mem (host_callback *cb, struct cb_syscall *sc,
435 unsigned long taddr, const char *buf, int bytes)
436 {
437 SIM_DESC sd = (SIM_DESC) sc->p1;
438 SIM_CPU *cpu = (SIM_CPU *) sc->p2;
439
440 return sim_core_write_buffer (sd, cpu, sim_core_write_map, buf, taddr, bytes);
441 }
442
443 /* Trap support. */
444
445 void
446 do_trap (SIM_CPU *current_cpu, int num)
447 {
448 SIM_DESC sd = CPU_STATE (current_cpu);
449 host_callback *cb = STATE_CALLBACK (sd);
450
451 switch (num)
452 {
453 case 0 :
454 /* Trap 0 is used for system calls. */
455 {
456 CB_SYSCALL s;
457
458 CB_SYSCALL_INIT (&s);
459 s.func = h_gr_get (current_cpu, 0);
460 s.arg1 = h_gr_get (current_cpu, 1);
461 s.arg2 = h_gr_get (current_cpu, 2);
462 s.arg3 = h_gr_get (current_cpu, 3);
463
464 if (s.func == TARGET_SYS_exit)
465 {
466 sim_engine_halt (sd, current_cpu, NULL, h_pc_get (current_cpu),
467 sim_exited, s.arg1);
468 }
469
470 s.p1 = (PTR) sd;
471 s.p2 = (PTR) current_cpu;
472 s.read_mem = syscall_read_mem;
473 s.write_mem = syscall_write_mem;
474 cb_syscall (STATE_CALLBACK (sd), &s);
475 h_gr_set (current_cpu, 2, s.errcode);
476 h_gr_set (current_cpu, 0, s.result);
477 h_gr_set (current_cpu, 1, s.result2);
478 break;
479 }
480
481 case 1: /* breakpoint trap */
482 sim_engine_halt (sd, current_cpu, NULL, NULL_CIA,
483 sim_stopped, SIM_SIGTRAP);
484 break;
485
486 default :
487 /* Unless environment operating, ignore other traps. */
488 break;
489 }
490 }