Add new Java files.
[deliverable/binutils-gdb.git] / sim / v850 / interp.c
CommitLineData
22c1c7dd
JL
1#include <signal.h>
2#include "sysdep.h"
3#include "bfd.h"
22c1c7dd
JL
4
5#include "v850_sim.h"
6
1ad886c9
DE
7enum interrupt_type
8{
9 int_none,
10 int_reset,
11 int_nmi,
12 int_intov1,
13 int_intp10,
14 int_intp11,
15 int_intp12,
16 int_intp13,
17 int_intcm4,
18 num_int_types
19};
20
21enum interrupt_cond_type
22{
23 int_cond_none,
24 int_cond_pc,
25 int_cond_time
26};
27
28struct interrupt_generator
29{
30 enum interrupt_type type;
31 enum interrupt_cond_type cond_type;
32 int number;
33 int address;
34 int time;
35 int enabled;
36 struct interrupt_generator *next;
37};
38
39char *interrupt_names[] = {
40 "",
41 "reset",
42 "nmi",
43 "intov1",
44 "intp10",
45 "intp11",
46 "intp12",
47 "intp13",
48 "intcm4",
49 NULL
50};
51
52struct interrupt_generator *intgen_list;
53
54/* True if a non-maskable (such as NMI or reset) interrupt generator
55 is present. */
56
57static int have_nm_generator;
58
9909e232
JL
59#ifndef INLINE
60#ifdef __GNUC__
61#define INLINE inline
62#else
63#define INLINE
64#endif
65#endif
66
1ad886c9
DE
67/* These default values correspond to expected usage for the chip. */
68
69SIM_ADDR rom_size = 0x8000;
70SIM_ADDR low_end = 0x200000;
71SIM_ADDR high_start = 0xffe000;
72
73SIM_ADDR high_base;
22c1c7dd 74
d81352b8 75host_callback *v850_callback;
1ad886c9 76
ead4a3f1 77int v850_debug;
d81352b8 78
1ad886c9
DE
79static SIM_OPEN_KIND sim_kind;
80static char *myname;
d81352b8
JL
81
82uint32 OP[4];
22c1c7dd
JL
83
84static struct hash_entry *lookup_hash PARAMS ((uint32 ins));
9909e232
JL
85static long hash PARAMS ((long));
86static void do_format_1_2 PARAMS ((uint32));
87static void do_format_3 PARAMS ((uint32));
88static void do_format_4 PARAMS ((uint32));
89static void do_format_5 PARAMS ((uint32));
90static void do_format_6 PARAMS ((uint32));
91static void do_format_7 PARAMS ((uint32));
92static void do_format_8 PARAMS ((uint32));
93static void do_format_9_10 PARAMS ((uint32));
94static void init_system PARAMS ((void));
22c1c7dd
JL
95
96#define MAX_HASH 63
1ad886c9 97
22c1c7dd
JL
98struct hash_entry
99{
100 struct hash_entry *next;
101 long opcode;
102 long mask;
103 struct simops *ops;
104};
105
106struct hash_entry hash_table[MAX_HASH+1];
107
9909e232
JL
108
109static INLINE long
22c1c7dd
JL
110hash(insn)
111 long insn;
112{
83fc3bac 113 if ((insn & 0x0600) == 0
9909e232
JL
114 || (insn & 0x0700) == 0x0200
115 || (insn & 0x0700) == 0x0600
116 || (insn & 0x0780) == 0x0700)
0ef0eba5 117 return (insn & 0x07e0) >> 5;
1ad886c9 118
83fc3bac
JL
119 if ((insn & 0x0700) == 0x0300
120 || (insn & 0x0700) == 0x0400
121 || (insn & 0x0700) == 0x0500)
122 return (insn & 0x0780) >> 7;
1ad886c9 123
83fc3bac 124 if ((insn & 0x07c0) == 0x0780)
0ef0eba5 125 return (insn & 0x07c0) >> 6;
1ad886c9 126
83fc3bac 127 return (insn & 0x07e0) >> 5;
22c1c7dd
JL
128}
129
130static struct hash_entry *
131lookup_hash (ins)
132 uint32 ins;
133{
134 struct hash_entry *h;
135
0ef0eba5 136 h = &hash_table[hash(ins)];
22c1c7dd 137
9909e232 138 while ((ins & h->mask) != h->opcode)
22c1c7dd
JL
139 {
140 if (h->next == NULL)
141 {
1ad886c9 142 (*v850_callback->printf_filtered) (v850_callback, "ERROR looking up hash for 0x%x, PC=0x%x\n", ins, PC);
22c1c7dd
JL
143 exit(1);
144 }
145 h = h->next;
146 }
147 return (h);
148}
149
1ad886c9
DE
150/* FIXME These would more efficient to use than load_mem/store_mem,
151 but need to be changed to use the memory map. */
152
28647e4c
JL
153uint8
154get_byte (x)
155 uint8 *x;
22c1c7dd 156{
28647e4c 157 return *x;
0ef0eba5
JL
158}
159
28647e4c
JL
160uint16
161get_half (x)
162 uint8 *x;
0ef0eba5
JL
163{
164 uint8 *a = x;
28647e4c 165 return (a[1] << 8) + (a[0]);
22c1c7dd
JL
166}
167
28647e4c 168uint32
0ef0eba5
JL
169get_word (x)
170 uint8 *x;
22c1c7dd 171{
0ef0eba5 172 uint8 *a = x;
28647e4c 173 return (a[3]<<24) + (a[2]<<16) + (a[1]<<8) + (a[0]);
22c1c7dd
JL
174}
175
176void
28647e4c 177put_byte (addr, data)
0ef0eba5 178 uint8 *addr;
28647e4c 179 uint8 data;
22c1c7dd 180{
0ef0eba5 181 uint8 *a = addr;
28647e4c 182 a[0] = data;
22c1c7dd
JL
183}
184
0ef0eba5 185void
28647e4c 186put_half (addr, data)
0ef0eba5 187 uint8 *addr;
28647e4c 188 uint16 data;
0ef0eba5 189{
28647e4c
JL
190 uint8 *a = addr;
191 a[0] = data & 0xff;
192 a[1] = (data >> 8) & 0xff;
0ef0eba5
JL
193}
194
195void
28647e4c 196put_word (addr, data)
0ef0eba5 197 uint8 *addr;
28647e4c 198 uint32 data;
0ef0eba5
JL
199{
200 uint8 *a = addr;
28647e4c
JL
201 a[0] = data & 0xff;
202 a[1] = (data >> 8) & 0xff;
203 a[2] = (data >> 16) & 0xff;
204 a[3] = (data >> 24) & 0xff;
22c1c7dd
JL
205}
206
1ad886c9
DE
207uint8 *
208map (addr)
209 SIM_ADDR addr;
210{
211 uint8 *p;
212
213 /* Mask down to 24 bits. */
214 addr &= 0xffffff;
215
216 if (addr < low_end)
217 {
218 /* "Mirror" the addresses below 1MB. */
219 if (addr < 0x100000)
220 addr &= (rom_size - 1);
221 else
222 addr += (rom_size - 0x100000);
223 return (uint8 *) (addr + State.mem);
224 }
225 else if (addr >= high_start)
226 {
227 /* If in the peripheral I/O region, mirror 1K region across 4K,
228 and similarly if in the internal RAM region. */
229 if (addr >= 0xfff000)
230 addr &= 0xfff3ff;
231 else if (addr >= 0xffe000)
232 addr &= 0xffe3ff;
233 return (uint8 *) (addr - high_start + high_base + State.mem);
234 }
235 else
236 {
237 /* Signal a memory error. */
238 State.exception = SIGSEGV;
239 /* Point to a location not in main memory - renders invalid
240 addresses harmless until we get back to main insn loop. */
241 return (uint8 *) &(State.dummy_mem);
242 }
243}
244
245uint32
246load_mem (addr, len)
247 SIM_ADDR addr;
248 int len;
249{
250 uint8 *p = map (addr);
251
252 switch (len)
253 {
254 case 1:
255 return p[0];
256 case 2:
257 return p[1] << 8 | p[0];
258 case 4:
259 return p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0];
260 default:
261 abort ();
262 }
263}
264
265void
266store_mem (addr, len, data)
267 SIM_ADDR addr;
268 int len;
269 uint32 data;
270{
271 uint8 *p = map (addr);
272
273 switch (len)
274 {
275 case 1:
276 p[0] = data;
277 return;
278 case 2:
279 p[0] = data;
280 p[1] = data >> 8;
281 return;
282 case 4:
283 p[0] = data;
284 p[1] = data >> 8;
285 p[2] = data >> 16;
286 p[3] = data >> 24;
287 return;
288 default:
289 abort ();
290 }
291}
292
22c1c7dd 293static void
0ef0eba5 294do_format_1_2 (insn)
22c1c7dd
JL
295 uint32 insn;
296{
0ef0eba5 297 struct hash_entry *h;
0ef0eba5
JL
298
299 h = lookup_hash (insn);
300 OP[0] = insn & 0x1f;
301 OP[1] = (insn >> 11) & 0x1f;
302 (h->ops->func) ();
22c1c7dd
JL
303}
304
305static void
306do_format_3 (insn)
307 uint32 insn;
308{
2108e864 309 struct hash_entry *h;
2108e864
JL
310
311 h = lookup_hash (insn);
312 OP[0] = (((insn & 0x70) >> 4) | ((insn & 0xf800) >> 8)) << 1;
313 (h->ops->func) ();
22c1c7dd
JL
314}
315
316static void
317do_format_4 (insn)
318 uint32 insn;
319{
3cb6bf78 320 struct hash_entry *h;
3cb6bf78
JL
321
322 h = lookup_hash (insn);
323 OP[0] = (insn >> 11) & 0x1f;
324 OP[1] = (insn & 0x7f);
325 (h->ops->func) ();
22c1c7dd
JL
326}
327
328static void
329do_format_5 (insn)
330 uint32 insn;
331{
e9b6cbac 332 struct hash_entry *h;
e9b6cbac
JL
333
334 h = lookup_hash (insn);
d81352b8 335 OP[0] = (((insn & 0x3f) << 15) | ((insn >> 17) & 0x7fff)) << 1;
e9b6cbac
JL
336 OP[1] = (insn >> 11) & 0x1f;
337 (h->ops->func) ();
22c1c7dd
JL
338}
339
340static void
341do_format_6 (insn)
342 uint32 insn;
343{
0ef0eba5 344 struct hash_entry *h;
0ef0eba5
JL
345
346 h = lookup_hash (insn);
347 OP[0] = (insn >> 16) & 0xffff;
348 OP[1] = insn & 0x1f;
349 OP[2] = (insn >> 11) & 0x1f;
350 (h->ops->func) ();
22c1c7dd
JL
351}
352
353static void
354do_format_7 (insn)
355 uint32 insn;
356{
28647e4c 357 struct hash_entry *h;
28647e4c
JL
358
359 h = lookup_hash (insn);
360 OP[0] = insn & 0x1f;
361 OP[1] = (insn >> 11) & 0x1f;
362 OP[2] = (insn >> 16) & 0xffff;
363 (h->ops->func) ();
22c1c7dd
JL
364}
365
366static void
367do_format_8 (insn)
368 uint32 insn;
369{
83fc3bac 370 struct hash_entry *h;
83fc3bac
JL
371
372 h = lookup_hash (insn);
373 OP[0] = insn & 0x1f;
374 OP[1] = (insn >> 11) & 0x7;
375 OP[2] = (insn >> 16) & 0xffff;
376 (h->ops->func) ();
22c1c7dd
JL
377}
378
379static void
9909e232 380do_format_9_10 (insn)
22c1c7dd
JL
381 uint32 insn;
382{
0ef0eba5 383 struct hash_entry *h;
0ef0eba5
JL
384
385 h = lookup_hash (insn);
386 OP[0] = insn & 0x1f;
387 OP[1] = (insn >> 11) & 0x1f;
388 (h->ops->func) ();
22c1c7dd
JL
389}
390
391void
392sim_size (power)
393 int power;
394
395{
1ad886c9
DE
396 int totsize;
397
28647e4c 398 if (State.mem)
1ad886c9
DE
399 free (State.mem);
400
401 totsize = rom_size + (low_end - 0x100000) + (0x1000000 - high_start);
402
403 high_base = rom_size + (low_end - 0x100000);
404
405 State.mem = (uint8 *) calloc (1, totsize);
406 if (!State.mem)
22c1c7dd 407 {
1ad886c9
DE
408 (*v850_callback->printf_filtered) (v850_callback, "Allocation of main memory failed.\n");
409 exit (1);
22c1c7dd 410 }
1ad886c9 411}
22c1c7dd 412
1ad886c9
DE
413void
414sim_set_memory_map (spec)
415 char *spec;
416{
417 char *reststr, *nreststr;
418 SIM_ADDR new_low_end, new_high_start;
419
420 new_low_end = low_end;
421 new_high_start = high_start;
422 if (! strncmp (spec, "hole=", 5))
22c1c7dd 423 {
1ad886c9
DE
424 new_low_end = sim_parse_number (spec + 5, &reststr);
425 if (new_low_end < 0x100000)
426 {
427 (*v850_callback->printf_filtered) (v850_callback,
428 "Low end must be at least 0x100000\n");
429 return;
430 }
431 if (*reststr == ',')
432 {
433 ++reststr;
434 new_high_start = sim_parse_number (reststr, &nreststr);
435 /* FIXME Check high_start also */
436 }
437 (*v850_callback->printf_filtered) (v850_callback,
438 "Hole goes from 0x%x to 0x%x\n",
439 new_low_end, new_high_start);
440 }
441 else
442 {
443 (*v850_callback->printf_filtered) (v850_callback, "Invalid specification for memory map, must be `hole=<m>[,<n>]'\n");
444 }
445
446 if (new_low_end != low_end || new_high_start != high_start)
447 {
448 low_end = new_low_end;
449 high_start = new_high_start;
450 if (State.mem)
451 {
452 (*v850_callback->printf_filtered) (v850_callback, "Reconfiguring memory (old contents will be lost)\n");
453 sim_size (1);
454 }
22c1c7dd 455 }
22c1c7dd
JL
456}
457
1ad886c9
DE
458/* Parse a number in hex, octal, or decimal form. */
459
460int
461sim_parse_number (str, rest)
462 char *str, **rest;
463{
464 if (str[0] == '0' && str[1] == 'x')
465 return strtol (str, rest, 16);
466 else if (str[0] == '0')
467 return strtol (str, rest, 16);
468 else
469 return strtol (str, rest, 10);
470}
471
22c1c7dd
JL
472static void
473init_system ()
474{
28647e4c 475 if (!State.mem)
22c1c7dd
JL
476 sim_size(1);
477}
478
479int
1ad886c9
DE
480sim_write (sd, addr, buffer, size)
481 SIM_DESC sd;
22c1c7dd
JL
482 SIM_ADDR addr;
483 unsigned char *buffer;
484 int size;
485{
486 int i;
1ad886c9 487
22c1c7dd
JL
488 init_system ();
489
22c1c7dd 490 for (i = 0; i < size; i++)
1ad886c9
DE
491 store_mem (addr + i, 1, buffer[i]);
492
22c1c7dd
JL
493 return size;
494}
495
1ad886c9
DE
496SIM_DESC
497sim_open (kind,argv)
498 SIM_OPEN_KIND kind;
499 char **argv;
22c1c7dd
JL
500{
501 struct simops *s;
9909e232 502 struct hash_entry *h;
1ad886c9
DE
503 char **p;
504
505 sim_kind = kind;
506 myname = argv[0];
507
508 for (p = argv + 1; *p; ++p)
ead4a3f1 509 {
1ad886c9
DE
510 if (strcmp (*p, "-E") == 0)
511 ++p; /* ignore endian spec */
512 else
ead4a3f1 513#ifdef DEBUG
1ad886c9 514 if (strcmp (*p, "-t") == 0)
88777ce2 515 v850_debug = DEBUG;
ead4a3f1
MM
516 else
517#endif
1ad886c9 518 (*v850_callback->printf_filtered) (v850_callback, "ERROR: unsupported option(s): %s\n",*p);
ead4a3f1 519 }
22c1c7dd
JL
520
521 /* put all the opcodes in the hash table */
522 for (s = Simops; s->func; s++)
523 {
524 h = &hash_table[hash(s->opcode)];
525
526 /* go to the last entry in the chain */
527 while (h->next)
528 h = h->next;
529
530 if (h->ops)
531 {
1ad886c9 532 h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
22c1c7dd
JL
533 h = h->next;
534 }
535 h->ops = s;
536 h->mask = s->mask;
537 h->opcode = s->opcode;
538 }
1ad886c9
DE
539
540 /* fudge our descriptor for now */
541 return (SIM_DESC) 1;
22c1c7dd
JL
542}
543
544
545void
1ad886c9
DE
546sim_close (sd, quitting)
547 SIM_DESC sd;
22c1c7dd
JL
548 int quitting;
549{
550 /* nothing to do */
551}
552
553void
554sim_set_profile (n)
555 int n;
556{
ead4a3f1 557 (*v850_callback->printf_filtered) (v850_callback, "sim_set_profile %d\n", n);
22c1c7dd
JL
558}
559
560void
561sim_set_profile_size (n)
562 int n;
563{
ead4a3f1 564 (*v850_callback->printf_filtered) (v850_callback, "sim_set_profile_size %d\n", n);
22c1c7dd
JL
565}
566
1ad886c9
DE
567time_t start_time;
568
569static void do_interrupt PARAMS ((enum interrupt_type));
570
22c1c7dd 571void
1ad886c9
DE
572sim_resume (sd, step, siggnal)
573 SIM_DESC sd;
22c1c7dd
JL
574 int step, siggnal;
575{
576 uint32 inst, opcode;
22c1c7dd 577 reg_t oldpc;
1ad886c9
DE
578 struct interrupt_generator *intgen;
579 time_t now;
22c1c7dd 580
1ad886c9
DE
581 if (step)
582 State.exception = SIGTRAP;
583 else
584 State.exception = 0;
88777ce2 585
1ad886c9
DE
586 time (&start_time);
587
588 do
589 {
590 /* Fetch the current instruction. */
591 inst = RLW (PC);
592 oldpc = PC;
593 opcode = (inst & 0x07e0) >> 5;
594
595 /* Decode the opcode field. */
596 if ((opcode & 0x30) == 0
597 || (opcode & 0x38) == 0x10)
598 {
599 do_format_1_2 (inst & 0xffff);
600 PC += 2;
601 }
602 else if ((opcode & 0x3C) == 0x18
603 || (opcode & 0x3C) == 0x1C
604 || (opcode & 0x3C) == 0x20
605 || (opcode & 0x3C) == 0x24
606 || (opcode & 0x3C) == 0x28)
607 {
608 do_format_4 (inst & 0xffff);
609 PC += 2;
610 }
611 else if ((opcode & 0x3C) == 0x2C)
612 {
613 do_format_3 (inst & 0xffff);
614 /* No PC update, it's done in the instruction. */
615 }
616 else if ((opcode & 0x38) == 0x30)
617 {
618 do_format_6 (inst);
619 PC += 4;
620 }
621 else if ((opcode & 0x3C) == 0x38)
622 {
623 do_format_7 (inst);
624 PC += 4;
625 }
626 else if ((opcode & 0x3E) == 0x3C)
627 {
628 do_format_5 (inst);
629 /* No PC update, it's done in the instruction. */
630 }
631 else if ((opcode & 0x3F) == 0x3E)
632 {
633 do_format_8 (inst);
634 PC += 4;
635 }
636 else
637 {
638 do_format_9_10 (inst);
639 PC += 4;
640 }
641
642 /* Check for and handle pending interrupts. */
643 if (intgen_list && (have_nm_generator || !(PSW & PSW_ID)))
644 {
645 intgen = NULL;
646 for (intgen = intgen_list; intgen != NULL; intgen = intgen->next)
647 {
648 if (intgen->cond_type == int_cond_pc
649 && oldpc == intgen->address
650 && intgen->enabled)
651 {
652 break;
653 }
654 else if (intgen->cond_type == int_cond_time
655 && intgen->enabled)
656 {
657 time (&now);
658 if (((long) now - (long) start_time) > intgen->time)
659 {
660 intgen->enabled = 0;
661 break;
662 }
663 }
664 }
665 if (intgen)
666 do_interrupt (intgen->type);
667 }
668 else if (State.pending_nmi)
669 {
670 State.pending_nmi = 0;
671 do_interrupt (int_nmi);
672 }
673 }
674 while (!State.exception);
675}
676
677static void
678do_interrupt (inttype)
679 enum interrupt_type inttype;
680{
681 /* Disable further interrupts. */
682 PSW |= PSW_ID;
683 /* Indicate that we're doing interrupt not exception processing. */
684 PSW &= ~PSW_EP;
685 if (inttype == int_reset)
686 {
687 PC = 0;
688 PSW = 0x20;
689 ECR = 0;
690 /* (Might be useful to init other regs with random values.) */
691 }
692 else if (inttype == int_nmi)
693 {
694 if (PSW & PSW_NP)
695 {
696 /* We're already working on an NMI, so this one must wait
697 around until the previous one is done. The processor
698 ignores subsequent NMIs, so we don't need to count them. */
699 State.pending_nmi = 1;
700 }
701 else
702 {
703 FEPC = PC;
704 FEPSW = PSW;
705 /* Set the FECC part of the ECR. */
706 ECR &= 0x0000ffff;
707 ECR |= 0x10;
708 PSW |= PSW_NP;
709 PC = 0x10;
710 }
711 }
712 else
713 {
714 EIPC = PC;
715 EIPSW = PSW;
716 /* Clear the EICC part of the ECR, will set below. */
717 ECR &= 0xffff0000;
718 switch (inttype)
719 {
720 case int_intov1:
721 PC = 0x80;
722 ECR |= 0x80;
723 break;
724 case int_intp10:
725 PC = 0x90;
726 ECR |= 0x90;
727 break;
728 case int_intp11:
729 PC = 0xa0;
730 ECR |= 0xa0;
731 break;
732 case int_intp12:
733 PC = 0xb0;
734 ECR |= 0xb0;
735 break;
736 case int_intp13:
737 PC = 0xc0;
738 ECR |= 0xc0;
739 break;
740 case int_intcm4:
741 PC = 0xd0;
742 ECR |= 0xd0;
743 break;
744 default:
745 /* Should never be possible. */
746 abort ();
747 break;
748 }
749 }
22c1c7dd
JL
750}
751
752int
1ad886c9
DE
753sim_trace (sd)
754 SIM_DESC sd;
22c1c7dd 755{
ead4a3f1
MM
756#ifdef DEBUG
757 v850_debug = DEBUG;
758#endif
1ad886c9 759 sim_resume (sd, 0, 0);
ead4a3f1 760 return 1;
22c1c7dd
JL
761}
762
763void
1ad886c9
DE
764sim_info (sd, verbose)
765 SIM_DESC sd;
22c1c7dd
JL
766 int verbose;
767{
ead4a3f1 768 (*v850_callback->printf_filtered) (v850_callback, "sim_info\n");
22c1c7dd
JL
769}
770
1ad886c9
DE
771SIM_RC
772sim_create_inferior (sd, argv, env)
773 SIM_DESC sd;
22c1c7dd
JL
774 char **argv;
775 char **env;
776{
1ad886c9 777 return SIM_RC_OK;
22c1c7dd
JL
778}
779
22c1c7dd 780void
1ad886c9
DE
781sim_kill (sd)
782 SIM_DESC sd;
22c1c7dd
JL
783{
784 /* nothing to do */
785}
786
787void
1ad886c9
DE
788sim_set_callbacks (sd, p)
789 SIM_DESC sd;
22c1c7dd
JL
790 host_callback *p;
791{
d81352b8 792 v850_callback = p;
22c1c7dd
JL
793}
794
2b6b2c6d 795/* All the code for exiting, signals, etc needs to be revamped.
d81352b8
JL
796
797 This is enough to get c-torture limping though. */
1ad886c9 798
22c1c7dd 799void
1ad886c9
DE
800sim_stop_reason (sd, reason, sigrc)
801 SIM_DESC sd;
22c1c7dd
JL
802 enum sim_stop *reason;
803 int *sigrc;
804{
1ad886c9
DE
805 if (State.exception == SIG_V850_EXIT)
806 {
807 *reason = sim_exited;
808 *sigrc = State.regs[7];
809 }
22c1c7dd 810 else
1ad886c9
DE
811 {
812 *reason = sim_stopped;
813 *sigrc = State.exception;
814 }
22c1c7dd
JL
815}
816
817void
1ad886c9
DE
818sim_fetch_register (sd, rn, memory)
819 SIM_DESC sd;
22c1c7dd
JL
820 int rn;
821 unsigned char *memory;
822{
88777ce2 823 put_word (memory, State.regs[rn]);
22c1c7dd
JL
824}
825
826void
1ad886c9
DE
827sim_store_register (sd, rn, memory)
828 SIM_DESC sd;
22c1c7dd
JL
829 int rn;
830 unsigned char *memory;
831{
88777ce2 832 State.regs[rn] = get_word (memory);
22c1c7dd
JL
833}
834
9909e232 835int
1ad886c9
DE
836sim_read (sd, addr, buffer, size)
837 SIM_DESC sd;
22c1c7dd
JL
838 SIM_ADDR addr;
839 unsigned char *buffer;
840 int size;
841{
842 int i;
843 for (i = 0; i < size; i++)
1ad886c9
DE
844 buffer[i] = load_mem (addr + i, 1);
845
22c1c7dd
JL
846 return size;
847}
848
1ad886c9
DE
849int current_intgen_number = 1;
850
22c1c7dd 851void
1ad886c9
DE
852sim_set_interrupt (spec)
853 char *spec;
854{
855 int i, num;
856 char **argv;
857 struct interrupt_generator *intgen, *tmpgen;
858 extern char **buildargv ();
859
860 argv = buildargv (spec);
861
862 if (*argv && ! strcmp (*argv, "add"))
863 {
864 /* Create a new interrupt generator object. */
865 intgen = (struct interrupt_generator *)
866 malloc (sizeof(struct interrupt_generator));
867 intgen->type = int_none;
868 intgen->cond_type = int_cond_none;
869 intgen->address = 0;
870 intgen->time = 0;
871 intgen->enabled = 0;
872 ++argv;
873 /* Match on interrupt type name. */
874 for (i = 0; i < num_int_types; ++i)
875 {
876 if (*argv && ! strcmp (*argv, interrupt_names[i]))
877 {
878 intgen->type = i;
879 break;
880 }
881 }
882 if (intgen->type == int_none)
883 {
884 (*v850_callback->printf_filtered) (v850_callback, "Interrupt type unknown; known types are\n");
885 for (i = 0; i < num_int_types; ++i)
886 {
887 (*v850_callback->printf_filtered) (v850_callback, " %s", interrupt_names[i]);
888 }
889 (*v850_callback->printf_filtered) (v850_callback, "\n");
890 free (intgen);
891 return;
892 }
893 ++argv;
894 intgen->address = 0;
895 intgen->time = 0;
896 if (*argv && ! strcmp (*argv, "pc"))
897 {
898 intgen->cond_type = int_cond_pc;
899 ++argv;
900 intgen->address = sim_parse_number (*argv, NULL);
901 }
902 else if (*argv && ! strcmp (*argv, "time"))
903 {
904 intgen->cond_type = int_cond_time;
905 ++argv;
906 intgen->time = sim_parse_number (*argv, NULL);
907 }
908 else
909 {
910 (*v850_callback->printf_filtered) (v850_callback, "Condition type must be `pc' or `time'.\n");
911 free (intgen);
912 return;
913 }
914 /* We now have a valid interrupt generator. Number it and add
915 to the list of generators. */
916 intgen->number = current_intgen_number++;
917 intgen->enabled = 1;
918 intgen->next = intgen_list;
919 intgen_list = intgen;
920 (*v850_callback->printf_filtered) (v850_callback, "Interrupt generator %d (NMI) at pc=0x%x, time=%d.\n", intgen_list->number, intgen_list->address, intgen_list->time);
921 }
922 else if (*argv && !strcmp (*argv, "remove"))
923 {
924 ++argv;
925 num = sim_parse_number (*argv, NULL);
926 tmpgen = NULL;
927 if (intgen_list)
928 {
929 if (intgen_list->number == num)
930 {
931 tmpgen = intgen_list;
932 intgen_list = intgen_list->next;
933 }
934 else
935 {
936 for (intgen = intgen_list; intgen != NULL; intgen = intgen->next)
937 {
938 if (intgen->next != NULL && intgen->next->number == num)
939 {
940 tmpgen = intgen->next;
941 intgen->next = intgen->next->next;
942 break;
943 }
944 }
945 }
946 if (tmpgen)
947 free (tmpgen);
948 else
949 (*v850_callback->printf_filtered) (v850_callback,
950 "No interrupt generator numbered %d, ignoring.\n", num);
951 }
952 }
953 else if (*argv && !strcmp (*argv, "info"))
954 {
955 if (intgen_list)
956 {
957 for (intgen = intgen_list; intgen != NULL; intgen = intgen->next)
958 (*v850_callback->printf_filtered) (v850_callback,
959 "Interrupt generator %d (%s) at pc=0x%x/time=%d%s.\n",
960 intgen->number,
961 interrupt_names[intgen->type],
962 intgen->address,
963 intgen->time,
964 (intgen->enabled ? "" : " (disabled)"));
965 }
966 else
967 {
968 (*v850_callback->printf_filtered) (v850_callback, "No interrupt generators defined.\n");
969 }
970
971 }
972 else
973 {
974 (*v850_callback->printf_filtered) (v850_callback,
975 "Invalid interrupt command, must be one of `add', `remove', or `info'.\n");
976 }
977 /* Cache the presence of a non-maskable generator. */
978 have_nm_generator = 0;
979 for (intgen = intgen_list; intgen != NULL; intgen = intgen->next)
980 {
981 if (intgen->type == int_nmi || intgen->type == int_reset)
982 {
983 have_nm_generator = 1;
984 break;
985 }
986 }
987}
988
989void
990sim_do_command (sd, cmd)
991 SIM_DESC sd;
22c1c7dd 992 char *cmd;
1ad886c9
DE
993{
994 char *mm_cmd = "memory-map";
995 char *int_cmd = "interrupt";
996
997 if (! strncmp (cmd, mm_cmd, strlen (mm_cmd))
998 && strchr (" ", cmd[strlen(mm_cmd)]))
999 sim_set_memory_map (cmd + strlen(mm_cmd) + 1);
1000
1001 else if (! strncmp (cmd, int_cmd, strlen (int_cmd))
1002 && strchr (" ", cmd[strlen(int_cmd)]))
1003 sim_set_interrupt (cmd + strlen(int_cmd) + 1);
1004
1005 else if (! strcmp (cmd, "help"))
1006 {
1007 (*v850_callback->printf_filtered) (v850_callback, "V850 simulator commands:\n\n");
1008 (*v850_callback->printf_filtered) (v850_callback, "interrupt add <inttype> { pc | time } <value> -- Set up an interrupt generator\n");
1009 (*v850_callback->printf_filtered) (v850_callback, "interrupt remove <n> -- Remove an existing interrupt generator\n");
1010 (*v850_callback->printf_filtered) (v850_callback, "interrupt info -- List all the interrupt generators\n");
1011 (*v850_callback->printf_filtered) (v850_callback, "memory-map hole=<m>,<n> -- Set the memory map to have a hole between <m> and <n>\n");
1012 (*v850_callback->printf_filtered) (v850_callback, "\n");
1013 }
1014 else
1015 (*v850_callback->printf_filtered) (v850_callback, "\"%s\" is not a valid V850 simulator command.\n",
1016 cmd);
22c1c7dd
JL
1017}
1018
1ad886c9
DE
1019SIM_RC
1020sim_load (sd, prog, abfd, from_tty)
1021 SIM_DESC sd;
22c1c7dd 1022 char *prog;
1ad886c9 1023 bfd *abfd;
22c1c7dd
JL
1024 int from_tty;
1025{
1ad886c9
DE
1026 extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
1027 bfd *prog_bfd;
1028
1029 prog_bfd = sim_load_file (sd, myname, v850_callback, prog, abfd,
1030 sim_kind == SIM_OPEN_DEBUG);
1031 if (prog_bfd == NULL)
1032 return SIM_RC_FAIL;
1033 PC = bfd_get_start_address (prog_bfd);
1034 if (abfd == NULL)
1035 bfd_close (prog_bfd);
1036 return SIM_RC_OK;
22c1c7dd 1037}
This page took 0.084986 seconds and 4 git commands to generate.