Annotation of previous_trunk/src/dimension/i860.hpp, revision 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.