Commit | Line | Data |
---|---|---|
646c6f2b DE |
1 | /* Main simulator entry points for the M32R. |
2 | Copyright (C) 1996, 1997 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 "cpu-sim.h" | |
28 | ||
29 | struct host_callback_struct *sim_callback; | |
30 | ||
31 | /* Global state until sim_open starts creating and returning it | |
32 | [and the other simulator i/f fns take it as an argument]. */ | |
33 | struct sim_state sim_global_state; | |
34 | ||
35 | /* FIXME: Do we *need* to pass state to the semantic routines? */ | |
36 | STATE current_state; | |
37 | ||
38 | /* Create an instance of the simulator. */ | |
39 | ||
40 | SIM_DESC | |
41 | sim_open (kind, argv) | |
42 | SIM_OPEN_KIND kind; | |
43 | char **argv; | |
44 | { | |
45 | int i; | |
46 | SIM_DESC sd = &sim_global_state; | |
47 | ||
48 | /* FIXME: until we alloc one, use the global. */ | |
49 | memset (sd, 0, sizeof (sim_global_state)); | |
50 | STATE_OPEN_KIND (sd) = kind; | |
51 | STATE_CALLBACK (sd) = sim_callback; | |
52 | ||
53 | if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) | |
54 | return 0; | |
55 | ||
56 | #if 0 /* FIXME: 'twould be nice if we could do this */ | |
57 | /* These options override any module options. | |
58 | Obviously ambiguity should be avoided, however the caller may wish to | |
59 | augment the meaning of an option. */ | |
60 | if (extra_options != NULL) | |
61 | sim_add_option_table (sd, extra_options); | |
62 | #endif | |
63 | ||
64 | /* getopt will print the error message so we just have to exit if this fails. | |
65 | FIXME: Hmmm... in the case of gdb we need getopt to call | |
66 | print_filtered. */ | |
67 | if (sim_parse_args (sd, argv) != SIM_RC_OK) | |
68 | { | |
69 | sim_module_uninstall (sd); | |
70 | return 0; | |
71 | } | |
72 | ||
73 | if (sim_post_argv_init (sd) != SIM_RC_OK) | |
74 | { | |
75 | sim_module_uninstall (sd); | |
76 | return 0; | |
77 | } | |
78 | ||
79 | /* Initialize various cgen things not done by common framework. */ | |
80 | cgen_init (sd); | |
81 | ||
82 | /* FIXME:wip */ | |
83 | sim_core_attach (sd, | |
7a418800 | 84 | NULL, |
646c6f2b DE |
85 | attach_raw_memory, |
86 | access_read_write_exec, | |
87 | 0, 0, 0x100000, NULL, NULL); | |
88 | ||
89 | /* We could only do this if profiling has been enabled, but the | |
90 | structure member is small so we don't bother. */ | |
91 | for (i = 0; i < MAX_NR_PROCESSORS; ++i) | |
92 | memset (& CPU_M32R_PROFILE (STATE_CPU (sd, i)), 0, | |
93 | sizeof (CPU_M32R_PROFILE (STATE_CPU (sd, i)))); | |
94 | ||
95 | return &sim_global_state; | |
96 | } | |
97 | ||
98 | void | |
99 | sim_close (sd, quitting) | |
100 | SIM_DESC sd; | |
101 | int quitting; | |
102 | { | |
103 | sim_module_uninstall (sd); | |
104 | } | |
105 | ||
106 | SIM_RC | |
107 | sim_load (sd, prog, abfd, from_tty) | |
108 | SIM_DESC sd; | |
109 | char *prog; | |
110 | bfd *abfd; | |
111 | int from_tty; | |
112 | { | |
113 | extern bfd *sim_load_file (); /* ??? Don't know where this should live. */ | |
114 | bfd *prog_bfd; | |
115 | ||
116 | prog_bfd = sim_load_file (sd, STATE_MY_NAME (sd), | |
117 | STATE_CALLBACK (sd), | |
118 | prog, | |
119 | /* pass NULL for abfd, we always open our own */ | |
120 | NULL, | |
121 | STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG); | |
122 | if (prog_bfd == NULL) | |
123 | return SIM_RC_FAIL; | |
124 | sim_analyze_program (sd, prog_bfd); | |
125 | STATE_CPU_CPU (sd, 0)->pc = STATE_START_ADDR (sd); | |
126 | return SIM_RC_OK; | |
127 | } | |
128 | ||
129 | SIM_RC | |
130 | sim_create_inferior (sd, argv, envp) | |
131 | SIM_DESC sd; | |
132 | char **argv; | |
133 | char **envp; | |
134 | { | |
135 | #if 0 | |
136 | STATE_ARGV (sd) = sim_copy_argv (argv); | |
137 | STATE_ENVP (sd) = sim_copy_argv (envp); | |
138 | #endif | |
139 | return SIM_RC_OK; | |
140 | } | |
141 | ||
142 | void | |
143 | sim_kill (sd) | |
144 | SIM_DESC sd; | |
145 | { | |
146 | /* nothing to do */ | |
147 | } | |
148 | ||
149 | int | |
150 | sim_stop (SIM_DESC sd) | |
151 | { | |
152 | return engine_stop (sd); | |
153 | } | |
154 | ||
155 | void | |
156 | sim_resume (sd, step, siggnal) | |
157 | SIM_DESC sd; | |
158 | int step, siggnal; | |
159 | { | |
160 | engine_run (sd, step, siggnal); | |
161 | } | |
162 | ||
163 | void | |
164 | sim_stop_reason (sd, reason, sigrc) | |
165 | SIM_DESC sd; | |
166 | enum sim_stop *reason; | |
167 | int *sigrc; | |
168 | { | |
169 | sim_cpu *cpu = STATE_CPU (sd, 0); | |
170 | ||
171 | /* Map sim_state to sim_stop. */ | |
172 | switch (CPU_EXEC_STATE (cpu)) | |
173 | { | |
174 | case EXEC_STATE_EXITED : | |
175 | *reason = sim_exited; | |
176 | *sigrc = CPU_HALT_SIGRC (cpu); | |
177 | break; | |
178 | case EXEC_STATE_STOPPED : | |
179 | *reason = sim_stopped; | |
180 | *sigrc = sim_signal_to_host (CPU_HALT_SIGRC (cpu)); | |
181 | break; | |
182 | case EXEC_STATE_SIGNALLED : | |
183 | *reason = sim_signalled; | |
184 | *sigrc = sim_signal_to_host (CPU_HALT_SIGRC (cpu)); | |
185 | break; | |
186 | } | |
187 | } | |
188 | ||
189 | /* PROFILE_CPU_CALLBACK */ | |
190 | ||
191 | static void | |
192 | print_m32r_misc_cpu (SIM_CPU *cpu, int verbose) | |
193 | { | |
194 | SIM_DESC sd = CPU_STATE (cpu); | |
7a418800 | 195 | char buf[20]; |
646c6f2b DE |
196 | |
197 | if (CPU_PROFILE_FLAGS (cpu) [PROFILE_INSN_IDX]) | |
198 | { | |
199 | sim_io_printf (sd, "Miscellaneous Statistics\n\n"); | |
7a418800 | 200 | sim_io_printf (sd, " %-*s %s\n\n", |
646c6f2b | 201 | PROFILE_LABEL_WIDTH, "Fill nops:", |
7a418800 AC |
202 | sim_add_commas (buf, sizeof (buf), |
203 | CPU_M32R_PROFILE (cpu).fillnop_count)); | |
646c6f2b DE |
204 | } |
205 | } | |
206 | ||
207 | void | |
208 | sim_info (sd, verbose) | |
209 | SIM_DESC sd; | |
210 | int verbose; | |
211 | { | |
212 | profile_print (sd, STATE_VERBOSE_P (sd), NULL, print_m32r_misc_cpu); | |
213 | } | |
214 | ||
215 | void | |
216 | sim_set_callbacks (sd, p) | |
217 | SIM_DESC sd; | |
218 | host_callback *p; | |
219 | { | |
220 | if (sd == NULL) | |
221 | sim_callback = p; | |
222 | else | |
223 | STATE_CALLBACK (sd) = p; | |
224 | } | |
225 | ||
226 | /* The contents of BUF are in target byte order. */ | |
227 | ||
228 | void | |
229 | sim_fetch_register (sd, rn, buf) | |
230 | SIM_DESC sd; | |
231 | int rn; | |
232 | unsigned char *buf; | |
233 | { | |
234 | if (rn < 16) | |
235 | SETTWI (buf, STATE_CPU_CPU (sd, 0)->h_gr[rn]); | |
236 | else if (rn < 21) | |
237 | SETTWI (buf, STATE_CPU_CPU (sd, 0)->h_cr[rn - 16]); | |
238 | else switch (rn) { | |
239 | case PC_REGNUM: | |
240 | SETTWI (buf, STATE_CPU_CPU (sd, 0)->pc); | |
241 | break; | |
242 | case ACCL_REGNUM: | |
243 | SETTWI (buf, GETLODI (STATE_CPU_CPU (sd, 0)->h_accum)); | |
244 | break; | |
245 | case ACCH_REGNUM: | |
246 | SETTWI (buf, GETHIDI (STATE_CPU_CPU (sd, 0)->h_accum)); | |
247 | break; | |
248 | #if 0 | |
249 | case 23: *reg = STATE_CPU_CPU (sd, 0)->h_cond; break; | |
250 | case 24: *reg = STATE_CPU_CPU (sd, 0)->h_sm; break; | |
251 | case 25: *reg = STATE_CPU_CPU (sd, 0)->h_bsm; break; | |
252 | case 26: *reg = STATE_CPU_CPU (sd, 0)->h_ie; break; | |
253 | case 27: *reg = STATE_CPU_CPU (sd, 0)->h_bie; break; | |
254 | case 28: *reg = STATE_CPU_CPU (sd, 0)->h_bcarry; break; /* rename: bc */ | |
255 | case 29: memcpy (buf, &STATE_CPU_CPU (sd, 0)->h_bpc, sizeof(WI)); break; /* duplicate */ | |
256 | #endif | |
257 | default: abort (); | |
258 | } | |
259 | } | |
260 | ||
261 | /* The contents of BUF are in target byte order. */ | |
262 | ||
263 | void | |
264 | sim_store_register (sd, rn, buf) | |
265 | SIM_DESC sd; | |
266 | int rn; | |
267 | unsigned char *buf; | |
268 | { | |
269 | if (rn < 16) | |
270 | STATE_CPU_CPU (sd, 0)->h_gr[rn] = GETTWI (buf); | |
271 | else if (rn < 21) | |
272 | STATE_CPU_CPU (sd, 0)->h_cr[rn - 16] = GETTWI (buf); | |
273 | else switch (rn) { | |
274 | case PC_REGNUM: | |
275 | STATE_CPU_CPU (sd, 0)->pc = GETTWI (buf); | |
276 | break; | |
277 | case ACCL_REGNUM: | |
278 | SETLODI (STATE_CPU_CPU (sd, 0)->h_accum, GETTWI (buf)); | |
279 | break; | |
280 | case ACCH_REGNUM: | |
281 | SETHIDI (STATE_CPU_CPU (sd, 0)->h_accum, GETTWI (buf)); | |
282 | break; | |
283 | #if 0 | |
284 | case 23: STATE_CPU_CPU (sd, 0)->h_cond = *reg; break; | |
285 | case 24: STATE_CPU_CPU (sd, 0)->h_sm = *reg; break; | |
286 | case 25: STATE_CPU_CPU (sd, 0)->h_bsm = *reg; break; | |
287 | case 26: STATE_CPU_CPU (sd, 0)->h_ie = *reg; break; | |
288 | case 27: STATE_CPU_CPU (sd, 0)->h_bie = *reg; break; | |
289 | case 28: STATE_CPU_CPU (sd, 0)->h_bcarry = *reg; break; /* rename: bc */ | |
290 | case 29: memcpy (&STATE_CPU_CPU (sd, 0)->h_bpc, buf, sizeof(DI)); break; /* duplicate */ | |
291 | #endif | |
292 | } | |
293 | } | |
294 | ||
295 | int | |
296 | sim_read (sd, addr, buf, len) | |
297 | SIM_DESC sd; | |
298 | SIM_ADDR addr; | |
299 | unsigned char *buf; | |
300 | int len; | |
301 | { | |
302 | #if 1 | |
303 | return sim_core_read_buffer (sd, sim_core_read_map, | |
304 | buf, addr, len); | |
305 | #else | |
306 | return (*STATE_MEM_READ (sd)) (sd, addr, buf, len); | |
307 | #endif | |
308 | } | |
309 | ||
310 | int | |
311 | sim_write (sd, addr, buf, len) | |
312 | SIM_DESC sd; | |
313 | SIM_ADDR addr; | |
314 | unsigned char *buf; | |
315 | int len; | |
316 | { | |
317 | #if 1 | |
318 | return sim_core_write_buffer (sd, sim_core_write_map, | |
319 | buf, addr, len); | |
320 | #else | |
321 | return (*STATE_MEM_WRITE (sd)) (sd, addr, buf, len); | |
322 | #endif | |
323 | } | |
324 | ||
325 | void | |
326 | sim_do_command (sd, cmd) | |
327 | SIM_DESC sd; | |
328 | char *cmd; | |
329 | { | |
330 | sim_io_error (sd, "sim_do_command - unimplemented"); | |
331 | } |