aboutsummaryrefslogtreecommitdiff
path: root/sim/rx/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'sim/rx/main.c')
-rw-r--r--sim/rx/main.c200
1 files changed, 200 insertions, 0 deletions
diff --git a/sim/rx/main.c b/sim/rx/main.c
new file mode 100644
index 0000000..9945e5e
--- /dev/null
+++ b/sim/rx/main.c
@@ -0,0 +1,200 @@
+/* main.c --- main function for stand-alone RX simulator.
+
+Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
+Contributed by Red Hat, Inc.
+
+This file is part of the GNU simulators.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include <setjmp.h>
+#include <signal.h>
+
+#include "bfd.h"
+
+#include "cpu.h"
+#include "mem.h"
+#include "misc.h"
+#include "load.h"
+#include "trace.h"
+#include "err.h"
+
+static int disassemble = 0;
+
+/* This must be higher than any other option index. */
+#define OPT_ACT 400
+
+#define ACT(E,A) (OPT_ACT + SIM_ERR_##E * SIM_ERRACTION_NUM_ACTIONS + SIM_ERRACTION_##A)
+
+static struct option sim_options[] =
+{
+ { "end-sim-args", 0, NULL, 'E' },
+ { "exit-null-deref", 0, NULL, ACT(NULL_POINTER_DEREFERENCE,EXIT) },
+ { "warn-null-deref", 0, NULL, ACT(NULL_POINTER_DEREFERENCE,WARN) },
+ { "ignore-null-deref", 0, NULL, ACT(NULL_POINTER_DEREFERENCE,IGNORE) },
+ { "exit-unwritten-pages", 0, NULL, ACT(READ_UNWRITTEN_PAGES,EXIT) },
+ { "warn-unwritten-pages", 0, NULL, ACT(READ_UNWRITTEN_PAGES,WARN) },
+ { "ignore-unwritten-pages", 0, NULL, ACT(READ_UNWRITTEN_PAGES,IGNORE) },
+ { "exit-unwritten-bytes", 0, NULL, ACT(READ_UNWRITTEN_BYTES,EXIT) },
+ { "warn-unwritten-bytes", 0, NULL, ACT(READ_UNWRITTEN_BYTES,WARN) },
+ { "ignore-unwritten-bytes", 0, NULL, ACT(READ_UNWRITTEN_BYTES,IGNORE) },
+ { "exit-corrupt-stack", 0, NULL, ACT(CORRUPT_STACK,EXIT) },
+ { "warn-corrupt-stack", 0, NULL, ACT(CORRUPT_STACK,WARN) },
+ { "ignore-corrupt-stack", 0, NULL, ACT(CORRUPT_STACK,IGNORE) },
+ { 0, 0, 0, 0 }
+};
+
+static void
+done (int exit_code)
+{
+ if (verbose)
+ {
+ stack_heap_stats ();
+ mem_usage_stats ();
+ /* Only use comma separated numbers when being very verbose.
+ Comma separated numbers are hard to parse in awk scripts. */
+ if (verbose > 1)
+ printf ("insns: %14s\n", comma (rx_cycles));
+ else
+ printf ("insns: %u\n", rx_cycles);
+ }
+ exit (exit_code);
+}
+
+int
+main (int argc, char **argv)
+{
+ int o;
+ int save_trace;
+ bfd *prog;
+
+ /* By default, we exit when an execution error occurs. */
+ execution_error_init_standalone ();
+
+ while ((o = getopt_long (argc, argv, "tvdeEwi", sim_options, NULL)) != -1)
+ {
+ if (o == 'E')
+ /* Stop processing the command line. This is so that any remaining
+ words on the command line that look like arguments will be passed
+ on to the program being simulated. */
+ break;
+
+ if (o >= OPT_ACT)
+ {
+ int e, a;
+
+ o -= OPT_ACT;
+ e = o / SIM_ERRACTION_NUM_ACTIONS;
+ a = o % SIM_ERRACTION_NUM_ACTIONS;
+ execution_error_set_action (e, a);
+ }
+ else switch (o)
+ {
+ case 't':
+ trace++;
+ break;
+ case 'v':
+ verbose++;
+ break;
+ case 'd':
+ disassemble++;
+ break;
+ case 'e':
+ execution_error_init_standalone ();
+ break;
+ case 'w':
+ execution_error_warn_all ();
+ break;
+ case 'i':
+ execution_error_ignore_all ();
+ break;
+ case '?':
+ {
+ int i;
+ fprintf (stderr,
+ "usage: run [options] program [arguments]\n");
+ fprintf (stderr,
+ "\t-v\t- increase verbosity.\n"
+ "\t-t\t- trace.\n"
+ "\t-d\t- disassemble.\n"
+ "\t-E\t- stop processing sim args\n"
+ "\t-e\t- exit on all execution errors.\n"
+ "\t-w\t- warn (do not exit) on all execution errors.\n"
+ "\t-i\t- ignore all execution errors.\n");
+ for (i=0; sim_options[i].name; i++)
+ fprintf (stderr, "\t--%s\n", sim_options[i].name);
+ exit (1);
+ }
+ }
+ }
+
+ prog = bfd_openr (argv[optind], 0);
+ if (!prog)
+ {
+ fprintf (stderr, "Can't read %s\n", argv[optind]);
+ exit (1);
+ }
+
+ if (!bfd_check_format (prog, bfd_object))
+ {
+ fprintf (stderr, "%s not a rx program\n", argv[optind]);
+ exit (1);
+ }
+
+ init_regs ();
+
+ rx_in_gdb = 0;
+ save_trace = trace;
+ trace = 0;
+ rx_load (prog);
+ trace = save_trace;
+
+ sim_disasm_init (prog);
+
+ while (1)
+ {
+ int rc;
+
+ if (trace)
+ printf ("\n");
+
+ if (disassemble)
+ sim_disasm_one ();
+
+ enable_counting = verbose;
+ rc = decode_opcode ();
+ enable_counting = 0;
+
+ if (RX_HIT_BREAK (rc))
+ done (1);
+ else if (RX_EXITED (rc))
+ done (RX_EXIT_STATUS (rc));
+ else if (RX_STOPPED (rc))
+ {
+ if (verbose)
+ printf("Stopped on signal %d\n", RX_STOP_SIG (rc));
+ exit(1);
+ }
+ else
+ assert (RX_STEPPED (rc));
+
+ trace_register_changes ();
+ }
+}