]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/sh/interp.c
* interp.c (sim_resume): Fix argument to poll_quit.
[thirdparty/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 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 }