1 /* Simulator for the Hitachi SH architecture.
3 Written by Steve Chamberlain of Cygnus Support.
6 This file is part of SH sim
9 THIS SOFTWARE IS NOT COPYRIGHTED
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.
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.
21 #include <sys/times.h>
22 #include <sys/param.h>
24 #define O_RECOMPILE 85
27 #define DISASSEMBLER_TABLE
29 #define SBIT(x) ((x)&sbit)
30 #define R0 saved_state.asregs.regs[0]
31 #define Rn saved_state.asregs.regs[n]
32 #define Rm saved_state.asregs.regs[m]
33 #define UR0 (unsigned int)(saved_state.asregs.regs[0])
34 #define UR (unsigned int)R
35 #define UR (unsigned int)R
36 #define SR0 saved_state.asregs.regs[0]
37 #define GBR saved_state.asregs.gbr
38 #define VBR saved_state.asregs.vbr
39 #define MACH saved_state.asregs.mach
40 #define MACL saved_state.asregs.macl
41 #define M saved_state.asregs.sr.bits.m
42 #define Q saved_state.asregs.sr.bits.q
44 #define GET_SR() (saved_state.asregs.sr.bits.t = T, saved_state.asregs.sr.word)
45 #define SET_SR(x) {saved_state.asregs.sr.word = (x); T =saved_state.asregs.sr.bits.t;}
50 #ifdef TARGET_BIG_ENDIAN
51 #define LMEM(x) *((long *)(memory+((x)&maskl)))
52 #define BMEM(x) *((char *)(memory+((x)&maskb)))
53 #define UWMEM(x) *((unsigned short *)(memory+((x)&maskw)))
54 #define SWMEM(x) *((short *)(memory+((x)&maskw)))
55 #define WLAT(x,value) (LMEM(x) = value)
56 #define RLAT(x) (LMEM(x))
57 #define WWAT(x,value) (UWMEM(x) = value)
58 #define RSWAT(x) (SWMEM(x))
59 #define RUWAT(x) (UWMEM(x))
60 #define WBAT(x,value) (BMEM(x) = value)
61 #define RBAT(x) (BMEM(x))
63 /* For little endian or unknown host machines */
64 #define WLAT(x,value)\
65 { int v = value; unsigned char *p = memory + ((x) & maskl);\
66 p[0] =v>>24;p[1] = v>>16;p[2]=v>>8;p[3]=v; }
68 #define WWAT(x,value)\
69 { int v = value; unsigned char *p = memory + (x & maskw);p[0] =v>>8;p[1] = v ;}
71 #define WBAT(x,value)\
72 { unsigned char *p = memory + (x & maskb);p[0] =value;}
75 ((memory[x&maskl]<<24)|(memory[(x&maskl)+1]<<16)|(memory[(x&maskl)+2]<<8)| (memory[(x&maskl)+3]))
78 ((memory[x&maskw]<<8)|(memory[(x&maskw)+1]))
83 #define RUWAT(x) (RWAT(x) & 0xffff)
84 #define RSWAT(x) ((short)(RWAT(x)))
85 #define RSBAT(x) (SEXT(RBAT(x)))
91 #define SEXT(x) (((x&0xff) ^ (~0x7f))+0x80)
92 #define SEXTW(y) ((int)((short)y))
94 #define SL(TEMPPC) iword= RUWAT(TEMPPC); goto top;
97 #define L(x) thislock = x;
98 #define TL(x) if ((x) == prevlock) stalls++;
99 #define TB(x,y) if ((x) == prevlock || (y)==prevlock) stalls++;
100 int sim_memory_size
= 19;
101 static int sim_profile_size
= 17;
145 #define PROFILE_FREQ 1
146 #define PROFILE_SHIFT 2
148 unsigned short *profile_hist
;
149 unsigned char *memory
;
158 saved_state_type saved_state
;
165 return b
.tms_utime
+ b
.tms_stime
;
182 static FILE *profile_file
;
211 fwrite (b
, 4, 1, profile_file
);
221 fwrite (b
, 2, 1, profile_file
);
225 /* Turn a pointer in a register into a pointer into real memory. */
231 return (char *) (x
+ saved_state
.asregs
.memory
);
234 /* Simulate a monitor trap. */
244 printf ("%c", regs
[0]);
247 saved_state
.asregs
.exception
= SIGQUIT
;
258 regs
[4] = read (regs
[5], ptr (regs
[6]), regs
[7]);
261 regs
[4] = write (regs
[5], ptr (regs
[6]), regs
[7]);
264 regs
[4] = lseek (regs
[5], regs
[6], regs
[7]);
267 regs
[4] = close (regs
[5]);
270 regs
[4] = open (ptr (regs
[5]), regs
[6]);
282 saved_state
.asregs
.exception
= SIGILL
;
288 control_c (sig
, code
, scp
, addr
)
294 saved_state
.asregs
.exception
= SIGINT
;
299 div1 (R
, iRn2
, iRn1
, T
)
306 unsigned char old_q
, tmp1
;
309 Q
= (unsigned char) ((0x80000000 & R
[iRn1
]) != 0);
311 R
[iRn1
] |= (unsigned long) T
;
321 tmp1
= (R
[iRn1
] > tmp0
);
328 Q
= (unsigned char) (tmp1
== 0);
335 tmp1
= (R
[iRn1
] < tmp0
);
339 Q
= (unsigned char) (tmp1
== 0);
354 tmp1
= (R
[iRn1
] < tmp0
);
361 Q
= (unsigned char) (tmp1
== 0);
368 tmp1
= (R
[iRn1
] > tmp0
);
372 Q
= (unsigned char) (tmp1
== 0);
393 unsigned long RnL
, RnH
;
394 unsigned long RmL
, RmH
;
395 unsigned long temp0
, temp1
, temp2
, temp3
;
396 unsigned long Res2
, Res1
, Res0
;
403 RnH
= (rn
>> 16) & 0xffff;
405 RmH
= (rm
>> 16) & 0xffff;
411 Res1
= temp1
+ temp2
;
414 temp1
= (Res1
<< 16) & 0xffff0000;
415 Res0
= temp0
+ temp1
;
418 Res2
+= ((Res1
>> 16) & 0xffff) + temp3
;
432 /* Set the memory size to the power of two provided. */
439 saved_state
.asregs
.msize
= 1 << power
;
441 sim_memory_size
= power
;
444 if (saved_state
.asregs
.memory
)
446 free (saved_state
.asregs
.memory
);
449 saved_state
.asregs
.memory
=
450 (unsigned char *) calloc (64, saved_state
.asregs
.msize
/ 64);
452 if (!saved_state
.asregs
.memory
)
455 "Not enough VM for simuation of %d bytes of RAM\n",
456 saved_state
.asregs
.msize
);
458 saved_state
.asregs
.msize
= 1;
459 saved_state
.asregs
.memory
= (unsigned char *) calloc (1, 1);
469 if (saved_state
.asregs
.msize
!= 1 << sim_memory_size
)
471 sim_size (sim_memory_size
);
474 if (saved_state
.asregs
.profile
&& !profile_file
)
476 profile_file
= fopen ("gmon.out", "wb");
477 /* Seek to where to put the call arc data */
478 nsamples
= (1 << sim_profile_size
);
480 fseek (profile_file
, nsamples
* 2 + 12, 0);
484 fprintf (stderr
, "Can't open gmon.out\n");
488 saved_state
.asregs
.profile_hist
=
489 (unsigned short *) calloc (64, (nsamples
* sizeof (short) / 64));
503 unsigned short *first
;
506 p
= saved_state
.asregs
.profile_hist
;
508 maxpc
= (1 << sim_profile_size
);
510 fseek (profile_file
, 0L, 0);
511 swapout (minpc
<< PROFILE_SHIFT
);
512 swapout (maxpc
<< PROFILE_SHIFT
);
513 swapout (nsamples
* 2 + 12);
514 for (i
= 0; i
< nsamples
; i
++)
515 swapout16 (saved_state
.asregs
.profile_hist
[i
]);
529 #define MMASKB ((saved_state.asregs.msize -1) & ~0)
534 register unsigned int pc
;
535 register int cycles
= 0;
536 register int stalls
= 0;
537 register int insts
= 0;
538 register int prevlock
;
539 register int thislock
;
540 register unsigned int doprofile
;
542 int tick_start
= get_now ();
544 extern unsigned char sh_jump_table0
[];
546 register unsigned char *jump_table
= sh_jump_table0
;
548 register int *R
= &(saved_state
.asregs
.regs
[0]);
552 register int maskb
= ((saved_state
.asregs
.msize
- 1) & ~0);
553 register int maskw
= ((saved_state
.asregs
.msize
- 1) & ~1);
554 register int maskl
= ((saved_state
.asregs
.msize
- 1) & ~3);
555 register unsigned char *memory
= saved_state
.asregs
.memory
;
556 register unsigned int sbit
= (1 << 31);
558 prev
= signal (SIGINT
, control_c
);
564 saved_state
.asregs
.exception
= SIGTRAP
;
568 saved_state
.asregs
.exception
= 0;
571 pc
= saved_state
.asregs
.pc
;
572 PR
= saved_state
.asregs
.pr
;
573 T
= saved_state
.asregs
.sr
.bits
.t
;
574 prevlock
= saved_state
.asregs
.prevlock
;
575 thislock
= saved_state
.asregs
.thislock
;
576 doprofile
= saved_state
.asregs
.profile
;
578 /* If profiling not enabled, disable it by asking for
579 profiles infrequently. */
585 register unsigned int iword
= RUWAT (pc
);
586 register unsigned int ult
;
599 if (cycles
>= doprofile
)
601 saved_state
.asregs
.cycles
+= doprofile
;
603 if (saved_state
.asregs
.profile_hist
)
605 int n
= pc
>> PROFILE_SHIFT
;
608 int i
= saved_state
.asregs
.profile_hist
[n
];
610 saved_state
.asregs
.profile_hist
[n
] = i
+ 1;
616 while (!saved_state
.asregs
.exception
);
618 if (saved_state
.asregs
.exception
== SIGILL
)
623 saved_state
.asregs
.ticks
+= get_now () - tick_start
;
624 saved_state
.asregs
.cycles
+= cycles
;
625 saved_state
.asregs
.stalls
+= stalls
;
626 saved_state
.asregs
.insts
+= insts
;
627 saved_state
.asregs
.pc
= pc
;
628 saved_state
.asregs
.sr
.bits
.t
= T
;
629 saved_state
.asregs
.pr
= PR
;
631 saved_state
.asregs
.prevlock
= prevlock
;
632 saved_state
.asregs
.thislock
= thislock
;
640 signal (SIGINT
, prev
);
647 sim_write (addr
, buffer
, size
)
649 unsigned char *buffer
;
655 for (i
= 0; i
< size
; i
++)
657 saved_state
.asregs
.memory
[MMASKB
& (addr
+ i
)] = buffer
[i
];
662 sim_read (addr
, buffer
, size
)
671 for (i
= 0; i
< size
; i
++)
673 buffer
[i
] = saved_state
.asregs
.memory
[MMASKB
& (addr
+ i
)];
679 sim_store_register (rn
, value
)
683 saved_state
.asregs
.regs
[rn
] = value
;
687 sim_fetch_register (rn
, buf
)
691 int value
= ((int *) (&saved_state
))[rn
];
706 return saved_state
.asregs
.exception
;
713 saved_state
.asregs
.pc
= x
;
720 double timetaken
= (double) saved_state
.asregs
.ticks
/ (double) now_persec ();
721 double virttime
= saved_state
.asregs
.cycles
/ 36.0e6
;
723 printf ("\n\n# instructions executed %10d\n", saved_state
.asregs
.insts
);
724 printf ("# cycles %10d\n", saved_state
.asregs
.cycles
);
725 printf ("# pipeline stalls %10d\n", saved_state
.asregs
.stalls
);
726 printf ("# real time taken %10.4f\n", timetaken
);
727 printf ("# virtual time taked %10.4f\n", virttime
);
728 printf ("# profiling size %10d\n", sim_profile_size
);
729 printf ("# profiling frequency %10d\n", saved_state
.asregs
.profile
);
730 printf ("# profile maxpc %10x\n", (1 << sim_profile_size
) << PROFILE_SHIFT
);
734 printf ("# cycles/second %10d\n", (int) (saved_state
.asregs
.cycles
/ timetaken
));
735 printf ("# simulation ratio %10.4f\n", virttime
/ timetaken
);
743 saved_state
.asregs
.profile
= n
;
747 sim_set_profile_size (n
)
749 sim_profile_size
= n
;