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