|
|
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__ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.