]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/v850/interp.c
Check reserved bits before executing instructions.
[thirdparty/binutils-gdb.git] / sim / v850 / interp.c
1 #include <signal.h>
2 #include "sim-main.h"
3 #include "sim-options.h"
4 #include "v850_sim.h"
5
6 #ifdef HAVE_STDLIB_H
7 #include <stdlib.h>
8 #endif
9
10 #ifdef HAVE_STRING_H
11 #include <string.h>
12 #else
13 #ifdef HAVE_STRINGS_H
14 #include <strings.h>
15 #endif
16 #endif
17
18 #include "bfd.h"
19
20 #ifndef INLINE
21 #ifdef __GNUC__
22 #define INLINE inline
23 #else
24 #define INLINE
25 #endif
26 #endif
27
28
29 /* For compatibility */
30 SIM_DESC simulator;
31
32
33
34 /* v850 interrupt model */
35
36 enum interrupt_type
37 {
38 int_reset,
39 int_nmi,
40 int_intov1,
41 int_intp10,
42 int_intp11,
43 int_intp12,
44 int_intp13,
45 int_intcm4,
46 num_int_types
47 };
48
49 char *interrupt_names[] = {
50 "reset",
51 "nmi",
52 "intov1",
53 "intp10",
54 "intp11",
55 "intp12",
56 "intp13",
57 "intcm4",
58 NULL
59 };
60
61 static void
62 do_interrupt (sd, data)
63 SIM_DESC sd;
64 void *data;
65 {
66 char **interrupt_name = (char**)data;
67 enum interrupt_type inttype;
68 inttype = (interrupt_name - STATE_WATCHPOINTS (sd)->interrupt_names);
69 /* Disable further interrupts. */
70 PSW |= PSW_ID;
71 /* Indicate that we're doing interrupt not exception processing. */
72 PSW &= ~PSW_EP;
73 if (inttype == int_reset)
74 {
75 PC = 0;
76 PSW = 0x20;
77 ECR = 0;
78 /* (Might be useful to init other regs with random values.) */
79 }
80 else if (inttype == int_nmi)
81 {
82 if (PSW & PSW_NP)
83 {
84 /* We're already working on an NMI, so this one must wait
85 around until the previous one is done. The processor
86 ignores subsequent NMIs, so we don't need to count them. */
87 State.pending_nmi = 1;
88 }
89 else
90 {
91 FEPC = PC;
92 FEPSW = PSW;
93 /* Set the FECC part of the ECR. */
94 ECR &= 0x0000ffff;
95 ECR |= 0x10;
96 PSW |= PSW_NP;
97 PC = 0x10;
98 }
99 }
100 else
101 {
102 EIPC = PC;
103 EIPSW = PSW;
104 /* Clear the EICC part of the ECR, will set below. */
105 ECR &= 0xffff0000;
106 switch (inttype)
107 {
108 case int_intov1:
109 PC = 0x80;
110 ECR |= 0x80;
111 break;
112 case int_intp10:
113 PC = 0x90;
114 ECR |= 0x90;
115 break;
116 case int_intp11:
117 PC = 0xa0;
118 ECR |= 0xa0;
119 break;
120 case int_intp12:
121 PC = 0xb0;
122 ECR |= 0xb0;
123 break;
124 case int_intp13:
125 PC = 0xc0;
126 ECR |= 0xc0;
127 break;
128 case int_intcm4:
129 PC = 0xd0;
130 ECR |= 0xd0;
131 break;
132 default:
133 /* Should never be possible. */
134 abort ();
135 break;
136 }
137 }
138 }
139
140 /* These default values correspond to expected usage for the chip. */
141
142 int v850_debug;
143
144 uint32 OP[4];
145
146 static long hash PARAMS ((long));
147 #if 0
148 static void do_format_1_2 PARAMS ((uint32));
149 static void do_format_3 PARAMS ((uint32));
150 static void do_format_4 PARAMS ((uint32));
151 static void do_format_5 PARAMS ((uint32));
152 static void do_format_6 PARAMS ((uint32));
153 static void do_format_7 PARAMS ((uint32));
154 static void do_format_8 PARAMS ((uint32));
155 static void do_format_9_10 PARAMS ((uint32));
156 #endif
157
158 #define MAX_HASH 63
159
160 struct hash_entry
161 {
162 struct hash_entry *next;
163 unsigned long opcode;
164 unsigned long mask;
165 struct simops *ops;
166 };
167
168 struct hash_entry hash_table[MAX_HASH+1];
169
170
171 static INLINE long
172 hash(insn)
173 long insn;
174 {
175 if ( (insn & 0x0600) == 0
176 || (insn & 0x0700) == 0x0200
177 || (insn & 0x0700) == 0x0600
178 || (insn & 0x0780) == 0x0700)
179 return (insn & 0x07e0) >> 5;
180
181 if ((insn & 0x0700) == 0x0300
182 || (insn & 0x0700) == 0x0400
183 || (insn & 0x0700) == 0x0500)
184 return (insn & 0x0780) >> 7;
185
186 if ((insn & 0x07c0) == 0x0780)
187 return (insn & 0x07c0) >> 6;
188
189 return (insn & 0x07e0) >> 5;
190 }
191
192 #if 0
193 static struct hash_entry *
194 lookup_hash (sd, ins)
195 SIM_DESC sd;
196 uint32 ins;
197 {
198 struct hash_entry *h;
199
200 h = &hash_table[hash(ins)];
201
202 while ((ins & h->mask) != h->opcode)
203 {
204 if (h->next == NULL)
205 {
206 sim_io_error (sd, "ERROR looking up hash for 0x%lx, PC=0x%lx",
207 (long) ins, (long) PC);
208 }
209 h = h->next;
210 }
211 return (h);
212 }
213 #endif
214
215 SIM_DESC
216 sim_open (kind, cb, abfd, argv)
217 SIM_OPEN_KIND kind;
218 host_callback *cb;
219 struct _bfd *abfd;
220 char **argv;
221 {
222 SIM_DESC sd = sim_state_alloc (kind, cb);
223 #if 0
224 struct simops *s;
225 struct hash_entry *h;
226 #endif
227
228 /* for compatibility */
229 simulator = sd;
230
231 /* FIXME: should be better way of setting up interrupts */
232 STATE_WATCHPOINTS (sd)->pc = &(PC);
233 STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
234 STATE_WATCHPOINTS (sd)->interrupt_handler = do_interrupt;
235 STATE_WATCHPOINTS (sd)->interrupt_names = interrupt_names;
236 /* start-sanitize-v850e */
237 STATE_ARCHITECTURE (sd) = bfd_lookup_arch (bfd_arch_v850, bfd_mach_v850e);
238 /* end-sanitize-v850e */
239 /* start-sanitize-v850eq */
240 STATE_ARCHITECTURE (sd) = bfd_lookup_arch (bfd_arch_v850, bfd_mach_v850eq);
241 /* end-sanitize-v850eq */
242
243 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
244 return 0;
245
246 /* Allocate core managed memory */
247
248 /* "Mirror" the ROM addresses below 1MB. */
249 sim_do_commandf (sd, "memory region 0,0x100000,0x%lx", V850_ROM_SIZE);
250 /* Chunk of ram adjacent to rom */
251 sim_do_commandf (sd, "memory region 0x100000,0x%lx", V850_LOW_END-0x100000);
252 /* peripheral I/O region - mirror 1K across 4k (0x1000) */
253 sim_do_command (sd, "memory region 0xfff000,0x1000,1024");
254 /* similarly if in the internal RAM region */
255 sim_do_command (sd, "memory region 0xffe000,0x1000,1024");
256
257 /* getopt will print the error message so we just have to exit if this fails.
258 FIXME: Hmmm... in the case of gdb we need getopt to call
259 print_filtered. */
260 if (sim_parse_args (sd, argv) != SIM_RC_OK)
261 {
262 /* Uninstall the modules to avoid memory leaks,
263 file descriptor leaks, etc. */
264 sim_module_uninstall (sd);
265 return 0;
266 }
267
268 /* check for/establish the a reference program image */
269 if (sim_analyze_program (sd,
270 (STATE_PROG_ARGV (sd) != NULL
271 ? *STATE_PROG_ARGV (sd)
272 : NULL),
273 abfd) != SIM_RC_OK)
274 {
275 sim_module_uninstall (sd);
276 return 0;
277 }
278
279 /* establish any remaining configuration options */
280 if (sim_config (sd) != SIM_RC_OK)
281 {
282 sim_module_uninstall (sd);
283 return 0;
284 }
285
286 if (sim_post_argv_init (sd) != SIM_RC_OK)
287 {
288 /* Uninstall the modules to avoid memory leaks,
289 file descriptor leaks, etc. */
290 sim_module_uninstall (sd);
291 return 0;
292 }
293
294 #if 0
295 /* put all the opcodes in the hash table */
296 for (s = Simops; s->func; s++)
297 {
298 h = &hash_table[hash(s->opcode)];
299
300 /* go to the last entry in the chain */
301 while (h->next)
302 h = h->next;
303
304 if (h->ops)
305 {
306 h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
307 h = h->next;
308 }
309 h->ops = s;
310 h->mask = s->mask;
311 h->opcode = s->opcode;
312 }
313 #endif
314
315 return sd;
316 }
317
318
319 void
320 sim_close (sd, quitting)
321 SIM_DESC sd;
322 int quitting;
323 {
324 sim_module_uninstall (sd);
325 }
326
327 int
328 sim_stop (sd)
329 SIM_DESC sd;
330 {
331 return 0;
332 }
333
334 #if 0
335 void
336 sim_engine_run (sd, next_cpu_nr, siggnal)
337 SIM_DESC sd;
338 int next_cpu_nr;
339 int siggnal;
340 {
341 uint32 inst;
342 SIM_ADDR oldpc;
343
344 while (1)
345 {
346 struct hash_entry * h;
347 /* Fetch the current instruction. */
348 inst = RLW (PC);
349 oldpc = PC;
350
351 h = lookup_hash (sd, inst);
352 OP[0] = inst & 0x1f;
353 OP[1] = (inst >> 11) & 0x1f;
354 OP[2] = (inst >> 16) & 0xffff;
355 OP[3] = inst;
356
357 /* fprintf (stderr, "PC = %x, SP = %x\n", PC, SP ); */
358
359 if (inst == 0)
360 {
361 fprintf (stderr, "NOP encountered!\n");
362 break;
363 }
364
365 PC += h->ops->func ();
366
367 if (oldpc == PC)
368 {
369 sim_io_eprintf (sd, "simulator loop at %lx\n", (long) PC );
370 break;
371 }
372
373 if (sim_events_tick (sd))
374 {
375 sim_events_process (sd);
376 }
377 }
378 }
379 #endif
380
381 #if 0
382 int
383 sim_trace (sd)
384 SIM_DESC sd;
385 {
386 #ifdef DEBUG
387 v850_debug = DEBUG;
388 #endif
389 sim_resume (sd, 0, 0);
390 return 1;
391 }
392 #endif
393
394 void
395 sim_info (sd, verbose)
396 SIM_DESC sd;
397 int verbose;
398 {
399 profile_print (sd, STATE_VERBOSE_P (sd), NULL, NULL);
400 }
401
402 SIM_RC
403 sim_create_inferior (sd, prog_bfd, argv, env)
404 SIM_DESC sd;
405 struct _bfd *prog_bfd;
406 char **argv;
407 char **env;
408 {
409 memset (&State, 0, sizeof (State));
410 if (prog_bfd != NULL)
411 PC = bfd_get_start_address (prog_bfd);
412 return SIM_RC_OK;
413 }
414
415 void
416 sim_fetch_register (sd, rn, memory)
417 SIM_DESC sd;
418 int rn;
419 unsigned char *memory;
420 {
421 *(unsigned32*)memory = H2T_4 (State.regs[rn]);
422 }
423
424 void
425 sim_store_register (sd, rn, memory)
426 SIM_DESC sd;
427 int rn;
428 unsigned char *memory;
429 {
430 State.regs[rn] = T2H_4 (*(unsigned32*)memory);
431 }
432
433 void
434 sim_do_command (sd, cmd)
435 SIM_DESC sd;
436 char *cmd;
437 {
438 char *mm_cmd = "memory-map";
439 char *int_cmd = "interrupt";
440
441 if (sim_args_command (sd, cmd) != SIM_RC_OK)
442 {
443 if (strncmp (cmd, mm_cmd, strlen (mm_cmd) == 0))
444 sim_io_eprintf (sd, "`memory-map' command replaced by `sim memory'\n");
445 else if (strncmp (cmd, int_cmd, strlen (int_cmd)) == 0)
446 sim_io_eprintf (sd, "`interrupt' command replaced by `sim watch'\n");
447 else
448 sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
449 }
450 }