|
|
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 <unistd.h> ! 27: #include <ctype.h> ! 28: ! 29: #include "i860cfg.h" ! 30: #include "nd_sdl.h" ! 31: ! 32: const int LOG_WARN = 3; ! 33: extern "C" void Log_Printf(int nType, const char *psFormat, ...); ! 34: ! 35: typedef uint64_t UINT64; ! 36: typedef int64_t INT64; ! 37: ! 38: typedef uint32_t UINT32; ! 39: typedef int32_t INT32; ! 40: ! 41: typedef uint16_t UINT16; ! 42: typedef int16_t INT16; ! 43: ! 44: typedef uint8_t UINT8; ! 45: typedef int8_t INT8; ! 46: ! 47: typedef int64_t offs_t; ! 48: ! 49: extern "C" { ! 50: UINT8 nd_board_cs8get(UINT32 addr); ! 51: UINT8 nd_board_bget(UINT32 addr); ! 52: void nd_board_bput(UINT32 addr, UINT8 val); ! 53: UINT16 nd_board_wget(UINT32 addr); ! 54: void nd_board_wput(UINT32 addr, UINT16 val); ! 55: UINT32 nd_board_lget(UINT32 addr); ! 56: void nd_board_lput(UINT32 addr, UINT32 val); ! 57: void nd_board_put (UINT32 addr, UINT32 val); ! 58: ! 59: void nd_board_rd8_le (UINT32 addr, UINT32* val); ! 60: void nd_board_rd16_le (UINT32 addr, UINT32* val); ! 61: void nd_board_rd32_le (UINT32 addr, UINT32* val); ! 62: void nd_board_rd64_le (UINT32 addr, UINT32* val); ! 63: void nd_board_rd128_le(UINT32 addr, UINT32* val); ! 64: ! 65: void nd_board_rd8_be (UINT32 addr, UINT32* val); ! 66: void nd_board_rd16_be (UINT32 addr, UINT32* val); ! 67: void nd_board_rd32_be (UINT32 addr, UINT32* val); ! 68: void nd_board_rd64_be (UINT32 addr, UINT32* val); ! 69: void nd_board_rd128_be(UINT32 addr, UINT32* val); ! 70: ! 71: void nd_board_wr8_le (UINT32 addr, const UINT32* val); ! 72: void nd_board_wr16_le (UINT32 addr, const UINT32* val); ! 73: void nd_board_wr32_le (UINT32 addr, const UINT32* val); ! 74: void nd_board_wr64_le (UINT32 addr, const UINT32* val); ! 75: void nd_board_wr128_le(UINT32 addr, const UINT32* val); ! 76: ! 77: void nd_board_wr8_be (UINT32 addr, const UINT32* val); ! 78: void nd_board_wr16_be (UINT32 addr, const UINT32* val); ! 79: void nd_board_wr32_be (UINT32 addr, const UINT32* val); ! 80: void nd_board_wr64_be (UINT32 addr, const UINT32* val); ! 81: void nd_board_wr128_be(UINT32 addr, const UINT32* val); ! 82: ! 83: void nd_nbic_interrupt(void); ! 84: bool nd_dbg_cmd(const char* cmd); ! 85: void Statusbar_SetNdLed(int state); ! 86: } ! 87: ! 88: typedef void (*mem_rd_func)(UINT32, UINT32*); ! 89: typedef void (*mem_wr_func)(UINT32, const UINT32*); ! 90: ! 91: /*************************************************************************** ! 92: REGISTER ENUMERATION ! 93: ***************************************************************************/ ! 94: ! 95: ! 96: /* Various m_flow control flags (pending traps, pc update) */ ! 97: enum { ! 98: FLOW_CLEAR_MASK = 0xF0000000, ! 99: /* Indicate an instruction just generated a trap, so we know the PC ! 100: needs to go to the trap address. */ ! 101: TRAP_NORMAL = 0x00000001, ! 102: TRAP_IN_DELAY_SLOT = 0x00000002, ! 103: TRAP_WAS_EXTERNAL = 0x00000004, ! 104: TRAP_MASK = 0x00000007, ! 105: /* Indicate a control-flow instruction, so we know the PC is updated. */ ! 106: PC_UPDATED = 0x00000100, ! 107: /* Various memory access faults */ ! 108: EXITING_IFETCH = 0x00001000, ! 109: EXITING_READMEM = 0x00010000, ! 110: EXITING_WRITEMEM = 0x00020000, ! 111: EXITING_FPREADMEM = 0x00030000, ! 112: EXITING_FPWRITEMEM = 0x00040000, ! 113: EXITING_MEMRW = 0x00070000, ! 114: /* This is 1 if the next fir load gets the trap address, otherwise ! 115: it is 0 to get the ld.c address. This is set to 1 only when a ! 116: non-reset trap occurs. */ ! 117: FIR_GETS_TRAP = 0x10000000, ! 118: /* An external interrupt occured. */ ! 119: EXT_INTR = 0x20000000, ! 120: /* A f-op with DIM bit set encountered. */ ! 121: DIM_OP = 0x40000000, ! 122: }; ! 123: ! 124: enum { ! 125: MSG_NONE = 0x00, ! 126: MSG_I860_RESET = 0x01, ! 127: MSG_I860_KILL = 0x02, ! 128: MSG_DBG_BREAK = 0x04, ! 129: MSG_INTR = 0x08, ! 130: }; ! 131: ! 132: /* dual mode instruction state */ ! 133: enum { ! 134: DIM_NONE, ! 135: DIM_TEMP, ! 136: DIM_FULL, ! 137: }; ! 138: ! 139: /* Macros for accessing register fields in instruction word. */ ! 140: #define get_isrc1(bits) (((bits) >> 11) & 0x1f) ! 141: #define get_isrc2(bits) (((bits) >> 21) & 0x1f) ! 142: #define get_idest(bits) (((bits) >> 16) & 0x1f) ! 143: #define get_fsrc1(bits) (((bits) >> 11) & 0x1f) ! 144: #define get_fsrc2(bits) (((bits) >> 21) & 0x1f) ! 145: #define get_fdest(bits) (((bits) >> 16) & 0x1f) ! 146: #define get_creg(bits) (((bits) >> 21) & 0x7) ! 147: ! 148: /* Macros for accessing immediate fields. */ ! 149: /* 16-bit immediate. */ ! 150: #define get_imm16(insn) ((insn) & 0xffff) ! 151: ! 152: /* A mask for all the trap bits of the PSR (FT, DAT, IAT, IN, IT, or ! 153: bits [12..8]). */ ! 154: #define PSR_ALL_TRAP_BITS_MASK 0x00001f00 ! 155: ! 156: /* A mask for PSR bits which can only be changed from supervisor level. */ ! 157: #define PSR_SUPERVISOR_ONLY_MASK 0x0000fff3 ! 158: ! 159: ! 160: /* PSR: BR flag (PSR[0]): set/get. */ ! 161: #define GET_PSR_BR() ((m_cregs[CR_PSR] >> 0) & 1) ! 162: #define SET_PSR_BR(val) (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 0)) | (((val) & 1) << 0)) ! 163: ! 164: /* PSR: BW flag (PSR[1]): set/get. */ ! 165: #define GET_PSR_BW() ((m_cregs[CR_PSR] >> 1) & 1) ! 166: #define SET_PSR_BW(val) (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 1)) | (((val) & 1) << 1)) ! 167: ! 168: /* PSR: Shift count (PSR[21..17]): set/get. */ ! 169: #define GET_PSR_SC() ((m_cregs[CR_PSR] >> 17) & 0x1f) ! 170: #define SET_PSR_SC(val) (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~0x003e0000) | (((val) & 0x1f) << 17)) ! 171: ! 172: /* PSR: CC flag (PSR[2]): set/get. */ ! 173: #define GET_PSR_CC() ((m_cregs[CR_PSR] >> 2) & 1) ! 174: #define SET_PSR_CC_F(val) (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 2)) | (((val) & 1) << 2)) ! 175: ! 176: /* PSR: IT flag (PSR[8]): set/get. */ ! 177: #define GET_PSR_IT() ((m_cregs[CR_PSR] >> 8) & 1) ! 178: #define SET_PSR_IT(val) (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 8)) | (((val) & 1) << 8)) ! 179: ! 180: /* PSR: IN flag (PSR[9]): set/get. */ ! 181: #define GET_PSR_IN() ((m_cregs[CR_PSR] >> 9) & 1) ! 182: #define SET_PSR_IN(val) (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 9)) | (((val) & 1) << 9)) ! 183: ! 184: /* PSR: IAT flag (PSR[10]): set/get. */ ! 185: #define GET_PSR_IAT() ((m_cregs[CR_PSR] >> 10) & 1) ! 186: #define SET_PSR_IAT(val) (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 10)) | (((val) & 1) << 10)) ! 187: ! 188: /* PSR: DAT flag (PSR[11]): set/get. */ ! 189: #define GET_PSR_DAT() ((m_cregs[CR_PSR] >> 11) & 1) ! 190: #define SET_PSR_DAT(val) (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 11)) | (((val) & 1) << 11)) ! 191: ! 192: /* PSR: FT flag (PSR[12]): set/get. */ ! 193: #define GET_PSR_FT() ((m_cregs[CR_PSR] >> 12) & 1) ! 194: #define SET_PSR_FT(val) (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 12)) | (((val) & 1) << 12)) ! 195: ! 196: /* PSR: DS flag (PSR[13]): set/get. */ ! 197: #define GET_PSR_DS() ((m_cregs[CR_PSR] >> 13) & 1) ! 198: #define SET_PSR_DS(val) (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 13)) | (((val) & 1) << 13)) ! 199: ! 200: /* PSR: DIM flag (PSR[14]): set/get. */ ! 201: #define GET_PSR_DIM() ((m_cregs[CR_PSR] >> 14) & 1) ! 202: #define SET_PSR_DIM(val) (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 14)) | (((val) & 1) << 14)) ! 203: ! 204: /* PSR: LCC (PSR[3]): set/get. */ ! 205: #define GET_PSR_LCC() ((m_cregs[CR_PSR] >> 3) & 1) ! 206: #define SET_PSR_LCC(val) (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 3)) | (((val) & 1) << 3)) ! 207: ! 208: /* PSR: IM (PSR[4]): set/get. */ ! 209: #define GET_PSR_IM() ((m_cregs[CR_PSR] >> 4) & 1) ! 210: #define SET_PSR_IM(val) (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 4)) | (((val) & 1) << 4)) ! 211: ! 212: /* PSR: PIM (PSR[5]): set/get. */ ! 213: #define GET_PSR_PIM() ((m_cregs[CR_PSR] >> 5) & 1) ! 214: #define SET_PSR_PIM(val) (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 5)) | (((val) & 1) << 5)) ! 215: ! 216: /* PSR: U (PSR[6]): set/get. */ ! 217: #define GET_PSR_U() ((m_cregs[CR_PSR] >> 6) & 1) ! 218: #define SET_PSR_U(val) (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 6)) | (((val) & 1) << 6)) ! 219: ! 220: /* PSR: PU (PSR[7]): set/get. */ ! 221: #define GET_PSR_PU() ((m_cregs[CR_PSR] >> 7) & 1) ! 222: #define SET_PSR_PU(val) (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 7)) | (((val) & 1) << 7)) ! 223: ! 224: /* PSR: Pixel size (PSR[23..22]): set/get. */ ! 225: #define GET_PSR_PS() ((m_cregs[CR_PSR] >> 22) & 0x3) ! 226: #define SET_PSR_PS(val) (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~0x00c00000) | (((val) & 0x3) << 22)) ! 227: ! 228: /* PSR: Pixel mask (PSR[31..24]): set/get. */ ! 229: #define GET_PSR_PM() ((m_cregs[CR_PSR] >> 24) & 0xff) ! 230: #define SET_PSR_PM(val) (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~0xff000000) | (((val) & 0xff) << 24)) ! 231: ! 232: /* EPSR: WP bit (EPSR[14]): set/get. */ ! 233: #define GET_EPSR_WP() ((m_cregs[CR_EPSR] >> 14) & 1) ! 234: #define SET_EPSR_WP(val) (m_cregs[CR_EPSR] = (m_cregs[CR_EPSR] & ~(1 << 14)) | (((val) & 1) << 14)) ! 235: ! 236: /* EPSR: INT bit (EPSR[17]): set/get. */ ! 237: #define GET_EPSR_INT() ((m_cregs[CR_EPSR] >> 17) & 1) ! 238: #define SET_EPSR_INT(val) (m_cregs[CR_EPSR] = (m_cregs[CR_EPSR] & ~(1 << 17)) | (((val) & 1) << 17)) ! 239: ! 240: /* EPSR: OF flag (EPSR[24]): set/get. */ ! 241: #define GET_EPSR_OF() ((m_cregs[CR_EPSR] >> 24) & 1) ! 242: #define SET_EPSR_OF(val) (m_cregs[CR_EPSR] = (m_cregs[CR_EPSR] & ~(1 << 24)) | (((val) & 1) << 24)) ! 243: ! 244: /* EPSR: BE flag (EPSR[23]): set/get. */ ! 245: #define GET_EPSR_BE() ((m_cregs[CR_EPSR] >> 23) & 1) ! 246: #define SET_EPSR_BE(val) (m_cregs[CR_EPSR] = (m_cregs[CR_EPSR] & ~(1 << 23)) | (((val) & 1) << 23)) ! 247: ! 248: /* DIRBASE: ATE bit (DIRBASE[0]): get. */ ! 249: #define GET_DIRBASE_ATE() (m_cregs[CR_DIRBASE] & 1) ! 250: ! 251: /* DIRBASE: CS8 bit (DIRBASE[7]): get. */ ! 252: #define GET_DIRBASE_CS8() ((m_cregs[CR_DIRBASE] >> 7) & 1) ! 253: ! 254: /* DIRBASE: CS8 bit (DIRBASE[7]): get. */ ! 255: #define GET_DIRBASE_ITI() ((m_cregs[CR_DIRBASE] >> 5) & 1) ! 256: ! 257: /* FSR: FTE bit (FSR[5]): set/get. */ ! 258: #define GET_FSR_FTE() ((m_cregs[CR_FSR] >> 5) & 1) ! 259: #define SET_FSR_FTE(val) (m_cregs[CR_FSR] = (m_cregs[CR_FSR] & ~(1 << 5)) | (((val) & 1) << 5)) ! 260: ! 261: /* FSR: SE bit (FSR[8]): set/get. */ ! 262: #define GET_FSR_SE() ((m_cregs[CR_FSR] >> 8) & 1) ! 263: #define SET_FSR_SE(val) (m_cregs[CR_FSR] = (m_cregs[CR_FSR] & ~(1 << 8)) | (((val) & 1) << 8)) ! 264: ! 265: /* FSR: SE bit (RM[3..2]): set/get. */ ! 266: #define GET_FSR_RM() ((m_cregs[CR_FSR] >> 2) & 3) ! 267: #define SET_FSR_RM(val) (m_cregs[CR_FSR] = (m_cregs[CR_FSR] & ~0xC) | (((val) & 3) << 2)) ! 268: ! 269: #define CLEAR_FLOW() (m_flow &= FLOW_CLEAR_MASK) ! 270: ! 271: /* check for pending trap */ ! 272: #define PENDING_TRAP() (m_flow & TRAP_MASK) ! 273: ! 274: /* check for updated PC */ ! 275: #define GET_PC_UPDATED() (m_flow & PC_UPDATED) ! 276: #define SET_PC_UPDATED() m_flow |= PC_UPDATED ! 277: ! 278: /* access fault traps */ ! 279: #define GET_EXITING_MEMRW() (m_flow & EXITING_MEMRW) ! 280: #define SET_EXITING_MEMRW(val) (m_flow = (val) | (m_flow & ~EXITING_MEMRW)) ! 281: ! 282: const UINT32 INSN_NOP = 0xA0000000; ! 283: const UINT32 INSN_DIM = 0x00000200; ! 284: const UINT32 INSN_FNOP = 0xB0000000; ! 285: const UINT32 INSN_FNOP_DIM = INSN_FNOP | INSN_DIM; ! 286: const UINT32 INSN_FP = 0x48000000; ! 287: const UINT32 INSN_FP_DIM = INSN_FP | INSN_DIM; ! 288: const UINT32 INSN_MASK = 0xFC000000; ! 289: const UINT32 INSN_MASK_DIM = INSN_MASK | INSN_DIM; ! 290: ! 291: const size_t I860_ICACHE_SZ = 9; // in powers of two lines (2^9 = 512; 512 x 2 words = 4 kbytes) ! 292: const size_t I860_ICACHE_MASK = (1<<I860_ICACHE_SZ)-1; ! 293: const size_t I860_TLB_SZ = 11; // in powers of two ! 294: const size_t I860_TLB_MASK = (1<<I860_TLB_SZ)-1; ! 295: const size_t I860_PAGE_SZ = 12; // in powers of two ! 296: const size_t I860_PAGE_OFF_MASK = (1<<I860_PAGE_SZ)-1; ! 297: const size_t I860_PAGE_FRAME_MASK = ~I860_PAGE_OFF_MASK; ! 298: const size_t I860_TLB_FLAGS = I860_PAGE_OFF_MASK; ! 299: ! 300: /* Control register numbers. */ ! 301: enum { ! 302: CR_FIR = 0, ! 303: CR_PSR = 1, ! 304: CR_DIRBASE = 2, ! 305: CR_DB = 3, ! 306: CR_FSR = 4, ! 307: CR_EPSR = 5 ! 308: }; ! 309: ! 310: class i860_reg { ! 311: UINT32 id; ! 312: const char* name; ! 313: const char* format; ! 314: const UINT32* reg; ! 315: public: ! 316: i860_reg() : id(0), name(0), format(0), reg(&id) {} ! 317: ! 318: bool valid() { ! 319: return name; ! 320: } ! 321: ! 322: void formatstr(const char* format) { ! 323: this->format = format; ! 324: } ! 325: ! 326: void set(int regId, const char* name, const UINT32 * reg) { ! 327: this->id = regId; ! 328: this->name = name; ! 329: this->reg = reg; ! 330: } ! 331: ! 332: UINT32 get() const { ! 333: return *reg; ! 334: } ! 335: ! 336: const char* get_name() { ! 337: return name; ! 338: } ! 339: }; ! 340: ! 341: class i860_cpu_device { ! 342: public: ! 343: // construction/destruction ! 344: i860_cpu_device(); ! 345: ! 346: /* External interface */ ! 347: void send_msg(int msg); ! 348: void init(); ! 349: void uninit(); ! 350: void halt(bool state); ! 351: inline bool is_halted() {return m_halt;}; ! 352: ! 353: /* Run one i860 cycle */ ! 354: void run_cycle(); ! 355: /* Run the i860 thread */ ! 356: void run(); ! 357: /* i860 thread message handler */ ! 358: bool handle_msgs(); ! 359: /* External tick event for the i860 emulator to update real-time dependent state + interrupt flag */ ! 360: void tick(bool intr); ! 361: /* Lock acquired by debugger to block other threads (e.g. m68k) */ ! 362: lock_t m_debugger_lock; ! 363: ! 364: #if ENABLE_PERF_COUNTERS ! 365: UINT64 m_m68k_cylces; ! 366: #endif ! 367: ! 368: private: ! 369: // debugger ! 370: void debugger(char cmd, const char* format, ...); ! 371: void debugger(); ! 372: ! 373: /* Message port for host->i860 communication */ ! 374: volatile int m_port; ! 375: lock_t m_port_lock; ! 376: ! 377: #if ENABLE_I860_THREAD ! 378: thread_t* m_thread; ! 379: #endif ! 380: ! 381: #if ENABLE_PERF_COUNTERS ! 382: UINT64 m_insn_decoded; ! 383: UINT64 m_icache_hit; ! 384: UINT64 m_icache_miss; ! 385: UINT64 m_icache_inval; ! 386: UINT64 m_tlb_hit; ! 387: UINT64 m_tlb_miss; ! 388: UINT64 m_tlb_inval; ! 389: UINT64 m_intrs; ! 390: UINT32 m_time_delta_ms; ! 391: UINT32 m_abs_time_ms; ! 392: ! 393: void dump_reset_perfc(); ! 394: #endif ! 395: ! 396: /* Debugger stuff */ ! 397: char m_lastcmd; ! 398: char m_console[512*1024]; ! 399: int m_console_idx; ! 400: bool m_break_on_next_msg; ! 401: UINT32 m_traceback[256]; ! 402: int m_traceback_idx; ! 403: ! 404: /* Program counter (1 x 32-bits). Reset starts at pc=0xffffff00. */ ! 405: UINT32 m_pc; ! 406: ! 407: /* Integer registers (32 x 32-bits). */ ! 408: UINT32 m_iregs[32]; ! 409: ! 410: /* Floating point registers (32 x 32-bits, 16 x 64 bits, or 8 x 128 bits). ! 411: When referenced as pairs or quads, the higher numbered registers ! 412: are the upper bits. E.g., double precision f0 is f1:f0. */ ! 413: UINT8 m_fregs[32 * 4]; ! 414: ! 415: /* Control registers (6 x 32-bits). */ ! 416: UINT32 m_cregs[6]; ! 417: ! 418: /* Dual instruction mode flags */ ! 419: int m_dim; ! 420: bool m_dim_cc; ! 421: bool m_dim_cc_valid; ! 422: int m_save_dim; ! 423: int m_save_flow; ! 424: bool m_save_cc; ! 425: bool m_save_cc_valid; ! 426: ! 427: /* Special registers (4 x 64-bits). */ ! 428: union ! 429: { ! 430: float s; ! 431: double d; ! 432: } m_KR, m_KI, m_T; ! 433: ! 434: UINT64 m_merge; ! 435: ! 436: /* The adder pipeline, always 3 stages. */ ! 437: struct ! 438: { ! 439: /* The stage contents. */ ! 440: union { ! 441: float s; ! 442: double d; ! 443: } val; ! 444: ! 445: /* The stage status bits. */ ! 446: struct { ! 447: /* Adder result precision (1 = dbl, 0 = sgl). */ ! 448: char arp; ! 449: } stat; ! 450: } m_A[3]; ! 451: ! 452: /* The multiplier pipeline. 3 stages for single precision, 2 stages ! 453: for double precision, and confusing for mixed precision. */ ! 454: struct { ! 455: /* The stage contents. */ ! 456: union { ! 457: float s; ! 458: double d; ! 459: } val; ! 460: ! 461: /* The stage status bits. */ ! 462: struct { ! 463: /* Multiplier result precision (1 = dbl, 0 = sgl). */ ! 464: char mrp; ! 465: } stat; ! 466: } m_M[3]; ! 467: ! 468: /* The load pipeline, always 3 stages. */ ! 469: struct { ! 470: /* The stage contents. */ ! 471: union { ! 472: float s; ! 473: double d; ! 474: } val; ! 475: ! 476: /* The stage status bits. */ ! 477: struct { ! 478: /* Load result precision (1 = dbl, 0 = sgl). */ ! 479: char lrp; ! 480: } stat; ! 481: } m_L[3]; ! 482: ! 483: /* The graphics/integer pipeline, always 1 stage. */ ! 484: struct { ! 485: /* The stage contents. */ ! 486: union { ! 487: float s; ! 488: double d; ! 489: } val; ! 490: ! 491: /* The stage status bits. */ ! 492: struct { ! 493: /* Integer/graphics result precision (1 = dbl, 0 = sgl). */ ! 494: char irp; ! 495: } stat; ! 496: } m_G; ! 497: ! 498: /* Instruction cache */ ! 499: UINT64 m_icache[1<<I860_ICACHE_SZ]; ! 500: UINT32 m_icache_vaddr[1<<I860_ICACHE_SZ]; ! 501: ! 502: /* Translation look-aside buffer */ ! 503: UINT32 m_tlb_vaddr[1<<I860_TLB_SZ]; ! 504: UINT32 m_tlb_paddr[1<<I860_TLB_SZ]; ! 505: ! 506: /* ! 507: * Halt state. Can be set externally ! 508: */ ! 509: volatile bool m_halt; ! 510: ! 511: /* Indicate an instruction just generated a trap, ! 512: needs to go to the trap address or a control-flow ! 513: instruction, so we know the PC is updated. */ ! 514: UINT32 m_flow; ! 515: ! 516: /* Single stepping state - for internal use. */ ! 517: UINT32 m_single_stepping; ! 518: ! 519: /* memory access */ ! 520: mem_rd_func rdmem[17]; ! 521: mem_wr_func wrmem[17]; ! 522: ! 523: void set_mem_access(bool be); ! 524: UINT8 rdcs8(UINT32 addr); ! 525: void writemem_emu(UINT32 addr, int size, UINT8 *data); ! 526: void writemem_emu(UINT32 addr, int size, UINT8 *data, UINT32 wmask); ! 527: void readmem_emu (UINT32 addr, int size, UINT8 *data); ! 528: ! 529: /* instructions */ ! 530: void insn_ld_ctrl (UINT32 insn); ! 531: void insn_st_ctrl (UINT32 insn); ! 532: void insn_ldx (UINT32 insn); ! 533: void insn_stx (UINT32 insn); ! 534: void insn_fsty (UINT32 insn); ! 535: void insn_fldy (UINT32 insn); ! 536: void insn_pstd (UINT32 insn); ! 537: void insn_ixfr (UINT32 insn); ! 538: void insn_addu (UINT32 insn); ! 539: void insn_addu_imm (UINT32 insn); ! 540: void insn_adds (UINT32 insn); ! 541: void insn_adds_imm (UINT32 insn); ! 542: void insn_subu (UINT32 insn); ! 543: void insn_subu_imm (UINT32 insn); ! 544: void insn_subs (UINT32 insn); ! 545: void insn_subs_imm (UINT32 insn); ! 546: void insn_shl (UINT32 insn); ! 547: void insn_shl_imm (UINT32 insn); ! 548: void insn_shr (UINT32 insn); ! 549: void insn_shr_imm (UINT32 insn); ! 550: void insn_shra (UINT32 insn); ! 551: void insn_shra_imm (UINT32 insn); ! 552: void insn_shrd (UINT32 insn); ! 553: void insn_and (UINT32 insn); ! 554: void insn_and_imm (UINT32 insn); ! 555: void insn_andh_imm (UINT32 insn); ! 556: void insn_andnot (UINT32 insn); ! 557: void insn_andnot_imm (UINT32 insn); ! 558: void insn_andnoth_imm (UINT32 insn); ! 559: void insn_or (UINT32 insn); ! 560: void insn_or_imm (UINT32 insn); ! 561: void insn_orh_imm (UINT32 insn); ! 562: void insn_xor (UINT32 insn); ! 563: void insn_xor_imm (UINT32 insn); ! 564: void insn_xorh_imm (UINT32 insn); ! 565: void insn_trap (UINT32 insn); ! 566: void insn_intovr (UINT32 insn); ! 567: void insn_bte (UINT32 insn); ! 568: void insn_bte_imm (UINT32 insn); ! 569: void insn_btne (UINT32 insn); ! 570: void insn_btne_imm (UINT32 insn); ! 571: void insn_bc (UINT32 insn); ! 572: void insn_bnc (UINT32 insn); ! 573: void insn_bct (UINT32 insn); ! 574: void insn_bnct (UINT32 insn); ! 575: void insn_call (UINT32 insn); ! 576: void insn_br (UINT32 insn); ! 577: void insn_bri (UINT32 insn); ! 578: void insn_calli (UINT32 insn); ! 579: void insn_bla (UINT32 insn); ! 580: void insn_flush (UINT32 insn); ! 581: void insn_fmul (UINT32 insn); ! 582: void insn_fmlow (UINT32 insn); ! 583: void insn_fadd_sub (UINT32 insn); ! 584: void insn_dualop (UINT32 insn); ! 585: void insn_frcp (UINT32 insn); ! 586: void insn_frsqr (UINT32 insn); ! 587: void insn_fxfr (UINT32 insn); ! 588: void insn_ftrunc (UINT32 insn); ! 589: void insn_fix (UINT32 insn); ! 590: void insn_famov (UINT32 insn); ! 591: void insn_fiadd_sub (UINT32 insn); ! 592: void insn_fcmp (UINT32 insn); ! 593: void insn_fzchk (UINT32 insn); ! 594: void insn_form (UINT32 insn); ! 595: void insn_faddp (UINT32 insn); ! 596: void insn_faddz (UINT32 insn); ! 597: ! 598: /* register access */ ! 599: UINT32 get_iregval(int gr); ! 600: void set_iregval(int gr, UINT32 val); ! 601: float get_fregval_s (int fr); ! 602: void set_fregval_s (int fr, float s); ! 603: double get_fregval_d (int fr); ! 604: void set_fregval_d (int fr, double d); ! 605: void SET_PSR_CC(int val); ! 606: ! 607: void invalidate_icache(); ! 608: void invalidate_tlb(); ! 609: UINT64 ifetch64(const UINT32 pc); ! 610: UINT32 ifetch(const UINT32 pc); ! 611: UINT32 ifetch_notrap(const UINT32 pc); ! 612: void handle_trap(UINT32 savepc); ! 613: void ret_from_trap(); ! 614: void unrecog_opcode (UINT32 pc, UINT32 insn); ! 615: ! 616: void decode_exec (UINT32 insn); ! 617: void dump_pipe (int type); ! 618: void dump_state (); ! 619: UINT32 disasm (UINT32 addr, int len); ! 620: offs_t disasm(char* buffer, offs_t pc); ! 621: void dbg_db (UINT32 addr, int len); ! 622: int delay_slots(UINT32 insn); ! 623: UINT32 get_address_translation (UINT32 vaddr, int is_dataref, int is_write); ! 624: float get_fval_from_optype_s (UINT32 insn, int optype); ! 625: double get_fval_from_optype_d (UINT32 insn, int optype); ! 626: int memtest(bool be); ! 627: void dbg_check_wr(UINT32 addr, int size, UINT8* data); ! 628: ! 629: /* This is theinterface for asserting an external interrupt to the i860. */ ! 630: void gen_interrupt(); ! 631: /* This is the interface for clearing an external interrupt of the i860. */ ! 632: void clr_interrupt(); ! 633: /* This is the interface for reseting the i860. */ ! 634: void reset(); ! 635: void intr(); ! 636: ! 637: typedef void (i860_cpu_device::*insn_func)(UINT32); ! 638: struct decode_tbl_t ! 639: { ! 640: /* Execute function for this opcode. */ ! 641: insn_func insn_exec; ! 642: /* Flags for this opcode. */ ! 643: char flags; ! 644: }; ! 645: static const decode_tbl_t decode_tbl[64]; ! 646: static const decode_tbl_t core_esc_decode_tbl[8]; ! 647: static const decode_tbl_t fp_decode_tbl[128]; ! 648: }; ! 649: ! 650: /* disassembler */ ! 651: int i860_disassembler(UINT32 pc, UINT32 insn, char* buffer); ! 652: ! 653: #endif /* __I860_H__ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.