]>
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, | |
84 | attach_raw_memory, | |
85 | access_read_write_exec, | |
86 | 0, 0, 0x100000, NULL, NULL); | |
87 | ||
88 | /* We could only do this if profiling has been enabled, but the | |
89 | structure member is small so we don't bother. */ | |
90 | for (i = 0; i < MAX_NR_PROCESSORS; ++i) | |
91 | memset (& CPU_M32R_PROFILE (STATE_CPU (sd, i)), 0, | |
92 | sizeof (CPU_M32R_PROFILE (STATE_CPU (sd, i)))); | |
93 | ||
94 | return &sim_global_state; | |
95 | } | |
96 | ||
97 | void | |
98 | sim_close (sd, quitting) | |
99 | SIM_DESC sd; | |
100 | int quitting; | |
101 | { | |
102 | sim_module_uninstall (sd); | |
103 | } | |
104 | ||
105 | SIM_RC | |
106 | sim_load (sd, prog, abfd, from_tty) | |
107 | SIM_DESC sd; | |
108 | char *prog; | |
109 | bfd *abfd; | |
110 | int from_tty; | |
111 | { | |
112 | extern bfd *sim_load_file (); /* ??? Don't know where this should live. */ | |
113 | bfd *prog_bfd; | |
114 | ||
115 | prog_bfd = sim_load_file (sd, STATE_MY_NAME (sd), | |
116 | STATE_CALLBACK (sd), | |
117 | prog, | |
118 | /* pass NULL for abfd, we always open our own */ | |
119 | NULL, | |
120 | STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG); | |
121 | if (prog_bfd == NULL) | |
122 | return SIM_RC_FAIL; | |
123 | sim_analyze_program (sd, prog_bfd); | |
124 | STATE_CPU_CPU (sd, 0)->pc = STATE_START_ADDR (sd); | |
125 | return SIM_RC_OK; | |
126 | } | |
127 | ||
128 | SIM_RC | |
129 | sim_create_inferior (sd, argv, envp) | |
130 | SIM_DESC sd; | |
131 | char **argv; | |
132 | char **envp; | |
133 | { | |
134 | #if 0 | |
135 | STATE_ARGV (sd) = sim_copy_argv (argv); | |
136 | STATE_ENVP (sd) = sim_copy_argv (envp); | |
137 | #endif | |
138 | return SIM_RC_OK; | |
139 | } | |
140 | ||
141 | void | |
142 | sim_kill (sd) | |
143 | SIM_DESC sd; | |
144 | { | |
145 | /* nothing to do */ | |
146 | } | |
147 | ||
148 | int | |
149 | sim_stop (SIM_DESC sd) | |
150 | { | |
151 | return engine_stop (sd); | |
152 | } | |
153 | ||
154 | void | |
155 | sim_resume (sd, step, siggnal) | |
156 | SIM_DESC sd; | |
157 | int step, siggnal; | |
158 | { | |
159 | engine_run (sd, step, siggnal); | |
160 | } | |
161 | ||
162 | void | |
163 | sim_stop_reason (sd, reason, sigrc) | |
164 | SIM_DESC sd; | |
165 | enum sim_stop *reason; | |
166 | int *sigrc; | |
167 | { | |
168 | sim_cpu *cpu = STATE_CPU (sd, 0); | |
169 | ||
170 | /* Map sim_state to sim_stop. */ | |
171 | switch (CPU_EXEC_STATE (cpu)) | |
172 | { | |
173 | case EXEC_STATE_EXITED : | |
174 | *reason = sim_exited; | |
175 | *sigrc = CPU_HALT_SIGRC (cpu); | |
176 | break; | |
177 | case EXEC_STATE_STOPPED : | |
178 | *reason = sim_stopped; | |
179 | *sigrc = sim_signal_to_host (CPU_HALT_SIGRC (cpu)); | |
180 | break; | |
181 | case EXEC_STATE_SIGNALLED : | |
182 | *reason = sim_signalled; | |
183 | *sigrc = sim_signal_to_host (CPU_HALT_SIGRC (cpu)); | |
184 | break; | |
185 | } | |
186 | } | |
187 | ||
188 | /* PROFILE_CPU_CALLBACK */ | |
189 | ||
190 | static void | |
191 | print_m32r_misc_cpu (SIM_CPU *cpu, int verbose) | |
192 | { | |
193 | SIM_DESC sd = CPU_STATE (cpu); | |
194 | ||
195 | if (CPU_PROFILE_FLAGS (cpu) [PROFILE_INSN_IDX]) | |
196 | { | |
197 | sim_io_printf (sd, "Miscellaneous Statistics\n\n"); | |
198 | sim_io_printf (sd, " %-*s %ld\n\n", | |
199 | PROFILE_LABEL_WIDTH, "Fill nops:", | |
200 | CPU_M32R_PROFILE (cpu).fillnop_count); | |
201 | } | |
202 | } | |
203 | ||
204 | void | |
205 | sim_info (sd, verbose) | |
206 | SIM_DESC sd; | |
207 | int verbose; | |
208 | { | |
209 | profile_print (sd, STATE_VERBOSE_P (sd), NULL, print_m32r_misc_cpu); | |
210 | } | |
211 | ||
212 | void | |
213 | sim_set_callbacks (sd, p) | |
214 | SIM_DESC sd; | |
215 | host_callback *p; | |
216 | { | |
217 | if (sd == NULL) | |
218 | sim_callback = p; | |
219 | else | |
220 | STATE_CALLBACK (sd) = p; | |
221 | } | |
222 | ||
223 | /* The contents of BUF are in target byte order. */ | |
224 | ||
225 | void | |
226 | sim_fetch_register (sd, rn, buf) | |
227 | SIM_DESC sd; | |
228 | int rn; | |
229 | unsigned char *buf; | |
230 | { | |
231 | if (rn < 16) | |
232 | SETTWI (buf, STATE_CPU_CPU (sd, 0)->h_gr[rn]); | |
233 | else if (rn < 21) | |
234 | SETTWI (buf, STATE_CPU_CPU (sd, 0)->h_cr[rn - 16]); | |
235 | else switch (rn) { | |
236 | case PC_REGNUM: | |
237 | SETTWI (buf, STATE_CPU_CPU (sd, 0)->pc); | |
238 | break; | |
239 | case ACCL_REGNUM: | |
240 | SETTWI (buf, GETLODI (STATE_CPU_CPU (sd, 0)->h_accum)); | |
241 | break; | |
242 | case ACCH_REGNUM: | |
243 | SETTWI (buf, GETHIDI (STATE_CPU_CPU (sd, 0)->h_accum)); | |
244 | break; | |
245 | #if 0 | |
246 | case 23: *reg = STATE_CPU_CPU (sd, 0)->h_cond; break; | |
247 | case 24: *reg = STATE_CPU_CPU (sd, 0)->h_sm; break; | |
248 | case 25: *reg = STATE_CPU_CPU (sd, 0)->h_bsm; break; | |
249 | case 26: *reg = STATE_CPU_CPU (sd, 0)->h_ie; break; | |
250 | case 27: *reg = STATE_CPU_CPU (sd, 0)->h_bie; break; | |
251 | case 28: *reg = STATE_CPU_CPU (sd, 0)->h_bcarry; break; /* rename: bc */ | |
252 | case 29: memcpy (buf, &STATE_CPU_CPU (sd, 0)->h_bpc, sizeof(WI)); break; /* duplicate */ | |
253 | #endif | |
254 | default: abort (); | |
255 | } | |
256 | } | |
257 | ||
258 | /* The contents of BUF are in target byte order. */ | |
259 | ||
260 | void | |
261 | sim_store_register (sd, rn, buf) | |
262 | SIM_DESC sd; | |
263 | int rn; | |
264 | unsigned char *buf; | |
265 | { | |
266 | if (rn < 16) | |
267 | STATE_CPU_CPU (sd, 0)->h_gr[rn] = GETTWI (buf); | |
268 | else if (rn < 21) | |
269 | STATE_CPU_CPU (sd, 0)->h_cr[rn - 16] = GETTWI (buf); | |
270 | else switch (rn) { | |
271 | case PC_REGNUM: | |
272 | STATE_CPU_CPU (sd, 0)->pc = GETTWI (buf); | |
273 | break; | |
274 | case ACCL_REGNUM: | |
275 | SETLODI (STATE_CPU_CPU (sd, 0)->h_accum, GETTWI (buf)); | |
276 | break; | |
277 | case ACCH_REGNUM: | |
278 | SETHIDI (STATE_CPU_CPU (sd, 0)->h_accum, GETTWI (buf)); | |
279 | break; | |
280 | #if 0 | |
281 | case 23: STATE_CPU_CPU (sd, 0)->h_cond = *reg; break; | |
282 | case 24: STATE_CPU_CPU (sd, 0)->h_sm = *reg; break; | |
283 | case 25: STATE_CPU_CPU (sd, 0)->h_bsm = *reg; break; | |
284 | case 26: STATE_CPU_CPU (sd, 0)->h_ie = *reg; break; | |
285 | case 27: STATE_CPU_CPU (sd, 0)->h_bie = *reg; break; | |
286 | case 28: STATE_CPU_CPU (sd, 0)->h_bcarry = *reg; break; /* rename: bc */ | |
287 | case 29: memcpy (&STATE_CPU_CPU (sd, 0)->h_bpc, buf, sizeof(DI)); break; /* duplicate */ | |
288 | #endif | |
289 | } | |
290 | } | |
291 | ||
292 | int | |
293 | sim_read (sd, addr, buf, len) | |
294 | SIM_DESC sd; | |
295 | SIM_ADDR addr; | |
296 | unsigned char *buf; | |
297 | int len; | |
298 | { | |
299 | #if 1 | |
300 | return sim_core_read_buffer (sd, sim_core_read_map, | |
301 | buf, addr, len); | |
302 | #else | |
303 | return (*STATE_MEM_READ (sd)) (sd, addr, buf, len); | |
304 | #endif | |
305 | } | |
306 | ||
307 | int | |
308 | sim_write (sd, addr, buf, len) | |
309 | SIM_DESC sd; | |
310 | SIM_ADDR addr; | |
311 | unsigned char *buf; | |
312 | int len; | |
313 | { | |
314 | #if 1 | |
315 | return sim_core_write_buffer (sd, sim_core_write_map, | |
316 | buf, addr, len); | |
317 | #else | |
318 | return (*STATE_MEM_WRITE (sd)) (sd, addr, buf, len); | |
319 | #endif | |
320 | } | |
321 | ||
322 | void | |
323 | sim_do_command (sd, cmd) | |
324 | SIM_DESC sd; | |
325 | char *cmd; | |
326 | { | |
327 | sim_io_error (sd, "sim_do_command - unimplemented"); | |
328 | } |