sim: erc32: strip paren from return statements
[deliverable/binutils-gdb.git] / sim / erc32 / interf.c
1 /*
2 * This file is part of SIS.
3 *
4 * SIS, SPARC instruction simulator V1.6 Copyright (C) 1995 Jiri Gaisler,
5 * European Space Agency
6 *
7 * This program is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 3 of the License, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22 #include "config.h"
23 #include <signal.h>
24 #include <string.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <sys/fcntl.h>
28 #include "sis.h"
29 #include "libiberty.h"
30 #include "bfd.h"
31 #include <dis-asm.h>
32 #include "sim-config.h"
33
34 #include "gdb/remote-sim.h"
35 #include "gdb/signals.h"
36
37 #define PSR_CWP 0x7
38
39 extern struct disassemble_info dinfo;
40 extern struct pstate sregs;
41 extern struct estate ebase;
42
43 extern int current_target_byte_order;
44 extern int ctrl_c;
45 extern int nfp;
46 extern int ift;
47 extern int rom8;
48 extern int wrp;
49 extern int uben;
50 extern int sis_verbose;
51 extern char *sis_version;
52 extern struct estate ebase;
53 extern struct evcell evbuf[];
54 extern struct irqcell irqarr[];
55 extern int irqpend, ext_irl;
56 extern int sparclite;
57 extern int dumbio;
58 extern int sparclite_board;
59 extern int termsave;
60 extern char uart_dev1[], uart_dev2[];
61
62 int sis_gdb_break = 1;
63
64 host_callback *sim_callback;
65
66 int
67 run_sim(sregs, icount, dis)
68 struct pstate *sregs;
69 uint64 icount;
70 int dis;
71 {
72 int mexc, irq;
73
74 if (sis_verbose)
75 (*sim_callback->printf_filtered) (sim_callback, "resuming at %x\n",
76 sregs->pc);
77 init_stdio();
78 sregs->starttime = get_time();
79 irq = 0;
80 if ((sregs->pc != 0) && (ebase.simtime == 0))
81 boot_init();
82 while (!sregs->err_mode & (icount > 0)) {
83
84 sregs->fhold = 0;
85 sregs->hold = 0;
86 sregs->icnt = 1;
87
88 if (sregs->psr & 0x080)
89 sregs->asi = 8;
90 else
91 sregs->asi = 9;
92
93 #if 0 /* DELETE ME! for debugging purposes only */
94 if (sis_verbose > 1)
95 if (sregs->pc == 0 || sregs->npc == 0)
96 printf ("bogus pc or npc\n");
97 #endif
98 mexc = memory_read(sregs->asi, sregs->pc, &sregs->inst,
99 2, &sregs->hold);
100 #if 1 /* DELETE ME! for debugging purposes only */
101 if (sis_verbose > 2)
102 printf("pc %x, np %x, sp %x, fp %x, wm %x, cw %x, i %08x\n",
103 sregs->pc, sregs->npc,
104 sregs->r[(((sregs->psr & 7) << 4) + 14) & 0x7f],
105 sregs->r[(((sregs->psr & 7) << 4) + 30) & 0x7f],
106 sregs->wim,
107 sregs->psr & 7,
108 sregs->inst);
109 #endif
110 if (sregs->annul) {
111 sregs->annul = 0;
112 sregs->icnt = 1;
113 sregs->pc = sregs->npc;
114 sregs->npc = sregs->npc + 4;
115 } else {
116 if (ext_irl) irq = check_interrupts(sregs);
117 if (!irq) {
118 if (mexc) {
119 sregs->trap = I_ACC_EXC;
120 } else {
121 if ((sis_gdb_break) && (sregs->inst == 0x91d02001)) {
122 if (sis_verbose)
123 (*sim_callback->printf_filtered) (sim_callback,
124 "SW BP hit at %x\n", sregs->pc);
125 sim_halt();
126 restore_stdio();
127 clearerr(stdin);
128 return BPT_HIT;
129 } else
130 dispatch_instruction(sregs);
131 }
132 icount--;
133 }
134 if (sregs->trap) {
135 irq = 0;
136 sregs->err_mode = execute_trap(sregs);
137 }
138 }
139 advance_time(sregs);
140 if (ctrl_c) {
141 icount = 0;
142 }
143 }
144 sim_halt();
145 sregs->tottime += get_time() - sregs->starttime;
146 restore_stdio();
147 clearerr(stdin);
148 if (sregs->err_mode)
149 error_mode(sregs->pc);
150 if (sregs->err_mode)
151 return ERROR;
152 if (sregs->bphit) {
153 if (sis_verbose)
154 (*sim_callback->printf_filtered) (sim_callback,
155 "HW BP hit at %x\n", sregs->pc);
156 return BPT_HIT;
157 }
158 if (ctrl_c) {
159 ctrl_c = 0;
160 return CTRL_C;
161 }
162 return TIME_OUT;
163 }
164
165 SIM_DESC
166 sim_open (kind, callback, abfd, argv)
167 SIM_OPEN_KIND kind;
168 struct host_callback_struct *callback;
169 struct bfd *abfd;
170 char **argv;
171 {
172
173 int argc = 0;
174 int stat = 1;
175 int freq = 0;
176
177 sim_callback = callback;
178
179 while (argv[argc])
180 argc++;
181 while (stat < argc) {
182 if (argv[stat][0] == '-') {
183 if (strcmp(argv[stat], "-v") == 0) {
184 sis_verbose++;
185 } else
186 if (strcmp(argv[stat], "-nfp") == 0) {
187 nfp = 1;
188 } else
189 if (strcmp(argv[stat], "-ift") == 0) {
190 ift = 1;
191 } else
192 if (strcmp(argv[stat], "-sparclite") == 0) {
193 sparclite = 1;
194 } else
195 if (strcmp(argv[stat], "-sparclite-board") == 0) {
196 sparclite_board = 1;
197 } else
198 if (strcmp(argv[stat], "-dumbio") == 0) {
199 dumbio = 1;
200 } else
201 if (strcmp(argv[stat], "-wrp") == 0) {
202 wrp = 1;
203 } else
204 if (strcmp(argv[stat], "-rom8") == 0) {
205 rom8 = 1;
206 } else
207 if (strcmp(argv[stat], "-uben") == 0) {
208 uben = 1;
209 } else
210 if (strcmp(argv[stat], "-uart1") == 0) {
211 if ((stat + 1) < argc)
212 strcpy(uart_dev1, argv[++stat]);
213 } else
214 if (strcmp(argv[stat], "-uart2") == 0) {
215 if ((stat + 1) < argc)
216 strcpy(uart_dev2, argv[++stat]);
217 } else
218 if (strcmp(argv[stat], "-nogdb") == 0) {
219 sis_gdb_break = 0;
220 } else
221 if (strcmp(argv[stat], "-freq") == 0) {
222 if ((stat + 1) < argc) {
223 freq = strtol(argv[++stat], (char **)NULL, 0);
224 }
225 } else
226 if (strncmp(argv[stat], "--sysroot=", sizeof("--sysroot=") - 1) == 0) {
227 /* Ignore until we start to support this. */
228 } else {
229 (*sim_callback->printf_filtered) (sim_callback,
230 "unknown option %s\n",
231 argv[stat]);
232 }
233 } else
234 bfd_load(argv[stat]);
235 stat++;
236 }
237
238 if (sis_verbose) {
239 (*sim_callback->printf_filtered) (sim_callback, "\n SIS - SPARC instruction simulator %s\n", sis_version);
240 (*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler ESA/ESTEC (jgais@wd.estec.esa.nl)\n");
241 if (nfp)
242 (*sim_callback->printf_filtered) (sim_callback, "no FPU\n");
243 if (sparclite)
244 (*sim_callback->printf_filtered) (sim_callback, "simulating Sparclite\n");
245 if (dumbio)
246 (*sim_callback->printf_filtered) (sim_callback, "dumb IO (no input, dumb output)\n");
247 if (sis_gdb_break == 0)
248 (*sim_callback->printf_filtered) (sim_callback, "disabling GDB trap handling for breakpoints\n");
249 if (freq)
250 (*sim_callback->printf_filtered) (sim_callback, " ERC32 freq %d Mhz\n", freq);
251 }
252
253 sregs.freq = freq ? freq : 15;
254 termsave = fcntl(0, F_GETFL, 0);
255 INIT_DISASSEMBLE_INFO(dinfo, stdout,(fprintf_ftype)fprintf);
256 dinfo.endian = BFD_ENDIAN_BIG;
257 reset_all();
258 ebase.simtime = 0;
259 init_sim();
260 init_bpt(&sregs);
261 reset_stat(&sregs);
262
263 /* Fudge our descriptor for now. */
264 return (SIM_DESC) 1;
265 }
266
267 void
268 sim_close(sd, quitting)
269 SIM_DESC sd;
270 int quitting;
271 {
272
273 exit_sim();
274 fcntl(0, F_SETFL, termsave);
275
276 };
277
278 SIM_RC
279 sim_load(sd, prog, abfd, from_tty)
280 SIM_DESC sd;
281 const char *prog;
282 bfd *abfd;
283 int from_tty;
284 {
285 bfd_load (prog);
286 return SIM_RC_OK;
287 }
288
289 SIM_RC
290 sim_create_inferior(sd, abfd, argv, env)
291 SIM_DESC sd;
292 struct bfd *abfd;
293 char **argv;
294 char **env;
295 {
296 bfd_vma start_address = 0;
297 if (abfd != NULL)
298 start_address = bfd_get_start_address (abfd);
299
300 ebase.simtime = 0;
301 reset_all();
302 reset_stat(&sregs);
303 sregs.pc = start_address & ~3;
304 sregs.npc = sregs.pc + 4;
305 return SIM_RC_OK;
306 }
307
308 int
309 sim_store_register(sd, regno, value, length)
310 SIM_DESC sd;
311 int regno;
312 unsigned char *value;
313 int length;
314 {
315 /* FIXME: Review the computation of regval. */
316 int regval;
317 if (current_target_byte_order == BIG_ENDIAN)
318 regval = (value[0] << 24) | (value[1] << 16)
319 | (value[2] << 8) | value[3];
320 else
321 regval = (value[3] << 24) | (value[2] << 16)
322 | (value[1] << 8) | value[0];
323 set_regi(&sregs, regno, regval);
324 return length;
325 }
326
327
328 int
329 sim_fetch_register(sd, regno, buf, length)
330 SIM_DESC sd;
331 int regno;
332 unsigned char *buf;
333 int length;
334 {
335 get_regi(&sregs, regno, buf);
336 return -1;
337 }
338
339 int
340 sim_write(sd, mem, buf, length)
341 SIM_DESC sd;
342 SIM_ADDR mem;
343 const unsigned char *buf;
344 int length;
345 {
346 return sis_memory_write (mem, buf, length);
347 }
348
349 int
350 sim_read(sd, mem, buf, length)
351 SIM_DESC sd;
352 SIM_ADDR mem;
353 unsigned char *buf;
354 int length;
355 {
356 return sis_memory_read (mem, buf, length);
357 }
358
359 void
360 sim_info(sd, verbose)
361 SIM_DESC sd;
362 int verbose;
363 {
364 show_stat(&sregs);
365 }
366
367 int simstat = OK;
368
369 void
370 sim_stop_reason(sd, reason, sigrc)
371 SIM_DESC sd;
372 enum sim_stop * reason;
373 int *sigrc;
374 {
375
376 switch (simstat) {
377 case CTRL_C:
378 *reason = sim_stopped;
379 *sigrc = GDB_SIGNAL_INT;
380 break;
381 case OK:
382 case TIME_OUT:
383 case BPT_HIT:
384 *reason = sim_stopped;
385 *sigrc = GDB_SIGNAL_TRAP;
386 break;
387 case ERROR:
388 *sigrc = 0;
389 *reason = sim_exited;
390 }
391 ctrl_c = 0;
392 simstat = OK;
393 }
394
395 /* Flush all register windows out to the stack. Starting after the invalid
396 window, flush all windows up to, and including the current window. This
397 allows GDB to do backtraces and look at local variables for frames that
398 are still in the register windows. Note that strictly speaking, this
399 behavior is *wrong* for several reasons. First, it doesn't use the window
400 overflow handlers. It therefore assumes standard frame layouts and window
401 handling policies. Second, it changes system state behind the back of the
402 target program. I expect this to mainly pose problems when debugging trap
403 handlers.
404 */
405
406 static void
407 flush_windows ()
408 {
409 int invwin;
410 int cwp;
411 int win;
412 int ws;
413
414 /* Keep current window handy */
415
416 cwp = sregs.psr & PSR_CWP;
417
418 /* Calculate the invalid window from the wim. */
419
420 for (invwin = 0; invwin <= PSR_CWP; invwin++)
421 if ((sregs.wim >> invwin) & 1)
422 break;
423
424 /* Start saving with the window after the invalid window. */
425
426 invwin = (invwin - 1) & PSR_CWP;
427
428 for (win = invwin; ; win = (win - 1) & PSR_CWP)
429 {
430 uint32 sp;
431 int i;
432
433 sp = sregs.r[(win * 16 + 14) & 0x7f];
434 #if 1
435 if (sis_verbose > 2) {
436 uint32 fp = sregs.r[(win * 16 + 30) & 0x7f];
437 printf("flush_window: win %d, sp %x, fp %x\n", win, sp, fp);
438 }
439 #endif
440
441 for (i = 0; i < 16; i++)
442 memory_write (11, sp + 4 * i, &sregs.r[(win * 16 + 16 + i) & 0x7f], 2,
443 &ws);
444
445 if (win == cwp)
446 break;
447 }
448 }
449
450 void
451 sim_resume(SIM_DESC sd, int step, int siggnal)
452 {
453 simstat = run_sim(&sregs, UINT64_MAX, 0);
454
455 if (sis_gdb_break) flush_windows ();
456 }
457
458 void
459 sim_do_command(sd, cmd)
460 SIM_DESC sd;
461 const char *cmd;
462 {
463 exec_cmd(&sregs, cmd);
464 }
465
466 char **
467 sim_complete_command (SIM_DESC sd, const char *text, const char *word)
468 {
469 return NULL;
470 }
471
472 #if 0 /* FIXME: These shouldn't exist. */
473
474 int
475 sim_insert_breakpoint(int addr)
476 {
477 if (sregs.bptnum < BPT_MAX) {
478 sregs.bpts[sregs.bptnum] = addr & ~0x3;
479 sregs.bptnum++;
480 if (sis_verbose)
481 (*sim_callback->printf_filtered) (sim_callback, "inserted HW BP at %x\n", addr);
482 return 0;
483 } else
484 return 1;
485 }
486
487 int
488 sim_remove_breakpoint(int addr)
489 {
490 int i = 0;
491
492 while ((i < sregs.bptnum) && (sregs.bpts[i] != addr))
493 i++;
494 if (addr == sregs.bpts[i]) {
495 for (; i < sregs.bptnum - 1; i++)
496 sregs.bpts[i] = sregs.bpts[i + 1];
497 sregs.bptnum -= 1;
498 if (sis_verbose)
499 (*sim_callback->printf_filtered) (sim_callback, "removed HW BP at %x\n", addr);
500 return 0;
501 }
502 return 1;
503 }
504
505 #endif
This page took 0.046983 seconds and 5 git commands to generate.