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.
23 #include <sys/times.h>
24 #include <sys/param.h>
26 #include "remote-sim.h"
27 #include "../../newlib/libc/sys/sh/sys/syscall.h"
28 #define O_RECOMPILE 85
31 #define DISASSEMBLER_TABLE
33 #define SBIT(x) ((x)&sbit)
34 #define R0 saved_state.asregs.regs[0]
35 #define Rn saved_state.asregs.regs[n]
36 #define Rm saved_state.asregs.regs[m]
37 #define UR0 (unsigned int)(saved_state.asregs.regs[0])
38 #define UR (unsigned int)R
39 #define UR (unsigned int)R
40 #define SR0 saved_state.asregs.regs[0]
41 #define GBR saved_state.asregs.gbr
42 #define VBR saved_state.asregs.vbr
43 #define MACH saved_state.asregs.mach
44 #define MACL saved_state.asregs.macl
45 #define M saved_state.asregs.sr.bits.m
46 #define Q saved_state.asregs.sr.bits.q
47 #define S saved_state.asregs.sr.bits.s
49 #define GET_SR() (saved_state.asregs.sr.bits.t = T, saved_state.asregs.sr.word)
50 #define SET_SR(x) {saved_state.asregs.sr.word = (x); T =saved_state.asregs.sr.bits.t;}
62 #define BUSERROR(addr, mask) \
63 if (addr & ~mask) { saved_state.asregs.exception = SIGBUS;}
65 /* Define this to enable register lifetime checking.
66 The compiler generates "add #0,rn" insns to mark registers as invalid,
67 the simulator uses this info to call fail if it finds a ref to an invalid
75 #define CREF(x) if(!valid[x]) fail();
76 #define CDEF(x) valid[x] = 1;
77 #define UNDEF(x) valid[x] = 0;
84 static int IOMEM
PARAMS ((int addr
, int write
, int value
));
86 /* These variables are at file scope so that functions other than
87 sim_resume can use the fetch/store macros */
89 static int little_endian
;
92 static int maskl
= ~0;
93 static int maskw
= ~0;
137 #define PROFILE_FREQ 1
138 #define PROFILE_SHIFT 2
140 unsigned short *profile_hist
;
141 unsigned char *memory
;
148 saved_state_type saved_state
;
151 wlat_little (memory
, x
, value
, maskl
)
152 unsigned char *memory
;
155 unsigned char *p
= memory
+ ((x
) & maskl
);
164 wwat_little (memory
, x
, value
, maskw
)
165 unsigned char *memory
;
168 unsigned char *p
= memory
+ ((x
) & maskw
);
177 wbat_any (memory
, x
, value
, maskb
)
178 unsigned char *memory
;
180 unsigned char *p
= memory
+ (x
& maskb
);
191 wlat_big (memory
, x
, value
, maskl
)
192 unsigned char *memory
;
195 unsigned char *p
= memory
+ ((x
) & maskl
);
205 wwat_big (memory
, x
, value
, maskw
)
206 unsigned char *memory
;
209 unsigned char *p
= memory
+ ((x
) & maskw
);
218 wbat_big (memory
, x
, value
, maskb
)
219 unsigned char *memory
;
221 unsigned char *p
= memory
+ (x
& maskb
);
233 rlat_little (memory
, x
, maskl
)
234 unsigned char *memory
;
236 unsigned char *p
= memory
+ ((x
) & maskl
);
239 return (p
[3] << 24) | (p
[2] << 16) | (p
[1] << 8) | p
[0];
244 rwat_little (memory
, x
, maskw
)
245 unsigned char *memory
;
247 unsigned char *p
= memory
+ ((x
) & maskw
);
250 return (p
[1] << 8) | p
[0];
254 rbat_any (memory
, x
, maskb
)
255 unsigned char *memory
;
257 unsigned char *p
= memory
+ ((x
) & maskb
);
264 rlat_big (memory
, x
, maskl
)
265 unsigned char *memory
;
267 unsigned char *p
= memory
+ ((x
) & maskl
);
270 return (p
[0] << 24) | (p
[1] << 16) | (p
[2] << 8) | p
[3];
275 rwat_big (memory
, x
, maskw
)
276 unsigned char *memory
;
278 unsigned char *p
= memory
+ ((x
) & maskw
);
281 return (p
[0] << 8) | p
[1];
285 #define RWAT(x) (little_endian ? rwat_little(memory, x, maskw): rwat_big(memory, x, maskw))
286 #define RLAT(x) (little_endian ? rlat_little(memory, x, maskl): rlat_big(memory, x, maskl))
287 #define RBAT(x) (rbat_any (memory, x, maskb))
288 #define WWAT(x,v) (little_endian ? wwat_little(memory, x, v, maskw): wwat_big(memory, x, v, maskw))
289 #define WLAT(x,v) (little_endian ? wlat_little(memory, x, v, maskl): wlat_big(memory, x, v, maskl))
290 #define WBAT(x,v) (wbat_any (memory, x, v, maskb))
292 #define RUWAT(x) (RWAT(x) & 0xffff)
293 #define RSWAT(x) ((short)(RWAT(x)))
294 #define RSBAT(x) (SEXT(RBAT(x)))
296 #define SEXT(x) (((x&0xff) ^ (~0x7f))+0x80)
297 #define SEXTW(y) ((int)((short)y))
299 #define SL(TEMPPC) iword= RUWAT(TEMPPC); goto top;
304 #define L(x) thislock = x;
305 #define TL(x) if ((x) == prevlock) stalls++;
306 #define TB(x,y) if ((x) == prevlock || (y)==prevlock) stalls++;
309 int sim_memory_size
= 19;
311 int sim_memory_size
= 24;
314 static int sim_profile_size
= 17;
320 #define SMR1 (0x05FFFEC8) /* Channel 1 serial mode register */
321 #define BRR1 (0x05FFFEC9) /* Channel 1 bit rate register */
322 #define SCR1 (0x05FFFECA) /* Channel 1 serial control register */
323 #define TDR1 (0x05FFFECB) /* Channel 1 transmit data register */
324 #define SSR1 (0x05FFFECC) /* Channel 1 serial status register */
325 #define RDR1 (0x05FFFECD) /* Channel 1 receive data register */
327 #define SCI_RDRF 0x40 /* Recieve data register full */
328 #define SCI_TDRE 0x80 /* Transmit data register empty */
331 IOMEM (addr
, write
, value
)
339 static char lastchar
;
369 return time ((long *) 0);
380 static FILE *profile_file
;
384 unsigned char *memory
;
391 unsigned char *memory
;
405 fwrite (b
, 4, 1, profile_file
);
415 fwrite (b
, 2, 1, profile_file
);
419 /* Turn a pointer in a register into a pointer into real memory. */
425 return (char *) (x
+ saved_state
.asregs
.memory
);
429 /* Simulate a monitor trap, put the result into r0 and errno into r1 */
431 trap (i
, regs
, memory
, maskl
, maskw
, little_endian
)
434 unsigned char *memory
;
439 printf ("%c", regs
[0]);
442 saved_state
.asregs
.exception
= SIGQUIT
;
446 trap8 (ptr (regs
[4]));
449 trap9 (ptr (regs
[4]));
476 regs
[0] = execve (ptr (regs
[5]), ptr (regs
[6]), ptr (regs
[7]));
479 regs
[0] = execv (ptr (regs
[5]), ptr (regs
[6]));
488 regs
[0] = pipe (host_fd
);
490 WLAT (buf
, host_fd
[0]);
492 WLAT (buf
, host_fd
[1]);
497 regs
[0] = wait (ptr (regs
[5]));
502 regs
[0] = read (regs
[5], ptr (regs
[6]), regs
[7]);
505 regs
[0] = write (regs
[5], ptr (regs
[6]), regs
[7]);
508 regs
[0] = lseek (regs
[5], regs
[6], regs
[7]);
511 regs
[0] = close (regs
[5]);
514 regs
[0] = open (ptr (regs
[5]), regs
[6]);
517 /* EXIT - caller can look in r5 to work out the
519 saved_state
.asregs
.exception
= SIGQUIT
;
522 case SYS_stat
: /* added at hmsi */
523 /* stat system call */
525 struct stat host_stat
;
528 regs
[0] = stat (ptr (regs
[5]), &host_stat
);
532 WWAT (buf
, host_stat
.st_dev
);
534 WWAT (buf
, host_stat
.st_ino
);
536 WLAT (buf
, host_stat
.st_mode
);
538 WWAT (buf
, host_stat
.st_nlink
);
540 WWAT (buf
, host_stat
.st_uid
);
542 WWAT (buf
, host_stat
.st_gid
);
544 WWAT (buf
, host_stat
.st_rdev
);
546 WLAT (buf
, host_stat
.st_size
);
548 WLAT (buf
, host_stat
.st_atime
);
552 WLAT (buf
, host_stat
.st_mtime
);
556 WLAT (buf
, host_stat
.st_ctime
);
568 regs
[0] = chown (ptr (regs
[5]), regs
[6], regs
[7]);
571 regs
[0] = chmod (ptr (regs
[5]), regs
[6]);
574 regs
[0] = utime (ptr (regs
[5]), ptr (regs
[6]));
587 saved_state
.asregs
.exception
= SIGTRAP
;
593 control_c (sig
, code
, scp
, addr
)
599 saved_state
.asregs
.exception
= SIGINT
;
604 div1 (R
, iRn2
, iRn1
, T
)
611 unsigned char old_q
, tmp1
;
614 Q
= (unsigned char) ((0x80000000 & R
[iRn1
]) != 0);
616 R
[iRn1
] |= (unsigned long) T
;
626 tmp1
= (R
[iRn1
] > tmp0
);
633 Q
= (unsigned char) (tmp1
== 0);
640 tmp1
= (R
[iRn1
] < tmp0
);
644 Q
= (unsigned char) (tmp1
== 0);
659 tmp1
= (R
[iRn1
] < tmp0
);
666 Q
= (unsigned char) (tmp1
== 0);
673 tmp1
= (R
[iRn1
] > tmp0
);
677 Q
= (unsigned char) (tmp1
== 0);
698 unsigned long RnL
, RnH
;
699 unsigned long RmL
, RmH
;
700 unsigned long temp0
, temp1
, temp2
, temp3
;
701 unsigned long Res2
, Res1
, Res0
;
704 RnH
= (rn
>> 16) & 0xffff;
706 RmH
= (rm
>> 16) & 0xffff;
712 Res1
= temp1
+ temp2
;
715 temp1
= (Res1
<< 16) & 0xffff0000;
716 Res0
= temp0
+ temp1
;
719 Res2
+= ((Res1
>> 16) & 0xffff) + temp3
;
734 macw (regs
, memory
, n
, m
)
736 unsigned char *memory
;
740 long prod
, macl
, sum
;
742 tempm
=RSWAT(regs
[m
]); regs
[m
]+=2;
743 tempn
=RSWAT(regs
[n
]); regs
[n
]+=2;
746 prod
= (long)(short) tempm
* (long)(short) tempn
;
750 if ((~(prod
^ macl
) & (sum
^ prod
)) < 0)
752 /* MACH's lsb is a sticky overflow bit. */
754 /* Store the smallest negative number in MACL if prod is
755 negative, and the largest positive number otherwise. */
756 sum
= 0x7fffffff + (prod
< 0);
761 /* Add to MACH the sign extended product, and carry from low sum. */
762 MACH
+= (-(prod
< 0)) + ((unsigned long) sum
< prod
);
767 /* Set the memory size to the power of two provided. */
774 saved_state
.asregs
.msize
= 1 << power
;
776 sim_memory_size
= power
;
779 if (saved_state
.asregs
.memory
)
781 free (saved_state
.asregs
.memory
);
784 saved_state
.asregs
.memory
=
785 (unsigned char *) calloc (64, saved_state
.asregs
.msize
/ 64);
787 if (!saved_state
.asregs
.memory
)
790 "Not enough VM for simulation of %d bytes of RAM\n",
791 saved_state
.asregs
.msize
);
793 saved_state
.asregs
.msize
= 1;
794 saved_state
.asregs
.memory
= (unsigned char *) calloc (1, 1);
799 extern int target_byte_order
;
802 set_static_little_endian(x
)
812 register int little_endian
= target_byte_order
== 1234;
813 set_static_little_endian (little_endian
);
814 if (saved_state
.asregs
.msize
!= 1 << sim_memory_size
)
816 sim_size (sim_memory_size
);
819 if (saved_state
.asregs
.profile
&& !profile_file
)
821 profile_file
= fopen ("gmon.out", "wb");
822 /* Seek to where to put the call arc data */
823 nsamples
= (1 << sim_profile_size
);
825 fseek (profile_file
, nsamples
* 2 + 12, 0);
829 fprintf (stderr
, "Can't open gmon.out\n");
833 saved_state
.asregs
.profile_hist
=
834 (unsigned short *) calloc (64, (nsamples
* sizeof (short) / 64));
848 unsigned short *first
;
851 p
= saved_state
.asregs
.profile_hist
;
853 maxpc
= (1 << sim_profile_size
);
855 fseek (profile_file
, 0L, 0);
856 swapout (minpc
<< PROFILE_SHIFT
);
857 swapout (maxpc
<< PROFILE_SHIFT
);
858 swapout (nsamples
* 2 + 12);
859 for (i
= 0; i
< nsamples
; i
++)
860 swapout16 (saved_state
.asregs
.profile_hist
[i
]);
874 #define MMASKB ((saved_state.asregs.msize -1) & ~0)
878 sim_resume (step
, siggnal
)
881 register unsigned int pc
;
882 register int cycles
= 0;
883 register int stalls
= 0;
884 register int insts
= 0;
885 register int prevlock
;
886 register int thislock
;
887 register unsigned int doprofile
;
889 register int pollcount
= 0;
891 register int little_endian
= target_byte_order
== 1234;
894 int tick_start
= get_now ();
896 extern unsigned char sh_jump_table0
[];
898 register unsigned char *jump_table
= sh_jump_table0
;
900 register int *R
= &(saved_state
.asregs
.regs
[0]);
904 register int maskb
= ((saved_state
.asregs
.msize
- 1) & ~0);
905 register int maskw
= ((saved_state
.asregs
.msize
- 1) & ~1);
906 register int maskl
= ((saved_state
.asregs
.msize
- 1) & ~3);
907 register unsigned char *memory
;
908 register unsigned int sbit
= (1 << 31);
910 prev
= signal (SIGINT
, control_c
);
914 memory
= saved_state
.asregs
.memory
;
918 saved_state
.asregs
.exception
= SIGTRAP
;
922 saved_state
.asregs
.exception
= 0;
925 pc
= saved_state
.asregs
.pc
;
926 PR
= saved_state
.asregs
.pr
;
927 T
= saved_state
.asregs
.sr
.bits
.t
;
928 prevlock
= saved_state
.asregs
.prevlock
;
929 thislock
= saved_state
.asregs
.thislock
;
930 doprofile
= saved_state
.asregs
.profile
;
932 /* If profiling not enabled, disable it by asking for
933 profiles infrequently. */
939 register unsigned int iword
= RUWAT (pc
);
940 register unsigned int ult
;
953 if (pollcount
> 1000)
959 saved_state
.asregs
.exception
= SIGINT
;
970 if (cycles
>= doprofile
)
973 saved_state
.asregs
.cycles
+= doprofile
;
975 if (saved_state
.asregs
.profile_hist
)
977 int n
= pc
>> PROFILE_SHIFT
;
980 int i
= saved_state
.asregs
.profile_hist
[n
];
982 saved_state
.asregs
.profile_hist
[n
] = i
+ 1;
989 while (!saved_state
.asregs
.exception
);
991 if (saved_state
.asregs
.exception
== SIGILL
992 || saved_state
.asregs
.exception
== SIGBUS
993 || (saved_state
.asregs
.exception
== SIGTRAP
&& !step
))
998 saved_state
.asregs
.ticks
+= get_now () - tick_start
;
999 saved_state
.asregs
.cycles
+= cycles
;
1000 saved_state
.asregs
.stalls
+= stalls
;
1001 saved_state
.asregs
.insts
+= insts
;
1002 saved_state
.asregs
.pc
= pc
;
1003 saved_state
.asregs
.sr
.bits
.t
= T
;
1004 saved_state
.asregs
.pr
= PR
;
1006 saved_state
.asregs
.prevlock
= prevlock
;
1007 saved_state
.asregs
.thislock
= thislock
;
1015 signal (SIGINT
, prev
);
1022 sim_write (addr
, buffer
, size
)
1024 unsigned char *buffer
;
1030 for (i
= 0; i
< size
; i
++)
1032 saved_state
.asregs
.memory
[MMASKB
& (addr
+ i
)] = buffer
[i
];
1038 sim_read (addr
, buffer
, size
)
1040 unsigned char *buffer
;
1047 for (i
= 0; i
< size
; i
++)
1049 buffer
[i
] = saved_state
.asregs
.memory
[MMASKB
& (addr
+ i
)];
1056 sim_store_register (rn
, memory
)
1058 unsigned char *memory
;
1061 saved_state
.asregs
.regs
[rn
]=RLAT(0);
1065 sim_fetch_register (rn
, memory
)
1067 unsigned char *memory
;
1070 WLAT (0, saved_state
.asregs
.regs
[rn
]);
1081 sim_stop_reason (reason
, sigrc
)
1082 enum sim_stop
*reason
;
1085 *reason
= sim_stopped
;
1086 *sigrc
= saved_state
.asregs
.exception
;
1094 double timetaken
= (double) saved_state
.asregs
.ticks
/ (double) now_persec ();
1095 double virttime
= saved_state
.asregs
.cycles
/ 36.0e6
;
1097 printf_filtered ("\n\n# instructions executed %10d\n", saved_state
.asregs
.insts
);
1098 printf_filtered ("# cycles %10d\n", saved_state
.asregs
.cycles
);
1099 printf_filtered ("# pipeline stalls %10d\n", saved_state
.asregs
.stalls
);
1100 printf_filtered ("# real time taken %10.4f\n", timetaken
);
1101 printf_filtered ("# virtual time taken %10.4f\n", virttime
);
1102 printf_filtered ("# profiling size %10d\n", sim_profile_size
);
1103 printf_filtered ("# profiling frequency %10d\n", saved_state
.asregs
.profile
);
1104 printf_filtered ("# profile maxpc %10x\n", (1 << sim_profile_size
) << PROFILE_SHIFT
);
1108 printf_filtered ("# cycles/second %10d\n", (int) (saved_state
.asregs
.cycles
/ timetaken
));
1109 printf_filtered ("# simulation ratio %10.4f\n", virttime
/ timetaken
);
1118 saved_state
.asregs
.profile
= n
;
1122 sim_set_profile_size (n
)
1125 sim_profile_size
= n
;
1137 sim_close (quitting
)
1144 sim_load (prog
, from_tty
)
1148 /* Return nonzero so GDB will handle it. */
1153 sim_create_inferior (start_address
, argv
, env
)
1154 SIM_ADDR start_address
;
1158 saved_state
.asregs
.pc
= start_address
;