150276Speter/* main.c --- main function for stand-alone RL78 simulator. 262449Speter 350276Speter Copyright (C) 2011-2023 Free Software Foundation, Inc. 450276Speter Contributed by Red Hat, Inc. 550276Speter 650276Speter This file is part of the GNU simulators. 750276Speter 850276Speter This program is free software; you can redistribute it and/or modify 950276Speter it under the terms of the GNU General Public License as published by 1050276Speter the Free Software Foundation; either version 3 of the License, or 1150276Speter (at your option) any later version. 1250276Speter 1350276Speter This program is distributed in the hope that it will be useful, 1450276Speter but WITHOUT ANY WARRANTY; without even the implied warranty of 1550276Speter MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1650276Speter GNU General Public License for more details. 1750276Speter 1850276Speter You should have received a copy of the GNU General Public License 1950276Speter along with this program. If not, see <http://www.gnu.org/licenses/>. 2050276Speter*/ 2150276Speter 2250276Speter/* This must come before any other includes. */ 2350276Speter#include "defs.h" 2450276Speter 2550276Speter#include <stdio.h> 2650276Speter#include <string.h> 2750276Speter#include <stdlib.h> 2850276Speter#ifdef HAVE_UNISTD_H 2950276Speter#include <unistd.h> 3050276Speter#endif 3150276Speter#include <assert.h> 3250276Speter#include <setjmp.h> 3350276Speter#include <signal.h> 3450276Speter#include <getopt.h> 3550276Speter 3650276Speter#include "libiberty.h" 3750276Speter#include "bfd.h" 3850276Speter 3950276Speter#include "cpu.h" 4050276Speter#include "mem.h" 4150276Speter#include "load.h" 4250276Speter#include "trace.h" 4362449Speter 4462449Speterstatic int disassemble = 0; 4550276Speterstatic const char * dump_counts_filename = NULL; 4676726Speter 4750276Speterstatic void 4876726Speterdone (int exit_code) 4962449Speter{ 5050276Speter if (verbose) 5162449Speter { 5250276Speter printf ("Exit code: %d\n", exit_code); 5362449Speter printf ("total clocks: %lld\n", total_clocks); 5450276Speter } 5562449Speter if (dump_counts_filename) 5662449Speter dump_counts_per_insn (dump_counts_filename); 5750276Speter exit (exit_code); 5862449Speter} 5962449Speter 6062449Speterint 6162449Spetermain (int argc, char **argv) 6262449Speter{ 6362449Speter int o; 6462449Speter int save_trace; 6550276Speter bfd *prog; 6662449Speter int rc; 6762449Speter static const struct option longopts[] = { { 0 } }; 6850276Speter 6950276Speter xmalloc_set_program_name (argv[0]); 7062449Speter 7162449Speter while ((o = getopt_long (argc, argv, "tvdr:D:M:", longopts, NULL)) 7250276Speter != -1) 7362449Speter { 7462449Speter switch (o) 7562449Speter { 7662449Speter case 't': 7762449Speter trace ++; 7850276Speter break; 7950276Speter case 'v': 8050276Speter verbose ++; 8150276Speter break; 8250276Speter case 'd': 8376726Speter disassemble ++; 8462449Speter break; 8550276Speter case 'r': 8662449Speter mem_ram_size (atoi (optarg)); 8750276Speter break; 8862449Speter case 'D': 8950276Speter dump_counts_filename = optarg; 9062449Speter break; 9162449Speter case 'M': 9262449Speter if (strcmp (optarg, "g10") == 0) 9362449Speter { 9450276Speter rl78_g10_mode = 1; 9562449Speter g13_multiply = 0; 9662449Speter g14_multiply = 0; 9750276Speter mem_set_mirror (0, 0xf8000, 4096); 9876726Speter } 9976726Speter if (strcmp (optarg, "g13") == 0) 10076726Speter { 10162449Speter rl78_g10_mode = 0; 10262449Speter g13_multiply = 1; 10350276Speter g14_multiply = 0; 10462449Speter } 10562449Speter if (strcmp (optarg, "g14") == 0) 10650276Speter { 10762449Speter rl78_g10_mode = 0; 10862449Speter g13_multiply = 0; 10950276Speter g14_multiply = 1; 11062449Speter } 11150276Speter break; 11262449Speter case '?': 11362449Speter { 11462449Speter fprintf (stderr, 11562449Speter "usage: run [options] program [arguments]\n"); 11662449Speter fprintf (stderr, 11762449Speter "\t-v\t\t- increase verbosity.\n" 11862449Speter "\t-t\t\t- trace.\n" 11962449Speter "\t-d\t\t- disassemble.\n" 12062449Speter "\t-r <bytes>\t- ram size.\n" 12162449Speter "\t-M <mcu>\t- mcu type, default none, allowed: g10,g13,g14\n" 12262449Speter "\t-D <filename>\t- dump cycle count histogram\n"); 12350276Speter exit (1); 12462449Speter } 12562449Speter } 12662449Speter } 12762449Speter 12862449Speter prog = bfd_openr (argv[optind], 0); 12962449Speter if (!prog) 13062449Speter { 13162449Speter fprintf (stderr, "Can't read %s\n", argv[optind]); 13262449Speter exit (1); 13362449Speter } 13462449Speter 13562449Speter if (!bfd_check_format (prog, bfd_object)) 13662449Speter { 13762449Speter fprintf (stderr, "%s not a rl78 program\n", argv[optind]); 13862449Speter exit (1); 13962449Speter } 14050276Speter 14150276Speter init_cpu (); 14250276Speter 14350276Speter rl78_in_gdb = 0; 14450276Speter save_trace = trace; 14550276Speter trace = 0; 14662449Speter rl78_load (prog, 0, argv[0]); 14762449Speter trace = save_trace; 14862449Speter 14962449Speter sim_disasm_init (prog); 15062449Speter 15150276Speter rc = setjmp (decode_jmp_buf); 15262449Speter 15362449Speter if (rc == 0) 15462449Speter { 15562449Speter if (!trace && !disassemble) 15662449Speter { 15762449Speter /* This will longjmp to the above if an exception 15862449Speter happens. */ 15962449Speter for (;;) 16062449Speter decode_opcode (); 16162449Speter } 16262449Speter else 16362449Speter while (1) 16462449Speter { 16562449Speter 16662449Speter if (trace) 16762449Speter printf ("\n"); 16862449Speter 16962449Speter if (disassemble) 17062449Speter sim_disasm_one (); 17162449Speter 17262449Speter rc = decode_opcode (); 17362449Speter 17466963Speter if (trace) 17562449Speter trace_register_changes (); 17662449Speter } 17762449Speter } 17862449Speter 17962449Speter if (RL78_HIT_BREAK (rc)) 18062449Speter done (1); 18162449Speter else if (RL78_EXITED (rc)) 18262449Speter done (RL78_EXIT_STATUS (rc)); 18362449Speter else if (RL78_STOPPED (rc)) 18462449Speter { 18562449Speter if (verbose) 18662449Speter printf ("Stopped on signal %d\n", RL78_STOP_SIG (rc)); 18762449Speter exit (1); 18862449Speter } 18962449Speter done (0); 19062449Speter exit (0); 19162449Speter} 19262449Speter