1 /* main.c --- main function for stand-alone RL78 simulator. 2 3 Copyright (C) 2011-2023 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 /* This must come before any other includes. */ 23 #include "defs.h" 24 25 #include <stdio.h> 26 #include <string.h> 27 #include <stdlib.h> 28 #ifdef HAVE_UNISTD_H 29 #include <unistd.h> 30 #endif 31 #include <assert.h> 32 #include <setjmp.h> 33 #include <signal.h> 34 #include <getopt.h> 35 36 #include "libiberty.h" 37 #include "bfd.h" 38 39 #include "cpu.h" 40 #include "mem.h" 41 #include "load.h" 42 #include "trace.h" 43 44 static int disassemble = 0; 45 static const char * dump_counts_filename = NULL; 46 47 static void 48 done (int exit_code) 49 { 50 if (verbose) 51 { 52 printf ("Exit code: %d\n", exit_code); 53 printf ("total clocks: %lld\n", total_clocks); 54 } 55 if (dump_counts_filename) 56 dump_counts_per_insn (dump_counts_filename); 57 exit (exit_code); 58 } 59 60 int 61 main (int argc, char **argv) 62 { 63 int o; 64 int save_trace; 65 bfd *prog; 66 int rc; 67 static const struct option longopts[] = { { 0 } }; 68 69 xmalloc_set_program_name (argv[0]); 70 71 while ((o = getopt_long (argc, argv, "tvdr:D:M:", longopts, NULL)) 72 != -1) 73 { 74 switch (o) 75 { 76 case 't': 77 trace ++; 78 break; 79 case 'v': 80 verbose ++; 81 break; 82 case 'd': 83 disassemble ++; 84 break; 85 case 'r': 86 mem_ram_size (atoi (optarg)); 87 break; 88 case 'D': 89 dump_counts_filename = optarg; 90 break; 91 case 'M': 92 if (strcmp (optarg, "g10") == 0) 93 { 94 rl78_g10_mode = 1; 95 g13_multiply = 0; 96 g14_multiply = 0; 97 mem_set_mirror (0, 0xf8000, 4096); 98 } 99 if (strcmp (optarg, "g13") == 0) 100 { 101 rl78_g10_mode = 0; 102 g13_multiply = 1; 103 g14_multiply = 0; 104 } 105 if (strcmp (optarg, "g14") == 0) 106 { 107 rl78_g10_mode = 0; 108 g13_multiply = 0; 109 g14_multiply = 1; 110 } 111 break; 112 case '?': 113 { 114 fprintf (stderr, 115 "usage: run [options] program [arguments]\n"); 116 fprintf (stderr, 117 "\t-v\t\t- increase verbosity.\n" 118 "\t-t\t\t- trace.\n" 119 "\t-d\t\t- disassemble.\n" 120 "\t-r <bytes>\t- ram size.\n" 121 "\t-M <mcu>\t- mcu type, default none, allowed: g10,g13,g14\n" 122 "\t-D <filename>\t- dump cycle count histogram\n"); 123 exit (1); 124 } 125 } 126 } 127 128 prog = bfd_openr (argv[optind], 0); 129 if (!prog) 130 { 131 fprintf (stderr, "Can't read %s\n", argv[optind]); 132 exit (1); 133 } 134 135 if (!bfd_check_format (prog, bfd_object)) 136 { 137 fprintf (stderr, "%s not a rl78 program\n", argv[optind]); 138 exit (1); 139 } 140 141 init_cpu (); 142 143 rl78_in_gdb = 0; 144 save_trace = trace; 145 trace = 0; 146 rl78_load (prog, 0, argv[0]); 147 trace = save_trace; 148 149 sim_disasm_init (prog); 150 151 rc = setjmp (decode_jmp_buf); 152 153 if (rc == 0) 154 { 155 if (!trace && !disassemble) 156 { 157 /* This will longjmp to the above if an exception 158 happens. */ 159 for (;;) 160 decode_opcode (); 161 } 162 else 163 while (1) 164 { 165 166 if (trace) 167 printf ("\n"); 168 169 if (disassemble) 170 sim_disasm_one (); 171 172 rc = decode_opcode (); 173 174 if (trace) 175 trace_register_changes (); 176 } 177 } 178 179 if (RL78_HIT_BREAK (rc)) 180 done (1); 181 else if (RL78_EXITED (rc)) 182 done (RL78_EXIT_STATUS (rc)); 183 else if (RL78_STOPPED (rc)) 184 { 185 if (verbose) 186 printf ("Stopped on signal %d\n", RL78_STOP_SIG (rc)); 187 exit (1); 188 } 189 done (0); 190 exit (0); 191 } 192