Annotation of tme/ic/m68k/m68k-impl.h, revision 1.1.1.3

1.1.1.3 ! root        1: /* $Id: m68k-impl.h,v 1.16 2005/03/23 12:12:37 fredette Exp $ */
1.1       root        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>
1.1.1.3 ! root       40: _TME_RCSID("$Id: m68k-impl.h,v 1.16 2005/03/23 12:12:37 fredette Exp $");
1.1       root       41: 
                     42: /* includes: */
                     43: #include <tme/ic/m68k.h>
1.1.1.3 ! root       44: #include <tme/ic/ieee754.h>
1.1       root       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)
1.1.1.3 ! root       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)
1.1       root       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)
1.1.1.3 ! root       82: #define TME_M68K_FLAG_T0       TME_BIT(14)
        !            83: #define TME_M68K_FLAG_T1       TME_BIT(15)
1.1       root       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 | \
1.1.1.3 ! root       89:                                 TME_M68K_FLAG_T0 | TME_M68K_FLAG_T1)
1.1       root       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)
1.1.1.3 ! root      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)
1.1       root      130: 
                    131: /* exception frame formats: */
                    132: #define TME_M68K_FORMAT_0      (0)
1.1.1.3 ! root      133: #define TME_M68K_FORMAT_1      (1)
        !           134: #define TME_M68K_FORMAT_2      (2)
1.1       root      135: #define TME_M68K_FORMAT_8      (8)
1.1.1.3 ! root      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)
1.1       root      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)
1.1.1.3 ! root      177:                                /* 3 unused */
1.1       root      178: #define TME_M68K_SIZE_32       (4)
1.1.1.3 ! root      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)
1.1       root      242: 
1.1.1.3 ! root      243: /* if the opcode is special, bit 31 is set: */
        !           244: #define TME_M68K_OPCODE_SPECOP         TME_BIT(31)
1.1       root      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_ENTRY(ic, function_code, linear_address) \
                    259:   (TME_ATOMIC_READ(struct tme_m68k_tlb *, (ic)->_tme_m68k_tlb_array) \
                    260:     + ((linear_address >> 10) & (_TME_M68K_TLB_HASH_SIZE - 1)))
                    261: 
                    262: /* macros for sequence control: */
                    263: #define TME_M68K_SEQUENCE_START                                                \
                    264: do {                                                                   \
                    265:   ic->_tme_m68k_sequence._tme_m68k_sequence_mode_flags = 0;            \
                    266:   ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted = 0;      \
                    267:   ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next = 1;         \
                    268: } while (/* CONSTCOND */ 0)
                    269: #define TME_M68K_SEQUENCE_RESTARTING                                   \
                    270:   (ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted          \
                    271:    >= ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next)
                    272: #define TME_M68K_SEQUENCE_RESTART                                      \
                    273: do {                                                                   \
                    274:   if (!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:   ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next = 1;         \
                    278: } while (/* CONSTCOND */ 0)
                    279: #define TME_M68K_SEQUENCE_TRANSFER_STEP                                        \
                    280: do {                                                                   \
                    281:   ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next++;           \
                    282: } while (/* CONSTCOND */ 0)
                    283: 
                    284: /* instruction handler macros: */
                    285: #define TME_M68K_INSN_DECL(name) void name _TME_P((struct tme_m68k *, void *, void *))
                    286: #ifdef __STDC__
                    287: #define TME_M68K_INSN(name) void name(struct tme_m68k *ic, void *_op0, void *_op1)
                    288: #else  /* !__STDC__ */
                    289: #define TME_M68K_INSN(name) void name(ic, _op0, _op1) struct tme_m68k *ic; void *_op0, *_op1;
                    290: #endif /* !__STDC__ */
                    291: #define TME_M68K_INSN_OP0(t)           (*((t *) _op0))
                    292: #define TME_M68K_INSN_OP1(t)           (*((t *) _op1))
                    293: #define TME_M68K_INSN_OPCODE           ic->_tme_m68k_insn_opcode
                    294: #define TME_M68K_INSN_SPECOP           ic->_tme_m68k_insn_specop
                    295: #define TME_M68K_INSN_OK               return
                    296: #define TME_M68K_INSN_EXCEPTION(e)     tme_m68k_exception(ic, e)
                    297: #define TME_M68K_INSN_PRIV                     \
                    298:   if (!TME_M68K_PRIV(ic))      \
1.1.1.3 ! root      299:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_PRIV)
1.1       root      300: #define TME_M68K_INSN_ILL                      \
1.1.1.3 ! root      301:   TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_ILL)
1.1       root      302: #define TME_M68K_INSN_CANFAULT                 \
                    303: do {                                           \
                    304:   ic->_tme_m68k_mode_flags                     \
                    305:     |= TME_M68K_EXECUTION_INST_CANFAULT;       \
                    306: } while (/* CONSTCOND */ 0)
                    307: #define TME_M68K_INSN_BRANCH(pc)                               \
                    308: do {                                                           \
                    309:   tme_m68k_verify_end_branch(ic, pc);                          \
                    310:   ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next = (pc);     \
1.1.1.3 ! root      311:   if (__tme_predict_false((ic->tme_m68k_ireg_sr                        \
        !           312:                           & ic->_tme_m68k_sr_mask_t) != 0)) {  \
        !           313:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_TRACE);         \
        !           314:   }                                                            \
1.1       root      315:   if (tme_m68k_go_slow(ic)) {                                  \
                    316:     TME_M68K_SEQUENCE_START;                                   \
                    317:     tme_m68k_redispatch(ic);                                   \
                    318:   }                                                            \
                    319: } while (/* CONSTCOND */ 0)
                    320: #define TME_M68K_INSN_CHANGE_SR(reg)                           \
                    321: do {                                                           \
                    322:   TME_M68K_INSN_PRIV;                                          \
                    323:   tme_m68k_change_sr(ic, reg);                                 \
1.1.1.3 ! root      324:   tme_m68k_verify_end_branch(ic, ic->tme_m68k_ireg_pc_next);   \
        !           325:   if (__tme_predict_false((ic->tme_m68k_ireg_sr                        \
        !           326:                           & ic->_tme_m68k_sr_mask_t) != 0)) {  \
        !           327:     ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc;          \
        !           328:     ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;          \
        !           329:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_TRACE);         \
        !           330:   }                                                            \
        !           331:   if (tme_m68k_go_slow(ic)) {                                  \
        !           332:     TME_M68K_SEQUENCE_START;                                   \
        !           333:     tme_m68k_redispatch(ic);                                   \
        !           334:   }                                                            \
1.1       root      335: } while (/* CONSTCOND */ 0)
                    336: 
                    337: /* logging: */
                    338: #define TME_M68K_LOG_HANDLE(ic)                                        \
                    339:   (&(ic)->tme_m68k_element->tme_element_log_handle)
                    340: #define tme_m68k_log_start(ic, level, rc)                      \
                    341: do {                                                           \
                    342:   tme_log_start(TME_M68K_LOG_HANDLE(ic), level, rc) {          \
                    343:     if ((ic)->_tme_m68k_mode != TME_M68K_MODE_EXECUTION) {     \
                    344:       tme_log_part(TME_M68K_LOG_HANDLE(ic),                    \
                    345:                    "mode=%d ",                                 \
                    346:                    (ic)->_tme_m68k_mode);                      \
                    347:     }                                                          \
                    348:     else {                                                     \
                    349:       tme_log_part(TME_M68K_LOG_HANDLE(ic),                    \
                    350:                   "pc=%c/0x%08x ",                             \
                    351:                   (((ic)->tme_m68k_ireg_sr                     \
                    352:                     & (TME_M68K_FLAG_M                         \
                    353:                        | TME_M68K_FLAG_S))                     \
                    354:                    ? 'S'                                       \
                    355:                    : 'U'),                                     \
                    356:                   ic->tme_m68k_ireg_pc);                       \
                    357:     }                                                          \
                    358:     do
                    359: #define tme_m68k_log_finish(ic)                                        \
                    360:     while (/* CONSTCOND */ 0);                                 \
                    361:   } tme_log_finish(TME_M68K_LOG_HANDLE(ic));                   \
                    362: } while (/* CONSTCOND */ 0)
                    363: #define tme_m68k_log(ic, level, rc, x)         \
                    364: do {                                           \
                    365:   tme_m68k_log_start(ic, level, rc) {          \
                    366:     tme_log_part x;                            \
                    367:   } tme_m68k_log_finish(ic);                   \
                    368: } while (/* CONSTCOND */ 0)
                    369: 
                    370: /* miscellaneous: */
                    371: #define TME_M68K_PRIV(ic)      ((ic)->tme_m68k_ireg_sr & TME_M68K_FLAG_S)
                    372: #define TME_M68K_FUNCTION_CODE_DATA(ic)        \
                    373:   (TME_M68K_PRIV(ic) ? TME_M68K_FC_SD : TME_M68K_FC_UD)
                    374: #define TME_M68K_FUNCTION_CODE_PROGRAM(ic)     \
                    375:   (TME_M68K_PRIV(ic) ? TME_M68K_FC_SP : TME_M68K_FC_UP)
                    376: #define TME_M68K_INSN_WORDS_MAX        (11)
                    377: 
                    378: /* structures: */
                    379: struct tme_m68k;
                    380: 
                    381: /* an memory read or write function: */
                    382: typedef void (*_tme_m68k_xfer_memx) _TME_P((struct tme_m68k *));
                    383: typedef void (*_tme_m68k_xfer_mem) _TME_P((struct tme_m68k *, int));
                    384: 
1.1.1.3 ! root      385: /* an insn function: */
        !           386: typedef TME_M68K_INSN_DECL((*_tme_m68k_insn));
1.1       root      387: 
                    388: /* an m68k sequence: */
                    389: struct _tme_m68k_sequence {
                    390:   
                    391:   /* the mode of the emulator: */
1.1.1.2   root      392:   unsigned int _tme_m68k_sequence_mode;
1.1       root      393: 
                    394:   /* any mode-specific flags for the sequence: */
1.1.1.2   root      395:   unsigned int _tme_m68k_sequence_mode_flags;
1.1       root      396:   
                    397:   /* the ordinal of the next memory transfer.  always starts from one: */
                    398:   unsigned short _tme_m68k_sequence_transfer_next;
                    399: 
                    400:   /* the ordinal of the memory transfer that faulted.  if this is
                    401:      greater than or equal to _tme_m68k_sequence_transfer_next, we are
                    402:      restarting, and bus cycles and changes to the m68k state are
                    403:      forbidden: */
                    404:   unsigned short _tme_m68k_sequence_transfer_faulted;
                    405: 
                    406:   /* the fault happened after this number of bytes were successfully
                    407:      transferred: */
                    408:   unsigned short _tme_m68k_sequence_transfer_faulted_after;
                    409: 
                    410: #ifdef _TME_M68K_VERIFY
                    411:   /* the sequence unique identifier: */
                    412:   unsigned long _tme_m68k_sequence_uid;
                    413: #endif /* _TME_M68K_VERIFY */
                    414: };
                    415: 
                    416: /* the m68k state: */
                    417: struct tme_m68k {
                    418: 
                    419:   /* the IC data structure.  it is beneficial to have this structure
                    420:      first, since register numbers can often simply be scaled and 
                    421:      added without an offset to the struct tme_m68k pointer to get
                    422:      to their contents: */
                    423:   struct tme_ic tme_m68k_ic;
                    424: 
                    425:   /* the m68k type: */
                    426:   int tme_m68k_type;
                    427: 
                    428:   /* the backpointer to our element: */
                    429:   struct tme_element *tme_m68k_element;
                    430: 
                    431:   /* our bus connection.  if both are defined, the m68k bus connection
                    432:      is an adaptation layer for the generic bus connection: */
                    433:   struct tme_m68k_bus_connection *_tme_m68k_bus_connection;
                    434:   struct tme_bus_connection *_tme_m68k_bus_generic;
                    435: 
                    436:   /* a jmp_buf back to the dispatcher: */
                    437:   jmp_buf _tme_m68k_dispatcher;
                    438: 
                    439:   /* the current sequence: */
                    440:   struct _tme_m68k_sequence _tme_m68k_sequence;
                    441: #define _tme_m68k_mode _tme_m68k_sequence._tme_m68k_sequence_mode
                    442: #define _tme_m68k_mode_flags _tme_m68k_sequence._tme_m68k_sequence_mode_flags
                    443: #define _tme_m68k_insn_uid _tme_m68k_sequence._tme_m68k_sequence_uid
                    444: 
                    445:   /* the CPU-dependent functions for the different modes: */
                    446:   void (*_tme_m68k_mode_execute) _TME_P((struct tme_m68k *));
                    447:   void (*_tme_m68k_mode_exception) _TME_P((struct tme_m68k *));
                    448:   void (*_tme_m68k_mode_rte) _TME_P((struct tme_m68k *));
                    449: 
1.1.1.3 ! root      450:   /* the CPU-dependent status register T bits mask: */
        !           451:   tme_uint16_t _tme_m68k_sr_mask_t;
        !           452: 
1.1.1.2   root      453:   /* the instruction decoder root map: */
1.1       root      454:   const struct _tme_m68k_decoder_root *_tme_m68k_decoder_root;
1.1.1.2   root      455: 
                    456:   /* the instruction burst count, and the remaining burst: */
1.1       root      457:   unsigned int _tme_m68k_instruction_burst;
1.1.1.2   root      458:   unsigned int _tme_m68k_instruction_burst_remaining;
1.1       root      459: 
                    460:   /* the effective address: */
1.1.1.3 ! root      461: #define _tme_m68k_ea_address tme_m68k_ireg_ea
1.1       root      462:   unsigned int _tme_m68k_ea_function_code;
                    463: 
                    464:   /* instruction fetch information: */
                    465:   tme_uint16_t _tme_m68k_insn_opcode;
                    466:   tme_uint16_t _tme_m68k_insn_specop;
                    467:   
                    468:   /* the instruction buffer: */
                    469:   tme_uint8_t _tme_m68k_insn_buffer[TME_M68K_INSN_WORDS_MAX * sizeof(tme_uint32_t)];
                    470:   unsigned int _tme_m68k_insn_buffer_off;
                    471:   tme_uint16_t _tme_m68k_insn_buffer_fetch_total;
                    472:   tme_uint16_t _tme_m68k_insn_buffer_fetch_sizes;
                    473: 
                    474:   /* the TLB entry set, and a separate instruction TLB entry set
                    475:      reserved for the executors: */
                    476:   TME_ATOMIC(struct tme_m68k_tlb *, _tme_m68k_tlb_array);
                    477:   TME_ATOMIC(struct tme_m68k_tlb *, _tme_m68k_itlb);
                    478: 
                    479:   /* exception handling information: */
                    480:   tme_uint32_t _tme_m68k_exceptions;
                    481: 
                    482:   /* nonzero iff this CPU has a 16-bit bus: */
                    483:   int _tme_m68k_bus_16bit;
                    484: 
                    485:   /* group 0 exception information: */
                    486:   void (*_tme_m68k_group0_hook) _TME_P((struct tme_m68k *));
                    487:   unsigned int _tme_m68k_group0_flags;
                    488:   unsigned int _tme_m68k_group0_function_code;
                    489:   tme_uint32_t _tme_m68k_group0_address;
                    490:   struct _tme_m68k_sequence _tme_m68k_group0_sequence;
                    491:   tme_uint8_t _tme_m68k_group0_buffer_read[sizeof(tme_uint32_t)];
                    492:   unsigned int _tme_m68k_group0_buffer_read_size;
                    493:   unsigned int _tme_m68k_group0_buffer_read_softrr;
                    494:   tme_uint8_t _tme_m68k_group0_buffer_write[sizeof(tme_uint32_t)];
                    495:   unsigned int _tme_m68k_group0_buffer_write_size;
                    496:   unsigned int _tme_m68k_group0_buffer_write_softrr;
                    497: 
                    498:   /* the external request lines: */
                    499:   tme_mutex_t tme_m68k_external_mutex;
                    500:   tme_cond_t tme_m68k_external_cond;
                    501:   unsigned int tme_m68k_external_reset;
                    502:   unsigned int tme_m68k_external_halt;
                    503:   unsigned int tme_m68k_external_ipl;
1.1.1.3 ! root      504:   unsigned int tme_m68k_external_ipl_previous_nmi;
        !           505: 
        !           506:   /* any FPU state: */
        !           507:   int tme_m68k_fpu_enabled;
        !           508:   int tme_m68k_fpu_type;
        !           509:   struct tme_ieee754_ctl tme_m68k_fpu_ieee754_ctl;
        !           510:   _tme_const struct tme_ieee754_ops *tme_m68k_fpu_ieee754_ops;
        !           511:   struct tme_float tme_m68k_fpu_fpreg[8];
        !           512:   tme_uint32_t tme_m68k_fpu_fpcr;
        !           513:   tme_uint32_t tme_m68k_fpu_fpsr;
        !           514:   tme_uint32_t tme_m68k_fpu_fpiar;
        !           515:   int tme_m68k_fpu_incomplete_abort;
        !           516: 
        !           517: #ifdef _TME_M68K_STATS
        !           518:   /* statistics: */
        !           519:   struct {
        !           520: 
        !           521:     /* the total number of instructions executed: */
        !           522:     tme_uint64_t tme_m68k_stats_insns_total;
        !           523: 
        !           524:     /* the total number of instructions executed by the slow executor: */
        !           525:     tme_uint64_t tme_m68k_stats_insns_slow;
        !           526: 
        !           527:     /* the total number of redispatches: */
        !           528:     tme_uint64_t tme_m68k_stats_redispatches;
        !           529: 
        !           530:     /* the total number of data memory operations: */
        !           531:     tme_uint64_t tme_m68k_stats_memory_total;
        !           532: 
        !           533:     /* the total number of ITLB fills: */
        !           534:     tme_uint64_t tme_m68k_stats_itlb_fill;
        !           535: 
        !           536:     /* the total number of DTLB fills: */
        !           537:     tme_uint64_t tme_m68k_stats_dtlb_fill;
        !           538: 
        !           539:   } tme_m68k_stats;
        !           540: #endif /* _TME_M68K_STATS */
1.1       root      541: };
                    542: 
                    543: /* globals: */
                    544: extern const tme_uint16_t _tme_m68k_conditions[32];
                    545: extern const _tme_m68k_xfer_memx _tme_m68k_read_memx[5];
                    546: extern const _tme_m68k_xfer_memx _tme_m68k_write_memx[5];
                    547: extern const _tme_m68k_xfer_mem _tme_m68k_read_mem[5];
                    548: extern const _tme_m68k_xfer_mem _tme_m68k_write_mem[5];
1.1.1.3 ! root      549: extern tme_uint32_t tme_m68k_opcodes_m68000[65536];
        !           550: extern tme_uint32_t tme_m68k_opcodes_m68010[65536];
        !           551: extern tme_uint32_t tme_m68k_opcodes_m68020[65536];
        !           552: extern const _tme_m68k_insn tme_m68k_opcode_insns[];
        !           553: extern const tme_uint8_t _tme_m6888x_fpgen_opmode_bitmap[128 / 8];
1.1       root      554: 
                    555: /* prototypes: */
                    556: int tme_m68k_new _TME_P((struct tme_m68k *, const char * const *, const void *, char **));
                    557: void tme_m68k_redispatch _TME_P((struct tme_m68k *));
                    558: int tme_m68k_go_slow _TME_P((const struct tme_m68k *));
                    559: void tme_m68k_change_sr _TME_P((struct tme_m68k *, tme_uint16_t));
                    560: void tme_m68k_external_check _TME_P((struct tme_m68k *, tme_uint32_t));
                    561: void tme_m68k_tlb_fill _TME_P((struct tme_m68k *, struct tme_m68k_tlb *, unsigned int, tme_uint32_t, unsigned int));
                    562: void tme_m68k_do_reset _TME_P((struct tme_m68k *));
                    563: 
                    564: /* exception support: */
                    565: void tme_m68k_exception _TME_P((struct tme_m68k *, tme_uint32_t));
                    566: void tme_m68k_exception_process_start _TME_P((struct tme_m68k *, unsigned int));
                    567: void tme_m68k_exception_process_finish _TME_P((struct tme_m68k *, tme_uint8_t, tme_uint8_t));
1.1.1.3 ! root      568: void tme_m68000_exception_process _TME_P((struct tme_m68k *));
        !           569: void tme_m68020_exception_process _TME_P((struct tme_m68k *));
1.1       root      570: 
                    571: /* rte support: */
                    572: tme_uint16_t tme_m68k_rte_start _TME_P((struct tme_m68k *));
                    573: void tme_m68k_rte_finish _TME_P((struct tme_m68k *, tme_uint32_t));
                    574: 
                    575: /* decoder map support: */
1.1.1.3 ! root      576: void tme_m68k_opcodes_init_m68000 _TME_P((tme_uint32_t *));
        !           577: void tme_m68k_opcodes_init_m68010 _TME_P((tme_uint32_t *));
        !           578: void tme_m68k_opcodes_init_m68020 _TME_P((tme_uint32_t *));
1.1       root      579: 
                    580: /* read/modify/write cycle support: */
                    581: struct tme_m68k_tlb *tme_m68k_rmw_start _TME_P((struct tme_m68k *));
                    582: void tme_m68k_rmw_finish _TME_P((struct tme_m68k *, struct tme_m68k_tlb *));
                    583: 
                    584: /* group 0 fault support: */
                    585: int tme_m68k_insn_buffer_xfer _TME_P((struct tme_m68k *, tme_uint8_t *, unsigned int, int));
                    586: void tme_m68k_group0_hook_fast _TME_P((struct tme_m68k *));
                    587: #define tme_m68k_insn_buffer_empty(ic, r, ra) \
                    588:   tme_m68k_insn_buffer_xfer(ic, r, ra, 1)
                    589: #define tme_m68k_insn_buffer_fill(ic, r, ra) \
                    590:   tme_m68k_insn_buffer_xfer(ic, r, ra, 2)
                    591: int tme_m68k_sequence_empty _TME_P((const struct tme_m68k *, tme_uint8_t *, unsigned int));
                    592: int tme_m68k_sequence_fill _TME_P((struct tme_m68k *, const tme_uint8_t *, unsigned int));
                    593: 
                    594: /* bitfield support: */
                    595: unsigned int tme_m68k_bitfield_width _TME_P((struct tme_m68k *));
                    596: tme_uint32_t _tme_m68k_bitfield_read _TME_P((struct tme_m68k *, int));
                    597: #define tme_m68k_bitfield_read_signed(ic) ((tme_int32_t) _tme_m68k_bitfield_read(ic, TRUE))
                    598: #define tme_m68k_bitfield_read_unsigned(ic) _tme_m68k_bitfield_read(ic, FALSE)
                    599: void tme_m68k_bitfield_write_unsigned _TME_P((struct tme_m68k *, tme_uint32_t, int));
                    600: #define tme_m68k_bitfield_write_signed(ic, v, sf) tme_m68k_bitfield_write_unsigned(ic, (tme_uint32_t) (v), sf)
                    601: 
