sim: clean up C11 header includes
[binutils-gdb.git] / sim / rx / main.c
1 /* main.c --- main function for stand-alone RX simulator.
2
3 Copyright (C) 2005-2021 Free Software Foundation, Inc.
4 Contributed by Red Hat, Inc.
5
6 This file is part of the GNU simulators.
7
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.
12
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.
17
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/>. */
20
21
22 #include "config.h"
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #ifdef HAVE_UNISTD_H
27 #include <unistd.h>
28 #endif
29 #include <assert.h>
30 #include <setjmp.h>
31 #include <signal.h>
32 #ifdef HAVE_GETOPT_H
33 #include <getopt.h>
34 #endif
35
36 #include "bfd.h"
37
38 #include "cpu.h"
39 #include "mem.h"
40 #include "misc.h"
41 #include "load.h"
42 #include "trace.h"
43 #include "err.h"
44
45 static int disassemble = 0;
46
47 /* This must be higher than any other option index. */
48 #define OPT_ACT 400
49
50 #define ACT(E,A) (OPT_ACT + SIM_ERR_##E * SIM_ERRACTION_NUM_ACTIONS + SIM_ERRACTION_##A)
51
52 static struct option sim_options[] =
53 {
54 { "end-sim-args", 0, NULL, 'E' },
55 { "exit-null-deref", 0, NULL, ACT(NULL_POINTER_DEREFERENCE,EXIT) },
56 { "warn-null-deref", 0, NULL, ACT(NULL_POINTER_DEREFERENCE,WARN) },
57 { "ignore-null-deref", 0, NULL, ACT(NULL_POINTER_DEREFERENCE,IGNORE) },
58 { "exit-unwritten-pages", 0, NULL, ACT(READ_UNWRITTEN_PAGES,EXIT) },
59 { "warn-unwritten-pages", 0, NULL, ACT(READ_UNWRITTEN_PAGES,WARN) },
60 { "ignore-unwritten-pages", 0, NULL, ACT(READ_UNWRITTEN_PAGES,IGNORE) },
61 { "exit-unwritten-bytes", 0, NULL, ACT(READ_UNWRITTEN_BYTES,EXIT) },
62 { "warn-unwritten-bytes", 0, NULL, ACT(READ_UNWRITTEN_BYTES,WARN) },
63 { "ignore-unwritten-bytes", 0, NULL, ACT(READ_UNWRITTEN_BYTES,IGNORE) },
64 { "exit-corrupt-stack", 0, NULL, ACT(CORRUPT_STACK,EXIT) },
65 { "warn-corrupt-stack", 0, NULL, ACT(CORRUPT_STACK,WARN) },
66 { "ignore-corrupt-stack", 0, NULL, ACT(CORRUPT_STACK,IGNORE) },
67 { 0, 0, 0, 0 }
68 };
69
70 static void
71 done (int exit_code)
72 {
73 if (verbose)
74 {
75 stack_heap_stats ();
76 mem_usage_stats ();
77 /* Only use comma separated numbers when being very verbose.
78 Comma separated numbers are hard to parse in awk scripts. */
79 if (verbose > 1)
80 printf ("insns: %14s\n", comma (rx_cycles));
81 else
82 printf ("insns: %u\n", rx_cycles);
83
84 pipeline_stats ();
85 }
86 exit (exit_code);
87 }
88
89 int
90 main (int argc, char **argv)
91 {
92 int o;
93 int save_trace;
94 bfd *prog;
95 int rc;
96
97 /* By default, we exit when an execution error occurs. */
98 execution_error_init_standalone ();
99
100 while ((o = getopt_long (argc, argv, "tvdeEwi", sim_options, NULL)) != -1)
101 {
102 if (o == 'E')
103 /* Stop processing the command line. This is so that any remaining
104 words on the command line that look like arguments will be passed
105 on to the program being simulated. */
106 break;
107
108 if (o >= OPT_ACT)
109 {
110 int e, a;
111
112 o -= OPT_ACT;
113 e = o / SIM_ERRACTION_NUM_ACTIONS;
114 a = o % SIM_ERRACTION_NUM_ACTIONS;
115 execution_error_set_action (e, a);
116 }
117 else switch (o)
118 {
119 case 't':
120 trace++;
121 break;
122 case 'v':
123 verbose++;
124 break;
125 case 'd':
126 disassemble++;
127 break;
128 case 'e':
129 execution_error_init_standalone ();
130 break;
131 case 'w':
132 execution_error_warn_all ();
133 break;
134 case 'i':
135 execution_error_ignore_all ();
136 break;
137 case '?':
138 {
139 int i;
140 fprintf (stderr,
141 "usage: run [options] program [arguments]\n");
142 fprintf (stderr,
143 "\t-v\t- increase verbosity.\n"
144 "\t-t\t- trace.\n"
145 "\t-d\t- disassemble.\n"
146 "\t-E\t- stop processing sim args\n"
147 "\t-e\t- exit on all execution errors.\n"
148 "\t-w\t- warn (do not exit) on all execution errors.\n"
149 "\t-i\t- ignore all execution errors.\n");
150 for (i=0; sim_options[i].name; i++)
151 fprintf (stderr, "\t--%s\n", sim_options[i].name);
152 exit (1);
153 }
154 }
155 }
156
157 prog = bfd_openr (argv[optind], 0);
158 if (!prog)
159 {
160 fprintf (stderr, "Can't read %s\n", argv[optind]);
161 exit (1);
162 }
163
164 if (!bfd_check_format (prog, bfd_object))
165 {
166 fprintf (stderr, "%s not a rx program\n", argv[optind]);
167 exit (1);
168 }
169
170 init_regs ();
171
172 rx_in_gdb = 0;
173 save_trace = trace;
174 trace = 0;
175 rx_load (prog, NULL);
176 trace = save_trace;
177
178 sim_disasm_init (prog);
179
180 enable_counting = verbose;
181
182 rc = setjmp (decode_jmp_buf);
183
184 if (rc == 0)
185 {
186 if (!trace && !disassemble)
187 {
188 /* This will longjmp to the above if an exception
189 happens. */
190 for (;;)
191 decode_opcode ();
192 }
193 else
194 while (1)
195 {
196
197 if (trace)
198 printf ("\n");
199
200 if (disassemble)
201 {
202 enable_counting = 0;
203 sim_disasm_one ();
204 enable_counting = verbose;
205 }
206
207 rc = decode_opcode ();
208
209 if (trace)
210 trace_register_changes ();
211 }
212 }
213
214 if (RX_HIT_BREAK (rc))
215 done (1);
216 else if (RX_EXITED (rc))
217 done (RX_EXIT_STATUS (rc));
218 else if (RX_STOPPED (rc))
219 {
220 if (verbose)
221 printf("Stopped on signal %d\n", RX_STOP_SIG (rc));
222 exit(1);
223 }
224 done (0);
225 exit (0);
226 }