1 #include "sim-main.h" 2 #include "targ-vals.h" 3 4 #ifdef HAVE_UTIME_H 5 #include <utime.h> 6 #endif 7 8 #ifdef HAVE_TIME_H 9 #include <time.h> 10 #endif 11 12 #ifdef HAVE_UNISTD_H 13 #include <unistd.h> 14 #endif 15 16 #ifdef HAVE_STRING_H 17 #include <string.h> 18 #else 19 #ifdef HAVE_STRINGS_H 20 #include <strings.h> 21 #endif 22 #endif 23 #include <sys/stat.h> 24 #include <sys/times.h> 25 #include <sys/time.h> 26 27 28 29 #define REG0(X) ((X) & 0x3) 30 #define REG1(X) (((X) & 0xc) >> 2) 31 #define REG0_4(X) (((X) & 0x30) >> 4) 32 #define REG0_8(X) (((X) & 0x300) >> 8) 33 #define REG1_8(X) (((X) & 0xc00) >> 10) 34 #define REG0_16(X) (((X) & 0x30000) >> 16) 35 #define REG1_16(X) (((X) & 0xc0000) >> 18) 36 37 38 INLINE_SIM_MAIN (void) 39 genericAdd(unsigned32 source, unsigned32 destReg) 40 { 41 int z, c, n, v; 42 unsigned32 dest, sum; 43 44 dest = State.regs[destReg]; 45 sum = source + dest; 46 State.regs[destReg] = sum; 47 48 z = (sum == 0); 49 n = (sum & 0x80000000); 50 c = (sum < source) || (sum < dest); 51 v = ((dest & 0x80000000) == (source & 0x80000000) 52 && (dest & 0x80000000) != (sum & 0x80000000)); 53 54 PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); 55 PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) 56 | (c ? PSW_C : 0) | (v ? PSW_V : 0)); 57 } 58 59 60 61 62 INLINE_SIM_MAIN (void) 63 genericSub(unsigned32 source, unsigned32 destReg) 64 { 65 int z, c, n, v; 66 unsigned32 dest, difference; 67 68 dest = State.regs[destReg]; 69 difference = dest - source; 70 State.regs[destReg] = difference; 71 72 z = (difference == 0); 73 n = (difference & 0x80000000); 74 c = (source > dest); 75 v = ((dest & 0x80000000) != (source & 0x80000000) 76 && (dest & 0x80000000) != (difference & 0x80000000)); 77 78 PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); 79 PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) 80 | (c ? PSW_C : 0) | (v ? PSW_V : 0)); 81 } 82 83 INLINE_SIM_MAIN (void) 84 genericCmp(unsigned32 leftOpnd, unsigned32 rightOpnd) 85 { 86 int z, c, n, v; 87 unsigned32 value; 88 89 value = rightOpnd - leftOpnd; 90 91 z = (value == 0); 92 n = (value & 0x80000000); 93 c = (leftOpnd > rightOpnd); 94 v = ((rightOpnd & 0x80000000) != (leftOpnd & 0x80000000) 95 && (rightOpnd & 0x80000000) != (value & 0x80000000)); 96 97 PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); 98 PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0) 99 | (c ? PSW_C : 0) | (v ? PSW_V : 0)); 100 } 101 102 103 INLINE_SIM_MAIN (void) 104 genericOr(unsigned32 source, unsigned32 destReg) 105 { 106 int n, z; 107 108 State.regs[destReg] |= source; 109 z = (State.regs[destReg] == 0); 110 n = (State.regs[destReg] & 0x80000000) != 0; 111 PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); 112 PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); 113 } 114 115 116 INLINE_SIM_MAIN (void) 117 genericXor(unsigned32 source, unsigned32 destReg) 118 { 119 int n, z; 120 121 State.regs[destReg] ^= source; 122 z = (State.regs[destReg] == 0); 123 n = (State.regs[destReg] & 0x80000000) != 0; 124 PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); 125 PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0)); 126 } 127 128 129 INLINE_SIM_MAIN (void) 130 genericBtst(unsigned32 leftOpnd, unsigned32 rightOpnd) 131 { 132 unsigned32 temp; 133 int z, n; 134 135 temp = rightOpnd; 136 temp &= leftOpnd; 137 n = (temp & 0x80000000) != 0; 138 z = (temp == 0); 139 PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V); 140 PSW |= (z ? PSW_Z : 0) | (n ? PSW_N : 0); 141 } 142 143 /* Read/write functions for system call interface. */ 144 INLINE_SIM_MAIN (int) 145 syscall_read_mem (host_callback *cb, struct cb_syscall *sc, 146 unsigned long taddr, char *buf, int bytes) 147 { 148 SIM_DESC sd = (SIM_DESC) sc->p1; 149 sim_cpu *cpu = STATE_CPU(sd, 0); 150 151 return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes); 152 } 153 154 INLINE_SIM_MAIN (int) 155 syscall_write_mem (host_callback *cb, struct cb_syscall *sc, 156 unsigned long taddr, const char *buf, int bytes) 157 { 158 SIM_DESC sd = (SIM_DESC) sc->p1; 159 sim_cpu *cpu = STATE_CPU(sd, 0); 160 161 return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes); 162 } 163 164 165 /* syscall */ 166 INLINE_SIM_MAIN (void) 167 do_syscall (void) 168 { 169 170 /* We use this for simulated system calls; we may need to change 171 it to a reserved instruction if we conflict with uses at 172 Matsushita. */ 173 int save_errno = errno; 174 errno = 0; 175 176 /* Registers passed to trap 0 */ 177 178 /* Function number. */ 179 #define FUNC (State.regs[0]) 180 181 /* Parameters. */ 182 #define PARM1 (State.regs[1]) 183 #define PARM2 (load_word (State.regs[REG_SP] + 12)) 184 #define PARM3 (load_word (State.regs[REG_SP] + 16)) 185 186 /* Registers set by trap 0 */ 187 188 #define RETVAL State.regs[0] /* return value */ 189 #define RETERR State.regs[1] /* return error code */ 190 191 /* Turn a pointer in a register into a pointer into real memory. */ 192 #define MEMPTR(x) (State.mem + x) 193 194 if ( FUNC == TARGET_SYS_exit ) 195 { 196 /* EXIT - caller can look in PARM1 to work out the reason */ 197 if (PARM1 == 0xdead) 198 State.exception = SIGABRT; 199 else 200 { 201 sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC, 202 sim_exited, PARM1); 203 State.exception = SIGQUIT; 204 } 205 State.exited = 1; 206 } 207 else 208 { 209 CB_SYSCALL syscall; 210 211 CB_SYSCALL_INIT (&syscall); 212 syscall.arg1 = PARM1; 213 syscall.arg2 = PARM2; 214 syscall.arg3 = PARM3; 215 syscall.func = FUNC; 216 syscall.p1 = (PTR) simulator; 217 syscall.read_mem = syscall_read_mem; 218 syscall.write_mem = syscall_write_mem; 219 cb_syscall (STATE_CALLBACK (simulator), &syscall); 220 RETERR = syscall.errcode; 221 RETVAL = syscall.result; 222 } 223 224 225 errno = save_errno; 226 } 227 228