Annotation of previous_trunk/src/dimension/i860.hpp, revision 1.1.1.1

1.1       root        1: /***************************************************************************
                      2: 
                      3:     i860.h
                      4: 
                      5:     Interface file for the Intel i860 emulator.
                      6: 
                      7:     Copyright (C) 1995-present Jason Eckhardt ([email protected])
                      8:     Released for general non-commercial use under the MAME license
                      9:     with the additional requirement that you are free to use and
                     10:     redistribute this code in modified or unmodified form, provided
                     11:     you list me in the credits.
                     12:     Visit http://mamedev.org for licensing and usage restrictions.
                     13: 
                     14:     Changes for previous/NeXTdimension by Simon Schubiger (SC)
                     15: 
                     16: ***************************************************************************/
                     17: 
                     18: #pragma once
                     19: 
                     20: #ifndef __I860_H__
                     21: #define __I860_H__
                     22: 
                     23: #include <stdint.h>
                     24: #include <stdio.h>
                     25: #include <stdarg.h>
                     26: #include <string.h>
                     27: #include <ctype.h>
                     28: #include <assert.h>
                     29: 
                     30: #include "i860cfg.h"
                     31: #include "host.h"
                     32: #include "nd_sdl.hpp"
                     33: 
                     34: typedef uint64_t UINT64;
                     35: typedef int64_t INT64;
                     36: 
                     37: typedef uint32_t UINT32;
                     38: typedef int32_t INT32;
                     39: 
                     40: typedef uint16_t UINT16;
                     41: typedef int16_t INT16;
                     42: 
                     43: typedef uint8_t  UINT8;
                     44: typedef int8_t  INT8;
                     45: 
                     46: typedef int64_t offs_t;
                     47: 
                     48: extern "C" {
                     49:     class NextDimension;
                     50:     
                     51:     void   nd_nbic_interrupt(void);
                     52:     void   Statusbar_SetNdLed(int state);
                     53:     typedef void (*mem_rd_func)(NextDimension*, UINT32, UINT32*);
                     54:     typedef void (*mem_wr_func)(NextDimension*, UINT32, const UINT32*);
                     55: }
                     56: 
                     57: #if WITH_SOFTFLOAT_I860
                     58: extern "C" {
                     59: #include <softfloat.h>
                     60: }
                     61: typedef float32 FLOAT32;
                     62: typedef float64 FLOAT64;
                     63: 
                     64: #define FLOAT32_ZERO            0x00000000
                     65: #define FLOAT32_ONE             0x3F800000
                     66: #define FLOAT32_IS_NEG(x)       ((x) & 0x80000000)
                     67: #define FLOAT32_IS_ZERO(x)      (((x) & 0x7FFFFFFF) == 0x00000000)
                     68: #define FLOAT64_ZERO            LIT64(0x0000000000000000)
                     69: #define FLOAT64_ONE             LIT64(0x3FF0000000000000)
                     70: #define FLOAT64_IS_NEG(x)       ((x) & LIT64(0x8000000000000000))
                     71: #define FLOAT64_IS_ZERO(x)      (((x) & LIT64(0x7FFFFFFFFFFFFFFF)) == LIT64(0x0000000000000000))
                     72: 
                     73: #define float32_add(x,y)        float32_add(x,y,&m_fpcs)
                     74: #define float32_sub(x,y)        float32_sub(x,y,&m_fpcs)
                     75: #define float32_mul(x,y)        float32_mul(x,y,&m_fpcs)
                     76: #define float32_div(x,y)        float32_div(x,y,&m_fpcs)
                     77: #define float32_sqrt(x)         float32_sqrt(x,&m_fpcs)
                     78: #define float32_to_int32(x)     float32_to_int32(x,&m_fpcs)
                     79: #define float32_to_int32_round_to_zero(x)     float32_to_int32_round_to_zero(x,&m_fpcs)
                     80: #define float32_to_float64(x)   float32_to_float64(x,&m_fpcs)
                     81: #define float32_gt(x,y)         float32_gt(x,y,&m_fpcs)
                     82: #define float32_le(x,y)         float32_le(x,y,&m_fpcs)
                     83: #define float32_eq(x,y)         float32_eq(x,y,&m_fpcs)
                     84: #define float64_add(x,y)        float64_add(x,y,&m_fpcs)
                     85: #define float64_sub(x,y)        float64_sub(x,y,&m_fpcs)
                     86: #define float64_mul(x,y)        float64_mul(x,y,&m_fpcs)
                     87: #define float64_div(x,y)        float64_div(x,y,&m_fpcs)
                     88: #define float64_sqrt(x)         float64_sqrt(x,&m_fpcs)
                     89: #define float64_to_int32(x)     float64_to_int32(x,&m_fpcs)
                     90: #define float64_to_int32_round_to_zero(x)     float64_to_int32_round_to_zero(x,&m_fpcs)
                     91: #define float64_to_float32(x)   float64_to_float32(x,&m_fpcs)
                     92: #define float64_gt(x,y)         float64_gt(x,y,&m_fpcs)
                     93: #define float64_le(x,y)         float64_le(x,y,&m_fpcs)
                     94: #define float64_eq(x,y)         float64_eq(x,y,&m_fpcs)
                     95: 
                     96: static inline void reset_fpcs(float_ctrl* fp_control) {
                     97:     float_init(fp_control);
                     98: }
                     99: 
                    100: static inline void float_set_rounding_mode (int mode, float_ctrl* fp_control) {
                    101:     switch (mode) {
                    102:         case 0: set_float_rounding_mode(float_round_nearest_even, fp_control); break;
                    103:         case 1: set_float_rounding_mode(float_round_down, fp_control);         break;
                    104:         case 2: set_float_rounding_mode(float_round_up, fp_control);           break;
                    105:         case 3: set_float_rounding_mode(float_round_to_zero, fp_control);      break;
                    106:     }
                    107: }
                    108: 
                    109: #else // NATIVE FLOAT
                    110: 
                    111: #include <math.h>
                    112: #ifdef __MINGW32__
                    113: #define _GLIBCXX_HAVE_FENV_H 1
                    114: #endif
                    115: #include <fenv.h>
                    116: #if __APPLE__
                    117: #else
                    118: #pragma STDC FENV_ACCESS ON
                    119: #endif
                    120: 
                    121: typedef float FLOAT32;
                    122: typedef double FLOAT64;
                    123: 
                    124: #define float_ctrl int
                    125: 
                    126: #define FLOAT32_ZERO            0.0
                    127: #define FLOAT32_ONE             1.0
                    128: #define FLOAT32_IS_NEG(x)       ((x) < 0.0)
                    129: #define FLOAT32_IS_ZERO(x)      ((x) == 0.0)
                    130: #define FLOAT64_ZERO            0.0
                    131: #define FLOAT64_ONE             1.0
                    132: #define FLOAT64_IS_NEG(x)       ((x) < 0.0)
                    133: #define FLOAT64_IS_ZERO(x)      ((x) == 0.0)
                    134: 
                    135: #define float32_add(x,y)        ((x)+(y))
                    136: #define float32_sub(x,y)        ((x)-(y))
                    137: #define float32_mul(x,y)        ((x)*(y))
                    138: #define float32_div(x,y)        ((x)/(y))
                    139: #define float32_sqrt(x)         (sqrt(x))
                    140: #define float32_to_int32(x)     (rint(x))
                    141: #define float32_to_int32_round_to_zero(x)     ((UINT32)(x))
                    142: #define float32_to_float64(x)   ((double)(x))
                    143: #define float32_gt(x,y)         ((x)>(y))
                    144: #define float32_le(x,y)         ((x)<=(y))
                    145: #define float32_eq(x,y)         ((x)==(y))
                    146: #define float64_add(x,y)        ((x)+(y))
                    147: #define float64_sub(x,y)        ((x)-(y))
                    148: #define float64_mul(x,y)        ((x)*(y))
                    149: #define float64_div(x,y)        ((x)/(y))
                    150: #define float64_sqrt(x)         (sqrt(x))
                    151: #define float64_to_int32(x)     (rint(x))
                    152: #define float64_to_int32_round_to_zero(x)     ((UINT32)(x))
                    153: #define float64_to_float32(x)   ((float)(x))
                    154: #define float64_gt(x,y)         ((x)>(y))
                    155: #define float64_le(x,y)         ((x)<=(y))
                    156: #define float64_eq(x,y)         ((x)==(y))
                    157: 
                    158: static inline void reset_fpcs(float_ctrl* dummy) {
                    159:     *dummy = 0;
                    160: }
                    161: 
                    162: static inline void float_set_rounding_mode (int mode, float_ctrl* dummy) {
                    163:     switch (mode) {
                    164:         case 0: fesetround(FE_TONEAREST);  break;
                    165:         case 1: fesetround(FE_DOWNWARD);   break;
                    166:         case 2: fesetround(FE_UPWARD);     break;
                    167:         case 3: fesetround(FE_TOWARDZERO); break;
                    168:     }
                    169: }
                    170: #endif // NATIVE FLOAT
                    171: 
                    172: 
                    173: /***************************************************************************
                    174:     REGISTER ENUMERATION
                    175: ***************************************************************************/
                    176: 
                    177: 
                    178: /* Various m_flow control flags (pending traps, pc update) */
                    179: enum {
                    180:     FLOW_CLEAR_MASK    = 0xF0000000,
                    181:     /* Indicate an instruction just generated a trap, so we know the PC
                    182:      needs to go to the trap address.  */
                    183:     TRAP_NORMAL        = 0x00000001,
                    184:     TRAP_IN_DELAY_SLOT = 0x00000002,
                    185:     TRAP_WAS_EXTERNAL  = 0x00000004,
                    186:     TRAP_MASK          = 0x00000007,
                    187:     /* Indicate a control-flow instruction, so we know the PC is updated.  */
                    188:     PC_UPDATED         = 0x00000100,
                    189:     /* Various memory access faults */
                    190:     EXITING_IFETCH     = 0x00001000,
                    191:     EXITING_READMEM    = 0x00010000,
                    192:     EXITING_WRITEMEM   = 0x00020000,
                    193:     EXITING_FPREADMEM  = 0x00030000,
                    194:     EXITING_FPWRITEMEM = 0x00040000,
                    195:     EXITING_MEMRW      = 0x00070000,
                    196:     /* This is 1 if the next fir load gets the trap address, otherwise
                    197:      it is 0 to get the ld.c address.  This is set to 1 only when a
                    198:      non-reset trap occurs.  */
                    199:     FIR_GETS_TRAP      = 0x10000000,
                    200:     /* An external interrupt occured. */
                    201:     EXT_INTR           = 0x20000000,
                    202:     /* A f-op with DIM bit set encountered. */
                    203:     DIM_OP             = 0x40000000,
                    204: };
                    205: 
                    206: enum {
                    207:     MSG_NONE           = 0x00,
                    208:     MSG_I860_RESET     = 0x01,
                    209:     MSG_I860_KILL      = 0x02,
                    210:     MSG_DBG_BREAK      = 0x04,
                    211:     MSG_INTR           = 0x08,
                    212:     MSG_DISPLAY_BLANK  = 0x10,
                    213:     MSG_VIDEO_BLANK    = 0x20,
                    214: };
                    215: 
                    216: /* dual mode instruction state */
                    217: enum {
                    218:     DIM_NONE,
                    219:     DIM_TEMP,
                    220:     DIM_FULL,
                    221: };
                    222: 
                    223: /* Macros for accessing register fields in instruction word.  */
                    224: #define get_isrc1(bits) (((bits) >> 11) & 0x1f)
                    225: #define get_isrc2(bits) (((bits) >> 21) & 0x1f)
                    226: #define get_idest(bits) (((bits) >> 16) & 0x1f)
                    227: #define get_fsrc1(bits) (((bits) >> 11) & 0x1f)
                    228: #define get_fsrc2(bits) (((bits) >> 21) & 0x1f)
                    229: #define get_fdest(bits) (((bits) >> 16) & 0x1f)
                    230: #define get_creg(bits) (((bits) >> 21) & 0x7)
                    231: 
                    232: /* Macros for accessing immediate fields.  */
                    233: /* 16-bit immediate.  */
                    234: #define get_imm16(insn) ((insn) & 0xffff)
                    235: 
                    236: /* A mask for all the trap bits of the PSR (FT, DAT, IAT, IN, IT, or
                    237:  bits [12..8]).  */
                    238: #define PSR_ALL_TRAP_BITS_MASK 0x00001f00
                    239: 
                    240: /* A mask for PSR bits which can only be changed from supervisor level.  */
                    241: #define PSR_SUPERVISOR_ONLY_MASK 0x0000fff3
                    242: 
                    243: 
                    244: /* PSR: BR flag (PSR[0]):  set/get.  */
                    245: #define GET_PSR_BR()  ((m_cregs[CR_PSR] >> 0) & 1)
                    246: #define SET_PSR_BR(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 0)) | (((val) & 1) << 0))
                    247: 
                    248: /* PSR: BW flag (PSR[1]):  set/get.  */
                    249: #define GET_PSR_BW()  ((m_cregs[CR_PSR] >> 1) & 1)
                    250: #define SET_PSR_BW(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 1)) | (((val) & 1) << 1))
                    251: 
                    252: /* PSR: Shift count (PSR[21..17]):  set/get.  */
                    253: #define GET_PSR_SC()  ((m_cregs[CR_PSR] >> 17) & 0x1f)
                    254: #define SET_PSR_SC(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~0x003e0000) | (((val) & 0x1f) << 17))
                    255: 
                    256: /* PSR: CC flag (PSR[2]):  set/get.  */
                    257: #define GET_PSR_CC()      ((m_cregs[CR_PSR] >> 2) & 1)
                    258: #define SET_PSR_CC_F(val) (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 2)) | (((val) & 1) << 2))
                    259: 
                    260: /* PSR: IT flag (PSR[8]):  set/get.  */
                    261: #define GET_PSR_IT()  ((m_cregs[CR_PSR] >> 8) & 1)
                    262: #define SET_PSR_IT(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 8)) | (((val) & 1) << 8))
                    263: 
                    264: /* PSR: IN flag (PSR[9]):  set/get.  */
                    265: #define GET_PSR_IN()  ((m_cregs[CR_PSR] >> 9) & 1)
                    266: #define SET_PSR_IN(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 9)) | (((val) & 1) << 9))
                    267: 
                    268: /* PSR: IAT flag (PSR[10]):  set/get.  */
                    269: #define GET_PSR_IAT()  ((m_cregs[CR_PSR] >> 10) & 1)
                    270: #define SET_PSR_IAT(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 10)) | (((val) & 1) << 10))
                    271: 
                    272: /* PSR: DAT flag (PSR[11]):  set/get.  */
                    273: #define GET_PSR_DAT()  ((m_cregs[CR_PSR] >> 11) & 1)
                    274: #define SET_PSR_DAT(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 11)) | (((val) & 1) << 11))
                    275: 
                    276: /* PSR: FT flag (PSR[12]):  set/get.  */
                    277: #define GET_PSR_FT()  ((m_cregs[CR_PSR] >> 12) & 1)
                    278: #define SET_PSR_FT(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 12)) | (((val) & 1) << 12))
                    279: 
                    280: /* PSR: DS flag (PSR[13]):  set/get.  */
                    281: #define GET_PSR_DS()  ((m_cregs[CR_PSR] >> 13) & 1)
                    282: #define SET_PSR_DS(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 13)) | (((val) & 1) << 13))
                    283: 
                    284: /* PSR: DIM flag (PSR[14]):  set/get.  */
                    285: #define GET_PSR_DIM()  ((m_cregs[CR_PSR] >> 14) & 1)
                    286: #define SET_PSR_DIM(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 14)) | (((val) & 1) << 14))
                    287: 
                    288: /* PSR: LCC (PSR[3]):  set/get.  */
                    289: #define GET_PSR_LCC()  ((m_cregs[CR_PSR] >> 3) & 1)
                    290: #define SET_PSR_LCC(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 3)) | (((val) & 1) << 3))
                    291: 
                    292: /* PSR: IM (PSR[4]):  set/get.  */
                    293: #define GET_PSR_IM()  ((m_cregs[CR_PSR] >> 4) & 1)
                    294: #define SET_PSR_IM(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 4)) | (((val) & 1) << 4))
                    295: 
                    296: /* PSR: PIM (PSR[5]):  set/get.  */
                    297: #define GET_PSR_PIM()  ((m_cregs[CR_PSR] >> 5) & 1)
                    298: #define SET_PSR_PIM(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 5)) | (((val) & 1) << 5))
                    299: 
                    300: /* PSR: U (PSR[6]):  set/get.  */
                    301: #define GET_PSR_U()  ((m_cregs[CR_PSR] >> 6) & 1)
                    302: #define SET_PSR_U(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 6)) | (((val) & 1) << 6))
                    303: 
                    304: /* PSR: PU (PSR[7]):  set/get.  */
                    305: #define GET_PSR_PU()  ((m_cregs[CR_PSR] >> 7) & 1)
                    306: #define SET_PSR_PU(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 7)) | (((val) & 1) << 7))
                    307: 
                    308: /* PSR: Pixel size (PSR[23..22]):  set/get.  */
                    309: #define GET_PSR_PS()  ((m_cregs[CR_PSR] >> 22) & 0x3)
                    310: #define SET_PSR_PS(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~0x00c00000) | (((val) & 0x3) << 22))
                    311: 
                    312: /* PSR: Pixel mask (PSR[31..24]):  set/get.  */
                    313: #define GET_PSR_PM()  ((m_cregs[CR_PSR] >> 24) & 0xff)
                    314: #define SET_PSR_PM(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~0xff000000) | (((val) & 0xff) << 24))
                    315: 
                    316: /* EPSR: WP bit (EPSR[14]):  set/get.  */
                    317: #define GET_EPSR_WP()  ((m_cregs[CR_EPSR] >> 14) & 1)
                    318: #define SET_EPSR_WP(val)  (m_cregs[CR_EPSR] = (m_cregs[CR_EPSR] & ~(1 << 14)) | (((val) & 1) << 14))
                    319: 
                    320: /* EPSR: INT bit (EPSR[17]):  set/get.  */
                    321: #define GET_EPSR_INT()  ((m_cregs[CR_EPSR] >> 17) & 1)
                    322: #define SET_EPSR_INT(val)  (m_cregs[CR_EPSR] = (m_cregs[CR_EPSR] & ~(1 << 17)) | (((val) & 1) << 17))
                    323: 
                    324: /* EPSR: OF flag (EPSR[24]):  set/get.  */
                    325: #define GET_EPSR_OF()  ((m_cregs[CR_EPSR] >> 24) & 1)
                    326: #define SET_EPSR_OF(val)  (m_cregs[CR_EPSR] = (m_cregs[CR_EPSR] & ~(1 << 24)) | (((val) & 1) << 24))
                    327: 
                    328: /* EPSR: BE flag (EPSR[23]):  set/get.  */
                    329: #define GET_EPSR_BE()  ((m_cregs[CR_EPSR] >> 23) & 1)
                    330: #define SET_EPSR_BE(val)  (m_cregs[CR_EPSR] = (m_cregs[CR_EPSR] & ~(1 << 23)) | (((val) & 1) << 23))
                    331: 
                    332: /* DIRBASE: ATE bit (DIRBASE[0]):  get.  */
                    333: #define GET_DIRBASE_ATE()  (m_cregs[CR_DIRBASE] & 1)
                    334: 
                    335: /* DIRBASE: CS8 bit (DIRBASE[7]):  get.  */
                    336: #define GET_DIRBASE_CS8()  ((m_cregs[CR_DIRBASE] >> 7) & 1)
                    337: 
                    338: /* DIRBASE: CS8 bit (DIRBASE[7]):  get.  */
                    339: #define GET_DIRBASE_ITI()  ((m_cregs[CR_DIRBASE] >> 5) & 1)
                    340: 
                    341: /* FSR: FTE bit (FSR[5]):  set/get.  */
                    342: #define GET_FSR_FTE()  ((m_cregs[CR_FSR] >> 5) & 1)
                    343: #define SET_FSR_FTE(val)  (m_cregs[CR_FSR] = (m_cregs[CR_FSR] & ~(1 << 5)) | (((val) & 1) << 5))
                    344: 
                    345: /* FSR: SE bit (FSR[8]):  set/get.  */
                    346: #define GET_FSR_SE()  ((m_cregs[CR_FSR] >> 8) & 1)
                    347: #define SET_FSR_SE(val)  (m_cregs[CR_FSR] = (m_cregs[CR_FSR] & ~(1 << 8)) | (((val) & 1) << 8))
                    348: 
                    349: /* FSR: SE bit (RM[3..2]):  set/get.  */
                    350: #define GET_FSR_RM()    ((m_cregs[CR_FSR] >> 2) & 3)
                    351: #define SET_FSR_RM(val) (m_cregs[CR_FSR] = (m_cregs[CR_FSR] & ~0xC) | (((val) & 3) << 2))
                    352: 
                    353: #define CLEAR_FLOW() (m_flow &= FLOW_CLEAR_MASK)
                    354: 
                    355: /* check for pending trap */
                    356: #define PENDING_TRAP() (m_flow & TRAP_MASK)
                    357: 
                    358: /* check for updated PC */
                    359: #define GET_PC_UPDATED() (m_flow & PC_UPDATED)
                    360: #define SET_PC_UPDATED() m_flow |= PC_UPDATED
                    361: 
                    362: /* access fault traps */
                    363: #define GET_EXITING_MEMRW()    (m_flow & EXITING_MEMRW)
                    364: #define SET_EXITING_MEMRW(val) (m_flow = (val) | (m_flow & ~EXITING_MEMRW))
                    365: 
                    366: const UINT32 INSN_NOP      = 0xA0000000;
                    367: const UINT32 INSN_DIM      = 0x00000200;
                    368: const UINT32 INSN_FNOP     = 0xB0000000;
                    369: const UINT32 INSN_FNOP_DIM = INSN_FNOP | INSN_DIM;
                    370: const UINT32 INSN_FP       = 0x48000000;
                    371: const UINT32 INSN_FP_DIM   = INSN_FP   | INSN_DIM;
                    372: const UINT32 INSN_MASK     = 0xFC000000;
                    373: const UINT32 INSN_MASK_DIM = INSN_MASK | INSN_DIM;
                    374: 
                    375: const size_t I860_ICACHE_SZ       = 9; // in powers of two lines (2^9 = 512; 512 x 2 words = 4 kbytes)
                    376: const size_t I860_ICACHE_MASK     = (1<<I860_ICACHE_SZ)-1;
                    377: const size_t I860_TLB_SZ          = 11; // in powers of two
                    378: const size_t I860_TLB_MASK        = (1<<I860_TLB_SZ)-1;
                    379: const size_t I860_PAGE_SZ         = 12; // in powers of two
                    380: const size_t I860_PAGE_OFF_MASK   = (1<<I860_PAGE_SZ)-1;
                    381: const size_t I860_PAGE_FRAME_MASK = ~I860_PAGE_OFF_MASK;
                    382: const size_t I860_TLB_FLAGS       = I860_PAGE_OFF_MASK;
                    383: 
                    384: /* Control register numbers.  */
                    385: enum {
                    386:     CR_FIR     = 0,
                    387:     CR_PSR     = 1,
                    388:     CR_DIRBASE = 2,
                    389:     CR_DB      = 3,
                    390:     CR_FSR     = 4,
                    391:     CR_EPSR    = 5
                    392: };
                    393: 
                    394: class i860_reg {
                    395:     UINT32        id;
                    396:     const char*   name;
                    397:     const char*   format;
                    398:     const UINT32* reg;
                    399: public:
                    400:     i860_reg() : id(0), name(0), format(0), reg(&id) {}
                    401:     
                    402:     bool valid() {
                    403:         return name;
                    404:     }
                    405:     
                    406:     void formatstr(const char* format) {
                    407:         this->format = format;
                    408:     }
                    409:     
                    410:     void set(int regId, const char* name, const UINT32 * reg) {
                    411:         this->id   = regId;
                    412:         this->name = name;
                    413:         this->reg  = reg;
                    414:     }
                    415:     
                    416:     UINT32 get() const {
                    417:         return *reg;
                    418:     }
                    419:     
                    420:     const char* get_name() {
                    421:         return name;
                    422:     }
                    423: };
                    424: 
                    425: class NextDimension;
                    426: 
                    427: class i860_cpu_device {
                    428: public:
                    429:     NextDimension* nd;
                    430:     
                    431:        // construction/destruction
                    432:     i860_cpu_device(NextDimension* nd);
                    433:     
                    434:     /* External interface */
                    435:     void init(void);
                    436:     void set_run_func(void);
                    437:     void uninit(void);
                    438:     void halt(bool state);
                    439:     void pause(bool state);
                    440:     inline bool is_halted(void) {return m_halt;};
                    441: 
                    442:     /* i860 cycle counter */
                    443:     int i860cycles;
                    444:     /* Run one i860 cycle */
                    445:     void    run_cycle(void);
                    446:     /* Run the i860 thread */
                    447:     void run();
                    448:     /* i860 thread message handler */
                    449:     bool   handle_msgs(int msg);
                    450:     
                    451:     static int thread(void* data);
                    452:     
                    453:     const char* reports(double realTime, double hostTIme);
                    454: private:
                    455:     // debugger
                    456:     void debugger(char cmd, const char* format, ...);
                    457:     void debugger(void);
                    458:     
                    459:     // softfloat control and status
                    460:     float_ctrl m_fpcs;
                    461:     
                    462:     thread_t*    m_thread;
                    463: 
                    464:     UINT64 m_insn_decoded;
                    465:     UINT64 m_icache_hit;
                    466:     UINT64 m_icache_miss;
                    467:     UINT64 m_icache_inval;
                    468:     UINT64 m_tlb_hit;
                    469:     UINT64 m_tlb_miss;
                    470:     UINT64 m_tlb_inval;
                    471:     UINT64 m_intrs;
                    472:     UINT32 m_last_rt;
                    473:     UINT32 m_last_vt;
                    474:     char   m_report[1024];
                    475: 
                    476:     /* Debugger stuff */
                    477:     char   m_lastcmd;
                    478:     char   m_console[32*1024];
                    479:     int    m_console_idx;
                    480:     bool   m_break_on_next_msg;
                    481:     UINT32 m_traceback[256];
                    482:     int    m_traceback_idx;
                    483:     
                    484:     /* Program counter (1 x 32-bits).  Reset starts at pc=0xffffff00.  */
                    485:     UINT32 m_pc;
                    486: 
                    487:        /* Integer registers (32 x 32-bits).  */
                    488:        UINT32  m_iregs[32];
                    489:     
                    490:        /* Floating point registers (32 x 32-bits, 16 x 64 bits, or 8 x 128 bits).
                    491:           When referenced as pairs or quads, the higher numbered registers
                    492:           are the upper bits. E.g., double precision f0 is f1:f0.  */
                    493:        UINT8   m_fregs[32 * 4];
                    494: 
                    495:        /* Control registers (6 x 32-bits).  */
                    496:        UINT32 m_cregs[6];
                    497: 
                    498:     /* Dual instruction mode flags */
                    499:     int  m_dim;
                    500:     bool m_dim_cc;
                    501:     bool m_dim_cc_valid;
                    502:     int  m_save_dim;
                    503:     int  m_save_flow;
                    504:     bool m_save_cc;
                    505:     bool m_save_cc_valid;
                    506:     
                    507:        /* Special registers (4 x 64-bits).  */
                    508:        union
                    509:        {
                    510:                FLOAT32 s;
                    511:                FLOAT64 d;
                    512:        } m_KR, m_KI, m_T;
                    513:     
                    514:        UINT64 m_merge;
                    515: 
                    516:        /* The adder pipeline, always 3 stages.  */
                    517:        struct
                    518:        {
                    519:                /* The stage contents.  */
                    520:                union {
                    521:                        FLOAT32 s;
                    522:                        FLOAT64 d;
                    523:                } val;
                    524: 
                    525:                /* The stage status bits.  */
                    526:                struct {
                    527:                        /* Adder result precision (1 = dbl, 0 = sgl).  */
                    528:                        char arp;
                    529:                } stat;
                    530:        } m_A[3];
                    531: 
                    532:        /* The multiplier pipeline. 3 stages for single precision, 2 stages
                    533:           for double precision, and confusing for mixed precision.  */
                    534:        struct {
                    535:                /* The stage contents.  */
                    536:                union {
                    537:                        FLOAT32 s;
                    538:                        FLOAT64 d;
                    539:                } val;
                    540: 
                    541:                /* The stage status bits.  */
                    542:                struct {
                    543:                        /* Multiplier result precision (1 = dbl, 0 = sgl).  */
                    544:                        char mrp;
                    545:                } stat;
                    546:        } m_M[3];
                    547: 
                    548:        /* The load pipeline, always 3 stages.  */
                    549:        struct {
                    550:                /* The stage contents.  */
                    551:                union {
                    552:                        FLOAT32 s;
                    553:                        FLOAT64 d;
                    554:                } val;
                    555: 
                    556:                /* The stage status bits.  */
                    557:                struct {
                    558:                        /* Load result precision (1 = dbl, 0 = sgl).  */
                    559:                        char lrp;
                    560:                } stat;
                    561:        } m_L[3];
                    562: 
                    563:        /* The graphics/integer pipeline, always 1 stage.  */
                    564:        struct {
                    565:                /* The stage contents.  */
                    566:                union {
                    567:                        FLOAT32 s;
                    568:                        FLOAT64 d;
                    569:                } val;
                    570: 
                    571:                /* The stage status bits.  */
                    572:                struct {
                    573:                        /* Integer/graphics result precision (1 = dbl, 0 = sgl).  */
                    574:                        char irp;
                    575:                } stat;
                    576:        } m_G;
                    577: 
                    578:     /* Instruction cache */
                    579:     UINT64 m_icache[1<<I860_ICACHE_SZ];
                    580:     UINT32 m_icache_vaddr[1<<I860_ICACHE_SZ];
                    581:     
                    582:     /* Translation look-aside buffer */
                    583:     UINT32 m_tlb_vaddr[1<<I860_TLB_SZ];
                    584:     UINT32 m_tlb_paddr[1<<I860_TLB_SZ];
                    585:     
                    586:        /*
                    587:         * Halt state. Can be set externally
                    588:         */
                    589:     volatile bool m_halt;
                    590:         
                    591:        /* Indicate an instruction just generated a trap,
                    592:      needs to go to the trap address or a control-flow 
                    593:      instruction, so we know the PC is updated.  */
                    594:        UINT32 m_flow;
                    595:     
                    596:     /* Single stepping state - for internal use.  */
                    597:     UINT32 m_single_stepping;
                    598: 
                    599:     /* memory access */
                    600:     mem_rd_func rdmem[17];
                    601:     mem_wr_func wrmem[17];
                    602:     
                    603:     void   set_mem_access(bool be);
                    604:     UINT8  rdcs8(UINT32 addr);
                    605:        inline void   writemem_emu(UINT32 addr, int size, UINT8 *data);
                    606:        inline void   writemem_emu(UINT32 addr, int size, UINT8 *data, UINT32 wmask);
                    607:     inline void   readmem_emu (UINT32 addr, int size, UINT8 *data);
                    608: 
                    609:     /* instructions */
                    610:        void insn_ld_ctrl (UINT32 insn);
                    611:        void insn_st_ctrl (UINT32 insn);
                    612:        void insn_ldx (UINT32 insn);
                    613:        void insn_stx (UINT32 insn);
                    614:        void insn_fsty (UINT32 insn);
                    615:        void insn_fldy (UINT32 insn);
                    616:        void insn_pstd (UINT32 insn);
                    617:        void insn_ixfr (UINT32 insn);
                    618:        void insn_addu (UINT32 insn);
                    619:        void insn_addu_imm (UINT32 insn);
                    620:        void insn_adds (UINT32 insn);
                    621:        void insn_adds_imm (UINT32 insn);
                    622:        void insn_subu (UINT32 insn);
                    623:        void insn_subu_imm (UINT32 insn);
                    624:        void insn_subs (UINT32 insn);
                    625:        void insn_subs_imm (UINT32 insn);
                    626:        void insn_shl (UINT32 insn);
                    627:        void insn_shl_imm (UINT32 insn);
                    628:        void insn_shr (UINT32 insn);
                    629:        void insn_shr_imm (UINT32 insn);
                    630:        void insn_shra (UINT32 insn);
                    631:        void insn_shra_imm (UINT32 insn);
                    632:        void insn_shrd (UINT32 insn);
                    633:        void insn_and (UINT32 insn);
                    634:        void insn_and_imm (UINT32 insn);
                    635:        void insn_andh_imm (UINT32 insn);
                    636:        void insn_andnot (UINT32 insn);
                    637:        void insn_andnot_imm (UINT32 insn);
                    638:        void insn_andnoth_imm (UINT32 insn);
                    639:        void insn_or (UINT32 insn);
                    640:        void insn_or_imm (UINT32 insn);
                    641:        void insn_orh_imm (UINT32 insn);
                    642:        void insn_xor (UINT32 insn);
                    643:        void insn_xor_imm (UINT32 insn);
                    644:        void insn_xorh_imm (UINT32 insn);
                    645:        void insn_trap (UINT32 insn);
                    646:        void insn_intovr (UINT32 insn);
                    647:        void insn_bte (UINT32 insn);
                    648:        void insn_bte_imm (UINT32 insn);
                    649:        void insn_btne (UINT32 insn);
                    650:        void insn_btne_imm (UINT32 insn);
                    651:        void insn_bc (UINT32 insn);
                    652:        void insn_bnc (UINT32 insn);
                    653:        void insn_bct (UINT32 insn);
                    654:        void insn_bnct (UINT32 insn);
                    655:        void insn_call (UINT32 insn);
                    656:        void insn_br (UINT32 insn);
                    657:        void insn_bri (UINT32 insn);
                    658:        void insn_calli (UINT32 insn);
                    659:        void insn_bla (UINT32 insn);
                    660:        void insn_flush (UINT32 insn);
                    661:        void insn_fmul (UINT32 insn);
                    662:        void insn_fmlow (UINT32 insn);
                    663:        void insn_fadd_sub (UINT32 insn);
                    664:        void insn_dualop (UINT32 insn);
                    665:        void insn_frcp (UINT32 insn);
                    666:        void insn_frsqr (UINT32 insn);
                    667:        void insn_fxfr (UINT32 insn);
                    668:        void insn_ftrunc (UINT32 insn);
                    669:     void insn_fix (UINT32 insn);
                    670:        void insn_famov (UINT32 insn);
                    671:        void insn_fiadd_sub (UINT32 insn);
                    672:        void insn_fcmp (UINT32 insn);
                    673:        void insn_fzchk (UINT32 insn);
                    674:        void insn_form (UINT32 insn);
                    675:        void insn_faddp (UINT32 insn);
                    676:        void insn_faddz (UINT32 insn);
                    677: 
                    678:     void dec_unrecog (UINT32 insn);
                    679: 
                    680:     /* register access */
                    681:     UINT32 get_iregval(int gr);
                    682:     void   set_iregval(int gr, UINT32 val);
                    683:     FLOAT32  get_fregval_s (int fr);
                    684:     void   set_fregval_s (int fr, FLOAT32 s);
                    685:     FLOAT64 get_fregval_d (int fr);
                    686:     void   set_fregval_d (int fr, FLOAT64 d);
                    687:     void   SET_PSR_CC(int val);
                    688:     
                    689:     void   invalidate_icache();
                    690:     void   invalidate_tlb();
                    691:     inline UINT64 ifetch64(const UINT32 pc);
                    692:     UINT64 ifetch64(const UINT32 pc, const UINT32 vaddr, int const cidx);
                    693:     UINT32 ifetch(const UINT32 pc);
                    694:     UINT32 ifetch_notrap(const UINT32 pc);
                    695:     void   handle_trap(UINT32 savepc);
                    696:     void   ret_from_trap();
                    697:     void   unrecog_opcode (UINT32 pc, UINT32 insn);
                    698:     
                    699:     void   decode_exec (UINT32 insn);
                    700:     void   dump_pipe (int type);
                    701:     void   dump_state ();
                    702:        UINT32 disasm (UINT32 addr, int len);
                    703:     offs_t disasm(char* buffer, offs_t pc);
                    704:        void   dbg_memdump (UINT32 addr, int len);
                    705:        int    delay_slots(UINT32 insn);
                    706:        UINT32 get_address_translation(UINT32 vaddr, int is_dataref, int is_write);
                    707:     inline UINT32 get_address_translation(UINT32 vaddr, UINT32 voffset, UINT32 tlbidx, int is_dataref, int is_write);
                    708:        FLOAT32  get_fval_from_optype_s (UINT32 insn, int optype);
                    709:        FLOAT64 get_fval_from_optype_d (UINT32 insn, int optype);
                    710:     int    memtest(bool be);
                    711:     void   dbg_check_wr(UINT32 addr, int size, UINT8* data);
                    712:     
                    713:     /* This is theinterface for asserting an external interrupt to the i860.  */
                    714:     void gen_interrupt();
                    715:     /* This is the interface for clearing an external interrupt of the i860.  */
                    716:     void clr_interrupt();
                    717:     /* This is the interface for reseting the i860.  */
                    718:     void reset();
                    719:     void intr();
                    720: 
                    721:        typedef void (i860_cpu_device::*insn_func)(UINT32);
                    722:        static const insn_func decode_tbl[64];
                    723:        static const insn_func core_esc_decode_tbl[8];
                    724:        static const insn_func fp_decode_tbl[128];
                    725:     static       insn_func decoder_tbl[8192];
                    726: };
                    727: 
                    728: /* disassembler */
                    729: int i860_disassembler(UINT32 pc, UINT32 insn, char* buffer);
                    730: 
                    731: #endif /* __I860_H__ */

unix.superglobalmegacorp.com

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