Automatic date update in version.in
[binutils-gdb.git] / sim / rx / main.c
blob13d0c473e7434dbfc78687758323e938b2ff42e5
1 /* main.c --- main function for stand-alone RX simulator.
3 Copyright (C) 2005-2023 Free Software Foundation, Inc.
4 Contributed by Red Hat, Inc.
6 This file is part of the GNU simulators.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 /* This must come before any other includes. */
22 #include "defs.h"
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <assert.h>
29 #include <setjmp.h>
30 #include <signal.h>
31 #include <getopt.h>
33 #include "bfd.h"
35 #include "cpu.h"
36 #include "mem.h"
37 #include "misc.h"
38 #include "load.h"
39 #include "trace.h"
40 #include "err.h"
42 static int disassemble = 0;
44 /* This must be higher than any other option index. */
45 #define OPT_ACT 400
47 #define ACT(E,A) (OPT_ACT + SIM_ERR_##E * SIM_ERRACTION_NUM_ACTIONS + SIM_ERRACTION_##A)
49 static struct option sim_options[] =
51 { "end-sim-args", 0, NULL, 'E' },
52 { "exit-null-deref", 0, NULL, ACT(NULL_POINTER_DEREFERENCE,EXIT) },
53 { "warn-null-deref", 0, NULL, ACT(NULL_POINTER_DEREFERENCE,WARN) },
54 { "ignore-null-deref", 0, NULL, ACT(NULL_POINTER_DEREFERENCE,IGNORE) },
55 { "exit-unwritten-pages", 0, NULL, ACT(READ_UNWRITTEN_PAGES,EXIT) },
56 { "warn-unwritten-pages", 0, NULL, ACT(READ_UNWRITTEN_PAGES,WARN) },
57 { "ignore-unwritten-pages", 0, NULL, ACT(READ_UNWRITTEN_PAGES,IGNORE) },
58 { "exit-unwritten-bytes", 0, NULL, ACT(READ_UNWRITTEN_BYTES,EXIT) },
59 { "warn-unwritten-bytes", 0, NULL, ACT(READ_UNWRITTEN_BYTES,WARN) },
60 { "ignore-unwritten-bytes", 0, NULL, ACT(READ_UNWRITTEN_BYTES,IGNORE) },
61 { "exit-corrupt-stack", 0, NULL, ACT(CORRUPT_STACK,EXIT) },
62 { "warn-corrupt-stack", 0, NULL, ACT(CORRUPT_STACK,WARN) },
63 { "ignore-corrupt-stack", 0, NULL, ACT(CORRUPT_STACK,IGNORE) },
64 { 0, 0, 0, 0 }
67 static void
68 done (int exit_code)
70 if (verbose)
72 stack_heap_stats ();
73 mem_usage_stats ();
74 /* Only use comma separated numbers when being very verbose.
75 Comma separated numbers are hard to parse in awk scripts. */
76 if (verbose > 1)
77 printf ("insns: %14s\n", comma (rx_cycles));
78 else
79 printf ("insns: %u\n", rx_cycles);
81 pipeline_stats ();
83 exit (exit_code);
86 int
87 main (int argc, char **argv)
89 int o;
90 int save_trace;
91 bfd *prog;
92 int rc;
94 /* By default, we exit when an execution error occurs. */
95 execution_error_init_standalone ();
97 while ((o = getopt_long (argc, argv, "tvdeEwi", sim_options, NULL)) != -1)
99 if (o == 'E')
100 /* Stop processing the command line. This is so that any remaining
101 words on the command line that look like arguments will be passed
102 on to the program being simulated. */
103 break;
105 if (o >= OPT_ACT)
107 int e, a;
109 o -= OPT_ACT;
110 e = o / SIM_ERRACTION_NUM_ACTIONS;
111 a = o % SIM_ERRACTION_NUM_ACTIONS;
112 execution_error_set_action (e, a);
114 else switch (o)
116 case 't':
117 trace++;
118 break;
119 case 'v':
120 verbose++;
121 break;
122 case 'd':
123 disassemble++;
124 break;
125 case 'e':
126 execution_error_init_standalone ();
127 break;
128 case 'w':
129 execution_error_warn_all ();
130 break;
131 case 'i':
132 execution_error_ignore_all ();
133 break;
134 case '?':
136 int i;
137 fprintf (stderr,
138 "usage: run [options] program [arguments]\n");
139 fprintf (stderr,
140 "\t-v\t- increase verbosity.\n"
141 "\t-t\t- trace.\n"
142 "\t-d\t- disassemble.\n"
143 "\t-E\t- stop processing sim args\n"
144 "\t-e\t- exit on all execution errors.\n"
145 "\t-w\t- warn (do not exit) on all execution errors.\n"
146 "\t-i\t- ignore all execution errors.\n");
147 for (i=0; sim_options[i].name; i++)
148 fprintf (stderr, "\t--%s\n", sim_options[i].name);
149 exit (1);
154 prog = bfd_openr (argv[optind], 0);
155 if (!prog)
157 fprintf (stderr, "Can't read %s\n", argv[optind]);
158 exit (1);
161 if (!bfd_check_format (prog, bfd_object))
163 fprintf (stderr, "%s not a rx program\n", argv[optind]);
164 exit (1);
167 init_regs ();
169 rx_in_gdb = 0;
170 save_trace = trace;
171 trace = 0;
172 rx_load (prog, NULL);
173 trace = save_trace;
175 sim_disasm_init (prog);
177 enable_counting = verbose;
179 rc = setjmp (decode_jmp_buf);
181 if (rc == 0)
183 if (!trace && !disassemble)
185 /* This will longjmp to the above if an exception
186 happens. */
187 for (;;)
188 decode_opcode ();
190 else
191 while (1)
194 if (trace)
195 printf ("\n");
197 if (disassemble)
199 enable_counting = 0;
200 sim_disasm_one ();
201 enable_counting = verbose;
204 rc = decode_opcode ();
206 if (trace)
207 trace_register_changes ();
211 if (RX_HIT_BREAK (rc))
212 done (1);
213 else if (RX_EXITED (rc))
214 done (RX_EXIT_STATUS (rc));
215 else if (RX_STOPPED (rc))
217 if (verbose)
218 printf("Stopped on signal %d\n", RX_STOP_SIG (rc));
219 exit(1);
221 done (0);
222 exit (0);