Flush defunct sim_kill.
[external/binutils.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, argv, env)
667      SIM_DESC sd;
668      char **argv;
669      char **env;
670 {
671   return SIM_RC_OK;
672 }
673
674 void
675 sim_set_callbacks (p)
676      host_callback *p;
677 {
678   v850_callback = p;
679 }
680
681 /* All the code for exiting, signals, etc needs to be revamped.
682
683    This is enough to get c-torture limping though.  */
684
685 void
686 sim_stop_reason (sd, reason, sigrc)
687      SIM_DESC sd;
688      enum sim_stop *reason;
689      int *sigrc;
690 {
691   if (State.exception == SIG_V850_EXIT)
692     {
693       *reason = sim_exited;
694       *sigrc = State.regs[7];
695     }
696   else
697     {
698       *reason = sim_stopped;
699       *sigrc = State.exception;
700     }
701 }
702
703 void
704 sim_fetch_register (sd, rn, memory)
705      SIM_DESC sd;
706      int rn;
707      unsigned char *memory;
708 {
709   put_word (memory, State.regs[rn]);
710 }
711  
712 void
713 sim_store_register (sd, rn, memory)
714      SIM_DESC sd;
715      int rn;
716      unsigned char *memory;
717 {
718   State.regs[rn] = get_word (memory);
719 }
720
721 int
722 sim_read (sd, addr, buffer, size)
723      SIM_DESC sd;
724      SIM_ADDR addr;
725      unsigned char *buffer;
726      int size;
727 {
728   int i;
729   for (i = 0; i < size; i++)
730     buffer[i] = load_mem (addr + i, 1);
731
732   return size;
733
734
735 int current_intgen_number = 1;
736
737 void
738 sim_set_interrupt (spec)
739      char *spec;
740 {
741   int i, num;
742   char **argv;
743   struct interrupt_generator *intgen, *tmpgen;
744   extern char **buildargv ();
745
746   argv = buildargv (spec);
747
748   if (*argv && ! strcmp (*argv, "add"))
749     {
750       /* Create a new interrupt generator object.  */
751       intgen = (struct interrupt_generator *)
752         malloc (sizeof(struct interrupt_generator));
753       intgen->type = int_none;
754       intgen->cond_type = int_cond_none;
755       intgen->address = 0;
756       intgen->time = 0;
757       intgen->enabled = 0;
758       ++argv;
759       /* Match on interrupt type name.  */
760       for (i = 0; i < num_int_types; ++i)
761         {
762           if (*argv && ! strcmp (*argv, interrupt_names[i]))
763             {
764               intgen->type = i;
765               break;
766             }
767         }
768       if (intgen->type == int_none)
769         {
770           (*v850_callback->printf_filtered) (v850_callback, "Interrupt type unknown; known types are\n");
771           for (i = 0; i < num_int_types; ++i)
772             {
773               (*v850_callback->printf_filtered) (v850_callback, " %s", interrupt_names[i]);
774             }
775           (*v850_callback->printf_filtered) (v850_callback, "\n");
776           free (intgen);
777           return;
778         }
779       ++argv;
780       intgen->address = 0;
781       intgen->time = 0;
782       if (*argv && ! strcmp (*argv, "pc"))
783         {
784           intgen->cond_type = int_cond_pc;
785           ++argv;
786           intgen->address = sim_parse_number (*argv, NULL);
787         }
788       else if (*argv && ! strcmp (*argv, "time"))
789         {
790           intgen->cond_type = int_cond_time;
791           ++argv;
792           intgen->time = sim_parse_number (*argv, NULL);
793         }
794       else
795         {
796           (*v850_callback->printf_filtered) (v850_callback, "Condition type must be `pc' or `time'.\n");
797           free (intgen);
798           return;
799         }
800       /* We now have a valid interrupt generator.  Number it and add
801          to the list of generators.  */
802       intgen->number = current_intgen_number++;
803       intgen->enabled = 1;
804       intgen->next = intgen_list;
805       intgen_list = intgen;
806       (*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);
807     }
808   else if (*argv && !strcmp (*argv, "remove"))
809     {
810       ++argv;
811       num = sim_parse_number (*argv, NULL);
812       tmpgen = NULL;
813       if (intgen_list)
814         {
815           if (intgen_list->number == num)
816             {
817               tmpgen = intgen_list;
818               intgen_list = intgen_list->next;
819             }
820           else
821             {
822               for (intgen = intgen_list; intgen != NULL; intgen = intgen->next)
823                 {
824                   if (intgen->next != NULL && intgen->next->number == num)
825                     {
826                       tmpgen = intgen->next;
827                       intgen->next = intgen->next->next;
828                       break;
829                     }
830                 }
831             }
832           if (tmpgen)
833             free (tmpgen);
834           else
835             (*v850_callback->printf_filtered) (v850_callback,
836                                                "No interrupt generator numbered %d, ignoring.\n", num);
837         }
838     }
839   else if (*argv && !strcmp (*argv, "info"))
840     {
841       if (intgen_list)
842         {
843           for (intgen = intgen_list; intgen != NULL; intgen = intgen->next)
844             (*v850_callback->printf_filtered) (v850_callback,
845                                                "Interrupt generator %d (%s) at pc=0x%x/time=%d%s.\n",
846                                                intgen->number,
847                                                interrupt_names[intgen->type],
848                                                intgen->address,
849                                                intgen->time,
850                                                (intgen->enabled ? "" : " (disabled)"));
851         }
852       else
853         {
854           (*v850_callback->printf_filtered) (v850_callback, "No interrupt generators defined.\n"); 
855         }
856
857     }
858   else
859     {
860       (*v850_callback->printf_filtered) (v850_callback,
861                                          "Invalid interrupt command, must be one of `add', `remove', or `info'.\n");
862     }
863   /* Cache the presence of a non-maskable generator.  */
864   have_nm_generator = 0;
865   for (intgen = intgen_list; intgen != NULL; intgen = intgen->next)
866     {
867       if (intgen->type == int_nmi || intgen->type == int_reset)
868         {
869           have_nm_generator = 1;
870           break;
871         }
872     }
873 }
874
875 void
876 sim_do_command (sd, cmd)
877      SIM_DESC sd;
878      char *cmd;
879 {
880   char *mm_cmd = "memory-map";
881   char *int_cmd = "interrupt";
882
883   if (! strncmp (cmd, mm_cmd, strlen (mm_cmd))
884       && strchr ("      ", cmd[strlen(mm_cmd)]))
885     sim_set_memory_map (cmd + strlen(mm_cmd) + 1);
886
887   else if (! strncmp (cmd, int_cmd, strlen (int_cmd))
888       && strchr ("      ", cmd[strlen(int_cmd)]))
889     sim_set_interrupt (cmd + strlen(int_cmd) + 1);
890
891   else if (! strcmp (cmd, "help"))
892     {
893       (*v850_callback->printf_filtered) (v850_callback, "V850 simulator commands:\n\n");
894       (*v850_callback->printf_filtered) (v850_callback, "interrupt add <inttype> { pc | time } <value> -- Set up an interrupt generator\n");
895       (*v850_callback->printf_filtered) (v850_callback, "interrupt remove <n> -- Remove an existing interrupt generator\n");
896       (*v850_callback->printf_filtered) (v850_callback, "interrupt info -- List all the interrupt generators\n");
897       (*v850_callback->printf_filtered) (v850_callback, "memory-map hole=<m>,<n> -- Set the memory map to have a hole between <m> and <n>\n");
898       (*v850_callback->printf_filtered) (v850_callback, "\n");
899     }
900   else
901     (*v850_callback->printf_filtered) (v850_callback, "\"%s\" is not a valid V850 simulator command.\n",
902                                        cmd);
903 }
904
905 SIM_RC
906 sim_load (sd, prog, abfd, from_tty)
907      SIM_DESC sd;
908      char *prog;
909      bfd *abfd;
910      int from_tty;
911 {
912   extern bfd *sim_load_file (); /* ??? Don't know where this should live.  */
913
914   if (prog_bfd != NULL && prog_bfd_was_opened_p)
915     bfd_close (prog_bfd);
916   prog_bfd = sim_load_file (sd, myname, v850_callback, prog, abfd,
917                             sim_kind == SIM_OPEN_DEBUG);
918   if (prog_bfd == NULL)
919     return SIM_RC_FAIL;
920   PC = bfd_get_start_address (prog_bfd);
921   prog_bfd_was_opened_p = abfd == NULL;
922   return SIM_RC_OK;
923