Add ABFD argument to sim_create_inferior. Document.
[platform/upstream/binutils.git] / sim / d10v / interp.c
1 #include <signal.h>
2 #include "sysdep.h"
3 #include "bfd.h"
4 #include "callback.h"
5 #include "remote-sim.h"
6
7 #include "d10v_sim.h"
8
9 #define IMEM_SIZE 18    /* D10V instruction memory size is 18 bits */
10 #define DMEM_SIZE 16    /* Data memory is 64K (but only 32K internal RAM) */
11 #define UMEM_SIZE 17    /* each unified memory region is 17 bits */
12
13 enum _leftright { LEFT_FIRST, RIGHT_FIRST };
14
15 static char *myname;
16 static SIM_OPEN_KIND sim_kind;
17 int d10v_debug;
18 host_callback *d10v_callback;
19 unsigned long ins_type_counters[ (int)INS_MAX ];
20
21 uint16 OP[4];
22
23 static int init_text_p = 0;
24 /* non-zero if we opened prog_bfd */
25 static int prog_bfd_was_opened_p;
26 bfd *prog_bfd;
27 asection *text;
28 bfd_vma text_start;
29 bfd_vma text_end;
30
31 static long hash PARAMS ((long insn, int format));
32 static struct hash_entry *lookup_hash PARAMS ((uint32 ins, int size));
33 static void get_operands PARAMS ((struct simops *s, uint32 ins));
34 static void do_long PARAMS ((uint32 ins));
35 static void do_2_short PARAMS ((uint16 ins1, uint16 ins2, enum _leftright leftright));
36 static void do_parallel PARAMS ((uint16 ins1, uint16 ins2));
37 static char *add_commas PARAMS ((char *buf, int sizeof_buf, unsigned long value));
38 static void init_system PARAMS ((void));
39 extern void sim_set_profile PARAMS ((int n));
40 extern void sim_set_profile_size PARAMS ((int n));
41
42 #ifndef INLINE
43 #if defined(__GNUC__) && defined(__OPTIMIZE__)
44 #define INLINE __inline__
45 #else
46 #define INLINE
47 #endif
48 #endif
49
50 #define MAX_HASH  63
51 struct hash_entry
52 {
53   struct hash_entry *next;
54   long opcode;
55   long mask;
56   int size;
57   struct simops *ops;
58 };
59
60 struct hash_entry hash_table[MAX_HASH+1];
61
62 INLINE static long 
63 hash(insn, format)
64      long insn;
65      int format;
66 {
67   if (format & LONG_OPCODE)
68     return ((insn & 0x3F000000) >> 24);
69   else
70     return((insn & 0x7E00) >> 9);
71 }
72
73 INLINE static struct hash_entry *
74 lookup_hash (ins, size)
75      uint32 ins;
76      int size;
77 {
78   struct hash_entry *h;
79
80   if (size)
81     h = &hash_table[(ins & 0x3F000000) >> 24];
82   else
83     h = &hash_table[(ins & 0x7E00) >> 9];
84
85   while ((ins & h->mask) != h->opcode || h->size != size)
86     {
87       if (h->next == NULL)
88         {
89           (*d10v_callback->printf_filtered) (d10v_callback, "ERROR looking up hash for %x at PC %x\n",ins, PC);
90           exit (1);
91         }
92       h = h->next;
93     }
94   return (h);
95 }
96
97 INLINE static void
98 get_operands (struct simops *s, uint32 ins)
99 {
100   int i, shift, bits, flags;
101   uint32 mask;
102   for (i=0; i < s->numops; i++)
103     {
104       shift = s->operands[3*i];
105       bits = s->operands[3*i+1];
106       flags = s->operands[3*i+2];
107       mask = 0x7FFFFFFF >> (31 - bits);
108       OP[i] = (ins >> shift) & mask;
109     }
110 }
111
112 bfd_vma
113 decode_pc ()
114 {
115   asection *s;
116   if (!init_text_p)
117     {
118       init_text_p = 1;
119       for (s = prog_bfd->sections; s; s = s->next)
120         if (strcmp (bfd_get_section_name (prog_bfd, s), ".text") == 0)
121           {
122             text = s;
123             text_start = bfd_get_section_vma (prog_bfd, s);
124             text_end = text_start + bfd_section_size (prog_bfd, s);
125             break;
126           }
127     }
128
129   return (PC << 2) + text_start;
130 }
131
132 static void
133 do_long (ins)
134      uint32 ins;
135 {
136   struct hash_entry *h;
137 #ifdef DEBUG
138   if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
139     (*d10v_callback->printf_filtered) (d10v_callback, "do_long 0x%x\n", ins);
140 #endif
141   h = lookup_hash (ins, 1);
142   get_operands (h->ops, ins);
143   State.ins_type = INS_LONG;
144   ins_type_counters[ (int)State.ins_type ]++;
145   (h->ops->func)();
146 }
147
148 static void
149 do_2_short (ins1, ins2, leftright)
150      uint16 ins1, ins2;
151      enum _leftright leftright;
152 {
153   struct hash_entry *h;
154   reg_t orig_pc = PC;
155   enum _ins_type first, second;
156
157 #ifdef DEBUG
158   if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
159     (*d10v_callback->printf_filtered) (d10v_callback, "do_2_short 0x%x (%s) -> 0x%x\n",
160                                        ins1, (leftright) ? "left" : "right", ins2);
161 #endif
162
163   if (leftright == LEFT_FIRST)
164     {
165       first = INS_LEFT;
166       second = INS_RIGHT;
167       ins_type_counters[ (int)INS_LEFTRIGHT ]++;
168     }
169   else
170     {
171       first = INS_RIGHT;
172       second = INS_LEFT;
173       ins_type_counters[ (int)INS_RIGHTLEFT ]++;
174     }
175
176   h = lookup_hash (ins1, 0);
177   get_operands (h->ops, ins1);
178   State.ins_type = first;
179   ins_type_counters[ (int)State.ins_type ]++;
180   (h->ops->func)();
181
182   /* If the PC has changed (ie, a jump), don't do the second instruction */
183   if (orig_pc == PC && !State.exception)
184     {
185       h = lookup_hash (ins2, 0);
186       get_operands (h->ops, ins2);
187       State.ins_type = second;
188       ins_type_counters[ (int)State.ins_type ]++;
189       ins_type_counters[ (int)INS_CYCLES ]++;
190       (h->ops->func)();
191     }
192   else if (orig_pc != PC && !State.exception)
193     ins_type_counters[ (int)INS_COND_JUMP ]++;
194 }
195
196 static void
197 do_parallel (ins1, ins2)
198      uint16 ins1, ins2;
199 {
200   struct hash_entry *h1, *h2;
201 #ifdef DEBUG
202   if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
203     (*d10v_callback->printf_filtered) (d10v_callback, "do_parallel 0x%x || 0x%x\n", ins1, ins2);
204 #endif
205   ins_type_counters[ (int)INS_PARALLEL ]++;
206   h1 = lookup_hash (ins1, 0);
207   h2 = lookup_hash (ins2, 0);
208
209   if (h1->ops->exec_type == PARONLY)
210     {
211       get_operands (h1->ops, ins1);
212       State.ins_type = INS_LEFT_COND_TEST;
213       ins_type_counters[ (int)State.ins_type ]++;
214       (h1->ops->func)();
215       if (State.exe)
216         {
217           ins_type_counters[ (int)INS_COND_TRUE ]++;
218           get_operands (h2->ops, ins2);
219           State.ins_type = INS_RIGHT_COND_EXE;
220           ins_type_counters[ (int)State.ins_type ]++;
221           (h2->ops->func)();
222         }
223       else
224         ins_type_counters[ (int)INS_COND_FALSE ]++;
225     }
226   else if (h2->ops->exec_type == PARONLY)
227     {
228       get_operands (h2->ops, ins2);
229       State.ins_type = INS_RIGHT_COND_TEST;
230       ins_type_counters[ (int)State.ins_type ]++;
231       (h2->ops->func)();
232       if (State.exe)
233         {
234           ins_type_counters[ (int)INS_COND_TRUE ]++;
235           get_operands (h1->ops, ins1);
236           State.ins_type = INS_LEFT_COND_EXE;
237           ins_type_counters[ (int)State.ins_type ]++;
238           (h1->ops->func)();
239         }
240       else
241         ins_type_counters[ (int)INS_COND_FALSE ]++;
242     }
243   else
244     {
245       get_operands (h1->ops, ins1);
246       State.ins_type = INS_LEFT_PARALLEL;
247       ins_type_counters[ (int)State.ins_type ]++;
248       (h1->ops->func)();
249       if (!State.exception)
250         {
251           get_operands (h2->ops, ins2);
252           State.ins_type = INS_RIGHT_PARALLEL;
253           ins_type_counters[ (int)State.ins_type ]++;
254           (h2->ops->func)();
255         }
256     }
257 }
258  
259 static char *
260 add_commas(buf, sizeof_buf, value)
261      char *buf;
262      int sizeof_buf;
263      unsigned long value;
264 {
265   int comma = 3;
266   char *endbuf = buf + sizeof_buf - 1;
267
268   *--endbuf = '\0';
269   do {
270     if (comma-- == 0)
271       {
272         *--endbuf = ',';
273         comma = 2;
274       }
275
276     *--endbuf = (value % 10) + '0';
277   } while ((value /= 10) != 0);
278
279   return endbuf;
280 }
281
282 void
283 sim_size (power)
284      int power;
285
286 {
287   int i;
288
289   if (State.imem)
290     {
291       for (i=0;i<128;i++)
292         {
293           if (State.umem[i])
294             {
295               free (State.umem[i]);
296               State.umem[i] = NULL;
297             }
298         }
299       free (State.imem);
300       free (State.dmem);
301     }
302
303   State.imem = (uint8 *)calloc(1,1<<IMEM_SIZE);
304   State.dmem = (uint8 *)calloc(1,1<<DMEM_SIZE);
305   for (i=1;i<127;i++)
306     State.umem[i] = NULL;
307   State.umem[0] = (uint8 *)calloc(1,1<<UMEM_SIZE);
308   State.umem[1] = (uint8 *)calloc(1,1<<UMEM_SIZE);
309   State.umem[2] = (uint8 *)calloc(1,1<<UMEM_SIZE);
310   State.umem[127] = (uint8 *)calloc(1,1<<UMEM_SIZE);
311   if (!State.imem || !State.dmem || !State.umem[0] || !State.umem[1] || !State.umem[2] || !State.umem[127] )
312     {
313       (*d10v_callback->printf_filtered) (d10v_callback, "Memory allocation failed.\n");
314       exit(1);
315     }
316   
317   SET_IMAP0(0x1000);
318   SET_IMAP1(0x1000);
319   SET_DMAP(0);
320
321 #ifdef DEBUG
322   if ((d10v_debug & DEBUG_MEMSIZE) != 0)
323     {
324       char buffer[20];
325       (*d10v_callback->printf_filtered) (d10v_callback,
326                                          "Allocated %s bytes instruction memory and\n",
327                                          add_commas (buffer, sizeof (buffer), (1UL<<IMEM_SIZE)));
328
329       (*d10v_callback->printf_filtered) (d10v_callback, "          %s bytes data memory.\n",
330                                          add_commas (buffer, sizeof (buffer), (1UL<<IMEM_SIZE)));
331     }
332 #endif
333 }
334
335 static void
336 init_system ()
337 {
338   if (!State.imem)
339     sim_size(1);
340 }
341
342 static int
343 xfer_mem (addr, buffer, size, write)
344      SIM_ADDR addr;
345      unsigned char *buffer;
346      int size;
347      int write;
348 {
349   if (!State.imem)
350     init_system ();
351
352 #ifdef DEBUG
353   if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
354     {
355       if (write)
356         (*d10v_callback->printf_filtered) (d10v_callback, "sim_write %d bytes to 0x%x\n", size, addr);
357       else
358         (*d10v_callback->printf_filtered) (d10v_callback, "sim_read %d bytes from 0x%x\n", size, addr);
359     }
360 #endif
361
362   /* to access data, we use the following mapping */
363   /* 0x01000000 - 0x0103ffff : instruction memory */
364   /* 0x02000000 - 0x0200ffff : data memory        */
365   /* 0x00000000 - 0x00ffffff : unified memory     */
366
367   if ( (addr & 0x03000000) == 0)
368     {
369       /* UNIFIED MEMORY */
370       int segment;
371       segment = addr >> UMEM_SIZE;
372       addr &= 0x1ffff;
373       if (!State.umem[segment])
374         {
375 #ifdef DEBUG
376           (*d10v_callback->printf_filtered) (d10v_callback,"Allocating %s bytes unified memory to region %d\n",
377                                              add_commas (buffer, sizeof (buffer), (1UL<<IMEM_SIZE)), segment);
378 #endif
379           State.umem[segment] = (uint8 *)calloc(1,1<<UMEM_SIZE);
380         }
381       if (!State.umem[segment])
382         {
383           (*d10v_callback->printf_filtered) (d10v_callback, "Memory allocation failed.\n");
384           exit(1);
385         }
386       /* FIXME:  need to check size and read/write multiple segments if necessary */
387       if (write)
388         memcpy (State.umem[segment]+addr, buffer, size) ; 
389       else
390         memcpy (buffer, State.umem[segment]+addr, size); 
391     }
392   else if ( (addr & 0x03000000) == 0x02000000)
393     {
394       /* DATA MEMORY */
395       addr &= ~0x02000000;
396       if (size > (1<<(DMEM_SIZE-1)))
397         {
398           (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: data section is only %d bytes.\n",1<<(DMEM_SIZE-1));
399           exit(1);
400         }
401       if (write)
402         memcpy (State.dmem+addr, buffer, size); 
403       else
404         memcpy (buffer, State.dmem+addr, size); 
405     }
406   else if ( (addr & 0x03000000) == 0x01000000)
407     {
408       /* INSTRUCTION MEMORY */
409       addr &= ~0x01000000;
410       if (size > (1<<IMEM_SIZE))
411         {
412           (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: inst section is only %d bytes.\n",1<<IMEM_SIZE);
413           exit(1);
414         }
415       if (write)
416         memcpy (State.imem+addr, buffer, size); 
417       else
418         memcpy (buffer, State.imem+addr, size); 
419     }
420   else if (write)
421     {
422       (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: address 0x%x is not in valid range\n",addr);
423       (*d10v_callback->printf_filtered) (d10v_callback, "Instruction addresses start at 0x01000000\n");
424       (*d10v_callback->printf_filtered) (d10v_callback, "Data addresses start at 0x02000000\n");
425       (*d10v_callback->printf_filtered) (d10v_callback, "Unified addresses start at 0x00000000\n");
426       exit(1);
427     }
428   else
429     return 0;
430
431   return size;
432 }
433
434
435 int
436 sim_write (sd, addr, buffer, size)
437      SIM_DESC sd;
438      SIM_ADDR addr;
439      unsigned char *buffer;
440      int size;
441 {
442   return xfer_mem( addr, buffer, size, 1);
443 }
444
445 int
446 sim_read (sd, addr, buffer, size)
447      SIM_DESC sd;
448      SIM_ADDR addr;
449      unsigned char *buffer;
450      int size;
451 {
452   return xfer_mem( addr, buffer, size, 0);
453 }
454
455
456 SIM_DESC
457 sim_open (kind, callback, abfd, argv)
458      SIM_OPEN_KIND kind;
459      host_callback *callback;
460      struct _bfd *abfd;
461      char **argv;
462 {
463   struct simops *s;
464   struct hash_entry *h;
465   static int init_p = 0;
466   char **p;
467
468   sim_kind = kind;
469   d10v_callback = callback;
470   myname = argv[0];
471
472   for (p = argv + 1; *p; ++p)
473     {
474 #ifdef DEBUG
475       if (strcmp (*p, "-t") == 0)
476         d10v_debug = DEBUG;
477       else
478 #endif
479         (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: unsupported option(s): %s\n",*p);
480     }
481   
482   /* put all the opcodes in the hash table */
483   if (!init_p++)
484     {
485       for (s = Simops; s->func; s++)
486         {
487           h = &hash_table[hash(s->opcode,s->format)];
488       
489           /* go to the last entry in the chain */
490           while (h->next)
491             h = h->next;
492
493           if (h->ops)
494             {
495               h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
496               if (!h->next)
497                 perror ("malloc failure");
498
499               h = h->next;
500             }
501           h->ops = s;
502           h->mask = s->mask;
503           h->opcode = s->opcode;
504           h->size = s->is_long;
505         }
506     }
507
508   /* Fudge our descriptor.  */
509   return (SIM_DESC) 1;
510 }
511
512
513 void
514 sim_close (sd, quitting)
515      SIM_DESC sd;
516      int quitting;
517 {
518   if (prog_bfd != NULL && prog_bfd_was_opened_p)
519     bfd_close (prog_bfd);
520 }
521
522 void
523 sim_set_profile (n)
524      int n;
525 {
526   (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile %d\n",n);
527 }
528
529 void
530 sim_set_profile_size (n)
531      int n;
532 {
533   (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile_size %d\n",n);
534 }
535
536
537 uint8 *
538 dmem_addr( addr )
539      uint32 addr;
540 {
541   int seg;
542
543   addr &= 0xffff;
544
545   if (addr > 0xbfff)
546     {
547       if ( (addr & 0xfff0) != 0xff00)
548         {
549           (*d10v_callback->printf_filtered) (d10v_callback, "Data address 0x%lx is in I/O space, pc = 0x%lx.\n",
550                                              (long)addr, (long)decode_pc ());
551           State.exception = SIGBUS;
552         }
553
554       return State.dmem + addr;
555     }
556   
557   if (addr > 0x7fff)
558     {
559       if (DMAP & 0x1000)
560         {
561           /* instruction memory */
562           return (DMAP & 0xf) * 0x4000 + State.imem;
563         }
564       /* unified memory */
565       /* this is ugly because we allocate unified memory in 128K segments and */
566       /* dmap addresses 16k segments */
567       seg = (DMAP & 0x3ff) >> 3;
568       if (State.umem[seg] == NULL)
569         {
570           (*d10v_callback->printf_filtered) (d10v_callback, "ERROR:  unified memory region %d unmapped, pc = 0x%lx\n",
571                                              seg, (long)decode_pc ());
572           State.exception = SIGBUS;
573         }
574       return State.umem[seg] + (DMAP & 7) * 0x4000;
575     }
576
577   return State.dmem + addr;
578 }
579
580
581 static uint8 *
582 pc_addr()
583 {
584   uint32 pc = ((uint32)PC) << 2;
585   uint16 imap;
586
587   if (pc & 0x20000)
588     imap = IMAP1;
589   else
590     imap = IMAP0;
591   
592   if (imap & 0x1000)
593     return State.imem + pc;
594
595   if (State.umem[imap & 0xff] == NULL)
596     {
597       (*d10v_callback->printf_filtered) (d10v_callback, "ERROR:  unified memory region %d unmapped, pc = 0x%lx\n",
598                                          imap & 0xff, (long)PC);
599       State.exception = SIGBUS;
600       return 0;
601     }
602
603   return State.umem[imap & 0xff] + pc;
604 }
605
606
607 static int stop_simulator;
608
609 static void
610 sim_ctrl_c()
611 {
612   stop_simulator = 1;
613 }
614
615
616 int
617 sim_stop (sd)
618      SIM_DESC sd;
619 {
620   stop_simulator = 1;
621   return 1;
622 }
623
624
625 /* Run (or resume) the program.  */
626 void
627 sim_resume (sd, step, siggnal)
628      SIM_DESC sd;
629      int step, siggnal;
630 {
631   void (*prev) ();
632   uint32 inst;
633
634 /*   (*d10v_callback->printf_filtered) (d10v_callback, "sim_resume (%d,%d)  PC=0x%x\n",step,siggnal,PC); */
635   State.exception = 0;
636   prev = signal(SIGINT, sim_ctrl_c);
637   stop_simulator = step;
638
639   do
640     {
641       inst = get_longword( pc_addr() ); 
642       State.pc_changed = 0;
643       ins_type_counters[ (int)INS_CYCLES ]++;
644       switch (inst & 0xC0000000)
645         {
646         case 0xC0000000:
647           /* long instruction */
648           do_long (inst & 0x3FFFFFFF);
649           break;
650         case 0x80000000:
651           /* R -> L */
652           do_2_short ( inst & 0x7FFF, (inst & 0x3FFF8000) >> 15, 0);
653           break;
654         case 0x40000000:
655           /* L -> R */
656           do_2_short ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF, 1);
657           break;
658         case 0:
659           do_parallel ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
660           break;
661         }
662       
663       if (State.RP && PC == RPT_E)
664         {
665           RPT_C -= 1;
666           if (RPT_C == 0)
667             State.RP = 0;
668           else
669             PC = RPT_S;
670         }
671       else if (!State.pc_changed)
672         PC++;
673     } 
674   while ( !State.exception && !stop_simulator);
675   
676   if (step && !State.exception)
677     State.exception = SIGTRAP;
678
679   signal(SIGINT, prev);
680 }
681
682 int
683 sim_trace (sd)
684      SIM_DESC sd;
685 {
686 #ifdef DEBUG
687   d10v_debug = DEBUG;
688 #endif
689   sim_resume (sd, 0, 0);
690   return 1;
691 }
692
693 void
694 sim_info (sd, verbose)
695      SIM_DESC sd;
696      int verbose;
697 {
698   char buf1[40];
699   char buf2[40];
700   char buf3[40];
701   char buf4[40];
702   char buf5[40];
703   unsigned long left            = ins_type_counters[ (int)INS_LEFT ] + ins_type_counters[ (int)INS_LEFT_COND_EXE ];
704   unsigned long left_nops       = ins_type_counters[ (int)INS_LEFT_NOPS ];
705   unsigned long left_parallel   = ins_type_counters[ (int)INS_LEFT_PARALLEL ];
706   unsigned long left_cond       = ins_type_counters[ (int)INS_LEFT_COND_TEST ];
707   unsigned long left_total      = left + left_parallel + left_cond + left_nops;
708
709   unsigned long right           = ins_type_counters[ (int)INS_RIGHT ] + ins_type_counters[ (int)INS_RIGHT_COND_EXE ];
710   unsigned long right_nops      = ins_type_counters[ (int)INS_RIGHT_NOPS ];
711   unsigned long right_parallel  = ins_type_counters[ (int)INS_RIGHT_PARALLEL ];
712   unsigned long right_cond      = ins_type_counters[ (int)INS_RIGHT_COND_TEST ];
713   unsigned long right_total     = right + right_parallel + right_cond + right_nops;
714
715   unsigned long unknown         = ins_type_counters[ (int)INS_UNKNOWN ];
716   unsigned long ins_long        = ins_type_counters[ (int)INS_LONG ];
717   unsigned long parallel        = ins_type_counters[ (int)INS_PARALLEL ];
718   unsigned long leftright       = ins_type_counters[ (int)INS_LEFTRIGHT ];
719   unsigned long rightleft       = ins_type_counters[ (int)INS_RIGHTLEFT ];
720   unsigned long cond_true       = ins_type_counters[ (int)INS_COND_TRUE ];
721   unsigned long cond_false      = ins_type_counters[ (int)INS_COND_FALSE ];
722   unsigned long cond_jump       = ins_type_counters[ (int)INS_COND_JUMP ];
723   unsigned long cycles          = ins_type_counters[ (int)INS_CYCLES ];
724   unsigned long total           = (unknown + left_total + right_total + ins_long);
725
726   int size                      = strlen (add_commas (buf1, sizeof (buf1), total));
727   int parallel_size             = strlen (add_commas (buf1, sizeof (buf1),
728                                                       (left_parallel > right_parallel) ? left_parallel : right_parallel));
729   int cond_size                 = strlen (add_commas (buf1, sizeof (buf1), (left_cond > right_cond) ? left_cond : right_cond));
730   int nop_size                  = strlen (add_commas (buf1, sizeof (buf1), (left_nops > right_nops) ? left_nops : right_nops));
731   int normal_size               = strlen (add_commas (buf1, sizeof (buf1), (left > right) ? left : right));
732
733   (*d10v_callback->printf_filtered) (d10v_callback,
734                                      "executed %*s left  instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
735                                      size, add_commas (buf1, sizeof (buf1), left_total),
736                                      normal_size, add_commas (buf2, sizeof (buf2), left),
737                                      parallel_size, add_commas (buf3, sizeof (buf3), left_parallel),
738                                      cond_size, add_commas (buf4, sizeof (buf4), left_cond),
739                                      nop_size, add_commas (buf5, sizeof (buf5), left_nops));
740
741   (*d10v_callback->printf_filtered) (d10v_callback,
742                                      "executed %*s right instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
743                                      size, add_commas (buf1, sizeof (buf1), right_total),
744                                      normal_size, add_commas (buf2, sizeof (buf2), right),
745                                      parallel_size, add_commas (buf3, sizeof (buf3), right_parallel),
746                                      cond_size, add_commas (buf4, sizeof (buf4), right_cond),
747                                      nop_size, add_commas (buf5, sizeof (buf5), right_nops));
748
749   if (ins_long)
750     (*d10v_callback->printf_filtered) (d10v_callback,
751                                        "executed %*s long instruction(s)\n",
752                                        size, add_commas (buf1, sizeof (buf1), ins_long));
753
754   if (parallel)
755     (*d10v_callback->printf_filtered) (d10v_callback,
756                                        "executed %*s parallel instruction(s)\n",
757                                        size, add_commas (buf1, sizeof (buf1), parallel));
758
759   if (leftright)
760     (*d10v_callback->printf_filtered) (d10v_callback,
761                                        "executed %*s instruction(s) encoded L->R\n",
762                                        size, add_commas (buf1, sizeof (buf1), leftright));
763
764   if (rightleft)
765     (*d10v_callback->printf_filtered) (d10v_callback,
766                                        "executed %*s instruction(s) encoded R->L\n",
767                                        size, add_commas (buf1, sizeof (buf1), rightleft));
768
769   if (unknown)
770     (*d10v_callback->printf_filtered) (d10v_callback,
771                                        "executed %*s unknown instruction(s)\n",
772                                        size, add_commas (buf1, sizeof (buf1), unknown));
773
774   if (cond_true)
775     (*d10v_callback->printf_filtered) (d10v_callback,
776                                        "executed %*s instruction(s) due to EXExxx condition being true\n",
777                                        size, add_commas (buf1, sizeof (buf1), cond_true));
778
779   if (cond_false)
780     (*d10v_callback->printf_filtered) (d10v_callback,
781                                        "skipped  %*s instruction(s) due to EXExxx condition being false\n",
782                                        size, add_commas (buf1, sizeof (buf1), cond_false));
783
784   if (cond_jump)
785     (*d10v_callback->printf_filtered) (d10v_callback,
786                                        "skipped  %*s instruction(s) due to conditional branch succeeding\n",
787                                        size, add_commas (buf1, sizeof (buf1), cond_jump));
788
789   (*d10v_callback->printf_filtered) (d10v_callback,
790                                      "executed %*s cycle(s)\n",
791                                      size, add_commas (buf1, sizeof (buf1), cycles));
792
793   (*d10v_callback->printf_filtered) (d10v_callback,
794                                      "executed %*s total instructions\n",
795                                      size, add_commas (buf1, sizeof (buf1), total));
796 }
797
798 SIM_RC
799 sim_create_inferior (sd, abfd, argv, env)
800      SIM_DESC sd;
801      struct _bfd *abfd;
802      char **argv;
803      char **env;
804 {
805   bfd_vma start_address;
806
807   /* reset all state information */
808   memset (&State.regs, 0, (int)&State.imem - (int)&State.regs[0]);
809
810   /* set PC */
811   if (abfd != NULL)
812     start_address = bfd_get_start_address (prog_bfd);
813   else
814     start_address = 0xffc0 << 2;
815 #ifdef DEBUG
816   if (d10v_debug)
817     (*d10v_callback->printf_filtered) (d10v_callback, "sim_create_inferior:  PC=0x%lx\n", (long) start_address);
818 #endif
819   PC = start_address >> 2;
820
821   /* cpu resets imap0 to 0 and imap1 to 0x7f, but D10V-EVA board */
822   /* resets imap0 and imap1 to 0x1000. */
823
824   SET_IMAP0(0x1000);
825   SET_IMAP1(0x1000);
826   SET_DMAP(0);
827
828   return SIM_RC_OK;
829 }
830
831
832 void
833 sim_set_callbacks (p)
834      host_callback *p;
835 {
836   d10v_callback = p;
837 }
838
839 void
840 sim_stop_reason (sd, reason, sigrc)
841      SIM_DESC sd;
842      enum sim_stop *reason;
843      int *sigrc;
844 {
845 /*   (*d10v_callback->printf_filtered) (d10v_callback, "sim_stop_reason:  PC=0x%x\n",PC<<2); */
846
847   switch (State.exception)
848     {
849     case SIG_D10V_STOP:                 /* stop instruction */
850       *reason = sim_exited;
851       *sigrc = 0;
852       break;
853
854     case SIG_D10V_EXIT:                 /* exit trap */
855       *reason = sim_exited;
856       *sigrc = State.regs[2];
857       break;
858
859     default:                            /* some signal */
860       *reason = sim_stopped;
861       *sigrc = State.exception;
862       break;
863     } 
864 }
865
866 void
867 sim_fetch_register (sd, rn, memory)
868      SIM_DESC sd;
869      int rn;
870      unsigned char *memory;
871 {
872   if (!State.imem)
873     init_system();
874
875   if (rn > 34)
876     WRITE_64 (memory, State.a[rn-35]);
877   else if (rn == 32)
878     WRITE_16 (memory, IMAP0);
879   else if (rn == 33)
880     WRITE_16 (memory, IMAP1);
881   else if (rn == 34)
882     WRITE_16 (memory, DMAP);
883   else
884     WRITE_16 (memory, State.regs[rn]);
885 }
886  
887 void
888 sim_store_register (sd, rn, memory)
889      SIM_DESC sd;
890      int rn;
891      unsigned char *memory;
892 {
893   if (!State.imem)
894     init_system();
895
896   if (rn > 34)
897     State.a[rn-35] =  READ_64 (memory) & MASK40;
898   else if (rn == 34)
899     SET_DMAP( READ_16(memory) );
900   else if (rn == 33)
901     SET_IMAP1( READ_16(memory) );
902   else if (rn == 32)
903     SET_IMAP0( READ_16(memory) );
904   else
905     State.regs[rn]= READ_16 (memory);
906 }
907
908
909 void
910 sim_do_command (sd, cmd)
911      SIM_DESC sd;
912      char *cmd;
913
914   (*d10v_callback->printf_filtered) (d10v_callback, "sim_do_command: %s\n",cmd);
915 }
916
917 SIM_RC
918 sim_load (sd, prog, abfd, from_tty)
919      SIM_DESC sd;
920      char *prog;
921      bfd *abfd;
922      int from_tty;
923 {
924   extern bfd *sim_load_file (); /* ??? Don't know where this should live.  */
925
926   if (prog_bfd != NULL && prog_bfd_was_opened_p)
927     bfd_close (prog_bfd);
928   prog_bfd = sim_load_file (sd, myname, d10v_callback, prog, abfd,
929                             sim_kind == SIM_OPEN_DEBUG);
930   if (prog_bfd == NULL)
931     return SIM_RC_FAIL;
932   prog_bfd_was_opened_p = abfd == NULL;
933   return SIM_RC_OK;
934