* interp.c (BUSERROR): New macro.
[external/binutils.git] / sim / sh / interp.c
1 /* Simulator for the Hitachi SH architecture.
2
3    Written by Steve Chamberlain of Cygnus Support.
4    sac@cygnus.com
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
21 #include <signal.h>
22 #include "sysdep.h"
23 #include <sys/times.h>
24 #include <sys/param.h>
25 #include "bfd.h"
26 #include "remote-sim.h"
27 #include "../../newlib/libc/sys/sh/sys/syscall.h"
28 #define O_RECOMPILE 85
29 #define DEFINE_TABLE
30 /*#define ACE_FAST*/
31 #define DISASSEMBLER_TABLE
32
33 #define SBIT(x) ((x)&sbit)
34 #define R0      saved_state.asregs.regs[0]
35 #define Rn      saved_state.asregs.regs[n]
36 #define Rm      saved_state.asregs.regs[m]
37 #define UR0     (unsigned int)(saved_state.asregs.regs[0])
38 #define UR      (unsigned int)R
39 #define UR      (unsigned int)R
40 #define SR0     saved_state.asregs.regs[0]
41 #define GBR     saved_state.asregs.gbr
42 #define VBR     saved_state.asregs.vbr
43 #define MACH    saved_state.asregs.mach
44 #define MACL    saved_state.asregs.macl
45 #define M       saved_state.asregs.sr.bits.m
46 #define Q       saved_state.asregs.sr.bits.q
47
48 #define GET_SR() (saved_state.asregs.sr.bits.t = T, saved_state.asregs.sr.word)
49 #define SET_SR(x) {saved_state.asregs.sr.word = (x); T =saved_state.asregs.sr.bits.t;}
50
51 #define PC pc
52 #define C cycles
53
54 int 
55 fail ()
56 {
57   abort ();
58
59 }
60
61 #define BUSERROR(addr, mask) \
62   if (addr & ~mask)  { saved_state.asregs.exception = SIGBUS;}
63
64 /* Define this to enable register lifetime checking.
65    The compiler generates "add #0,rn" insns to mark registers as invalid,
66    the simulator uses this info to call fail if it finds a ref to an invalid
67    register before a def
68
69    #define PARANOID
70 */
71
72 #ifdef PARANOID
73 int valid[16];
74 #define CREF(x)  if(!valid[x]) fail();
75 #define CDEF(x)  valid[x] = 1;
76 #define UNDEF(x) valid[x] = 0;
77 #else
78 #define CREF(x)
79 #define CDEF(x)
80 #define UNDEF(x)
81 #endif
82
83 #ifdef __GNUC__
84 #define INLINE inline
85 #else
86 #define INLINE
87 #endif
88
89 /* These variables are at file scope so that functions other than
90    sim_resume can use the fetch/store macros */
91
92 static int  little_endian;
93
94 #if 1
95 static int maskl = ~0;
96 static int maskw = ~0;
97 #endif
98 typedef union
99 {
100
101   struct
102   {
103
104     int regs[16];
105     int pc;
106     int pr;
107
108     int gbr;
109     int vbr;
110     int mach;
111     int macl;
112
113
114     union
115       {
116         struct
117           {
118             unsigned int d0:22;
119             unsigned int m:1;
120             unsigned int q:1;
121             unsigned int i:4;
122             unsigned int d1:2;
123             unsigned int s:1;
124             unsigned int t:1;
125           }
126         bits;
127         int word;
128       }
129     sr;
130     int ticks;
131     int stalls;
132     int cycles;
133     int insts;
134
135
136     int prevlock;
137     int thislock;
138     int exception;
139     int msize;
140 #define PROFILE_FREQ 1
141 #define PROFILE_SHIFT 2
142     int profile;
143     unsigned short *profile_hist;
144     unsigned char *memory;
145
146   }
147   asregs;
148   int asints[28];
149
150 } saved_state_type;
151 saved_state_type saved_state;
152
153 static void INLINE 
154 wlat_little (memory, x, value, maskl)
155      unsigned char *memory;
156 {
157   int v = value;
158   unsigned char *p = memory + ((x) & maskl);
159   BUSERROR(x, maskl);
160   p[3] = v >> 24;
161   p[2] = v >> 16;
162   p[1] = v >> 8;
163   p[0] = v;
164 }
165
166 static void INLINE 
167 wwat_little (memory, x, value, maskw)
168      unsigned char *memory;
169 {
170   int v = value;
171   unsigned char *p = memory + ((x) & maskw);
172   BUSERROR(x, maskw);
173
174   p[1] = v >> 8;
175   p[0] = v;
176 }
177
178
179 static void INLINE 
180 wbat_any (memory, x, value, maskb)
181      unsigned char *memory;
182 {
183   unsigned char *p = memory + (x & maskb);
184   if (x > 0x5000000)
185     IOMEM (x, 1, value);
186   BUSERROR(x, maskb);
187
188   p[0] = value;
189 }
190
191
192
193 static void INLINE 
194 wlat_big (memory, x, value, maskl)
195      unsigned char *memory;
196 {
197   int v = value;
198   unsigned char *p = memory + ((x) & maskl);
199   BUSERROR(x, maskl);
200
201   p[0] = v >> 24;
202   p[1] = v >> 16;
203   p[2] = v >> 8;
204   p[3] = v;
205 }
206
207 static void INLINE 
208 wwat_big (memory, x, value, maskw)
209      unsigned char *memory;
210 {
211   int v = value;
212   unsigned char *p = memory + ((x) & maskw);
213   BUSERROR(x, maskw);
214
215   p[0] = v >> 8;
216   p[1] = v;
217 }
218
219
220 static void INLINE 
221 wbat_big (memory, x, value, maskb)
222      unsigned char *memory;
223 {
224   unsigned char *p = memory + (x & maskb);
225   BUSERROR(x, maskb);
226
227   if (x > 0x5000000)
228     IOMEM (x, 1, value);
229   p[0] = value;
230 }
231
232
233
234 /* Read functions */
235 static int INLINE 
236 rlat_little (memory, x, maskl)
237      unsigned char *memory;
238 {
239   unsigned char *p = memory + ((x) & maskl);
240   BUSERROR(x, maskl);
241
242   return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
243
244 }
245
246 static int INLINE 
247 rwat_little (memory, x, maskw)
248      unsigned char *memory;
249 {
250   unsigned char *p = memory + ((x) & maskw);
251   BUSERROR(x, maskw);
252
253   return (p[1] << 8) | p[0];
254 }
255
256 static int INLINE 
257 rbat_any (memory, x, maskb)
258      unsigned char *memory;
259 {
260   unsigned char *p = memory + ((x) & maskb);
261   BUSERROR(x, maskb);
262
263   return p[0];
264 }
265
266 static int INLINE 
267 rlat_big (memory, x, maskl)
268      unsigned char *memory;
269 {
270   unsigned char *p = memory + ((x) & maskl);
271   BUSERROR(x, maskl);
272
273   return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
274
275 }
276
277 static int INLINE 
278 rwat_big (memory, x, maskw)
279      unsigned char *memory;
280 {
281   unsigned char *p = memory + ((x) & maskw);
282   BUSERROR(x, maskw);
283
284   return (p[0] << 8) | p[1];
285 }
286
287
288 #define RWAT(x)         (little_endian ? rwat_little(memory, x, maskw): rwat_big(memory, x, maskw))
289 #define RLAT(x)         (little_endian ? rlat_little(memory, x, maskl): rlat_big(memory, x, maskl))
290 #define RBAT(x)         (rbat_any (memory, x, maskb))
291 #define WWAT(x,v)       (little_endian ? wwat_little(memory, x, v, maskw): wwat_big(memory, x, v, maskw))
292 #define WLAT(x,v)       (little_endian ? wlat_little(memory, x, v, maskl): wlat_big(memory, x, v, maskl))
293 #define WBAT(x,v)       (wbat_any (memory, x, v, maskb))
294
295 #define RUWAT(x)  (RWAT(x) & 0xffff)
296 #define RSWAT(x)  ((short)(RWAT(x)))
297 #define RSBAT(x)  (SEXT(RBAT(x)))
298
299 #define SEXT(x)         (((x&0xff) ^ (~0x7f))+0x80)
300 #define SEXTW(y)        ((int)((short)y))
301
302 #define SL(TEMPPC)      iword= RUWAT(TEMPPC); goto top;
303
304
305 int empty[16];
306
307 #define L(x)   thislock = x;
308 #define TL(x)  if ((x) == prevlock) stalls++;
309 #define TB(x,y)  if ((x) == prevlock || (y)==prevlock) stalls++;
310
311 #ifdef __GO32__
312 int sim_memory_size = 19;
313 #else
314 int sim_memory_size = 24;
315 #endif
316
317 static int sim_profile_size = 17;
318 static int nsamples;
319
320 #undef TB
321 #define TB(x,y)
322
323 #define SMR1 (0x05FFFEC8)       /* Channel 1  serial mode register */
324 #define BRR1 (0x05FFFEC9)       /* Channel 1  bit rate register */
325 #define SCR1 (0x05FFFECA)       /* Channel 1  serial control register */
326 #define TDR1 (0x05FFFECB)       /* Channel 1  transmit data register */
327 #define SSR1 (0x05FFFECC)       /* Channel 1  serial status register */
328 #define RDR1 (0x05FFFECD)       /* Channel 1  receive data register */
329
330 #define SCI_RDRF         0x40   /* Recieve data register full */
331 #define SCI_TDRE        0x80    /* Transmit data register empty */
332
333 static int
334 IOMEM (addr, write, value)
335      int addr;
336      int write;
337      int value;
338 {
339   static int io;
340   static char ssr1;
341   int x;
342   static char lastchar;
343
344   if (write)
345     {
346       switch (addr)
347         {
348         case TDR1:
349           if (value != '\r')
350             {
351               putchar (value);
352               fflush (stdout);
353             }
354           break;
355         }
356     }
357   else
358     {
359       switch (addr)
360         {
361         case RDR1:
362           return getchar ();
363         }
364     }
365 }
366
367
368
369 static int
370 get_now ()
371 {
372   return time ((long *) 0);
373 }
374
375 static int
376 now_persec ()
377 {
378   return 1;
379 }
380
381
382
383 static FILE *profile_file;
384
385 static void
386 swap (memory, n)
387      unsigned char *memory;
388      int n;
389 {
390   WLAT (0, n);
391 }
392 static void
393 swap16 (memory, n)
394      unsigned char *memory;
395      int n;
396 {
397   WWAT (0, n);
398 }
399
400 static void
401 swapout (n)
402      int n;
403 {
404   if (profile_file)
405     {
406       char b[4];
407       swap (b, n);
408       fwrite (b, 4, 1, profile_file);
409     }
410 }
411
412 static void
413 swapout16 (n)
414      int n;
415 {
416   char b[4];
417   swap16 (b, n);
418   fwrite (b, 2, 1, profile_file);
419 }
420
421
422 /* Turn a pointer in a register into a pointer into real memory. */
423
424 static char *
425 ptr (x)
426      int x;
427 {
428   return (char *) (x + saved_state.asregs.memory);
429 }
430
431
432 /* Simulate a monitor trap, put the result into r0 and errno into r1 */
433 static void
434 trap (i, regs, memory, maskl, maskw, little_endian)
435      int i;
436      int *regs;
437      unsigned char *memory;
438 {
439   switch (i)
440     {
441     case 1:
442       printf ("%c", regs[0]);
443       break;
444     case 2:
445       saved_state.asregs.exception = SIGQUIT;
446       break;
447 #if 0
448     case 8:
449       trap8 (ptr (regs[4]));
450       break;
451     case 9:
452       trap9 (ptr (regs[4]));
453       break;
454     case 10:
455       trap10 ();
456       break;
457     case 11:
458       regs[0] = trap11 ();
459       break;
460     case 12:
461       regs[0] = trap12 ();
462       break;
463 #endif
464     case 3:
465       {
466         extern int errno;
467         int perrno = errno;
468         errno = 0;
469
470         switch (regs[4])
471           {
472
473 #ifndef __GO32__
474
475           case SYS_fork:
476             regs[0] = fork ();
477             break;
478           case SYS_execve:
479             regs[0] = execve (ptr (regs[5]), ptr (regs[6]), ptr (regs[7]));
480             break;
481           case SYS_execv:
482             regs[0] = execv (ptr (regs[5]), ptr (regs[6]));
483             break;
484           case SYS_pipe:
485             {
486               char *buf;
487               int host_fd[2];
488
489               buf = ptr (regs[5]);
490
491               regs[0] = pipe (host_fd);
492
493               WLAT (buf, host_fd[0]);
494               buf += 4;
495               WLAT (buf, host_fd[1]);
496             }
497             break;
498
499           case SYS_wait:
500             regs[0] = wait (ptr (regs[5]));
501             break;
502 #endif
503
504           case SYS_read:
505             regs[0] = read (regs[5], ptr (regs[6]), regs[7]);
506             break;
507           case SYS_write:
508             regs[0] = write (regs[5], ptr (regs[6]), regs[7]);
509             break;
510           case SYS_lseek:
511             regs[0] = lseek (regs[5], regs[6], regs[7]);
512             break;
513           case SYS_close:
514             regs[0] = close (regs[5]);
515             break;
516           case SYS_open:
517             regs[0] = open (ptr (regs[5]), regs[6]);
518             break;
519           case SYS_exit:
520             /* EXIT - caller can look in r5 to work out the 
521                reason */
522             saved_state.asregs.exception = SIGQUIT;
523             break;
524
525           case SYS_stat:        /* added at hmsi */
526             /* stat system call */
527             {
528               struct stat host_stat;
529               char *buf;
530
531               regs[0] = stat (ptr (regs[5]), &host_stat);
532
533               buf = ptr (regs[6]);
534
535               WWAT (buf, host_stat.st_dev);
536               buf += 2;
537               WWAT (buf, host_stat.st_ino);
538               buf += 2;
539               WLAT (buf, host_stat.st_mode);
540               buf += 4;
541               WWAT (buf, host_stat.st_nlink);
542               buf += 2;
543               WWAT (buf, host_stat.st_uid);
544               buf += 2;
545               WWAT (buf, host_stat.st_gid);
546               buf += 2;
547               WWAT (buf, host_stat.st_rdev);
548               buf += 2;
549               WLAT (buf, host_stat.st_size);
550               buf += 4;
551               WLAT (buf, host_stat.st_atime);
552               buf += 4;
553               WLAT (buf, 0);
554               buf += 4;
555               WLAT (buf, host_stat.st_mtime);
556               buf += 4;
557               WLAT (buf, 0);
558               buf += 4;
559               WLAT (buf, host_stat.st_ctime);
560               buf += 4;
561               WLAT (buf, 0);
562               buf += 4;
563               WLAT (buf, 0);
564               buf += 4;
565               WLAT (buf, 0);
566               buf += 4;
567             }
568             break;
569
570           case SYS_chown:
571             regs[0] = chown (ptr (regs[5]), regs[6], regs[7]);
572             break;
573           case SYS_chmod:
574             regs[0] = chmod (ptr (regs[5]), regs[6]);
575             break;
576           case SYS_utime:
577             regs[0] = utime (ptr (regs[5]), ptr (regs[6]));
578             break;
579           default:
580             abort ();
581           }
582         regs[1] = errno;
583         errno = perrno;
584       }
585
586       break;
587
588     case 0xc3:
589     case 255:
590       saved_state.asregs.exception = SIGTRAP;
591       break;
592     }
593
594 }
595 void
596 control_c (sig, code, scp, addr)
597      int sig;
598      int code;
599      char *scp;
600      char *addr;
601 {
602   saved_state.asregs.exception = SIGINT;
603 }
604
605
606 static int
607 div1 (R, iRn2, iRn1, T)
608      int *R;
609      int iRn1;
610      int iRn2;
611      int T;
612 {
613   unsigned long tmp0;
614   unsigned char old_q, tmp1;
615
616   old_q = Q;
617   Q = (unsigned char) ((0x80000000 & R[iRn1]) != 0);
618   R[iRn1] <<= 1;
619   R[iRn1] |= (unsigned long) T;
620
621   switch (old_q)
622     {
623     case 0:
624       switch (M)
625         {
626         case 0:
627           tmp0 = R[iRn1];
628           R[iRn1] -= R[iRn2];
629           tmp1 = (R[iRn1] > tmp0);
630           switch (Q)
631             {
632             case 0:
633               Q = tmp1;
634               break;
635             case 1:
636               Q = (unsigned char) (tmp1 == 0);
637               break;
638             }
639           break;
640         case 1:
641           tmp0 = R[iRn1];
642           R[iRn1] += R[iRn2];
643           tmp1 = (R[iRn1] < tmp0);
644           switch (Q)
645             {
646             case 0:
647               Q = (unsigned char) (tmp1 == 0);
648               break;
649             case 1:
650               Q = tmp1;
651               break;
652             }
653           break;
654         }
655       break;
656     case 1:
657       switch (M)
658         {
659         case 0:
660           tmp0 = R[iRn1];
661           R[iRn1] += R[iRn2];
662           tmp1 = (R[iRn1] < tmp0);
663           switch (Q)
664             {
665             case 0:
666               Q = tmp1;
667               break;
668             case 1:
669               Q = (unsigned char) (tmp1 == 0);
670               break;
671             }
672           break;
673         case 1:
674           tmp0 = R[iRn1];
675           R[iRn1] -= R[iRn2];
676           tmp1 = (R[iRn1] > tmp0);
677           switch (Q)
678             {
679             case 0:
680               Q = (unsigned char) (tmp1 == 0);
681               break;
682             case 1:
683               Q = tmp1;
684               break;
685             }
686           break;
687         }
688       break;
689     }
690   T = (Q == M);
691   return T;
692 }
693
694
695 static void
696 dmul (sign, rm, rn)
697      int sign;
698      unsigned int rm;
699      unsigned int rn;
700 {
701   unsigned long RnL, RnH;
702   unsigned long RmL, RmH;
703   unsigned long temp0, temp1, temp2, temp3;
704   unsigned long Res2, Res1, Res0;
705
706
707   if (!sign)
708     {
709
710       RnL = rn & 0xffff;
711       RnH = (rn >> 16) & 0xffff;
712       RmL = rm & 0xffff;
713       RmH = (rm >> 16) & 0xffff;
714       temp0 = RmL * RnL;
715       temp1 = RmH * RnL;
716       temp2 = RmL * RnH;
717       temp3 = RmH * RnH;
718       Res2 = 0;
719       Res1 = temp1 + temp2;
720       if (Res1 < temp1)
721         Res2 += 0x00010000;
722       temp1 = (Res1 << 16) & 0xffff0000;
723       Res0 = temp0 + temp1;
724       if (Res0 < temp0)
725         Res2 += 1;
726       Res2 += ((Res1 >> 16) & 0xffff) + temp3;
727       MACH = Res2;
728       MACL = Res0;
729
730     }
731
732   else
733     {
734 #ifdef __GNUC__
735       long long res;
736       long long a = rn;
737       long long b = rm;
738       res = a * b;
739       MACH = res >> 32;
740       MACL = res & 0xffffffff;
741 #else
742       abort ();
743 #endif
744     }
745
746 }
747
748
749 /* Set the memory size to the power of two provided. */
750
751 void
752 sim_size (power)
753      int power;
754
755 {
756   saved_state.asregs.msize = 1 << power;
757
758   sim_memory_size = power;
759
760
761   if (saved_state.asregs.memory)
762     {
763       free (saved_state.asregs.memory);
764     }
765
766   saved_state.asregs.memory =
767     (unsigned char *) calloc (64, saved_state.asregs.msize / 64);
768
769   if (!saved_state.asregs.memory)
770     {
771       fprintf (stderr,
772                "Not enough VM for simulation of %d bytes of RAM\n",
773                saved_state.asregs.msize);
774
775       saved_state.asregs.msize = 1;
776       saved_state.asregs.memory = (unsigned char *) calloc (1, 1);
777     }
778 }
779
780
781 extern int target_byte_order;
782
783 static void
784 set_static_little_endian(x)
785 int x;
786 {
787   little_endian = x;
788 }
789
790 static
791 void
792 init_pointers ()
793 {
794   register int little_endian = target_byte_order == 1234;
795   set_static_little_endian (little_endian);
796   if (saved_state.asregs.msize != 1 << sim_memory_size)
797     {
798       sim_size (sim_memory_size);
799     }
800
801   if (saved_state.asregs.profile && !profile_file)
802     {
803       profile_file = fopen ("gmon.out", "wb");
804       /* Seek to where to put the call arc data */
805       nsamples = (1 << sim_profile_size);
806
807       fseek (profile_file, nsamples * 2 + 12, 0);
808
809       if (!profile_file)
810         {
811           fprintf (stderr, "Can't open gmon.out\n");
812         }
813       else
814         {
815           saved_state.asregs.profile_hist =
816             (unsigned short *) calloc (64, (nsamples * sizeof (short) / 64));
817         }
818     }
819 }
820
821 static void
822 dump_profile ()
823 {
824   unsigned int minpc;
825   unsigned int maxpc;
826   unsigned short *p;
827
828   int thisshift;
829
830   unsigned short *first;
831
832   int i;
833   p = saved_state.asregs.profile_hist;
834   minpc = 0;
835   maxpc = (1 << sim_profile_size);
836
837   fseek (profile_file, 0L, 0);
838   swapout (minpc << PROFILE_SHIFT);
839   swapout (maxpc << PROFILE_SHIFT);
840   swapout (nsamples * 2 + 12);
841   for (i = 0; i < nsamples; i++)
842     swapout16 (saved_state.asregs.profile_hist[i]);
843
844 }
845
846 static int
847 gotcall (from, to)
848      int from;
849      int to;
850 {
851   swapout (from);
852   swapout (to);
853   swapout (1);
854 }
855
856 #define MMASKB ((saved_state.asregs.msize -1) & ~0)
857
858
859 void
860 sim_resume (step, siggnal)
861      int step, siggnal;
862 {
863   register unsigned int pc;
864   register int cycles = 0;
865   register int stalls = 0;
866   register int insts = 0;
867   register int prevlock;
868   register int thislock;
869   register unsigned int doprofile;
870 #ifdef __GO32__
871   register int pollcount = 0;
872 #endif
873   register int little_endian = target_byte_order == 1234;
874
875
876   int tick_start = get_now ();
877   void (*prev) ();
878   extern unsigned char sh_jump_table0[];
879
880   register unsigned char *jump_table = sh_jump_table0;
881
882   register int *R = &(saved_state.asregs.regs[0]);
883   register int T;
884   register int PR;
885
886   register int maskb = ((saved_state.asregs.msize - 1) & ~0);
887   register int maskw = ((saved_state.asregs.msize - 1) & ~1);
888   register int maskl = ((saved_state.asregs.msize - 1) & ~3);
889   register unsigned char *memory;
890   register unsigned int sbit = (1 << 31);
891
892   prev = signal (SIGINT, control_c);
893
894   init_pointers ();
895
896   memory = saved_state.asregs.memory;
897
898   if (step)
899     {
900       saved_state.asregs.exception = SIGTRAP;
901     }
902   else
903     {
904       saved_state.asregs.exception = 0;
905     }
906
907   pc = saved_state.asregs.pc;
908   PR = saved_state.asregs.pr;
909   T = saved_state.asregs.sr.bits.t;
910   prevlock = saved_state.asregs.prevlock;
911   thislock = saved_state.asregs.thislock;
912   doprofile = saved_state.asregs.profile;
913
914   /* If profiling not enabled, disable it by asking for
915      profiles infrequently. */
916   if (doprofile == 0)
917     doprofile = ~0;
918
919   do
920     {
921       register unsigned int iword = RUWAT (pc);
922       register unsigned int ult;
923 #ifndef ACE_FAST
924       insts++;
925 #endif
926     top:
927
928 #include "code.c"
929
930
931       pc += 2;
932
933 #ifdef __GO32__
934       pollcount++;
935       if (pollcount > 1000)
936         {
937           pollcount = 0;
938           if (kbhit()) {
939             int k = getkey();
940             if (k == 1)
941               saved_state.asregs.exception = SIGINT;        
942             
943           }
944         }
945 #endif
946
947 #ifndef ACE_FAST
948       prevlock = thislock;
949       thislock = 30;
950       cycles++;
951
952       if (cycles >= doprofile)
953         {
954
955           saved_state.asregs.cycles += doprofile;
956           cycles -= doprofile;
957           if (saved_state.asregs.profile_hist)
958             {
959               int n = pc >> PROFILE_SHIFT;
960               if (n < nsamples)
961                 {
962                   int i = saved_state.asregs.profile_hist[n];
963                   if (i < 65000)
964                     saved_state.asregs.profile_hist[n] = i + 1;
965                 }
966
967             }
968         }
969 #endif
970     }
971   while (!saved_state.asregs.exception);
972
973   if (saved_state.asregs.exception == SIGILL
974       || saved_state.asregs.exception == SIGBUS
975       || (saved_state.asregs.exception == SIGTRAP && !step))
976     {
977       pc -= 2;
978     }
979
980   saved_state.asregs.ticks += get_now () - tick_start;
981   saved_state.asregs.cycles += cycles;
982   saved_state.asregs.stalls += stalls;
983   saved_state.asregs.insts += insts;
984   saved_state.asregs.pc = pc;
985   saved_state.asregs.sr.bits.t = T;
986   saved_state.asregs.pr = PR;
987
988   saved_state.asregs.prevlock = prevlock;
989   saved_state.asregs.thislock = thislock;
990
991
992   if (profile_file)
993     {
994       dump_profile ();
995     }
996
997   signal (SIGINT, prev);
998 }
999
1000
1001
1002
1003 int
1004 sim_write (addr, buffer, size)
1005      SIM_ADDR addr;
1006      unsigned char *buffer;
1007      int size;
1008 {
1009   int i;
1010   init_pointers ();
1011
1012   for (i = 0; i < size; i++)
1013     {
1014       saved_state.asregs.memory[MMASKB & (addr + i)] = buffer[i];
1015     }
1016   return size;
1017 }
1018
1019 int
1020 sim_read (addr, buffer, size)
1021      SIM_ADDR addr;
1022      unsigned char *buffer;
1023      int size;
1024 {
1025   int i;
1026
1027   init_pointers ();
1028
1029   for (i = 0; i < size; i++)
1030     {
1031       buffer[i] = saved_state.asregs.memory[MMASKB & (addr + i)];
1032     }
1033   return size;
1034 }
1035
1036
1037 void
1038 sim_store_register (rn, memory)
1039      int rn;
1040      unsigned char *memory;
1041 {
1042   init_pointers();
1043   saved_state.asregs.regs[rn]=RLAT(0);
1044 }
1045
1046 void
1047 sim_fetch_register (rn, memory)
1048      int rn;
1049      unsigned char *memory;
1050 {
1051   init_pointers();
1052   WLAT (0, saved_state.asregs.regs[rn]);
1053 }
1054
1055
1056 int
1057 sim_trace ()
1058 {
1059   return 0;
1060 }
1061
1062 void
1063 sim_stop_reason (reason, sigrc)
1064      enum sim_stop *reason;
1065      int *sigrc;
1066 {
1067   *reason = sim_stopped;
1068   *sigrc = saved_state.asregs.exception;
1069 }
1070
1071
1072 void
1073 sim_info (verbose)
1074      int verbose;
1075 {
1076   double timetaken = (double) saved_state.asregs.ticks / (double) now_persec ();
1077   double virttime = saved_state.asregs.cycles / 36.0e6;
1078
1079   printf_filtered ("\n\n# instructions executed  %10d\n", saved_state.asregs.insts);
1080   printf_filtered ("# cycles                 %10d\n", saved_state.asregs.cycles);
1081   printf_filtered ("# pipeline stalls        %10d\n", saved_state.asregs.stalls);
1082   printf_filtered ("# real time taken        %10.4f\n", timetaken);
1083   printf_filtered ("# virtual time taken     %10.4f\n", virttime);
1084   printf_filtered ("# profiling size         %10d\n", sim_profile_size);
1085   printf_filtered ("# profiling frequency    %10d\n", saved_state.asregs.profile);
1086   printf_filtered ("# profile maxpc          %10x\n", (1 << sim_profile_size) << PROFILE_SHIFT);
1087
1088   if (timetaken != 0)
1089     {
1090       printf_filtered ("# cycles/second          %10d\n", (int) (saved_state.asregs.cycles / timetaken));
1091       printf_filtered ("# simulation ratio       %10.4f\n", virttime / timetaken);
1092     }
1093 }
1094
1095
1096 void
1097 sim_set_profile (n)
1098      int n;
1099 {
1100   saved_state.asregs.profile = n;
1101 }
1102
1103 void
1104 sim_set_profile_size (n)
1105      int n;
1106 {
1107   sim_profile_size = n;
1108 }
1109
1110
1111 void
1112 sim_open (name)
1113      char *name;
1114 {
1115   /* nothing to do */
1116 }
1117
1118 void
1119 sim_close (quitting)
1120      int quitting;
1121 {
1122   /* nothing to do */
1123 }
1124
1125 int
1126 sim_load (prog, from_tty)
1127      char *prog;
1128      int from_tty;
1129 {
1130   /* Return nonzero so GDB will handle it.  */
1131   return 1;
1132 }
1133
1134 void
1135 sim_create_inferior (start_address, argv, env)
1136      SIM_ADDR start_address;
1137      char **argv;
1138      char **env;
1139 {
1140   saved_state.asregs.pc = start_address;
1141 }
1142
1143 void
1144 sim_kill ()
1145 {
1146   /* nothing to do */
1147 }