1 /* $Id: m68k-impl.h,v 1.19 2009/08/29 19:28:08 fredette Exp $ */ 2 3 /* ic/m68k/m68k-impl.h - implementation header file for Motorola 68k emulation: */ 4 5 /* 6 * Copyright (c) 2002, 2003 Matt Fredette 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by Matt Fredette. 20 * 4. The name of the author may not be used to endorse or promote products 21 * derived from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 #ifndef _IC_M68K_IMPL_H 37 #define _IC_M68K_IMPL_H 38 39 #include <tme/common.h> 40 _TME_RCSID("$Id: m68k-impl.h,v 1.19 2009/08/29 19:28:08 fredette Exp $"); 41 42 /* includes: */ 43 #include <tme/ic/m68k.h> 44 #include <tme/ic/ieee754.h> 45 #include <tme/generic/ic.h> 46 #include <setjmp.h> 47 48 /* macros: */ 49 50 /* CPUs: */ 51 #define TME_M68K_M68000 (0) 52 #define TME_M68K_M68010 (1) 53 #define TME_M68K_M68020 (2) 54 #define TME_M68K_M68030 (3) 55 #define TME_M68K_M68040 (4) 56 57 /* FPUs: */ 58 #define TME_M68K_FPU_NONE (0) 59 #define TME_M68K_FPU_M68881 TME_BIT(0) 60 #define TME_M68K_FPU_M68882 TME_BIT(1) 61 #define TME_M68K_FPU_M6888X (TME_M68K_FPU_M68881 | TME_M68K_FPU_M68882) 62 #define TME_M68K_FPU_M68040 TME_BIT(2) 63 #define TME_M68K_FPU_ANY (TME_M68K_FPU_M68881 | TME_M68K_FPU_M68882 | TME_M68K_FPU_M68040) 64 65 /* generic registers: */ 66 #define tme_m68k_ireg_uint32(x) tme_m68k_ic.tme_ic_ireg_uint32(x) 67 #define tme_m68k_ireg_int32(x) tme_m68k_ic.tme_ic_ireg_int32(x) 68 #define tme_m68k_ireg_uint16(x) tme_m68k_ic.tme_ic_ireg_uint16(x) 69 #define tme_m68k_ireg_int16(x) tme_m68k_ic.tme_ic_ireg_int16(x) 70 #define tme_m68k_ireg_uint8(x) tme_m68k_ic.tme_ic_ireg_uint8(x) 71 #define tme_m68k_ireg_int8(x) tme_m68k_ic.tme_ic_ireg_int8(x) 72 73 /* flags: */ 74 #define TME_M68K_FLAG_C TME_BIT(0) 75 #define TME_M68K_FLAG_V TME_BIT(1) 76 #define TME_M68K_FLAG_Z TME_BIT(2) 77 #define TME_M68K_FLAG_N TME_BIT(3) 78 #define TME_M68K_FLAG_X TME_BIT(4) 79 #define TME_M68K_FLAG_IPM(x) TME_FIELD_EXTRACTU(x, 8, 3) 80 #define TME_M68K_FLAG_M TME_BIT(12) 81 #define TME_M68K_FLAG_S TME_BIT(13) 82 #define TME_M68K_FLAG_T0 TME_BIT(14) 83 #define TME_M68K_FLAG_T1 TME_BIT(15) 84 #define TME_M68K_FLAG_CCR (TME_M68K_FLAG_C | TME_M68K_FLAG_V | \ 85 TME_M68K_FLAG_Z | TME_M68K_FLAG_N | \ 86 TME_M68K_FLAG_X) 87 #define TME_M68K_FLAG_SR (TME_M68K_FLAG_CCR | (0x7 << 8) | \ 88 TME_M68K_FLAG_M | TME_M68K_FLAG_S | \ 89 TME_M68K_FLAG_T0 | TME_M68K_FLAG_T1) 90 91 /* conditions: */ 92 #define TME_M68K_C_T (0) 93 #define TME_M68K_C_F (1) 94 #define TME_M68K_C_HI (2) 95 #define TME_M68K_C_LS (3) 96 #define TME_M68K_C_CC (4) 97 #define TME_M68K_C_CS (5) 98 #define TME_M68K_C_NE (6) 99 #define TME_M68K_C_EQ (7) 100 #define TME_M68K_C_VC (8) 101 #define TME_M68K_C_VS (9) 102 #define TME_M68K_C_PL (10) 103 #define TME_M68K_C_MI (11) 104 #define TME_M68K_C_GE (12) 105 #define TME_M68K_C_LT (13) 106 #define TME_M68K_C_GT (14) 107 #define TME_M68K_C_LE (15) 108 #define TME_M68K_COND_TRUE(ic, c) (_tme_m68k_conditions[(ic)->tme_m68k_ireg_ccr] & TME_BIT(c)) 109 110 /* bus cycles: */ 111 #define TME_M68K_BUS_CYCLE_NORMAL (0) 112 #define TME_M68K_BUS_CYCLE_READ TME_BIT(0) 113 #define TME_M68K_BUS_CYCLE_FETCH TME_BIT(1) 114 #define TME_M68K_BUS_CYCLE_RMW TME_BIT(2) 115 #define TME_M68K_BUS_CYCLE_RAW TME_BIT(3) 116 117 /* exceptions: */ 118 #define TME_M68K_EXCEPTION_NONE (0) 119 #define TME_M68K_EXCEPTION_RESET TME_BIT(0) 120 #define TME_M68K_EXCEPTION_AERR TME_BIT(1) 121 #define TME_M68K_EXCEPTION_BERR TME_BIT(2) 122 #define TME_M68K_EXCEPTION_TRACE TME_BIT(3) 123 #define TME_M68K_EXCEPTION_INT(ipl, vec) (((ipl) << 4) | ((vec) << 7)) 124 #define TME_M68K_EXCEPTION_IS_INT(x) (((x) >> 4) & 0x7) 125 #define TME_M68K_EXCEPTION_INT_VEC(x) (((x) >> 7) & 0xff) 126 #define TME_M68K_EXCEPTION_ILL TME_BIT(15) 127 #define TME_M68K_EXCEPTION_PRIV TME_BIT(16) 128 #define TME_M68K_EXCEPTION_INST(x) ((x) << 17) 129 #define TME_M68K_EXCEPTION_IS_INST(x) ((x) >> 17) 130 131 /* exception frame formats: */ 132 #define TME_M68K_FORMAT_0 (0) 133 #define TME_M68K_FORMAT_1 (1) 134 #define TME_M68K_FORMAT_2 (2) 135 #define TME_M68K_FORMAT_8 (8) 136 #define TME_M68K_FORMAT_B (0xB) 137 138 /* exception vectors: */ 139 #define TME_M68K_VECTOR_RESET_PC (0x00) 140 #define TME_M68K_VECTOR_RESET_SP (0x01) 141 #define TME_M68K_VECTOR_BERR (0x02) 142 #define TME_M68K_VECTOR_AERR (0x03) 143 #define TME_M68K_VECTOR_ILL (0x04) 144 #define TME_M68K_VECTOR_DIV0 (0x05) 145 #define TME_M68K_VECTOR_CHK (0x06) 146 #define TME_M68K_VECTOR_TRAP (0x07) 147 #define TME_M68K_VECTOR_PRIV (0x08) 148 #define TME_M68K_VECTOR_TRACE (0x09) 149 #define TME_M68K_VECTOR_LINE_A (0x0a) 150 #define TME_M68K_VECTOR_LINE_F (0x0b) 151 /* (0x0c is unassigned, reserved) */ 152 #define TME_M68K_VECTOR_COPROC (0x0d) 153 #define TME_M68K_VECTOR_FORMAT (0x0e) 154 #define TME_M68K_VECTOR_INT_UNINIT (0x0f) 155 /* (0x10 through 0x17 are unassigned, reserved) */ 156 #define TME_M68K_VECTOR_SPURIOUS (0x18) 157 /* (0x19 through 0x1f are the interrupt autovectors) */ 158 #define TME_M68K_VECTOR_TRAP_0 (0x20) 159 /* (0x21 through 0x2f are also TRAP vectors) */ 160 161 /* m6888x type specifiers: */ 162 #define TME_M6888X_TYPE_LONG (0) 163 #define TME_M6888X_TYPE_SINGLE (1) 164 #define TME_M6888X_TYPE_EXTENDED80 (2) 165 #define TME_M6888X_TYPE_PACKEDDEC (3) 166 #define TME_M6888X_TYPE_WORD (4) 167 #define TME_M6888X_TYPE_DOUBLE (5) 168 #define TME_M6888X_TYPE_BYTE (6) 169 #define TME_M6888X_TYPE_PACKEDDEC_DK (7) 170 #define TME_M6888X_TYPE_INVALID (TME_M6888X_TYPE_PACKEDDEC_DK) 171 172 /* sizes: */ 173 #define TME_M68K_SIZE_UNDEF (-1) 174 #define TME_M68K_SIZE_UNSIZED (0) 175 #define TME_M68K_SIZE_8 (1) 176 #define TME_M68K_SIZE_16 (2) 177 /* 3 unused */ 178 #define TME_M68K_SIZE_32 (4) 179 /* 5 unused */ 180 /* 6 unused */ 181 /* 7 unused */ 182 #define TME_M68K_SIZE_64 (8) 183 /* 8 unused */ 184 /* 9 unused */ 185 /* 10 unused */ 186 /* 11 unused */ 187 #define TME_M68K_SIZE_96 (12) 188 189 /* opcode parameters: */ 190 191 /* bits 0 through 7, in the opcode map, are the instruction index. 192 immediately after the initial decoding, these bits are replaced 193 with the least significant 8 bits of the opcode word, making bits 0 194 through 2 any EA reg value, and bits 3 through 5 any EA mode 195 value: */ 196 #define TME_M68K_OPCODE_INSN(x) ((x) << 0) 197 #define TME_M68K_OPCODE_INSN_MASK TME_M68K_OPCODE_INSN(0xff) 198 #define TME_M68K_OPCODE_INSN_WHICH(params) TME_FIELD_MASK_EXTRACTU(params, TME_M68K_OPCODE_INSN(0xff)) 199 #define TME_M68K_OPCODE_EA_REG(x) ((x) << 0) 200 #define TME_M68K_OPCODE_EA_MODE(x) ((x) << 3) 201 #define TME_M68K_OPCODE_EA_REG_MASK TME_M68K_OPCODE_EA_REG(0x7) 202 #define TME_M68K_OPCODE_EA_MODE_MASK TME_M68K_OPCODE_EA_MODE(0x7) 203 #define TME_M68K_OPCODE_EA_MODE_WHICH(params) TME_FIELD_MASK_EXTRACTU(params, TME_M68K_OPCODE_EA_MODE_MASK) 204 #define TME_M68K_OPCODE_EA_REG_WHICH(params) TME_FIELD_MASK_EXTRACTU(params, TME_M68K_OPCODE_EA_REG_MASK) 205 206 /* bits 8 through 15 and 16 through 23 are the operands' ic offsets: */ 207 #define _TME_M68K_OPCODE_OP(f) ((tme_uint8_t) (((tme_uint8_t *) &((struct tme_m68k *) 0)->f) - ((tme_uint8_t *) (struct tme_m68k *) 0))) 208 #define TME_M68K_OPCODE_OP1(f) (_TME_M68K_OPCODE_OP(f) << 8) 209 #define TME_M68K_OPCODE_OP0(f) (_TME_M68K_OPCODE_OP(f) << 16) 210 #define TME_M68K_OPCODE_OP1_WHICH(ic, params) (((tme_uint8_t *) (ic)) + TME_FIELD_MASK_EXTRACTU(params, 0x0000ff00)) 211 #define TME_M68K_OPCODE_OP0_WHICH(ic, params) (((tme_uint8_t *) (ic)) + TME_FIELD_MASK_EXTRACTU(params, 0x00ff0000)) 212 213 /* bits 24 and 25 give the size of any immediate operand: */ 214 #define TME_M68K_OPCODE_IMM_16 TME_BIT(24) 215 #define TME_M68K_OPCODE_IMM_32 TME_BIT(25) 216 #define TME_M68K_OPCODE_HAS_IMM(params) (((params) & (TME_M68K_OPCODE_IMM_16 | TME_M68K_OPCODE_IMM_32)) != 0) 217 218 /* bit 26 is set for a move instruction with a memory destination 219 ((TME_M68K_OPCODE_SPECOP is additionally set for a 220 move-memory-to-memory instruction). 221 bit 27 is set for an opcode that needs its EA read. 222 bit 28 is set for an opcode that needs its EA written. 223 224 if the EA needs to be read or written, bits 29 and 30 give the size 225 of the EA, which can be TME_M68K_SIZE_8, TME_M68K_SIZE_16, or 226 TME_M68K_SIZE_32, encoded as (TME_M68K_SIZE_32 - size). if the EA 227 doesn't need to be read or written, but the EA must be calculated, 228 bit 29 is set, and size of the EA is understood to be 229 TME_M68K_SIZE_UNSIZED: */ 230 #define TME_M68K_OPCODE_EA_Y TME_BIT(26) 231 #define TME_M68K_OPCODE_EA_READ TME_BIT(27) 232 #define TME_M68K_OPCODE_EA_WRITE TME_BIT(28) 233 #define TME_M68K_OPCODE_EA_UNSIZED TME_BIT(29) 234 #define TME_M68K_OPCODE_EA_SIZE(x) ((TME_M68K_SIZE_32 - (x)) * TME_M68K_OPCODE_EA_UNSIZED) 235 #define TME_M68K_OPCODE_EA_SIZE_MASK TME_M68K_OPCODE_EA_SIZE(1) 236 #define TME_M68K_OPCODE_HAS_EA(params) ((params) & (TME_M68K_OPCODE_EA_READ | TME_M68K_OPCODE_EA_WRITE | TME_M68K_OPCODE_EA_UNSIZED)) 237 #define TME_M68K_OPCODE_EA_SIZE_WHICH(params) \ 238 (((params) & (TME_M68K_OPCODE_EA_READ | TME_M68K_OPCODE_EA_WRITE)) ? \ 239 (TME_M68K_SIZE_32 \ 240 - TME_FIELD_MASK_EXTRACTU(params, TME_M68K_OPCODE_EA_SIZE_MASK)) \ 241 : TME_M68K_SIZE_UNSIZED) 242 243 /* if the opcode is special, bit 31 is set: */ 244 #define TME_M68K_OPCODE_SPECOP TME_BIT(31) 245 246 /* major modes of the emulator: */ 247 #define TME_M68K_MODE_EXECUTION (0) 248 #define TME_M68K_MODE_EXCEPTION (1) 249 #define TME_M68K_MODE_RTE (2) 250 #define TME_M68K_MODE_STOP (3) 251 #define TME_M68K_MODE_HALT (4) 252 253 /* mode-specific flags: */ 254 #define TME_M68K_EXECUTION_INST_CANFAULT TME_BIT(0) 255 256 /* given a linear address, this hashes it into a TLB entry: */ 257 #define _TME_M68K_TLB_HASH_SIZE (1024) 258 #define TME_M68K_TLB_ADDRESS_BIAS(n) ((n) << 10) 259 #define TME_M68K_DTLB_ENTRY(ic, context, function_code, linear_address) \ 260 (((ic)->_tme_m68k_tlb_array \ 261 + ((((context) * 16) \ 262 + ((linear_address) \ 263 / TME_M68K_TLB_ADDRESS_BIAS(1))) \ 264 % _TME_M68K_TLB_HASH_SIZE)) \ 265 + (0 && (function_code))) 266 267 /* macros for sequence control: */ 268 #define TME_M68K_SEQUENCE_START \ 269 do { \ 270 ic->_tme_m68k_sequence._tme_m68k_sequence_mode_flags = 0; \ 271 ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted = 0; \ 272 ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next = 1; \ 273 } while (/* CONSTCOND */ 0) 274 #define TME_M68K_SEQUENCE_RESTARTING \ 275 (ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted \ 276 >= ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next) 277 #define TME_M68K_SEQUENCE_RESTART \ 278 do { \ 279 if (!TME_M68K_SEQUENCE_RESTARTING) \ 280 ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted = \ 281 ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next; \ 282 ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next = 1; \ 283 } while (/* CONSTCOND */ 0) 284 #define TME_M68K_SEQUENCE_TRANSFER_STEP \ 285 do { \ 286 ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next++; \ 287 } while (/* CONSTCOND */ 0) 288 289 /* instruction handler macros: */ 290 #define TME_M68K_INSN_DECL(name) void name _TME_P((struct tme_m68k *, void *, void *)) 291 #ifdef __STDC__ 292 #define TME_M68K_INSN(name) void name(struct tme_m68k *ic, void *_op0, void *_op1) 293 #else /* !__STDC__ */ 294 #define TME_M68K_INSN(name) void name(ic, _op0, _op1) struct tme_m68k *ic; void *_op0, *_op1; 295 #endif /* !__STDC__ */ 296 #define TME_M68K_INSN_OP0(t) (*((t *) _op0)) 297 #define TME_M68K_INSN_OP1(t) (*((t *) _op1)) 298 #define TME_M68K_INSN_OPCODE ic->_tme_m68k_insn_opcode 299 #define TME_M68K_INSN_SPECOP ic->_tme_m68k_insn_specop 300 #define TME_M68K_INSN_OK return 301 #define TME_M68K_INSN_EXCEPTION(e) tme_m68k_exception(ic, e) 302 #define TME_M68K_INSN_PRIV \ 303 if (!TME_M68K_PRIV(ic)) \ 304 TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_PRIV) 305 #define TME_M68K_INSN_ILL \ 306 TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_ILL) 307 #define TME_M68K_INSN_CANFAULT \ 308 do { \ 309 ic->_tme_m68k_mode_flags \ 310 |= TME_M68K_EXECUTION_INST_CANFAULT; \ 311 } while (/* CONSTCOND */ 0) 312 #define TME_M68K_INSN_BRANCH(pc) \ 313 do { \ 314 tme_m68k_verify_end_branch(ic, pc); \ 315 ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next = (pc); \ 316 if (__tme_predict_false((ic->tme_m68k_ireg_sr \ 317 & ic->_tme_m68k_sr_mask_t) != 0)) { \ 318 TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_TRACE); \ 319 } \ 320 if (tme_m68k_go_slow(ic)) { \ 321 TME_M68K_SEQUENCE_START; \ 322 tme_m68k_redispatch(ic); \ 323 } \ 324 } while (/* CONSTCOND */ 0) 325 #define TME_M68K_INSN_CHANGE_SR(reg) \ 326 do { \ 327 TME_M68K_INSN_PRIV; \ 328 tme_m68k_change_sr(ic, reg); \ 329 tme_m68k_verify_end_branch(ic, ic->tme_m68k_ireg_pc_next); \ 330 if (__tme_predict_false((ic->tme_m68k_ireg_sr \ 331 & ic->_tme_m68k_sr_mask_t) != 0)) { \ 332 ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc; \ 333 ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next; \ 334 TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_TRACE); \ 335 } \ 336 if (tme_m68k_go_slow(ic)) { \ 337 TME_M68K_SEQUENCE_START; \ 338 tme_m68k_redispatch(ic); \ 339 } \ 340 } while (/* CONSTCOND */ 0) 341 342 /* logging: */ 343 #define TME_M68K_LOG_HANDLE(ic) \ 344 (&(ic)->tme_m68k_element->tme_element_log_handle) 345 #define tme_m68k_log_start(ic, level, rc) \ 346 do { \ 347 tme_log_start(TME_M68K_LOG_HANDLE(ic), level, rc) { \ 348 if ((ic)->_tme_m68k_mode != TME_M68K_MODE_EXECUTION) { \ 349 tme_log_part(TME_M68K_LOG_HANDLE(ic), \ 350 "mode=%d ", \ 351 (ic)->_tme_m68k_mode); \ 352 } \ 353 else { \ 354 tme_log_part(TME_M68K_LOG_HANDLE(ic), \ 355 "pc=%c/0x%08x ", \ 356 (((ic)->tme_m68k_ireg_sr \ 357 & (TME_M68K_FLAG_M \ 358 | TME_M68K_FLAG_S)) \ 359 ? 'S' \ 360 : 'U'), \ 361 ic->tme_m68k_ireg_pc); \ 362 } \ 363 do 364 #define tme_m68k_log_finish(ic) \ 365 while (/* CONSTCOND */ 0); \ 366 } tme_log_finish(TME_M68K_LOG_HANDLE(ic)); \ 367 } while (/* CONSTCOND */ 0) 368 #define tme_m68k_log(ic, level, rc, x) \ 369 do { \ 370 tme_m68k_log_start(ic, level, rc) { \ 371 tme_log_part x; \ 372 } tme_m68k_log_finish(ic); \ 373 } while (/* CONSTCOND */ 0) 374 375 /* miscellaneous: */ 376 #define TME_M68K_PRIV(ic) ((ic)->tme_m68k_ireg_sr & TME_M68K_FLAG_S) 377 #define TME_M68K_FUNCTION_CODE_DATA(ic) \ 378 (TME_M68K_PRIV(ic) ? TME_M68K_FC_SD : TME_M68K_FC_UD) 379 #define TME_M68K_FUNCTION_CODE_PROGRAM(ic) \ 380 (TME_M68K_PRIV(ic) ? TME_M68K_FC_SP : TME_M68K_FC_UP) 381 #define TME_M68K_INSN_WORDS_MAX (11) 382 383 /* structures: */ 384 struct tme_m68k; 385 386 /* an memory read or write function: */ 387 typedef void (*_tme_m68k_xfer_memx) _TME_P((struct tme_m68k *)); 388 typedef void (*_tme_m68k_xfer_mem) _TME_P((struct tme_m68k *, int)); 389 390 /* an insn function: */ 391 typedef TME_M68K_INSN_DECL((*_tme_m68k_insn)); 392 393 /* an m68k sequence: */ 394 struct _tme_m68k_sequence { 395 396 /* the mode of the emulator: */ 397 unsigned int _tme_m68k_sequence_mode; 398 399 /* any mode-specific flags for the sequence: */ 400 unsigned int _tme_m68k_sequence_mode_flags; 401 402 /* the ordinal of the next memory transfer. always starts from one: */ 403 unsigned short _tme_m68k_sequence_transfer_next; 404 405 /* the ordinal of the memory transfer that faulted. if this is 406 greater than or equal to _tme_m68k_sequence_transfer_next, we are 407 restarting, and bus cycles and changes to the m68k state are 408 forbidden: */ 409 unsigned short _tme_m68k_sequence_transfer_faulted; 410 411 /* the fault happened after this number of bytes were successfully 412 transferred: */ 413 unsigned short _tme_m68k_sequence_transfer_faulted_after; 414 415 #ifdef _TME_M68K_VERIFY 416 /* the sequence unique identifier: */ 417 unsigned long _tme_m68k_sequence_uid; 418 #endif /* _TME_M68K_VERIFY */ 419 }; 420 421 /* the m68k state: */ 422 struct tme_m68k { 423 424 /* the IC data structure. it is beneficial to have this structure 425 first, since register numbers can often simply be scaled and 426 added without an offset to the struct tme_m68k pointer to get 427 to their contents: */ 428 struct tme_ic tme_m68k_ic; 429 430 /* the m68k type: */ 431 int tme_m68k_type; 432 433 /* the backpointer to our element: */ 434 struct tme_element *tme_m68k_element; 435 436 /* our bus connection. if both are defined, the m68k bus connection 437 is an adaptation layer for the generic bus connection: */ 438 struct tme_m68k_bus_connection *_tme_m68k_bus_connection; 439 struct tme_bus_connection *_tme_m68k_bus_generic; 440 441 /* a jmp_buf back to the dispatcher: */ 442 jmp_buf _tme_m68k_dispatcher; 443 444 /* the current sequence: */ 445 struct _tme_m68k_sequence _tme_m68k_sequence; 446 #define _tme_m68k_mode _tme_m68k_sequence._tme_m68k_sequence_mode 447 #define _tme_m68k_mode_flags _tme_m68k_sequence._tme_m68k_sequence_mode_flags 448 #define _tme_m68k_insn_uid _tme_m68k_sequence._tme_m68k_sequence_uid 449 450 /* the CPU-dependent functions for the different modes: */ 451 void (*_tme_m68k_mode_execute) _TME_P((struct tme_m68k *)); 452 void (*_tme_m68k_mode_exception) _TME_P((struct tme_m68k *)); 453 void (*_tme_m68k_mode_rte) _TME_P((struct tme_m68k *)); 454 455 /* the CPU-dependent status register T bits mask: */ 456 tme_uint16_t _tme_m68k_sr_mask_t; 457 458 /* the instruction burst count, and the remaining burst: */ 459 unsigned int _tme_m68k_instruction_burst; 460 unsigned int _tme_m68k_instruction_burst_remaining; 461 462 /* the effective address: */ 463 #define _tme_m68k_ea_address tme_m68k_ireg_ea 464 unsigned int _tme_m68k_ea_function_code; 465 466 /* instruction fetch information: */ 467 tme_uint16_t _tme_m68k_insn_fetch_buffer[TME_M68K_INSN_WORDS_MAX]; 468 #define _tme_m68k_insn_opcode _tme_m68k_insn_fetch_buffer[0] 469 #define _tme_m68k_insn_specop _tme_m68k_insn_fetch_buffer[1] 470 struct tme_m68k_tlb *_tme_m68k_insn_fetch_fast_itlb; 471 const tme_shared tme_uint8_t *_tme_m68k_insn_fetch_fast_start; 472 const tme_shared tme_uint8_t *_tme_m68k_insn_fetch_fast_next; 473 const tme_shared tme_uint8_t *_tme_m68k_insn_fetch_fast_last; 474 unsigned int _tme_m68k_insn_fetch_slow_next; 475 unsigned int _tme_m68k_insn_fetch_slow_count_fast; 476 unsigned int _tme_m68k_insn_fetch_slow_count_total; 477 478 /* the TLB set: */ 479 struct tme_m68k_tlb _tme_m68k_tlb_array[_TME_M68K_TLB_HASH_SIZE + 1]; 480 #define _tme_m68k_itlb _tme_m68k_tlb_array[_TME_M68K_TLB_HASH_SIZE] 481 482 /* the bus context: */ 483 tme_bus_context_t _tme_m68k_bus_context; 484 485 /* exception handling information: */ 486 tme_uint32_t _tme_m68k_exceptions; 487 488 /* this must be one iff this CPU has a 16-bit bus, else zero: */ 489 tme_uint32_t _tme_m68k_bus_16bit; 490 491 /* group 0 exception information: */ 492 void (*_tme_m68k_group0_hook) _TME_P((struct tme_m68k *)); 493 unsigned int _tme_m68k_group0_flags; 494 unsigned int _tme_m68k_group0_function_code; 495 tme_uint32_t _tme_m68k_group0_address; 496 struct _tme_m68k_sequence _tme_m68k_group0_sequence; 497 tme_uint8_t _tme_m68k_group0_buffer_read[sizeof(tme_uint32_t)]; 498 unsigned int _tme_m68k_group0_buffer_read_size; 499 unsigned int _tme_m68k_group0_buffer_read_softrr; 500 tme_uint8_t _tme_m68k_group0_buffer_write[sizeof(tme_uint32_t)]; 501 unsigned int _tme_m68k_group0_buffer_write_size; 502 unsigned int _tme_m68k_group0_buffer_write_softrr; 503 504 /* the external request lines: */ 505 tme_mutex_t tme_m68k_external_mutex; 506 tme_cond_t tme_m68k_external_cond; 507 unsigned int tme_m68k_external_reset; 508 unsigned int tme_m68k_external_halt; 509 unsigned int tme_m68k_external_ipl; 510 unsigned int tme_m68k_external_ipl_previous_nmi; 511 512 /* any FPU state: */ 513 int tme_m68k_fpu_enabled; 514 int tme_m68k_fpu_type; 515 struct tme_ieee754_ctl tme_m68k_fpu_ieee754_ctl; 516 _tme_const struct tme_ieee754_ops *tme_m68k_fpu_ieee754_ops; 517 struct tme_float tme_m68k_fpu_fpreg[8]; 518 tme_uint32_t tme_m68k_fpu_fpcr; 519 tme_uint32_t tme_m68k_fpu_fpsr; 520 tme_uint32_t tme_m68k_fpu_fpiar; 521 int tme_m68k_fpu_incomplete_abort; 522 523 #ifdef _TME_M68K_STATS 524 /* statistics: */ 525 struct { 526 527 /* the total number of instructions executed: */ 528 tme_uint64_t tme_m68k_stats_insns_total; 529 530 /* the total number of instructions executed by the slow executor: */ 531 tme_uint64_t tme_m68k_stats_insns_slow; 532 533 /* the total number of redispatches: */ 534 tme_uint64_t tme_m68k_stats_redispatches; 535 536 /* the total number of data memory operations: */ 537 tme_uint64_t tme_m68k_stats_memory_total; 538 539 /* the total number of ITLB fills: */ 540 tme_uint64_t tme_m68k_stats_itlb_fill; 541 542 /* the total number of DTLB fills: */ 543 tme_uint64_t tme_m68k_stats_dtlb_fill; 544 545 } tme_m68k_stats; 546 #endif /* _TME_M68K_STATS */ 547 }; 548 549 /* the read-modify-write cycle state: */ 550 struct tme_m68k_rmw { 551 552 /* the operand size: */ 553 unsigned int tme_m68k_rmw_size; 554 555 /* the address count, and up to two addresses: */ 556 unsigned int tme_m68k_rmw_address_count; 557 tme_uint32_t tme_m68k_rmw_addresses[2]; 558 559 /* if nonzero, the operand at the corresponding address has been 560 read with a slow bus cycle. address zero is read into the memx 561 register, and address one is read into the memy register: */ 562 unsigned int tme_m68k_rmw_slow_reads[2]; 563 564 /* the TLB entries used by the addresses. if two addresses are 565 sharing one TLB entry, that TLB entry is listed twice: */ 566 struct tme_m68k_tlb *tme_m68k_rmw_tlbs[2]; 567 }; 568 569 /* globals: */ 570 extern const tme_uint16_t _tme_m68k_conditions[32]; 571 extern const _tme_m68k_xfer_memx _tme_m68k_read_memx[5]; 572 extern const _tme_m68k_xfer_memx _tme_m68k_write_memx[5]; 573 extern const _tme_m68k_xfer_mem _tme_m68k_read_mem[5]; 574 extern const _tme_m68k_xfer_mem _tme_m68k_write_mem[5]; 575 extern tme_uint32_t tme_m68k_opcodes_m68000[65536]; 576 extern tme_uint32_t tme_m68k_opcodes_m68010[65536]; 577 extern tme_uint32_t tme_m68k_opcodes_m68020[65536]; 578 extern const _tme_m68k_insn tme_m68k_opcode_insns[]; 579 extern const tme_uint8_t _tme_m6888x_fpgen_opmode_bitmap[128 / 8]; 580 581 /* prototypes: */ 582 int tme_m68k_new _TME_P((struct tme_m68k *, const char * const *, const void *, char **)); 583 void tme_m68k_redispatch _TME_P((struct tme_m68k *)); 584 int tme_m68k_go_slow _TME_P((const struct tme_m68k *)); 585 void tme_m68k_change_sr _TME_P((struct tme_m68k *, tme_uint16_t)); 586 void tme_m68k_external_check _TME_P((struct tme_m68k *, tme_uint32_t)); 587 void tme_m68k_tlb_fill _TME_P((struct tme_m68k *, struct tme_m68k_tlb *, unsigned int, tme_uint32_t, unsigned int)); 588 void tme_m68k_do_reset _TME_P((struct tme_m68k *)); 589 void tme_m68k_callout_unlock _TME_P((struct tme_m68k *ic)); 590 void tme_m68k_callout_relock _TME_P((struct tme_m68k *ic)); 591 592 /* exception support: */ 593 void tme_m68k_exception _TME_P((struct tme_m68k *, tme_uint32_t)); 594 void tme_m68k_exception_process_start _TME_P((struct tme_m68k *, unsigned int)); 595 void tme_m68k_exception_process_finish _TME_P((struct tme_m68k *, tme_uint8_t, tme_uint8_t)); 596 void tme_m68000_exception_process _TME_P((struct tme_m68k *)); 597 void tme_m68020_exception_process _TME_P((struct tme_m68k *)); 598 599 /* rte support: */ 600 tme_uint16_t tme_m68k_rte_start _TME_P((struct tme_m68k *)); 601 void tme_m68k_rte_finish _TME_P((struct tme_m68k *, tme_uint32_t)); 602 603 /* decoder map support: */ 604 void tme_m68k_opcodes_init_m68000 _TME_P((tme_uint32_t *)); 605 void tme_m68k_opcodes_init_m68010 _TME_P((tme_uint32_t *)); 606 void tme_m68k_opcodes_init_m68020 _TME_P((tme_uint32_t *)); 607 608 /* read/modify/write cycle support: */ 609 int tme_m68k_rmw_start _TME_P((struct tme_m68k *, struct tme_m68k_rmw *)); 610 void tme_m68k_rmw_finish _TME_P((struct tme_m68k *, struct tme_m68k_rmw *, int)); 611 612 /* group 0 fault support: */ 613 void tme_m68k_group0_hook_fast _TME_P((struct tme_m68k *)); 614 unsigned int tme_m68k_insn_buffer_empty _TME_P((const struct tme_m68k *, tme_uint8_t *, unsigned int)); 615 unsigned int tme_m68k_insn_buffer_fill _TME_P((struct tme_m68k *, const tme_uint8_t *, unsigned int)); 616 unsigned int tme_m68k_sequence_empty _TME_P((const struct tme_m68k *, tme_uint8_t *, unsigned int)); 617 unsigned int tme_m68k_sequence_fill _TME_P((struct tme_m68k *, const tme_uint8_t *, unsigned int)); 618 619 /* bitfield support: */ 620 unsigned int tme_m68k_bitfield_width _TME_P((struct tme_m68k *)); 621 tme_uint32_t _tme_m68k_bitfield_read _TME_P((struct tme_m68k *, int)); 622 #define tme_m68k_bitfield_read_signed(ic) ((tme_int32_t) _tme_m68k_bitfield_read(ic, TRUE)) 623 #define tme_m68k_bitfield_read_unsigned(ic) _tme_m68k_bitfield_read(ic, FALSE) 624 void tme_m68k_bitfield_write_unsigned _TME_P((struct tme_m68k *, tme_uint32_t, int)); 625 #define tme_m68k_bitfield_write_signed(ic, v, sf) tme_m68k_bitfield_write_unsigned(ic, (tme_uint32_t) (v), sf) 626 627 /* FPU support: */ 628 int tme_m68k_fpu_new _TME_P((struct tme_m68k *, const char * const *, int *, int *, char **)); 629 void tme_m68k_fpu_reset _TME_P((struct tme_m68k *)); 630 void tme_m68k_fpu_usage _TME_P((char **)); 631 632 /* verification: */ 633 void tme_m68k_verify_hook _TME_P((void)); 634 #ifdef _TME_M68K_VERIFY 635 void tme_m68k_verify_init _TME_P((void)); 636 void tme_m68k_verify_begin _TME_P((const struct tme_m68k *, const tme_uint8_t *)); 637 void tme_m68k_verify_mem_any _TME_P((const struct tme_m68k *, 638 unsigned int, tme_uint32_t, 639 tme_uint8_t *, int, int)); 640 void tme_m68k_verify_end_branch _TME_P((const struct tme_m68k *, tme_uint32_t)); 641 void tme_m68k_verify_end _TME_P((const struct tme_m68k *, 642 void (*)(struct tme_m68k *, void *, void *))); 643 #else /* _TME_M68K_VERIFY */ 644 #define tme_m68k_verify_init() do { } while (/* CONSTCOND */ 0) 645 #define tme_m68k_verify_begin(ic, s) do { } while (/* CONSTCOND */ 0) 646 #define tme_m68k_verify_mem_any(ic, fc, a, v, c, rw) do { } while (/* CONSTCOND */ 0) 647 #define tme_m68k_verify_end_branch(ic, pc) do { } while (/* CONSTCOND */ 0) 648 #define tme_m68k_verify_end(ic, f) do { } while (/* CONSTCOND */ 0) 649 #define tme_m68k_verify_hook() do { } while (/* CONSTCOND */ 0) 650 #endif /* _TME_M68K_VERIFY */ 651 #define tme_m68k_verify_mem8(ic, fc, a, v, rw) tme_m68k_verify_mem_any(ic, fc, a, (tme_uint8_t *) &(v), -sizeof(tme_uint8_t), rw) 652 #define tme_m68k_verify_mem16(ic, fc, a, v, rw) tme_m68k_verify_mem_any(ic, fc, a, (tme_uint8_t *) &(v), -sizeof(tme_uint16_t), rw) 653 #define tme_m68k_verify_mem32(ic, fc, a, v, rw) tme_m68k_verify_mem_any(ic, fc, a, (tme_uint8_t *) &(v), -sizeof(tme_uint32_t), rw) 654 655 /* instruction functions: */ 656 TME_M68K_INSN_DECL(tme_m68k_illegal); 657 TME_M68K_INSN_DECL(tme_m68k_exg); 658 TME_M68K_INSN_DECL(tme_m68k_extw); 659 TME_M68K_INSN_DECL(tme_m68k_extl); 660 TME_M68K_INSN_DECL(tme_m68k_extbl); 661 TME_M68K_INSN_DECL(tme_m68k_lea); 662 TME_M68K_INSN_DECL(tme_m68k_move_from_ccr); 663 TME_M68K_INSN_DECL(tme_m68k_move_from_sr); 664 TME_M68K_INSN_DECL(tme_m68k_move_from_sr0); 665 TME_M68K_INSN_DECL(tme_m68k_swap); 666 TME_M68K_INSN_DECL(tme_m68k_nop); 667 TME_M68K_INSN_DECL(tme_m68k_scc); 668 TME_M68K_INSN_DECL(tme_m68k_dbcc); 669 TME_M68K_INSN_DECL(tme_m68k_bcc); 670 TME_M68K_INSN_DECL(tme_m68k_bccl); 671 TME_M68K_INSN_DECL(tme_m68k_bsr); 672 TME_M68K_INSN_DECL(tme_m68k_bsrl); 673 TME_M68K_INSN_DECL(tme_m68k_pea); 674 TME_M68K_INSN_DECL(tme_m68k_bkpt); 675 TME_M68K_INSN_DECL(tme_m68k_tas); 676 TME_M68K_INSN_DECL(tme_m68k_tas_r); 677 TME_M68K_INSN_DECL(tme_m68k_move_usp); 678 TME_M68K_INSN_DECL(tme_m68k_trap); 679 TME_M68K_INSN_DECL(tme_m68k_trapv); 680 TME_M68K_INSN_DECL(tme_m68k_link); 681 TME_M68K_INSN_DECL(tme_m68k_unlk); 682 TME_M68K_INSN_DECL(tme_m68k_movec); 683 TME_M68K_INSN_DECL(tme_m68k_reset); 684 TME_M68K_INSN_DECL(tme_m68k_rtd); 685 TME_M68K_INSN_DECL(tme_m68k_rtr); 686 TME_M68K_INSN_DECL(tme_m68k_rts); 687 TME_M68K_INSN_DECL(tme_m68k_jsr); 688 TME_M68K_INSN_DECL(tme_m68k_jmp); 689 TME_M68K_INSN_DECL(tme_m68k_rte); 690 TME_M68K_INSN_DECL(tme_m68k_stop); 691 TME_M68K_INSN_DECL(tme_m68k_priv); 692 TME_M68K_INSN_DECL(tme_m68k_cmp2_chk2); 693 TME_M68K_INSN_DECL(tme_m68k_callm); 694 TME_M68K_INSN_DECL(tme_m68k_rtm); 695 TME_M68K_INSN_DECL(tme_m68k_trapcc); 696 TME_M68K_INSN_DECL(tme_m68k_bfchg); 697 TME_M68K_INSN_DECL(tme_m68k_bfclr); 698 TME_M68K_INSN_DECL(tme_m68k_bfexts); 699 TME_M68K_INSN_DECL(tme_m68k_bfextu); 700 TME_M68K_INSN_DECL(tme_m68k_bfffo); 701 TME_M68K_INSN_DECL(tme_m68k_bfins); 702 TME_M68K_INSN_DECL(tme_m68k_bfset); 703 TME_M68K_INSN_DECL(tme_m68k_bftst); 704 TME_M68K_INSN_DECL(tme_m68k_pack); 705 TME_M68K_INSN_DECL(tme_m68k_unpk); 706 TME_M68K_INSN_DECL(tme_m68k_fpgen); 707 TME_M68K_INSN_DECL(tme_m68k_fmovemctl); 708 TME_M68K_INSN_DECL(tme_m68k_fmovem); 709 TME_M68K_INSN_DECL(tme_m68k_fmove_rm); 710 TME_M68K_INSN_DECL(tme_m68k_fdbcc); 711 TME_M68K_INSN_DECL(tme_m68k_ftrapcc); 712 TME_M68K_INSN_DECL(tme_m68k_fscc); 713 TME_M68K_INSN_DECL(tme_m68k_fbcc); 714 TME_M68K_INSN_DECL(tme_m68k_fsave); 715 TME_M68K_INSN_DECL(tme_m68k_frestore); 716 TME_M68K_INSN_DECL(tme_m68k_divl); 717 TME_M68K_INSN_DECL(tme_m68k_mull); 718 719 #endif /* !_IC_M68K_IMPL_H */ 720 721 /* the automatically-generated header information: */ 722 #include <m68k-auto.h> 723