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 /* Cast the second argument to void *, to avoid type mismatch
588 if a prototype is present. */
589 regs
[0] = utime (ptr (regs
[5]), (void *) ptr (regs
[6]));
601 saved_state
.asregs
.exception
= SIGTRAP
;
607 control_c (sig
, code
, scp
, addr
)
613 saved_state
.asregs
.exception
= SIGINT
;
618 div1 (R
, iRn2
, iRn1
, T
)
625 unsigned char old_q
, tmp1
;
628 Q
= (unsigned char) ((0x80000000 & R
[iRn1
]) != 0);
630 R
[iRn1
] |= (unsigned long) T
;
640 tmp1
= (R
[iRn1
] > tmp0
);
647 Q
= (unsigned char) (tmp1
== 0);
654 tmp1
= (R
[iRn1
] < tmp0
);
658 Q
= (unsigned char) (tmp1
== 0);
673 tmp1
= (R
[iRn1
] < tmp0
);
680 Q
= (unsigned char) (tmp1
== 0);
687 tmp1
= (R
[iRn1
] > tmp0
);
691 Q
= (unsigned char) (tmp1
== 0);
712 unsigned long RnL
, RnH
;
713 unsigned long RmL
, RmH
;
714 unsigned long temp0
, temp1
, temp2
, temp3
;
715 unsigned long Res2
, Res1
, Res0
;
718 RnH
= (rn
>> 16) & 0xffff;
720 RmH
= (rm
>> 16) & 0xffff;
726 Res1
= temp1
+ temp2
;
729 temp1
= (Res1
<< 16) & 0xffff0000;
730 Res0
= temp0
+ temp1
;
733 Res2
+= ((Res1
>> 16) & 0xffff) + temp3
;
748 macw (regs
, memory
, n
, m
)
750 unsigned char *memory
;
754 long prod
, macl
, sum
;
756 tempm
=RSWAT(regs
[m
]); regs
[m
]+=2;
757 tempn
=RSWAT(regs
[n
]); regs
[n
]+=2;
760 prod
= (long)(short) tempm
* (long)(short) tempn
;
764 if ((~(prod
^ macl
) & (sum
^ prod
)) < 0)
766 /* MACH's lsb is a sticky overflow bit. */
768 /* Store the smallest negative number in MACL if prod is
769 negative, and the largest positive number otherwise. */
770 sum
= 0x7fffffff + (prod
< 0);
776 /* Add to MACH the sign extended product, and carry from low sum. */
777 mach
= MACH
+ (-(prod
< 0)) + ((unsigned long) sum
< prod
);
778 /* Sign extend at 10:th bit in MACH. */
779 MACH
= (mach
& 0x1ff) | -(mach
& 0x200);
784 /* Set the memory size to the power of two provided. */
791 saved_state
.asregs
.msize
= 1 << power
;
793 sim_memory_size
= power
;
796 if (saved_state
.asregs
.memory
)
798 free (saved_state
.asregs
.memory
);
801 saved_state
.asregs
.memory
=
802 (unsigned char *) calloc (64, saved_state
.asregs
.msize
/ 64);
804 if (!saved_state
.asregs
.memory
)
807 "Not enough VM for simulation of %d bytes of RAM\n",
808 saved_state
.asregs
.msize
);
810 saved_state
.asregs
.msize
= 1;
811 saved_state
.asregs
.memory
= (unsigned char *) calloc (1, 1);
816 int target_byte_order
;
819 set_static_little_endian(x
)
829 register int little_endian
= target_byte_order
== 1234;
830 set_static_little_endian (little_endian
);
831 if (saved_state
.asregs
.msize
!= 1 << sim_memory_size
)
833 sim_size (sim_memory_size
);
836 if (saved_state
.asregs
.profile
&& !profile_file
)
838 profile_file
= fopen ("gmon.out", "wb");
839 /* Seek to where to put the call arc data */
840 nsamples
= (1 << sim_profile_size
);
842 fseek (profile_file
, nsamples
* 2 + 12, 0);
846 fprintf (stderr
, "Can't open gmon.out\n");
850 saved_state
.asregs
.profile_hist
=
851 (unsigned short *) calloc (64, (nsamples
* sizeof (short) / 64));
865 unsigned short *first
;
868 p
= saved_state
.asregs
.profile_hist
;
870 maxpc
= (1 << sim_profile_size
);
872 fseek (profile_file
, 0L, 0);
873 swapout (minpc
<< PROFILE_SHIFT
);
874 swapout (maxpc
<< PROFILE_SHIFT
);
875 swapout (nsamples
* 2 + 12);
876 for (i
= 0; i
< nsamples
; i
++)
877 swapout16 (saved_state
.asregs
.profile_hist
[i
]);
891 #define MMASKB ((saved_state.asregs.msize -1) & ~0)
895 sim_resume (step
, siggnal
)
898 register unsigned int pc
;
899 register int cycles
= 0;
900 register int stalls
= 0;
901 register int insts
= 0;
902 register int prevlock
;
903 register int thislock
;
904 register unsigned int doprofile
;
905 #if defined(__GO32__) || defined(WIN32)
906 register int pollcount
= 0;
908 register int little_endian
= target_byte_order
== 1234;
911 int tick_start
= get_now ();
913 extern unsigned char sh_jump_table0
[];
915 register unsigned char *jump_table
= sh_jump_table0
;
917 register int *R
= &(saved_state
.asregs
.regs
[0]);
918 /* start-sanitize-sh3e */
919 register float *F
= &(saved_state
.asregs
.fregs
[0]);
920 /* end-sanitize-sh3e */
924 register int maskb
= ((saved_state
.asregs
.msize
- 1) & ~0);
925 register int maskw
= ((saved_state
.asregs
.msize
- 1) & ~1);
926 register int maskl
= ((saved_state
.asregs
.msize
- 1) & ~3);
927 register unsigned char *memory
;
928 register unsigned int sbit
= ((unsigned int) 1 << 31);
930 prev
= signal (SIGINT
, control_c
);
934 memory
= saved_state
.asregs
.memory
;
938 saved_state
.asregs
.exception
= SIGTRAP
;
942 saved_state
.asregs
.exception
= 0;
945 pc
= saved_state
.asregs
.pc
;
946 PR
= saved_state
.asregs
.pr
;
947 T
= saved_state
.asregs
.sr
.bits
.t
;
948 prevlock
= saved_state
.asregs
.prevlock
;
949 thislock
= saved_state
.asregs
.thislock
;
950 doprofile
= saved_state
.asregs
.profile
;
952 /* If profiling not enabled, disable it by asking for
953 profiles infrequently. */
959 register unsigned int iword
= RUWAT (pc
);
960 register unsigned int ult
;
973 if (pollcount
> 1000)
979 saved_state
.asregs
.exception
= SIGINT
;
986 if (pollcount
> 1000)
1001 if (cycles
>= doprofile
)
1004 saved_state
.asregs
.cycles
+= doprofile
;
1005 cycles
-= doprofile
;
1006 if (saved_state
.asregs
.profile_hist
)
1008 int n
= pc
>> PROFILE_SHIFT
;
1011 int i
= saved_state
.asregs
.profile_hist
[n
];
1013 saved_state
.asregs
.profile_hist
[n
] = i
+ 1;
1020 while (!saved_state
.asregs
.exception
);
1022 if (saved_state
.asregs
.exception
== SIGILL
1023 || saved_state
.asregs
.exception
== SIGBUS
)
1028 saved_state
.asregs
.ticks
+= get_now () - tick_start
;
1029 saved_state
.asregs
.cycles
+= cycles
;
1030 saved_state
.asregs
.stalls
+= stalls
;
1031 saved_state
.asregs
.insts
+= insts
;
1032 saved_state
.asregs
.pc
= pc
;
1033 saved_state
.asregs
.sr
.bits
.t
= T
;
1034 saved_state
.asregs
.pr
= PR
;
1036 saved_state
.asregs
.prevlock
= prevlock
;
1037 saved_state
.asregs
.thislock
= thislock
;
1045 signal (SIGINT
, prev
);
1052 sim_write (addr
, buffer
, size
)
1054 unsigned char *buffer
;
1060 for (i
= 0; i
< size
; i
++)
1062 saved_state
.asregs
.memory
[MMASKB
& (addr
+ i
)] = buffer
[i
];
1068 sim_read (addr
, buffer
, size
)
1070 unsigned char *buffer
;
1077 for (i
= 0; i
< size
; i
++)
1079 buffer
[i
] = saved_state
.asregs
.memory
[MMASKB
& (addr
+ i
)];
1086 sim_store_register (rn
, memory
)
1088 unsigned char *memory
;
1091 saved_state
.asregs
.regs
[rn
]=RLAT(0);
1095 sim_fetch_register (rn
, memory
)
1097 unsigned char *memory
;
1100 WLAT (0, saved_state
.asregs
.regs
[rn
]);
1111 sim_stop_reason (reason
, sigrc
)
1112 enum sim_stop
*reason
;
1115 *reason
= sim_stopped
;
1116 *sigrc
= saved_state
.asregs
.exception
;
1124 double timetaken
= (double) saved_state
.asregs
.ticks
/ (double) now_persec ();
1125 double virttime
= saved_state
.asregs
.cycles
/ 36.0e6
;
1127 callback
->printf_filtered (callback
,
1128 "\n\n# instructions executed %10d\n",
1129 saved_state
.asregs
.insts
);
1130 callback
-> printf_filtered (callback
, "# cycles %10d\n", saved_state
.asregs
.cycles
);
1131 callback
-> printf_filtered (callback
, "# pipeline stalls %10d\n", saved_state
.asregs
.stalls
);
1132 callback
-> printf_filtered (callback
, "# real time taken %10.4f\n", timetaken
);
1133 callback
-> printf_filtered (callback
, "# virtual time taken %10.4f\n", virttime
);
1134 callback
-> printf_filtered (callback
, "# profiling size %10d\n", sim_profile_size
);
1135 callback
-> printf_filtered (callback
, "# profiling frequency %10d\n", saved_state
.asregs
.profile
);
1136 callback
-> printf_filtered (callback
, "# profile maxpc %10x\n",
1137 (1 << sim_profile_size
) << PROFILE_SHIFT
);
1141 callback
->printf_filtered (callback
, "# cycles/second %10d\n",
1142 (int) (saved_state
.asregs
.cycles
/ timetaken
));
1143 callback
->printf_filtered (callback
, "# simulation ratio %10.4f\n",
1144 virttime
/ timetaken
);
1153 saved_state
.asregs
.profile
= n
;
1157 sim_set_profile_size (n
)
1160 sim_profile_size
= n
;
1172 parse_and_set_memory_size (args
);
1177 parse_and_set_memory_size (str
)
1182 n
= strtol (str
, NULL
, 10);
1183 if (n
> 0 && n
<= 24)
1184 sim_memory_size
= n
;
1186 callback
->printf_filtered (callback
, "Bad memory size %d; must be 1 to 24, inclusive\n", n
);
1190 sim_close (quitting
)
1197 sim_load (prog
, from_tty
)
1201 /* Return nonzero so GDB will handle it. */
1206 sim_create_inferior (start_address
, argv
, env
)
1207 SIM_ADDR start_address
;
1211 saved_state
.asregs
.pc
= start_address
;
1221 sim_do_command (cmd
)
1225 char *sms_cmd
= "set-memory-size";
1227 if (strncmp (cmd
, sms_cmd
, strlen (sms_cmd
)) == 0
1228 && strchr (" ", cmd
[strlen(sms_cmd
)]))
1229 parse_and_set_memory_size (cmd
+ strlen(sms_cmd
) + 1);
1231 else if (strcmp (cmd
, "help") == 0)
1233 callback
->printf_filtered (callback
,"List of SH simulator commands:\n\n");
1234 callback
->printf_filtered (callback
,"set-memory-size <n> -- Set the number of address bits to use\n");
1235 callback
->printf_filtered (callback
,"\n");
1238 fprintf (stderr
, "Error: \"%s\" is not a valid SH simulator command.\n",
1246 return saved_state
.asregs
.regs
[5];
1252 sim_set_callbacks(p
)