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.
25 #include "remote-sim.h"
28 /* This file is local - if newlib changes, then so should this. */
31 /* start-sanitize-sh3e */
33 /* end-sanitize-sh3e */
36 #define SIGBUS SIGSEGV
40 #define SIGQUIT SIGTERM
43 #define O_RECOMPILE 85
45 #define DISASSEMBLER_TABLE
49 #define SBIT(x) ((x)&sbit)
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
63 #define S saved_state.asregs.sr.bits.s
64 /* start-sanitize-sh3e */
65 #define FPSCR saved_state.asregs.fpscr
66 #define FPUL saved_state.asregs.fpul
67 /* end-sanitize-sh3e */
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;}
81 #define BUSERROR(addr, mask) \
82 if (addr & ~mask) { saved_state.asregs.exception = SIGBUS;}
84 /* Define this to enable register lifetime checking.
85 The compiler generates "add #0,rn" insns to mark registers as invalid,
86 the simulator uses this info to call fail if it finds a ref to an invalid
94 #define CREF(x) if(!valid[x]) fail();
95 #define CDEF(x) valid[x] = 1;
96 #define UNDEF(x) valid[x] = 0;
103 static void parse_and_set_memory_size
PARAMS ((char *str
));
105 static int IOMEM
PARAMS ((int addr
, int write
, int value
));
108 static host_callback
*callback
= &default_callback
;
109 /* These variables are at file scope so that functions other than
110 sim_resume can use the fetch/store macros */
112 static int little_endian
;
117 static int maskl
= ~0;
118 static int maskw
= ~0;
159 /* start-sanitize-sh3e */
163 /* end-sanitize-sh3e */
166 #define PROFILE_FREQ 1
167 #define PROFILE_SHIFT 2
169 unsigned short *profile_hist
;
170 unsigned char *memory
;
175 saved_state_type saved_state
;
178 wlat_little (memory
, x
, value
, maskl
)
179 unsigned char *memory
;
182 unsigned char *p
= memory
+ ((x
) & maskl
);
191 wwat_little (memory
, x
, value
, maskw
)
192 unsigned char *memory
;
195 unsigned char *p
= memory
+ ((x
) & maskw
);
204 wbat_any (memory
, x
, value
, maskb
)
205 unsigned char *memory
;
207 unsigned char *p
= memory
+ (x
& maskb
);
218 wlat_big (memory
, x
, value
, maskl
)
219 unsigned char *memory
;
222 unsigned char *p
= memory
+ ((x
) & maskl
);
232 wwat_big (memory
, x
, value
, maskw
)
233 unsigned char *memory
;
236 unsigned char *p
= memory
+ ((x
) & maskw
);
245 wbat_big (memory
, x
, value
, maskb
)
246 unsigned char *memory
;
248 unsigned char *p
= memory
+ (x
& maskb
);
260 rlat_little (memory
, x
, maskl
)
261 unsigned char *memory
;
263 unsigned char *p
= memory
+ ((x
) & maskl
);
266 return (p
[3] << 24) | (p
[2] << 16) | (p
[1] << 8) | p
[0];
271 rwat_little (memory
, x
, maskw
)
272 unsigned char *memory
;
274 unsigned char *p
= memory
+ ((x
) & maskw
);
277 return (p
[1] << 8) | p
[0];
281 rbat_any (memory
, x
, maskb
)
282 unsigned char *memory
;
284 unsigned char *p
= memory
+ ((x
) & maskb
);
291 rlat_big (memory
, x
, maskl
)
292 unsigned char *memory
;
294 unsigned char *p
= memory
+ ((x
) & maskl
);
297 return (p
[0] << 24) | (p
[1] << 16) | (p
[2] << 8) | p
[3];
302 rwat_big (memory
, x
, maskw
)
303 unsigned char *memory
;
305 unsigned char *p
= memory
+ ((x
) & maskw
);
308 return (p
[0] << 8) | p
[1];
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))
319 #define RUWAT(x) (RWAT(x) & 0xffff)
320 #define RSWAT(x) ((short)(RWAT(x)))
321 #define RSBAT(x) (SEXT(RBAT(x)))
323 #define SEXT(x) (((x&0xff) ^ (~0x7f))+0x80)
324 #define SEXTW(y) ((int)((short)y))
326 #define SL(TEMPPC) iword= RUWAT(TEMPPC); goto top;
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++;
335 #if defined(__GO32__) || defined(WIN32)
336 int sim_memory_size
= 19;
338 int sim_memory_size
= 24;
341 static int sim_profile_size
= 17;
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 */
354 #define SCI_RDRF 0x40 /* Recieve data register full */
355 #define SCI_TDRE 0x80 /* Transmit data register empty */
358 IOMEM (addr
, write
, value
)
366 static char lastchar
;
396 return time ((long *) 0);
407 static FILE *profile_file
;
411 unsigned char *memory
;
418 unsigned char *memory
;
432 fwrite (b
, 4, 1, profile_file
);
442 fwrite (b
, 2, 1, profile_file
);
446 /* Turn a pointer in a register into a pointer into real memory. */
452 return (char *) (x
+ saved_state
.asregs
.memory
);
456 /* Simulate a monitor trap, put the result into r0 and errno into r1 */
458 trap (i
, regs
, memory
, maskl
, maskw
, little_endian
)
461 unsigned char *memory
;
466 printf ("%c", regs
[0]);
469 saved_state
.asregs
.exception
= SIGQUIT
;
471 case 3: /* FIXME: for backwards compat, should be removed */
481 #if !defined(__GO32__) && !defined(WIN32)
486 regs
[0] = execve (ptr (regs
[5]), (char **)ptr (regs
[6]), (char **)ptr (regs
[7]));
489 regs
[0] = execve (ptr (regs
[5]),(char **) ptr (regs
[6]), 0);
498 regs
[0] = pipe (host_fd
);
500 WLAT (buf
, host_fd
[0]);
502 WLAT (buf
, host_fd
[1]);
507 regs
[0] = wait (ptr (regs
[5]));
512 regs
[0] = callback
->read (callback
, regs
[5], ptr (regs
[6]), regs
[7]);
516 regs
[0] = (int)callback
->write_stdout (callback
, ptr(regs
[6]), regs
[7]);
518 regs
[0] = (int)callback
->write (callback
, regs
[5], ptr (regs
[6]), regs
[7]);
521 regs
[0] = callback
->lseek (callback
,regs
[5], regs
[6], regs
[7]);
524 regs
[0] = callback
->close (callback
,regs
[5]);
527 regs
[0] = callback
->open (callback
,ptr (regs
[5]), regs
[6]);
530 /* EXIT - caller can look in r5 to work out the
532 saved_state
.asregs
.exception
= SIGQUIT
;
535 case SYS_stat
: /* added at hmsi */
536 /* stat system call */
538 struct stat host_stat
;
541 regs
[0] = stat (ptr (regs
[5]), &host_stat
);
545 WWAT (buf
, host_stat
.st_dev
);
547 WWAT (buf
, host_stat
.st_ino
);
549 WLAT (buf
, host_stat
.st_mode
);
551 WWAT (buf
, host_stat
.st_nlink
);
553 WWAT (buf
, host_stat
.st_uid
);
555 WWAT (buf
, host_stat
.st_gid
);
557 WWAT (buf
, host_stat
.st_rdev
);
559 WLAT (buf
, host_stat
.st_size
);
561 WLAT (buf
, host_stat
.st_atime
);
565 WLAT (buf
, host_stat
.st_mtime
);
569 WLAT (buf
, host_stat
.st_ctime
);
581 regs
[0] = chown (ptr (regs
[5]), regs
[6], regs
[7]);
584 regs
[0] = chmod (ptr (regs
[5]), regs
[6]);
587 regs
[0] = utime (ptr (regs
[5]), ptr (regs
[6]));
599 saved_state
.asregs
.exception
= SIGTRAP
;
605 control_c (sig
, code
, scp
, addr
)
611 saved_state
.asregs
.exception
= SIGINT
;
616 div1 (R
, iRn2
, iRn1
, T
)
623 unsigned char old_q
, tmp1
;
626 Q
= (unsigned char) ((0x80000000 & R
[iRn1
]) != 0);
628 R
[iRn1
] |= (unsigned long) T
;
638 tmp1
= (R
[iRn1
] > tmp0
);
645 Q
= (unsigned char) (tmp1
== 0);
652 tmp1
= (R
[iRn1
] < tmp0
);
656 Q
= (unsigned char) (tmp1
== 0);
671 tmp1
= (R
[iRn1
] < tmp0
);
678 Q
= (unsigned char) (tmp1
== 0);
685 tmp1
= (R
[iRn1
] > tmp0
);
689 Q
= (unsigned char) (tmp1
== 0);
710 unsigned long RnL
, RnH
;
711 unsigned long RmL
, RmH
;
712 unsigned long temp0
, temp1
, temp2
, temp3
;
713 unsigned long Res2
, Res1
, Res0
;
716 RnH
= (rn
>> 16) & 0xffff;
718 RmH
= (rm
>> 16) & 0xffff;
724 Res1
= temp1
+ temp2
;
727 temp1
= (Res1
<< 16) & 0xffff0000;
728 Res0
= temp0
+ temp1
;
731 Res2
+= ((Res1
>> 16) & 0xffff) + temp3
;
746 macw (regs
, memory
, n
, m
)
748 unsigned char *memory
;
752 long prod
, macl
, sum
;
754 tempm
=RSWAT(regs
[m
]); regs
[m
]+=2;
755 tempn
=RSWAT(regs
[n
]); regs
[n
]+=2;
758 prod
= (long)(short) tempm
* (long)(short) tempn
;
762 if ((~(prod
^ macl
) & (sum
^ prod
)) < 0)
764 /* MACH's lsb is a sticky overflow bit. */
766 /* Store the smallest negative number in MACL if prod is
767 negative, and the largest positive number otherwise. */
768 sum
= 0x7fffffff + (prod
< 0);
774 /* Add to MACH the sign extended product, and carry from low sum. */
775 mach
= MACH
+ (-(prod
< 0)) + ((unsigned long) sum
< prod
);
776 /* Sign extend at 10:th bit in MACH. */
777 MACH
= (mach
& 0x1ff) | -(mach
& 0x200);
782 /* Set the memory size to the power of two provided. */
789 saved_state
.asregs
.msize
= 1 << power
;
791 sim_memory_size
= power
;
794 if (saved_state
.asregs
.memory
)
796 free (saved_state
.asregs
.memory
);
799 saved_state
.asregs
.memory
=
800 (unsigned char *) calloc (64, saved_state
.asregs
.msize
/ 64);
802 if (!saved_state
.asregs
.memory
)
805 "Not enough VM for simulation of %d bytes of RAM\n",
806 saved_state
.asregs
.msize
);
808 saved_state
.asregs
.msize
= 1;
809 saved_state
.asregs
.memory
= (unsigned char *) calloc (1, 1);
814 int target_byte_order
;
817 set_static_little_endian(x
)
827 register int little_endian
= target_byte_order
== 1234;
828 set_static_little_endian (little_endian
);
829 if (saved_state
.asregs
.msize
!= 1 << sim_memory_size
)
831 sim_size (sim_memory_size
);
834 if (saved_state
.asregs
.profile
&& !profile_file
)
836 profile_file
= fopen ("gmon.out", "wb");
837 /* Seek to where to put the call arc data */
838 nsamples
= (1 << sim_profile_size
);
840 fseek (profile_file
, nsamples
* 2 + 12, 0);
844 fprintf (stderr
, "Can't open gmon.out\n");
848 saved_state
.asregs
.profile_hist
=
849 (unsigned short *) calloc (64, (nsamples
* sizeof (short) / 64));
863 unsigned short *first
;
866 p
= saved_state
.asregs
.profile_hist
;
868 maxpc
= (1 << sim_profile_size
);
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
]);
889 #define MMASKB ((saved_state.asregs.msize -1) & ~0)
893 sim_resume (step
, siggnal
)
896 register unsigned int pc
;
897 register int cycles
= 0;
898 register int stalls
= 0;
899 register int insts
= 0;
900 register int prevlock
;
901 register int thislock
;
902 register unsigned int doprofile
;
903 #if defined(__GO32__) || defined(WIN32)
904 register int pollcount
= 0;
906 register int little_endian
= target_byte_order
== 1234;
909 int tick_start
= get_now ();
911 extern unsigned char sh_jump_table0
[];
913 register unsigned char *jump_table
= sh_jump_table0
;
915 register int *R
= &(saved_state
.asregs
.regs
[0]);
916 /* start-sanitize-sh3e */
917 register float *F
= &(saved_state
.asregs
.fregs
[0]);
918 /* end-sanitize-sh3e */
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
= ((unsigned int) 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 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
);
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
);
1151 saved_state
.asregs
.profile
= n
;
1155 sim_set_profile_size (n
)
1158 sim_profile_size
= n
;
1170 parse_and_set_memory_size (args
);
1175 parse_and_set_memory_size (str
)
1180 n
= strtol (str
, NULL
, 10);
1181 if (n
> 0 && n
<= 24)
1182 sim_memory_size
= n
;
1184 callback
->printf_filtered (callback
, "Bad memory size %d; must be 1 to 24, inclusive\n", n
);
1188 sim_close (quitting
)
1195 sim_load (prog
, from_tty
)
1199 /* Return nonzero so GDB will handle it. */
1204 sim_create_inferior (start_address
, argv
, env
)
1205 SIM_ADDR start_address
;
1209 saved_state
.asregs
.pc
= start_address
;
1219 sim_do_command (cmd
)
1223 char *sms_cmd
= "set-memory-size";
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);
1229 else if (strcmp (cmd
, "help") == 0)
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");
1236 fprintf (stderr
, "Error: \"%s\" is not a valid SH simulator command.\n",
1244 return saved_state
.asregs
.regs
[5];
1250 sim_set_callbacks(p
)