f50c76b9cae6cd5453288a85341b376fdcc8b221
[deliverable/binutils-gdb.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 void
887 sim_resume (sd, step, siggnal)
888 SIM_DESC sd;
889 int step, siggnal;
890 {
891 register unsigned int pc;
892 register int cycles = 0;
893 register int stalls = 0;
894 register int memstalls = 0;
895 register int insts = 0;
896 register int prevlock;
897 register int thislock;
898 register unsigned int doprofile;
899 #if defined(__GO32__) || defined(WIN32)
900 register int pollcount = 0;
901 #endif
902 register int little_endian = little_endian_p;
903
904 int tick_start = get_now ();
905 void (*prev) ();
906 extern unsigned char sh_jump_table0[];
907
908 register unsigned char *jump_table = sh_jump_table0;
909
910 register int *R = &(saved_state.asregs.regs[0]);
911 register float *F = &(saved_state.asregs.fregs[0]);
912 register int T;
913 register int PR;
914
915 register int maskb = ((saved_state.asregs.msize - 1) & ~0);
916 register int maskw = ((saved_state.asregs.msize - 1) & ~1);
917 register int maskl = ((saved_state.asregs.msize - 1) & ~3);
918 register unsigned char *memory;
919 register unsigned int sbit = ((unsigned int) 1 << 31);
920
921 prev = signal (SIGINT, control_c);
922
923 init_pointers ();
924
925 memory = saved_state.asregs.memory;
926
927 if (step)
928 {
929 saved_state.asregs.exception = SIGTRAP;
930 }
931 else
932 {
933 saved_state.asregs.exception = 0;
934 }
935
936 pc = saved_state.asregs.pc;
937 PR = saved_state.asregs.pr;
938 T = saved_state.asregs.sr.bits.t;
939 prevlock = saved_state.asregs.prevlock;
940 thislock = saved_state.asregs.thislock;
941 doprofile = saved_state.asregs.profile;
942
943 /* If profiling not enabled, disable it by asking for
944 profiles infrequently. */
945 if (doprofile == 0)
946 doprofile = ~0;
947
948 do
949 {
950 register unsigned int iword = RUWAT (pc);
951 register unsigned int ult;
952 #ifndef ACE_FAST
953 insts++;
954 #endif
955 top:
956
957 #include "code.c"
958
959
960 pc += 2;
961
962 #ifdef __GO32__
963 pollcount++;
964 if (pollcount > 1000)
965 {
966 pollcount = 0;
967 if (kbhit()) {
968 int k = getkey();
969 if (k == 1)
970 saved_state.asregs.exception = SIGINT;
971
972 }
973 }
974 #endif
975 /* FIXME: Testing for INSIDE_SIMULATOR is wrong.
976 Only one copy of interp.o is built. */
977 #if defined (WIN32) && !defined(INSIDE_SIMULATOR)
978 pollcount++;
979 if (pollcount > 1000)
980 {
981 pollcount = 0;
982 if (win32pollquit())
983 {
984 control_c();
985 }
986 }
987 #endif
988
989 #ifndef ACE_FAST
990 prevlock = thislock;
991 thislock = 30;
992 cycles++;
993
994 if (cycles >= doprofile)
995 {
996
997 saved_state.asregs.cycles += doprofile;
998 cycles -= doprofile;
999 if (saved_state.asregs.profile_hist)
1000 {
1001 int n = pc >> PROFILE_SHIFT;
1002 if (n < nsamples)
1003 {
1004 int i = saved_state.asregs.profile_hist[n];
1005 if (i < 65000)
1006 saved_state.asregs.profile_hist[n] = i + 1;
1007 }
1008
1009 }
1010 }
1011 #endif
1012 }
1013 while (!saved_state.asregs.exception);
1014
1015 if (saved_state.asregs.exception == SIGILL
1016 || saved_state.asregs.exception == SIGBUS)
1017 {
1018 pc -= 2;
1019 }
1020
1021 saved_state.asregs.ticks += get_now () - tick_start;
1022 saved_state.asregs.cycles += cycles;
1023 saved_state.asregs.stalls += stalls;
1024 saved_state.asregs.memstalls += memstalls;
1025 saved_state.asregs.insts += insts;
1026 saved_state.asregs.pc = pc;
1027 saved_state.asregs.sr.bits.t = T;
1028 saved_state.asregs.pr = PR;
1029
1030 saved_state.asregs.prevlock = prevlock;
1031 saved_state.asregs.thislock = thislock;
1032
1033 if (profile_file)
1034 {
1035 dump_profile ();
1036 }
1037
1038 signal (SIGINT, prev);
1039 }
1040
1041 int
1042 sim_write (sd, addr, buffer, size)
1043 SIM_DESC sd;
1044 SIM_ADDR addr;
1045 unsigned char *buffer;
1046 int size;
1047 {
1048 int i;
1049
1050 init_pointers ();
1051
1052 for (i = 0; i < size; i++)
1053 {
1054 saved_state.asregs.memory[MMASKB & (addr + i)] = buffer[i];
1055 }
1056 return size;
1057 }
1058
1059 int
1060 sim_read (sd, addr, buffer, size)
1061 SIM_DESC sd;
1062 SIM_ADDR addr;
1063 unsigned char *buffer;
1064 int size;
1065 {
1066 int i;
1067
1068 init_pointers ();
1069
1070 for (i = 0; i < size; i++)
1071 {
1072 buffer[i] = saved_state.asregs.memory[MMASKB & (addr + i)];
1073 }
1074 return size;
1075 }
1076
1077 void
1078 sim_store_register (sd, rn, memory)
1079 SIM_DESC sd;
1080 int rn;
1081 unsigned char *memory;
1082 {
1083 init_pointers ();
1084 saved_state.asregs.regs[rn] = RLAT(0);
1085 }
1086
1087 void
1088 sim_fetch_register (sd, rn, memory)
1089 SIM_DESC sd;
1090 int rn;
1091 unsigned char *memory;
1092 {
1093 init_pointers ();
1094 WLAT (0, saved_state.asregs.regs[rn]);
1095 }
1096
1097 int
1098 sim_trace (sd)
1099 SIM_DESC sd;
1100 {
1101 return 0;
1102 }
1103
1104 void
1105 sim_stop_reason (sd, reason, sigrc)
1106 SIM_DESC sd;
1107 enum sim_stop *reason;
1108 int *sigrc;
1109 {
1110 /* The SH simulator uses SIGQUIT to indicate that the program has
1111 exited, so we must check for it here and translate it to exit. */
1112 if (saved_state.asregs.exception == SIGQUIT)
1113 {
1114 *reason = sim_exited;
1115 *sigrc = saved_state.asregs.regs[5];
1116 }
1117 else
1118 {
1119 *reason = sim_stopped;
1120 *sigrc = saved_state.asregs.exception;
1121 }
1122 }
1123
1124 void
1125 sim_info (sd, verbose)
1126 SIM_DESC sd;
1127 int verbose;
1128 {
1129 double timetaken = (double) saved_state.asregs.ticks / (double) now_persec ();
1130 double virttime = saved_state.asregs.cycles / 36.0e6;
1131
1132 callback->printf_filtered (callback, "\n\n# instructions executed %10d\n",
1133 saved_state.asregs.insts);
1134 callback->printf_filtered (callback, "# cycles %10d\n",
1135 saved_state.asregs.cycles);
1136 callback->printf_filtered (callback, "# pipeline stalls %10d\n",
1137 saved_state.asregs.stalls);
1138 callback->printf_filtered (callback, "# misaligned load/store %10d\n",
1139 saved_state.asregs.memstalls);
1140 callback->printf_filtered (callback, "# real time taken %10.4f\n",
1141 timetaken);
1142 callback->printf_filtered (callback, "# virtual time taken %10.4f\n",
1143 virttime);
1144 callback->printf_filtered (callback, "# profiling size %10d\n",
1145 sim_profile_size);
1146 callback->printf_filtered (callback, "# profiling frequency %10d\n",
1147 saved_state.asregs.profile);
1148 callback->printf_filtered (callback, "# profile maxpc %10x\n",
1149 (1 << sim_profile_size) << PROFILE_SHIFT);
1150
1151 if (timetaken != 0)
1152 {
1153 callback->printf_filtered (callback, "# cycles/second %10d\n",
1154 (int) (saved_state.asregs.cycles / timetaken));
1155 callback->printf_filtered (callback, "# simulation ratio %10.4f\n",
1156 virttime / timetaken);
1157 }
1158 }
1159
1160 void
1161 sim_set_profile (n)
1162 int n;
1163 {
1164 saved_state.asregs.profile = n;
1165 }
1166
1167 void
1168 sim_set_profile_size (n)
1169 int n;
1170 {
1171 sim_profile_size = n;
1172 }
1173
1174 SIM_DESC
1175 sim_open (kind,argv)
1176 SIM_OPEN_KIND kind;
1177 char **argv;
1178 {
1179 char **p;
1180
1181 sim_kind = kind;
1182 myname = argv[0];
1183
1184 for (p = argv + 1; *p != NULL; ++p)
1185 {
1186 if (strcmp (*p, "-E") == 0)
1187 little_endian_p = strcmp (*++p, "big") != 0;
1188 else if (isdigit (**p))
1189 parse_and_set_memory_size (*p);
1190 }
1191
1192 /* fudge our descriptor for now */
1193 return (SIM_DESC) 1;
1194 }
1195
1196 static void
1197 parse_and_set_memory_size (str)
1198 char *str;
1199 {
1200 int n;
1201
1202 n = strtol (str, NULL, 10);
1203 if (n > 0 && n <= 24)
1204 sim_memory_size = n;
1205 else
1206 callback->printf_filtered (callback, "Bad memory size %d; must be 1 to 24, inclusive\n", n);
1207 }
1208
1209 void
1210 sim_close (sd, quitting)
1211 SIM_DESC sd;
1212 int quitting;
1213 {
1214 /* nothing to do */
1215 }
1216
1217 SIM_RC
1218 sim_load (sd, prog, abfd, from_tty)
1219 SIM_DESC sd;
1220 char *prog;
1221 bfd *abfd;
1222 int from_tty;
1223 {
1224 extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
1225 bfd *prog_bfd;
1226
1227 prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
1228 sim_kind == SIM_OPEN_DEBUG);
1229 if (prog_bfd == NULL)
1230 return SIM_RC_FAIL;
1231 saved_state.asregs.pc = bfd_get_start_address (prog_bfd);
1232 if (abfd == NULL)
1233 bfd_close (prog_bfd);
1234 return SIM_RC_OK;
1235 }
1236
1237 SIM_RC
1238 sim_create_inferior (sd, argv, env)
1239 SIM_DESC sd;
1240 char **argv;
1241 char **env;
1242 {
1243 return SIM_RC_OK;
1244 }
1245
1246 void
1247 sim_kill (sd)
1248 SIM_DESC sd;
1249 {
1250 /* nothing to do */
1251 }
1252
1253 void
1254 sim_do_command (sd, cmd)
1255 SIM_DESC sd;
1256 char *cmd;
1257 {
1258 char *sms_cmd = "set-memory-size";
1259 int cmdsize;
1260
1261 if (cmd == NULL || *cmd == '\0')
1262 {
1263 cmd = "help";
1264 }
1265
1266 cmdsize = strlen (sms_cmd);
1267 if (strncmp (cmd, sms_cmd, cmdsize) == 0 && strchr (" \t", cmd[cmdsize]) != NULL)
1268 {
1269 parse_and_set_memory_size (cmd + cmdsize + 1);
1270 }
1271 else if (strcmp (cmd, "help") == 0)
1272 {
1273 (callback->printf_filtered) (callback, "List of SH simulator commands:\n\n");
1274 (callback->printf_filtered) (callback, "set-memory-size <n> -- Set the number of address bits to use\n");
1275 (callback->printf_filtered) (callback, "\n");
1276 }
1277 else
1278 {
1279 (callback->printf_filtered) (callback, "Error: \"%s\" is not a valid SH simulator command.\n", cmd);
1280 }
1281 }
1282
1283 void
1284 sim_set_callbacks (sd, p)
1285 SIM_DESC sd;
1286 host_callback *p;
1287 {
1288 callback = p;
1289 }
This page took 0.059606 seconds and 4 git commands to generate.