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