📄 interp.c
字号:
regs[0] = -1; break; case SYS_time: regs[0] = get_now (); break; default: regs[0] = -1; break; } regs[1] = callback->get_errno (callback); errno = perrno; } break; case 0xc3: case 255: raise_exception (SIGTRAP); if (i == 0xc3) return -2; break; } return 0;}voidcontrol_c (sig, code, scp, addr) int sig; int code; char *scp; char *addr;{ raise_exception (SIGINT);}static intdiv1 (R, iRn2, iRn1/*, T*/) int *R; int iRn1; int iRn2; /* int T;*/{ unsigned long tmp0; unsigned char old_q, tmp1; old_q = Q; SET_SR_Q ((unsigned char) ((0x80000000 & R[iRn1]) != 0)); R[iRn1] <<= 1; R[iRn1] |= (unsigned long) T; switch (old_q) { case 0: switch (M) { case 0: tmp0 = R[iRn1]; R[iRn1] -= R[iRn2]; tmp1 = (R[iRn1] > tmp0); switch (Q) { case 0: SET_SR_Q (tmp1); break; case 1: SET_SR_Q ((unsigned char) (tmp1 == 0)); break; } break; case 1: tmp0 = R[iRn1]; R[iRn1] += R[iRn2]; tmp1 = (R[iRn1] < tmp0); switch (Q) { case 0: SET_SR_Q ((unsigned char) (tmp1 == 0)); break; case 1: SET_SR_Q (tmp1); break; } break; } break; case 1: switch (M) { case 0: tmp0 = R[iRn1]; R[iRn1] += R[iRn2]; tmp1 = (R[iRn1] < tmp0); switch (Q) { case 0: SET_SR_Q (tmp1); break; case 1: SET_SR_Q ((unsigned char) (tmp1 == 0)); break; } break; case 1: tmp0 = R[iRn1]; R[iRn1] -= R[iRn2]; tmp1 = (R[iRn1] > tmp0); switch (Q) { case 0: SET_SR_Q ((unsigned char) (tmp1 == 0)); break; case 1: SET_SR_Q (tmp1); break; } break; } break; } /*T = (Q == M);*/ SET_SR_T (Q == M); /*return T;*/}static voiddmul (sign, rm, rn) int sign; unsigned int rm; unsigned int rn;{ unsigned long RnL, RnH; unsigned long RmL, RmH; unsigned long temp0, temp1, temp2, temp3; unsigned long Res2, Res1, Res0; RnL = rn & 0xffff; RnH = (rn >> 16) & 0xffff; RmL = rm & 0xffff; RmH = (rm >> 16) & 0xffff; temp0 = RmL * RnL; temp1 = RmH * RnL; temp2 = RmL * RnH; temp3 = RmH * RnH; Res2 = 0; Res1 = temp1 + temp2; if (Res1 < temp1) Res2 += 0x00010000; temp1 = (Res1 << 16) & 0xffff0000; Res0 = temp0 + temp1; if (Res0 < temp0) Res2 += 1; Res2 += ((Res1 >> 16) & 0xffff) + temp3; if (sign) { if (rn & 0x80000000) Res2 -= rm; if (rm & 0x80000000) Res2 -= rn; } MACH = Res2; MACL = Res0;}static voidmacw (regs, memory, n, m, endianw) int *regs; unsigned char *memory; int m, n; int endianw;{ long tempm, tempn; long prod, macl, sum; tempm=RSWAT(regs[m]); regs[m]+=2; tempn=RSWAT(regs[n]); regs[n]+=2; macl = MACL; prod = (long)(short) tempm * (long)(short) tempn; sum = prod + macl; if (S) { if ((~(prod ^ macl) & (sum ^ prod)) < 0) { /* MACH's lsb is a sticky overflow bit. */ MACH |= 1; /* Store the smallest negative number in MACL if prod is negative, and the largest positive number otherwise. */ sum = 0x7fffffff + (prod < 0); } } else { long mach; /* Add to MACH the sign extended product, and carry from low sum. */ mach = MACH + (-(prod < 0)) + ((unsigned long) sum < prod); /* Sign extend at 10:th bit in MACH. */ MACH = (mach & 0x1ff) | -(mach & 0x200); } MACL = sum;}static struct loop_boundsget_loop_bounds (rs, re, memory, mem_end, maskw, endianw) int rs, re; unsigned char *memory, *mem_end; int maskw, endianw;{ struct loop_bounds loop; if (SR_RC) { if (RS >= RE) { loop.start = PT2H (RE - 4); SKIP_INSN (loop.start); loop.end = loop.start; if (RS - RE == 0) SKIP_INSN (loop.end); if (RS - RE <= 2) SKIP_INSN (loop.end); SKIP_INSN (loop.end); } else { loop.start = PT2H (RS); loop.end = PT2H (RE - 4); SKIP_INSN (loop.end); SKIP_INSN (loop.end); SKIP_INSN (loop.end); SKIP_INSN (loop.end); } if (loop.end >= mem_end) loop.end = PT2H (0); } else loop.end = PT2H (0); return loop;}static voidppi_insn();#include "ppi.c"/* Set the memory size to the power of two provided. */voidsim_size (power) int power;{ saved_state.asregs.msize = 1 << power; sim_memory_size = power; if (saved_state.asregs.memory) { free (saved_state.asregs.memory); } saved_state.asregs.memory = (unsigned char *) calloc (64, saved_state.asregs.msize / 64); if (!saved_state.asregs.memory) { fprintf (stderr, "Not enough VM for simulation of %d bytes of RAM\n", saved_state.asregs.msize); saved_state.asregs.msize = 1; saved_state.asregs.memory = (unsigned char *) calloc (1, 1); }}static voidinit_dsp (abfd) struct bfd *abfd;{ int was_dsp = target_dsp; unsigned long mach = bfd_get_mach (abfd); if (mach == bfd_mach_sh_dsp || mach == bfd_mach_sh3_dsp) { int ram_area_size, xram_start, yram_start; int new_select; target_dsp = 1; if (mach == bfd_mach_sh_dsp) { /* SH7410 (orig. sh-sdp): 4KB each for X & Y memory; On-chip X RAM 0x0800f000-0x0800ffff On-chip Y RAM 0x0801f000-0x0801ffff */ xram_start = 0x0800f000; ram_area_size = 0x1000; } if (mach == bfd_mach_sh3_dsp) { /* SH7612: 8KB each for X & Y memory; On-chip X RAM 0x1000e000-0x1000ffff On-chip Y RAM 0x1001e000-0x1001ffff */ xram_start = 0x1000e000; ram_area_size = 0x2000; } yram_start = xram_start + 0x10000; new_select = ~(ram_area_size - 1); if (saved_state.asregs.xyram_select != new_select) { saved_state.asregs.xyram_select = new_select; free (saved_state.asregs.xmem); free (saved_state.asregs.ymem); saved_state.asregs.xmem = (unsigned char *) calloc (1, ram_area_size); saved_state.asregs.ymem = (unsigned char *) calloc (1, ram_area_size); /* Disable use of X / Y mmeory if not allocated. */ if (! saved_state.asregs.xmem || ! saved_state.asregs.ymem) { saved_state.asregs.xyram_select = 0; if (saved_state.asregs.xmem) free (saved_state.asregs.xmem); if (saved_state.asregs.ymem) free (saved_state.asregs.ymem); } } saved_state.asregs.xram_start = xram_start; saved_state.asregs.yram_start = yram_start; saved_state.asregs.xmem_offset = saved_state.asregs.xmem - xram_start; saved_state.asregs.ymem_offset = saved_state.asregs.ymem - yram_start; } else { target_dsp = 0; if (saved_state.asregs.xyram_select) { saved_state.asregs.xyram_select = 0; free (saved_state.asregs.xmem); free (saved_state.asregs.ymem); } } if (! saved_state.asregs.xyram_select) { saved_state.asregs.xram_start = 1; saved_state.asregs.yram_start = 1; } if (target_dsp != was_dsp) { int i, tmp; for (i = sizeof sh_dsp_table - 1; i >= 0; i--) { tmp = sh_jump_table[0xf000 + i]; sh_jump_table[0xf000 + i] = sh_dsp_table[i]; sh_dsp_table[i] = tmp; } }}static voidinit_pointers (){ host_little_endian = 0; *(char*)&host_little_endian = 1; host_little_endian &= 1; if (saved_state.asregs.msize != 1 << sim_memory_size) { sim_size (sim_memory_size); } if (saved_state.asregs.profile && !profile_file) { profile_file = fopen ("gmon.out", "wb"); /* Seek to where to put the call arc data */ nsamples = (1 << sim_profile_size); fseek (profile_file, nsamples * 2 + 12, 0); if (!profile_file) { fprintf (stderr, "Can't open gmon.out\n"); } else { saved_state.asregs.profile_hist = (unsigned short *) calloc (64, (nsamples * sizeof (short) / 64)); } }}static voiddump_profile (){ unsigned int minpc; unsigned int maxpc; unsigned short *p; int i; p = saved_state.asregs.profile_hist; minpc = 0; maxpc = (1 << sim_profile_size); fseek (profile_file, 0L, 0); swapout (minpc << PROFILE_SHIFT); swapout (maxpc << PROFILE_SHIFT); swapout (nsamples * 2 + 12); for (i = 0; i < nsamples; i++) swapout16 (saved_state.asregs.profile_hist[i]);}static voidgotcall (from, to) int from; int to;{ swapout (from); swapout (to); swapout (1);}#define MMASKB ((saved_state.asregs.msize -1) & ~0)intsim_stop (sd) SIM_DESC sd;{ raise_exception (SIGINT); return 1;}voidsim_resume (sd, step, siggnal) SIM_DESC sd; int step, siggnal;{ register unsigned char *insn_ptr; unsigned char *mem_end; struct loop_bounds loop; register int cycles = 0; register int stalls = 0; register int memstalls = 0; register int insts = 0; register int prevlock; register int thislock; register unsigned int doprofile; register int pollcount = 0; /* endianw is used for every insn fetch, hence it makes sense to cache it. endianb is used less often. */ register int endianw = global_endianw; int tick_start = get_now (); void (*prev) (); void (*prev_fpe) (); register unsigned char *jump_table = sh_jump_table; register int *R = &(saved_state.asregs.regs[0]); /*register int T;*/#ifndef PR register int PR;#endif register int maskb = ~((saved_state.asregs.msize - 1) & ~0); register int maskw = ~((saved_state.asregs.msize - 1) & ~1); register int maskl = ~((saved_state.asregs.msize - 1) & ~3); register unsigned char *memory; register unsigned int sbit = ((unsigned int) 1 << 31); prev = signal (SIGINT, control_c); prev_fpe = signal (SIGFPE, SIG_IGN); init_pointers (); saved_state.asregs.exception = 0; memory = saved_state.asregs.memory; mem_end = memory + saved_state.asregs.msize; loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw); insn_ptr = PT2H (saved_state.asregs.pc); CHECK_INSN_PTR (insn_ptr);#ifndef PR PR = saved_state.asregs.sregs.named.pr;#endif /*T = GET_SR () & SR_MASK_T;*/ prevlock = saved_state.asregs.prevlock; thislock = saved_state.asregs.thislock; doprofile = saved_state.asregs.profile; /* If profiling not enabled, disable it by asking for profiles infrequently. */ if (doprofile == 0) doprofile = ~0; loop: if (step && insn_ptr < saved_state.asregs.insn_end) { if (saved_state.asregs.exception) /* This can happen if we've already been single-stepping and encountered a loop end. */ saved_state.asregs.insn_end = insn_ptr; else { saved_state.asregs.exception = SIGTRAP; saved_state.asregs.insn_end = insn_ptr + 2; } } while (insn_ptr < saved_state.asregs.insn_end) { register unsigned int iword = RIAT (insn_ptr); register unsigned int ult; register unsigned char *nip = insn_ptr + 2;#ifndef ACE_FAST insts++;#endif top:#include "code.c" insn_ptr = nip; if (--pollcount < 0) { pollcount = POLL_QUIT_INTERVAL; if ((*callback->poll_quit) != NULL && (*callback->poll_quit) (callback)) { sim_stop (sd); } }#ifndef ACE_FAST prevlock = thislock; thislock = 30; cycles++; if (cycles >= doprofile) { saved_state.asregs.cycles += doprofile; cycles -= doprofile; if (saved_state.asregs.profile_hist) { int n = PH2T (insn_ptr) >> PROFILE_SHIFT; if (n < nsamples) { int i = saved_state.asregs.profile_hist[n]; if (i < 65000) saved_state.asregs.profile_hist[n] = i + 1; } } }#endif } if (saved_state.asregs.insn_end == loop.end) { saved_state.asregs.cregs.named.sr += SR_RC_INCREMENT; if (SR_RC) insn_ptr = loop.start; else { saved_state.asregs.insn_end = mem_end; loop.end = PT2H (0); } goto loop;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -