📄 interp.c
字号:
#define MOD_ME DSP_GRD (17)#define MOD_DELTA DSP_GRD (18)#define FP_OP(n, OP, m) \{ \ if (FPSCR_PR) \ { \ if (((n) & 1) || ((m) & 1)) \ RAISE_EXCEPTION (SIGILL); \ else \ SET_DR (n, (DR (n) OP DR (m))); \ } \ else \ SET_FR (n, (FR (n) OP FR (m))); \} while (0)#define FP_UNARY(n, OP) \{ \ if (FPSCR_PR) \ { \ if ((n) & 1) \ RAISE_EXCEPTION (SIGILL); \ else \ SET_DR (n, (OP (DR (n)))); \ } \ else \ SET_FR (n, (OP (FR (n)))); \} while (0)#define FP_CMP(n, OP, m) \{ \ if (FPSCR_PR) \ { \ if (((n) & 1) || ((m) & 1)) \ RAISE_EXCEPTION (SIGILL); \ else \ SET_SR_T (DR (n) OP DR (m)); \ } \ else \ SET_SR_T (FR (n) OP FR (m)); \} while (0)static voidset_sr (new_sr) int new_sr;{ /* do we need to swap banks */ int old_gpr = SR_MD && SR_RB; int new_gpr = (new_sr & SR_MASK_MD) && (new_sr & SR_MASK_RB); if (old_gpr != new_gpr) { int i, tmp; for (i = 0; i < 8; i++) { tmp = saved_state.asregs.cregs.named.bank[i]; saved_state.asregs.cregs.named.bank[i] = saved_state.asregs.regs[i]; saved_state.asregs.regs[i] = tmp; } } saved_state.asregs.cregs.named.sr = new_sr; SET_MOD (MOD);}static void INLINE wlat_fast (memory, x, value, maskl) unsigned char *memory;{ int v = value; unsigned int *p = (unsigned int *) (memory + x); WRITE_BUSERROR (x, maskl, v, process_wlat_addr); *p = v;}static void INLINE wwat_fast (memory, x, value, maskw, endianw) unsigned char *memory;{ int v = value; unsigned short *p = (unsigned short *) (memory + (x ^ endianw)); WRITE_BUSERROR (x, maskw, v, process_wwat_addr); *p = v;}static void INLINE wbat_fast (memory, x, value, maskb) unsigned char *memory;{ unsigned char *p = memory + (x ^ endianb); WRITE_BUSERROR (x, maskb, value, process_wbat_addr); p[0] = value;}/* Read functions */static int INLINE rlat_fast (memory, x, maskl) unsigned char *memory;{ unsigned int *p = (unsigned int *) (memory + x); READ_BUSERROR (x, maskl, process_rlat_addr); return *p;}static int INLINE rwat_fast (memory, x, maskw, endianw) unsigned char *memory; int x, maskw, endianw;{ unsigned short *p = (unsigned short *) (memory + (x ^ endianw)); READ_BUSERROR (x, maskw, process_rwat_addr); return *p;}static int INLINE riat_fast (insn_ptr, endianw) unsigned char *insn_ptr;{ unsigned short *p = (unsigned short *) ((size_t) insn_ptr ^ endianw); return *p;}static int INLINE rbat_fast (memory, x, maskb) unsigned char *memory;{ unsigned char *p = memory + (x ^ endianb); READ_BUSERROR (x, maskb, process_rbat_addr); return *p;}#define RWAT(x) (rwat_fast (memory, x, maskw, endianw))#define RLAT(x) (rlat_fast (memory, x, maskl))#define RBAT(x) (rbat_fast (memory, x, maskb))#define RIAT(p) (riat_fast ((p), endianw))#define WWAT(x,v) (wwat_fast (memory, x, v, maskw, endianw))#define WLAT(x,v) (wlat_fast (memory, x, v, maskl))#define WBAT(x,v) (wbat_fast (memory, x, v, maskb))#define RUWAT(x) (RWAT (x) & 0xffff)#define RSWAT(x) ((short) (RWAT (x)))#define RSLAT(x) ((long) (RLAT (x)))#define RSBAT(x) (SEXT (RBAT (x)))#define RDAT(x, n) (do_rdat (memory, (x), (n), (maskl)))static intdo_rdat (memory, x, n, maskl) char *memory; int x; int n; int maskl;{ int f0; int f1; int i = (n & 1); int j = (n & ~1); f0 = rlat_fast (memory, x + 0, maskl); f1 = rlat_fast (memory, x + 4, maskl); saved_state.asregs.fregs[i].i[(j + 0)] = f0; saved_state.asregs.fregs[i].i[(j + 1)] = f1; return 0;}#define WDAT(x, n) (do_wdat (memory, (x), (n), (maskl)))static intdo_wdat (memory, x, n, maskl) char *memory; int x; int n; int maskl;{ int f0; int f1; int i = (n & 1); int j = (n & ~1); f0 = saved_state.asregs.fregs[i].i[(j + 0)]; f1 = saved_state.asregs.fregs[i].i[(j + 1)]; wlat_fast (memory, (x + 0), f0, maskl); wlat_fast (memory, (x + 4), f1, maskl); return 0;}static voidprocess_wlat_addr (addr, value) int addr; int value;{ unsigned int *ptr; PROCESS_SPECIAL_ADDRESS (addr, endianb, ptr, 32, 3, value, ); *ptr = value;}static voidprocess_wwat_addr (addr, value) int addr; int value;{ unsigned short *ptr; PROCESS_SPECIAL_ADDRESS (addr, endianb, ptr, 16, 1, value, ); *ptr = value;}static voidprocess_wbat_addr (addr, value) int addr; int value;{ unsigned char *ptr; PROCESS_SPECIAL_ADDRESS (addr, endianb, ptr, 8, 0, value, ); *ptr = value;}static intprocess_rlat_addr (addr) int addr;{ unsigned char *ptr; PROCESS_SPECIAL_ADDRESS (addr, endianb, ptr, -32, 3, -1, 0); return *ptr;}static intprocess_rwat_addr (addr) int addr;{ unsigned char *ptr; PROCESS_SPECIAL_ADDRESS (addr, endianb, ptr, -16, 1, -1, 0); return *ptr;}static intprocess_rbat_addr (addr) int addr;{ unsigned char *ptr; PROCESS_SPECIAL_ADDRESS (addr, endianb, ptr, -8, 0, -1, 0); return *ptr;}#define SEXT(x) (((x & 0xff) ^ (~0x7f))+0x80)#define SEXT12(x) (((x & 0xfff) ^ 0x800) - 0x800)#define SEXTW(y) ((int) ((short) y))#if 0#define SEXT32(x) ((int) ((x & 0xffffffff) ^ 0x80000000U) - 0x7fffffff - 1)#else#define SEXT32(x) ((int) (x))#endif#define SIGN32(x) (SEXT32 (x) >> 31)/* convert pointer from target to host value. */#define PT2H(x) ((x) + memory)/* convert pointer from host to target value. */#define PH2T(x) ((x) - memory)#define SKIP_INSN(p) ((p) += ((RIAT (p) & 0xfc00) == 0xf800 ? 4 : 2))#define SET_NIP(x) nip = (x); CHECK_INSN_PTR (nip);static int in_delay_slot = 0;#define Delay_Slot(TEMPPC) iword = RIAT (TEMPPC); in_delay_slot = 1; goto top;#define CHECK_INSN_PTR(p) \do { \ if (saved_state.asregs.exception || PH2T (p) & maskw) \ saved_state.asregs.insn_end = 0; \ else if (p < loop.end) \ saved_state.asregs.insn_end = loop.end; \ else \ saved_state.asregs.insn_end = mem_end; \} while (0)#ifdef ACE_FAST#define MA(n)#define L(x)#define TL(x)#define TB(x)#else#define MA(n) \ do { memstalls += ((((int) PC & 3) != 0) ? (n) : ((n) - 1)); } while (0)#define L(x) thislock = x;#define TL(x) if ((x) == prevlock) stalls++;#define TB(x,y) if ((x) == prevlock || (y) == prevlock) stalls++;#endif#if defined(__GO32__) || defined(_WIN32)int sim_memory_size = 19;#elseint sim_memory_size = 24;#endifstatic int sim_profile_size = 17;static int nsamples;#undef TB#define TB(x,y)#define SMR1 (0x05FFFEC8) /* Channel 1 serial mode register */#define BRR1 (0x05FFFEC9) /* Channel 1 bit rate register */#define SCR1 (0x05FFFECA) /* Channel 1 serial control register */#define TDR1 (0x05FFFECB) /* Channel 1 transmit data register */#define SSR1 (0x05FFFECC) /* Channel 1 serial status register */#define RDR1 (0x05FFFECD) /* Channel 1 receive data register */#define SCI_RDRF 0x40 /* Recieve data register full */#define SCI_TDRE 0x80 /* Transmit data register empty */static intIOMEM (addr, write, value) int addr; int write; int value;{ if (write) { switch (addr) { case TDR1: if (value != '\r') { putchar (value); fflush (stdout); } break; } } else { switch (addr) { case RDR1: return getchar (); } } return 0;}static intget_now (){ return time ((long *) 0);}static intnow_persec (){ return 1;}static FILE *profile_file;static unsigned INLINEswap (n) unsigned n;{ if (endianb) n = (n << 24 | (n & 0xff00) << 8 | (n & 0xff0000) >> 8 | (n & 0xff000000) >> 24); return n;}static unsigned short INLINEswap16 (n) unsigned short n;{ if (endianb) n = n << 8 | (n & 0xff00) >> 8; return n;}static voidswapout (n) int n;{ if (profile_file) { union { char b[4]; int n; } u; u.n = swap (n); fwrite (u.b, 4, 1, profile_file); }}static voidswapout16 (n) int n;{ union { char b[4]; int n; } u; u.n = swap16 (n); fwrite (u.b, 2, 1, profile_file);}/* Turn a pointer in a register into a pointer into real memory. */static char *ptr (x) int x;{ return (char *) (x + saved_state.asregs.memory);}static intstrswaplen (str) int str;{ unsigned char *memory = saved_state.asregs.memory; int start, end; int endian = endianb; if (! endian) return 0; end = str; for (end = str; memory[end ^ endian]; end++) ; return end - str;}static voidstrnswap (str, len) int str; int len;{ int *start, *end; if (! endianb || ! len) return; start = (int *) ptr (str & ~3); end = (int *) ptr (str + len); do { int old = *start; *start = (old << 24 | (old & 0xff00) << 8 | (old & 0xff0000) >> 8 | (old & 0xff000000) >> 24); start++; } while (start < end);}/* Simulate a monitor trap, put the result into r0 and errno into r1 return offset by which to adjust pc. */static inttrap (i, regs, insn_ptr, memory, maskl, maskw, endianw) int i; int *regs; unsigned char *insn_ptr; unsigned char *memory;{ switch (i) { case 1: printf ("%c", regs[0]); break; case 2: raise_exception (SIGQUIT); break; case 3: /* FIXME: for backwards compat, should be removed */ case 33: { unsigned int countp = * (unsigned int *) (insn_ptr + 4); WLAT (countp, RLAT (countp) + 1); return 6; } case 34: { extern int errno; int perrno = errno; errno = 0; switch (regs[4]) {#if !defined(__GO32__) && !defined(_WIN32) case SYS_fork: regs[0] = fork (); break;/* This would work only if endianness matched between host and target. Besides, it's quite dangerous. */#if 0 case SYS_execve: regs[0] = execve (ptr (regs[5]), (char **) ptr (regs[6]), (char **) ptr (regs[7])); break; case SYS_execv: regs[0] = execve (ptr (regs[5]), (char **) ptr (regs[6]), 0); break;#endif case SYS_pipe: { regs[0] = (BUSERROR (regs[5], maskl) ? -EINVAL : pipe ((int *) ptr (regs[5]))); } break; case SYS_wait: regs[0] = wait (ptr (regs[5])); break;#endif /* !defined(__GO32__) && !defined(_WIN32) */ case SYS_read: strnswap (regs[6], regs[7]); regs[0] = callback->read (callback, regs[5], ptr (regs[6]), regs[7]); strnswap (regs[6], regs[7]); break; case SYS_write: strnswap (regs[6], regs[7]); if (regs[5] == 1) regs[0] = (int) callback->write_stdout (callback, ptr (regs[6]), regs[7]); else regs[0] = (int) callback->write (callback, regs[5], ptr (regs[6]), regs[7]); strnswap (regs[6], regs[7]); break; case SYS_lseek: regs[0] = callback->lseek (callback,regs[5], regs[6], regs[7]); break; case SYS_close: regs[0] = callback->close (callback,regs[5]); break; case SYS_open: { int len = strswaplen (regs[5]); strnswap (regs[5], len); regs[0] = callback->open (callback, ptr (regs[5]), regs[6]); strnswap (regs[5], len); break; } case SYS_exit: /* EXIT - caller can look in r5 to work out the reason */ raise_exception (SIGQUIT); regs[0] = regs[5];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -