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