]> Git Repo - binutils.git/blob - sim/sh/interp.c
(sim_stop_signal): Result is now enum sim_stop.
[binutils.git] / sim / sh / interp.c
1 /* Simulator for the Hitachi SH architecture.
2
3    Written by Steve Chamberlain of Cygnus Support.
4    [email protected]
5
6    This file is part of SH sim
7
8
9                 THIS SOFTWARE IS NOT COPYRIGHTED
10
11    Cygnus offers the following for use in the public domain.  Cygnus
12    makes no warranty with regard to the software or it's performance
13    and the user accepts the software "AS IS" with all faults.
14
15    CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
16    THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18
19 */
20 #include <signal.h>
21 #include "sysdep.h"
22 #include <sys/times.h>
23 #include <sys/param.h>
24 #include "bfd.h"
25 #define O_RECOMPILE 85
26 #define DEFINE_TABLE
27
28 #define DISASSEMBLER_TABLE
29
30 #define SBIT(x) ((x)&sbit)
31 #define R0      saved_state.asregs.regs[0]
32 #define Rn      saved_state.asregs.regs[n]
33 #define Rm      saved_state.asregs.regs[m]
34 #define UR0     (unsigned int)(saved_state.asregs.regs[0])
35 #define UR      (unsigned int)R
36 #define UR      (unsigned int)R
37 #define SR0     saved_state.asregs.regs[0]
38 #define GBR     saved_state.asregs.gbr
39 #define VBR     saved_state.asregs.vbr
40 #define MACH    saved_state.asregs.mach
41 #define MACL    saved_state.asregs.macl
42 #define M       saved_state.asregs.sr.bits.m
43 #define Q       saved_state.asregs.sr.bits.q
44
45 #define GET_SR() (saved_state.asregs.sr.bits.t = T, saved_state.asregs.sr.word)
46 #define SET_SR(x) {saved_state.asregs.sr.word = (x); T =saved_state.asregs.sr.bits.t;}
47
48 #define PC pc
49 #define C cycles
50
51 #ifdef TARGET_BIG_ENDIAN
52 #define LMEM(x)         *((long *)(memory+((x)&maskl)))
53 #define BMEM(x)         *((char *)(memory+((x)&maskb)))
54 #define UWMEM(x)        *((unsigned short *)(memory+((x)&maskw)))
55 #define SWMEM(x)        *((short *)(memory+((x)&maskw)))
56 #define WLAT(x,value)   (LMEM(x) = value)
57 #define RLAT(x)         (LMEM(x))
58 #define WWAT(x,value)   (UWMEM(x) = value)
59 #define RSWAT(x)        (SWMEM(x))
60 #define RUWAT(x)        (UWMEM(x))
61 #define WBAT(x,value)   (BMEM(x) = value)
62 #define RBAT(x)         (BMEM(x))
63 #else
64 /* For little endian or unknown host machines */
65 #define WLAT(x,value)\
66 { int v = value; unsigned char *p = memory + ((x) & maskl);\
67   p[0] =v>>24;p[1] = v>>16;p[2]=v>>8;p[3]=v; }
68
69 #define WWAT(x,value)\
70 { int v = value; unsigned char *p = memory + (x & maskw);p[0] =v>>8;p[1] = v ;}
71
72 #define WBAT(x,value)\
73 { unsigned char *p = memory + (x & maskb);p[0] =value;}
74
75 #define RLAT(x)\
76   ((memory[x&maskl]<<24)|(memory[(x&maskl)+1]<<16)|(memory[(x&maskl)+2]<<8)| (memory[(x&maskl)+3]))
77
78 #define RWAT(x)\
79   ((memory[x&maskw]<<8)|(memory[(x&maskw)+1]))
80
81 #define RBAT(x)\
82   ((memory[x&maskb]))
83
84 #define RUWAT(x)  (RWAT(x) & 0xffff)
85 #define RSWAT(x)  ((short)(RWAT(x)))
86 #define RSBAT(x)  (SEXT(RBAT(x)))
87
88 #endif
89
90
91
92 #define SEXT(x)         (((x&0xff) ^ (~0x7f))+0x80)
93 #define SEXTW(y)        ((int)((short)y))
94
95 #define SL(TEMPPC)      iword= RUWAT(TEMPPC); goto top;
96
97
98 #define L(x)   thislock = x;
99 #define TL(x)  if ((x) == prevlock) stalls++;
100 #define TB(x,y)  if ((x) == prevlock || (y)==prevlock) stalls++;
101 int sim_memory_size = 19;
102 static int sim_profile_size = 17;
103 static int nsamples;
104 static int sim_timeout;
105
106 typedef union
107 {
108
109   struct
110     {
111
112       int regs[16];
113       int pc;
114       int pr;
115
116       int gbr;
117       int vbr;
118       int mach;
119       int macl;
120
121
122       union
123         {
124           struct
125             {
126               unsigned int d0:22;
127               unsigned int m:1;
128               unsigned int q:1;
129               unsigned int i:4;
130               unsigned int d1:2;
131               unsigned int s:1;
132               unsigned int t:1;
133             }
134           bits;
135           int word;
136         }
137       sr;
138       int ticks;
139       int stalls;
140       int cycles;
141       int insts;
142
143
144       int prevlock;
145       int thislock;
146       int exception;
147       int msize;
148 #define PROFILE_FREQ 1
149 #define PROFILE_SHIFT 2
150       int profile;
151       unsigned short *profile_hist;
152       unsigned char *memory;
153
154     }
155   asregs;
156   int asints[28];
157
158 }
159
160 saved_state_type;
161 saved_state_type saved_state;
162
163 static int
164 get_now ()
165 {
166   return time((char*)0);
167 }
168
169 static int
170 now_persec ()
171 {
172   return 1;
173 }
174
175
176
177 static FILE *profile_file;
178
179 static void 
180 swap (b, n)
181      unsigned char *b;
182      int n;
183 {
184   b[0] = n >> 24;
185   b[1] = n >> 16;
186   b[2] = n >> 8;
187   b[3] = n >> 0;
188 }
189 static void 
190 swap16 (b, n)
191      unsigned char *b;
192      int n;
193 {
194   b[0] = n >> 8;
195   b[1] = n >> 0;
196 }
197
198 static void
199 swapout (n)
200      int n;
201 {
202   if (profile_file)
203     {
204       char b[4];
205       swap (b, n);
206       fwrite (b, 4, 1, profile_file);
207     }
208 }
209
210 static void
211 swapout16 (n)
212      int n;
213 {
214   char b[4];
215   swap16 (b, n);
216   fwrite (b, 2, 1, profile_file);
217 }
218
219
220 /* Turn a pointer in a register into a pointer into real memory. */
221
222 static char *
223 ptr (x)
224      int x;
225 {
226   return (char *) (x + saved_state.asregs.memory);
227 }
228
229 /* Simulate a monitor trap.  */
230
231 static void
232 trap (i, regs)
233      int i;
234      int *regs;
235 {
236   switch (i)
237     {
238     case 1:
239       printf ("%c", regs[0]);
240       break;
241     case 2:
242       saved_state.asregs.exception = SIGQUIT;
243       break;
244     case 3:
245       {
246         extern int errno;
247         int perrno = errno;
248         errno = 0;
249
250         switch (regs[4])
251           {
252           case 3:
253             regs[4] = read (regs[5], ptr (regs[6]), regs[7]);
254             break;
255           case 4:
256             regs[4] = write (regs[5], ptr (regs[6]), regs[7]);
257             break;
258           case 19:
259             regs[4] = lseek (regs[5], regs[6], regs[7]);
260             break;
261           case 6:
262             regs[4] = close (regs[5]);
263             break;
264           case 5:
265             regs[4] = open (ptr (regs[5]), regs[6]);
266             break;
267           case 1:
268             /* EXIT */
269             saved_state.asregs.exception = SIGQUIT;
270             errno = regs[5];
271             break;
272             
273           default:
274             abort ();
275           }
276         regs[0] = errno;
277         errno = perrno;
278       }
279
280       break;
281
282     case 255:
283       saved_state.asregs.exception = SIGTRAP;
284       break;
285     }
286
287 }
288 void
289 control_c (sig, code, scp, addr)
290      int sig;
291      int code;
292      char *scp;
293      char *addr;
294 {
295   saved_state.asregs.exception = SIGINT;
296 }
297
298
299 static int
300 div1 (R, iRn2, iRn1, T)
301      int *R;
302      int iRn1;
303      int iRn2;
304      int T;
305 {
306   unsigned long tmp0;
307   unsigned char old_q, tmp1;
308
309   old_q = Q;
310   Q = (unsigned char) ((0x80000000 & R[iRn1]) != 0);
311   R[iRn1] <<= 1;
312   R[iRn1] |= (unsigned long) T;
313
314   switch (old_q)
315     {
316     case 0:
317       switch (M)
318         {
319         case 0:
320           tmp0 = R[iRn1];
321           R[iRn1] -= R[iRn2];
322           tmp1 = (R[iRn1] > tmp0);
323           switch (Q)
324             {
325             case 0:
326               Q = tmp1;
327               break;
328             case 1:
329               Q = (unsigned char) (tmp1 == 0);
330               break;
331             }
332           break;
333         case 1:
334           tmp0 = R[iRn1];
335           R[iRn1] += R[iRn2];
336           tmp1 = (R[iRn1] < tmp0);
337           switch (Q)
338             {
339             case 0:
340               Q = (unsigned char) (tmp1 == 0);
341               break;
342             case 1:
343               Q = tmp1;
344               break;
345             }
346           break;
347         }
348       break;
349     case 1:
350       switch (M)
351         {
352         case 0:
353           tmp0 = R[iRn1];
354           R[iRn1] += R[iRn2];
355           tmp1 = (R[iRn1] < tmp0);
356           switch (Q)
357             {
358             case 0:
359               Q = tmp1;
360               break;
361             case 1:
362               Q = (unsigned char) (tmp1 == 0);
363               break;
364             }
365           break;
366         case 1:
367           tmp0 = R[iRn1];
368           R[iRn1] -= R[iRn2];
369           tmp1 = (R[iRn1] > tmp0);
370           switch (Q)
371             {
372             case 0:
373               Q = (unsigned char) (tmp1 == 0);
374               break;
375             case 1:
376               Q = tmp1;
377               break;
378             }
379           break;
380         }
381       break;
382     }
383   T = (Q == M);
384   return T;
385 }
386
387
388 static void 
389 dmul (sign, rm, rn)
390      int sign;
391      unsigned int rm;
392      unsigned int rn;
393 {
394   unsigned long RnL, RnH;
395   unsigned long RmL, RmH;
396   unsigned long temp0, temp1, temp2, temp3;
397   unsigned long Res2, Res1, Res0;
398
399
400   if (!sign)
401     {
402
403       RnL = rn & 0xffff;
404       RnH = (rn >> 16) & 0xffff;
405       RmL = rm & 0xffff;
406       RmH = (rm >> 16) & 0xffff;
407       temp0 = RmL * RnL;
408       temp1 = RmH * RnL;
409       temp2 = RmL * RnH;
410       temp3 = RmH * RnH;
411       Res2 = 0;
412       Res1 = temp1 + temp2;
413       if (Res1 < temp1)
414         Res2 += 0x00010000;
415       temp1 = (Res1 << 16) & 0xffff0000;
416       Res0 = temp0 + temp1;
417       if (Res0 < temp0)
418         Res2 += 1;
419       Res2 += ((Res1 >> 16) & 0xffff) + temp3;
420       MACH = Res2;
421       MACL = Res0;
422
423     }
424
425   else
426     {
427       abort ();
428     }
429
430 }
431
432
433 /* Set the memory size to the power of two provided. */
434
435 void
436 sim_size (power)
437      int power;
438
439 {
440   saved_state.asregs.msize = 1 << power;
441
442   sim_memory_size = power;
443
444
445   if (saved_state.asregs.memory)
446     {
447       free (saved_state.asregs.memory);
448     }
449
450   saved_state.asregs.memory =
451     (unsigned char *) calloc (64, saved_state.asregs.msize / 64);
452
453   if (!saved_state.asregs.memory)
454     {
455       fprintf (stderr,
456                "Not enough VM for simuation of %d bytes of RAM\n",
457                saved_state.asregs.msize);
458
459       saved_state.asregs.msize = 1;
460       saved_state.asregs.memory = (unsigned char *) calloc (1, 1);
461     }
462 }
463
464
465
466 static
467 void
468 init_pointers ()
469 {
470   if (saved_state.asregs.msize != 1 << sim_memory_size)
471     {
472       sim_size (sim_memory_size);
473     }
474
475   if (saved_state.asregs.profile && !profile_file)
476     {
477       profile_file = fopen ("gmon.out", "wb");
478       /* Seek to where to put the call arc data */
479       nsamples = (1 << sim_profile_size);
480
481       fseek (profile_file, nsamples * 2 + 12, 0);
482
483       if (!profile_file)
484         {
485           fprintf (stderr, "Can't open gmon.out\n");
486         }
487       else
488         {
489           saved_state.asregs.profile_hist =
490             (unsigned short *) calloc (64, (nsamples * sizeof (short) / 64));
491         }
492     }
493 }
494
495 static void
496 dump_profile ()
497 {
498   unsigned int minpc;
499   unsigned int maxpc;
500   unsigned short *p;
501
502   int thisshift;
503
504   unsigned short *first;
505
506   int i;
507   p = saved_state.asregs.profile_hist;
508   minpc = 0;
509   maxpc = (1 << sim_profile_size);
510
511   fseek (profile_file, 0L, 0);
512   swapout (minpc << PROFILE_SHIFT);
513   swapout (maxpc << PROFILE_SHIFT);
514   swapout (nsamples * 2 + 12);
515   for (i = 0; i < nsamples; i++)
516     swapout16 (saved_state.asregs.profile_hist[i]);
517
518 }
519
520 static int 
521 gotcall (from, to)
522      int from;
523      int to;
524 {
525   swapout (from);
526   swapout (to);
527   swapout (1);
528 }
529
530 #define MMASKB ((saved_state.asregs.msize -1) & ~0)
531 void
532 sim_resume (step)
533      int step;
534 {
535   register unsigned int pc;
536   register int cycles = 0;
537   register int stalls = 0;
538   register int insts = 0;
539   register int prevlock;
540   register int thislock;
541   register unsigned int doprofile;
542
543   int tick_start = get_now ();
544   void (*prev) ();
545   extern unsigned char sh_jump_table0[];
546
547   register unsigned char *jump_table = sh_jump_table0;
548
549   register int *R = &(saved_state.asregs.regs[0]);
550   register int T;
551   register int PR;
552
553   register int maskb = ((saved_state.asregs.msize - 1) & ~0);
554   register int maskw = ((saved_state.asregs.msize - 1) & ~1);
555   register int maskl = ((saved_state.asregs.msize - 1) & ~3);
556   register unsigned char *memory ;
557   register unsigned int sbit = (1 << 31);
558
559   prev = signal (SIGINT, control_c);
560
561   init_pointers ();
562
563   memory = saved_state.asregs.memory;
564
565   if (step)
566     {
567       saved_state.asregs.exception = SIGTRAP;
568     }
569   else
570     {
571       saved_state.asregs.exception = 0;
572     }
573
574   pc = saved_state.asregs.pc;
575   PR = saved_state.asregs.pr;
576   T = saved_state.asregs.sr.bits.t;
577   prevlock = saved_state.asregs.prevlock;
578   thislock = saved_state.asregs.thislock;
579   doprofile = saved_state.asregs.profile;
580
581   /* If profiling not enabled, disable it by asking for
582      profiles infrequently. */
583   if (doprofile == 0)
584     doprofile = ~0;
585
586   do
587     {
588       register unsigned int iword = RUWAT (pc);
589       register unsigned int ult;
590
591       insts++;
592     top:
593
594 #include "code.c"
595
596
597       pc += 2;
598       prevlock = thislock;
599       thislock = 30;
600       cycles++;
601
602       if (cycles >= doprofile)
603         {
604           if (cycles > sim_timeout)
605             saved_state.asregs.exception = SIGQUIT;
606           
607           saved_state.asregs.cycles += doprofile;
608           cycles -= doprofile;
609           if (saved_state.asregs.profile_hist)
610             {
611               int n = pc >> PROFILE_SHIFT;
612               if (n < nsamples)
613                 {
614                   int i = saved_state.asregs.profile_hist[n];
615                   if (i < 65000)
616                     saved_state.asregs.profile_hist[n] = i + 1;
617                 }
618
619             }
620         }
621     }
622   while (!saved_state.asregs.exception);
623
624   if (saved_state.asregs.exception == SIGILL)
625     {
626       pc -= 2;
627     }
628
629   saved_state.asregs.ticks += get_now () - tick_start;
630   saved_state.asregs.cycles += cycles;
631   saved_state.asregs.stalls += stalls;
632   saved_state.asregs.insts += insts;
633   saved_state.asregs.pc = pc;
634   saved_state.asregs.sr.bits.t = T;
635   saved_state.asregs.pr = PR;
636
637   saved_state.asregs.prevlock = prevlock;
638   saved_state.asregs.thislock = thislock;
639
640
641   if (profile_file)
642     {
643       dump_profile ();
644     }
645
646   signal (SIGINT, prev);
647 }
648
649
650
651
652 int
653 sim_write (addr, buffer, size)
654      long int addr;
655      unsigned char *buffer;
656      int size;
657 {
658   int i;
659   init_pointers ();
660
661   for (i = 0; i < size; i++)
662     {
663       saved_state.asregs.memory[MMASKB & (addr + i)] = buffer[i];
664     }
665 return size;
666 }
667
668 int
669 sim_read (addr, buffer, size)
670      long int addr;
671      char *buffer;
672      int size;
673 {
674   int i;
675
676   init_pointers ();
677
678   for (i = 0; i < size; i++)
679     {
680       buffer[i] = saved_state.asregs.memory[MMASKB & (addr + i)];
681     }
682 return size;
683 }
684
685
686 void
687 sim_store_register (rn, value)
688      int rn;
689      unsigned char value[4];
690 {
691   saved_state.asregs.regs[rn] = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | (value[3]);
692 }
693
694 void
695 sim_fetch_register (rn, buf)
696      int rn;
697      char *buf;
698 {
699   int value = ((int *) (&saved_state))[rn];
700
701   swap (buf, value);
702 }
703
704
705 int
706 sim_trace ()
707 {
708   return 0;
709 }
710
711 enum sim_stop
712 sim_stop_signal (sigrc)
713      int *sigrc;
714 {
715   *sigrc = saved_state.asregs.exception;
716   return sim_stopped;
717 }
718
719 void
720 sim_set_pc (x)
721      int x;
722 {
723   saved_state.asregs.pc = x;
724 }
725
726
727 void
728 sim_info ()
729 {
730   double timetaken = (double) saved_state.asregs.ticks / (double) now_persec ();
731   double virttime = saved_state.asregs.cycles / 36.0e6;
732
733   printf ("\n\n# instructions executed  %10d\n", saved_state.asregs.insts);
734   printf ("# cycles                 %10d\n", saved_state.asregs.cycles);
735   printf ("# pipeline stalls        %10d\n", saved_state.asregs.stalls);
736   printf ("# real time taken        %10.4f\n", timetaken);
737   printf ("# virtual time taken     %10.4f\n", virttime);
738   printf ("# profiling size         %10d\n", sim_profile_size);
739   printf ("# profiling frequency    %10d\n", saved_state.asregs.profile);
740   printf ("# profile maxpc          %10x\n", (1 << sim_profile_size) << PROFILE_SHIFT);
741
742   if (timetaken != 0)
743     {
744       printf ("# cycles/second          %10d\n", (int) (saved_state.asregs.cycles / timetaken));
745       printf ("# simulation ratio       %10.4f\n", virttime / timetaken);
746     }
747 }
748
749
750 void
751 sim_set_profile (n)
752      int n;
753 {
754   saved_state.asregs.profile = n;
755 }
756
757 void
758 sim_set_profile_size (n)
759      int n;
760 {
761   sim_profile_size = n;
762 }
763
764
765 void
766 sim_kill()
767 {
768
769 }
770
771 int
772 sim_open()
773 {
774   return 0;
775 }
776 int sim_set_args()
777 {
778   return 0;
779 }
780
781
This page took 0.063586 seconds and 4 git commands to generate.