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 static SIM_OPEN_KIND sim_kind;
78 static int little_endian_p;
86 /* This function exists solely for the purpose of setting a breakpoint to
87 catch simulated bus errors when running the simulator under GDB. */
94 #define BUSERROR(addr, mask) \
95 if (addr & ~mask) { saved_state.asregs.exception = SIGBUS; bp_holder (); }
97 /* Define this to enable register lifetime checking.
98 The compiler generates "add #0,rn" insns to mark registers as invalid,
99 the simulator uses this info to call fail if it finds a ref to an invalid
100 register before a def
107 #define CREF(x) if(!valid[x]) fail();
108 #define CDEF(x) valid[x] = 1;
109 #define UNDEF(x) valid[x] = 0;
116 static void parse_and_set_memory_size PARAMS ((char *str));
118 static int IOMEM PARAMS ((int addr, int write, int value));
120 static host_callback *callback;
122 /* These variables are at file scope so that functions other than
123 sim_resume can use the fetch/store macros */
125 static int little_endian;
128 static int maskl = ~0;
129 static int maskw = ~0;
181 #define PROFILE_FREQ 1
182 #define PROFILE_SHIFT 2
184 unsigned short *profile_hist;
185 unsigned char *memory;
191 saved_state_type saved_state;
194 wlat_little (memory, x, value, maskl)
195 unsigned char *memory;
198 unsigned char *p = memory + ((x) & maskl);
207 wwat_little (memory, x, value, maskw)
208 unsigned char *memory;
211 unsigned char *p = memory + ((x) & maskw);
219 wbat_any (memory, x, value, maskb)
220 unsigned char *memory;
222 unsigned char *p = memory + (x & maskb);
231 wlat_big (memory, x, value, maskl)
232 unsigned char *memory;
235 unsigned char *p = memory + ((x) & maskl);
245 wwat_big (memory, x, value, maskw)
246 unsigned char *memory;
249 unsigned char *p = memory + ((x) & maskw);
257 wbat_big (memory, x, value, maskb)
258 unsigned char *memory;
260 unsigned char *p = memory + (x & maskb);
271 rlat_little (memory, x, maskl)
272 unsigned char *memory;
274 unsigned char *p = memory + ((x) & maskl);
277 return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
281 rwat_little (memory, x, maskw)
282 unsigned char *memory;
284 unsigned char *p = memory + ((x) & maskw);
287 return (p[1] << 8) | p[0];
291 rbat_any (memory, x, maskb)
292 unsigned char *memory;
294 unsigned char *p = memory + ((x) & maskb);
301 rlat_big (memory, x, maskl)
302 unsigned char *memory;
304 unsigned char *p = memory + ((x) & maskl);
307 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
311 rwat_big (memory, x, maskw)
312 unsigned char *memory;
314 unsigned char *p = memory + ((x) & maskw);
317 return (p[0] << 8) | p[1];
320 #define RWAT(x) (little_endian ? rwat_little(memory, x, maskw): rwat_big(memory, x, maskw))
321 #define RLAT(x) (little_endian ? rlat_little(memory, x, maskl): rlat_big(memory, x, maskl))
322 #define RBAT(x) (rbat_any (memory, x, maskb))
323 #define WWAT(x,v) (little_endian ? wwat_little(memory, x, v, maskw): wwat_big(memory, x, v, maskw))
324 #define WLAT(x,v) (little_endian ? wlat_little(memory, x, v, maskl): wlat_big(memory, x, v, maskl))
325 #define WBAT(x,v) (wbat_any (memory, x, v, maskb))
327 #define RUWAT(x) (RWAT(x) & 0xffff)
328 #define RSWAT(x) ((short)(RWAT(x)))
329 #define RSBAT(x) (SEXT(RBAT(x)))
331 #define MA() ((pc & 3) != 0 ? ++memstalls : 0)
333 #define SEXT(x) (((x&0xff) ^ (~0x7f))+0x80)
334 #define SEXTW(y) ((int)((short)y))
336 #define SL(TEMPPC) iword= RUWAT(TEMPPC); goto top;
340 #define L(x) thislock = x;
341 #define TL(x) if ((x) == prevlock) stalls++;
342 #define TB(x,y) if ((x) == prevlock || (y)==prevlock) stalls++;
344 #if defined(__GO32__) || defined(WIN32)
345 int sim_memory_size = 19;
347 int sim_memory_size = 24;
350 static int sim_profile_size = 17;
356 #define SMR1 (0x05FFFEC8) /* Channel 1 serial mode register */
357 #define BRR1 (0x05FFFEC9) /* Channel 1 bit rate register */
358 #define SCR1 (0x05FFFECA) /* Channel 1 serial control register */
359 #define TDR1 (0x05FFFECB) /* Channel 1 transmit data register */
360 #define SSR1 (0x05FFFECC) /* Channel 1 serial status register */
361 #define RDR1 (0x05FFFECD) /* Channel 1 receive data register */
363 #define SCI_RDRF 0x40 /* Recieve data register full */
364 #define SCI_TDRE 0x80 /* Transmit data register empty */
367 IOMEM (addr, write, value)
399 return time ((long *) 0);
408 static FILE *profile_file;
412 unsigned char *memory;
420 unsigned char *memory;
434 fwrite (b, 4, 1, profile_file);
444 fwrite (b, 2, 1, profile_file);
447 /* Turn a pointer in a register into a pointer into real memory. */
453 return (char *) (x + saved_state.asregs.memory);
456 /* Simulate a monitor trap, put the result into r0 and errno into r1 */
459 trap (i, regs, memory, maskl, maskw, little_endian)
462 unsigned char *memory;
467 printf ("%c", regs[0]);
470 saved_state.asregs.exception = SIGQUIT;
472 case 3: /* FIXME: for backwards compat, should be removed */
482 #if !defined(__GO32__) && !defined(WIN32)
487 regs[0] = execve (ptr (regs[5]), (char **)ptr (regs[6]), (char **)ptr (regs[7]));
490 regs[0] = execve (ptr (regs[5]),(char **) ptr (regs[6]), 0);
499 regs[0] = pipe (host_fd);
501 WLAT (buf, host_fd[0]);
503 WLAT (buf, host_fd[1]);
508 regs[0] = wait (ptr (regs[5]));
513 regs[0] = callback->read (callback, regs[5], ptr (regs[6]), regs[7]);
517 regs[0] = (int)callback->write_stdout (callback, ptr(regs[6]), regs[7]);
519 regs[0] = (int)callback->write (callback, regs[5], ptr (regs[6]), regs[7]);
522 regs[0] = callback->lseek (callback,regs[5], regs[6], regs[7]);
525 regs[0] = callback->close (callback,regs[5]);
528 regs[0] = callback->open (callback,ptr (regs[5]), regs[6]);
531 /* EXIT - caller can look in r5 to work out the reason */
532 saved_state.asregs.exception = SIGQUIT;
536 case SYS_stat: /* added at hmsi */
537 /* stat system call */
539 struct stat host_stat;
542 regs[0] = stat (ptr (regs[5]), &host_stat);
546 WWAT (buf, host_stat.st_dev);
548 WWAT (buf, host_stat.st_ino);
550 WLAT (buf, host_stat.st_mode);
552 WWAT (buf, host_stat.st_nlink);
554 WWAT (buf, host_stat.st_uid);
556 WWAT (buf, host_stat.st_gid);
558 WWAT (buf, host_stat.st_rdev);
560 WLAT (buf, host_stat.st_size);
562 WLAT (buf, host_stat.st_atime);
566 WLAT (buf, host_stat.st_mtime);
570 WLAT (buf, host_stat.st_ctime);
582 regs[0] = chown (ptr (regs[5]), regs[6], regs[7]);
585 regs[0] = chmod (ptr (regs[5]), regs[6]);
588 /* Cast the second argument to void *, to avoid type mismatch
589 if a prototype is present. */
590 regs[0] = utime (ptr (regs[5]), (void *) ptr (regs[6]));
595 regs[1] = callback->get_errno (callback);
602 saved_state.asregs.exception = SIGTRAP;
609 control_c (sig, code, scp, addr)
615 saved_state.asregs.exception = SIGINT;
619 div1 (R, iRn2, iRn1, T)
626 unsigned char old_q, tmp1;
629 Q = (unsigned char) ((0x80000000 & R[iRn1]) != 0);
631 R[iRn1] |= (unsigned long) T;
641 tmp1 = (R[iRn1] > tmp0);
648 Q = (unsigned char) (tmp1 == 0);
655 tmp1 = (R[iRn1] < tmp0);
659 Q = (unsigned char) (tmp1 == 0);
674 tmp1 = (R[iRn1] < tmp0);
681 Q = (unsigned char) (tmp1 == 0);
688 tmp1 = (R[iRn1] > tmp0);
692 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;
795 if (saved_state.asregs.memory)
797 free (saved_state.asregs.memory);
800 saved_state.asregs.memory =
801 (unsigned char *) calloc (64, saved_state.asregs.msize / 64);
803 if (!saved_state.asregs.memory)
806 "Not enough VM for simulation of %d bytes of RAM\n",
807 saved_state.asregs.msize);
809 saved_state.asregs.msize = 1;
810 saved_state.asregs.memory = (unsigned char *) calloc (1, 1);
815 set_static_little_endian (x)
824 int little_endian = little_endian_p;
826 set_static_little_endian (little_endian);
828 if (saved_state.asregs.msize != 1 << sim_memory_size)
830 sim_size (sim_memory_size);
833 if (saved_state.asregs.profile && !profile_file)
835 profile_file = fopen ("gmon.out", "wb");
836 /* Seek to where to put the call arc data */
837 nsamples = (1 << sim_profile_size);
839 fseek (profile_file, nsamples * 2 + 12, 0);
843 fprintf (stderr, "Can't open gmon.out\n");
847 saved_state.asregs.profile_hist =
848 (unsigned short *) calloc (64, (nsamples * sizeof (short) / 64));
861 p = saved_state.asregs.profile_hist;
863 maxpc = (1 << sim_profile_size);
865 fseek (profile_file, 0L, 0);
866 swapout (minpc << PROFILE_SHIFT);
867 swapout (maxpc << PROFILE_SHIFT);
868 swapout (nsamples * 2 + 12);
869 for (i = 0; i < nsamples; i++)
870 swapout16 (saved_state.asregs.profile_hist[i]);
884 #define MMASKB ((saved_state.asregs.msize -1) & ~0)
890 saved_state.asregs.exception = SIGINT;
895 sim_resume (sd, step, siggnal)
899 register unsigned int pc;
900 register int cycles = 0;
901 register int stalls = 0;
902 register int memstalls = 0;
903 register int insts = 0;
904 register int prevlock;
905 register int thislock;
906 register unsigned int doprofile;
907 register int pollcount = 0;
908 register int little_endian = little_endian_p;
910 int tick_start = get_now ();
912 extern unsigned char sh_jump_table0[];
914 register unsigned char *jump_table = sh_jump_table0;
916 register int *R = &(saved_state.asregs.regs[0]);
917 register float *F = &(saved_state.asregs.fregs[0]);
921 register int maskb = ((saved_state.asregs.msize - 1) & ~0);
922 register int maskw = ((saved_state.asregs.msize - 1) & ~1);
923 register int maskl = ((saved_state.asregs.msize - 1) & ~3);
924 register unsigned char *memory;
925 register unsigned int sbit = ((unsigned int) 1 << 31);
927 prev = signal (SIGINT, control_c);
931 memory = saved_state.asregs.memory;
935 saved_state.asregs.exception = SIGTRAP;
939 saved_state.asregs.exception = 0;
942 pc = saved_state.asregs.pc;
943 PR = saved_state.asregs.pr;
944 T = saved_state.asregs.sr.bits.t;
945 prevlock = saved_state.asregs.prevlock;
946 thislock = saved_state.asregs.thislock;
947 doprofile = saved_state.asregs.profile;
949 /* If profiling not enabled, disable it by asking for
950 profiles infrequently. */
956 register unsigned int iword = RUWAT (pc);
957 register unsigned int ult;
969 if (pollcount > 1000)
972 if ((*callback->poll_quit) != NULL
973 && (*callback->poll_quit) (callback))
984 if (cycles >= doprofile)
987 saved_state.asregs.cycles += doprofile;
989 if (saved_state.asregs.profile_hist)
991 int n = pc >> PROFILE_SHIFT;
994 int i = saved_state.asregs.profile_hist[n];
996 saved_state.asregs.profile_hist[n] = i + 1;
1003 while (!saved_state.asregs.exception);
1005 if (saved_state.asregs.exception == SIGILL
1006 || saved_state.asregs.exception == SIGBUS)
1011 saved_state.asregs.ticks += get_now () - tick_start;
1012 saved_state.asregs.cycles += cycles;
1013 saved_state.asregs.stalls += stalls;
1014 saved_state.asregs.memstalls += memstalls;
1015 saved_state.asregs.insts += insts;
1016 saved_state.asregs.pc = pc;
1017 saved_state.asregs.sr.bits.t = T;
1018 saved_state.asregs.pr = PR;
1020 saved_state.asregs.prevlock = prevlock;
1021 saved_state.asregs.thislock = thislock;
1028 signal (SIGINT, prev);
1032 sim_write (sd, addr, buffer, size)
1035 unsigned char *buffer;
1042 for (i = 0; i < size; i++)
1044 saved_state.asregs.memory[MMASKB & (addr + i)] = buffer[i];
1050 sim_read (sd, addr, buffer, size)
1053 unsigned char *buffer;
1060 for (i = 0; i < size; i++)
1062 buffer[i] = saved_state.asregs.memory[MMASKB & (addr + i)];
1068 sim_store_register (sd, rn, memory)
1071 unsigned char *memory;
1074 saved_state.asregs.regs[rn] = RLAT(0);
1078 sim_fetch_register (sd, rn, memory)
1081 unsigned char *memory;
1084 WLAT (0, saved_state.asregs.regs[rn]);
1095 sim_stop_reason (sd, reason, sigrc)
1097 enum sim_stop *reason;
1100 /* The SH simulator uses SIGQUIT to indicate that the program has
1101 exited, so we must check for it here and translate it to exit. */
1102 if (saved_state.asregs.exception == SIGQUIT)
1104 *reason = sim_exited;
1105 *sigrc = saved_state.asregs.regs[5];
1109 *reason = sim_stopped;
1110 *sigrc = saved_state.asregs.exception;
1115 sim_info (sd, verbose)
1119 double timetaken = (double) saved_state.asregs.ticks / (double) now_persec ();
1120 double virttime = saved_state.asregs.cycles / 36.0e6;
1122 callback->printf_filtered (callback, "\n\n# instructions executed %10d\n",
1123 saved_state.asregs.insts);
1124 callback->printf_filtered (callback, "# cycles %10d\n",
1125 saved_state.asregs.cycles);
1126 callback->printf_filtered (callback, "# pipeline stalls %10d\n",
1127 saved_state.asregs.stalls);
1128 callback->printf_filtered (callback, "# misaligned load/store %10d\n",
1129 saved_state.asregs.memstalls);
1130 callback->printf_filtered (callback, "# real time taken %10.4f\n",
1132 callback->printf_filtered (callback, "# virtual time taken %10.4f\n",
1134 callback->printf_filtered (callback, "# profiling size %10d\n",
1136 callback->printf_filtered (callback, "# profiling frequency %10d\n",
1137 saved_state.asregs.profile);
1138 callback->printf_filtered (callback, "# profile maxpc %10x\n",
1139 (1 << sim_profile_size) << PROFILE_SHIFT);
1143 callback->printf_filtered (callback, "# cycles/second %10d\n",
1144 (int) (saved_state.asregs.cycles / timetaken));
1145 callback->printf_filtered (callback, "# simulation ratio %10.4f\n",
1146 virttime / timetaken);
1154 saved_state.asregs.profile = n;
1158 sim_set_profile_size (n)
1161 sim_profile_size = n;
1165 sim_open (kind,argv)
1174 for (p = argv + 1; *p != NULL; ++p)
1176 if (strcmp (*p, "-E") == 0)
1177 little_endian_p = strcmp (*++p, "big") != 0;
1178 else if (isdigit (**p))
1179 parse_and_set_memory_size (*p);
1182 /* fudge our descriptor for now */
1183 return (SIM_DESC) 1;
1187 parse_and_set_memory_size (str)
1192 n = strtol (str, NULL, 10);
1193 if (n > 0 && n <= 24)
1194 sim_memory_size = n;
1196 callback->printf_filtered (callback, "Bad memory size %d; must be 1 to 24, inclusive\n", n);
1200 sim_close (sd, quitting)
1208 sim_load (sd, prog, abfd, from_tty)
1214 extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
1217 prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
1218 sim_kind == SIM_OPEN_DEBUG);
1219 if (prog_bfd == NULL)
1221 saved_state.asregs.pc = bfd_get_start_address (prog_bfd);
1223 bfd_close (prog_bfd);
1228 sim_create_inferior (sd, argv, env)
1244 sim_do_command (sd, cmd)
1248 char *sms_cmd = "set-memory-size";
1251 if (cmd == NULL || *cmd == '\0')
1256 cmdsize = strlen (sms_cmd);
1257 if (strncmp (cmd, sms_cmd, cmdsize) == 0 && strchr (" \t", cmd[cmdsize]) != NULL)
1259 parse_and_set_memory_size (cmd + cmdsize + 1);
1261 else if (strcmp (cmd, "help") == 0)
1263 (callback->printf_filtered) (callback, "List of SH simulator commands:\n\n");
1264 (callback->printf_filtered) (callback, "set-memory-size <n> -- Set the number of address bits to use\n");
1265 (callback->printf_filtered) (callback, "\n");
1269 (callback->printf_filtered) (callback, "Error: \"%s\" is not a valid SH simulator command.\n", cmd);
1274 sim_set_callbacks (sd, p)