1.1.1.3 ! root      602: /* FPU support: */
        !           603: int tme_m68k_fpu_new _TME_P((struct tme_m68k *, const char * const *, int *, int *, char **));
        !           604: void tme_m68k_fpu_reset _TME_P((struct tme_m68k *));
        !           605: void tme_m68k_fpu_usage _TME_P((char **));
        !           606: 
1.1       root      607: /* verification: */
1.1.1.2   root      608: void tme_m68k_verify_hook _TME_P((void));
1.1       root      609: #ifdef _TME_M68K_VERIFY
                    610: void tme_m68k_verify_init _TME_P((void));
                    611: void tme_m68k_verify_begin _TME_P((const struct tme_m68k *, const tme_uint8_t *));
                    612: void tme_m68k_verify_mem_any _TME_P((const struct tme_m68k *,
                    613:                                     unsigned int, tme_uint32_t,
                    614:                                     tme_uint8_t *, int, int));
                    615: void tme_m68k_verify_end_branch _TME_P((const struct tme_m68k *, tme_uint32_t));
                    616: void tme_m68k_verify_end _TME_P((const struct tme_m68k *,
                    617:                                 void (*)(struct tme_m68k *, void *, void *)));
                    618: #else  /* _TME_M68K_VERIFY */
                    619: #define tme_m68k_verify_init() do { } while (/* CONSTCOND */ 0)
                    620: #define tme_m68k_verify_begin(ic, s) do { } while (/* CONSTCOND */ 0)
                    621: #define tme_m68k_verify_mem_any(ic, fc, a, v, c, rw) do { } while (/* CONSTCOND */ 0)
                    622: #define tme_m68k_verify_end_branch(ic, pc) do { } while (/* CONSTCOND */ 0)
                    623: #define tme_m68k_verify_end(ic, f) do { } while (/* CONSTCOND */ 0)
                    624: #define tme_m68k_verify_hook() do { } while (/* CONSTCOND */ 0)
                    625: #endif /* _TME_M68K_VERIFY */
                    626: #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)
                    627: #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)
                    628: #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)
                    629: 
                    630: /* instruction functions: */
                    631: TME_M68K_INSN_DECL(tme_m68k_illegal);
                    632: TME_M68K_INSN_DECL(tme_m68k_exg);
                    633: TME_M68K_INSN_DECL(tme_m68k_extw);
                    634: TME_M68K_INSN_DECL(tme_m68k_extl);
                    635: TME_M68K_INSN_DECL(tme_m68k_extbl);
                    636: TME_M68K_INSN_DECL(tme_m68k_lea);
                    637: TME_M68K_INSN_DECL(tme_m68k_move_from_ccr);
                    638: TME_M68K_INSN_DECL(tme_m68k_move_from_sr);
                    639: TME_M68K_INSN_DECL(tme_m68k_move_from_sr0);
                    640: TME_M68K_INSN_DECL(tme_m68k_swap);
                    641: TME_M68K_INSN_DECL(tme_m68k_nop);
                    642: TME_M68K_INSN_DECL(tme_m68k_scc);
                    643: TME_M68K_INSN_DECL(tme_m68k_dbcc);
                    644: TME_M68K_INSN_DECL(tme_m68k_bcc);
1.1.1.3 ! root      645: TME_M68K_INSN_DECL(tme_m68k_bccl);
1.1       root      646: TME_M68K_INSN_DECL(tme_m68k_bsr);
1.1.1.3 ! root      647: TME_M68K_INSN_DECL(tme_m68k_bsrl);
1.1       root      648: TME_M68K_INSN_DECL(tme_m68k_pea);
                    649: TME_M68K_INSN_DECL(tme_m68k_bkpt);
                    650: TME_M68K_INSN_DECL(tme_m68k_tas);
                    651: TME_M68K_INSN_DECL(tme_m68k_tas_r);
                    652: TME_M68K_INSN_DECL(tme_m68k_move_usp);
                    653: TME_M68K_INSN_DECL(tme_m68k_trap);
                    654: TME_M68K_INSN_DECL(tme_m68k_trapv);
                    655: TME_M68K_INSN_DECL(tme_m68k_link);
                    656: TME_M68K_INSN_DECL(tme_m68k_unlk);
                    657: TME_M68K_INSN_DECL(tme_m68k_movec);
                    658: TME_M68K_INSN_DECL(tme_m68k_reset);
                    659: TME_M68K_INSN_DECL(tme_m68k_rtd);
                    660: TME_M68K_INSN_DECL(tme_m68k_rtr);
                    661: TME_M68K_INSN_DECL(tme_m68k_rts);
                    662: TME_M68K_INSN_DECL(tme_m68k_jsr);
                    663: TME_M68K_INSN_DECL(tme_m68k_jmp);
                    664: TME_M68K_INSN_DECL(tme_m68k_rte);
                    665: TME_M68K_INSN_DECL(tme_m68k_stop);
                    666: TME_M68K_INSN_DECL(tme_m68k_priv);
                    667: TME_M68K_INSN_DECL(tme_m68k_cmp2_chk2);
                    668: TME_M68K_INSN_DECL(tme_m68k_callm);
                    669: TME_M68K_INSN_DECL(tme_m68k_rtm);
                    670: TME_M68K_INSN_DECL(tme_m68k_trapcc);
                    671: TME_M68K_INSN_DECL(tme_m68k_bfchg);
                    672: TME_M68K_INSN_DECL(tme_m68k_bfclr);
                    673: TME_M68K_INSN_DECL(tme_m68k_bfexts);
                    674: TME_M68K_INSN_DECL(tme_m68k_bfextu);
                    675: TME_M68K_INSN_DECL(tme_m68k_bfffo);
                    676: TME_M68K_INSN_DECL(tme_m68k_bfins);
                    677: TME_M68K_INSN_DECL(tme_m68k_bfset);
                    678: TME_M68K_INSN_DECL(tme_m68k_bftst);
                    679: TME_M68K_INSN_DECL(tme_m68k_pack);
                    680: TME_M68K_INSN_DECL(tme_m68k_unpk);
1.1.1.3 ! root      681: TME_M68K_INSN_DECL(tme_m68k_fpgen);
        !           682: TME_M68K_INSN_DECL(tme_m68k_fmovemctl);
        !           683: TME_M68K_INSN_DECL(tme_m68k_fmovem);
        !           684: TME_M68K_INSN_DECL(tme_m68k_fmove_rm);
        !           685: TME_M68K_INSN_DECL(tme_m68k_fdbcc);
        !           686: TME_M68K_INSN_DECL(tme_m68k_ftrapcc);
        !           687: TME_M68K_INSN_DECL(tme_m68k_fscc);
        !           688: TME_M68K_INSN_DECL(tme_m68k_fbcc);
        !           689: TME_M68K_INSN_DECL(tme_m68k_fsave);
        !           690: TME_M68K_INSN_DECL(tme_m68k_frestore);
        !           691: TME_M68K_INSN_DECL(tme_m68k_divl);
        !           692: TME_M68K_INSN_DECL(tme_m68k_mull);
1.1       root      693: 
                    694: #endif /* !_IC_M68K_IMPL_H */
                    695: 
                    696: /* the automatically-generated header information: */
                    697: #include <m68k-auto.h>

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.