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 #include <float.h> /* Needed for _isnan() */
44 #define SIGBUS SIGSEGV
48 #define SIGQUIT SIGTERM
55 #define O_RECOMPILE 85
57 #define DISASSEMBLER_TABLE
59 /* Define the rate at which the simulator should poll the host
61 #define POLL_QUIT_INTERVAL 0x60000
68 /* On targets like sparc-sun-solaris, fregs will be aligned on a 64 bit
69 boundary (because of the d member). To avoid padding between
70 registers - which whould make the job of sim_fetch_register harder,
71 we add padding at the start. */
112 int end_of_registers
;
115 #define PROFILE_FREQ 1
116 #define PROFILE_SHIFT 2
118 unsigned short *profile_hist
;
119 unsigned char *memory
;
125 saved_state_type saved_state
;
128 /* These variables are at file scope so that functions other than
129 sim_resume can use the fetch/store macros */
131 static int target_little_endian
;
132 static int host_little_endian
;
135 static int maskl
= ~0;
136 static int maskw
= ~0;
139 static SIM_OPEN_KIND sim_kind
;
143 /* Short hand definitions of the registers */
145 #define SBIT(x) ((x)&sbit)
146 #define R0 saved_state.asregs.regs[0]
147 #define Rn saved_state.asregs.regs[n]
148 #define Rm saved_state.asregs.regs[m]
149 #define UR0 (unsigned int)(saved_state.asregs.regs[0])
150 #define UR (unsigned int)R
151 #define UR (unsigned int)R
152 #define SR0 saved_state.asregs.regs[0]
153 #define GBR saved_state.asregs.gbr
154 #define VBR saved_state.asregs.vbr
155 #define SSR saved_state.asregs.ssr
156 #define SPC saved_state.asregs.spc
157 #define MACH saved_state.asregs.mach
158 #define MACL saved_state.asregs.macl
159 #define FPUL saved_state.asregs.fpul
165 /* Alternate bank of registers r0-r6 */
167 /* Note: code controling SR handles flips between BANK0 and BANK1 */
168 #define Rn_BANK(n) (saved_state.asregs.bank[!SR_RB][(n)])
169 #define SET_Rn_BANK(n, EXP) do { saved_state.asregs.bank[!SR_RB][(n)] = (EXP); } while (0)
174 #define SR_MASK_M (1 << 9)
175 #define SR_MASK_Q (1 << 8)
176 #define SR_MASK_I (0xf << 4)
177 #define SR_MASK_S (1 << 1)
178 #define SR_MASK_T (1 << 0)
180 #define SR_MASK_BL (1 << 28)
181 #define SR_MASK_RB (1 << 29)
182 #define SR_MASK_MD (1 << 30)
184 #define M ((saved_state.asregs.sr & SR_MASK_M) != 0)
185 #define Q ((saved_state.asregs.sr & SR_MASK_Q) != 0)
186 #define S ((saved_state.asregs.sr & SR_MASK_S) != 0)
187 #define T ((saved_state.asregs.sr & SR_MASK_T) != 0)
189 #define SR_BL ((saved_state.asregs.sr & SR_MASK_BL) != 0)
190 #define SR_RB ((saved_state.asregs.sr & SR_MASK_RB) != 0)
191 #define SR_MD ((saved_state.asregs.sr & SR_MASK_MD) != 0)
193 /* Note: don't use this for privileged bits */
194 #define SET_SR_BIT(EXP, BIT) \
197 saved_state.asregs.sr |= (BIT); \
199 saved_state.asregs.sr &= ~(BIT); \
202 #define SET_SR_M(EXP) SET_SR_BIT ((EXP), SR_MASK_M)
203 #define SET_SR_Q(EXP) SET_SR_BIT ((EXP), SR_MASK_Q)
204 #define SET_SR_S(EXP) SET_SR_BIT ((EXP), SR_MASK_S)
205 #define SET_SR_T(EXP) SET_SR_BIT ((EXP), SR_MASK_T)
207 #define GET_SR() (saved_state.asregs.sr - 0)
208 #define SET_SR(x) set_sr (x)
213 /* do we need to swap banks */
214 int old_gpr
= (SR_MD
? !SR_RB
: 0);
215 int new_gpr
= ((new_sr
& SR_MASK_MD
)
216 ? (new_sr
& SR_MASK_RB
) == 0
218 if (old_gpr
!= new_gpr
)
221 for (i
= 0; i
< 8; i
++)
223 saved_state
.asregs
.bank
[old_gpr
][i
] = saved_state
.asregs
.regs
[i
];
224 saved_state
.asregs
.regs
[i
] = saved_state
.asregs
.bank
[new_gpr
][i
];
230 /* Manipulate FPSCR */
232 #define FPSCR_MASK_FR (1 << 21)
233 #define FPSCR_MASK_SZ (1 << 20)
234 #define FPSCR_MASK_PR (1 << 19)
236 #define FPSCR_FR ((GET_FPSCR() & FPSCR_MASK_FR) != 0)
237 #define FPSCR_SZ ((GET_FPSCR() & FPSCR_MASK_SZ) != 0)
238 #define FPSCR_PR ((GET_FPSCR() & FPSCR_MASK_PR) != 0)
244 int old
= saved_state
.asregs
.fpscr
;
245 saved_state
.asregs
.fpscr
= (x
);
246 /* swap the floating point register banks */
247 if ((saved_state
.asregs
.fpscr
^ old
) & FPSCR_MASK_FR
)
249 union fregs_u tmpf
= saved_state
.asregs
.fregs
[0];
250 saved_state
.asregs
.fregs
[0] = saved_state
.asregs
.fregs
[1];
251 saved_state
.asregs
.fregs
[1] = tmpf
;
255 #define GET_FPSCR() (saved_state.asregs.fpscr)
256 #define SET_FPSCR(x) \
269 special_address (addr
, bits_written
, data
)
271 int bits_written
, data
;
273 if ((unsigned) addr
>> 24 == 0xf0 && bits_written
== 32 && (data
& 1) == 0)
274 /* This invalidates (if not associative) or might invalidate
275 (if associative) an instruction cache line. This is used for
276 trampolines. Since we don't simulate the cache, this is a no-op
277 as far as the simulator is concerned. */
279 /* We can't do anything useful with the other stuff, so fail. */
283 /* This function exists solely for the purpose of setting a breakpoint to
284 catch simulated bus errors when running the simulator under GDB. */
291 /* FIXME: sim_resume should be renamed to sim_engine_run. sim_resume
292 being implemented by ../common/sim_resume.c and the below should
293 make a call to sim_engine_halt */
295 #define BUSERROR(addr, mask, bits_written, data) \
298 if (special_address (addr, bits_written, data)) \
300 saved_state.asregs.exception = SIGBUS; \
304 /* Define this to enable register lifetime checking.
305 The compiler generates "add #0,rn" insns to mark registers as invalid,
306 the simulator uses this info to call fail if it finds a ref to an invalid
307 register before a def
314 #define CREF(x) if(!valid[x]) fail();
315 #define CDEF(x) valid[x] = 1;
316 #define UNDEF(x) valid[x] = 0;
323 static void parse_and_set_memory_size
PARAMS ((char *str
));
325 static int IOMEM
PARAMS ((int addr
, int write
, int value
));
327 static host_callback
*callback
;
331 /* Floating point registers */
333 #define DR(n) (get_dr (n))
339 if (host_little_endian
)
346 dr
.i
[1] = saved_state
.asregs
.fregs
[0].i
[n
+ 0];
347 dr
.i
[0] = saved_state
.asregs
.fregs
[0].i
[n
+ 1];
351 return (saved_state
.asregs
.fregs
[0].d
[n
>> 1]);
354 #define SET_DR(n, EXP) set_dr ((n), (EXP))
361 if (host_little_endian
)
369 saved_state
.asregs
.fregs
[0].i
[n
+ 0] = dr
.i
[1];
370 saved_state
.asregs
.fregs
[0].i
[n
+ 1] = dr
.i
[0];
373 saved_state
.asregs
.fregs
[0].d
[n
>> 1] = exp
;
376 #define SET_FI(n,EXP) (saved_state.asregs.fregs[0].i[(n)] = (EXP))
377 #define FI(n) (saved_state.asregs.fregs[0].i[(n)])
379 #define FR(n) (saved_state.asregs.fregs[0].f[(n)])
380 #define SET_FR(n,EXP) (saved_state.asregs.fregs[0].f[(n)] = (EXP))
382 #define XD_TO_XF(n) ((((n) & 1) << 5) | ((n) & 0x1e))
383 #define XF(n) (saved_state.asregs.fregs[(n) >> 5].i[(n) & 0x1f])
384 #define SET_XF(n,EXP) (saved_state.asregs.fregs[(n) >> 5].i[(n) & 0x1f] = (EXP))
387 #define FP_OP(n, OP, m) \
391 if (((n) & 1) || ((m) & 1)) \
392 saved_state.asregs.exception = SIGILL; \
394 SET_DR(n, (DR(n) OP DR(m))); \
397 SET_FR(n, (FR(n) OP FR(m))); \
400 #define FP_UNARY(n, OP) \
405 saved_state.asregs.exception = SIGILL; \
407 SET_DR(n, (OP (DR(n)))); \
410 SET_FR(n, (OP (FR(n)))); \
413 #define FP_CMP(n, OP, m) \
417 if (((n) & 1) || ((m) & 1)) \
418 saved_state.asregs.exception = SIGILL; \
420 SET_SR_T (DR(n) OP DR(m)); \
423 SET_SR_T (FR(n) OP FR(m)); \
429 wlat_little (memory
, x
, value
, maskl
)
430 unsigned char *memory
;
433 unsigned char *p
= memory
+ ((x
) & maskl
);
434 BUSERROR(x
, maskl
, 32, v
);
442 wwat_little (memory
, x
, value
, maskw
)
443 unsigned char *memory
;
446 unsigned char *p
= memory
+ ((x
) & maskw
);
447 BUSERROR(x
, maskw
, 16, v
);
454 wbat_any (memory
, x
, value
, maskb
)
455 unsigned char *memory
;
457 unsigned char *p
= memory
+ (x
& maskb
);
460 BUSERROR(x
, maskb
, 8, value
);
466 wlat_big (memory
, x
, value
, maskl
)
467 unsigned char *memory
;
470 unsigned char *p
= memory
+ ((x
) & maskl
);
471 BUSERROR(x
, maskl
, 32, v
);
480 wwat_big (memory
, x
, value
, maskw
)
481 unsigned char *memory
;
484 unsigned char *p
= memory
+ ((x
) & maskw
);
485 BUSERROR(x
, maskw
, 16, v
);
492 wbat_big (memory
, x
, value
, maskb
)
493 unsigned char *memory
;
495 unsigned char *p
= memory
+ (x
& maskb
);
496 BUSERROR(x
, maskb
, 8, value
);
506 rlat_little (memory
, x
, maskl
)
507 unsigned char *memory
;
509 unsigned char *p
= memory
+ ((x
) & maskl
);
510 BUSERROR(x
, maskl
, -32, -1);
512 return (p
[3] << 24) | (p
[2] << 16) | (p
[1] << 8) | p
[0];
516 rwat_little (memory
, x
, maskw
)
517 unsigned char *memory
;
519 unsigned char *p
= memory
+ ((x
) & maskw
);
520 BUSERROR(x
, maskw
, -16, -1);
522 return (p
[1] << 8) | p
[0];
526 rbat_any (memory
, x
, maskb
)
527 unsigned char *memory
;
529 unsigned char *p
= memory
+ ((x
) & maskb
);
530 BUSERROR(x
, maskb
, -8, -1);
536 rlat_big (memory
, x
, maskl
)
537 unsigned char *memory
;
539 unsigned char *p
= memory
+ ((x
) & maskl
);
540 BUSERROR(x
, maskl
, -32, -1);
542 return (p
[0] << 24) | (p
[1] << 16) | (p
[2] << 8) | p
[3];
546 rwat_big (memory
, x
, maskw
)
547 unsigned char *memory
;
549 unsigned char *p
= memory
+ ((x
) & maskw
);
550 BUSERROR(x
, maskw
, -16, -1);
552 return (p
[0] << 8) | p
[1];
555 #define RWAT(x) (little_endian ? rwat_little(memory, x, maskw): rwat_big(memory, x, maskw))
556 #define RLAT(x) (little_endian ? rlat_little(memory, x, maskl): rlat_big(memory, x, maskl))
557 #define RBAT(x) (rbat_any (memory, x, maskb))
558 #define WWAT(x,v) (little_endian ? wwat_little(memory, x, v, maskw): wwat_big(memory, x, v, maskw))
559 #define WLAT(x,v) (little_endian ? wlat_little(memory, x, v, maskl): wlat_big(memory, x, v, maskl))
560 #define WBAT(x,v) (wbat_any (memory, x, v, maskb))
562 #define RUWAT(x) (RWAT(x) & 0xffff)
563 #define RSWAT(x) ((short)(RWAT(x)))
564 #define RSBAT(x) (SEXT(RBAT(x)))
566 #define RDAT(x, n) (do_rdat (memory, (x), (n), (little_endian)))
568 do_rdat (memory
, x
, n
, little_endian
)
580 f0
= rlat_little (memory
, x
+ 0, maskl
);
581 f1
= rlat_little (memory
, x
+ 4, maskl
);
585 f0
= rlat_big (memory
, x
+ 0, maskl
);
586 f1
= rlat_big (memory
, x
+ 4, maskl
);
588 saved_state
.asregs
.fregs
[i
].i
[(j
+ 0)] = f0
;
589 saved_state
.asregs
.fregs
[i
].i
[(j
+ 1)] = f1
;
593 #define WDAT(x, n) (do_wdat (memory, (x), (n), (little_endian)))
595 do_wdat (memory
, x
, n
, little_endian
)
605 f0
= saved_state
.asregs
.fregs
[i
].i
[(j
+ 0)];
606 f1
= saved_state
.asregs
.fregs
[i
].i
[(j
+ 1)];
609 wlat_little (memory
, (x
+ 0), f0
, maskl
);
610 wlat_little (memory
, (x
+ 4), f1
, maskl
);
614 wlat_big (memory
, (x
+ 0), f0
, maskl
);
615 wlat_big (memory
, (x
+ 4), f1
, maskl
);
621 #define MA(n) do { memstalls += (((pc & 3) != 0) ? (n) : ((n) - 1)); } while (0)
623 #define SEXT(x) (((x & 0xff) ^ (~0x7f))+0x80)
624 #define SEXT12(x) (((x & 0xfff) ^ 0x800) - 0x800)
625 #define SEXTW(y) ((int)((short)y))
627 #define Delay_Slot(TEMPPC) iword = RUWAT(TEMPPC); goto top;
631 #define L(x) thislock = x;
632 #define TL(x) if ((x) == prevlock) stalls++;
633 #define TB(x,y) if ((x) == prevlock || (y)==prevlock) stalls++;
635 #if defined(__GO32__) || defined(_WIN32)
636 int sim_memory_size
= 19;
638 int sim_memory_size
= 24;
641 static int sim_profile_size
= 17;
647 #define SMR1 (0x05FFFEC8) /* Channel 1 serial mode register */
648 #define BRR1 (0x05FFFEC9) /* Channel 1 bit rate register */
649 #define SCR1 (0x05FFFECA) /* Channel 1 serial control register */
650 #define TDR1 (0x05FFFECB) /* Channel 1 transmit data register */
651 #define SSR1 (0x05FFFECC) /* Channel 1 serial status register */
652 #define RDR1 (0x05FFFECD) /* Channel 1 receive data register */
654 #define SCI_RDRF 0x40 /* Recieve data register full */
655 #define SCI_TDRE 0x80 /* Transmit data register empty */
658 IOMEM (addr
, write
, value
)
690 return time ((long *) 0);
699 static FILE *profile_file
;
703 unsigned char *memory
;
706 int little_endian
= target_little_endian
;
712 unsigned char *memory
;
715 int little_endian
= target_little_endian
;
727 fwrite (b
, 4, 1, profile_file
);
737 fwrite (b
, 2, 1, profile_file
);
740 /* Turn a pointer in a register into a pointer into real memory. */
746 return (char *) (x
+ saved_state
.asregs
.memory
);
749 /* Simulate a monitor trap, put the result into r0 and errno into r1 */
752 trap (i
, regs
, memory
, maskl
, maskw
, little_endian
)
755 unsigned char *memory
;
760 printf ("%c", regs
[0]);
763 saved_state
.asregs
.exception
= SIGQUIT
;
765 case 3: /* FIXME: for backwards compat, should be removed */
775 #if !defined(__GO32__) && !defined(_WIN32)
780 regs
[0] = execve (ptr (regs
[5]), (char **)ptr (regs
[6]), (char **)ptr (regs
[7]));
783 regs
[0] = execve (ptr (regs
[5]),(char **) ptr (regs
[6]), 0);
792 regs
[0] = pipe (host_fd
);
794 WLAT (buf
, host_fd
[0]);
796 WLAT (buf
, host_fd
[1]);
801 regs
[0] = wait (ptr (regs
[5]));
806 regs
[0] = callback
->read (callback
, regs
[5], ptr (regs
[6]), regs
[7]);
810 regs
[0] = (int)callback
->write_stdout (callback
, ptr(regs
[6]), regs
[7]);
812 regs
[0] = (int)callback
->write (callback
, regs
[5], ptr (regs
[6]), regs
[7]);
815 regs
[0] = callback
->lseek (callback
,regs
[5], regs
[6], regs
[7]);
818 regs
[0] = callback
->close (callback
,regs
[5]);
821 regs
[0] = callback
->open (callback
,ptr (regs
[5]), regs
[6]);
824 /* EXIT - caller can look in r5 to work out the reason */
825 saved_state
.asregs
.exception
= SIGQUIT
;
829 case SYS_stat
: /* added at hmsi */
830 /* stat system call */
832 struct stat host_stat
;
835 regs
[0] = stat (ptr (regs
[5]), &host_stat
);
839 WWAT (buf
, host_stat
.st_dev
);
841 WWAT (buf
, host_stat
.st_ino
);
843 WLAT (buf
, host_stat
.st_mode
);
845 WWAT (buf
, host_stat
.st_nlink
);
847 WWAT (buf
, host_stat
.st_uid
);
849 WWAT (buf
, host_stat
.st_gid
);
851 WWAT (buf
, host_stat
.st_rdev
);
853 WLAT (buf
, host_stat
.st_size
);
855 WLAT (buf
, host_stat
.st_atime
);
859 WLAT (buf
, host_stat
.st_mtime
);
863 WLAT (buf
, host_stat
.st_ctime
);
876 regs
[0] = chown (ptr (regs
[5]), regs
[6], regs
[7]);
880 regs
[0] = chmod (ptr (regs
[5]), regs
[6]);
883 /* Cast the second argument to void *, to avoid type mismatch
884 if a prototype is present. */
885 regs
[0] = utime (ptr (regs
[5]), (void *) ptr (regs
[6]));
890 regs
[1] = callback
->get_errno (callback
);
897 saved_state
.asregs
.exception
= SIGTRAP
;
904 control_c (sig
, code
, scp
, addr
)
910 saved_state
.asregs
.exception
= SIGINT
;
914 div1 (R
, iRn2
, iRn1
/*, T*/)
921 unsigned char old_q
, tmp1
;
924 SET_SR_Q ((unsigned char) ((0x80000000 & R
[iRn1
]) != 0));
926 R
[iRn1
] |= (unsigned long) T
;
936 tmp1
= (R
[iRn1
] > tmp0
);
943 SET_SR_Q ((unsigned char) (tmp1
== 0));
950 tmp1
= (R
[iRn1
] < tmp0
);
954 SET_SR_Q ((unsigned char) (tmp1
== 0));
969 tmp1
= (R
[iRn1
] < tmp0
);
976 SET_SR_Q ((unsigned char) (tmp1
== 0));
983 tmp1
= (R
[iRn1
] > tmp0
);
987 SET_SR_Q ((unsigned char) (tmp1
== 0));
1008 unsigned long RnL
, RnH
;
1009 unsigned long RmL
, RmH
;
1010 unsigned long temp0
, temp1
, temp2
, temp3
;
1011 unsigned long Res2
, Res1
, Res0
;
1014 RnH
= (rn
>> 16) & 0xffff;
1016 RmH
= (rm
>> 16) & 0xffff;
1022 Res1
= temp1
+ temp2
;
1025 temp1
= (Res1
<< 16) & 0xffff0000;
1026 Res0
= temp0
+ temp1
;
1029 Res2
+= ((Res1
>> 16) & 0xffff) + temp3
;
1033 if (rn
& 0x80000000)
1035 if (rm
& 0x80000000)
1044 macw (regs
, memory
, n
, m
)
1046 unsigned char *memory
;
1049 int little_endian
= target_little_endian
;
1051 long prod
, macl
, sum
;
1053 tempm
=RSWAT(regs
[m
]); regs
[m
]+=2;
1054 tempn
=RSWAT(regs
[n
]); regs
[n
]+=2;
1057 prod
= (long)(short) tempm
* (long)(short) tempn
;
1061 if ((~(prod
^ macl
) & (sum
^ prod
)) < 0)
1063 /* MACH's lsb is a sticky overflow bit. */
1065 /* Store the smallest negative number in MACL if prod is
1066 negative, and the largest positive number otherwise. */
1067 sum
= 0x7fffffff + (prod
< 0);
1073 /* Add to MACH the sign extended product, and carry from low sum. */
1074 mach
= MACH
+ (-(prod
< 0)) + ((unsigned long) sum
< prod
);
1075 /* Sign extend at 10:th bit in MACH. */
1076 MACH
= (mach
& 0x1ff) | -(mach
& 0x200);
1081 /* Set the memory size to the power of two provided. */
1088 saved_state
.asregs
.msize
= 1 << power
;
1090 sim_memory_size
= power
;
1092 if (saved_state
.asregs
.memory
)
1094 free (saved_state
.asregs
.memory
);
1097 saved_state
.asregs
.memory
=
1098 (unsigned char *) calloc (64, saved_state
.asregs
.msize
/ 64);
1100 if (!saved_state
.asregs
.memory
)
1103 "Not enough VM for simulation of %d bytes of RAM\n",
1104 saved_state
.asregs
.msize
);
1106 saved_state
.asregs
.msize
= 1;
1107 saved_state
.asregs
.memory
= (unsigned char *) calloc (1, 1);
1114 host_little_endian
= 0;
1115 *(char*)&host_little_endian
= 1;
1116 host_little_endian
&= 1;
1118 if (saved_state
.asregs
.msize
!= 1 << sim_memory_size
)
1120 sim_size (sim_memory_size
);
1123 if (saved_state
.asregs
.profile
&& !profile_file
)
1125 profile_file
= fopen ("gmon.out", "wb");
1126 /* Seek to where to put the call arc data */
1127 nsamples
= (1 << sim_profile_size
);
1129 fseek (profile_file
, nsamples
* 2 + 12, 0);
1133 fprintf (stderr
, "Can't open gmon.out\n");
1137 saved_state
.asregs
.profile_hist
=
1138 (unsigned short *) calloc (64, (nsamples
* sizeof (short) / 64));
1151 p
= saved_state
.asregs
.profile_hist
;
1153 maxpc
= (1 << sim_profile_size
);
1155 fseek (profile_file
, 0L, 0);
1156 swapout (minpc
<< PROFILE_SHIFT
);
1157 swapout (maxpc
<< PROFILE_SHIFT
);
1158 swapout (nsamples
* 2 + 12);
1159 for (i
= 0; i
< nsamples
; i
++)
1160 swapout16 (saved_state
.asregs
.profile_hist
[i
]);
1174 #define MMASKB ((saved_state.asregs.msize -1) & ~0)
1180 saved_state
.asregs
.exception
= SIGINT
;
1185 sim_resume (sd
, step
, siggnal
)
1189 register unsigned int pc
;
1190 register int cycles
= 0;
1191 register int stalls
= 0;
1192 register int memstalls
= 0;
1193 register int insts
= 0;
1194 register int prevlock
;
1195 register int thislock
;
1196 register unsigned int doprofile
;
1197 register int pollcount
= 0;
1198 register int little_endian
= target_little_endian
;
1200 int tick_start
= get_now ();
1202 void (*prev_fpe
) ();
1203 extern unsigned char sh_jump_table0
[];
1205 register unsigned char *jump_table
= sh_jump_table0
;
1207 register int *R
= &(saved_state
.asregs
.regs
[0]);
1211 register int maskb
= ((saved_state
.asregs
.msize
- 1) & ~0);
1212 register int maskw
= ((saved_state
.asregs
.msize
- 1) & ~1);
1213 register int maskl
= ((saved_state
.asregs
.msize
- 1) & ~3);
1214 register unsigned char *memory
;
1215 register unsigned int sbit
= ((unsigned int) 1 << 31);
1217 prev
= signal (SIGINT
, control_c
);
1218 prev_fpe
= signal (SIGFPE
, SIG_IGN
);
1222 memory
= saved_state
.asregs
.memory
;
1226 saved_state
.asregs
.exception
= SIGTRAP
;
1230 saved_state
.asregs
.exception
= 0;
1233 pc
= saved_state
.asregs
.pc
;
1234 PR
= saved_state
.asregs
.pr
;
1235 /*T = GET_SR () & SR_MASK_T;*/
1236 prevlock
= saved_state
.asregs
.prevlock
;
1237 thislock
= saved_state
.asregs
.thislock
;
1238 doprofile
= saved_state
.asregs
.profile
;
1240 /* If profiling not enabled, disable it by asking for
1241 profiles infrequently. */
1247 register unsigned int iword
= RUWAT (pc
);
1248 register unsigned int ult
;
1249 register unsigned int nia
= pc
+ 2;
1260 if (--pollcount
< 0)
1262 pollcount
= POLL_QUIT_INTERVAL
;
1263 if ((*callback
->poll_quit
) != NULL
1264 && (*callback
->poll_quit
) (callback
))
1271 prevlock
= thislock
;
1275 if (cycles
>= doprofile
)
1278 saved_state
.asregs
.cycles
+= doprofile
;
1279 cycles
-= doprofile
;
1280 if (saved_state
.asregs
.profile_hist
)
1282 int n
= pc
>> PROFILE_SHIFT
;
1285 int i
= saved_state
.asregs
.profile_hist
[n
];
1287 saved_state
.asregs
.profile_hist
[n
] = i
+ 1;
1294 while (!saved_state
.asregs
.exception
);
1296 if (saved_state
.asregs
.exception
== SIGILL
1297 || saved_state
.asregs
.exception
== SIGBUS
)
1302 saved_state
.asregs
.ticks
+= get_now () - tick_start
;
1303 saved_state
.asregs
.cycles
+= cycles
;
1304 saved_state
.asregs
.stalls
+= stalls
;
1305 saved_state
.asregs
.memstalls
+= memstalls
;
1306 saved_state
.asregs
.insts
+= insts
;
1307 saved_state
.asregs
.pc
= pc
;
1308 /* restore the T and other cached SR bits */
1310 saved_state
.asregs
.pr
= PR
;
1312 saved_state
.asregs
.prevlock
= prevlock
;
1313 saved_state
.asregs
.thislock
= thislock
;
1320 signal (SIGFPE
, prev_fpe
);
1321 signal (SIGINT
, prev
);
1325 sim_write (sd
, addr
, buffer
, size
)
1328 unsigned char *buffer
;
1335 for (i
= 0; i
< size
; i
++)
1337 saved_state
.asregs
.memory
[MMASKB
& (addr
+ i
)] = buffer
[i
];
1343 sim_read (sd
, addr
, buffer
, size
)
1346 unsigned char *buffer
;
1353 for (i
= 0; i
< size
; i
++)
1355 buffer
[i
] = saved_state
.asregs
.memory
[MMASKB
& (addr
+ i
)];
1360 /* We have to add one to RN as an index into asints because of the padding
1361 added at the start of asregs. */
1363 sim_store_register (sd
, rn
, memory
, length
)
1366 unsigned char *memory
;
1371 little_endian
= target_little_endian
;
1372 if (&saved_state
.asints
[rn
+1]
1373 == &saved_state
.asregs
.fpscr
)
1374 set_fpscr1 (RLAT(0));
1376 saved_state
.asints
[rn
+1] = RLAT(0);
1381 sim_fetch_register (sd
, rn
, memory
, length
)
1384 unsigned char *memory
;
1389 little_endian
= target_little_endian
;
1390 WLAT (0, saved_state
.asints
[rn
+1]);
1402 sim_stop_reason (sd
, reason
, sigrc
)
1404 enum sim_stop
*reason
;
1407 /* The SH simulator uses SIGQUIT to indicate that the program has
1408 exited, so we must check for it here and translate it to exit. */
1409 if (saved_state
.asregs
.exception
== SIGQUIT
)
1411 *reason
= sim_exited
;
1412 *sigrc
= saved_state
.asregs
.regs
[5];
1416 *reason
= sim_stopped
;
1417 *sigrc
= saved_state
.asregs
.exception
;
1422 sim_info (sd
, verbose
)
1426 double timetaken
= (double) saved_state
.asregs
.ticks
/ (double) now_persec ();
1427 double virttime
= saved_state
.asregs
.cycles
/ 36.0e6
;
1429 callback
->printf_filtered (callback
, "\n\n# instructions executed %10d\n",
1430 saved_state
.asregs
.insts
);
1431 callback
->printf_filtered (callback
, "# cycles %10d\n",
1432 saved_state
.asregs
.cycles
);
1433 callback
->printf_filtered (callback
, "# pipeline stalls %10d\n",
1434 saved_state
.asregs
.stalls
);
1435 callback
->printf_filtered (callback
, "# misaligned load/store %10d\n",
1436 saved_state
.asregs
.memstalls
);
1437 callback
->printf_filtered (callback
, "# real time taken %10.4f\n",
1439 callback
->printf_filtered (callback
, "# virtual time taken %10.4f\n",
1441 callback
->printf_filtered (callback
, "# profiling size %10d\n",
1443 callback
->printf_filtered (callback
, "# profiling frequency %10d\n",
1444 saved_state
.asregs
.profile
);
1445 callback
->printf_filtered (callback
, "# profile maxpc %10x\n",
1446 (1 << sim_profile_size
) << PROFILE_SHIFT
);
1450 callback
->printf_filtered (callback
, "# cycles/second %10d\n",
1451 (int) (saved_state
.asregs
.cycles
/ timetaken
));
1452 callback
->printf_filtered (callback
, "# simulation ratio %10.4f\n",
1453 virttime
/ timetaken
);
1461 saved_state
.asregs
.profile
= n
;
1465 sim_set_profile_size (n
)
1468 sim_profile_size
= n
;
1472 sim_open (kind
, cb
, abfd
, argv
)
1485 for (p
= argv
+ 1; *p
!= NULL
; ++p
)
1487 if (strcmp (*p
, "-E") == 0)
1492 /* FIXME: This doesn't use stderr, but then the rest of the
1493 file doesn't either. */
1494 callback
->printf_filtered (callback
, "Missing argument to `-E'.\n");
1497 target_little_endian
= strcmp (*p
, "big") != 0;
1500 else if (isdigit (**p
))
1501 parse_and_set_memory_size (*p
);
1504 if (abfd
!= NULL
&& ! endian_set
)
1505 target_little_endian
= ! bfd_big_endian (abfd
);
1507 /* fudge our descriptor for now */
1508 return (SIM_DESC
) 1;
1512 parse_and_set_memory_size (str
)
1517 n
= strtol (str
, NULL
, 10);
1518 if (n
> 0 && n
<= 24)
1519 sim_memory_size
= n
;
1521 callback
->printf_filtered (callback
, "Bad memory size %d; must be 1 to 24, inclusive\n", n
);
1525 sim_close (sd
, quitting
)
1533 sim_load (sd
, prog
, abfd
, from_tty
)
1539 extern bfd
*sim_load_file (); /* ??? Don't know where this should live. */
1542 prog_bfd
= sim_load_file (sd
, myname
, callback
, prog
, abfd
,
1543 sim_kind
== SIM_OPEN_DEBUG
,
1545 if (prog_bfd
== NULL
)
1548 bfd_close (prog_bfd
);
1553 sim_create_inferior (sd
, prog_bfd
, argv
, env
)
1555 struct _bfd
*prog_bfd
;
1559 /* clear the registers */
1560 memset (&saved_state
, 0,
1561 (char*)&saved_state
.asregs
.end_of_registers
- (char*)&saved_state
);
1563 if (prog_bfd
!= NULL
)
1564 saved_state
.asregs
.pc
= bfd_get_start_address (prog_bfd
);
1569 sim_do_command (sd
, cmd
)
1573 char *sms_cmd
= "set-memory-size";
1576 if (cmd
== NULL
|| *cmd
== '\0')
1581 cmdsize
= strlen (sms_cmd
);
1582 if (strncmp (cmd
, sms_cmd
, cmdsize
) == 0 && strchr (" \t", cmd
[cmdsize
]) != NULL
)
1584 parse_and_set_memory_size (cmd
+ cmdsize
+ 1);
1586 else if (strcmp (cmd
, "help") == 0)
1588 (callback
->printf_filtered
) (callback
, "List of SH simulator commands:\n\n");
1589 (callback
->printf_filtered
) (callback
, "set-memory-size <n> -- Set the number of address bits to use\n");
1590 (callback
->printf_filtered
) (callback
, "\n");
1594 (callback
->printf_filtered
) (callback
, "Error: \"%s\" is not a valid SH simulator command.\n", cmd
);
1599 sim_set_callbacks (p
)