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"
26 /* This file is local - if newlib changes, then so should this. */
29 /* start-sanitize-sh3e */
31 /* end-sanitize-sh3e */
34 #define SIGBUS SIGSEGV
38 #define SIGQUIT SIGTERM
41 #define O_RECOMPILE 85
43 #define DISASSEMBLER_TABLE
47 #define SBIT(x) ((x)&sbit)
48 #define R0 saved_state.asregs.regs[0]
49 #define Rn saved_state.asregs.regs[n]
50 #define Rm saved_state.asregs.regs[m]
51 #define UR0 (unsigned int)(saved_state.asregs.regs[0])
52 #define UR (unsigned int)R
53 #define UR (unsigned int)R
54 #define SR0 saved_state.asregs.regs[0]
55 #define GBR saved_state.asregs.gbr
56 #define VBR saved_state.asregs.vbr
57 #define MACH saved_state.asregs.mach
58 #define MACL saved_state.asregs.macl
59 #define M saved_state.asregs.sr.bits.m
60 #define Q saved_state.asregs.sr.bits.q
61 #define S saved_state.asregs.sr.bits.s
62 /* start-sanitize-sh3e */
63 #define FPSCR saved_state.asregs.fpscr
64 #define FPUL saved_state.asregs.fpul
65 /* end-sanitize-sh3e */
67 #define GET_SR() (saved_state.asregs.sr.bits.t = T, saved_state.asregs.sr.word)
68 #define SET_SR(x) {saved_state.asregs.sr.word = (x); T =saved_state.asregs.sr.bits.t;}
79 #define BUSERROR(addr, mask) \
80 if (addr & ~mask) { saved_state.asregs.exception = SIGBUS;}
82 /* Define this to enable register lifetime checking.
83 The compiler generates "add #0,rn" insns to mark registers as invalid,
84 the simulator uses this info to call fail if it finds a ref to an invalid
92 #define CREF(x) if(!valid[x]) fail();
93 #define CDEF(x) valid[x] = 1;
94 #define UNDEF(x) valid[x] = 0;
101 static void parse_and_set_memory_size
PARAMS ((char *str
));
103 static int IOMEM
PARAMS ((int addr
, int write
, int value
));
105 /* These variables are at file scope so that functions other than
106 sim_resume can use the fetch/store macros */
108 static int little_endian
;
111 static int maskl
= ~0;
112 static int maskw
= ~0;
153 /* start-sanitize-sh3e */
157 /* end-sanitize-sh3e */
160 #define PROFILE_FREQ 1
161 #define PROFILE_SHIFT 2
163 unsigned short *profile_hist
;
164 unsigned char *memory
;
169 saved_state_type saved_state
;
172 wlat_little (memory
, x
, value
, maskl
)
173 unsigned char *memory
;
176 unsigned char *p
= memory
+ ((x
) & maskl
);
185 wwat_little (memory
, x
, value
, maskw
)
186 unsigned char *memory
;
189 unsigned char *p
= memory
+ ((x
) & maskw
);
198 wbat_any (memory
, x
, value
, maskb
)
199 unsigned char *memory
;
201 unsigned char *p
= memory
+ (x
& maskb
);
212 wlat_big (memory
, x
, value
, maskl
)
213 unsigned char *memory
;
216 unsigned char *p
= memory
+ ((x
) & maskl
);
226 wwat_big (memory
, x
, value
, maskw
)
227 unsigned char *memory
;
230 unsigned char *p
= memory
+ ((x
) & maskw
);
239 wbat_big (memory
, x
, value
, maskb
)
240 unsigned char *memory
;
242 unsigned char *p
= memory
+ (x
& maskb
);
254 rlat_little (memory
, x
, maskl
)
255 unsigned char *memory
;
257 unsigned char *p
= memory
+ ((x
) & maskl
);
260 return (p
[3] << 24) | (p
[2] << 16) | (p
[1] << 8) | p
[0];
265 rwat_little (memory
, x
, maskw
)
266 unsigned char *memory
;
268 unsigned char *p
= memory
+ ((x
) & maskw
);
271 return (p
[1] << 8) | p
[0];
275 rbat_any (memory
, x
, maskb
)
276 unsigned char *memory
;
278 unsigned char *p
= memory
+ ((x
) & maskb
);
285 rlat_big (memory
, x
, maskl
)
286 unsigned char *memory
;
288 unsigned char *p
= memory
+ ((x
) & maskl
);
291 return (p
[0] << 24) | (p
[1] << 16) | (p
[2] << 8) | p
[3];
296 rwat_big (memory
, x
, maskw
)
297 unsigned char *memory
;
299 unsigned char *p
= memory
+ ((x
) & maskw
);
302 return (p
[0] << 8) | p
[1];
306 #define RWAT(x) (little_endian ? rwat_little(memory, x, maskw): rwat_big(memory, x, maskw))
307 #define RLAT(x) (little_endian ? rlat_little(memory, x, maskl): rlat_big(memory, x, maskl))
308 #define RBAT(x) (rbat_any (memory, x, maskb))
309 #define WWAT(x,v) (little_endian ? wwat_little(memory, x, v, maskw): wwat_big(memory, x, v, maskw))
310 #define WLAT(x,v) (little_endian ? wlat_little(memory, x, v, maskl): wlat_big(memory, x, v, maskl))
311 #define WBAT(x,v) (wbat_any (memory, x, v, maskb))
313 #define RUWAT(x) (RWAT(x) & 0xffff)
314 #define RSWAT(x) ((short)(RWAT(x)))
315 #define RSBAT(x) (SEXT(RBAT(x)))
317 #define SEXT(x) (((x&0xff) ^ (~0x7f))+0x80)
318 #define SEXTW(y) ((int)((short)y))
320 #define SL(TEMPPC) iword= RUWAT(TEMPPC); goto top;
325 #define L(x) thislock = x;
326 #define TL(x) if ((x) == prevlock) stalls++;
327 #define TB(x,y) if ((x) == prevlock || (y)==prevlock) stalls++;
329 #if defined(__GO32__) || defined(WIN32)
330 int sim_memory_size
= 19;
332 int sim_memory_size
= 24;
335 static int sim_profile_size
= 17;
341 #define SMR1 (0x05FFFEC8) /* Channel 1 serial mode register */
342 #define BRR1 (0x05FFFEC9) /* Channel 1 bit rate register */
343 #define SCR1 (0x05FFFECA) /* Channel 1 serial control register */
344 #define TDR1 (0x05FFFECB) /* Channel 1 transmit data register */
345 #define SSR1 (0x05FFFECC) /* Channel 1 serial status register */
346 #define RDR1 (0x05FFFECD) /* Channel 1 receive data register */
348 #define SCI_RDRF 0x40 /* Recieve data register full */
349 #define SCI_TDRE 0x80 /* Transmit data register empty */
352 IOMEM (addr
, write
, value
)
360 static char lastchar
;
390 return time ((long *) 0);
401 static FILE *profile_file
;
405 unsigned char *memory
;
412 unsigned char *memory
;
426 fwrite (b
, 4, 1, profile_file
);
436 fwrite (b
, 2, 1, profile_file
);
440 /* Turn a pointer in a register into a pointer into real memory. */
446 return (char *) (x
+ saved_state
.asregs
.memory
);
450 /* Simulate a monitor trap, put the result into r0 and errno into r1 */
452 trap (i
, regs
, memory
, maskl
, maskw
, little_endian
)
455 unsigned char *memory
;
460 printf ("%c", regs
[0]);
463 saved_state
.asregs
.exception
= SIGQUIT
;
465 case 3: /* FIXME: for backwards compat, should be removed */
475 #if !defined(__GO32__) && !defined(WIN32)
480 regs
[0] = execve (ptr (regs
[5]), ptr (regs
[6]), ptr (regs
[7]));
483 regs
[0] = execve (ptr (regs
[5]), ptr (regs
[6]), 0);
492 regs
[0] = pipe (host_fd
);
494 WLAT (buf
, host_fd
[0]);
496 WLAT (buf
, host_fd
[1]);
501 regs
[0] = wait (ptr (regs
[5]));
506 regs
[0] = read (regs
[5], ptr (regs
[6]), regs
[7]);
509 regs
[0] = write (regs
[5], ptr (regs
[6]), regs
[7]);
512 regs
[0] = lseek (regs
[5], regs
[6], regs
[7]);
515 regs
[0] = close (regs
[5]);
518 regs
[0] = open (ptr (regs
[5]), regs
[6]);
521 /* EXIT - caller can look in r5 to work out the
523 saved_state
.asregs
.exception
= SIGQUIT
;
526 case SYS_stat
: /* added at hmsi */
527 /* stat system call */
529 struct stat host_stat
;
532 regs
[0] = stat (ptr (regs
[5]), &host_stat
);
536 WWAT (buf
, host_stat
.st_dev
);
538 WWAT (buf
, host_stat
.st_ino
);
540 WLAT (buf
, host_stat
.st_mode
);
542 WWAT (buf
, host_stat
.st_nlink
);
544 WWAT (buf
, host_stat
.st_uid
);
546 WWAT (buf
, host_stat
.st_gid
);
548 WWAT (buf
, host_stat
.st_rdev
);
550 WLAT (buf
, host_stat
.st_size
);
552 WLAT (buf
, host_stat
.st_atime
);
556 WLAT (buf
, host_stat
.st_mtime
);
560 WLAT (buf
, host_stat
.st_ctime
);
572 regs
[0] = chown (ptr (regs
[5]), regs
[6], regs
[7]);
575 regs
[0] = chmod (ptr (regs
[5]), regs
[6]);
578 regs
[0] = utime (ptr (regs
[5]), ptr (regs
[6]));
590 saved_state
.asregs
.exception
= SIGTRAP
;
596 control_c (sig
, code
, scp
, addr
)
602 saved_state
.asregs
.exception
= SIGINT
;
607 div1 (R
, iRn2
, iRn1
, T
)
614 unsigned char old_q
, tmp1
;
617 Q
= (unsigned char) ((0x80000000 & R
[iRn1
]) != 0);
619 R
[iRn1
] |= (unsigned long) T
;
629 tmp1
= (R
[iRn1
] > tmp0
);
636 Q
= (unsigned char) (tmp1
== 0);
643 tmp1
= (R
[iRn1
] < tmp0
);
647 Q
= (unsigned char) (tmp1
== 0);
662 tmp1
= (R
[iRn1
] < tmp0
);
669 Q
= (unsigned char) (tmp1
== 0);
676 tmp1
= (R
[iRn1
] > tmp0
);
680 Q
= (unsigned char) (tmp1
== 0);
701 unsigned long RnL
, RnH
;
702 unsigned long RmL
, RmH
;
703 unsigned long temp0
, temp1
, temp2
, temp3
;
704 unsigned long Res2
, Res1
, Res0
;
707 RnH
= (rn
>> 16) & 0xffff;
709 RmH
= (rm
>> 16) & 0xffff;
715 Res1
= temp1
+ temp2
;
718 temp1
= (Res1
<< 16) & 0xffff0000;
719 Res0
= temp0
+ temp1
;
722 Res2
+= ((Res1
>> 16) & 0xffff) + temp3
;
737 macw (regs
, memory
, n
, m
)
739 unsigned char *memory
;
743 long prod
, macl
, sum
;
745 tempm
=RSWAT(regs
[m
]); regs
[m
]+=2;
746 tempn
=RSWAT(regs
[n
]); regs
[n
]+=2;
749 prod
= (long)(short) tempm
* (long)(short) tempn
;
753 if ((~(prod
^ macl
) & (sum
^ prod
)) < 0)
755 /* MACH's lsb is a sticky overflow bit. */
757 /* Store the smallest negative number in MACL if prod is
758 negative, and the largest positive number otherwise. */
759 sum
= 0x7fffffff + (prod
< 0);
765 /* Add to MACH the sign extended product, and carry from low sum. */
766 mach
= MACH
+ (-(prod
< 0)) + ((unsigned long) sum
< prod
);
767 /* Sign extend at 10:th bit in MACH. */
768 MACH
= (mach
& 0x1ff) | -(mach
& 0x200);
773 /* Set the memory size to the power of two provided. */
780 saved_state
.asregs
.msize
= 1 << power
;
782 sim_memory_size
= power
;
785 if (saved_state
.asregs
.memory
)
787 free (saved_state
.asregs
.memory
);
790 saved_state
.asregs
.memory
=
791 (unsigned char *) calloc (64, saved_state
.asregs
.msize
/ 64);
793 if (!saved_state
.asregs
.memory
)
796 "Not enough VM for simulation of %d bytes of RAM\n",
797 saved_state
.asregs
.msize
);
799 saved_state
.asregs
.msize
= 1;
800 saved_state
.asregs
.memory
= (unsigned char *) calloc (1, 1);
805 int target_byte_order
;
808 set_static_little_endian(x
)
818 register int little_endian
= target_byte_order
== 1234;
819 set_static_little_endian (little_endian
);
820 if (saved_state
.asregs
.msize
!= 1 << sim_memory_size
)
822 sim_size (sim_memory_size
);
825 if (saved_state
.asregs
.profile
&& !profile_file
)
827 profile_file
= fopen ("gmon.out", "wb");
828 /* Seek to where to put the call arc data */
829 nsamples
= (1 << sim_profile_size
);
831 fseek (profile_file
, nsamples
* 2 + 12, 0);
835 fprintf (stderr
, "Can't open gmon.out\n");
839 saved_state
.asregs
.profile_hist
=
840 (unsigned short *) calloc (64, (nsamples
* sizeof (short) / 64));
854 unsigned short *first
;
857 p
= saved_state
.asregs
.profile_hist
;
859 maxpc
= (1 << sim_profile_size
);
861 fseek (profile_file
, 0L, 0);
862 swapout (minpc
<< PROFILE_SHIFT
);
863 swapout (maxpc
<< PROFILE_SHIFT
);
864 swapout (nsamples
* 2 + 12);
865 for (i
= 0; i
< nsamples
; i
++)
866 swapout16 (saved_state
.asregs
.profile_hist
[i
]);
880 #define MMASKB ((saved_state.asregs.msize -1) & ~0)
884 sim_resume (step
, siggnal
)
887 register unsigned int pc
;
888 register int cycles
= 0;
889 register int stalls
= 0;
890 register int insts
= 0;
891 register int prevlock
;
892 register int thislock
;
893 register unsigned int doprofile
;
894 #if defined(__GO32__) || defined(WIN32)
895 register int pollcount
= 0;
897 register int little_endian
= target_byte_order
== 1234;
900 int tick_start
= get_now ();
902 extern unsigned char sh_jump_table0
[];
904 register unsigned char *jump_table
= sh_jump_table0
;
906 register int *R
= &(saved_state
.asregs
.regs
[0]);
907 /* start-sanitize-sh3e */
908 register float *F
= &(saved_state
.asregs
.fregs
[0]);
909 /* end-sanitize-sh3e */
913 register int maskb
= ((saved_state
.asregs
.msize
- 1) & ~0);
914 register int maskw
= ((saved_state
.asregs
.msize
- 1) & ~1);
915 register int maskl
= ((saved_state
.asregs
.msize
- 1) & ~3);
916 register unsigned char *memory
;
917 register unsigned int sbit
= ((unsigned int) 1 << 31);
919 prev
= signal (SIGINT
, control_c
);
923 memory
= saved_state
.asregs
.memory
;
927 saved_state
.asregs
.exception
= SIGTRAP
;
931 saved_state
.asregs
.exception
= 0;
934 pc
= saved_state
.asregs
.pc
;
935 PR
= saved_state
.asregs
.pr
;
936 T
= saved_state
.asregs
.sr
.bits
.t
;
937 prevlock
= saved_state
.asregs
.prevlock
;
938 thislock
= saved_state
.asregs
.thislock
;
939 doprofile
= saved_state
.asregs
.profile
;
941 /* If profiling not enabled, disable it by asking for
942 profiles infrequently. */
948 register unsigned int iword
= RUWAT (pc
);
949 register unsigned int ult
;
962 if (pollcount
> 1000)
968 saved_state
.asregs
.exception
= SIGINT
;
975 if (pollcount
> 1000)
990 if (cycles
>= doprofile
)
993 saved_state
.asregs
.cycles
+= doprofile
;
995 if (saved_state
.asregs
.profile_hist
)
997 int n
= pc
>> PROFILE_SHIFT
;
1000 int i
= saved_state
.asregs
.profile_hist
[n
];
1002 saved_state
.asregs
.profile_hist
[n
] = i
+ 1;
1009 while (!saved_state
.asregs
.exception
);
1011 if (saved_state
.asregs
.exception
== SIGILL
1012 || saved_state
.asregs
.exception
== SIGBUS
)
1017 saved_state
.asregs
.ticks
+= get_now () - tick_start
;
1018 saved_state
.asregs
.cycles
+= cycles
;
1019 saved_state
.asregs
.stalls
+= stalls
;
1020 saved_state
.asregs
.insts
+= insts
;
1021 saved_state
.asregs
.pc
= pc
;
1022 saved_state
.asregs
.sr
.bits
.t
= T
;
1023 saved_state
.asregs
.pr
= PR
;
1025 saved_state
.asregs
.prevlock
= prevlock
;
1026 saved_state
.asregs
.thislock
= thislock
;
1034 signal (SIGINT
, prev
);
1041 sim_write (addr
, buffer
, size
)
1043 unsigned char *buffer
;
1049 for (i
= 0; i
< size
; i
++)
1051 saved_state
.asregs
.memory
[MMASKB
& (addr
+ i
)] = buffer
[i
];
1057 sim_read (addr
, buffer
, size
)
1059 unsigned char *buffer
;
1066 for (i
= 0; i
< size
; i
++)
1068 buffer
[i
] = saved_state
.asregs
.memory
[MMASKB
& (addr
+ i
)];
1075 sim_store_register (rn
, memory
)
1077 unsigned char *memory
;
1080 saved_state
.asregs
.regs
[rn
]=RLAT(0);
1084 sim_fetch_register (rn
, memory
)
1086 unsigned char *memory
;
1089 WLAT (0, saved_state
.asregs
.regs
[rn
]);
1100 sim_stop_reason (reason
, sigrc
)
1101 enum sim_stop
*reason
;
1104 *reason
= sim_stopped
;
1105 *sigrc
= saved_state
.asregs
.exception
;
1113 double timetaken
= (double) saved_state
.asregs
.ticks
/ (double) now_persec ();
1114 double virttime
= saved_state
.asregs
.cycles
/ 36.0e6
;
1116 printf_filtered ("\n\n# instructions executed %10d\n", saved_state
.asregs
.insts
);
1117 printf_filtered ("# cycles %10d\n", saved_state
.asregs
.cycles
);
1118 printf_filtered ("# pipeline stalls %10d\n", saved_state
.asregs
.stalls
);
1119 printf_filtered ("# real time taken %10.4f\n", timetaken
);
1120 printf_filtered ("# virtual time taken %10.4f\n", virttime
);
1121 printf_filtered ("# profiling size %10d\n", sim_profile_size
);
1122 printf_filtered ("# profiling frequency %10d\n", saved_state
.asregs
.profile
);
1123 printf_filtered ("# profile maxpc %10x\n", (1 << sim_profile_size
) << PROFILE_SHIFT
);
1127 printf_filtered ("# cycles/second %10d\n", (int) (saved_state
.asregs
.cycles
/ timetaken
));
1128 printf_filtered ("# simulation ratio %10.4f\n", virttime
/ timetaken
);
1137 saved_state
.asregs
.profile
= n
;
1141 sim_set_profile_size (n
)
1144 sim_profile_size
= n
;
1156 parse_and_set_memory_size (args
);
1161 parse_and_set_memory_size (str
)
1166 n
= strtol (str
, NULL
, 10);
1167 if (n
> 0 && n
<= 24)
1168 sim_memory_size
= n
;
1170 printf_filtered ("Bad memory size %d; must be 1 to 24, inclusive\n", n
);
1174 sim_close (quitting
)
1181 sim_load (prog
, from_tty
)
1185 /* Return nonzero so GDB will handle it. */
1190 sim_create_inferior (start_address
, argv
, env
)
1191 SIM_ADDR start_address
;
1195 saved_state
.asregs
.pc
= start_address
;
1205 sim_do_command (cmd
)
1209 char *sms_cmd
= "set-memory-size";
1211 if (strncmp (cmd
, sms_cmd
, strlen (sms_cmd
)) == 0
1212 && strchr (" ", cmd
[strlen(sms_cmd
)]))
1213 parse_and_set_memory_size (cmd
+ strlen(sms_cmd
) + 1);
1215 else if (strcmp (cmd
, "help") == 0)
1217 printf_filtered ("List of SH simulator commands:\n\n");
1218 printf_filtered ("set-memory-size <n> -- Set the number of address bits to use\n");
1219 printf_filtered ("\n");
1222 fprintf (stderr
, "Error: \"%s\" is not a valid SH simulator command.\n",