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