📄 interp.c
字号:
{ /* Don't let him close it. */ cpu.gr[RET1] = (-1); } break; case 9: a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]); a[1] = (unsigned long) (cpu.mem + cpu.gr[PARM2]); cpu.gr[RET1] = link ((char *) a[0], (char *) a[1]); break; case 10: a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]); cpu.gr[RET1] = callback->unlink (callback, (char *) a[0]); break; case 13: /* handle time(0) vs time(&var) */ a[0] = (unsigned long) (cpu.gr[PARM1]); if (a[0]) a[0] += (unsigned long) cpu.mem; cpu.gr[RET1] = callback->time (callback, (time_t *) a[0]); break; case 19: a[0] = (unsigned long) (cpu.gr[PARM1]); a[1] = (unsigned long) (cpu.gr[PARM2]); a[2] = (unsigned long) (cpu.gr[PARM3]); cpu.gr[RET1] = callback->lseek (callback, a[0], a[1], a[2]); break; case 33: a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]); a[1] = (unsigned long) (cpu.gr[PARM2]); cpu.gr[RET1] = access ((char *) a[0], a[1]); break; case 43: a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]);#if 0 cpu.gr[RET1] = times ((char *)a[0]);#else { /* Give him simulated cycles for utime and an instruction count for stime. */ struct tms { time_t tms_utime; time_t tms_stime; time_t tms_cutime; time_t tms_cstime; } t; t.tms_utime = cpu.asregs.cycles; t.tms_stime = cpu.asregs.insts; t.tms_cutime = t.tms_utime; t.tms_cstime = t.tms_stime; memcpy ((struct tms *)(a[0]), &t, sizeof (t)); cpu.gr[RET1] = cpu.asregs.cycles; }#endif break; case 69: a[0] = (unsigned long) (cpu.gr[PARM1]); cpu.gr[RET1] = int_sbrk (a[0]); break; default: if (issue_messages) fprintf (stderr, "WARNING: sys call %d unimplemented\n", cpu.gr[TRAPCODE]); break; }}static voidprocess_stub (what) int what;{ /* These values should match those in libgloss/mcore/syscalls.s. */ switch (what) { case 3: /* _read */ case 4: /* _write */ case 5: /* _open */ case 6: /* _close */ case 10: /* _unlink */ case 19: /* _lseek */ case 43: /* _times */ cpu.gr [TRAPCODE] = what; handle_trap1 (); break; default: if (issue_messages) fprintf (stderr, "Unhandled stub opcode: %d\n", what); break; }}static voidutil (what) unsigned what;{ switch (what) { case 0: /* exit */ cpu.asregs.exception = SIGQUIT; break; case 1: /* printf */ { unsigned long a[6]; unsigned char *s; int i; a[0] = (unsigned long)(cpu.mem + cpu.gr[PARM1]); for (s = (unsigned char *)a[0], i = 1 ; *s && i < 6 ; s++) { if (*s == '%') { if (*++s == 's') a[i] = (unsigned long)(cpu.mem + cpu.gr[PARM1+i]); else a[i] = cpu.gr[i+PARM1]; i++; } } cpu.gr[RET1] = printf ((char *)a[0], a[1], a[2], a[3], a[4], a[5]); } break; case 2: /* scanf */ if (issue_messages) fprintf (stderr, "WARNING: scanf unimplemented\n"); break; case 3: /* utime */ cpu.gr[RET1] = cpu.asregs.insts; break; case 0xFF: process_stub (cpu.gr[1]); break; default: if (issue_messages) fprintf (stderr, "Unhandled util code: %x\n", what); break; }} /* For figuring out whether we carried; addc/subc use this. */static intiu_carry (a, b, cin) unsigned long a; unsigned long b; int cin;{ unsigned long x; x = (a & 0xffff) + (b & 0xffff) + cin; x = (x >> 16) + (a >> 16) + (b >> 16); x >>= 16; return (x != 0);}#define WATCHFUNCTIONS 1#ifdef WATCHFUNCTIONS#define MAXWL 80word WL[MAXWL];char * WLstr[MAXWL];int ENDWL=0;int WLincyc;int WLcyc[MAXWL];int WLcnts[MAXWL];int WLmax[MAXWL];int WLmin[MAXWL];word WLendpc;int WLbcyc;int WLW;#endif#define RD (inst & 0xF)#define RS ((inst >> 4) & 0xF)#define RX ((inst >> 8) & 0xF)#define IMM5 ((inst >> 4) & 0x1F)#define IMM4 ((inst) & 0xF)static int tracing = 0;voidsim_resume (sd, step, siggnal) SIM_DESC sd; int step, siggnal;{ int needfetch; word ibuf; word pc; unsigned short inst; void (* sigsave)(); int memops; int bonus_cycles; int insts; int w; int cycs; word WLhash; sigsave = signal (SIGINT, interrupt); cpu.asregs.exception = step ? SIGTRAP: 0; pc = cpu.asregs.pc; /* Fetch the initial instructions that we'll decode. */ ibuf = rlat (pc & 0xFFFFFFFC); needfetch = 0; memops = 0; bonus_cycles = 0; insts = 0; /* make our register set point to the right place */ if (SR_AF ()) cpu.asregs.active_gregs = & cpu.asregs.alt_gregs[0]; else cpu.asregs.active_gregs = & cpu.asregs.gregs[0]; /* make a hash to speed exec loop, hope it's nonzero */ WLhash = 0xFFFFFFFF; for (w = 1; w <= ENDWL; w++) WLhash = WLhash & WL[w]; do { word oldpc; insts ++; if (pc & 02) { if (! target_big_endian) inst = ibuf >> 16; else inst = ibuf & 0xFFFF; needfetch = 1; } else { if (! target_big_endian) inst = ibuf & 0xFFFF; else inst = ibuf >> 16; }#ifdef WATCHFUNCTIONS /* now scan list of watch addresses, if match, count it and note return address and count cycles until pc=return address */ if ((WLincyc == 1) && (pc == WLendpc)) { cycs = (cpu.asregs.cycles + (insts + bonus_cycles + (memops * memcycles)) - WLbcyc); if (WLcnts[WLW] == 1) { WLmax[WLW] = cycs; WLmin[WLW] = cycs; WLcyc[WLW] = 0; } if (cycs > WLmax[WLW]) { WLmax[WLW] = cycs; } if (cycs < WLmin[WLW]) { WLmin[WLW] = cycs; } WLcyc[WLW] += cycs; WLincyc = 0; WLendpc = 0; } /* Optimize with a hash to speed loop. */ if (WLincyc == 0) { if ((WLhash == 0) || ((WLhash & pc) != 0)) { for (w=1; w <= ENDWL; w++) { if (pc == WL[w]) { WLcnts[w]++; WLbcyc = cpu.asregs.cycles + insts + bonus_cycles + (memops * memcycles); WLendpc = cpu.gr[15]; WLincyc = 1; WLW = w; break; } } } }#endif if (tracing) fprintf (stderr, "%.4x: inst = %.4x ", pc, inst); oldpc = pc; pc += 2; switch (inst >> 8) { case 0x00: switch RS { case 0x0: switch RD { case 0x0: /* bkpt */ cpu.asregs.exception = SIGTRAP; pc -= 2; break; case 0x1: /* sync */ break; case 0x2: /* rte */ pc = cpu.epc; cpu.sr = cpu.esr; needfetch = 1; if (SR_AF ()) cpu.asregs.active_gregs = & cpu.asregs.alt_gregs[0]; else cpu.asregs.active_gregs = & cpu.asregs.gregs[0]; break; case 0x3: /* rfi */ pc = cpu.fpc; cpu.sr = cpu.fsr; needfetch = 1; if (SR_AF ()) cpu.asregs.active_gregs = &cpu.asregs.alt_gregs[0]; else cpu.asregs.active_gregs = &cpu.asregs.gregs[0]; break; case 0x4: /* stop */ if (issue_messages) fprintf (stderr, "WARNING: stop unimplemented\n"); break; case 0x5: /* wait */ if (issue_messages) fprintf (stderr, "WARNING: wait unimplemented\n"); break; case 0x6: /* doze */ if (issue_messages) fprintf (stderr, "WARNING: doze unimplemented\n"); break; case 0x7: cpu.asregs.exception = SIGILL; /* illegal */ break; case 0x8: /* trap 0 */ case 0xA: /* trap 2 */ case 0xB: /* trap 3 */ cpu.asregs.exception = SIGTRAP; break; case 0xC: /* trap 4 */ case 0xD: /* trap 5 */ case 0xE: /* trap 6 */ cpu.asregs.exception = SIGILL; /* illegal */ break; case 0xF: /* trap 7 */ cpu.asregs.exception = SIGTRAP; /* integer div-by-0 */ break; case 0x9: /* trap 1 */ handle_trap1 (); break; } break; case 0x1: cpu.asregs.exception = SIGILL; /* illegal */ break; case 0x2: /* mvc */ cpu.gr[RD] = C_VALUE(); break; case 0x3: /* mvcv */ cpu.gr[RD] = C_OFF(); break; case 0x4: /* ldq */ { char *addr = (char *)cpu.gr[RD]; int regno = 4; /* always r4-r7 */ bonus_cycles++; memops += 4; do { cpu.gr[regno] = rlat(addr); addr += 4; regno++; } while ((regno&0x3) != 0); } break; case 0x5: /* stq */ { char *addr = (char *)cpu.gr[RD]; int regno = 4; /* always r4-r7 */ memops += 4; bonus_cycles++; do { wlat(addr, cpu.gr[regno]); addr += 4; regno++; } while ((regno & 0x3) != 0); } break; case 0x6: /* ldm */ { char *addr = (char *)cpu.gr[0]; int regno = RD; /* bonus cycle is really only needed if the next insn shifts the last reg loaded. bonus_cycles++; */ memops += 16-regno; while (regno <= 0xF) { cpu.gr[regno] = rlat(addr); addr += 4; regno++; } } break; case 0x7: /* stm */ { char *addr = (char *)cpu.gr[0]; int regno = RD; /* this should be removed! */ /* bonus_cycles ++; */ memops += 16 - regno; while (regno <= 0xF) { wlat(addr, cpu.gr[regno]); addr += 4; regno++; } } break; case 0x8: /* dect */ cpu.gr[RD] -= C_VALUE(); break; case 0x9: /* decf */ cpu.gr[RD] -= C_OFF(); break; case 0xA: /* inct */ cpu.gr[RD] += C_VALUE(); break; case 0xB: /* incf */ cpu.gr[RD] += C_OFF(); break; case 0xC: /* jmp */ pc = cpu.gr[RD]; if (tracing && RD == 15) fprintf (stderr, "Func return, r2 = %x, r3 = %x\n", cpu.gr[2], cpu.gr[3]); bonus_cycles++; needfetch = 1; break; case 0xD: /* jsr */ cpu.gr[15] = pc; pc = cpu.gr[RD]; bonus_cycles++; needfetch = 1; break; case 0xE: /* ff1 */ { word tmp, i; tmp = cpu.gr[RD]; for (i = 0; !(tmp & 0x80000000) && i < 32; i++) tmp <<= 1; cpu.gr[RD] = i; } break; case 0xF: /* brev */ { word tmp; tmp = cpu.gr[RD]; tmp = ((tmp & 0xaaaaaaaa) >> 1) | ((tmp & 0x55555555) << 1); tmp = ((tmp & 0xcccccccc) >> 2) | ((tmp & 0x33333333) << 2); tmp = ((tmp & 0xf0f0f0f0) >> 4) | ((tmp & 0x0f0f0f0f) << 4); tmp = ((tmp & 0xff00ff00) >> 8) | ((tmp & 0x00ff00ff) << 8); cpu.gr[RD] = ((tmp & 0xffff0000) >> 16) | ((tmp & 0x0000ffff) << 16); } break; } break; case 0x01: switch RS { case 0x0: /* xtrb3 */ cpu.gr[1] = (cpu.gr[RD]) & 0xFF; NEW_C (cpu.gr[RD] != 0); break; case 0x1: /* xtrb2 */ cpu.gr[1] = (cpu.gr[RD]>>8) & 0xFF; NEW_C (cpu.gr[RD] != 0); break; case 0x2: /* xtrb1 */ cpu.gr[1] = (cpu.gr[RD]>>16) & 0xFF; NEW_C (cpu.gr[RD] != 0); break; case 0x3: /* xtrb0 */ cpu.gr[1] = (cpu.gr[RD]>>24) & 0xFF; NEW_C (cpu.gr[RD] != 0); break; case 0x4: /* zextb */ cpu.gr[RD] &= 0x000000FF; break; case 0x5: /* sextb */ { long tmp; tmp = cpu.gr[RD];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -