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.
24 #include "remote-sim.h"
25 #include <sys/syscall.h>
27 #if !defined (SYS_wait) && defined (SYS_wait4)
28 #define SYS_wait SYS_wait4 /* SunOS 4.1.3 for example */
31 #if !defined (SYS_utime) && defined (SYS_utimes)
32 #define SYS_utime SYS_utimes /* SunOS 4.1.3 for example */
36 #define SIGBUS SIGSEGV
39 #define SIGQUIT SIGTERM
42 #define O_RECOMPILE 85
44 #define DISASSEMBLER_TABLE
48 #define SBIT(x) ((x)&sbit)
49 #define R0 saved_state.asregs.regs[0]
50 #define Rn saved_state.asregs.regs[n]
51 #define Rm saved_state.asregs.regs[m]
52 #define UR0 (unsigned int)(saved_state.asregs.regs[0])
53 #define UR (unsigned int)R
54 #define UR (unsigned int)R
55 #define SR0 saved_state.asregs.regs[0]
56 #define GBR saved_state.asregs.gbr
57 #define VBR saved_state.asregs.vbr
58 #define MACH saved_state.asregs.mach
59 #define MACL saved_state.asregs.macl
60 #define M saved_state.asregs.sr.bits.m
61 #define Q saved_state.asregs.sr.bits.q
62 #define S saved_state.asregs.sr.bits.s
64 #define GET_SR() (saved_state.asregs.sr.bits.t = T, saved_state.asregs.sr.word)
65 #define SET_SR(x) {saved_state.asregs.sr.word = (x); T =saved_state.asregs.sr.bits.t;}
77 #define BUSERROR(addr, mask) \
78 if (addr & ~mask) { saved_state.asregs.exception = SIGBUS;}
80 /* Define this to enable register lifetime checking.
81 The compiler generates "add #0,rn" insns to mark registers as invalid,
82 the simulator uses this info to call fail if it finds a ref to an invalid
90 #define CREF(x) if(!valid[x]) fail();
91 #define CDEF(x) valid[x] = 1;
92 #define UNDEF(x) valid[x] = 0;
99 static int IOMEM
PARAMS ((int addr
, int write
, int value
));
101 /* These variables are at file scope so that functions other than
102 sim_resume can use the fetch/store macros */
104 static int little_endian
;
107 static int maskl
= ~0;
108 static int maskw
= ~0;
152 #define PROFILE_FREQ 1
153 #define PROFILE_SHIFT 2
155 unsigned short *profile_hist
;
156 unsigned char *memory
;
163 saved_state_type saved_state
;
166 wlat_little (memory
, x
, value
, maskl
)
167 unsigned char *memory
;
170 unsigned char *p
= memory
+ ((x
) & maskl
);
179 wwat_little (memory
, x
, value
, maskw
)
180 unsigned char *memory
;
183 unsigned char *p
= memory
+ ((x
) & maskw
);
192 wbat_any (memory
, x
, value
, maskb
)
193 unsigned char *memory
;
195 unsigned char *p
= memory
+ (x
& maskb
);
206 wlat_big (memory
, x
, value
, maskl
)
207 unsigned char *memory
;
210 unsigned char *p
= memory
+ ((x
) & maskl
);
220 wwat_big (memory
, x
, value
, maskw
)
221 unsigned char *memory
;
224 unsigned char *p
= memory
+ ((x
) & maskw
);
233 wbat_big (memory
, x
, value
, maskb
)
234 unsigned char *memory
;
236 unsigned char *p
= memory
+ (x
& maskb
);
248 rlat_little (memory
, x
, maskl
)
249 unsigned char *memory
;
251 unsigned char *p
= memory
+ ((x
) & maskl
);
254 return (p
[3] << 24) | (p
[2] << 16) | (p
[1] << 8) | p
[0];
259 rwat_little (memory
, x
, maskw
)
260 unsigned char *memory
;
262 unsigned char *p
= memory
+ ((x
) & maskw
);
265 return (p
[1] << 8) | p
[0];
269 rbat_any (memory
, x
, maskb
)
270 unsigned char *memory
;
272 unsigned char *p
= memory
+ ((x
) & maskb
);
279 rlat_big (memory
, x
, maskl
)
280 unsigned char *memory
;
282 unsigned char *p
= memory
+ ((x
) & maskl
);
285 return (p
[0] << 24) | (p
[1] << 16) | (p
[2] << 8) | p
[3];
290 rwat_big (memory
, x
, maskw
)
291 unsigned char *memory
;
293 unsigned char *p
= memory
+ ((x
) & maskw
);
296 return (p
[0] << 8) | p
[1];
300 #define RWAT(x) (little_endian ? rwat_little(memory, x, maskw): rwat_big(memory, x, maskw))
301 #define RLAT(x) (little_endian ? rlat_little(memory, x, maskl): rlat_big(memory, x, maskl))
302 #define RBAT(x) (rbat_any (memory, x, maskb))
303 #define WWAT(x,v) (little_endian ? wwat_little(memory, x, v, maskw): wwat_big(memory, x, v, maskw))
304 #define WLAT(x,v) (little_endian ? wlat_little(memory, x, v, maskl): wlat_big(memory, x, v, maskl))
305 #define WBAT(x,v) (wbat_any (memory, x, v, maskb))
307 #define RUWAT(x) (RWAT(x) & 0xffff)
308 #define RSWAT(x) ((short)(RWAT(x)))
309 #define RSBAT(x) (SEXT(RBAT(x)))
311 #define SEXT(x) (((x&0xff) ^ (~0x7f))+0x80)
312 #define SEXTW(y) ((int)((short)y))
314 #define SL(TEMPPC) iword= RUWAT(TEMPPC); goto top;
319 #define L(x) thislock = x;
320 #define TL(x) if ((x) == prevlock) stalls++;
321 #define TB(x,y) if ((x) == prevlock || (y)==prevlock) stalls++;
323 #if defined(__GO32__) || defined(WIN32)
324 int sim_memory_size
= 19;
326 int sim_memory_size
= 24;
329 static int sim_profile_size
= 17;
335 #define SMR1 (0x05FFFEC8) /* Channel 1 serial mode register */
336 #define BRR1 (0x05FFFEC9) /* Channel 1 bit rate register */
337 #define SCR1 (0x05FFFECA) /* Channel 1 serial control register */
338 #define TDR1 (0x05FFFECB) /* Channel 1 transmit data register */
339 #define SSR1 (0x05FFFECC) /* Channel 1 serial status register */
340 #define RDR1 (0x05FFFECD) /* Channel 1 receive data register */
342 #define SCI_RDRF 0x40 /* Recieve data register full */
343 #define SCI_TDRE 0x80 /* Transmit data register empty */
346 IOMEM (addr
, write
, value
)
354 static char lastchar
;
384 return time ((long *) 0);
395 static FILE *profile_file
;
399 unsigned char *memory
;
406 unsigned char *memory
;
420 fwrite (b
, 4, 1, profile_file
);
430 fwrite (b
, 2, 1, profile_file
);
434 /* Turn a pointer in a register into a pointer into real memory. */
440 return (char *) (x
+ saved_state
.asregs
.memory
);
444 /* Simulate a monitor trap, put the result into r0 and errno into r1 */
446 trap (i
, regs
, memory
, maskl
, maskw
, little_endian
)
449 unsigned char *memory
;
454 printf ("%c", regs
[0]);
457 saved_state
.asregs
.exception
= SIGQUIT
;
461 trap8 (ptr (regs
[4]));
464 trap9 (ptr (regs
[4]));
485 #if !defined(__GO32__) && !defined(WIN32)
491 regs
[0] = execve (ptr (regs
[5]), ptr (regs
[6]), ptr (regs
[7]));
494 regs
[0] = execv (ptr (regs
[5]), ptr (regs
[6]));
503 regs
[0] = pipe (host_fd
);
505 WLAT (buf
, host_fd
[0]);
507 WLAT (buf
, host_fd
[1]);
512 regs
[0] = wait (ptr (regs
[5]));
517 regs
[0] = read (regs
[5], ptr (regs
[6]), regs
[7]);
520 regs
[0] = write (regs
[5], ptr (regs
[6]), regs
[7]);
523 regs
[0] = lseek (regs
[5], regs
[6], regs
[7]);
526 regs
[0] = close (regs
[5]);
529 regs
[0] = open (ptr (regs
[5]), regs
[6]);
532 /* EXIT - caller can look in r5 to work out the
534 saved_state
.asregs
.exception
= SIGQUIT
;
537 case SYS_stat
: /* added at hmsi */
538 /* stat system call */
540 struct stat host_stat
;
543 regs
[0] = stat (ptr (regs
[5]), &host_stat
);
547 WWAT (buf
, host_stat
.st_dev
);
549 WWAT (buf
, host_stat
.st_ino
);
551 WLAT (buf
, host_stat
.st_mode
);
553 WWAT (buf
, host_stat
.st_nlink
);
555 WWAT (buf
, host_stat
.st_uid
);
557 WWAT (buf
, host_stat
.st_gid
);
559 WWAT (buf
, host_stat
.st_rdev
);
561 WLAT (buf
, host_stat
.st_size
);
563 WLAT (buf
, host_stat
.st_atime
);
567 WLAT (buf
, host_stat
.st_mtime
);
571 WLAT (buf
, host_stat
.st_ctime
);
583 regs
[0] = chown (ptr (regs
[5]), regs
[6], regs
[7]);
586 regs
[0] = chmod (ptr (regs
[5]), regs
[6]);
589 regs
[0] = utime (ptr (regs
[5]), ptr (regs
[6]));
602 saved_state
.asregs
.exception
= SIGTRAP
;
608 control_c (sig
, code
, scp
, addr
)
614 saved_state
.asregs
.exception
= SIGINT
;
619 div1 (R
, iRn2
, iRn1
, T
)
626 unsigned char old_q
, tmp1
;
629 Q
= (unsigned char) ((0x80000000 & R
[iRn1
]) != 0);
631 R
[iRn1
] |= (unsigned long) T
;
641 tmp1
= (R
[iRn1
] > tmp0
);
648 Q
= (unsigned char) (tmp1
== 0);
655 tmp1
= (R
[iRn1
] < tmp0
);
659 Q
= (unsigned char) (tmp1
== 0);
674 tmp1
= (R
[iRn1
] < tmp0
);
681 Q
= (unsigned char) (tmp1
== 0);
688 tmp1
= (R
[iRn1
] > tmp0
);
692 Q
= (unsigned char) (tmp1
== 0);
713 unsigned long RnL
, RnH
;
714 unsigned long RmL
, RmH
;
715 unsigned long temp0
, temp1
, temp2
, temp3
;
716 unsigned long Res2
, Res1
, Res0
;
719 RnH
= (rn
>> 16) & 0xffff;
721 RmH
= (rm
>> 16) & 0xffff;
727 Res1
= temp1
+ temp2
;
730 temp1
= (Res1
<< 16) & 0xffff0000;
731 Res0
= temp0
+ temp1
;
734 Res2
+= ((Res1
>> 16) & 0xffff) + temp3
;
749 macw (regs
, memory
, n
, m
)
751 unsigned char *memory
;
755 long prod
, macl
, sum
;
757 tempm
=RSWAT(regs
[m
]); regs
[m
]+=2;
758 tempn
=RSWAT(regs
[n
]); regs
[n
]+=2;
761 prod
= (long)(short) tempm
* (long)(short) tempn
;
765 if ((~(prod
^ macl
) & (sum
^ prod
)) < 0)
767 /* MACH's lsb is a sticky overflow bit. */
769 /* Store the smallest negative number in MACL if prod is
770 negative, and the largest positive number otherwise. */
771 sum
= 0x7fffffff + (prod
< 0);
777 /* Add to MACH the sign extended product, and carry from low sum. */
778 mach
= MACH
+ (-(prod
< 0)) + ((unsigned long) sum
< prod
);
779 /* Sign extend at 10:th bit in MACH. */
780 MACH
= (mach
& 0x1ff) | -(mach
& 0x200);
785 /* Set the memory size to the power of two provided. */
792 saved_state
.asregs
.msize
= 1 << power
;
794 sim_memory_size
= power
;
797 if (saved_state
.asregs
.memory
)
799 free (saved_state
.asregs
.memory
);
802 saved_state
.asregs
.memory
=
803 (unsigned char *) calloc (64, saved_state
.asregs
.msize
/ 64);
805 if (!saved_state
.asregs
.memory
)
808 "Not enough VM for simulation of %d bytes of RAM\n",
809 saved_state
.asregs
.msize
);
811 saved_state
.asregs
.msize
= 1;
812 saved_state
.asregs
.memory
= (unsigned char *) calloc (1, 1);
817 int target_byte_order
;
820 set_static_little_endian(x
)
830 register int little_endian
= target_byte_order
== 1234;
831 set_static_little_endian (little_endian
);
832 if (saved_state
.asregs
.msize
!= 1 << sim_memory_size
)
834 sim_size (sim_memory_size
);
837 if (saved_state
.asregs
.profile
&& !profile_file
)
839 profile_file
= fopen ("gmon.out", "wb");
840 /* Seek to where to put the call arc data */
841 nsamples
= (1 << sim_profile_size
);
843 fseek (profile_file
, nsamples
* 2 + 12, 0);
847 fprintf (stderr
, "Can't open gmon.out\n");
851 saved_state
.asregs
.profile_hist
=
852 (unsigned short *) calloc (64, (nsamples
* sizeof (short) / 64));
866 unsigned short *first
;
869 p
= saved_state
.asregs
.profile_hist
;
871 maxpc
= (1 << sim_profile_size
);
873 fseek (profile_file
, 0L, 0);
874 swapout (minpc
<< PROFILE_SHIFT
);
875 swapout (maxpc
<< PROFILE_SHIFT
);
876 swapout (nsamples
* 2 + 12);
877 for (i
= 0; i
< nsamples
; i
++)
878 swapout16 (saved_state
.asregs
.profile_hist
[i
]);
892 #define MMASKB ((saved_state.asregs.msize -1) & ~0)
896 sim_resume (step
, siggnal
)
899 register unsigned int pc
;
900 register int cycles
= 0;
901 register int stalls
= 0;
902 register int insts
= 0;
903 register int prevlock
;
904 register int thislock
;
905 register unsigned int doprofile
;
906 #if defined(__GO32__) || defined(WIN32)
907 register int pollcount
= 0;
909 register int little_endian
= target_byte_order
== 1234;
912 int tick_start
= get_now ();
914 extern unsigned char sh_jump_table0
[];
916 register unsigned char *jump_table
= sh_jump_table0
;
918 register int *R
= &(saved_state
.asregs
.regs
[0]);
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);
925 register unsigned char *memory
;
926 register unsigned int sbit
= (1 << 31);
928 prev
= signal (SIGINT
, control_c
);
932 memory
= saved_state
.asregs
.memory
;
936 saved_state
.asregs
.exception
= SIGTRAP
;
940 saved_state
.asregs
.exception
= 0;
943 pc
= saved_state
.asregs
.pc
;
944 PR
= saved_state
.asregs
.pr
;
945 T
= saved_state
.asregs
.sr
.bits
.t
;
946 prevlock
= saved_state
.asregs
.prevlock
;
947 thislock
= saved_state
.asregs
.thislock
;
948 doprofile
= saved_state
.asregs
.profile
;
950 /* If profiling not enabled, disable it by asking for
951 profiles infrequently. */
957 register unsigned int iword
= RUWAT (pc
);
958 register unsigned int ult
;
971 if (pollcount
> 1000)
977 saved_state
.asregs
.exception
= SIGINT
;
984 if (pollcount
> 1000)
999 if (cycles
>= doprofile
)
1002 saved_state
.asregs
.cycles
+= doprofile
;
1003 cycles
-= doprofile
;
1004 if (saved_state
.asregs
.profile_hist
)
1006 int n
= pc
>> PROFILE_SHIFT
;
1009 int i
= saved_state
.asregs
.profile_hist
[n
];
1011 saved_state
.asregs
.profile_hist
[n
] = i
+ 1;
1018 while (!saved_state
.asregs
.exception
);
1020 if (saved_state
.asregs
.exception
== SIGILL
1021 || saved_state
.asregs
.exception
== SIGBUS
)
1026 saved_state
.asregs
.ticks
+= get_now () - tick_start
;
1027 saved_state
.asregs
.cycles
+= cycles
;
1028 saved_state
.asregs
.stalls
+= stalls
;
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
;
1034 saved_state
.asregs
.prevlock
= prevlock
;
1035 saved_state
.asregs
.thislock
= thislock
;
1043 signal (SIGINT
, prev
);
1050 sim_write (addr
, buffer
, size
)
1052 unsigned char *buffer
;
1058 for (i
= 0; i
< size
; i
++)
1060 saved_state
.asregs
.memory
[MMASKB
& (addr
+ i
)] = buffer
[i
];
1066 sim_read (addr
, buffer
, size
)
1068 unsigned char *buffer
;
1075 for (i
= 0; i
< size
; i
++)
1077 buffer
[i
] = saved_state
.asregs
.memory
[MMASKB
& (addr
+ i
)];
1084 sim_store_register (rn
, memory
)
1086 unsigned char *memory
;
1089 saved_state
.asregs
.regs
[rn
]=RLAT(0);
1093 sim_fetch_register (rn
, memory
)
1095 unsigned char *memory
;
1098 WLAT (0, saved_state
.asregs
.regs
[rn
]);
1109 sim_stop_reason (reason
, sigrc
)
1110 enum sim_stop
*reason
;
1113 *reason
= sim_stopped
;
1114 *sigrc
= saved_state
.asregs
.exception
;
1122 double timetaken
= (double) saved_state
.asregs
.ticks
/ (double) now_persec ();
1123 double virttime
= saved_state
.asregs
.cycles
/ 36.0e6
;
1125 printf_filtered ("\n\n# instructions executed %10d\n", saved_state
.asregs
.insts
);
1126 printf_filtered ("# cycles %10d\n", saved_state
.asregs
.cycles
);
1127 printf_filtered ("# pipeline stalls %10d\n", saved_state
.asregs
.stalls
);
1128 printf_filtered ("# real time taken %10.4f\n", timetaken
);
1129 printf_filtered ("# virtual time taken %10.4f\n", virttime
);
1130 printf_filtered ("# profiling size %10d\n", sim_profile_size
);
1131 printf_filtered ("# profiling frequency %10d\n", saved_state
.asregs
.profile
);
1132 printf_filtered ("# profile maxpc %10x\n", (1 << sim_profile_size
) << PROFILE_SHIFT
);
1136 printf_filtered ("# cycles/second %10d\n", (int) (saved_state
.asregs
.cycles
/ timetaken
));
1137 printf_filtered ("# simulation ratio %10.4f\n", virttime
/ timetaken
);
1146 saved_state
.asregs
.profile
= n
;
1150 sim_set_profile_size (n
)
1153 sim_profile_size
= n
;
1165 sim_close (quitting
)
1172 sim_load (prog
, from_tty
)
1176 /* Return nonzero so GDB will handle it. */
1181 sim_create_inferior (start_address
, argv
, env
)
1182 SIM_ADDR start_address
;
1186 saved_state
.asregs
.pc
= start_address
;