/* This must come before any other includes. */ #include "defs.h" #include "sim-main.h" #include "sim-syscall.h" #include "targ-vals.h" #include #ifdef HAVE_UNISTD_H #include #endif #include #include #include #define REG0(X) ((X) & 0x3) #define REG1(X) (((X) & 0xc) >> 2) #define REG0_4(X) (((X) & 0x30) >> 4) #define REG0_8(X) (((X) & 0x300) >> 8) #define REG1_8(X) (((X) & 0xc00) >> 10) #define REG0_16(X) (((X) & 0x30000) >> 16) #define REG1_16(X) (((X) & 0xc0000) >> 18) INLINE_SIM_MAIN (void) genericAdd(unsigned32 source, unsigned32 destReg) { int z, c, n, v; unsigned32 dest, sum; dest = State.regs[destReg]; sum = source + dest; State.regs[destReg] = sum; z = (sum == 0); n = (sum & 0x80000000); c = (sum < source) || (sum < dest); v = ((dest & 0x80000000) == (source & 0x80000000) && (dest & 0x80000000) != (sum & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } INLINE_SIM_MAIN (void) genericSub(unsigned32 source, unsigned32 destReg) { int z, c, n, v; unsigned32 dest, difference; dest = State.regs[destReg]; difference = dest - source; State.regs[destReg] = difference; z = (difference == 0); n = (difference & 0x80000000); c = (source > dest); v = ((dest & 0x80000000) != (source & 0x80000000) && (dest & 0x80000000) != (difference & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } INLINE_SIM_MAIN (void) genericCmp(unsigned32 leftOpnd, unsigned32 rightOpnd) { int z, c, n, v; unsigned32 value; value = rightOpnd - leftOpnd; z = (value == 0); n = (value & 0x80000000); c = (leftOpnd > rightOpnd); v = ((rightOpnd & 0x80000000) != (leftOpnd & 0x80000000) && (rightOpnd & 0x80000000) != (value & 0x80000000)); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) | (c ? PSW_C : 0) | (v ? PSW_V : 0)); } INLINE_SIM_MAIN (void) genericOr(unsigned32 source, unsigned32 destReg) { int n, z; State.regs[destReg] |= source; z = (State.regs[destReg] == 0); n = (State.regs[destReg] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); } INLINE_SIM_MAIN (void) genericXor(unsigned32 source, unsigned32 destReg) { int n, z; State.regs[destReg] ^= source; z = (State.regs[destReg] == 0); n = (State.regs[destReg] & 0x80000000) != 0; PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); } INLINE_SIM_MAIN (void) genericBtst(unsigned32 leftOpnd, unsigned32 rightOpnd) { unsigned32 temp; int z, n; temp = rightOpnd; temp &= leftOpnd; n = (temp & 0x80000000) != 0; z = (temp == 0); PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); PSW |= (z ? PSW_Z : 0) | (n ? PSW_N : 0); } /* syscall */ INLINE_SIM_MAIN (void) do_syscall (void) { /* Registers passed to trap 0. */ /* Function number. */ reg_t func = State.regs[0]; /* Parameters. */ reg_t parm1 = State.regs[1]; reg_t parm2 = load_word (State.regs[REG_SP] + 12); reg_t parm3 = load_word (State.regs[REG_SP] + 16); reg_t parm4 = load_word (State.regs[REG_SP] + 20); /* We use this for simulated system calls; we may need to change it to a reserved instruction if we conflict with uses at Matsushita. */ int save_errno = errno; errno = 0; if (func == TARGET_SYS_exit) { /* EXIT - caller can look in parm1 to work out the reason */ sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC, (parm1 == 0xdead ? SIM_SIGABRT : sim_exited), parm1); } else { long result, result2; int errcode; sim_syscall_multi (STATE_CPU (simulator, 0), func, parm1, parm2, parm3, parm4, &result, &result2, &errcode); /* Registers set by trap 0. */ State.regs[0] = errcode; State.regs[1] = result; } errno = save_errno; }