| 1 | #include "sim-main.h" |
| 2 | #include "sim-syscall.h" |
| 3 | #include "targ-vals.h" |
| 4 | |
| 5 | #ifdef HAVE_UTIME_H |
| 6 | #include <utime.h> |
| 7 | #endif |
| 8 | |
| 9 | #ifdef HAVE_TIME_H |
| 10 | #include <time.h> |
| 11 | #endif |
| 12 | |
| 13 | #ifdef HAVE_UNISTD_H |
| 14 | #include <unistd.h> |
| 15 | #endif |
| 16 | |
| 17 | #ifdef HAVE_STRING_H |
| 18 | #include <string.h> |
| 19 | #else |
| 20 | #ifdef HAVE_STRINGS_H |
| 21 | #include <strings.h> |
| 22 | #endif |
| 23 | #endif |
| 24 | #include <sys/stat.h> |
| 25 | #include <sys/times.h> |
| 26 | #include <sys/time.h> |
| 27 | |
| 28 | |
| 29 | |
| 30 | #define REG0(X) ((X) & 0x3) |
| 31 | #define REG1(X) (((X) & 0xc) >> 2) |
| 32 | #define REG0_4(X) (((X) & 0x30) >> 4) |
| 33 | #define REG0_8(X) (((X) & 0x300) >> 8) |
| 34 | #define REG1_8(X) (((X) & 0xc00) >> 10) |
| 35 | #define REG0_16(X) (((X) & 0x30000) >> 16) |
| 36 | #define REG1_16(X) (((X) & 0xc0000) >> 18) |
| 37 | |
| 38 | |
| 39 | INLINE_SIM_MAIN (void) |
| 40 | genericAdd(unsigned32 source, unsigned32 destReg) |
| 41 | { |
| 42 | int z, c, n, v; |
| 43 | unsigned32 dest, sum; |
| 44 | |
| 45 | dest = State.regs[destReg]; |
| 46 | sum = source + dest; |
| 47 | State.regs[destReg] = sum; |
| 48 | |
| 49 | z = (sum == 0); |
| 50 | n = (sum & 0x80000000); |
| 51 | c = (sum < source) || (sum < dest); |
| 52 | v = ((dest & 0x80000000) == (source & 0x80000000) |
| 53 | && (dest & 0x80000000) != (sum & 0x80000000)); |
| 54 | |
| 55 | PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); |
| 56 | PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) |
| 57 | | (c ? PSW_C : 0) | (v ? PSW_V : 0)); |
| 58 | } |
| 59 | |
| 60 | |
| 61 | |
| 62 | |
| 63 | INLINE_SIM_MAIN (void) |
| 64 | genericSub(unsigned32 source, unsigned32 destReg) |
| 65 | { |
| 66 | int z, c, n, v; |
| 67 | unsigned32 dest, difference; |
| 68 | |
| 69 | dest = State.regs[destReg]; |
| 70 | difference = dest - source; |
| 71 | State.regs[destReg] = difference; |
| 72 | |
| 73 | z = (difference == 0); |
| 74 | n = (difference & 0x80000000); |
| 75 | c = (source > dest); |
| 76 | v = ((dest & 0x80000000) != (source & 0x80000000) |
| 77 | && (dest & 0x80000000) != (difference & 0x80000000)); |
| 78 | |
| 79 | PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); |
| 80 | PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) |
| 81 | | (c ? PSW_C : 0) | (v ? PSW_V : 0)); |
| 82 | } |
| 83 | |
| 84 | INLINE_SIM_MAIN (void) |
| 85 | genericCmp(unsigned32 leftOpnd, unsigned32 rightOpnd) |
| 86 | { |
| 87 | int z, c, n, v; |
| 88 | unsigned32 value; |
| 89 | |
| 90 | value = rightOpnd - leftOpnd; |
| 91 | |
| 92 | z = (value == 0); |
| 93 | n = (value & 0x80000000); |
| 94 | c = (leftOpnd > rightOpnd); |
| 95 | v = ((rightOpnd & 0x80000000) != (leftOpnd & 0x80000000) |
| 96 | && (rightOpnd & 0x80000000) != (value & 0x80000000)); |
| 97 | |
| 98 | PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); |
| 99 | PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) |
| 100 | | (c ? PSW_C : 0) | (v ? PSW_V : 0)); |
| 101 | } |
| 102 | |
| 103 | |
| 104 | INLINE_SIM_MAIN (void) |
| 105 | genericOr(unsigned32 source, unsigned32 destReg) |
| 106 | { |
| 107 | int n, z; |
| 108 | |
| 109 | State.regs[destReg] |= source; |
| 110 | z = (State.regs[destReg] == 0); |
| 111 | n = (State.regs[destReg] & 0x80000000) != 0; |
| 112 | PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); |
| 113 | PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); |
| 114 | } |
| 115 | |
| 116 | |
| 117 | INLINE_SIM_MAIN (void) |
| 118 | genericXor(unsigned32 source, unsigned32 destReg) |
| 119 | { |
| 120 | int n, z; |
| 121 | |
| 122 | State.regs[destReg] ^= source; |
| 123 | z = (State.regs[destReg] == 0); |
| 124 | n = (State.regs[destReg] & 0x80000000) != 0; |
| 125 | PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); |
| 126 | PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); |
| 127 | } |
| 128 | |
| 129 | |
| 130 | INLINE_SIM_MAIN (void) |
| 131 | genericBtst(unsigned32 leftOpnd, unsigned32 rightOpnd) |
| 132 | { |
| 133 | unsigned32 temp; |
| 134 | int z, n; |
| 135 | |
| 136 | temp = rightOpnd; |
| 137 | temp &= leftOpnd; |
| 138 | n = (temp & 0x80000000) != 0; |
| 139 | z = (temp == 0); |
| 140 | PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); |
| 141 | PSW |= (z ? PSW_Z : 0) | (n ? PSW_N : 0); |
| 142 | } |
| 143 | |
| 144 | /* syscall */ |
| 145 | INLINE_SIM_MAIN (void) |
| 146 | do_syscall (void) |
| 147 | { |
| 148 | /* Registers passed to trap 0. */ |
| 149 | |
| 150 | /* Function number. */ |
| 151 | reg_t func = State.regs[0]; |
| 152 | /* Parameters. */ |
| 153 | reg_t parm1 = State.regs[1]; |
| 154 | reg_t parm2 = load_word (State.regs[REG_SP] + 12); |
| 155 | reg_t parm3 = load_word (State.regs[REG_SP] + 16); |
| 156 | reg_t parm4 = load_word (State.regs[REG_SP] + 20); |
| 157 | |
| 158 | /* We use this for simulated system calls; we may need to change |
| 159 | it to a reserved instruction if we conflict with uses at |
| 160 | Matsushita. */ |
| 161 | int save_errno = errno; |
| 162 | errno = 0; |
| 163 | |
| 164 | if (func == TARGET_SYS_exit) |
| 165 | { |
| 166 | /* EXIT - caller can look in parm1 to work out the reason */ |
| 167 | sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC, |
| 168 | (parm1 == 0xdead ? SIM_SIGABRT : sim_exited), parm1); |
| 169 | } |
| 170 | else |
| 171 | { |
| 172 | long result, result2; |
| 173 | int errcode; |
| 174 | |
| 175 | sim_syscall_multi (STATE_CPU (simulator, 0), func, parm1, parm2, |
| 176 | parm3, parm4, &result, &result2, &errcode); |
| 177 | |
| 178 | /* Registers set by trap 0. */ |
| 179 | State.regs[0] = errcode; |
| 180 | State.regs[1] = result; |
| 181 | } |
| 182 | |
| 183 | errno = save_errno; |
| 184 | } |