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