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