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.
22 #include <sys/times.h>
23 #include <sys/param.h>
25 #define O_RECOMPILE 85
28 #define DISASSEMBLER_TABLE
30 #define SBIT(x) ((x)&sbit)
31 #define R0 saved_state.asregs.regs[0]
32 #define Rn saved_state.asregs.regs[n]
33 #define Rm saved_state.asregs.regs[m]
34 #define UR0 (unsigned int)(saved_state.asregs.regs[0])
35 #define UR (unsigned int)R
36 #define UR (unsigned int)R
37 #define SR0 saved_state.asregs.regs[0]
38 #define GBR saved_state.asregs.gbr
39 #define VBR saved_state.asregs.vbr
40 #define MACH saved_state.asregs.mach
41 #define MACL saved_state.asregs.macl
42 #define M saved_state.asregs.sr.bits.m
43 #define Q saved_state.asregs.sr.bits.q
45 #define GET_SR() (saved_state.asregs.sr.bits.t = T, saved_state.asregs.sr.word)
46 #define SET_SR(x) {saved_state.asregs.sr.word = (x); T =saved_state.asregs.sr.bits.t;}
51 #ifdef TARGET_BIG_ENDIAN
52 #define LMEM(x) *((long *)(memory+((x)&maskl)))
53 #define BMEM(x) *((char *)(memory+((x)&maskb)))
54 #define UWMEM(x) *((unsigned short *)(memory+((x)&maskw)))
55 #define SWMEM(x) *((short *)(memory+((x)&maskw)))
56 #define WLAT(x,value) (LMEM(x) = value)
57 #define RLAT(x) (LMEM(x))
58 #define WWAT(x,value) (UWMEM(x) = value)
59 #define RSWAT(x) (SWMEM(x))
60 #define RUWAT(x) (UWMEM(x))
61 #define WBAT(x,value) (BMEM(x) = value)
62 #define RBAT(x) (BMEM(x))
64 /* For little endian or unknown host machines */
65 #define WLAT(x,value)\
66 { int v = value; unsigned char *p = memory + ((x) & maskl);\
67 p[0] =v>>24;p[1] = v>>16;p[2]=v>>8;p[3]=v; }
69 #define WWAT(x,value)\
70 { int v = value; unsigned char *p = memory + (x & maskw);p[0] =v>>8;p[1] = v ;}
72 #define WBAT(x,value)\
73 { unsigned char *p = memory + (x & maskb);p[0] =value;}
76 ((memory[x&maskl]<<24)|(memory[(x&maskl)+1]<<16)|(memory[(x&maskl)+2]<<8)| (memory[(x&maskl)+3]))
79 ((memory[x&maskw]<<8)|(memory[(x&maskw)+1]))
84 #define RUWAT(x) (RWAT(x) & 0xffff)
85 #define RSWAT(x) ((short)(RWAT(x)))
86 #define RSBAT(x) (SEXT(RBAT(x)))
92 #define SEXT(x) (((x&0xff) ^ (~0x7f))+0x80)
93 #define SEXTW(y) ((int)((short)y))
95 #define SL(TEMPPC) iword= RUWAT(TEMPPC); goto top;
98 #define L(x) thislock = x;
99 #define TL(x) if ((x) == prevlock) stalls++;
100 #define TB(x,y) if ((x) == prevlock || (y)==prevlock) stalls++;
101 int sim_memory_size = 19;
102 static int sim_profile_size = 17;
104 static int sim_timeout;
148 #define PROFILE_FREQ 1
149 #define PROFILE_SHIFT 2
151 unsigned short *profile_hist;
152 unsigned char *memory;
161 saved_state_type saved_state;
166 return time((char*)0);
177 static FILE *profile_file;
206 fwrite (b, 4, 1, profile_file);
216 fwrite (b, 2, 1, profile_file);
220 /* Turn a pointer in a register into a pointer into real memory. */
226 return (char *) (x + saved_state.asregs.memory);
229 /* Simulate a monitor trap. */
239 printf ("%c", regs[0]);
242 saved_state.asregs.exception = SIGQUIT;
253 regs[4] = read (regs[5], ptr (regs[6]), regs[7]);
256 regs[4] = write (regs[5], ptr (regs[6]), regs[7]);
259 regs[4] = lseek (regs[5], regs[6], regs[7]);
262 regs[4] = close (regs[5]);
265 regs[4] = open (ptr (regs[5]), regs[6]);
269 saved_state.asregs.exception = SIGQUIT;
283 saved_state.asregs.exception = SIGTRAP;
289 control_c (sig, code, scp, addr)
295 saved_state.asregs.exception = SIGINT;
300 div1 (R, iRn2, iRn1, T)
307 unsigned char old_q, tmp1;
310 Q = (unsigned char) ((0x80000000 & R[iRn1]) != 0);
312 R[iRn1] |= (unsigned long) T;
322 tmp1 = (R[iRn1] > tmp0);
329 Q = (unsigned char) (tmp1 == 0);
336 tmp1 = (R[iRn1] < tmp0);
340 Q = (unsigned char) (tmp1 == 0);
355 tmp1 = (R[iRn1] < tmp0);
362 Q = (unsigned char) (tmp1 == 0);
369 tmp1 = (R[iRn1] > tmp0);
373 Q = (unsigned char) (tmp1 == 0);
394 unsigned long RnL, RnH;
395 unsigned long RmL, RmH;
396 unsigned long temp0, temp1, temp2, temp3;
397 unsigned long Res2, Res1, Res0;
404 RnH = (rn >> 16) & 0xffff;
406 RmH = (rm >> 16) & 0xffff;
412 Res1 = temp1 + temp2;
415 temp1 = (Res1 << 16) & 0xffff0000;
416 Res0 = temp0 + temp1;
419 Res2 += ((Res1 >> 16) & 0xffff) + temp3;
433 /* Set the memory size to the power of two provided. */
440 saved_state.asregs.msize = 1 << power;
442 sim_memory_size = power;
445 if (saved_state.asregs.memory)
447 free (saved_state.asregs.memory);
450 saved_state.asregs.memory =
451 (unsigned char *) calloc (64, saved_state.asregs.msize / 64);
453 if (!saved_state.asregs.memory)
456 "Not enough VM for simuation of %d bytes of RAM\n",
457 saved_state.asregs.msize);
459 saved_state.asregs.msize = 1;
460 saved_state.asregs.memory = (unsigned char *) calloc (1, 1);
470 if (saved_state.asregs.msize != 1 << sim_memory_size)
472 sim_size (sim_memory_size);
475 if (saved_state.asregs.profile && !profile_file)
477 profile_file = fopen ("gmon.out", "wb");
478 /* Seek to where to put the call arc data */
479 nsamples = (1 << sim_profile_size);
481 fseek (profile_file, nsamples * 2 + 12, 0);
485 fprintf (stderr, "Can't open gmon.out\n");
489 saved_state.asregs.profile_hist =
490 (unsigned short *) calloc (64, (nsamples * sizeof (short) / 64));
504 unsigned short *first;
507 p = saved_state.asregs.profile_hist;
509 maxpc = (1 << sim_profile_size);
511 fseek (profile_file, 0L, 0);
512 swapout (minpc << PROFILE_SHIFT);
513 swapout (maxpc << PROFILE_SHIFT);
514 swapout (nsamples * 2 + 12);
515 for (i = 0; i < nsamples; i++)
516 swapout16 (saved_state.asregs.profile_hist[i]);
530 #define MMASKB ((saved_state.asregs.msize -1) & ~0)
535 register unsigned int pc;
536 register int cycles = 0;
537 register int stalls = 0;
538 register int insts = 0;
539 register int prevlock;
540 register int thislock;
541 register unsigned int doprofile;
543 int tick_start = get_now ();
545 extern unsigned char sh_jump_table0[];
547 register unsigned char *jump_table = sh_jump_table0;
549 register int *R = &(saved_state.asregs.regs[0]);
553 register int maskb = ((saved_state.asregs.msize - 1) & ~0);
554 register int maskw = ((saved_state.asregs.msize - 1) & ~1);
555 register int maskl = ((saved_state.asregs.msize - 1) & ~3);
556 register unsigned char *memory ;
557 register unsigned int sbit = (1 << 31);
559 prev = signal (SIGINT, control_c);
563 memory = saved_state.asregs.memory;
567 saved_state.asregs.exception = SIGTRAP;
571 saved_state.asregs.exception = 0;
574 pc = saved_state.asregs.pc;
575 PR = saved_state.asregs.pr;
576 T = saved_state.asregs.sr.bits.t;
577 prevlock = saved_state.asregs.prevlock;
578 thislock = saved_state.asregs.thislock;
579 doprofile = saved_state.asregs.profile;
581 /* If profiling not enabled, disable it by asking for
582 profiles infrequently. */
588 register unsigned int iword = RUWAT (pc);
589 register unsigned int ult;
602 if (cycles >= doprofile)
604 if (cycles > sim_timeout)
605 saved_state.asregs.exception = SIGQUIT;
607 saved_state.asregs.cycles += doprofile;
609 if (saved_state.asregs.profile_hist)
611 int n = pc >> PROFILE_SHIFT;
614 int i = saved_state.asregs.profile_hist[n];
616 saved_state.asregs.profile_hist[n] = i + 1;
622 while (!saved_state.asregs.exception);
624 if (saved_state.asregs.exception == SIGILL)
629 saved_state.asregs.ticks += get_now () - tick_start;
630 saved_state.asregs.cycles += cycles;
631 saved_state.asregs.stalls += stalls;
632 saved_state.asregs.insts += insts;
633 saved_state.asregs.pc = pc;
634 saved_state.asregs.sr.bits.t = T;
635 saved_state.asregs.pr = PR;
637 saved_state.asregs.prevlock = prevlock;
638 saved_state.asregs.thislock = thislock;
646 signal (SIGINT, prev);
653 sim_write (addr, buffer, size)
655 unsigned char *buffer;
661 for (i = 0; i < size; i++)
663 saved_state.asregs.memory[MMASKB & (addr + i)] = buffer[i];
669 sim_read (addr, buffer, size)
678 for (i = 0; i < size; i++)
680 buffer[i] = saved_state.asregs.memory[MMASKB & (addr + i)];
687 sim_store_register (rn, value)
689 unsigned char value[4];
691 saved_state.asregs.regs[rn] = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | (value[3]);
695 sim_fetch_register (rn, buf)
699 int value = ((int *) (&saved_state))[rn];
712 sim_stop_signal (sigrc)
715 *sigrc = saved_state.asregs.exception;
723 saved_state.asregs.pc = x;
730 double timetaken = (double) saved_state.asregs.ticks / (double) now_persec ();
731 double virttime = saved_state.asregs.cycles / 36.0e6;
733 printf ("\n\n# instructions executed %10d\n", saved_state.asregs.insts);
734 printf ("# cycles %10d\n", saved_state.asregs.cycles);
735 printf ("# pipeline stalls %10d\n", saved_state.asregs.stalls);
736 printf ("# real time taken %10.4f\n", timetaken);
737 printf ("# virtual time taken %10.4f\n", virttime);
738 printf ("# profiling size %10d\n", sim_profile_size);
739 printf ("# profiling frequency %10d\n", saved_state.asregs.profile);
740 printf ("# profile maxpc %10x\n", (1 << sim_profile_size) << PROFILE_SHIFT);
744 printf ("# cycles/second %10d\n", (int) (saved_state.asregs.cycles / timetaken));
745 printf ("# simulation ratio %10.4f\n", virttime / timetaken);
754 saved_state.asregs.profile = n;
758 sim_set_profile_size (n)
761 sim_profile_size = n;