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