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