4221c0ea7deee951f1cb9f6f7fc6c259bd0c2640
[external/binutils.git] / sim / m32r / sim-if.c
1 /* Main simulator entry points specific to the M32R.
2    Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
3    Contributed by Cygnus Support.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
18
19 #include "sim-main.h"
20 #ifdef HAVE_STDLIB_H
21 #include <stdlib.h>
22 #endif
23 #include "sim-options.h"
24 #include "libiberty.h"
25 #include "bfd.h"
26
27 static void free_state (SIM_DESC);
28 static void print_m32r_misc_cpu (SIM_CPU *cpu, int verbose);
29
30 /* Records simulator descriptor so utilities like m32r_dump_regs can be
31    called from gdb.  */
32 SIM_DESC current_state;
33 \f
34 /* Cover function of sim_state_free to free the cpu buffers as well.  */
35
36 static void
37 free_state (SIM_DESC sd)
38 {
39   if (STATE_MODULES (sd) != NULL)
40     sim_module_uninstall (sd);
41   sim_cpu_free_all (sd);
42   sim_state_free (sd);
43 }
44
45 /* Create an instance of the simulator.  */
46
47 SIM_DESC
48 sim_open (kind, callback, abfd, argv)
49      SIM_OPEN_KIND kind;
50      host_callback *callback;
51      struct _bfd *abfd;
52      char **argv;
53 {
54   char c;
55   SIM_DESC sd = sim_state_alloc (kind, callback);
56
57   /* The cpu data is kept in a separately allocated chunk of memory.  */
58   if (sim_cpu_alloc_all (sd, 1, cgen_cpu_max_extra_bytes ()) != SIM_RC_OK)
59     {
60       free_state (sd);
61       return 0;
62     }
63
64 #if 0 /* FIXME: pc is in mach-specific struct */
65   /* FIXME: watchpoints code shouldn't need this */
66   {
67     SIM_CPU *current_cpu = STATE_CPU (sd, 0);
68     STATE_WATCHPOINTS (sd)->pc = &(PC);
69     STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
70   }
71 #endif
72
73   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
74     {
75       free_state (sd);
76       return 0;
77     }
78
79 #if 0 /* FIXME: 'twould be nice if we could do this */
80   /* These options override any module options.
81      Obviously ambiguity should be avoided, however the caller may wish to
82      augment the meaning of an option.  */
83   if (extra_options != NULL)
84     sim_add_option_table (sd, extra_options);
85 #endif
86
87   /* getopt will print the error message so we just have to exit if this fails.
88      FIXME: Hmmm...  in the case of gdb we need getopt to call
89      print_filtered.  */
90   if (sim_parse_args (sd, argv) != SIM_RC_OK)
91     {
92       free_state (sd);
93       return 0;
94     }
95
96   /* Allocate a handler for the control registers and other devices
97      if no memory for that range has been allocated by the user.
98      All are allocated in one chunk to keep things from being
99      unnecessarily complicated.  */
100   if (sim_core_read_buffer (sd, NULL, read_map, &c, M32R_DEVICE_ADDR, 1) == 0)
101     sim_core_attach (sd, NULL,
102                      0 /*level*/,
103                      access_read_write,
104                      0 /*space ???*/,
105                      M32R_DEVICE_ADDR, M32R_DEVICE_LEN /*nr_bytes*/,
106                      0 /*modulo*/,
107                      &m32r_devices,
108                      NULL /*buffer*/);
109
110   /* Allocate core managed memory if none specified by user.
111      Use address 4 here in case the user wanted address 0 unmapped.  */
112   if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0)
113     sim_do_commandf (sd, "memory region 0,0x%lx", M32R_DEFAULT_MEM_SIZE);
114
115   /* check for/establish the reference program image */
116   if (sim_analyze_program (sd,
117                            (STATE_PROG_ARGV (sd) != NULL
118                             ? *STATE_PROG_ARGV (sd)
119                             : NULL),
120                            abfd) != SIM_RC_OK)
121     {
122       free_state (sd);
123       return 0;
124     }
125
126   /* If both cpu model and state architecture are set, ensure they're
127      compatible.  If only one is set, set the other.  If neither are set,
128      use the default model.  STATE_ARCHITECTURE is the bfd_arch_info data
129      for the selected "mach" (bfd terminology).  */
130   {
131     SIM_CPU *cpu = STATE_CPU (sd, 0);
132
133     if (! STATE_ARCHITECTURE (sd)
134         /* Only check cpu 0.  STATE_ARCHITECTURE is for that one only.  */
135         && ! CPU_MACH (cpu))
136       {
137         /* Set the default model.  */
138         const MODEL *model = sim_model_lookup (WITH_DEFAULT_MODEL);
139         sim_model_set (sd, NULL, model);
140       }
141     if (STATE_ARCHITECTURE (sd)
142         && CPU_MACH (cpu))
143       {
144         if (strcmp (STATE_ARCHITECTURE (sd)->printable_name,
145                     MACH_NAME (CPU_MACH (cpu))) != 0)
146           {
147             sim_io_eprintf (sd, "invalid model `%s' for `%s'\n",
148                             MODEL_NAME (CPU_MODEL (cpu)),
149                             STATE_ARCHITECTURE (sd)->printable_name);
150             free_state (sd);
151             return 0;
152           }
153       }
154     else if (STATE_ARCHITECTURE (sd))
155       {
156         /* Use the default model for the selected machine.
157            The default model is the first one in the list.  */
158         const MACH *mach = sim_mach_lookup (STATE_ARCHITECTURE (sd)->printable_name);
159         sim_model_set (sd, NULL, MACH_MODELS (mach));
160       }
161     else
162       {
163         STATE_ARCHITECTURE (sd) = bfd_scan_arch (MACH_NAME (CPU_MACH (cpu)));
164       }
165   }
166
167   /* Establish any remaining configuration options.  */
168   if (sim_config (sd) != SIM_RC_OK)
169     {
170       free_state (sd);
171       return 0;
172     }
173
174   if (sim_post_argv_init (sd) != SIM_RC_OK)
175     {
176       free_state (sd);
177       return 0;
178     }
179
180   /* Initialize various cgen things not done by common framework.  */
181   cgen_init (sd);
182
183   /* Open a copy of the opcode table.  */
184   STATE_OPCODE_TABLE (sd) = m32r_cgen_opcode_open (STATE_ARCHITECTURE (sd)->mach,
185                                                    CGEN_ENDIAN_BIG);
186   m32r_cgen_init_dis (STATE_OPCODE_TABLE (sd));
187
188   {
189     int c;
190
191     for (c = 0; c < MAX_NR_PROCESSORS; ++c)
192       {
193         /* Only needed for profiling, but the structure member is small.  */
194         memset (CPU_M32R_MISC_PROFILE (STATE_CPU (sd, c)), 0,
195                 sizeof (* CPU_M32R_MISC_PROFILE (STATE_CPU (sd, c))));
196         /* Hook in callback for reporting these stats */
197         PROFILE_INFO_CPU_CALLBACK (CPU_PROFILE_DATA (STATE_CPU (sd, c)))
198           = print_m32r_misc_cpu;
199       }
200   }
201
202   /* Store in a global so things like sparc32_dump_regs can be invoked
203      from the gdb command line.  */
204   current_state = sd;
205
206   return sd;
207 }
208
209 void
210 sim_close (sd, quitting)
211      SIM_DESC sd;
212      int quitting;
213 {
214   m32r_cgen_opcode_close (STATE_OPCODE_TABLE (sd));
215   sim_module_uninstall (sd);
216 }
217 \f
218 SIM_RC
219 sim_create_inferior (sd, abfd, argv, envp)
220      SIM_DESC sd;
221      struct _bfd *abfd;
222      char **argv;
223      char **envp;
224 {
225   SIM_CPU *current_cpu = STATE_CPU (sd, 0);
226   SIM_ADDR addr;
227
228   if (abfd != NULL)
229     addr = bfd_get_start_address (abfd);
230   else
231     addr = 0;
232   sim_pc_set (current_cpu, addr);
233
234 #if 0
235   STATE_ARGV (sd) = sim_copy_argv (argv);
236   STATE_ENVP (sd) = sim_copy_argv (envp);
237 #endif
238
239   return SIM_RC_OK;
240 }
241
242 /* PROFILE_CPU_CALLBACK */
243
244 static void
245 print_m32r_misc_cpu (SIM_CPU *cpu, int verbose)
246 {
247   SIM_DESC sd = CPU_STATE (cpu);
248   char buf[20];
249
250   if (CPU_PROFILE_FLAGS (cpu) [PROFILE_INSN_IDX])
251     {
252       sim_io_printf (sd, "Miscellaneous Statistics\n\n");
253       sim_io_printf (sd, "  %-*s %s\n\n",
254                      PROFILE_LABEL_WIDTH, "Fill nops:",
255                      sim_add_commas (buf, sizeof (buf),
256                                      CPU_M32R_MISC_PROFILE (cpu)->fillnop_count));
257       if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_m32rx)
258         sim_io_printf (sd, "  %-*s %s\n\n",
259                        PROFILE_LABEL_WIDTH, "Parallel insns:",
260                        sim_add_commas (buf, sizeof (buf),
261                                        CPU_M32R_MISC_PROFILE (cpu)->parallel_count));
262     }
263 }
264
265 void
266 sim_do_command (sd, cmd)
267      SIM_DESC sd;
268      char *cmd;
269
270   char **argv;
271
272   if (cmd == NULL)
273     return;
274
275   argv = buildargv (cmd);
276
277   if (argv[0] != NULL
278       && strcasecmp (argv[0], "info") == 0
279       && argv[1] != NULL
280       && strncasecmp (argv[1], "reg", 3) == 0)
281     {
282       SI val;
283
284       /* We only support printing bbpsw,bbpc here as there is no equivalent
285          functionality in gdb.  */
286       if (argv[2] == NULL)
287         sim_io_eprintf (sd, "Missing register in `%s'\n", cmd);
288       else if (argv[3] != NULL)
289         sim_io_eprintf (sd, "Too many arguments in `%s'\n", cmd);
290       else if (strcasecmp (argv[2], "bbpsw") == 0)
291         {
292           val = a_m32r_h_cr_get (STATE_CPU (sd, 0), H_CR_BBPSW);
293           sim_io_printf (sd, "bbpsw 0x%x %d\n", val, val);
294         }
295       else if (strcasecmp (argv[2], "bbpc") == 0)
296         {
297           val = a_m32r_h_cr_get (STATE_CPU (sd, 0), H_CR_BBPC);
298           sim_io_printf (sd, "bbpc 0x%x %d\n", val, val);
299         }
300       else
301         sim_io_eprintf (sd, "Printing of register `%s' not supported with `sim info'\n",
302                         argv[2]);
303     }
304   else
305     {
306       if (sim_args_command (sd, cmd) != SIM_RC_OK)
307         sim_io_eprintf (sd, "Unknown sim command `%s'\n", cmd);
308     }
309
310   freeargv (argv);
311 }