* Makefile.in (SIM_OBJS): Add sim-load.o.
[binutils-gdb.git] / sim / v850 / interp.c
1 #include <signal.h>
2 #include "sysdep.h"
3 #include "bfd.h"
4
5 #include "v850_sim.h"
6
7 enum 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
21 enum interrupt_cond_type
22 {
23 int_cond_none,
24 int_cond_pc,
25 int_cond_time
26 };
27
28 struct 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
39 char *interrupt_names[] = {
40 "",
41 "reset",
42 "nmi",
43 "intov1",
44 "intp10",
45 "intp11",
46 "intp12",
47 "intp13",
48 "intcm4",
49 NULL
50 };
51
52 struct interrupt_generator *intgen_list;
53
54 /* True if a non-maskable (such as NMI or reset) interrupt generator
55 is present. */
56
57 static int have_nm_generator;
58
59 #ifndef INLINE
60 #ifdef __GNUC__
61 #define INLINE inline
62 #else
63 #define INLINE
64 #endif
65 #endif
66
67 /* These default values correspond to expected usage for the chip. */
68
69 SIM_ADDR rom_size = 0x8000;
70 SIM_ADDR low_end = 0x200000;
71 SIM_ADDR high_start = 0xffe000;
72
73 SIM_ADDR high_base;
74
75 host_callback *v850_callback;
76
77 int v850_debug;
78
79 static SIM_OPEN_KIND sim_kind;
80 static char *myname;
81
82 uint32 OP[4];
83
84 static struct hash_entry *lookup_hash PARAMS ((uint32 ins));
85 static long hash PARAMS ((long));
86 static void do_format_1_2 PARAMS ((uint32));
87 static void do_format_3 PARAMS ((uint32));
88 static void do_format_4 PARAMS ((uint32));
89 static void do_format_5 PARAMS ((uint32));
90 static void do_format_6 PARAMS ((uint32));
91 static void do_format_7 PARAMS ((uint32));
92 static void do_format_8 PARAMS ((uint32));
93 static void do_format_9_10 PARAMS ((uint32));
94 static void init_system PARAMS ((void));
95
96 #define MAX_HASH 63
97
98 struct hash_entry
99 {
100 struct hash_entry *next;
101 long opcode;
102 long mask;
103 struct simops *ops;
104 };
105
106 struct hash_entry hash_table[MAX_HASH+1];
107
108
109 static INLINE long
110 hash(insn)
111 long insn;
112 {
113 if ((insn & 0x0600) == 0
114 || (insn & 0x0700) == 0x0200
115 || (insn & 0x0700) == 0x0600
116 || (insn & 0x0780) == 0x0700)
117 return (insn & 0x07e0) >> 5;
118
119 if ((insn & 0x0700) == 0x0300
120 || (insn & 0x0700) == 0x0400
121 || (insn & 0x0700) == 0x0500)
122 return (insn & 0x0780) >> 7;
123
124 if ((insn & 0x07c0) == 0x0780)
125 return (insn & 0x07c0) >> 6;
126
127 return (insn & 0x07e0) >> 5;
128 }
129
130 static struct hash_entry *
131 lookup_hash (ins)
132 uint32 ins;
133 {
134 struct hash_entry *h;
135
136 h = &hash_table[hash(ins)];
137
138 while ((ins & h->mask) != h->opcode)
139 {
140 if (h->next == NULL)
141 {
142 (*v850_callback->printf_filtered) (v850_callback, "ERROR looking up hash for 0x%x, PC=0x%x\n", ins, PC);
143 exit(1);
144 }
145 h = h->next;
146 }
147 return (h);
148 }
149
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
153 uint8
154 get_byte (x)
155 uint8 *x;
156 {
157 return *x;
158 }
159
160 uint16
161 get_half (x)
162 uint8 *x;
163 {
164 uint8 *a = x;
165 return (a[1] << 8) + (a[0]);
166 }
167
168 uint32
169 get_word (x)
170 uint8 *x;
171 {
172 uint8 *a = x;
173 return (a[3]<<24) + (a[2]<<16) + (a[1]<<8) + (a[0]);
174 }
175
176 void
177 put_byte (addr, data)
178 uint8 *addr;
179 uint8 data;
180 {
181 uint8 *a = addr;
182 a[0] = data;
183 }
184
185 void
186 put_half (addr, data)
187 uint8 *addr;
188 uint16 data;
189 {
190 uint8 *a = addr;
191 a[0] = data & 0xff;
192 a[1] = (data >> 8) & 0xff;
193 }
194
195 void
196 put_word (addr, data)
197 uint8 *addr;
198 uint32 data;
199 {
200 uint8 *a = addr;
201 a[0] = data & 0xff;
202 a[1] = (data >> 8) & 0xff;
203 a[2] = (data >> 16) & 0xff;
204 a[3] = (data >> 24) & 0xff;
205 }
206
207 uint8 *
208 map (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
245 uint32
246 load_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
265 void
266 store_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
293 static void
294 do_format_1_2 (insn)
295 uint32 insn;
296 {
297 struct hash_entry *h;
298
299 h = lookup_hash (insn);
300 OP[0] = insn & 0x1f;
301 OP[1] = (insn >> 11) & 0x1f;
302 (h->ops->func) ();
303 }
304
305 static void
306 do_format_3 (insn)
307 uint32 insn;
308 {
309 struct hash_entry *h;
310
311 h = lookup_hash (insn);
312 OP[0] = (((insn & 0x70) >> 4) | ((insn & 0xf800) >> 8)) << 1;
313 (h->ops->func) ();
314 }
315
316 static void
317 do_format_4 (insn)
318 uint32 insn;
319 {
320 struct hash_entry *h;
321
322 h = lookup_hash (insn);
323 OP[0] = (insn >> 11) & 0x1f;
324 OP[1] = (insn & 0x7f);
325 (h->ops->func) ();
326 }
327
328 static void
329 do_format_5 (insn)
330 uint32 insn;
331 {
332 struct hash_entry *h;
333
334 h = lookup_hash (insn);
335 OP[0] = (((insn & 0x3f) << 15) | ((insn >> 17) & 0x7fff)) << 1;
336 OP[1] = (insn >> 11) & 0x1f;
337 (h->ops->func) ();
338 }
339
340 static void
341 do_format_6 (insn)
342 uint32 insn;
343 {
344 struct hash_entry *h;
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) ();
351 }
352
353 static void
354 do_format_7 (insn)
355 uint32 insn;
356 {
357 struct hash_entry *h;
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) ();
364 }
365
366 static void
367 do_format_8 (insn)
368 uint32 insn;
369 {
370 struct hash_entry *h;
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) ();
377 }
378
379 static void
380 do_format_9_10 (insn)
381 uint32 insn;
382 {
383 struct hash_entry *h;
384
385 h = lookup_hash (insn);
386 OP[0] = insn & 0x1f;
387 OP[1] = (insn >> 11) & 0x1f;
388 (h->ops->func) ();
389 }
390
391 void
392 sim_size (power)
393 int power;
394
395 {
396 int totsize;
397
398 if (State.mem)
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)
407 {
408 (*v850_callback->printf_filtered) (v850_callback, "Allocation of main memory failed.\n");
409 exit (1);
410 }
411 }
412
413 void
414 sim_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))
423 {
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 }
455 }
456 }
457
458 /* Parse a number in hex, octal, or decimal form. */
459
460 int
461 sim_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
472 static void
473 init_system ()
474 {
475 if (!State.mem)
476 sim_size(1);
477 }
478
479 int
480 sim_write (sd, addr, buffer, size)
481 SIM_DESC sd;
482 SIM_ADDR addr;
483 unsigned char *buffer;
484 int size;
485 {
486 int i;
487
488 init_system ();
489
490 for (i = 0; i < size; i++)
491 store_mem (addr + i, 1, buffer[i]);
492
493 return size;
494 }
495
496 SIM_DESC
497 sim_open (kind,argv)
498 SIM_OPEN_KIND kind;
499 char **argv;
500 {
501 struct simops *s;
502 struct hash_entry *h;
503 char **p;
504
505 sim_kind = kind;
506 myname = argv[0];
507
508 for (p = argv + 1; *p; ++p)
509 {
510 if (strcmp (*p, "-E") == 0)
511 ++p; /* ignore endian spec */
512 else
513 #ifdef DEBUG
514 if (strcmp (*p, "-t") == 0)
515 v850_debug = DEBUG;
516 else
517 #endif
518 (*v850_callback->printf_filtered) (v850_callback, "ERROR: unsupported option(s): %s\n",*p);
519 }
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 {
532 h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
533 h = h->next;
534 }
535 h->ops = s;
536 h->mask = s->mask;
537 h->opcode = s->opcode;
538 }
539
540 /* fudge our descriptor for now */
541 return (SIM_DESC) 1;
542 }
543
544
545 void
546 sim_close (sd, quitting)
547 SIM_DESC sd;
548 int quitting;
549 {
550 /* nothing to do */
551 }
552
553 void
554 sim_set_profile (n)
555 int n;
556 {
557 (*v850_callback->printf_filtered) (v850_callback, "sim_set_profile %d\n", n);
558 }
559
560 void
561 sim_set_profile_size (n)
562 int n;
563 {
564 (*v850_callback->printf_filtered) (v850_callback, "sim_set_profile_size %d\n", n);
565 }
566
567 time_t start_time;
568
569 static void do_interrupt PARAMS ((enum interrupt_type));
570
571 void
572 sim_resume (sd, step, siggnal)
573 SIM_DESC sd;
574 int step, siggnal;
575 {
576 uint32 inst, opcode;
577 reg_t oldpc;
578 struct interrupt_generator *intgen;
579 time_t now;
580
581 if (step)
582 State.exception = SIGTRAP;
583 else
584 State.exception = 0;
585
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
677 static void
678 do_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 }
750 }
751
752 int
753 sim_trace (sd)
754 SIM_DESC sd;
755 {
756 #ifdef DEBUG
757 v850_debug = DEBUG;
758 #endif
759 sim_resume (sd, 0, 0);
760 return 1;
761 }
762
763 void
764 sim_info (sd, verbose)
765 SIM_DESC sd;
766 int verbose;
767 {
768 (*v850_callback->printf_filtered) (v850_callback, "sim_info\n");
769 }
770
771 SIM_RC
772 sim_create_inferior (sd, argv, env)
773 SIM_DESC sd;
774 char **argv;
775 char **env;
776 {
777 return SIM_RC_OK;
778 }
779
780 void
781 sim_kill (sd)
782 SIM_DESC sd;
783 {
784 /* nothing to do */
785 }
786
787 void
788 sim_set_callbacks (sd, p)
789 SIM_DESC sd;
790 host_callback *p;
791 {
792 v850_callback = p;
793 }
794
795 /* All the code for exiting, signals, etc needs to be revamped.
796
797 This is enough to get c-torture limping though. */
798
799 void
800 sim_stop_reason (sd, reason, sigrc)
801 SIM_DESC sd;
802 enum sim_stop *reason;
803 int *sigrc;
804 {
805 if (State.exception == SIG_V850_EXIT)
806 {
807 *reason = sim_exited;
808 *sigrc = State.regs[7];
809 }
810 else
811 {
812 *reason = sim_stopped;
813 *sigrc = State.exception;
814 }
815 }
816
817 void
818 sim_fetch_register (sd, rn, memory)
819 SIM_DESC sd;
820 int rn;
821 unsigned char *memory;
822 {
823 put_word (memory, State.regs[rn]);
824 }
825
826 void
827 sim_store_register (sd, rn, memory)
828 SIM_DESC sd;
829 int rn;
830 unsigned char *memory;
831 {
832 State.regs[rn] = get_word (memory);
833 }
834
835 int
836 sim_read (sd, addr, buffer, size)
837 SIM_DESC sd;
838 SIM_ADDR addr;
839 unsigned char *buffer;
840 int size;
841 {
842 int i;
843 for (i = 0; i < size; i++)
844 buffer[i] = load_mem (addr + i, 1);
845
846 return size;
847 }
848
849 int current_intgen_number = 1;
850
851 void
852 sim_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
989 void
990 sim_do_command (sd, cmd)
991 SIM_DESC sd;
992 char *cmd;
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);
1017 }
1018
1019 SIM_RC
1020 sim_load (sd, prog, abfd, from_tty)
1021 SIM_DESC sd;
1022 char *prog;
1023 bfd *abfd;
1024 int from_tty;
1025 {
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;
1037 }