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