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