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.
31 #include "remote-sim.h"
33 /* This file is local - if newlib changes, then so should this. */
39 #define SIGBUS SIGSEGV
43 #define SIGQUIT SIGTERM
46 #define O_RECOMPILE 85
48 #define DISASSEMBLER_TABLE
50 #define SBIT(x) ((x)&sbit)
51 #define R0 saved_state.asregs.regs[0]
52 #define Rn saved_state.asregs.regs[n]
53 #define Rm saved_state.asregs.regs[m]
54 #define UR0 (unsigned int)(saved_state.asregs.regs[0])
55 #define UR (unsigned int)R
56 #define UR (unsigned int)R
57 #define SR0 saved_state.asregs.regs[0]
58 #define GBR saved_state.asregs.gbr
59 #define VBR saved_state.asregs.vbr
60 #define SSR saved_state.asregs.ssr
61 #define SPC saved_state.asregs.spc
62 #define MACH saved_state.asregs.mach
63 #define MACL saved_state.asregs.macl
64 #define M saved_state.asregs.sr.bits.m
65 #define Q saved_state.asregs.sr.bits.q
66 #define S saved_state.asregs.sr.bits.s
67 #define FPSCR saved_state.asregs.fpscr
68 #define FPUL saved_state.asregs.fpul
70 #define GET_SR() (saved_state.asregs.sr.bits.t = T, saved_state.asregs.sr.word)
71 #define SET_SR(x) {saved_state.asregs.sr.word = (x); T =saved_state.asregs.sr.bits.t;}
76 extern int target_byte_order
;
84 /* This function exists solely for the purpose of setting a breakpoint to
85 catch simulated bus errors when running the simulator under GDB. */
92 #define BUSERROR(addr, mask) \
93 if (addr & ~mask) { saved_state.asregs.exception = SIGBUS; bp_holder (); }
95 /* Define this to enable register lifetime checking.
96 The compiler generates "add #0,rn" insns to mark registers as invalid,
97 the simulator uses this info to call fail if it finds a ref to an invalid
105 #define CREF(x) if(!valid[x]) fail();
106 #define CDEF(x) valid[x] = 1;
107 #define UNDEF(x) valid[x] = 0;
114 static void parse_and_set_memory_size
PARAMS ((char *str
));
116 static int IOMEM
PARAMS ((int addr
, int write
, int value
));
118 static host_callback
*callback
;
120 /* These variables are at file scope so that functions other than
121 sim_resume can use the fetch/store macros */
123 static int little_endian
;
126 static int maskl
= ~0;
127 static int maskw
= ~0;
179 #define PROFILE_FREQ 1
180 #define PROFILE_SHIFT 2
182 unsigned short *profile_hist
;
183 unsigned char *memory
;
189 saved_state_type saved_state
;
192 wlat_little (memory
, x
, value
, maskl
)
193 unsigned char *memory
;
196 unsigned char *p
= memory
+ ((x
) & maskl
);
205 wwat_little (memory
, x
, value
, maskw
)
206 unsigned char *memory
;
209 unsigned char *p
= memory
+ ((x
) & maskw
);
217 wbat_any (memory
, x
, value
, maskb
)
218 unsigned char *memory
;
220 unsigned char *p
= memory
+ (x
& maskb
);
229 wlat_big (memory
, x
, value
, maskl
)
230 unsigned char *memory
;
233 unsigned char *p
= memory
+ ((x
) & maskl
);
243 wwat_big (memory
, x
, value
, maskw
)
244 unsigned char *memory
;
247 unsigned char *p
= memory
+ ((x
) & maskw
);
255 wbat_big (memory
, x
, value
, maskb
)
256 unsigned char *memory
;
258 unsigned char *p
= memory
+ (x
& maskb
);
269 rlat_little (memory
, x
, maskl
)
270 unsigned char *memory
;
272 unsigned char *p
= memory
+ ((x
) & maskl
);
275 return (p
[3] << 24) | (p
[2] << 16) | (p
[1] << 8) | p
[0];
279 rwat_little (memory
, x
, maskw
)
280 unsigned char *memory
;
282 unsigned char *p
= memory
+ ((x
) & maskw
);
285 return (p
[1] << 8) | p
[0];
289 rbat_any (memory
, x
, maskb
)
290 unsigned char *memory
;
292 unsigned char *p
= memory
+ ((x
) & maskb
);
299 rlat_big (memory
, x
, maskl
)
300 unsigned char *memory
;
302 unsigned char *p
= memory
+ ((x
) & maskl
);
305 return (p
[0] << 24) | (p
[1] << 16) | (p
[2] << 8) | p
[3];
309 rwat_big (memory
, x
, maskw
)
310 unsigned char *memory
;
312 unsigned char *p
= memory
+ ((x
) & maskw
);
315 return (p
[0] << 8) | p
[1];
318 #define RWAT(x) (little_endian ? rwat_little(memory, x, maskw): rwat_big(memory, x, maskw))
319 #define RLAT(x) (little_endian ? rlat_little(memory, x, maskl): rlat_big(memory, x, maskl))
320 #define RBAT(x) (rbat_any (memory, x, maskb))
321 #define WWAT(x,v) (little_endian ? wwat_little(memory, x, v, maskw): wwat_big(memory, x, v, maskw))
322 #define WLAT(x,v) (little_endian ? wlat_little(memory, x, v, maskl): wlat_big(memory, x, v, maskl))
323 #define WBAT(x,v) (wbat_any (memory, x, v, maskb))
325 #define RUWAT(x) (RWAT(x) & 0xffff)
326 #define RSWAT(x) ((short)(RWAT(x)))
327 #define RSBAT(x) (SEXT(RBAT(x)))
329 #define MA() ((pc & 3) != 0 ? ++memstalls : 0)
331 #define SEXT(x) (((x&0xff) ^ (~0x7f))+0x80)
332 #define SEXTW(y) ((int)((short)y))
334 #define SL(TEMPPC) iword= RUWAT(TEMPPC); goto top;
338 #define L(x) thislock = x;
339 #define TL(x) if ((x) == prevlock) stalls++;
340 #define TB(x,y) if ((x) == prevlock || (y)==prevlock) stalls++;
342 #if defined(__GO32__) || defined(WIN32)
343 int sim_memory_size
= 19;
345 int sim_memory_size
= 24;
348 static int sim_profile_size
= 17;
354 #define SMR1 (0x05FFFEC8) /* Channel 1 serial mode register */
355 #define BRR1 (0x05FFFEC9) /* Channel 1 bit rate register */
356 #define SCR1 (0x05FFFECA) /* Channel 1 serial control register */
357 #define TDR1 (0x05FFFECB) /* Channel 1 transmit data register */
358 #define SSR1 (0x05FFFECC) /* Channel 1 serial status register */
359 #define RDR1 (0x05FFFECD) /* Channel 1 receive data register */
361 #define SCI_RDRF 0x40 /* Recieve data register full */
362 #define SCI_TDRE 0x80 /* Transmit data register empty */
365 IOMEM (addr
, write
, value
)
397 return time ((long *) 0);
406 static FILE *profile_file
;
410 unsigned char *memory
;
418 unsigned char *memory
;
432 fwrite (b
, 4, 1, profile_file
);
442 fwrite (b
, 2, 1, profile_file
);
445 /* Turn a pointer in a register into a pointer into real memory. */
451 return (char *) (x
+ saved_state
.asregs
.memory
);
454 /* Simulate a monitor trap, put the result into r0 and errno into r1 */
457 trap (i
, regs
, memory
, maskl
, maskw
, little_endian
)
460 unsigned char *memory
;
465 printf ("%c", regs
[0]);
468 saved_state
.asregs
.exception
= SIGQUIT
;
470 case 3: /* FIXME: for backwards compat, should be removed */
480 #if !defined(__GO32__) && !defined(WIN32)
485 regs
[0] = execve (ptr (regs
[5]), (char **)ptr (regs
[6]), (char **)ptr (regs
[7]));
488 regs
[0] = execve (ptr (regs
[5]),(char **) ptr (regs
[6]), 0);
497 regs
[0] = pipe (host_fd
);
499 WLAT (buf
, host_fd
[0]);
501 WLAT (buf
, host_fd
[1]);
506 regs
[0] = wait (ptr (regs
[5]));
511 regs
[0] = callback
->read (callback
, regs
[5], ptr (regs
[6]), regs
[7]);
515 regs
[0] = (int)callback
->write_stdout (callback
, ptr(regs
[6]), regs
[7]);
517 regs
[0] = (int)callback
->write (callback
, regs
[5], ptr (regs
[6]), regs
[7]);
520 regs
[0] = callback
->lseek (callback
,regs
[5], regs
[6], regs
[7]);
523 regs
[0] = callback
->close (callback
,regs
[5]);
526 regs
[0] = callback
->open (callback
,ptr (regs
[5]), regs
[6]);
529 /* EXIT - caller can look in r5 to work out the reason */
530 saved_state
.asregs
.exception
= SIGQUIT
;
534 case SYS_stat
: /* added at hmsi */
535 /* stat system call */
537 struct stat host_stat
;
540 regs
[0] = stat (ptr (regs
[5]), &host_stat
);
544 WWAT (buf
, host_stat
.st_dev
);
546 WWAT (buf
, host_stat
.st_ino
);
548 WLAT (buf
, host_stat
.st_mode
);
550 WWAT (buf
, host_stat
.st_nlink
);
552 WWAT (buf
, host_stat
.st_uid
);
554 WWAT (buf
, host_stat
.st_gid
);
556 WWAT (buf
, host_stat
.st_rdev
);
558 WLAT (buf
, host_stat
.st_size
);
560 WLAT (buf
, host_stat
.st_atime
);
564 WLAT (buf
, host_stat
.st_mtime
);
568 WLAT (buf
, host_stat
.st_ctime
);
580 regs
[0] = chown (ptr (regs
[5]), regs
[6], regs
[7]);
583 regs
[0] = chmod (ptr (regs
[5]), regs
[6]);
586 /* Cast the second argument to void *, to avoid type mismatch
587 if a prototype is present. */
588 regs
[0] = utime (ptr (regs
[5]), (void *) ptr (regs
[6]));
593 regs
[1] = callback
->get_errno (callback
);
600 saved_state
.asregs
.exception
= SIGTRAP
;
607 control_c (sig
, code
, scp
, addr
)
613 saved_state
.asregs
.exception
= SIGINT
;
617 div1 (R
, iRn2
, iRn1
, T
)
624 unsigned char old_q
, tmp1
;
627 Q
= (unsigned char) ((0x80000000 & R
[iRn1
]) != 0);
629 R
[iRn1
] |= (unsigned long) T
;
639 tmp1
= (R
[iRn1
] > tmp0
);
646 Q
= (unsigned char) (tmp1
== 0);
653 tmp1
= (R
[iRn1
] < tmp0
);
657 Q
= (unsigned char) (tmp1
== 0);
672 tmp1
= (R
[iRn1
] < tmp0
);
679 Q
= (unsigned char) (tmp1
== 0);
686 tmp1
= (R
[iRn1
] > tmp0
);
690 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
;
793 if (saved_state
.asregs
.memory
)
795 free (saved_state
.asregs
.memory
);
798 saved_state
.asregs
.memory
=
799 (unsigned char *) calloc (64, saved_state
.asregs
.msize
/ 64);
801 if (!saved_state
.asregs
.memory
)
804 "Not enough VM for simulation of %d bytes of RAM\n",
805 saved_state
.asregs
.msize
);
807 saved_state
.asregs
.msize
= 1;
808 saved_state
.asregs
.memory
= (unsigned char *) calloc (1, 1);
813 set_static_little_endian (x
)
822 int little_endian
= (target_byte_order
== 1234);
824 set_static_little_endian (little_endian
);
826 if (saved_state
.asregs
.msize
!= 1 << sim_memory_size
)
828 sim_size (sim_memory_size
);
831 if (saved_state
.asregs
.profile
&& !profile_file
)
833 profile_file
= fopen ("gmon.out", "wb");
834 /* Seek to where to put the call arc data */
835 nsamples
= (1 << sim_profile_size
);
837 fseek (profile_file
, nsamples
* 2 + 12, 0);
841 fprintf (stderr
, "Can't open gmon.out\n");
845 saved_state
.asregs
.profile_hist
=
846 (unsigned short *) calloc (64, (nsamples
* sizeof (short) / 64));
859 p
= saved_state
.asregs
.profile_hist
;
861 maxpc
= (1 << sim_profile_size
);
863 fseek (profile_file
, 0L, 0);
864 swapout (minpc
<< PROFILE_SHIFT
);
865 swapout (maxpc
<< PROFILE_SHIFT
);
866 swapout (nsamples
* 2 + 12);
867 for (i
= 0; i
< nsamples
; i
++)
868 swapout16 (saved_state
.asregs
.profile_hist
[i
]);
882 #define MMASKB ((saved_state.asregs.msize -1) & ~0)
885 sim_resume (sd
, step
, siggnal
)
889 register unsigned int pc
;
890 register int cycles
= 0;
891 register int stalls
= 0;
892 register int memstalls
= 0;
893 register int insts
= 0;
894 register int prevlock
;
895 register int thislock
;
896 register unsigned int doprofile
;
897 #if defined(__GO32__) || defined(WIN32)
898 register int pollcount
= 0;
900 register int little_endian
= target_byte_order
== 1234;
902 int tick_start
= get_now ();
904 extern unsigned char sh_jump_table0
[];
906 register unsigned char *jump_table
= sh_jump_table0
;
908 register int *R
= &(saved_state
.asregs
.regs
[0]);
909 register float *F
= &(saved_state
.asregs
.fregs
[0]);
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
;
973 /* FIXME: Testing for INSIDE_SIMULATOR is wrong.
974 Only one copy of interp.o is built. */
975 #if defined (WIN32) && !defined(INSIDE_SIMULATOR)
977 if (pollcount
> 1000)
992 if (cycles
>= doprofile
)
995 saved_state
.asregs
.cycles
+= doprofile
;
997 if (saved_state
.asregs
.profile_hist
)
999 int n
= pc
>> PROFILE_SHIFT
;
1002 int i
= saved_state
.asregs
.profile_hist
[n
];
1004 saved_state
.asregs
.profile_hist
[n
] = i
+ 1;
1011 while (!saved_state
.asregs
.exception
);
1013 if (saved_state
.asregs
.exception
== SIGILL
1014 || saved_state
.asregs
.exception
== SIGBUS
)
1019 saved_state
.asregs
.ticks
+= get_now () - tick_start
;
1020 saved_state
.asregs
.cycles
+= cycles
;
1021 saved_state
.asregs
.stalls
+= stalls
;
1022 saved_state
.asregs
.memstalls
+= memstalls
;
1023 saved_state
.asregs
.insts
+= insts
;
1024 saved_state
.asregs
.pc
= pc
;
1025 saved_state
.asregs
.sr
.bits
.t
= T
;
1026 saved_state
.asregs
.pr
= PR
;
1028 saved_state
.asregs
.prevlock
= prevlock
;
1029 saved_state
.asregs
.thislock
= thislock
;
1036 signal (SIGINT
, prev
);
1040 sim_write (sd
, addr
, buffer
, size
)
1043 unsigned char *buffer
;
1050 for (i
= 0; i
< size
; i
++)
1052 saved_state
.asregs
.memory
[MMASKB
& (addr
+ i
)] = buffer
[i
];
1058 sim_read (sd
, addr
, buffer
, size
)
1061 unsigned char *buffer
;
1068 for (i
= 0; i
< size
; i
++)
1070 buffer
[i
] = saved_state
.asregs
.memory
[MMASKB
& (addr
+ i
)];
1076 sim_store_register (sd
, rn
, memory
)
1079 unsigned char *memory
;
1082 saved_state
.asregs
.regs
[rn
] = RLAT(0);
1086 sim_fetch_register (sd
, rn
, memory
)
1089 unsigned char *memory
;
1092 WLAT (0, saved_state
.asregs
.regs
[rn
]);
1103 sim_stop_reason (sd
, reason
, sigrc
)
1105 enum sim_stop
*reason
;
1108 /* The SH simulator uses SIGQUIT to indicate that the program has
1109 exited, so we must check for it here and translate it to exit. */
1110 if (saved_state
.asregs
.exception
== SIGQUIT
)
1112 *reason
= sim_exited
;
1113 *sigrc
= saved_state
.asregs
.regs
[5];
1117 *reason
= sim_stopped
;
1118 *sigrc
= saved_state
.asregs
.exception
;
1123 sim_info (sd
, verbose
)
1127 double timetaken
= (double) saved_state
.asregs
.ticks
/ (double) now_persec ();
1128 double virttime
= saved_state
.asregs
.cycles
/ 36.0e6
;
1130 callback
->printf_filtered (callback
, "\n\n# instructions executed %10d\n",
1131 saved_state
.asregs
.insts
);
1132 callback
->printf_filtered (callback
, "# cycles %10d\n",
1133 saved_state
.asregs
.cycles
);
1134 callback
->printf_filtered (callback
, "# pipeline stalls %10d\n",
1135 saved_state
.asregs
.stalls
);
1136 callback
->printf_filtered (callback
, "# misaligned load/store %10d\n",
1137 saved_state
.asregs
.memstalls
);
1138 callback
->printf_filtered (callback
, "# real time taken %10.4f\n",
1140 callback
->printf_filtered (callback
, "# virtual time taken %10.4f\n",
1142 callback
->printf_filtered (callback
, "# profiling size %10d\n",
1144 callback
->printf_filtered (callback
, "# profiling frequency %10d\n",
1145 saved_state
.asregs
.profile
);
1146 callback
->printf_filtered (callback
, "# profile maxpc %10x\n",
1147 (1 << sim_profile_size
) << PROFILE_SHIFT
);
1151 callback
->printf_filtered (callback
, "# cycles/second %10d\n",
1152 (int) (saved_state
.asregs
.cycles
/ timetaken
));
1153 callback
->printf_filtered (callback
, "# simulation ratio %10.4f\n",
1154 virttime
/ timetaken
);
1162 saved_state
.asregs
.profile
= n
;
1166 sim_set_profile_size (n
)
1169 sim_profile_size
= n
;
1176 /* FIXME: Better argument checking is needed here. */
1177 if (argv
[1] != NULL
)
1179 parse_and_set_memory_size (argv
[1]);
1181 /* fudge our descriptor for now */
1182 return (SIM_DESC
) 1;
1186 parse_and_set_memory_size (str
)
1191 n
= strtol (str
, NULL
, 10);
1192 if (n
> 0 && n
<= 24)
1193 sim_memory_size
= n
;
1195 callback
->printf_filtered (callback
, "Bad memory size %d; must be 1 to 24, inclusive\n", n
);
1199 sim_close (sd
, quitting
)
1207 sim_load (sd
, prog
, from_tty
)
1212 /* Return nonzero so GDB will handle it. */
1217 sim_create_inferior (sd
, start_address
, argv
, env
)
1219 SIM_ADDR start_address
;
1223 saved_state
.asregs
.pc
= start_address
;
1234 sim_do_command (sd
, cmd
)
1238 char *sms_cmd
= "set-memory-size";
1240 if (strncmp (cmd
, sms_cmd
, strlen (sms_cmd
)) == 0
1241 && strchr (" ", cmd
[strlen(sms_cmd
)]))
1242 parse_and_set_memory_size (cmd
+ strlen(sms_cmd
) + 1);
1244 else if (strcmp (cmd
, "help") == 0)
1246 callback
->printf_filtered (callback
, "List of SH simulator commands:\n\n");
1247 callback
->printf_filtered (callback
, "set-memory-size <n> -- Set the number of address bits to use\n");
1248 callback
->printf_filtered (callback
, "\n");
1251 fprintf (stderr
, "Error: \"%s\" is not a valid SH simulator command.\n",
1256 sim_set_callbacks (sd
, p
)