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