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