* simops.c (v850_rotl): New function.
[deliverable/binutils-gdb.git] / sim / v850 / interp.c
CommitLineData
c906108c
SS
1#include "sim-main.h"
2#include "sim-options.h"
3#include "v850_sim.h"
4#include "sim-assert.h"
5#include "itable.h"
6
7#ifdef HAVE_STDLIB_H
8#include <stdlib.h>
9#endif
10
11#ifdef HAVE_STRING_H
12#include <string.h>
13#else
14#ifdef HAVE_STRINGS_H
15#include <strings.h>
16#endif
17#endif
18
19#include "bfd.h"
20
21#ifndef INLINE
22#ifdef __GNUC__
23#define INLINE inline
24#else
25#define INLINE
26#endif
27#endif
28
29static const char * get_insn_name (sim_cpu *, int);
30
31/* For compatibility */
32SIM_DESC simulator;
33
34
35
36/* v850 interrupt model */
37
38enum interrupt_type
39{
40 int_reset,
41 int_nmi,
42 int_intov1,
43 int_intp10,
44 int_intp11,
45 int_intp12,
46 int_intp13,
47 int_intcm4,
48 num_int_types
49};
50
4e9586f0 51const char *interrupt_names[] = {
c906108c
SS
52 "reset",
53 "nmi",
54 "intov1",
55 "intp10",
56 "intp11",
57 "intp12",
58 "intp13",
59 "intcm4",
60 NULL
61};
62
63static void
64do_interrupt (sd, data)
65 SIM_DESC sd;
66 void *data;
67{
4e9586f0 68 const char **interrupt_name = (const char**)data;
c906108c
SS
69 enum interrupt_type inttype;
70 inttype = (interrupt_name - STATE_WATCHPOINTS (sd)->interrupt_names);
71
72 /* For a hardware reset, drop everything and jump to the start
73 address */
74 if (inttype == int_reset)
75 {
76 PC = 0;
77 PSW = 0x20;
78 ECR = 0;
79 sim_engine_restart (sd, NULL, NULL, NULL_CIA);
80 }
81
82 /* Deliver an NMI when allowed */
83 if (inttype == int_nmi)
84 {
85 if (PSW & PSW_NP)
86 {
87 /* We're already working on an NMI, so this one must wait
88 around until the previous one is done. The processor
89 ignores subsequent NMIs, so we don't need to count them.
90 Just keep re-scheduling a single NMI until it manages to
91 be delivered */
92 if (STATE_CPU (sd, 0)->pending_nmi != NULL)
93 sim_events_deschedule (sd, STATE_CPU (sd, 0)->pending_nmi);
94 STATE_CPU (sd, 0)->pending_nmi =
95 sim_events_schedule (sd, 1, do_interrupt, data);
96 return;
97 }
98 else
99 {
100 /* NMI can be delivered. Do not deschedule pending_nmi as
101 that, if still in the event queue, is a second NMI that
102 needs to be delivered later. */
103 FEPC = PC;
104 FEPSW = PSW;
105 /* Set the FECC part of the ECR. */
106 ECR &= 0x0000ffff;
107 ECR |= 0x10;
108 PSW |= PSW_NP;
109 PSW &= ~PSW_EP;
110 PSW |= PSW_ID;
111 PC = 0x10;
112 sim_engine_restart (sd, NULL, NULL, NULL_CIA);
113 }
114 }
115
116 /* deliver maskable interrupt when allowed */
117 if (inttype > int_nmi && inttype < num_int_types)
118 {
119 if ((PSW & PSW_NP) || (PSW & PSW_ID))
120 {
121 /* Can't deliver this interrupt, reschedule it for later */
122 sim_events_schedule (sd, 1, do_interrupt, data);
123 return;
124 }
125 else
126 {
127 /* save context */
128 EIPC = PC;
129 EIPSW = PSW;
130 /* Disable further interrupts. */
131 PSW |= PSW_ID;
132 /* Indicate that we're doing interrupt not exception processing. */
133 PSW &= ~PSW_EP;
134 /* Clear the EICC part of the ECR, will set below. */
135 ECR &= 0xffff0000;
136 switch (inttype)
137 {
138 case int_intov1:
139 PC = 0x80;
140 ECR |= 0x80;
141 break;
142 case int_intp10:
143 PC = 0x90;
144 ECR |= 0x90;
145 break;
146 case int_intp11:
147 PC = 0xa0;
148 ECR |= 0xa0;
149 break;
150 case int_intp12:
151 PC = 0xb0;
152 ECR |= 0xb0;
153 break;
154 case int_intp13:
155 PC = 0xc0;
156 ECR |= 0xc0;
157 break;
158 case int_intcm4:
159 PC = 0xd0;
160 ECR |= 0xd0;
161 break;
162 default:
163 /* Should never be possible. */
164 sim_engine_abort (sd, NULL, NULL_CIA,
165 "do_interrupt - internal error - bad switch");
166 break;
167 }
168 }
169 sim_engine_restart (sd, NULL, NULL, NULL_CIA);
170 }
171
172 /* some other interrupt? */
173 sim_engine_abort (sd, NULL, NULL_CIA,
174 "do_interrupt - internal error - interrupt %d unknown",
175 inttype);
176}
177
178/* Return name of an insn, used by insn profiling. */
179
180static const char *
181get_insn_name (sim_cpu *cpu, int i)
182{
183 return itable[i].name;
184}
185
186/* These default values correspond to expected usage for the chip. */
187
188uint32 OP[4];
189
190
191SIM_DESC
192sim_open (kind, cb, abfd, argv)
193 SIM_OPEN_KIND kind;
194 host_callback *cb;
6b4a8935 195 struct bfd *abfd;
c906108c
SS
196 char **argv;
197{
198 SIM_DESC sd = sim_state_alloc (kind, cb);
199 int mach;
200
201 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
202
203 /* for compatibility */
204 simulator = sd;
205
206 /* FIXME: should be better way of setting up interrupts */
207 STATE_WATCHPOINTS (sd)->pc = &(PC);
208 STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
209 STATE_WATCHPOINTS (sd)->interrupt_handler = do_interrupt;
210 STATE_WATCHPOINTS (sd)->interrupt_names = interrupt_names;
211
212 /* Initialize the mechanism for doing insn profiling. */
213 CPU_INSN_NAME (STATE_CPU (sd, 0)) = get_insn_name;
214 CPU_MAX_INSNS (STATE_CPU (sd, 0)) = nr_itable_entries;
215
216 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
217 return 0;
218
219 /* Allocate core managed memory */
220
221 /* "Mirror" the ROM addresses below 1MB. */
222 sim_do_commandf (sd, "memory region 0,0x100000,0x%lx", V850_ROM_SIZE);
223 /* Chunk of ram adjacent to rom */
224 sim_do_commandf (sd, "memory region 0x100000,0x%lx", V850_LOW_END-0x100000);
225 /* peripheral I/O region - mirror 1K across 4k (0x1000) */
226 sim_do_command (sd, "memory region 0xfff000,0x1000,1024");
227 /* similarly if in the internal RAM region */
228 sim_do_command (sd, "memory region 0xffe000,0x1000,1024");
229
230 /* getopt will print the error message so we just have to exit if this fails.
231 FIXME: Hmmm... in the case of gdb we need getopt to call
232 print_filtered. */
233 if (sim_parse_args (sd, argv) != SIM_RC_OK)
234 {
235 /* Uninstall the modules to avoid memory leaks,
236 file descriptor leaks, etc. */
237 sim_module_uninstall (sd);
238 return 0;
239 }
240
241 /* check for/establish the a reference program image */
242 if (sim_analyze_program (sd,
243 (STATE_PROG_ARGV (sd) != NULL
244 ? *STATE_PROG_ARGV (sd)
245 : NULL),
246 abfd) != SIM_RC_OK)
247 {
248 sim_module_uninstall (sd);
249 return 0;
250 }
251
252 /* establish any remaining configuration options */
253 if (sim_config (sd) != SIM_RC_OK)
254 {
255 sim_module_uninstall (sd);
256 return 0;
257 }
258
259 if (sim_post_argv_init (sd) != SIM_RC_OK)
260 {
261 /* Uninstall the modules to avoid memory leaks,
262 file descriptor leaks, etc. */
263 sim_module_uninstall (sd);
264 return 0;
265 }
266
267
268 /* determine the machine type */
269 if (STATE_ARCHITECTURE (sd) != NULL
85367826
NC
270 && (STATE_ARCHITECTURE (sd)->arch == bfd_arch_v850
271 || STATE_ARCHITECTURE (sd)->arch == bfd_arch_v850_rh850))
c906108c
SS
272 mach = STATE_ARCHITECTURE (sd)->mach;
273 else
274 mach = bfd_mach_v850; /* default */
275
276 /* set machine specific configuration */
277 switch (mach)
278 {
279 case bfd_mach_v850:
280 case bfd_mach_v850e:
c5ea1d53 281 case bfd_mach_v850e1:
85367826
NC
282 case bfd_mach_v850e2:
283 case bfd_mach_v850e2v3:
67d7515b 284 case bfd_mach_v850e3v5:
c906108c
SS
285 STATE_CPU (sd, 0)->psw_mask = (PSW_NP | PSW_EP | PSW_ID | PSW_SAT
286 | PSW_CY | PSW_OV | PSW_S | PSW_Z);
287 break;
c906108c
SS
288 }
289
290 return sd;
291}
292
293
294void
295sim_close (sd, quitting)
296 SIM_DESC sd;
297 int quitting;
298{
299 sim_module_uninstall (sd);
300}
301
302SIM_RC
303sim_create_inferior (sd, prog_bfd, argv, env)
304 SIM_DESC sd;
6b4a8935 305 struct bfd *prog_bfd;
c906108c
SS
306 char **argv;
307 char **env;
308{
309 memset (&State, 0, sizeof (State));
310 if (prog_bfd != NULL)
311 PC = bfd_get_start_address (prog_bfd);
c906108c
SS
312 return SIM_RC_OK;
313}
314
315int
316sim_fetch_register (sd, rn, memory, length)
317 SIM_DESC sd;
318 int rn;
319 unsigned char *memory;
320 int length;
321{
322 *(unsigned32*)memory = H2T_4 (State.regs[rn]);
323 return -1;
324}
325
326int
327sim_store_register (sd, rn, memory, length)
328 SIM_DESC sd;
329 int rn;
330 unsigned char *memory;
331 int length;
332{
333 State.regs[rn] = T2H_4 (*(unsigned32*)memory);
dae477fe 334 return length;
c906108c 335}
This page took 0.649376 seconds and 4 git commands to generate.