📄 simops.c
字号:
/* xor reg, reg */intOP_120 (){ unsigned int op0, op1, result, z, s; trace_input ("xor", OP_REG_REG, 0); /* Compute the result. */ op0 = State.regs[ OP[0] ]; op1 = State.regs[ OP[1] ]; result = op0 ^ op1; /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); /* Store the result and condition codes. */ State.regs[OP[1]] = result; PSW &= ~(PSW_Z | PSW_S | PSW_OV); PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); trace_output (OP_REG_REG); return 2;}/* xori zero_extend(imm16), reg, reg */intOP_6A0 (){ unsigned int op0, op1, result, z, s; trace_input ("xori", OP_UIMM16_REG_REG, 0); op0 = OP[2]; op1 = State.regs[ OP[0] ]; result = op0 ^ op1; /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); /* Store the result and condition codes. */ State.regs[OP[1]] = result; PSW &= ~(PSW_Z | PSW_S | PSW_OV); PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); trace_output (OP_UIMM16_REG_REG); return 4;}/* not reg1, reg2 */intOP_20 (){ unsigned int op0, result, z, s; trace_input ("not", OP_REG_REG_MOVE, 0); /* Compute the result. */ op0 = State.regs[ OP[0] ]; result = ~op0; /* Compute the condition codes. */ z = (result == 0); s = (result & 0x80000000); /* Store the result and condition codes. */ State.regs[OP[1]] = result; PSW &= ~(PSW_Z | PSW_S | PSW_OV); PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); trace_output (OP_REG_REG_MOVE); return 2;}/* set1 */intOP_7C0 (){ unsigned int op0, op1, op2; int temp; trace_input ("set1", OP_BIT, 0); op0 = State.regs[ OP[0] ]; op1 = OP[1] & 0x7; temp = EXTEND16 (OP[2]); op2 = temp; temp = load_mem (op0 + op2, 1); PSW &= ~PSW_Z; if ((temp & (1 << op1)) == 0) PSW |= PSW_Z; temp |= (1 << op1); store_mem (op0 + op2, 1, temp); trace_output (OP_BIT); return 4;}/* not1 */intOP_47C0 (){ unsigned int op0, op1, op2; int temp; trace_input ("not1", OP_BIT, 0); op0 = State.regs[ OP[0] ]; op1 = OP[1] & 0x7; temp = EXTEND16 (OP[2]); op2 = temp; temp = load_mem (op0 + op2, 1); PSW &= ~PSW_Z; if ((temp & (1 << op1)) == 0) PSW |= PSW_Z; temp ^= (1 << op1); store_mem (op0 + op2, 1, temp); trace_output (OP_BIT); return 4;}/* clr1 */intOP_87C0 (){ unsigned int op0, op1, op2; int temp; trace_input ("clr1", OP_BIT, 0); op0 = State.regs[ OP[0] ]; op1 = OP[1] & 0x7; temp = EXTEND16 (OP[2]); op2 = temp; temp = load_mem (op0 + op2, 1); PSW &= ~PSW_Z; if ((temp & (1 << op1)) == 0) PSW |= PSW_Z; temp &= ~(1 << op1); store_mem (op0 + op2, 1, temp); trace_output (OP_BIT); return 4;}/* tst1 */intOP_C7C0 (){ unsigned int op0, op1, op2; int temp; trace_input ("tst1", OP_BIT, 0); op0 = State.regs[ OP[0] ]; op1 = OP[1] & 0x7; temp = EXTEND16 (OP[2]); op2 = temp; temp = load_mem (op0 + op2, 1); PSW &= ~PSW_Z; if ((temp & (1 << op1)) == 0) PSW |= PSW_Z; trace_output (OP_BIT); return 4;}/* di */intOP_16007E0 (){ trace_input ("di", OP_NONE, 0); PSW |= PSW_ID; trace_output (OP_NONE); return 4;}/* ei */intOP_16087E0 (){ trace_input ("ei", OP_NONE, 0); PSW &= ~PSW_ID; trace_output (OP_NONE); return 4;}/* halt */intOP_12007E0 (){ trace_input ("halt", OP_NONE, 0); /* FIXME this should put processor into a mode where NMI still handled */ trace_output (OP_NONE); sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC, sim_stopped, SIM_SIGTRAP); return 0;}/* trap */intOP_10007E0 (){ trace_input ("trap", OP_TRAP, 0); trace_output (OP_TRAP); /* Trap 31 is used for simulating OS I/O functions */ if (OP[0] == 31) { int save_errno = errno; errno = 0;/* Registers passed to trap 0 */#define FUNC State.regs[6] /* function number, return value */#define PARM1 State.regs[7] /* optional parm 1 */#define PARM2 State.regs[8] /* optional parm 2 */#define PARM3 State.regs[9] /* optional parm 3 *//* Registers set by trap 0 */#define RETVAL State.regs[10] /* return value */#define RETERR State.regs[11] /* return error code *//* Turn a pointer in a register into a pointer into real memory. */#define MEMPTR(x) (map (x)) switch (FUNC) {#ifdef HAVE_FORK#ifdef TARGET_SYS_fork case TARGET_SYS_fork: RETVAL = fork (); break;#endif#endif#ifdef HAVE_EXECVE#ifdef TARGET_SYS_execv case TARGET_SYS_execve: { char *path = fetch_str (simulator, PARM1); char **argv = fetch_argv (simulator, PARM2); char **envp = fetch_argv (simulator, PARM3); RETVAL = execve (path, argv, envp); zfree (path); freeargv (argv); freeargv (envp); break; }#endif#endif#if HAVE_EXECV#ifdef TARGET_SYS_execv case TARGET_SYS_execv: { char *path = fetch_str (simulator, PARM1); char **argv = fetch_argv (simulator, PARM2); RETVAL = execv (path, argv); zfree (path); freeargv (argv); break; }#endif#endif#if 0#ifdef TARGET_SYS_pipe case TARGET_SYS_pipe: { reg_t buf; int host_fd[2]; buf = PARM1; RETVAL = pipe (host_fd); SW (buf, host_fd[0]); buf += sizeof(uint16); SW (buf, host_fd[1]); } break;#endif#endif#if 0#ifdef TARGET_SYS_wait case TARGET_SYS_wait: { int status; RETVAL = wait (&status); SW (PARM1, status); } break;#endif#endif#ifdef TARGET_SYS_read case TARGET_SYS_read: { char *buf = zalloc (PARM3); RETVAL = sim_io_read (simulator, PARM1, buf, PARM3); sim_write (simulator, PARM2, buf, PARM3); zfree (buf); break; }#endif#ifdef TARGET_SYS_write case TARGET_SYS_write: { char *buf = zalloc (PARM3); sim_read (simulator, PARM2, buf, PARM3); if (PARM1 == 1) RETVAL = sim_io_write_stdout (simulator, buf, PARM3); else RETVAL = sim_io_write (simulator, PARM1, buf, PARM3); zfree (buf); break; }#endif#ifdef TARGET_SYS_lseek case TARGET_SYS_lseek: RETVAL = sim_io_lseek (simulator, PARM1, PARM2, PARM3); break;#endif#ifdef TARGET_SYS_close case TARGET_SYS_close: RETVAL = sim_io_close (simulator, PARM1); break;#endif#ifdef TARGET_SYS_open case TARGET_SYS_open: { char *buf = fetch_str (simulator, PARM1); RETVAL = sim_io_open (simulator, buf, PARM2); zfree (buf); break; }#endif#ifdef TARGET_SYS_exit case TARGET_SYS_exit: if ((PARM1 & 0xffff0000) == 0xdead0000 && (PARM1 & 0xffff) != 0) /* get signal encoded by kill */ sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC, sim_signalled, PARM1 & 0xffff); else if (PARM1 == 0xdead) /* old libraries */ sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC, sim_stopped, SIM_SIGABRT); else /* PARM1 has exit status */ sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC, sim_exited, PARM1); break;#endif#if !defined(__GO32__) && !defined(_WIN32)#ifdef TARGET_SYS_stat case TARGET_SYS_stat: /* added at hmsi */ /* stat system call */ { struct stat host_stat; reg_t buf; char *path = fetch_str (simulator, PARM1); RETVAL = stat (path, &host_stat); zfree (path); buf = PARM2; /* Just wild-assed guesses. */ store_mem (buf, 2, host_stat.st_dev); store_mem (buf + 2, 2, host_stat.st_ino); store_mem (buf + 4, 4, host_stat.st_mode); store_mem (buf + 8, 2, host_stat.st_nlink); store_mem (buf + 10, 2, host_stat.st_uid); store_mem (buf + 12, 2, host_stat.st_gid); store_mem (buf + 14, 2, host_stat.st_rdev); store_mem (buf + 16, 4, host_stat.st_size); store_mem (buf + 20, 4, host_stat.st_atime); store_mem (buf + 28, 4, host_stat.st_mtime); store_mem (buf + 36, 4, host_stat.st_ctime); } break;#endif#endif#ifdef HAVE_CHOWN#ifdef TARGET_SYS_chown case TARGET_SYS_chown: { char *path = fetch_str (simulator, PARM1); RETVAL = chown (path, PARM2, PARM3); zfree (path); } break;#endif#endif#if HAVE_CHMOD#ifdef TARGET_SYS_chmod case TARGET_SYS_chmod: { char *path = fetch_str (simulator, PARM1); RETVAL = chmod (path, PARM2); zfree (path); } break;#endif#endif#ifdef TARGET_SYS_time#if HAVE_TIME case TARGET_SYS_time: { time_t now; RETVAL = time (&now); store_mem (PARM1, 4, now); } break;#endif#endif#if !defined(__GO32__) && !defined(_WIN32)#ifdef TARGET_SYS_times case TARGET_SYS_times: { struct tms tms; RETVAL = times (&tms); store_mem (PARM1, 4, tms.tms_utime); store_mem (PARM1 + 4, 4, tms.tms_stime); store_mem (PARM1 + 8, 4, tms.tms_cutime); store_mem (PARM1 + 12, 4, tms.tms_cstime); break; }#endif#endif#ifdef TARGET_SYS_gettimeofday#if !defined(__GO32__) && !defined(_WIN32) case TARGET_SYS_gettimeofday: { struct timeval t; struct timezone tz; RETVAL = gettimeofday (&t, &tz); store_mem (PARM1, 4, t.tv_sec); store_mem (PARM1 + 4, 4, t.tv_usec); store_mem (PARM2, 4, tz.tz_minuteswest); store_mem (PARM2 + 4, 4, tz.tz_dsttime); break; }#endif#endif#ifdef TARGET_SYS_utime#if HAVE_UTIME case TARGET_SYS_utime: { /* Cast the second argument to void *, to avoid type mismatch if a prototype is present. */ sim_io_error (simulator, "Utime not supported"); /* RETVAL = utime (path, (void *) MEMPTR (PARM2)); */ } break;#endif#endif default: abort (); } RETERR = errno; errno = save_errno; return 4; } else { /* Trap 0 -> 30 */ EIPC = PC + 4; EIPSW = PSW; /* Mask out EICC */ ECR &= 0xffff0000; ECR |= 0x40 + OP[0]; /* Flag that we are now doing exception processing. */ PSW |= PSW_EP | PSW_ID; PC = (OP[0] < 0x10) ? 0x40 : 0x50; return 0; }}/* tst1 reg2, [reg1] */intOP_E607E0 (void){ int temp; trace_input ("tst1", OP_BIT, 1); temp = load_mem (State.regs[ OP[0] ], 1); PSW &= ~PSW_Z; if ((temp & (1 << (State.regs[ OP[1] ] & 0x7))) == 0) PSW |= PSW_Z; trace_output (OP_BIT); return 4;}/* mulu reg1, reg2, reg3 */intOP_22207E0 (void){ trace_input ("mulu", OP_REG_REG_REG, 0); Multiply64 (0, State.regs[ OP[0] ]); trace_output (OP_REG_REG_REG); return 4;}#define BIT_CHANGE_OP( name, binop ) \ unsigned int bit; \ unsigned int temp; \ \ trace_input (name, OP_BIT_CHANGE, 0); \ \ bit = 1 << (State.regs[ OP[1] ] & 0x7); \ temp = load_mem (State.regs[ OP[0] ], 1); \ \ PSW &= ~PSW_Z; \ if ((temp & bit) == 0) \ PSW |= PSW_Z; \ temp binop bit; \ \ store_mem (State.regs[ OP[0] ], 1, temp); \ \ trace_output (OP_BIT_CHANGE); \ \ return 4;/* clr1 reg2, [reg1] */intOP_E407E0 (void){ BIT_CHANGE_OP ("clr1", &= ~ );}/* not1 reg2, [reg1] */intOP_E207E0 (void){ BIT_CHANGE_OP ("not1", ^= );}/* set1 */intOP_E007E0 (void){ BIT_CHANGE_OP ("set1", |= );}/* sasf */intOP_20007E0 (void){ trace_input ("sasf", OP_EX1, 0); State.regs[ OP[1] ] = (State.regs[ OP[1] ] << 1) | condition_met (OP[0]); trace_output (OP_EX1); return 4;}/* This function is courtesy of Sugimoto at NEC, via Seow Tan (Soew_Tan@el.nec.com) */voiddivun( unsigned int N, unsigned long int als, unsigned long int sfi, unsigned32 /*unsigned long int*/ * quotient_ptr, unsigned32 /*unsigned long int*/ * remainder_ptr, int * overflow_ptr){ unsigned long ald = sfi >> (N - 1); unsigned long alo = als; unsigned int Q = 1; unsigned int C; unsigned int S = 0; unsigned int i; unsigned int R1 = 1; unsigned int DBZ = (als == 0) ? 1 : 0; unsigned long alt = Q ? ~als : als; /* 1st Loop */ alo = ald + alt + Q; C = (((alt >> 31) & (ald >> 31)) | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31))); C = C ^ Q; Q = ~(C ^ S) & 1; R1 = (alo == 0) ? 0 : (R1 & Q); if ((S ^ (alo>>31)) && !C) { DBZ = 1; } S = alo >> 31; sfi = (sfi << (32-N+1)) | Q; ald = (alo << 1) | (sfi >> 31); /* 2nd - N-1th Loop */ for (i = 2; i < N; i++) { alt = Q ? ~als : als; alo = ald + alt + Q; C = (((alt >> 31) & (ald >> 31)) | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31))); C = C ^ Q; Q = ~(C ^ S) & 1; R1 = (alo == 0) ? 0 : (R1 & Q); if ((S ^ (alo>>31)) && !C && !DBZ) { DBZ = 1; } S = alo >> 31; sfi = (sfi << 1) | Q; ald = (alo << 1) | (sfi >> 31); } /* Nth Loop */ alt = Q ? ~als : als; alo = ald + alt + Q; C = (((alt >> 31) & (ald >> 31)) | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31))); C = C ^ Q; Q = ~(C ^ S) & 1; R1 = (alo == 0) ? 0 : (R1 & Q); if ((S ^ (alo>>31)) && !C) { DBZ = 1; } * quotient_ptr = (sfi << 1) | Q; * remainder_ptr = Q ? alo : (alo + als); * overflow_ptr = DBZ | R1;}/* This function is courtesy of Sugimoto at NEC, via Seow Tan (Soew_Tan@el.nec.com) */voiddivn( unsigned int N, unsigned long int als, unsigned long int sfi, signed32 /*signed long int*/ * quotient_ptr, signed32 /*signed long int*/ * remainder_ptr, int * overflow_ptr){ unsigned long ald = (signed long) sfi >> (N - 1); unsigned long alo = als; unsigned int SS = als >> 31;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -