|
|
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 <ctype.h>
1.1.1.2 root 28: #include <assert.h>
1.1.1.3 ! root 29:
1.1 root 30: #include "i860cfg.h"
1.1.1.2 root 31: #include "host.h"
1.1.1.3 ! root 32: #include "nd_sdl.hpp"
1.1 root 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;
1.1.1.3 ! root 47:
! 48: extern "C" {
! 49: class NextDimension;
! 50:
1.1 root 51: void nd_nbic_interrupt(void);
52: void Statusbar_SetNdLed(int state);
1.1.1.3 ! root 53: typedef void (*mem_rd_func)(NextDimension*, UINT32, UINT32*);
! 54: typedef void (*mem_wr_func)(NextDimension*, UINT32, const UINT32*);
1.1.1.2 root 55: }
56:
57: #if WITH_SOFTFLOAT_I860
58: extern "C" {
59: #include <softfloat.h>
1.1 root 60: }
1.1.1.2 root 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:
1.1.1.3 ! root 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) {
1.1.1.2 root 101: switch (mode) {
1.1.1.3 ! root 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;
1.1.1.2 root 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:
1.1.1.3 ! root 124: #define float_ctrl int
! 125:
1.1.1.2 root 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:
1.1.1.3 ! root 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) {
1.1.1.2 root 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
1.1 root 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 {
1.1.1.2 root 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,
1.1 root 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: };
1.1.1.3 ! root 424:
! 425: class NextDimension;
1.1 root 426:
427: class i860_cpu_device {
1.1.1.3 ! root 428: public:
! 429: NextDimension* nd;
! 430:
1.1 root 431: // construction/destruction
1.1.1.3 ! root 432: i860_cpu_device(NextDimension* nd);
1.1 root 433:
434: /* External interface */
1.1.1.3 ! root 435: void init(void);
! 436: void set_run_func(void);
! 437: void uninit(void);
1.1 root 438: void halt(bool state);
1.1.1.2 root 439: void pause(bool state);
1.1.1.3 ! root 440: inline bool is_halted(void) {return m_halt;};
! 441:
! 442: /* i860 cycle counter */
! 443: int i860cycles;
1.1 root 444: /* Run one i860 cycle */
1.1.1.3 ! root 445: void run_cycle(void);
1.1 root 446: /* Run the i860 thread */
447: void run();
1.1.1.3 ! root 448: /* i860 thread message handler */
! 449: bool handle_msgs(int msg);
! 450:
! 451: static int thread(void* data);
1.1 root 452:
1.1.1.3 ! root 453: const char* reports(double realTime, double hostTIme);
1.1 root 454: private:
455: // debugger
456: void debugger(char cmd, const char* format, ...);
1.1.1.3 ! root 457: void debugger(void);
! 458:
! 459: // softfloat control and status
! 460: float_ctrl m_fpcs;
1.1 root 461:
1.1.1.2 root 462: thread_t* m_thread;
1.1 root 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;
1.1.1.2 root 472: UINT32 m_last_rt;
473: UINT32 m_last_vt;
474: char m_report[1024];
475:
1.1 root 476: /* Debugger stuff */
477: char m_lastcmd;
1.1.1.2 root 478: char m_console[32*1024];
1.1 root 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: {
1.1.1.2 root 510: FLOAT32 s;
511: FLOAT64 d;
1.1 root 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 {
1.1.1.2 root 521: FLOAT32 s;
522: FLOAT64 d;
1.1 root 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 {
1.1.1.2 root 537: FLOAT32 s;
538: FLOAT64 d;
1.1 root 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 {
1.1.1.2 root 552: FLOAT32 s;
553: FLOAT64 d;
1.1 root 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 {
1.1.1.2 root 567: FLOAT32 s;
568: FLOAT64 d;
1.1 root 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;
1.1.1.3 ! root 590:
1.1 root 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);
1.1.1.2 root 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);
1.1 root 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);
1.1.1.2 root 677:
678: void dec_unrecog (UINT32 insn);
679:
1.1 root 680: /* register access */
681: UINT32 get_iregval(int gr);
682: void set_iregval(int gr, UINT32 val);
1.1.1.2 root 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);
1.1 root 687: void SET_PSR_CC(int val);
688:
689: void invalidate_icache();
690: void invalidate_tlb();
1.1.1.2 root 691: inline UINT64 ifetch64(const UINT32 pc);
692: UINT64 ifetch64(const UINT32 pc, const UINT32 vaddr, int const cidx);
1.1 root 693: UINT32 ifetch(const UINT32 pc);
694: UINT32 ifetch_notrap(const UINT32 pc);
1.1.1.3 ! root 695: const char* trap_info();
1.1 root 696: void handle_trap(UINT32 savepc);
697: void ret_from_trap();
698: void unrecog_opcode (UINT32 pc, UINT32 insn);
699:
700: void decode_exec (UINT32 insn);
701: void dump_pipe (int type);
702: void dump_state ();
703: UINT32 disasm (UINT32 addr, int len);
704: offs_t disasm(char* buffer, offs_t pc);
1.1.1.2 root 705: void dbg_memdump (UINT32 addr, int len);
1.1 root 706: int delay_slots(UINT32 insn);
1.1.1.2 root 707: UINT32 get_address_translation(UINT32 vaddr, int is_dataref, int is_write);
708: inline UINT32 get_address_translation(UINT32 vaddr, UINT32 voffset, UINT32 tlbidx, int is_dataref, int is_write);
709: FLOAT32 get_fval_from_optype_s (UINT32 insn, int optype);
710: FLOAT64 get_fval_from_optype_d (UINT32 insn, int optype);
1.1 root 711: int memtest(bool be);
712: void dbg_check_wr(UINT32 addr, int size, UINT8* data);
713:
714: /* This is theinterface for asserting an external interrupt to the i860. */
715: void gen_interrupt();
716: /* This is the interface for clearing an external interrupt of the i860. */
717: void clr_interrupt();
718: /* This is the interface for reseting the i860. */
719: void reset();
720: void intr();
721:
722: typedef void (i860_cpu_device::*insn_func)(UINT32);
1.1.1.2 root 723: static const insn_func decode_tbl[64];
724: static const insn_func core_esc_decode_tbl[8];
725: static const insn_func fp_decode_tbl[128];
726: static insn_func decoder_tbl[8192];
1.1 root 727: };
728:
729: /* disassembler */
730: int i860_disassembler(UINT32 pc, UINT32 insn, char* buffer);
1.1.1.3 ! root 731:
1.1 root 732: #endif /* __I860_H__ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.