1 /* Main simulator entry points for the M32R.
2 Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
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)
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.
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. */
24 #include "libiberty.h"
27 #include "targ-vals.h"
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
);
33 /* Records simulator descriptor so utilities like m32r_dump_regs can be
35 SIM_DESC current_state
;
37 /* Scan the args and bfd to see what kind of cpus are in use and allocate
41 alloc_cpu (SIM_DESC sd
, struct _bfd
*abfd
, char **argv
)
43 /* Compute the size of the SIM_CPU struct.
44 For now its the max of all the possible sizes. */
48 for (mach
= &machs
[0]; MACH_NAME (mach
) != NULL
; ++mach
)
50 int mach_size
= IMP_PROPS_SIM_CPU_SIZE (MACH_IMP_PROPS (mach
));
51 size
= mach_size
> size
? mach_size
: size
;
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
);
63 /* Cover function of sim_state_free to free the cpu buffers as well. */
66 free_state (SIM_DESC sd
)
68 if (STATE_CPU (sd
, 0))
69 zfree (STATE_CPU (sd
, 0));
73 /* Create an instance of the simulator. */
76 sim_open (kind
, callback
, abfd
, argv
)
78 host_callback
*callback
;
82 SIM_DESC sd
= sim_state_alloc (kind
, callback
);
84 /* The cpu data is kept in a separately allocated chunk of memory. */
85 if (alloc_cpu (sd
, abfd
, argv
) != SIM_RC_OK
)
91 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
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
);
105 /* Allocate core managed memory */
106 sim_do_commandf (sd
, "memory region 0,0x%lx", M32R_DEFAULT_MEM_SIZE
);
108 /* Allocate a handler for the MSPR register. */
109 sim_core_attach (sd
, NULL
,
113 MSPR_ADDR
, 1 /*nr_bytes*/, 0 /*modulo*/,
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
120 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
122 sim_module_uninstall (sd
);
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
)
134 sim_module_uninstall (sd
);
139 /* Establish any remaining configuration options. */
140 if (sim_config (sd
) != SIM_RC_OK
)
142 sim_module_uninstall (sd
);
147 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
149 sim_module_uninstall (sd
);
154 /* Initialize various cgen things not done by common framework. */
160 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
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
;
171 /* Store in a global so things like sparc32_dump_regs can be invoked
172 from the gdb command line. */
179 sim_close (sd
, quitting
)
183 sim_module_uninstall (sd
);
187 sim_create_inferior (sd
, abfd
, argv
, envp
)
193 SIM_CPU
*current_cpu
= STATE_CPU (sd
, 0);
197 addr
= bfd_get_start_address (abfd
);
200 h_pc_set (current_cpu
, addr
);
203 STATE_ARGV (sd
) = sim_copy_argv (argv
);
204 STATE_ENVP (sd
) = sim_copy_argv (envp
);
211 sim_stop (SIM_DESC sd
)
213 switch (STATE_ARCHITECTURE (sd
)->mach
)
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
);
222 /* end-sanitize-m32rx */
229 sim_resume (sd
, step
, siggnal
)
233 switch (STATE_ARCHITECTURE (sd
)->mach
)
236 m32r_engine_run (sd
, step
, siggnal
);
238 /* start-sanitize-m32rx */
239 #ifdef HAVE_CPU_M32RX
240 case bfd_mach_m32rx
:
241 m32rx_engine_run (sd
, step
, siggnal
);
244 /* end-sanitize-m32rx */
250 /* PROFILE_CPU_CALLBACK */
253 print_m32r_misc_cpu (SIM_CPU
*cpu
, int verbose
)
255 SIM_DESC sd
= CPU_STATE (cpu
);
258 if (CPU_PROFILE_FLAGS (cpu
) [PROFILE_INSN_IDX
])
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
));
268 /* The contents of BUF are in target byte order. */
271 sim_fetch_register (sd
, rn
, buf
, length
)
277 switch (STATE_ARCHITECTURE (sd
)->mach
)
280 m32r_fetch_register (sd
, rn
, buf
);
282 /* start-sanitize-m32rx */
283 #ifdef HAVE_CPU_M32RX
284 case bfd_mach_m32rx
:
285 m32rx_fetch_register (sd
, rn
, buf
);
288 /* end-sanitize-m32rx */
295 /* The contents of BUF are in target byte order. */
298 sim_store_register (sd
, rn
, buf
, length
)
304 switch (STATE_ARCHITECTURE (sd
)->mach
)
307 m32r_store_register (sd
, rn
, buf
);
309 /* start-sanitize-m32rx */
310 #ifdef HAVE_CPU_M32RX
311 case bfd_mach_m32rx
:
312 m32rx_store_register (sd
, rn
, buf
);
315 /* end-sanitize-m32rx */
323 sim_do_command (sd
, cmd
)
327 if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
328 sim_io_eprintf (sd
, "Unknown command `%s'\n", cmd
);
331 /* The semantic code invokes this for illegal (unrecognized) instructions. */
334 sim_engine_illegal_insn (current_cpu
, pc
)
335 SIM_CPU
*current_cpu
;
338 sim_engine_halt (CPU_STATE (current_cpu
), current_cpu
, NULL
, pc
,
339 sim_stopped
, SIM_SIGILL
);
342 /* Utility fns to access registers, without knowing the current mach.
343 FIXME: Machine generate? */
346 h_pc_get (SIM_CPU
*current_cpu
)
348 switch (STATE_ARCHITECTURE (CPU_STATE (current_cpu
))->mach
)
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
);
357 /* end-sanitize-m32rx */
364 h_pc_set (SIM_CPU
*current_cpu
, USI newval
)
366 switch (STATE_ARCHITECTURE (CPU_STATE (current_cpu
))->mach
)
369 m32r_h_pc_set (current_cpu
, newval
);
371 /* start-sanitize-m32rx */
372 #ifdef HAVE_CPU_M32RX
373 case bfd_mach_m32rx
:
374 m32rx_h_pc_set (current_cpu
, newval
);
377 /* end-sanitize-m32rx */
384 h_gr_get (SIM_CPU
*current_cpu
, UINT regno
)
386 switch (STATE_ARCHITECTURE (CPU_STATE (current_cpu
))->mach
)
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
);
395 /* end-sanitize-m32rx */
402 h_gr_set (SIM_CPU
*current_cpu
, UINT regno
, SI newval
)
404 switch (STATE_ARCHITECTURE (CPU_STATE (current_cpu
))->mach
)
407 m32r_h_gr_set (current_cpu
, regno
, newval
);
409 /* start-sanitize-m32rx */
410 #ifdef HAVE_CPU_M32RX
411 case bfd_mach_m32rx
:
412 m32rx_h_gr_set (current_cpu
, regno
, newval
);
415 /* end-sanitize-m32rx */
421 /* Read/write functions for system call interface. */
424 syscall_read_mem (host_callback
*cb
, struct cb_syscall
*sc
,
425 unsigned long taddr
, char *buf
, int bytes
)
427 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
428 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
430 return sim_core_read_buffer (sd
, cpu
, sim_core_read_map
, buf
, taddr
, bytes
);
434 syscall_write_mem (host_callback
*cb
, struct cb_syscall
*sc
,
435 unsigned long taddr
, const char *buf
, int bytes
)
437 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
438 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
440 return sim_core_write_buffer (sd
, cpu
, sim_core_write_map
, buf
, taddr
, bytes
);
446 do_trap (SIM_CPU
*current_cpu
, int num
)
448 SIM_DESC sd
= CPU_STATE (current_cpu
);
449 host_callback
*cb
= STATE_CALLBACK (sd
);
454 /* Trap 0 is used for system calls. */
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);
464 if (s
.func
== TARGET_SYS_exit
)
466 sim_engine_halt (sd
, current_cpu
, NULL
, h_pc_get (current_cpu
),
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
);
481 case 1: /* breakpoint trap */
482 sim_engine_halt (sd
, current_cpu
, NULL
, NULL_CIA
,
483 sim_stopped
, SIM_SIGTRAP
);
487 /* Unless environment operating, ignore other traps. */