1 /* $Id: m68k-impl.h,v 1.19 2009/08/29 19:28:08 fredette Exp $ */
2 
3 /* ic/m68k/m68k-impl.h - implementation header file for Motorola 68k emulation: */
4 
5 /*
6  * Copyright (c) 2002, 2003 Matt Fredette
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed by Matt Fredette.
20  * 4. The name of the author may not be used to endorse or promote products
21  *    derived from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
27  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #ifndef _IC_M68K_IMPL_H
37 #define _IC_M68K_IMPL_H
38 
39 #include <tme/common.h>
40 _TME_RCSID("$Id: m68k-impl.h,v 1.19 2009/08/29 19:28:08 fredette Exp $");
41 
42 /* includes: */
43 #include <tme/ic/m68k.h>
44 #include <tme/ic/ieee754.h>
45 #include <tme/generic/ic.h>
46 #include <setjmp.h>
47 
48 /* macros: */
49 
50 /* CPUs: */
51 #define TME_M68K_M68000		(0)
52 #define TME_M68K_M68010		(1)
53 #define TME_M68K_M68020		(2)
54 #define TME_M68K_M68030		(3)
55 #define TME_M68K_M68040		(4)
56 
57 /* FPUs: */
58 #define TME_M68K_FPU_NONE	(0)
59 #define TME_M68K_FPU_M68881	TME_BIT(0)
60 #define TME_M68K_FPU_M68882	TME_BIT(1)
61 #define TME_M68K_FPU_M6888X	(TME_M68K_FPU_M68881 | TME_M68K_FPU_M68882)
62 #define TME_M68K_FPU_M68040	TME_BIT(2)
63 #define TME_M68K_FPU_ANY	(TME_M68K_FPU_M68881 | TME_M68K_FPU_M68882 | TME_M68K_FPU_M68040)
64 
65 /* generic registers: */
66 #define tme_m68k_ireg_uint32(x)	tme_m68k_ic.tme_ic_ireg_uint32(x)
67 #define tme_m68k_ireg_int32(x)	tme_m68k_ic.tme_ic_ireg_int32(x)
68 #define tme_m68k_ireg_uint16(x)	tme_m68k_ic.tme_ic_ireg_uint16(x)
69 #define tme_m68k_ireg_int16(x)	tme_m68k_ic.tme_ic_ireg_int16(x)
70 #define tme_m68k_ireg_uint8(x)	tme_m68k_ic.tme_ic_ireg_uint8(x)
71 #define tme_m68k_ireg_int8(x)	tme_m68k_ic.tme_ic_ireg_int8(x)
72 
73 /* flags: */
74 #define TME_M68K_FLAG_C 	TME_BIT(0)
75 #define TME_M68K_FLAG_V 	TME_BIT(1)
76 #define TME_M68K_FLAG_Z 	TME_BIT(2)
77 #define TME_M68K_FLAG_N 	TME_BIT(3)
78 #define TME_M68K_FLAG_X 	TME_BIT(4)
79 #define TME_M68K_FLAG_IPM(x)	TME_FIELD_EXTRACTU(x, 8, 3)
80 #define TME_M68K_FLAG_M		TME_BIT(12)
81 #define TME_M68K_FLAG_S		TME_BIT(13)
82 #define TME_M68K_FLAG_T0	TME_BIT(14)
83 #define TME_M68K_FLAG_T1	TME_BIT(15)
84 #define TME_M68K_FLAG_CCR	(TME_M68K_FLAG_C | TME_M68K_FLAG_V | \
85 				 TME_M68K_FLAG_Z | TME_M68K_FLAG_N | \
86 				 TME_M68K_FLAG_X)
87 #define TME_M68K_FLAG_SR	(TME_M68K_FLAG_CCR | (0x7 << 8) | \
88 				 TME_M68K_FLAG_M | TME_M68K_FLAG_S | \
89 				 TME_M68K_FLAG_T0 | TME_M68K_FLAG_T1)
90 
91 /* conditions: */
92 #define TME_M68K_C_T	(0)
93 #define TME_M68K_C_F	(1)
94 #define TME_M68K_C_HI	(2)
95 #define TME_M68K_C_LS	(3)
96 #define TME_M68K_C_CC	(4)
97 #define TME_M68K_C_CS	(5)
98 #define TME_M68K_C_NE	(6)
99 #define TME_M68K_C_EQ	(7)
100 #define TME_M68K_C_VC	(8)
101 #define TME_M68K_C_VS	(9)
102 #define TME_M68K_C_PL	(10)
103 #define TME_M68K_C_MI	(11)
104 #define TME_M68K_C_GE	(12)
105 #define TME_M68K_C_LT	(13)
106 #define TME_M68K_C_GT	(14)
107 #define TME_M68K_C_LE	(15)
108 #define TME_M68K_COND_TRUE(ic, c) (_tme_m68k_conditions[(ic)->tme_m68k_ireg_ccr] & TME_BIT(c))
109 
110 /* bus cycles: */
111 #define TME_M68K_BUS_CYCLE_NORMAL		(0)
112 #define TME_M68K_BUS_CYCLE_READ			TME_BIT(0)
113 #define TME_M68K_BUS_CYCLE_FETCH		TME_BIT(1)
114 #define TME_M68K_BUS_CYCLE_RMW			TME_BIT(2)
115 #define TME_M68K_BUS_CYCLE_RAW			TME_BIT(3)
116 
117 /* exceptions: */
118 #define TME_M68K_EXCEPTION_NONE			(0)
119 #define TME_M68K_EXCEPTION_RESET		TME_BIT(0)
120 #define TME_M68K_EXCEPTION_AERR			TME_BIT(1)
121 #define TME_M68K_EXCEPTION_BERR			TME_BIT(2)
122 #define TME_M68K_EXCEPTION_TRACE		TME_BIT(3)
123 #define TME_M68K_EXCEPTION_INT(ipl, vec)	(((ipl) << 4) | ((vec) << 7))
124 #define TME_M68K_EXCEPTION_IS_INT(x)		(((x) >> 4) & 0x7)
125 #define TME_M68K_EXCEPTION_INT_VEC(x)		(((x) >> 7) & 0xff)
126 #define TME_M68K_EXCEPTION_ILL			TME_BIT(15)
127 #define TME_M68K_EXCEPTION_PRIV			TME_BIT(16)
128 #define TME_M68K_EXCEPTION_INST(x)		((x) << 17)
129 #define TME_M68K_EXCEPTION_IS_INST(x)		((x) >> 17)
130 
131 /* exception frame formats: */
132 #define TME_M68K_FORMAT_0	(0)
133 #define TME_M68K_FORMAT_1	(1)
134 #define TME_M68K_FORMAT_2	(2)
135 #define TME_M68K_FORMAT_8	(8)
136 #define TME_M68K_FORMAT_B	(0xB)
137 
138 /* exception vectors: */
139 #define TME_M68K_VECTOR_RESET_PC	(0x00)
140 #define TME_M68K_VECTOR_RESET_SP	(0x01)
141 #define TME_M68K_VECTOR_BERR		(0x02)
142 #define TME_M68K_VECTOR_AERR		(0x03)
143 #define TME_M68K_VECTOR_ILL		(0x04)
144 #define TME_M68K_VECTOR_DIV0		(0x05)
145 #define TME_M68K_VECTOR_CHK		(0x06)
146 #define TME_M68K_VECTOR_TRAP		(0x07)
147 #define TME_M68K_VECTOR_PRIV		(0x08)
148 #define TME_M68K_VECTOR_TRACE		(0x09)
149 #define TME_M68K_VECTOR_LINE_A		(0x0a)
150 #define TME_M68K_VECTOR_LINE_F		(0x0b)
151 					/* (0x0c is unassigned, reserved) */
152 #define TME_M68K_VECTOR_COPROC		(0x0d)
153 #define TME_M68K_VECTOR_FORMAT		(0x0e)
154 #define TME_M68K_VECTOR_INT_UNINIT	(0x0f)
155 					/* (0x10 through 0x17 are unassigned, reserved) */
156 #define TME_M68K_VECTOR_SPURIOUS	(0x18)
157 					/* (0x19 through 0x1f are the interrupt autovectors) */
158 #define TME_M68K_VECTOR_TRAP_0		(0x20)
159 					/* (0x21 through 0x2f are also TRAP vectors) */
160 
161 /* m6888x type specifiers: */
162 #define TME_M6888X_TYPE_LONG		(0)
163 #define TME_M6888X_TYPE_SINGLE		(1)
164 #define TME_M6888X_TYPE_EXTENDED80	(2)
165 #define TME_M6888X_TYPE_PACKEDDEC	(3)
166 #define TME_M6888X_TYPE_WORD		(4)
167 #define TME_M6888X_TYPE_DOUBLE		(5)
168 #define TME_M6888X_TYPE_BYTE		(6)
169 #define TME_M6888X_TYPE_PACKEDDEC_DK	(7)
170 #define TME_M6888X_TYPE_INVALID		(TME_M6888X_TYPE_PACKEDDEC_DK)
171 
172 /* sizes: */
173 #define TME_M68K_SIZE_UNDEF	(-1)
174 #define TME_M68K_SIZE_UNSIZED	(0)
175 #define TME_M68K_SIZE_8		(1)
176 #define TME_M68K_SIZE_16	(2)
177 				/* 3 unused */
178 #define TME_M68K_SIZE_32	(4)
179 				/* 5 unused */
180 				/* 6 unused */
181 				/* 7 unused */
182 #define TME_M68K_SIZE_64	(8)
183 				/* 8 unused */
184 				/* 9 unused */
185 				/* 10 unused */
186 				/* 11 unused */
187 #define TME_M68K_SIZE_96	(12)
188 
189 /* opcode parameters: */
190 
191 /* bits 0 through 7, in the opcode map, are the instruction index.
192    immediately after the initial decoding, these bits are replaced
193    with the least significant 8 bits of the opcode word, making bits 0
194    through 2 any EA reg value, and bits 3 through 5 any EA mode
195    value: */
196 #define TME_M68K_OPCODE_INSN(x)		((x) << 0)
197 #define TME_M68K_OPCODE_INSN_MASK	TME_M68K_OPCODE_INSN(0xff)
198 #define TME_M68K_OPCODE_INSN_WHICH(params)	TME_FIELD_MASK_EXTRACTU(params, TME_M68K_OPCODE_INSN(0xff))
199 #define TME_M68K_OPCODE_EA_REG(x)      ((x) << 0)
200 #define TME_M68K_OPCODE_EA_MODE(x)     ((x) << 3)
201 #define TME_M68K_OPCODE_EA_REG_MASK    TME_M68K_OPCODE_EA_REG(0x7)
202 #define TME_M68K_OPCODE_EA_MODE_MASK   TME_M68K_OPCODE_EA_MODE(0x7)
203 #define TME_M68K_OPCODE_EA_MODE_WHICH(params)  TME_FIELD_MASK_EXTRACTU(params, TME_M68K_OPCODE_EA_MODE_MASK)
204 #define TME_M68K_OPCODE_EA_REG_WHICH(params)   TME_FIELD_MASK_EXTRACTU(params, TME_M68K_OPCODE_EA_REG_MASK)
205 
206 /* bits 8 through 15 and 16 through 23 are the operands' ic offsets: */
207 #define _TME_M68K_OPCODE_OP(f)		((tme_uint8_t) (((tme_uint8_t *) &((struct tme_m68k *) 0)->f) - ((tme_uint8_t *) (struct tme_m68k *) 0)))
208 #define TME_M68K_OPCODE_OP1(f)		(_TME_M68K_OPCODE_OP(f) << 8)
209 #define TME_M68K_OPCODE_OP0(f)		(_TME_M68K_OPCODE_OP(f) << 16)
210 #define TME_M68K_OPCODE_OP1_WHICH(ic, params) (((tme_uint8_t *) (ic)) + TME_FIELD_MASK_EXTRACTU(params, 0x0000ff00))
211 #define TME_M68K_OPCODE_OP0_WHICH(ic, params) (((tme_uint8_t *) (ic)) + TME_FIELD_MASK_EXTRACTU(params, 0x00ff0000))
212 
213 /* bits 24 and 25 give the size of any immediate operand: */
214 #define TME_M68K_OPCODE_IMM_16		TME_BIT(24)
215 #define TME_M68K_OPCODE_IMM_32		TME_BIT(25)
216 #define TME_M68K_OPCODE_HAS_IMM(params)	(((params) & (TME_M68K_OPCODE_IMM_16 | TME_M68K_OPCODE_IMM_32)) != 0)
217 
218 /* bit 26 is set for a move instruction with a memory destination
219    ((TME_M68K_OPCODE_SPECOP is additionally set for a
220    move-memory-to-memory instruction).
221    bit 27 is set for an opcode that needs its EA read.
222    bit 28 is set for an opcode that needs its EA written.
223 
224    if the EA needs to be read or written, bits 29 and 30 give the size
225    of the EA, which can be TME_M68K_SIZE_8, TME_M68K_SIZE_16, or
226    TME_M68K_SIZE_32, encoded as (TME_M68K_SIZE_32 - size).  if the EA
227    doesn't need to be read or written, but the EA must be calculated,
228    bit 29 is set, and size of the EA is understood to be
229    TME_M68K_SIZE_UNSIZED: */
230 #define TME_M68K_OPCODE_EA_Y		TME_BIT(26)
231 #define TME_M68K_OPCODE_EA_READ		TME_BIT(27)
232 #define TME_M68K_OPCODE_EA_WRITE	TME_BIT(28)
233 #define TME_M68K_OPCODE_EA_UNSIZED	TME_BIT(29)
234 #define TME_M68K_OPCODE_EA_SIZE(x)	((TME_M68K_SIZE_32 - (x)) * TME_M68K_OPCODE_EA_UNSIZED)
235 #define TME_M68K_OPCODE_EA_SIZE_MASK	TME_M68K_OPCODE_EA_SIZE(1)
236 #define TME_M68K_OPCODE_HAS_EA(params)	((params) & (TME_M68K_OPCODE_EA_READ | TME_M68K_OPCODE_EA_WRITE | TME_M68K_OPCODE_EA_UNSIZED))
237 #define TME_M68K_OPCODE_EA_SIZE_WHICH(params)					\
238 	(((params) & (TME_M68K_OPCODE_EA_READ | TME_M68K_OPCODE_EA_WRITE)) ?	\
239 	 (TME_M68K_SIZE_32							\
240 	  - TME_FIELD_MASK_EXTRACTU(params, TME_M68K_OPCODE_EA_SIZE_MASK))	\
241 	 : TME_M68K_SIZE_UNSIZED)
242 
243 /* if the opcode is special, bit 31 is set: */
244 #define TME_M68K_OPCODE_SPECOP		TME_BIT(31)
245 
246 /* major modes of the emulator: */
247 #define TME_M68K_MODE_EXECUTION	(0)
248 #define TME_M68K_MODE_EXCEPTION	(1)
249 #define TME_M68K_MODE_RTE	(2)
250 #define TME_M68K_MODE_STOP	(3)
251 #define TME_M68K_MODE_HALT	(4)
252 
253 /* mode-specific flags: */
254 #define TME_M68K_EXECUTION_INST_CANFAULT	TME_BIT(0)
255 
256 /* given a linear address, this hashes it into a TLB entry: */
257 #define _TME_M68K_TLB_HASH_SIZE (1024)
258 #define TME_M68K_TLB_ADDRESS_BIAS(n)	((n) << 10)
259 #define TME_M68K_DTLB_ENTRY(ic, context, function_code, linear_address)	\
260   (((ic)->_tme_m68k_tlb_array					\
261     + ((((context) * 16)			\
262 	+ ((linear_address)			\
263 	   / TME_M68K_TLB_ADDRESS_BIAS(1)))	\
264        % _TME_M68K_TLB_HASH_SIZE))		\
265    + (0 && (function_code)))
266 
267 /* macros for sequence control: */
268 #define TME_M68K_SEQUENCE_START						\
269 do {									\
270   ic->_tme_m68k_sequence._tme_m68k_sequence_mode_flags = 0;		\
271   ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted = 0;	\
272   ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next = 1;		\
273 } while (/* CONSTCOND */ 0)
274 #define TME_M68K_SEQUENCE_RESTARTING					\
275   (ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted		\
276    >= ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next)
277 #define TME_M68K_SEQUENCE_RESTART					\
278 do {									\
279   if (!TME_M68K_SEQUENCE_RESTARTING)					\
280     ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted =	\
281       ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next;		\
282   ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next = 1;		\
283 } while (/* CONSTCOND */ 0)
284 #define TME_M68K_SEQUENCE_TRANSFER_STEP					\
285 do {									\
286   ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next++;		\
287 } while (/* CONSTCOND */ 0)
288 
289 /* instruction handler macros: */
290 #define TME_M68K_INSN_DECL(name) void name _TME_P((struct tme_m68k *, void *, void *))
291 #ifdef __STDC__
292 #define TME_M68K_INSN(name) void name(struct tme_m68k *ic, void *_op0, void *_op1)
293 #else  /* !__STDC__ */
294 #define TME_M68K_INSN(name) void name(ic, _op0, _op1) struct tme_m68k *ic; void *_op0, *_op1;
295 #endif /* !__STDC__ */
296 #define TME_M68K_INSN_OP0(t) 		(*((t *) _op0))
297 #define TME_M68K_INSN_OP1(t) 		(*((t *) _op1))
298 #define TME_M68K_INSN_OPCODE		ic->_tme_m68k_insn_opcode
299 #define TME_M68K_INSN_SPECOP		ic->_tme_m68k_insn_specop
300 #define TME_M68K_INSN_OK		return
301 #define TME_M68K_INSN_EXCEPTION(e)	tme_m68k_exception(ic, e)
302 #define TME_M68K_INSN_PRIV			\
303   if (!TME_M68K_PRIV(ic))	\
304     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_PRIV)
305 #define TME_M68K_INSN_ILL			\
306   TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_ILL)
307 #define TME_M68K_INSN_CANFAULT			\
308 do {						\
309   ic->_tme_m68k_mode_flags			\
310     |= TME_M68K_EXECUTION_INST_CANFAULT;	\
311 } while (/* CONSTCOND */ 0)
312 #define TME_M68K_INSN_BRANCH(pc)				\
313 do {								\
314   tme_m68k_verify_end_branch(ic, pc);				\
315   ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next = (pc);	\
316   if (__tme_predict_false((ic->tme_m68k_ireg_sr			\
317 			   & ic->_tme_m68k_sr_mask_t) != 0)) {	\
318     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_TRACE);		\
319   }								\
320   if (tme_m68k_go_slow(ic)) {					\
321     TME_M68K_SEQUENCE_START;					\
322     tme_m68k_redispatch(ic);					\
323   }								\
324 } while (/* CONSTCOND */ 0)
325 #define TME_M68K_INSN_CHANGE_SR(reg)				\
326 do {								\
327   TME_M68K_INSN_PRIV;						\
328   tme_m68k_change_sr(ic, reg);					\
329   tme_m68k_verify_end_branch(ic, ic->tme_m68k_ireg_pc_next);	\
330   if (__tme_predict_false((ic->tme_m68k_ireg_sr			\
331 			   & ic->_tme_m68k_sr_mask_t) != 0)) {	\
332     ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc;		\
333     ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;		\
334     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_TRACE);		\
335   }								\
336   if (tme_m68k_go_slow(ic)) {					\
337     TME_M68K_SEQUENCE_START;					\
338     tme_m68k_redispatch(ic);					\
339   }								\
340 } while (/* CONSTCOND */ 0)
341 
342 /* logging: */
343 #define TME_M68K_LOG_HANDLE(ic)					\
344   (&(ic)->tme_m68k_element->tme_element_log_handle)
345 #define tme_m68k_log_start(ic, level, rc)			\
346 do {								\
347   tme_log_start(TME_M68K_LOG_HANDLE(ic), level, rc) {		\
348     if ((ic)->_tme_m68k_mode != TME_M68K_MODE_EXECUTION) {	\
349       tme_log_part(TME_M68K_LOG_HANDLE(ic),			\
350                    "mode=%d ",					\
351                    (ic)->_tme_m68k_mode);			\
352     }								\
353     else {							\
354       tme_log_part(TME_M68K_LOG_HANDLE(ic),			\
355 	           "pc=%c/0x%08x ",				\
356 	           (((ic)->tme_m68k_ireg_sr 			\
357 		     & (TME_M68K_FLAG_M				\
358 		        | TME_M68K_FLAG_S))			\
359 		    ? 'S'					\
360 		    : 'U'),					\
361 		   ic->tme_m68k_ireg_pc);			\
362     }								\
363     do
364 #define tme_m68k_log_finish(ic)					\
365     while (/* CONSTCOND */ 0);					\
366   } tme_log_finish(TME_M68K_LOG_HANDLE(ic));			\
367 } while (/* CONSTCOND */ 0)
368 #define tme_m68k_log(ic, level, rc, x)		\
369 do {						\
370   tme_m68k_log_start(ic, level, rc) {		\
371     tme_log_part x;				\
372   } tme_m68k_log_finish(ic);			\
373 } while (/* CONSTCOND */ 0)
374 
375 /* miscellaneous: */
376 #define TME_M68K_PRIV(ic)	((ic)->tme_m68k_ireg_sr & TME_M68K_FLAG_S)
377 #define TME_M68K_FUNCTION_CODE_DATA(ic)	\
378   (TME_M68K_PRIV(ic) ? TME_M68K_FC_SD : TME_M68K_FC_UD)
379 #define TME_M68K_FUNCTION_CODE_PROGRAM(ic)	\
380   (TME_M68K_PRIV(ic) ? TME_M68K_FC_SP : TME_M68K_FC_UP)
381 #define TME_M68K_INSN_WORDS_MAX	(11)
382 
383 /* structures: */
384 struct tme_m68k;
385 
386 /* an memory read or write function: */
387 typedef void (*_tme_m68k_xfer_memx) _TME_P((struct tme_m68k *));
388 typedef void (*_tme_m68k_xfer_mem) _TME_P((struct tme_m68k *, int));
389 
390 /* an insn function: */
391 typedef TME_M68K_INSN_DECL((*_tme_m68k_insn));
392 
393 /* an m68k sequence: */
394 struct _tme_m68k_sequence {
395 
396   /* the mode of the emulator: */
397   unsigned int _tme_m68k_sequence_mode;
398 
399   /* any mode-specific flags for the sequence: */
400   unsigned int _tme_m68k_sequence_mode_flags;
401 
402   /* the ordinal of the next memory transfer.  always starts from one: */
403   unsigned short _tme_m68k_sequence_transfer_next;
404 
405   /* the ordinal of the memory transfer that faulted.  if this is
406      greater than or equal to _tme_m68k_sequence_transfer_next, we are
407      restarting, and bus cycles and changes to the m68k state are
408      forbidden: */
409   unsigned short _tme_m68k_sequence_transfer_faulted;
410 
411   /* the fault happened after this number of bytes were successfully
412      transferred: */
413   unsigned short _tme_m68k_sequence_transfer_faulted_after;
414 
415 #ifdef _TME_M68K_VERIFY
416   /* the sequence unique identifier: */
417   unsigned long _tme_m68k_sequence_uid;
418 #endif /* _TME_M68K_VERIFY */
419 };
420 
421 /* the m68k state: */
422 struct tme_m68k {
423 
424   /* the IC data structure.  it is beneficial to have this structure
425      first, since register numbers can often simply be scaled and
426      added without an offset to the struct tme_m68k pointer to get
427      to their contents: */
428   struct tme_ic tme_m68k_ic;
429 
430   /* the m68k type: */
431   int tme_m68k_type;
432 
433   /* the backpointer to our element: */
434   struct tme_element *tme_m68k_element;
435 
436   /* our bus connection.  if both are defined, the m68k bus connection
437      is an adaptation layer for the generic bus connection: */
438   struct tme_m68k_bus_connection *_tme_m68k_bus_connection;
439   struct tme_bus_connection *_tme_m68k_bus_generic;
440 
441   /* a jmp_buf back to the dispatcher: */
442   jmp_buf _tme_m68k_dispatcher;
443 
444   /* the current sequence: */
445   struct _tme_m68k_sequence _tme_m68k_sequence;
446 #define _tme_m68k_mode _tme_m68k_sequence._tme_m68k_sequence_mode
447 #define _tme_m68k_mode_flags _tme_m68k_sequence._tme_m68k_sequence_mode_flags
448 #define _tme_m68k_insn_uid _tme_m68k_sequence._tme_m68k_sequence_uid
449 
450   /* the CPU-dependent functions for the different modes: */
451   void (*_tme_m68k_mode_execute) _TME_P((struct tme_m68k *));
452   void (*_tme_m68k_mode_exception) _TME_P((struct tme_m68k *));
453   void (*_tme_m68k_mode_rte) _TME_P((struct tme_m68k *));
454 
455   /* the CPU-dependent status register T bits mask: */
456   tme_uint16_t _tme_m68k_sr_mask_t;
457 
458   /* the instruction burst count, and the remaining burst: */
459   unsigned int _tme_m68k_instruction_burst;
460   unsigned int _tme_m68k_instruction_burst_remaining;
461 
462   /* the effective address: */
463 #define _tme_m68k_ea_address tme_m68k_ireg_ea
464   unsigned int _tme_m68k_ea_function_code;
465 
466   /* instruction fetch information: */
467   tme_uint16_t _tme_m68k_insn_fetch_buffer[TME_M68K_INSN_WORDS_MAX];
468 #define _tme_m68k_insn_opcode _tme_m68k_insn_fetch_buffer[0]
469 #define _tme_m68k_insn_specop _tme_m68k_insn_fetch_buffer[1]
470   struct tme_m68k_tlb *_tme_m68k_insn_fetch_fast_itlb;
471   const tme_shared tme_uint8_t *_tme_m68k_insn_fetch_fast_start;
472   const tme_shared tme_uint8_t *_tme_m68k_insn_fetch_fast_next;
473   const tme_shared tme_uint8_t *_tme_m68k_insn_fetch_fast_last;
474   unsigned int _tme_m68k_insn_fetch_slow_next;
475   unsigned int _tme_m68k_insn_fetch_slow_count_fast;
476   unsigned int _tme_m68k_insn_fetch_slow_count_total;
477 
478   /* the TLB set: */
479   struct tme_m68k_tlb _tme_m68k_tlb_array[_TME_M68K_TLB_HASH_SIZE + 1];
480 #define _tme_m68k_itlb _tme_m68k_tlb_array[_TME_M68K_TLB_HASH_SIZE]
481 
482   /* the bus context: */
483   tme_bus_context_t _tme_m68k_bus_context;
484 
485   /* exception handling information: */
486   tme_uint32_t _tme_m68k_exceptions;
487 
488   /* this must be one iff this CPU has a 16-bit bus, else zero: */
489   tme_uint32_t _tme_m68k_bus_16bit;
490 
491   /* group 0 exception information: */
492   void (*_tme_m68k_group0_hook) _TME_P((struct tme_m68k *));
493   unsigned int _tme_m68k_group0_flags;
494   unsigned int _tme_m68k_group0_function_code;
495   tme_uint32_t _tme_m68k_group0_address;
496   struct _tme_m68k_sequence _tme_m68k_group0_sequence;
497   tme_uint8_t _tme_m68k_group0_buffer_read[sizeof(tme_uint32_t)];
498   unsigned int _tme_m68k_group0_buffer_read_size;
499   unsigned int _tme_m68k_group0_buffer_read_softrr;
500   tme_uint8_t _tme_m68k_group0_buffer_write[sizeof(tme_uint32_t)];
501   unsigned int _tme_m68k_group0_buffer_write_size;
502   unsigned int _tme_m68k_group0_buffer_write_softrr;
503 
504   /* the external request lines: */
505   tme_mutex_t tme_m68k_external_mutex;
506   tme_cond_t tme_m68k_external_cond;
507   unsigned int tme_m68k_external_reset;
508   unsigned int tme_m68k_external_halt;
509   unsigned int tme_m68k_external_ipl;
510   unsigned int tme_m68k_external_ipl_previous_nmi;
511 
512   /* any FPU state: */
513   int tme_m68k_fpu_enabled;
514   int tme_m68k_fpu_type;
515   struct tme_ieee754_ctl tme_m68k_fpu_ieee754_ctl;
516   _tme_const struct tme_ieee754_ops *tme_m68k_fpu_ieee754_ops;
517   struct tme_float tme_m68k_fpu_fpreg[8];
518   tme_uint32_t tme_m68k_fpu_fpcr;
519   tme_uint32_t tme_m68k_fpu_fpsr;
520   tme_uint32_t tme_m68k_fpu_fpiar;
521   int tme_m68k_fpu_incomplete_abort;
522 
523 #ifdef _TME_M68K_STATS
524   /* statistics: */
525   struct {
526 
527     /* the total number of instructions executed: */
528     tme_uint64_t tme_m68k_stats_insns_total;
529 
530     /* the total number of instructions executed by the slow executor: */
531     tme_uint64_t tme_m68k_stats_insns_slow;
532 
533     /* the total number of redispatches: */
534     tme_uint64_t tme_m68k_stats_redispatches;
535 
536     /* the total number of data memory operations: */
537     tme_uint64_t tme_m68k_stats_memory_total;
538 
539     /* the total number of ITLB fills: */
540     tme_uint64_t tme_m68k_stats_itlb_fill;
541 
542     /* the total number of DTLB fills: */
543     tme_uint64_t tme_m68k_stats_dtlb_fill;
544 
545   } tme_m68k_stats;
546 #endif /* _TME_M68K_STATS */
547 };
548 
549 /* the read-modify-write cycle state: */
550 struct tme_m68k_rmw {
551 
552   /* the operand size: */
553   unsigned int tme_m68k_rmw_size;
554 
555   /* the address count, and up to two addresses: */
556   unsigned int tme_m68k_rmw_address_count;
557   tme_uint32_t tme_m68k_rmw_addresses[2];
558 
559   /* if nonzero, the operand at the corresponding address has been
560      read with a slow bus cycle.  address zero is read into the memx
561      register, and address one is read into the memy register: */
562   unsigned int tme_m68k_rmw_slow_reads[2];
563 
564   /* the TLB entries used by the addresses.  if two addresses are
565      sharing one TLB entry, that TLB entry is listed twice: */
566   struct tme_m68k_tlb *tme_m68k_rmw_tlbs[2];
567 };
568 
569 /* globals: */
570 extern const tme_uint16_t _tme_m68k_conditions[32];
571 extern const _tme_m68k_xfer_memx _tme_m68k_read_memx[5];
572 extern const _tme_m68k_xfer_memx _tme_m68k_write_memx[5];
573 extern const _tme_m68k_xfer_mem _tme_m68k_read_mem[5];
574 extern const _tme_m68k_xfer_mem _tme_m68k_write_mem[5];
575 extern tme_uint32_t tme_m68k_opcodes_m68000[65536];
576 extern tme_uint32_t tme_m68k_opcodes_m68010[65536];
577 extern tme_uint32_t tme_m68k_opcodes_m68020[65536];
578 extern const _tme_m68k_insn tme_m68k_opcode_insns[];
579 extern const tme_uint8_t _tme_m6888x_fpgen_opmode_bitmap[128 / 8];
580 
581 /* prototypes: */
582 int tme_m68k_new _TME_P((struct tme_m68k *, const char * const *, const void *, char **));
583 void tme_m68k_redispatch _TME_P((struct tme_m68k *));
584 int tme_m68k_go_slow _TME_P((const struct tme_m68k *));
585 void tme_m68k_change_sr _TME_P((struct tme_m68k *, tme_uint16_t));
586 void tme_m68k_external_check _TME_P((struct tme_m68k *, tme_uint32_t));
587 void tme_m68k_tlb_fill _TME_P((struct tme_m68k *, struct tme_m68k_tlb *, unsigned int, tme_uint32_t, unsigned int));
588 void tme_m68k_do_reset _TME_P((struct tme_m68k *));
589 void tme_m68k_callout_unlock _TME_P((struct tme_m68k *ic));
590 void tme_m68k_callout_relock _TME_P((struct tme_m68k *ic));
591 
592 /* exception support: */
593 void tme_m68k_exception _TME_P((struct tme_m68k *, tme_uint32_t));
594 void tme_m68k_exception_process_start _TME_P((struct tme_m68k *, unsigned int));
595 void tme_m68k_exception_process_finish _TME_P((struct tme_m68k *, tme_uint8_t, tme_uint8_t));
596 void tme_m68000_exception_process _TME_P((struct tme_m68k *));
597 void tme_m68020_exception_process _TME_P((struct tme_m68k *));
598 
599 /* rte support: */
600 tme_uint16_t tme_m68k_rte_start _TME_P((struct tme_m68k *));
601 void tme_m68k_rte_finish _TME_P((struct tme_m68k *, tme_uint32_t));
602 
603 /* decoder map support: */
604 void tme_m68k_opcodes_init_m68000 _TME_P((tme_uint32_t *));
605 void tme_m68k_opcodes_init_m68010 _TME_P((tme_uint32_t *));
606 void tme_m68k_opcodes_init_m68020 _TME_P((tme_uint32_t *));
607 
608 /* read/modify/write cycle support: */
609 int tme_m68k_rmw_start _TME_P((struct tme_m68k *, struct tme_m68k_rmw *));
610 void tme_m68k_rmw_finish _TME_P((struct tme_m68k *, struct tme_m68k_rmw *, int));
611 
612 /* group 0 fault support: */
613 void tme_m68k_group0_hook_fast _TME_P((struct tme_m68k *));
614 unsigned int tme_m68k_insn_buffer_empty _TME_P((const struct tme_m68k *, tme_uint8_t *, unsigned int));
615 unsigned int tme_m68k_insn_buffer_fill _TME_P((struct tme_m68k *, const tme_uint8_t *, unsigned int));
616 unsigned int tme_m68k_sequence_empty _TME_P((const struct tme_m68k *, tme_uint8_t *, unsigned int));
617 unsigned int tme_m68k_sequence_fill _TME_P((struct tme_m68k *, const tme_uint8_t *, unsigned int));
618 
619 /* bitfield support: */
620 unsigned int tme_m68k_bitfield_width _TME_P((struct tme_m68k *));
621 tme_uint32_t _tme_m68k_bitfield_read _TME_P((struct tme_m68k *, int));
622 #define tme_m68k_bitfield_read_signed(ic) ((tme_int32_t) _tme_m68k_bitfield_read(ic, TRUE))
623 #define tme_m68k_bitfield_read_unsigned(ic) _tme_m68k_bitfield_read(ic, FALSE)
624 void tme_m68k_bitfield_write_unsigned _TME_P((struct tme_m68k *, tme_uint32_t, int));
625 #define tme_m68k_bitfield_write_signed(ic, v, sf) tme_m68k_bitfield_write_unsigned(ic, (tme_uint32_t) (v), sf)
626 
627 /* FPU support: */
628 int tme_m68k_fpu_new _TME_P((struct tme_m68k *, const char * const *, int *, int *, char **));
629 void tme_m68k_fpu_reset _TME_P((struct tme_m68k *));
630 void tme_m68k_fpu_usage _TME_P((char **));
631 
632 /* verification: */
633 void tme_m68k_verify_hook _TME_P((void));
634 #ifdef _TME_M68K_VERIFY
635 void tme_m68k_verify_init _TME_P((void));
636 void tme_m68k_verify_begin _TME_P((const struct tme_m68k *, const tme_uint8_t *));
637 void tme_m68k_verify_mem_any _TME_P((const struct tme_m68k *,
638 				     unsigned int, tme_uint32_t,
639 				     tme_uint8_t *, int, int));
640 void tme_m68k_verify_end_branch _TME_P((const struct tme_m68k *, tme_uint32_t));
641 void tme_m68k_verify_end _TME_P((const struct tme_m68k *,
642 				 void (*)(struct tme_m68k *, void *, void *)));
643 #else  /* _TME_M68K_VERIFY */
644 #define tme_m68k_verify_init() do { } while (/* CONSTCOND */ 0)
645 #define tme_m68k_verify_begin(ic, s) do { } while (/* CONSTCOND */ 0)
646 #define tme_m68k_verify_mem_any(ic, fc, a, v, c, rw) do { } while (/* CONSTCOND */ 0)
647 #define tme_m68k_verify_end_branch(ic, pc) do { } while (/* CONSTCOND */ 0)
648 #define tme_m68k_verify_end(ic, f) do { } while (/* CONSTCOND */ 0)
649 #define tme_m68k_verify_hook() do { } while (/* CONSTCOND */ 0)
650 #endif /* _TME_M68K_VERIFY */
651 #define tme_m68k_verify_mem8(ic, fc, a, v, rw) tme_m68k_verify_mem_any(ic, fc, a, (tme_uint8_t *) &(v), -sizeof(tme_uint8_t), rw)
652 #define tme_m68k_verify_mem16(ic, fc, a, v, rw) tme_m68k_verify_mem_any(ic, fc, a, (tme_uint8_t *) &(v), -sizeof(tme_uint16_t), rw)
653 #define tme_m68k_verify_mem32(ic, fc, a, v, rw) tme_m68k_verify_mem_any(ic, fc, a, (tme_uint8_t *) &(v), -sizeof(tme_uint32_t), rw)
654 
655 /* instruction functions: */
656 TME_M68K_INSN_DECL(tme_m68k_illegal);
657 TME_M68K_INSN_DECL(tme_m68k_exg);
658 TME_M68K_INSN_DECL(tme_m68k_extw);
659 TME_M68K_INSN_DECL(tme_m68k_extl);
660 TME_M68K_INSN_DECL(tme_m68k_extbl);
661 TME_M68K_INSN_DECL(tme_m68k_lea);
662 TME_M68K_INSN_DECL(tme_m68k_move_from_ccr);
663 TME_M68K_INSN_DECL(tme_m68k_move_from_sr);
664 TME_M68K_INSN_DECL(tme_m68k_move_from_sr0);
665 TME_M68K_INSN_DECL(tme_m68k_swap);
666 TME_M68K_INSN_DECL(tme_m68k_nop);
667 TME_M68K_INSN_DECL(tme_m68k_scc);
668 TME_M68K_INSN_DECL(tme_m68k_dbcc);
669 TME_M68K_INSN_DECL(tme_m68k_bcc);
670 TME_M68K_INSN_DECL(tme_m68k_bccl);
671 TME_M68K_INSN_DECL(tme_m68k_bsr);
672 TME_M68K_INSN_DECL(tme_m68k_bsrl);
673 TME_M68K_INSN_DECL(tme_m68k_pea);
674 TME_M68K_INSN_DECL(tme_m68k_bkpt);
675 TME_M68K_INSN_DECL(tme_m68k_tas);
676 TME_M68K_INSN_DECL(tme_m68k_tas_r);
677 TME_M68K_INSN_DECL(tme_m68k_move_usp);
678 TME_M68K_INSN_DECL(tme_m68k_trap);
679 TME_M68K_INSN_DECL(tme_m68k_trapv);
680 TME_M68K_INSN_DECL(tme_m68k_link);
681 TME_M68K_INSN_DECL(tme_m68k_unlk);
682 TME_M68K_INSN_DECL(tme_m68k_movec);
683 TME_M68K_INSN_DECL(tme_m68k_reset);
684 TME_M68K_INSN_DECL(tme_m68k_rtd);
685 TME_M68K_INSN_DECL(tme_m68k_rtr);
686 TME_M68K_INSN_DECL(tme_m68k_rts);
687 TME_M68K_INSN_DECL(tme_m68k_jsr);
688 TME_M68K_INSN_DECL(tme_m68k_jmp);
689 TME_M68K_INSN_DECL(tme_m68k_rte);
690 TME_M68K_INSN_DECL(tme_m68k_stop);
691 TME_M68K_INSN_DECL(tme_m68k_priv);
692 TME_M68K_INSN_DECL(tme_m68k_cmp2_chk2);
693 TME_M68K_INSN_DECL(tme_m68k_callm);
694 TME_M68K_INSN_DECL(tme_m68k_rtm);
695 TME_M68K_INSN_DECL(tme_m68k_trapcc);
696 TME_M68K_INSN_DECL(tme_m68k_bfchg);
697 TME_M68K_INSN_DECL(tme_m68k_bfclr);
698 TME_M68K_INSN_DECL(tme_m68k_bfexts);
699 TME_M68K_INSN_DECL(tme_m68k_bfextu);
700 TME_M68K_INSN_DECL(tme_m68k_bfffo);
701 TME_M68K_INSN_DECL(tme_m68k_bfins);
702 TME_M68K_INSN_DECL(tme_m68k_bfset);
703 TME_M68K_INSN_DECL(tme_m68k_bftst);
704 TME_M68K_INSN_DECL(tme_m68k_pack);
705 TME_M68K_INSN_DECL(tme_m68k_unpk);
706 TME_M68K_INSN_DECL(tme_m68k_fpgen);
707 TME_M68K_INSN_DECL(tme_m68k_fmovemctl);
708 TME_M68K_INSN_DECL(tme_m68k_fmovem);
709 TME_M68K_INSN_DECL(tme_m68k_fmove_rm);
710 TME_M68K_INSN_DECL(tme_m68k_fdbcc);
711 TME_M68K_INSN_DECL(tme_m68k_ftrapcc);
712 TME_M68K_INSN_DECL(tme_m68k_fscc);
713 TME_M68K_INSN_DECL(tme_m68k_fbcc);
714 TME_M68K_INSN_DECL(tme_m68k_fsave);
715 TME_M68K_INSN_DECL(tme_m68k_frestore);
716 TME_M68K_INSN_DECL(tme_m68k_divl);
717 TME_M68K_INSN_DECL(tme_m68k_mull);
718 
719 #endif /* !_IC_M68K_IMPL_H */
720 
721 /* the automatically-generated header information: */
722 #include <m68k-auto.h>
723