update copyright year range in GDB files
[external/binutils.git] / sim / sh64 / sim-if.c
1 /* Main simulator entry points specific to the SH5.
2    Copyright (C) 2000-2017 Free Software Foundation, Inc.
3    Contributed by Cygnus Solutions.
4
5 This file is part of the GNU simulators.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #include "config.h"
21 #include "libiberty.h"
22 #include "bfd.h"
23 #include "sim-main.h"
24 #ifdef HAVE_STDLIB_H
25 #include <stdlib.h>
26 #endif
27 #include "sim-options.h"
28 #include "dis-asm.h"
29
30 static void free_state (SIM_DESC);
31
32 /* Since we don't build the cgen-opcode table, we use a wrapper around
33    the existing disassembler from libopcodes. */
34 static CGEN_DISASSEMBLER sh64_disassemble_insn;
35 \f
36 /* Cover function of sim_state_free to free the cpu buffers as well.  */
37
38 static void
39 free_state (SIM_DESC sd)
40 {
41   if (STATE_MODULES (sd) != NULL)
42     sim_module_uninstall (sd);
43   sim_cpu_free_all (sd);
44   sim_state_free (sd);
45 }
46
47 /* Create an instance of the simulator.  */
48
49 SIM_DESC
50 sim_open (kind, callback, abfd, argv)
51      SIM_OPEN_KIND kind;
52      host_callback *callback;
53      struct bfd *abfd;
54      char * const *argv;
55 {
56   char c;
57   int i;
58   SIM_DESC sd = sim_state_alloc (kind, callback);
59
60   /* The cpu data is kept in a separately allocated chunk of memory.  */
61   if (sim_cpu_alloc_all (sd, 1, cgen_cpu_max_extra_bytes ()) != SIM_RC_OK)
62     {
63       free_state (sd);
64       return 0;
65     }
66
67 #if 0 /* FIXME: pc is in mach-specific struct */
68   /* FIXME: watchpoints code shouldn't need this */
69   {
70     SIM_CPU *current_cpu = STATE_CPU (sd, 0);
71     STATE_WATCHPOINTS (sd)->pc = &(PC);
72     STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
73   }
74 #endif
75
76   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
77     {
78       free_state (sd);
79       return 0;
80     }
81
82   /* The parser will print an error message for us, so we silently return.  */
83   if (sim_parse_args (sd, argv) != SIM_RC_OK)
84     {
85       free_state (sd);
86       return 0;
87     }
88
89   /* Allocate core managed memory if none specified by user.
90      Use address 4 here in case the user wanted address 0 unmapped.  */
91   if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0)
92     sim_do_commandf (sd, "memory region 0,0x%x", SH64_DEFAULT_MEM_SIZE);
93
94   /* Add a small memory region way up in the address space to handle
95      writes to invalidate an instruction cache line.  This is used for
96      trampolines.  Since we don't simulate the cache, this memory just
97      avoids bus errors.  64K ought to do. */
98   sim_do_command (sd," memory region 0xf0000000,0x10000");
99
100   /* check for/establish the reference program image */
101   if (sim_analyze_program (sd,
102                            (STATE_PROG_ARGV (sd) != NULL
103                             ? *STATE_PROG_ARGV (sd)
104                             : NULL),
105                            abfd) != SIM_RC_OK)
106     {
107       free_state (sd);
108       return 0;
109     }
110
111   /* Establish any remaining configuration options.  */
112   if (sim_config (sd) != SIM_RC_OK)
113     {
114       free_state (sd);
115       return 0;
116     }
117
118   if (sim_post_argv_init (sd) != SIM_RC_OK)
119     {
120       free_state (sd);
121       return 0;
122     }
123
124   /* Open a copy of the cpu descriptor table.  */
125   {
126     CGEN_CPU_DESC cd = sh_cgen_cpu_open_1 (STATE_ARCHITECTURE (sd)->printable_name,
127                                               CGEN_ENDIAN_BIG);
128
129     for (i = 0; i < MAX_NR_PROCESSORS; ++i)
130       {
131         SIM_CPU *cpu = STATE_CPU (sd, i);
132         CPU_CPU_DESC (cpu) = cd;
133         CPU_DISASSEMBLER (cpu) = sh64_disassemble_insn;
134       }
135   }
136
137   /* Clear idesc table pointers for good measure. */
138   sh64_idesc_media = sh64_idesc_compact = NULL;
139
140   /* Initialize various cgen things not done by common framework.
141      Must be done after sh_cgen_cpu_open.  */
142   cgen_init (sd);
143
144   return sd;
145 }
146 \f
147 SIM_RC
148 sim_create_inferior (sd, abfd, argv, envp)
149      SIM_DESC sd;
150      struct bfd *abfd;
151      char * const *argv;
152      char * const *envp;
153 {
154   SIM_CPU *current_cpu = STATE_CPU (sd, 0);
155   SIM_ADDR addr;
156
157   if (abfd != NULL)
158     addr = bfd_get_start_address (abfd);
159   else
160     addr = 0;
161   sim_pc_set (current_cpu, addr);
162
163   /* Standalone mode (i.e. `run`) will take care of the argv for us in
164      sim_open() -> sim_parse_args().  But in debug mode (i.e. 'target sim'
165      with `gdb`), we need to handle it because the user can change the
166      argv on the fly via gdb's 'run'.  */
167   if (STATE_PROG_ARGV (sd) != argv)
168     {
169       freeargv (STATE_PROG_ARGV (sd));
170       STATE_PROG_ARGV (sd) = dupargv (argv);
171     }
172
173   return SIM_RC_OK;
174 }
175 \f
176 /* Disassemble an instruction.  */
177
178 static void
179 sh64_disassemble_insn (SIM_CPU *cpu, const CGEN_INSN *insn,
180                        const ARGBUF *abuf, IADDR pc, char *buf)
181 {
182   struct disassemble_info disasm_info;
183   SFILE sfile;
184   SIM_DESC sd = CPU_STATE (cpu);
185
186   sfile.buffer = sfile.current = buf;
187   INIT_DISASSEMBLE_INFO (disasm_info, (FILE *) &sfile,
188                          (fprintf_ftype) sim_disasm_sprintf);
189
190   disasm_info.arch = bfd_get_arch (STATE_PROG_BFD (sd));
191   disasm_info.mach = bfd_get_mach (STATE_PROG_BFD (sd));
192   disasm_info.endian =
193     (bfd_big_endian (STATE_PROG_BFD (sd)) ? BFD_ENDIAN_BIG
194      : bfd_little_endian (STATE_PROG_BFD (sd)) ? BFD_ENDIAN_LITTLE
195      : BFD_ENDIAN_UNKNOWN);
196   disasm_info.read_memory_func = sim_disasm_read_memory;
197   disasm_info.memory_error_func = sim_disasm_perror_memory;
198   disasm_info.application_data = (PTR) cpu;
199
200   if (sh64_h_ism_get (cpu) == ISM_MEDIA)
201     print_insn_sh64x_media (pc, &disasm_info);
202   else
203     print_insn_sh (pc, &disasm_info);
204 }