This commit was generated by cvs2svn to track changes on a CVS vendor
[platform/upstream/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 #ifdef _WIN32
39 #include <float.h>              /* Needed for _isnan() */
40 #define isnan _isnan
41 #endif
42
43 #ifndef SIGBUS
44 #define SIGBUS SIGSEGV
45 #endif
46
47 #ifndef SIGQUIT
48 #define SIGQUIT SIGTERM
49 #endif
50
51 #ifndef SIGTRAP
52 #define SIGTRAP 5
53 #endif
54
55 #define O_RECOMPILE 85
56 #define DEFINE_TABLE
57 #define DISASSEMBLER_TABLE
58
59 /* Define the rate at which the simulator should poll the host
60    for a quit. */
61 #define POLL_QUIT_INTERVAL 0x60000
62
63 typedef union
64 {
65
66   struct
67   {
68     /* On targets like sparc-sun-solaris, fregs will be aligned on a 64 bit
69        boundary (because of the d member).  To avoid padding between
70        registers - which whould make the job of sim_fetch_register harder,
71        we add padding at the start.  */
72     int pad_dummy;
73     int regs[16];
74     int pc;
75     int pr;
76
77     int gbr;
78     int vbr;
79     int mach;
80     int macl;
81
82     int sr;
83
84     int fpul;
85
86     int fpscr;
87
88     /* sh3e */
89     union fregs_u
90       {
91         float f[16];
92         double d[8];
93         int i[16];
94       }
95     fregs[2];
96
97     int ssr;
98     int spc;
99     /* sh3 */
100     int bank[2][8];
101
102     int ticks;
103     int stalls;
104     int memstalls;
105     int cycles;
106     int insts;
107
108     int prevlock;
109     int thislock;
110     int exception;
111
112     int end_of_registers;
113
114     int msize;
115 #define PROFILE_FREQ 1
116 #define PROFILE_SHIFT 2
117     int profile;
118     unsigned short *profile_hist;
119     unsigned char *memory;
120   }
121   asregs;
122   int asints[40];
123 } saved_state_type;
124
125 saved_state_type saved_state;
126
127
128 /* These variables are at file scope so that functions other than
129    sim_resume can use the fetch/store macros */
130
131 static int target_little_endian;
132 static int host_little_endian;
133
134 #if 1
135 static int maskl = ~0;
136 static int maskw = ~0;
137 #endif
138
139 static SIM_OPEN_KIND sim_kind;
140 static char *myname;
141
142
143 /* Short hand definitions of the registers */
144
145 #define SBIT(x) ((x)&sbit)
146 #define R0      saved_state.asregs.regs[0]
147 #define Rn      saved_state.asregs.regs[n]
148 #define Rm      saved_state.asregs.regs[m]
149 #define UR0     (unsigned int)(saved_state.asregs.regs[0])
150 #define UR      (unsigned int)R
151 #define UR      (unsigned int)R
152 #define SR0     saved_state.asregs.regs[0]
153 #define GBR     saved_state.asregs.gbr
154 #define VBR     saved_state.asregs.vbr
155 #define SSR     saved_state.asregs.ssr
156 #define SPC     saved_state.asregs.spc
157 #define MACH    saved_state.asregs.mach
158 #define MACL    saved_state.asregs.macl
159 #define FPUL    saved_state.asregs.fpul
160
161 #define PC pc
162
163
164
165 /* Alternate bank of registers r0-r6 */
166
167 /* Note: code controling SR handles flips between BANK0 and BANK1 */
168 #define Rn_BANK(n) (saved_state.asregs.bank[!SR_RB][(n)])
169 #define SET_Rn_BANK(n, EXP) do { saved_state.asregs.bank[!SR_RB][(n)] = (EXP); } while (0)
170
171
172 /* Manipulate SR */
173
174 #define SR_MASK_M (1 << 9)
175 #define SR_MASK_Q (1 << 8)
176 #define SR_MASK_I (0xf << 4)
177 #define SR_MASK_S (1 << 1)
178 #define SR_MASK_T (1 << 0)
179
180 #define SR_MASK_BL (1 << 28)
181 #define SR_MASK_RB (1 << 29)
182 #define SR_MASK_MD (1 << 30)
183
184 #define M       ((saved_state.asregs.sr & SR_MASK_M) != 0)
185 #define Q       ((saved_state.asregs.sr & SR_MASK_Q) != 0)
186 #define S       ((saved_state.asregs.sr & SR_MASK_S) != 0)
187 #define T       ((saved_state.asregs.sr & SR_MASK_T) != 0)
188
189 #define SR_BL ((saved_state.asregs.sr & SR_MASK_BL) != 0)
190 #define SR_RB ((saved_state.asregs.sr & SR_MASK_RB) != 0)
191 #define SR_MD ((saved_state.asregs.sr & SR_MASK_MD) != 0)
192
193 /* Note: don't use this for privileged bits */
194 #define SET_SR_BIT(EXP, BIT) \
195 do { \
196   if ((EXP) & 1) \
197     saved_state.asregs.sr |= (BIT); \
198   else \
199     saved_state.asregs.sr &= ~(BIT); \
200 } while (0)
201
202 #define SET_SR_M(EXP) SET_SR_BIT ((EXP), SR_MASK_M)
203 #define SET_SR_Q(EXP) SET_SR_BIT ((EXP), SR_MASK_Q)
204 #define SET_SR_S(EXP) SET_SR_BIT ((EXP), SR_MASK_S)
205 #define SET_SR_T(EXP) SET_SR_BIT ((EXP), SR_MASK_T)
206
207 #define GET_SR() (saved_state.asregs.sr - 0)
208 #define SET_SR(x) set_sr (x)
209 static void
210 set_sr (new_sr)
211      int new_sr;
212 {
213   /* do we need to swap banks */
214   int old_gpr = (SR_MD ? !SR_RB : 0);
215   int new_gpr = ((new_sr & SR_MASK_MD)
216                  ? (new_sr & SR_MASK_RB) == 0
217                  : 0);
218   if (old_gpr != new_gpr)
219     {
220       int i;
221       for (i = 0; i < 8; i++)
222         {
223           saved_state.asregs.bank[old_gpr][i] = saved_state.asregs.regs[i];
224           saved_state.asregs.regs[i] = saved_state.asregs.bank[new_gpr][i];
225         }
226     }
227 }
228
229
230 /* Manipulate FPSCR */
231
232 #define FPSCR_MASK_FR (1 << 21)
233 #define FPSCR_MASK_SZ (1 << 20)
234 #define FPSCR_MASK_PR (1 << 19)
235
236 #define FPSCR_FR  ((GET_FPSCR() & FPSCR_MASK_FR) != 0)
237 #define FPSCR_SZ  ((GET_FPSCR() & FPSCR_MASK_SZ) != 0)
238 #define FPSCR_PR  ((GET_FPSCR() & FPSCR_MASK_PR) != 0)
239
240 static void
241 set_fpscr1 (x)
242         int x;
243 {
244   int old = saved_state.asregs.fpscr;
245   saved_state.asregs.fpscr = (x);
246   /* swap the floating point register banks */
247   if ((saved_state.asregs.fpscr ^ old) & FPSCR_MASK_FR)
248     {
249       union fregs_u tmpf = saved_state.asregs.fregs[0];
250       saved_state.asregs.fregs[0] = saved_state.asregs.fregs[1];
251       saved_state.asregs.fregs[1] = tmpf;
252     }
253 }
254
255 #define GET_FPSCR()  (saved_state.asregs.fpscr)
256 #define SET_FPSCR(x) \
257 do { \
258   set_fpscr1 (x); \
259 } while (0)
260
261
262 int 
263 fail ()
264 {
265   abort ();
266 }
267
268 int
269 special_address (addr, bits_written, data)
270      void *addr;
271      int bits_written, data;
272 {
273   if ((unsigned) addr >> 24 == 0xf0 && bits_written == 32 && (data & 1) == 0)
274     /* This invalidates (if not associative) or might invalidate
275        (if associative) an instruction cache line.  This is used for
276        trampolines.  Since we don't simulate the cache, this is a no-op
277        as far as the simulator is concerned.  */
278     return 1;
279   /* We can't do anything useful with the other stuff, so fail.  */
280   return 0;
281 }
282
283 /* This function exists solely for the purpose of setting a breakpoint to
284    catch simulated bus errors when running the simulator under GDB.  */
285
286 void
287 bp_holder ()
288 {
289 }
290
291 /* FIXME: sim_resume should be renamed to sim_engine_run.  sim_resume
292    being implemented by ../common/sim_resume.c and the below should
293    make a call to sim_engine_halt */
294
295 #define BUSERROR(addr, mask, bits_written, data) \
296   if (addr & ~mask) \
297     { \
298       if (special_address (addr, bits_written, data)) \
299         return; \
300       saved_state.asregs.exception = SIGBUS; \
301       bp_holder (); \
302     }
303
304 /* Define this to enable register lifetime checking.
305    The compiler generates "add #0,rn" insns to mark registers as invalid,
306    the simulator uses this info to call fail if it finds a ref to an invalid
307    register before a def
308
309    #define PARANOID
310 */
311
312 #ifdef PARANOID
313 int valid[16];
314 #define CREF(x)  if(!valid[x]) fail();
315 #define CDEF(x)  valid[x] = 1;
316 #define UNDEF(x) valid[x] = 0;
317 #else
318 #define CREF(x)
319 #define CDEF(x)
320 #define UNDEF(x)
321 #endif
322
323 static void parse_and_set_memory_size PARAMS ((char *str));
324
325 static int IOMEM PARAMS ((int addr, int write, int value));
326
327 static host_callback *callback;
328
329
330
331 /* Floating point registers */
332
333 #define DR(n) (get_dr (n))
334 static double
335 get_dr (n)
336      int n;
337 {
338   n = (n & ~1);
339   if (host_little_endian)
340     {
341       union
342       {
343         int i[2];
344         double d;
345       } dr;
346       dr.i[1] = saved_state.asregs.fregs[0].i[n + 0];
347       dr.i[0] = saved_state.asregs.fregs[0].i[n + 1];
348       return dr.d;
349     }
350   else
351     return (saved_state.asregs.fregs[0].d[n >> 1]);
352 }
353
354 #define SET_DR(n, EXP) set_dr ((n), (EXP))
355 static void
356 set_dr (n, exp)
357      int n;
358      double exp;
359 {
360   n = (n & ~1);
361   if (host_little_endian)
362     {
363       union
364       {
365         int i[2];
366         double d;
367       } dr;
368       dr.d = exp;
369       saved_state.asregs.fregs[0].i[n + 0] = dr.i[1];
370       saved_state.asregs.fregs[0].i[n + 1] = dr.i[0];
371     }
372   else
373     saved_state.asregs.fregs[0].d[n >> 1] = exp;
374 }
375
376 #define SET_FI(n,EXP) (saved_state.asregs.fregs[0].i[(n)] = (EXP))
377 #define FI(n) (saved_state.asregs.fregs[0].i[(n)])
378
379 #define FR(n) (saved_state.asregs.fregs[0].f[(n)])
380 #define SET_FR(n,EXP) (saved_state.asregs.fregs[0].f[(n)] = (EXP))
381
382 #define XD_TO_XF(n) ((((n) & 1) << 5) | ((n) & 0x1e))
383 #define XF(n) (saved_state.asregs.fregs[(n) >> 5].i[(n) & 0x1f])
384 #define SET_XF(n,EXP) (saved_state.asregs.fregs[(n) >> 5].i[(n) & 0x1f] = (EXP))
385
386
387 #define FP_OP(n, OP, m) \
388 { \
389   if (FPSCR_PR) \
390     { \
391       if (((n) & 1) || ((m) & 1)) \
392         saved_state.asregs.exception = SIGILL; \
393       else \
394         SET_DR(n, (DR(n) OP DR(m))); \
395     } \
396   else \
397     SET_FR(n, (FR(n) OP FR(m))); \
398 } while (0)
399
400 #define FP_UNARY(n, OP) \
401 { \
402   if (FPSCR_PR) \
403     { \
404       if ((n) & 1) \
405         saved_state.asregs.exception = SIGILL; \
406       else \
407         SET_DR(n, (OP (DR(n)))); \
408     } \
409   else \
410     SET_FR(n, (OP (FR(n)))); \
411 } while (0)
412
413 #define FP_CMP(n, OP, m) \
414 { \
415   if (FPSCR_PR) \
416     { \
417       if (((n) & 1) || ((m) & 1)) \
418         saved_state.asregs.exception = SIGILL; \
419       else \
420         SET_SR_T (DR(n) OP DR(m)); \
421     } \
422   else \
423     SET_SR_T (FR(n) OP FR(m)); \
424 } while (0)
425
426
427
428 static void INLINE 
429 wlat_little (memory, x, value, maskl)
430      unsigned char *memory;
431 {
432   int v = value;
433   unsigned char *p = memory + ((x) & maskl);
434   BUSERROR(x, maskl, 32, v);
435   p[3] = v >> 24;
436   p[2] = v >> 16;
437   p[1] = v >> 8;
438   p[0] = v;
439 }
440
441 static void INLINE 
442 wwat_little (memory, x, value, maskw)
443      unsigned char *memory;
444 {
445   int v = value;
446   unsigned char *p = memory + ((x) & maskw);
447   BUSERROR(x, maskw, 16, v);
448
449   p[1] = v >> 8;
450   p[0] = v;
451 }
452
453 static void INLINE 
454 wbat_any (memory, x, value, maskb)
455      unsigned char *memory;
456 {
457   unsigned char *p = memory + (x & maskb);
458   if (x > 0x5000000)
459     IOMEM (x, 1, value);
460   BUSERROR(x, maskb, 8, value);
461
462   p[0] = value;
463 }
464
465 static void INLINE 
466 wlat_big (memory, x, value, maskl)
467      unsigned char *memory;
468 {
469   int v = value;
470   unsigned char *p = memory + ((x) & maskl);
471   BUSERROR(x, maskl, 32, v);
472
473   p[0] = v >> 24;
474   p[1] = v >> 16;
475   p[2] = v >> 8;
476   p[3] = v;
477 }
478
479 static void INLINE 
480 wwat_big (memory, x, value, maskw)
481      unsigned char *memory;
482 {
483   int v = value;
484   unsigned char *p = memory + ((x) & maskw);
485   BUSERROR(x, maskw, 16, v);
486
487   p[0] = v >> 8;
488   p[1] = v;
489 }
490
491 static void INLINE 
492 wbat_big (memory, x, value, maskb)
493      unsigned char *memory;
494 {
495   unsigned char *p = memory + (x & maskb);
496   BUSERROR(x, maskb, 8, value);
497
498   if (x > 0x5000000)
499     IOMEM (x, 1, value);
500   p[0] = value;
501 }
502
503 /* Read functions */
504
505 static int INLINE 
506 rlat_little (memory, x, maskl)
507      unsigned char *memory;
508 {
509   unsigned char *p = memory + ((x) & maskl);
510   BUSERROR(x, maskl, -32, -1);
511
512   return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
513 }
514
515 static int INLINE 
516 rwat_little (memory, x, maskw)
517      unsigned char *memory;
518 {
519   unsigned char *p = memory + ((x) & maskw);
520   BUSERROR(x, maskw, -16, -1);
521
522   return (p[1] << 8) | p[0];
523 }
524
525 static int INLINE 
526 rbat_any (memory, x, maskb)
527      unsigned char *memory;
528 {
529   unsigned char *p = memory + ((x) & maskb);
530   BUSERROR(x, maskb, -8, -1);
531
532   return p[0];
533 }
534
535 static int INLINE 
536 rlat_big (memory, x, maskl)
537      unsigned char *memory;
538 {
539   unsigned char *p = memory + ((x) & maskl);
540   BUSERROR(x, maskl, -32, -1);
541
542   return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
543 }
544
545 static int INLINE 
546 rwat_big (memory, x, maskw)
547      unsigned char *memory;
548 {
549   unsigned char *p = memory + ((x) & maskw);
550   BUSERROR(x, maskw, -16, -1);
551
552   return (p[0] << 8) | p[1];
553 }
554
555 #define RWAT(x)         (little_endian ? rwat_little(memory, x, maskw): rwat_big(memory, x, maskw))
556 #define RLAT(x)         (little_endian ? rlat_little(memory, x, maskl): rlat_big(memory, x, maskl))
557 #define RBAT(x)         (rbat_any (memory, x, maskb))
558 #define WWAT(x,v)       (little_endian ? wwat_little(memory, x, v, maskw): wwat_big(memory, x, v, maskw))
559 #define WLAT(x,v)       (little_endian ? wlat_little(memory, x, v, maskl): wlat_big(memory, x, v, maskl))
560 #define WBAT(x,v)       (wbat_any (memory, x, v, maskb))
561
562 #define RUWAT(x)  (RWAT(x) & 0xffff)
563 #define RSWAT(x)  ((short)(RWAT(x)))
564 #define RSBAT(x)  (SEXT(RBAT(x)))
565
566 #define RDAT(x, n) (do_rdat (memory, (x), (n), (little_endian)))
567 static int
568 do_rdat (memory, x, n, little_endian)
569      char *memory;
570      int x;
571      int n;
572      int little_endian;
573 {
574   int f0;
575   int f1;
576   int i = (n & 1);
577   int j = (n & ~1);
578   if (little_endian)
579     {
580       f0 = rlat_little (memory, x + 0, maskl);
581       f1 = rlat_little (memory, x + 4, maskl);
582     }
583   else
584     {
585       f0 = rlat_big (memory, x + 0, maskl);
586       f1 = rlat_big (memory, x + 4, maskl);
587     }
588   saved_state.asregs.fregs[i].i[(j + 0)] = f0;
589   saved_state.asregs.fregs[i].i[(j + 1)] = f1;
590   return 0;
591 }
592
593 #define WDAT(x, n) (do_wdat (memory, (x), (n), (little_endian)))
594 static int
595 do_wdat (memory, x, n, little_endian)
596      char *memory;
597      int x;
598      int n;
599      int little_endian;
600 {
601   int f0;
602   int f1;
603   int i = (n & 1);
604   int j = (n & ~1);
605   f0 = saved_state.asregs.fregs[i].i[(j + 0)];
606   f1 = saved_state.asregs.fregs[i].i[(j + 1)];
607   if (little_endian)
608     {
609       wlat_little (memory, (x + 0), f0, maskl);
610       wlat_little (memory, (x + 4), f1, maskl);
611     }
612   else
613     {
614       wlat_big (memory, (x + 0), f0, maskl);
615       wlat_big (memory, (x + 4), f1, maskl);
616     }
617   return 0;
618 }
619
620
621 #define MA(n) do { memstalls += (((pc & 3) != 0) ? (n) : ((n) - 1)); } while (0)
622
623 #define SEXT(x)         (((x &  0xff) ^ (~0x7f))+0x80)
624 #define SEXT12(x)       (((x & 0xfff) ^ 0x800) - 0x800)
625 #define SEXTW(y)        ((int)((short)y))
626
627 #define Delay_Slot(TEMPPC)      iword = RUWAT(TEMPPC); goto top;
628
629 int empty[16];
630
631 #define L(x)   thislock = x;
632 #define TL(x)  if ((x) == prevlock) stalls++;
633 #define TB(x,y)  if ((x) == prevlock || (y)==prevlock) stalls++;
634
635 #if defined(__GO32__) || defined(_WIN32)
636 int sim_memory_size = 19;
637 #else
638 int sim_memory_size = 24;
639 #endif
640
641 static int sim_profile_size = 17;
642 static int nsamples;
643
644 #undef TB
645 #define TB(x,y)
646
647 #define SMR1 (0x05FFFEC8)       /* Channel 1  serial mode register */
648 #define BRR1 (0x05FFFEC9)       /* Channel 1  bit rate register */
649 #define SCR1 (0x05FFFECA)       /* Channel 1  serial control register */
650 #define TDR1 (0x05FFFECB)       /* Channel 1  transmit data register */
651 #define SSR1 (0x05FFFECC)       /* Channel 1  serial status register */
652 #define RDR1 (0x05FFFECD)       /* Channel 1  receive data register */
653
654 #define SCI_RDRF         0x40   /* Recieve data register full */
655 #define SCI_TDRE        0x80    /* Transmit data register empty */
656
657 static int
658 IOMEM (addr, write, value)
659      int addr;
660      int write;
661      int value;
662 {
663   if (write)
664     {
665       switch (addr)
666         {
667         case TDR1:
668           if (value != '\r')
669             {
670               putchar (value);
671               fflush (stdout);
672             }
673           break;
674         }
675     }
676   else
677     {
678       switch (addr)
679         {
680         case RDR1:
681           return getchar ();
682         }
683     }
684   return 0;
685 }
686
687 static int
688 get_now ()
689 {
690   return time ((long *) 0);
691 }
692
693 static int
694 now_persec ()
695 {
696   return 1;
697 }
698
699 static FILE *profile_file;
700
701 static void
702 swap (memory, n)
703      unsigned char *memory;
704      int n;
705 {
706   int little_endian = target_little_endian;
707   WLAT (0, n);
708 }
709
710 static void
711 swap16 (memory, n)
712      unsigned char *memory;
713      int n;
714 {
715   int little_endian = target_little_endian;
716   WWAT (0, n);
717 }
718
719 static void
720 swapout (n)
721      int n;
722 {
723   if (profile_file)
724     {
725       char b[4];
726       swap (b, n);
727       fwrite (b, 4, 1, profile_file);
728     }
729 }
730
731 static void
732 swapout16 (n)
733      int n;
734 {
735   char b[4];
736   swap16 (b, n);
737   fwrite (b, 2, 1, profile_file);
738 }
739
740 /* Turn a pointer in a register into a pointer into real memory. */
741
742 static char *
743 ptr (x)
744      int x;
745 {
746   return (char *) (x + saved_state.asregs.memory);
747 }
748
749 /* Simulate a monitor trap, put the result into r0 and errno into r1 */
750
751 static void
752 trap (i, regs, memory, maskl, maskw, little_endian)
753      int i;
754      int *regs;
755      unsigned char *memory;
756 {
757   switch (i)
758     {
759     case 1:
760       printf ("%c", regs[0]);
761       break;
762     case 2:
763       saved_state.asregs.exception = SIGQUIT;
764       break;
765     case 3:                     /* FIXME: for backwards compat, should be removed */
766     case 34:
767       {
768         extern int errno;
769         int perrno = errno;
770         errno = 0;
771
772         switch (regs[4])
773           {
774
775 #if !defined(__GO32__) && !defined(_WIN32)
776           case SYS_fork:
777             regs[0] = fork ();
778             break;
779           case SYS_execve:
780             regs[0] = execve (ptr (regs[5]), (char **)ptr (regs[6]), (char **)ptr (regs[7]));
781             break;
782           case SYS_execv:
783             regs[0] = execve (ptr (regs[5]),(char **) ptr (regs[6]), 0);
784             break;
785           case SYS_pipe:
786             {
787               char *buf;
788               int host_fd[2];
789
790               buf = ptr (regs[5]);
791
792               regs[0] = pipe (host_fd);
793
794               WLAT (buf, host_fd[0]);
795               buf += 4;
796               WLAT (buf, host_fd[1]);
797             }
798             break;
799
800           case SYS_wait:
801             regs[0] = wait (ptr (regs[5]));
802             break;
803 #endif
804
805           case SYS_read:
806             regs[0] = callback->read (callback, regs[5], ptr (regs[6]), regs[7]);
807             break;
808           case SYS_write:
809             if (regs[5] == 1)
810               regs[0] = (int)callback->write_stdout (callback, ptr(regs[6]), regs[7]);
811             else
812               regs[0] = (int)callback->write (callback, regs[5], ptr (regs[6]), regs[7]);
813             break;
814           case SYS_lseek:
815             regs[0] = callback->lseek (callback,regs[5], regs[6], regs[7]);
816             break;
817           case SYS_close:
818             regs[0] = callback->close (callback,regs[5]);
819             break;
820           case SYS_open:
821             regs[0] = callback->open (callback,ptr (regs[5]), regs[6]);
822             break;
823           case SYS_exit:
824             /* EXIT - caller can look in r5 to work out the reason */
825             saved_state.asregs.exception = SIGQUIT;
826             regs[0] = regs[5];
827             break;
828
829           case SYS_stat:        /* added at hmsi */
830             /* stat system call */
831             {
832               struct stat host_stat;
833               char *buf;
834
835               regs[0] = stat (ptr (regs[5]), &host_stat);
836
837               buf = ptr (regs[6]);
838
839               WWAT (buf, host_stat.st_dev);
840               buf += 2;
841               WWAT (buf, host_stat.st_ino);
842               buf += 2;
843               WLAT (buf, host_stat.st_mode);
844               buf += 4;
845               WWAT (buf, host_stat.st_nlink);
846               buf += 2;
847               WWAT (buf, host_stat.st_uid);
848               buf += 2;
849               WWAT (buf, host_stat.st_gid);
850               buf += 2;
851               WWAT (buf, host_stat.st_rdev);
852               buf += 2;
853               WLAT (buf, host_stat.st_size);
854               buf += 4;
855               WLAT (buf, host_stat.st_atime);
856               buf += 4;
857               WLAT (buf, 0);
858               buf += 4;
859               WLAT (buf, host_stat.st_mtime);
860               buf += 4;
861               WLAT (buf, 0);
862               buf += 4;
863               WLAT (buf, host_stat.st_ctime);
864               buf += 4;
865               WLAT (buf, 0);
866               buf += 4;
867               WLAT (buf, 0);
868               buf += 4;
869               WLAT (buf, 0);
870               buf += 4;
871             }
872             break;
873
874 #ifndef _WIN32
875           case SYS_chown:
876             regs[0] = chown (ptr (regs[5]), regs[6], regs[7]);
877             break;
878 #endif /* _WIN32 */
879           case SYS_chmod:
880             regs[0] = chmod (ptr (regs[5]), regs[6]);
881             break;
882           case SYS_utime:
883             /* Cast the second argument to void *, to avoid type mismatch
884                if a prototype is present.  */
885             regs[0] = utime (ptr (regs[5]), (void *) ptr (regs[6]));
886             break;
887           default:
888             abort ();
889           }
890         regs[1] = callback->get_errno (callback);
891         errno = perrno;
892       }
893       break;
894
895     case 0xc3:
896     case 255:
897       saved_state.asregs.exception = SIGTRAP;
898       break;
899     }
900
901 }
902
903 void
904 control_c (sig, code, scp, addr)
905      int sig;
906      int code;
907      char *scp;
908      char *addr;
909 {
910   saved_state.asregs.exception = SIGINT;
911 }
912
913 static int
914 div1 (R, iRn2, iRn1/*, T*/)
915      int *R;
916      int iRn1;
917      int iRn2;
918      /* int T;*/
919 {
920   unsigned long tmp0;
921   unsigned char old_q, tmp1;
922
923   old_q = Q;
924   SET_SR_Q ((unsigned char) ((0x80000000 & R[iRn1]) != 0));
925   R[iRn1] <<= 1;
926   R[iRn1] |= (unsigned long) T;
927
928   switch (old_q)
929     {
930     case 0:
931       switch (M)
932         {
933         case 0:
934           tmp0 = R[iRn1];
935           R[iRn1] -= R[iRn2];
936           tmp1 = (R[iRn1] > tmp0);
937           switch (Q)
938             {
939             case 0:
940               SET_SR_Q (tmp1);
941               break;
942             case 1:
943               SET_SR_Q ((unsigned char) (tmp1 == 0));
944               break;
945             }
946           break;
947         case 1:
948           tmp0 = R[iRn1];
949           R[iRn1] += R[iRn2];
950           tmp1 = (R[iRn1] < tmp0);
951           switch (Q)
952             {
953             case 0:
954               SET_SR_Q ((unsigned char) (tmp1 == 0));
955               break;
956             case 1:
957               SET_SR_Q (tmp1);
958               break;
959             }
960           break;
961         }
962       break;
963     case 1:
964       switch (M)
965         {
966         case 0:
967           tmp0 = R[iRn1];
968           R[iRn1] += R[iRn2];
969           tmp1 = (R[iRn1] < tmp0);
970           switch (Q)
971             {
972             case 0:
973               SET_SR_Q (tmp1);
974               break;
975             case 1:
976               SET_SR_Q ((unsigned char) (tmp1 == 0));
977               break;
978             }
979           break;
980         case 1:
981           tmp0 = R[iRn1];
982           R[iRn1] -= R[iRn2];
983           tmp1 = (R[iRn1] > tmp0);
984           switch (Q)
985             {
986             case 0:
987               SET_SR_Q ((unsigned char) (tmp1 == 0));
988               break;
989             case 1:
990               SET_SR_Q (tmp1);
991               break;
992             }
993           break;
994         }
995       break;
996     }
997   /*T = (Q == M);*/
998   SET_SR_T (Q == M);
999   /*return T;*/
1000 }
1001
1002 static void
1003 dmul (sign, rm, rn)
1004      int sign;
1005      unsigned int rm;
1006      unsigned int rn;
1007 {
1008   unsigned long RnL, RnH;
1009   unsigned long RmL, RmH;
1010   unsigned long temp0, temp1, temp2, temp3;
1011   unsigned long Res2, Res1, Res0;
1012
1013   RnL = rn & 0xffff;
1014   RnH = (rn >> 16) & 0xffff;
1015   RmL = rm & 0xffff;
1016   RmH = (rm >> 16) & 0xffff;
1017   temp0 = RmL * RnL;
1018   temp1 = RmH * RnL;
1019   temp2 = RmL * RnH;
1020   temp3 = RmH * RnH;
1021   Res2 = 0;
1022   Res1 = temp1 + temp2;
1023   if (Res1 < temp1)
1024     Res2 += 0x00010000;
1025   temp1 = (Res1 << 16) & 0xffff0000;
1026   Res0 = temp0 + temp1;
1027   if (Res0 < temp0)
1028     Res2 += 1;
1029   Res2 += ((Res1 >> 16) & 0xffff) + temp3;
1030   
1031   if (sign)
1032     {
1033       if (rn & 0x80000000)
1034         Res2 -= rm;
1035       if (rm & 0x80000000)
1036         Res2 -= rn;
1037     }
1038
1039   MACH = Res2;
1040   MACL = Res0;
1041 }
1042
1043 static void
1044 macw (regs, memory, n, m)
1045      int *regs;
1046      unsigned char *memory;
1047      int m, n;
1048 {
1049   int little_endian = target_little_endian;
1050   long tempm, tempn;
1051   long prod, macl, sum;
1052
1053   tempm=RSWAT(regs[m]); regs[m]+=2;
1054   tempn=RSWAT(regs[n]); regs[n]+=2;
1055
1056   macl = MACL;
1057   prod = (long)(short) tempm * (long)(short) tempn;
1058   sum = prod + macl;
1059   if (S)
1060     {
1061       if ((~(prod ^ macl) & (sum ^ prod)) < 0)
1062         {
1063           /* MACH's lsb is a sticky overflow bit.  */
1064           MACH |= 1;
1065           /* Store the smallest negative number in MACL if prod is
1066              negative, and the largest positive number otherwise.  */
1067           sum = 0x7fffffff + (prod < 0);
1068         }
1069     }
1070   else
1071     {
1072       long mach;
1073       /* Add to MACH the sign extended product, and carry from low sum.  */
1074       mach = MACH + (-(prod < 0)) + ((unsigned long) sum < prod);
1075       /* Sign extend at 10:th bit in MACH.  */
1076       MACH = (mach & 0x1ff) | -(mach & 0x200);
1077     }
1078   MACL = sum;
1079 }
1080
1081 /* Set the memory size to the power of two provided. */
1082
1083 void
1084 sim_size (power)
1085      int power;
1086
1087 {
1088   saved_state.asregs.msize = 1 << power;
1089
1090   sim_memory_size = power;
1091
1092   if (saved_state.asregs.memory)
1093     {
1094       free (saved_state.asregs.memory);
1095     }
1096
1097   saved_state.asregs.memory =
1098     (unsigned char *) calloc (64, saved_state.asregs.msize / 64);
1099
1100   if (!saved_state.asregs.memory)
1101     {
1102       fprintf (stderr,
1103                "Not enough VM for simulation of %d bytes of RAM\n",
1104                saved_state.asregs.msize);
1105
1106       saved_state.asregs.msize = 1;
1107       saved_state.asregs.memory = (unsigned char *) calloc (1, 1);
1108     }
1109 }
1110
1111 static void
1112 init_pointers ()
1113 {
1114   host_little_endian = 0;
1115   *(char*)&host_little_endian = 1;
1116   host_little_endian &= 1;
1117
1118   if (saved_state.asregs.msize != 1 << sim_memory_size)
1119     {
1120       sim_size (sim_memory_size);
1121     }
1122
1123   if (saved_state.asregs.profile && !profile_file)
1124     {
1125       profile_file = fopen ("gmon.out", "wb");
1126       /* Seek to where to put the call arc data */
1127       nsamples = (1 << sim_profile_size);
1128
1129       fseek (profile_file, nsamples * 2 + 12, 0);
1130
1131       if (!profile_file)
1132         {
1133           fprintf (stderr, "Can't open gmon.out\n");
1134         }
1135       else
1136         {
1137           saved_state.asregs.profile_hist =
1138             (unsigned short *) calloc (64, (nsamples * sizeof (short) / 64));
1139         }
1140     }
1141 }
1142
1143 static void
1144 dump_profile ()
1145 {
1146   unsigned int minpc;
1147   unsigned int maxpc;
1148   unsigned short *p;
1149   int i;
1150
1151   p = saved_state.asregs.profile_hist;
1152   minpc = 0;
1153   maxpc = (1 << sim_profile_size);
1154
1155   fseek (profile_file, 0L, 0);
1156   swapout (minpc << PROFILE_SHIFT);
1157   swapout (maxpc << PROFILE_SHIFT);
1158   swapout (nsamples * 2 + 12);
1159   for (i = 0; i < nsamples; i++)
1160     swapout16 (saved_state.asregs.profile_hist[i]);
1161
1162 }
1163
1164 static void
1165 gotcall (from, to)
1166      int from;
1167      int to;
1168 {
1169   swapout (from);
1170   swapout (to);
1171   swapout (1);
1172 }
1173
1174 #define MMASKB ((saved_state.asregs.msize -1) & ~0)
1175
1176 int
1177 sim_stop (sd)
1178      SIM_DESC sd;
1179 {
1180   saved_state.asregs.exception = SIGINT;
1181   return 1;
1182 }
1183
1184 void
1185 sim_resume (sd, step, siggnal)
1186      SIM_DESC sd;
1187      int step, siggnal;
1188 {
1189   register unsigned int pc;
1190   register int cycles = 0;
1191   register int stalls = 0;
1192   register int memstalls = 0;
1193   register int insts = 0;
1194   register int prevlock;
1195   register int thislock;
1196   register unsigned int doprofile;
1197   register int pollcount = 0;
1198   register int little_endian = target_little_endian;
1199
1200   int tick_start = get_now ();
1201   void (*prev) ();
1202   void (*prev_fpe) ();
1203   extern unsigned char sh_jump_table0[];
1204
1205   register unsigned char *jump_table = sh_jump_table0;
1206
1207   register int *R = &(saved_state.asregs.regs[0]);
1208   /*register int T;*/
1209   register int PR;
1210
1211   register int maskb = ((saved_state.asregs.msize - 1) & ~0);
1212   register int maskw = ((saved_state.asregs.msize - 1) & ~1);
1213   register int maskl = ((saved_state.asregs.msize - 1) & ~3);
1214   register unsigned char *memory;
1215   register unsigned int sbit = ((unsigned int) 1 << 31);
1216
1217   prev = signal (SIGINT, control_c);
1218   prev_fpe = signal (SIGFPE, SIG_IGN);
1219
1220   init_pointers ();
1221
1222   memory = saved_state.asregs.memory;
1223
1224   if (step)
1225     {
1226       saved_state.asregs.exception = SIGTRAP;
1227     }
1228   else
1229     {
1230       saved_state.asregs.exception = 0;
1231     }
1232
1233   pc = saved_state.asregs.pc;
1234   PR = saved_state.asregs.pr;
1235   /*T = GET_SR () & SR_MASK_T;*/
1236   prevlock = saved_state.asregs.prevlock;
1237   thislock = saved_state.asregs.thislock;
1238   doprofile = saved_state.asregs.profile;
1239
1240   /* If profiling not enabled, disable it by asking for
1241      profiles infrequently. */
1242   if (doprofile == 0)
1243     doprofile = ~0;
1244
1245   do
1246     {
1247       register unsigned int iword = RUWAT (pc);
1248       register unsigned int ult;
1249       register unsigned int nia = pc + 2;
1250 #ifndef ACE_FAST
1251       insts++;
1252 #endif
1253     top:
1254
1255 #include "code.c"
1256
1257
1258       pc = nia;
1259
1260       if (--pollcount < 0)
1261         {
1262           pollcount = POLL_QUIT_INTERVAL;
1263           if ((*callback->poll_quit) != NULL
1264               && (*callback->poll_quit) (callback))
1265             {
1266               sim_stop (sd);
1267             }       
1268         }
1269
1270 #ifndef ACE_FAST
1271       prevlock = thislock;
1272       thislock = 30;
1273       cycles++;
1274
1275       if (cycles >= doprofile)
1276         {
1277
1278           saved_state.asregs.cycles += doprofile;
1279           cycles -= doprofile;
1280           if (saved_state.asregs.profile_hist)
1281             {
1282               int n = pc >> PROFILE_SHIFT;
1283               if (n < nsamples)
1284                 {
1285                   int i = saved_state.asregs.profile_hist[n];
1286                   if (i < 65000)
1287                     saved_state.asregs.profile_hist[n] = i + 1;
1288                 }
1289
1290             }
1291         }
1292 #endif
1293     }
1294   while (!saved_state.asregs.exception);
1295
1296   if (saved_state.asregs.exception == SIGILL
1297       || saved_state.asregs.exception == SIGBUS)
1298     {
1299       pc -= 2;
1300     }
1301
1302   saved_state.asregs.ticks += get_now () - tick_start;
1303   saved_state.asregs.cycles += cycles;
1304   saved_state.asregs.stalls += stalls;
1305   saved_state.asregs.memstalls += memstalls;
1306   saved_state.asregs.insts += insts;
1307   saved_state.asregs.pc = pc;
1308   /* restore the T and other cached SR bits */
1309   SET_SR (GET_SR());
1310   saved_state.asregs.pr = PR;
1311
1312   saved_state.asregs.prevlock = prevlock;
1313   saved_state.asregs.thislock = thislock;
1314
1315   if (profile_file)
1316     {
1317       dump_profile ();
1318     }
1319
1320   signal (SIGFPE, prev_fpe);
1321   signal (SIGINT, prev);
1322 }
1323
1324 int
1325 sim_write (sd, addr, buffer, size)
1326      SIM_DESC sd;
1327      SIM_ADDR addr;
1328      unsigned char *buffer;
1329      int size;
1330 {
1331   int i;
1332
1333   init_pointers ();
1334
1335   for (i = 0; i < size; i++)
1336     {
1337       saved_state.asregs.memory[MMASKB & (addr + i)] = buffer[i];
1338     }
1339   return size;
1340 }
1341
1342 int
1343 sim_read (sd, addr, buffer, size)
1344      SIM_DESC sd;
1345      SIM_ADDR addr;
1346      unsigned char *buffer;
1347      int size;
1348 {
1349   int i;
1350
1351   init_pointers ();
1352
1353   for (i = 0; i < size; i++)
1354     {
1355       buffer[i] = saved_state.asregs.memory[MMASKB & (addr + i)];
1356     }
1357   return size;
1358 }
1359
1360 /* We have to add one to RN as an index into asints because of the padding
1361    added at the start of asregs.  */
1362 int
1363 sim_store_register (sd, rn, memory, length)
1364      SIM_DESC sd;
1365      int rn;
1366      unsigned char *memory;
1367      int length;
1368 {
1369   int little_endian;
1370   init_pointers ();
1371   little_endian = target_little_endian;
1372   if (&saved_state.asints[rn+1]
1373       == &saved_state.asregs.fpscr)
1374     set_fpscr1 (RLAT(0));
1375   else
1376     saved_state.asints[rn+1] = RLAT(0);
1377   return -1;
1378 }
1379
1380 int
1381 sim_fetch_register (sd, rn, memory, length)
1382      SIM_DESC sd;
1383      int rn;
1384      unsigned char *memory;
1385      int length;
1386 {
1387   int little_endian;
1388   init_pointers ();
1389   little_endian = target_little_endian;
1390   WLAT (0, saved_state.asints[rn+1]);
1391   return -1;
1392 }
1393
1394 int
1395 sim_trace (sd)
1396      SIM_DESC sd;
1397 {
1398   return 0;
1399 }
1400
1401 void
1402 sim_stop_reason (sd, reason, sigrc)
1403      SIM_DESC sd;
1404      enum sim_stop *reason;
1405      int *sigrc;
1406 {
1407   /* The SH simulator uses SIGQUIT to indicate that the program has
1408      exited, so we must check for it here and translate it to exit.  */
1409   if (saved_state.asregs.exception == SIGQUIT)
1410     {
1411       *reason = sim_exited;
1412       *sigrc = saved_state.asregs.regs[5];
1413     }
1414   else
1415     {
1416       *reason = sim_stopped;
1417       *sigrc = saved_state.asregs.exception;
1418     }
1419 }
1420
1421 void
1422 sim_info (sd, verbose)
1423      SIM_DESC sd;
1424      int verbose;
1425 {
1426   double timetaken = (double) saved_state.asregs.ticks / (double) now_persec ();
1427   double virttime = saved_state.asregs.cycles / 36.0e6;
1428
1429   callback->printf_filtered (callback, "\n\n# instructions executed  %10d\n", 
1430                              saved_state.asregs.insts);
1431   callback->printf_filtered (callback, "# cycles                 %10d\n",
1432                              saved_state.asregs.cycles);
1433   callback->printf_filtered (callback, "# pipeline stalls        %10d\n",
1434                              saved_state.asregs.stalls);
1435   callback->printf_filtered (callback, "# misaligned load/store  %10d\n",
1436                              saved_state.asregs.memstalls);
1437   callback->printf_filtered (callback, "# real time taken        %10.4f\n",
1438                              timetaken);
1439   callback->printf_filtered (callback, "# virtual time taken     %10.4f\n",
1440                              virttime);
1441   callback->printf_filtered (callback, "# profiling size         %10d\n",
1442                              sim_profile_size);
1443   callback->printf_filtered (callback, "# profiling frequency    %10d\n",
1444                              saved_state.asregs.profile);
1445   callback->printf_filtered (callback, "# profile maxpc          %10x\n",
1446                              (1 << sim_profile_size) << PROFILE_SHIFT);
1447
1448   if (timetaken != 0)
1449     {
1450       callback->printf_filtered (callback, "# cycles/second          %10d\n", 
1451                                  (int) (saved_state.asregs.cycles / timetaken));
1452       callback->printf_filtered (callback, "# simulation ratio       %10.4f\n", 
1453                                  virttime / timetaken);
1454     }
1455 }
1456
1457 void
1458 sim_set_profile (n)
1459      int n;
1460 {
1461   saved_state.asregs.profile = n;
1462 }
1463
1464 void
1465 sim_set_profile_size (n)
1466      int n;
1467 {
1468   sim_profile_size = n;
1469 }
1470
1471 SIM_DESC
1472 sim_open (kind, cb, abfd, argv)
1473      SIM_OPEN_KIND kind;
1474      host_callback *cb;
1475      struct _bfd *abfd;
1476      char **argv;
1477 {
1478   char **p;
1479   int endian_set = 0;
1480
1481   sim_kind = kind;
1482   myname = argv[0];
1483   callback = cb;
1484
1485   for (p = argv + 1; *p != NULL; ++p)
1486     {
1487       if (strcmp (*p, "-E") == 0)
1488         {
1489           ++p;
1490           if (*p == NULL)
1491             {
1492               /* FIXME: This doesn't use stderr, but then the rest of the
1493                  file doesn't either.  */
1494               callback->printf_filtered (callback, "Missing argument to `-E'.\n");
1495               return 0;
1496             }
1497           target_little_endian = strcmp (*p, "big") != 0;
1498           endian_set = 1;
1499         }
1500       else if (isdigit (**p))
1501         parse_and_set_memory_size (*p);
1502     }
1503
1504   if (abfd != NULL && ! endian_set)
1505       target_little_endian = ! bfd_big_endian (abfd);
1506
1507   /* fudge our descriptor for now */
1508   return (SIM_DESC) 1;
1509 }
1510
1511 static void
1512 parse_and_set_memory_size (str)
1513      char *str;
1514 {
1515   int n;
1516
1517   n = strtol (str, NULL, 10);
1518   if (n > 0 && n <= 24)
1519     sim_memory_size = n;
1520   else
1521     callback->printf_filtered (callback, "Bad memory size %d; must be 1 to 24, inclusive\n", n);
1522 }
1523
1524 void
1525 sim_close (sd, quitting)
1526      SIM_DESC sd;
1527      int quitting;
1528 {
1529   /* nothing to do */
1530 }
1531
1532 SIM_RC
1533 sim_load (sd, prog, abfd, from_tty)
1534      SIM_DESC sd;
1535      char *prog;
1536      bfd *abfd;
1537      int from_tty;
1538 {
1539   extern bfd *sim_load_file (); /* ??? Don't know where this should live.  */
1540   bfd *prog_bfd;
1541
1542   prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
1543                             sim_kind == SIM_OPEN_DEBUG,
1544                             0, sim_write);
1545   if (prog_bfd == NULL)
1546     return SIM_RC_FAIL;
1547   if (abfd == NULL)
1548     bfd_close (prog_bfd);
1549   return SIM_RC_OK;
1550 }
1551
1552 SIM_RC
1553 sim_create_inferior (sd, prog_bfd, argv, env)
1554      SIM_DESC sd;
1555      struct _bfd *prog_bfd;
1556      char **argv;
1557      char **env;
1558 {
1559   /* clear the registers */
1560   memset (&saved_state, 0,
1561           (char*)&saved_state.asregs.end_of_registers - (char*)&saved_state);
1562   /* set the PC */
1563   if (prog_bfd != NULL)
1564     saved_state.asregs.pc = bfd_get_start_address (prog_bfd);
1565   return SIM_RC_OK;
1566 }
1567
1568 void
1569 sim_do_command (sd, cmd)
1570      SIM_DESC sd;
1571      char *cmd;
1572 {
1573   char *sms_cmd = "set-memory-size";
1574   int cmdsize;
1575
1576   if (cmd == NULL || *cmd == '\0')
1577     {
1578       cmd = "help";
1579     }
1580
1581   cmdsize = strlen (sms_cmd);
1582   if (strncmp (cmd, sms_cmd, cmdsize) == 0 && strchr (" \t", cmd[cmdsize]) != NULL)
1583     {
1584       parse_and_set_memory_size (cmd + cmdsize + 1);
1585     }
1586   else if (strcmp (cmd, "help") == 0)
1587     {
1588       (callback->printf_filtered) (callback, "List of SH simulator commands:\n\n");
1589       (callback->printf_filtered) (callback, "set-memory-size <n> -- Set the number of address bits to use\n");
1590       (callback->printf_filtered) (callback, "\n");
1591     }
1592   else
1593     {
1594       (callback->printf_filtered) (callback, "Error: \"%s\" is not a valid SH simulator command.\n", cmd);
1595     }
1596 }
1597
1598 void
1599 sim_set_callbacks (p)
1600      host_callback *p;
1601 {
1602   callback = p;
1603 }