|
|
1.1 root 1: /* m68k-insns.c - m68k instruction functions: */
2:
3: /* $Header: /aquery/home0/fredette/project/tme/TME-CVS-LOCAL/tme/ic/m68k/m68k-insns.c,v 1.6 2003/05/09 17:45:06 fredette Exp $ */
4:
5: /* includes: */
6: #include "m68k-impl.h"
7:
8: _TME_RCSID("$Id: m68k-insns.c,v 1.6 2003/05/09 17:45:06 fredette Exp $");
9:
10: #define TME_M68K_STD_FLAGS \
11: do { \
12: ic->tme_m68k_ireg_ccr = ((ic->tme_m68k_ireg_ccr \
13: & TME_M68K_FLAG_X) \
14: | (res < 0 ? TME_M68K_FLAG_N : 0) \
15: | (res == 0 ? TME_M68K_FLAG_Z : 0)); \
16: } while (/* CONSTCOND */ 0)
17:
18: /* this cannot fault: */
19: TME_M68K_INSN(tme_m68k_exg)
20: {
21: tme_uint32_t tmp;
22: tmp = TME_M68K_INSN_OP0(tme_uint32_t);
23: TME_M68K_INSN_OP0(tme_uint32_t) = TME_M68K_INSN_OP1(tme_uint32_t);
24: TME_M68K_INSN_OP1(tme_uint32_t) = tmp;
25: TME_M68K_INSN_OK;
26: }
27:
28: /* this cannot fault: */
29: TME_M68K_INSN(tme_m68k_extw)
30: {
31: tme_int16_t res;
32: res = TME_EXT_S8_S16((tme_int8_t) TME_M68K_INSN_OP1(tme_int16_t));
33: TME_M68K_INSN_OP1(tme_int16_t) = res;
34: TME_M68K_STD_FLAGS;
35: TME_M68K_INSN_OK;
36: }
37:
38: /* this cannot fault: */
39: TME_M68K_INSN(tme_m68k_extl)
40: {
41: tme_int32_t res;
42: res = TME_EXT_S16_S32((tme_int16_t) TME_M68K_INSN_OP1(tme_int32_t));
43: TME_M68K_INSN_OP1(tme_int32_t) = res;
44: TME_M68K_STD_FLAGS;
45: TME_M68K_INSN_OK;
46: }
47:
48: /* this cannot fault: */
49: TME_M68K_INSN(tme_m68k_extbl)
50: {
51: tme_int32_t res;
52: res = TME_EXT_S8_S32((tme_int8_t) TME_M68K_INSN_OP1(tme_int32_t));
53: TME_M68K_INSN_OP1(tme_int32_t) = res;
54: TME_M68K_STD_FLAGS;
55: TME_M68K_INSN_OK;
56: }
57:
58: /* this cannot fault: */
59: TME_M68K_INSN(tme_m68k_lea)
60: {
61: TME_M68K_INSN_OP0(tme_uint32_t) = TME_M68K_INSN_OP1(tme_uint32_t);
62: TME_M68K_INSN_OK;
63: }
64:
65: /* this cannot fault: */
66: TME_M68K_INSN(tme_m68k_move_from_ccr)
67: {
68: TME_M68K_INSN_OP1(tme_uint16_t) = ic->tme_m68k_ireg_ccr;
69: TME_M68K_INSN_OK;
70: }
71:
72: /* this cannot fault: */
73: TME_M68K_INSN(tme_m68k_move_from_sr)
74: {
75: TME_M68K_INSN_PRIV;
76: TME_M68K_INSN_OP1(tme_uint16_t) = ic->tme_m68k_ireg_sr;
77: TME_M68K_INSN_OK;
78: }
79:
80: /* this cannot fault: */
81: /* this is the 68000 version, which isn't privileged: */
82: TME_M68K_INSN(tme_m68k_move_from_sr0)
83: {
84: TME_M68K_INSN_OP1(tme_uint16_t) = ic->tme_m68k_ireg_sr;
85: TME_M68K_INSN_OK;
86: }
87:
88: /* this cannot fault: */
89: TME_M68K_INSN(tme_m68k_swap)
90: {
91: tme_uint32_t tmp;
92: tme_int32_t res;
93: tmp = TME_M68K_INSN_OP1(tme_uint32_t);
94: tmp = (TME_FIELD_EXTRACTU(tmp, 0, 16) << 16) | TME_FIELD_EXTRACTU(tmp, 16, 16);
95: TME_M68K_INSN_OP1(tme_uint32_t) = tmp;
96: res = (tme_int32_t) tmp;
97: TME_M68K_STD_FLAGS;
98: TME_M68K_INSN_OK;
99: }
100:
101: /* this cannot fault: */
102: TME_M68K_INSN(tme_m68k_nop)
103: {
104: TME_M68K_INSN_OK;
105: }
106:
107: /* this cannot fault: */
108: TME_M68K_INSN(tme_m68k_scc)
109: {
110: TME_M68K_INSN_OP1(tme_uint8_t) =
111: (TME_M68K_COND_TRUE(ic, TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 8, 4))
112: ? 0xff
113: : 0x00);
114: TME_M68K_INSN_OK;
115: }
116:
117: /* this cannot fault: */
118: TME_M68K_INSN(tme_m68k_dbcc)
119: {
120: if (!TME_M68K_COND_TRUE(ic, TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 8, 4))) {
121: if (--TME_M68K_INSN_OP0(tme_int16_t) != -1) {
122: TME_M68K_INSN_BRANCH(ic->tme_m68k_ireg_pc
123: + 2
124: + TME_EXT_S16_U32(TME_M68K_INSN_OP1(tme_int16_t)));
125: }
126: }
127: TME_M68K_INSN_OK;
128: }
129:
130: /* this cannot fault: */
131: TME_M68K_INSN(tme_m68k_bcc)
132: {
133: if (TME_M68K_COND_TRUE(ic, TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 8, 4))) {
134: TME_M68K_INSN_BRANCH(ic->tme_m68k_ireg_pc + 2 + TME_M68K_INSN_OP0(tme_uint32_t));
135: }
136: TME_M68K_INSN_OK;
137: }
138:
139: /* this can fault: */
140: TME_M68K_INSN(tme_m68k_bsr)
141: {
142: TME_M68K_INSN_CANFAULT;
143: tme_m68k_push32(ic, ic->tme_m68k_ireg_pc_next);
144: /* while the above push can fault, we don't have to worry about
145: restarting here, because after this point, nothing can fault for
146: the remainder of this instruction (the executor makes no stores
147: on behalf of a bsr): */
148: TME_M68K_INSN_BRANCH(ic->tme_m68k_ireg_pc + 2 + TME_M68K_INSN_OP0(tme_uint32_t));
149: TME_M68K_INSN_OK;
150: }
151:
152: /* this can fault: */
153: TME_M68K_INSN(tme_m68k_pea)
154: {
155: TME_M68K_INSN_CANFAULT;
156: tme_m68k_push32(ic, TME_M68K_INSN_OP1(tme_uint32_t));
157: /* while the above push can fault, we don't have to worry about
158: restarting here, because after this point, nothing can fault for
159: the remainder of this instruction (the executor makes no stores
160: on behalf of a pea): */
161: TME_M68K_INSN_OK;
162: }
163:
164: /* this cannot fault: */
165: TME_M68K_INSN(tme_m68k_bkpt)
166: {
167: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP1_ILL);
168: }
169:
170: /* this cannot fault: */
171: TME_M68K_INSN(tme_m68k_illegal)
172: {
173: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP1_ILL);
174: }
175:
176: /* this can fault: */
177: TME_M68K_INSN(tme_m68k_tas)
178: {
179: struct tme_m68k_tlb *tlb;
180: tme_uint8_t flags;
181: tme_int8_t value;
182:
183: TME_M68K_INSN_CANFAULT;
184:
185: /* start the read/modify/write cycle: */
186: tlb = tme_m68k_rmw_start(ic);
187: if (tlb == NULL)
188: TME_M68K_INSN_OK;
189:
190: /* the read part of the read/modify/write cycle: */
191: tme_m68k_read8(ic, tlb,
192: &ic->_tme_m68k_ea_function_code,
193: &ic->_tme_m68k_ea_address,
194: &ic->tme_m68k_ireg_memx8,
195: TME_M68K_BUS_CYCLE_RMW);
196:
197: /* the modify part of the read/modify/write cycle: */
198: value = ic->tme_m68k_ireg_memx8;
199: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
200: if (value < 0) flags |= TME_M68K_FLAG_N;
201: if (value == 0) flags |= TME_M68K_FLAG_Z;
202: ic->tme_m68k_ireg_ccr = flags;
203: ic->tme_m68k_ireg_memx8 |= 0x80;
204:
205: /* the write part of the read/modify/write cycle: */
206: tme_m68k_write8(ic, tlb,
207: &ic->_tme_m68k_ea_function_code,
208: &ic->_tme_m68k_ea_address,
209: &ic->tme_m68k_ireg_memx8,
210: TME_M68K_BUS_CYCLE_RMW);
211:
212: /* finish the read/modify/write cycle: */
213: tme_m68k_rmw_finish(ic, tlb);
214:
215: TME_M68K_INSN_OK;
216: }
217:
218: /* this cannot fault: */
219: TME_M68K_INSN(tme_m68k_tas_r)
220: {
221: tme_uint8_t flags;
222: tme_int8_t value;
223: value = TME_M68K_INSN_OP1(tme_int8_t);
224: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
225: if (value < 0) flags |= TME_M68K_FLAG_N;
226: if (value == 0) flags |= TME_M68K_FLAG_Z;
227: ic->tme_m68k_ireg_ccr = flags;
228: TME_M68K_INSN_OP1(tme_int8_t) = value | 0x80;
229: TME_M68K_INSN_OK;
230: }
231:
232: /* this cannot fault: */
233: TME_M68K_INSN(tme_m68k_move_usp)
234: {
235: TME_M68K_INSN_PRIV;
236: if (TME_M68K_INSN_OPCODE & TME_BIT(3)) {
237: TME_M68K_INSN_OP1(tme_uint32_t) = ic->tme_m68k_ireg_usp;
238: }
239: else {
240: ic->tme_m68k_ireg_usp = TME_M68K_INSN_OP1(tme_uint32_t);
241: }
242: TME_M68K_INSN_OK;
243: }
244:
245: /* this cannot fault: */
246: TME_M68K_INSN(tme_m68k_trap)
247: {
248: ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
249: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(32 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 4)));
250: }
251:
252: /* this cannot fault: */
253: TME_M68K_INSN(tme_m68k_trapv)
254: {
255: if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_V) {
256: ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
257: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(7));
258: }
259: TME_M68K_INSN_OK;
260: }
261:
262: /* this can fault: */
263: TME_M68K_INSN(tme_m68k_link)
264: {
265: TME_M68K_INSN_CANFAULT;
266: tme_m68k_push32(ic, TME_M68K_INSN_OP1(tme_uint32_t));
267: TME_M68K_INSN_OP1(tme_uint32_t) = ic->tme_m68k_ireg_a7;
268: ic->tme_m68k_ireg_a7 += TME_M68K_INSN_OP0(tme_uint32_t);
269: TME_M68K_INSN_OK;
270: }
271:
272: /* this can fault: */
273: TME_M68K_INSN(tme_m68k_unlk)
274: {
275: TME_M68K_INSN_CANFAULT;
276: ic->tme_m68k_ireg_a7 = TME_M68K_INSN_OP0(tme_uint32_t);
277: tme_m68k_pop32(ic, &TME_M68K_INSN_OP0(tme_uint32_t));
278: TME_M68K_INSN_OK;
279: }
280:
281: /* this cannot fault: */
282: TME_M68K_INSN(tme_m68k_movec)
283: {
284: int ireg;
285: tme_uint32_t *creg;
286: TME_M68K_INSN_PRIV;
287: /* in case we're reading the msp or isp and we're on that stack,
288: this flushes %a7 to that register: */
289: tme_m68k_change_sr(ic, ic->tme_m68k_ireg_sr);
290: ireg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 4);
291: switch (TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 0, 12)) {
292: case 0x000: creg = &ic->tme_m68k_ireg_sfc; break;
293: case 0x001: creg = &ic->tme_m68k_ireg_dfc; break;
294: case 0x800: creg = &ic->tme_m68k_ireg_usp; break;
295: case 0x801: creg = &ic->tme_m68k_ireg_vbr; break;
296: default: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP1_ILL); creg = NULL;
297: }
298: if (TME_M68K_INSN_OPCODE & TME_BIT(0)) {
299: *creg = ic->tme_m68k_ireg_uint32(ireg);
300: }
301: else {
302: ic->tme_m68k_ireg_uint32(ireg) = *creg;
303: }
304: /* in case we're writing the msp or isp and we're on that stack,
305: this flushes that register to %a7: */
306: tme_m68k_change_sr(ic, ic->tme_m68k_ireg_sr);
307: TME_M68K_INSN_OK;
308: }
309:
310: /* this cannot fault: */
311: TME_M68K_INSN(tme_m68k_reset)
312: {
313: TME_M68K_INSN_PRIV;
314: abort();
315: }
316:
317: /* this can fault: */
318: TME_M68K_INSN(tme_m68k_rtd)
319: {
320: TME_M68K_INSN_CANFAULT;
321: tme_m68k_pop32(ic, &ic->tme_m68k_ireg_memx32);
322: /* while the above pop can fault, we don't have to worry about
323: restarting here, because after this point, nothing can fault for
324: the remainder of this instruction (the executor makes no stores
325: on behalf of an rtd): */
326: ic->tme_m68k_ireg_a7 += TME_M68K_INSN_OP0(tme_uint32_t);
327: TME_M68K_INSN_BRANCH(ic->tme_m68k_ireg_memx32);
328: TME_M68K_INSN_OK;
329: }
330:
331: /* this can fault: */
332: TME_M68K_INSN(tme_m68k_rtr)
333: {
334: TME_M68K_INSN_CANFAULT;
335: tme_m68k_pop16(ic, &ic->tme_m68k_ireg_memx16);
336: if (!TME_M68K_SEQUENCE_RESTARTING) {
337: ic->tme_m68k_ireg_ccr = ic->tme_m68k_ireg_memx8 & TME_M68K_FLAG_CCR;
338: }
339: tme_m68k_pop32(ic, &ic->tme_m68k_ireg_memx32);
340: /* while the above pop can fault, we don't have to worry about
341: restarting here, because after this point, nothing can fault for
342: the remainder of this instruction (the executor makes no stores
343: on behalf of an rtr): */
344: TME_M68K_INSN_BRANCH(ic->tme_m68k_ireg_memx32);
345: TME_M68K_INSN_OK;
346: }
347:
348: /* this can fault: */
349: TME_M68K_INSN(tme_m68k_rts)
350: {
351: TME_M68K_INSN_CANFAULT;
352: tme_m68k_pop32(ic, &ic->tme_m68k_ireg_memx32);
353: TME_M68K_INSN_BRANCH(ic->tme_m68k_ireg_memx32);
354: TME_M68K_INSN_OK;
355: }
356:
357: /* this can fault: */
358: TME_M68K_INSN(tme_m68k_jsr)
359: {
360: TME_M68K_INSN_CANFAULT;
361: tme_m68k_push32(ic, ic->tme_m68k_ireg_pc_next);
362: TME_M68K_INSN_BRANCH(ic->_tme_m68k_ea_address);
363: TME_M68K_INSN_OK;
364: }
365:
366: /* this cannot fault: */
367: TME_M68K_INSN(tme_m68k_jmp)
368: {
369: TME_M68K_INSN_BRANCH(ic->_tme_m68k_ea_address);
370: TME_M68K_INSN_OK;
371: }
372:
373: /* this cannot fault: */
374: TME_M68K_INSN(tme_m68k_rte)
375: {
376: TME_M68K_INSN_PRIV;
377: ic->_tme_m68k_mode = TME_M68K_MODE_RTE;
378: TME_M68K_SEQUENCE_START;
379: tme_m68k_redispatch(ic);
380: }
381:
382: /* this cannot fault: */
383: TME_M68K_INSN(tme_m68k_stop)
384: {
385: TME_M68K_INSN_PRIV;
386: ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
387: ic->tme_m68k_ireg_sr = TME_M68K_INSN_SPECOP;
388: ic->_tme_m68k_mode = TME_M68K_MODE_STOP;
389: TME_M68K_SEQUENCE_START;
390: tme_m68k_redispatch(ic);
391: }
392:
393: /* this cannot fault: */
394: TME_M68K_INSN(tme_m68k_priv)
395: {
396: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP1_PRIV);
397: }
398:
399: /* this can fault: */
400: TME_M68K_INSN(tme_m68k_cmp2_chk2)
401: {
402: tme_uint32_t ireg;
403: unsigned int size_bytes, size_name, size_ireg;
404: tme_uint32_t uvalue, ulower, uupper;
405: tme_int32_t value, lower, upper;
406:
407: TME_M68K_INSN_CANFAULT;
408:
409: /* get the register to check and the operand size: */
410: ireg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 4);
411: size_bytes = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 2);
412: size_ireg = 2 - size_bytes;
413: size_name = TME_M68K_SIZE_8 + size_bytes;
414: size_bytes = 1 << size_bytes;
415:
416: /* read in the two bounds: */
417: (*_tme_m68k_read_mem[size_name])(ic, TME_M68K_IREG_MEMX32 << size_ireg);
418: if (!TME_M68K_SEQUENCE_RESTARTING) {
419: ic->_tme_m68k_ea_address += size_bytes;
420: }
421: (*_tme_m68k_read_mem[size_name])(ic, TME_M68K_IREG_MEMY32 << size_ireg);
422:
423: /* if we have an address register, sign-extend the bounds to 32
424: bits: */
425: if (ireg >= TME_M68K_IREG_A0) {
426: if (size_name == TME_M68K_SIZE_8) {
427: ic->tme_m68k_ireg_int32(TME_M68K_IREG_MEMX32) = TME_EXT_S8_S32(ic->tme_m68k_ireg_int8(TME_M68K_IREG_MEMX8));
428: ic->tme_m68k_ireg_int32(TME_M68K_IREG_MEMY32) = TME_EXT_S8_S32(ic->tme_m68k_ireg_int8(TME_M68K_IREG_MEMY8));
429: }
430: else if (size_name == TME_M68K_SIZE_16) {
431: ic->tme_m68k_ireg_int32(TME_M68K_IREG_MEMX32) = TME_EXT_S16_S32(ic->tme_m68k_ireg_int16(TME_M68K_IREG_MEMX16));
432: ic->tme_m68k_ireg_int32(TME_M68K_IREG_MEMY32) = TME_EXT_S16_S32(ic->tme_m68k_ireg_int16(TME_M68K_IREG_MEMY16));
433: }
434: size_bytes = sizeof(tme_uint32_t);
435: size_name = TME_M68K_SIZE_32;
436: }
437:
438: /* get the values to check: */
439: switch (size_name) {
440: case TME_M68K_SIZE_8:
441: uvalue = ic->tme_m68k_ireg_uint8(ireg);
442: ulower = ic->tme_m68k_ireg_uint8(TME_M68K_IREG_MEMX8);
443: uupper = ic->tme_m68k_ireg_uint8(TME_M68K_IREG_MEMY8);
444: value = ic->tme_m68k_ireg_int8(ireg);
445: lower = ic->tme_m68k_ireg_int8(TME_M68K_IREG_MEMX8);
446: upper = ic->tme_m68k_ireg_int8(TME_M68K_IREG_MEMY8);
447: break;
448: case TME_M68K_SIZE_16:
449: uvalue = ic->tme_m68k_ireg_uint16(ireg);
450: ulower = ic->tme_m68k_ireg_uint16(TME_M68K_IREG_MEMX16);
451: uupper = ic->tme_m68k_ireg_uint16(TME_M68K_IREG_MEMY16);
452: value = ic->tme_m68k_ireg_int16(ireg);
453: lower = ic->tme_m68k_ireg_int16(TME_M68K_IREG_MEMX16);
454: upper = ic->tme_m68k_ireg_int16(TME_M68K_IREG_MEMY16);
455: break;
456: case TME_M68K_SIZE_32:
457: uvalue = ic->tme_m68k_ireg_uint32(ireg);
458: ulower = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_MEMX32);
459: uupper = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_MEMY32);
460: value = ic->tme_m68k_ireg_int32(ireg);
461: lower = ic->tme_m68k_ireg_int32(TME_M68K_IREG_MEMX32);
462: upper = ic->tme_m68k_ireg_int32(TME_M68K_IREG_MEMY32);
463: break;
464: default: abort();
465: }
466:
467: /* do the comparison. if the value is out-of-bounds and this is
468: a chk2 instruction, trap: */
469: ic->tme_m68k_ireg_ccr = (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
470: if (uvalue == ulower
471: || uvalue == uupper) {
472: ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z;
473: }
474: else if ((ulower > uupper)
475: /* signed comparison: */
476: ? (value < lower || value > upper)
477: /* unsigned comparison: */
478: : (uvalue < ulower || uvalue > uupper)) {
479: ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_C;
480: if (TME_M68K_INSN_OPCODE & TME_BIT(11)) {
481: ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
482: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(6));
483: }
484: }
485:
486: TME_M68K_INSN_OK;
487: }
488:
489: TME_M68K_INSN(tme_m68k_callm)
490: {
491: /* TBD */
492: abort();
493: }
494:
495: TME_M68K_INSN(tme_m68k_rtm)
496: {
497: /* TBD */
498: abort();
499: }
500:
501: /* this cannot fault: */
502: TME_M68K_INSN(tme_m68k_trapcc)
503: {
504: if (TME_M68K_COND_TRUE(ic, TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 8, 4))) {
505: ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
506: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(7));
507: }
508: TME_M68K_INSN_OK;
509: }
510:
511: /* the bitfield helper functions handle faults: */
512: TME_M68K_INSN(tme_m68k_bfchg)
513: {
514: tme_uint32_t bf_value;
515: bf_value = tme_m68k_bitfield_read_unsigned(ic);
516: tme_m68k_bitfield_write_unsigned(ic, ~bf_value, FALSE);
517: TME_M68K_INSN_OK;
518: }
519:
520: /* the bitfield helper functions handle faults: */
521: TME_M68K_INSN(tme_m68k_bfclr)
522: {
523: (void) tme_m68k_bitfield_read_unsigned(ic);
524: tme_m68k_bitfield_write_unsigned(ic, 0, FALSE);
525: TME_M68K_INSN_OK;
526: }
527:
528: /* the bitfield helper functions handle faults: */
529: TME_M68K_INSN(tme_m68k_bfexts)
530: {
531: tme_int32_t bf_value;
532: bf_value = tme_m68k_bitfield_read_signed(ic);
533: ic->tme_m68k_ireg_int32(TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 3))
534: = bf_value;
535: TME_M68K_INSN_OK;
536: }
537:
538: /* the bitfield helper functions handle faults: */
539: TME_M68K_INSN(tme_m68k_bfextu)
540: {
541: tme_uint32_t bf_value;
542: bf_value = tme_m68k_bitfield_read_unsigned(ic);
543: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 3))
544: = bf_value;
545: TME_M68K_INSN_OK;
546: }
547:
548: /* the bitfield helper functions handle faults: */
549: TME_M68K_INSN(tme_m68k_bfffo)
550: {
551: tme_int16_t specop;
552: tme_int32_t bf_offset;
553: unsigned int bf_width;
554: tme_uint32_t bf_value;
555:
556: /* get the bitfield offset from a data register or as an immediate: */
557: specop = TME_M68K_INSN_SPECOP;
558: bf_offset = ((specop & TME_BIT(11))
559: ? ic->tme_m68k_ireg_int32(TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specop, 6, 3))
560: : (tme_int32_t) TME_FIELD_EXTRACTU(specop, 6, 5));
561:
562: /* get the bitfield width: */
563: bf_width = tme_m68k_bitfield_width(ic);
564:
565: /* get the bitfield value: */
566: bf_value = tme_m68k_bitfield_read_unsigned(ic);
567:
568: /* set the result: */
569: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specop, 12, 3))
570: = bf_offset + bf_width - ffs((int) bf_value);
571:
572: TME_M68K_INSN_OK;
573: }
574:
575: /* the bitfield helper functions handle faults: */
576: TME_M68K_INSN(tme_m68k_bfins)
577: {
578: tme_m68k_bitfield_write_unsigned(ic,
579: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_D0
580: + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 3)),
581: TRUE);
582: TME_M68K_INSN_OK;
583: }
584:
585: /* the bitfield helper functions handle faults: */
586: TME_M68K_INSN(tme_m68k_bfset)
587: {
588: (void) tme_m68k_bitfield_read_unsigned(ic);
589: tme_m68k_bitfield_write_unsigned(ic, 0xffffffff, FALSE);
590: TME_M68K_INSN_OK;
591: }
592:
593: /* the bitfield helper functions handle faults: */
594: TME_M68K_INSN(tme_m68k_bftst)
595: {
596: (void) tme_m68k_bitfield_read_unsigned(ic);
597: TME_M68K_INSN_OK;
598: }
599:
600: /* this can fault: */
601: TME_M68K_INSN(tme_m68k_pack)
602: {
603: int ireg_x, ireg_y;
604: tme_uint16_t value;
605:
606: TME_M68K_INSN_CANFAULT;
607:
608: /* get the two registers: */
609: ireg_x = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
610: ireg_y = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
611:
612: /* if this is a memory pack: */
613: if (TME_M68K_INSN_OPCODE & TME_BIT(3)) {
614: ireg_x += TME_M68K_IREG_A0;
615: ireg_y += TME_M68K_IREG_A0;
616:
617: /* do the predecrement read of two bytes: */
618: if (!TME_M68K_SEQUENCE_RESTARTING) {
619: ic->tme_m68k_ireg_uint32(ireg_x) -= sizeof(tme_uint16_t);
620: ic->_tme_m68k_ea_function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
621: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(ireg_x);
622: }
623: tme_m68k_read_memx16(ic);
624:
625: /* get the two bytes and add the extension: */
626: value = ic->tme_m68k_ireg_memx16 + TME_M68K_INSN_SPECOP;
627:
628: /* do the predecrement write of one byte: */
629: if (!TME_M68K_SEQUENCE_RESTARTING) {
630: ic->tme_m68k_ireg_uint32(ireg_y) -= sizeof(tme_uint8_t);
631: ic->_tme_m68k_ea_function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
632: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(ireg_y);
633: ic->tme_m68k_ireg_memx8 = (tme_uint8_t) ((value & 0x0f) | (value >> 4));
634: }
635: tme_m68k_write_memx8(ic);
636: }
637:
638: /* if this is a register pack: */
639: else {
640: ireg_x += TME_M68K_IREG_D0;
641: ireg_y += TME_M68K_IREG_D0;
642: value = ic->tme_m68k_ireg_uint16(ireg_x << 1) + TME_M68K_INSN_SPECOP;
643: ic->tme_m68k_ireg_uint8(ireg_y << 2) = (tme_uint8_t) ((value & 0x0f) | (value >> 4));
644: }
645:
646: TME_M68K_INSN_OK;
647: }
648:
649: /* this can fault: */
650: TME_M68K_INSN(tme_m68k_unpk)
651: {
652: int ireg_x, ireg_y;
653: tme_uint16_t value;
654:
655: TME_M68K_INSN_CANFAULT;
656:
657: /* get the two registers: */
658: ireg_x = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
659: ireg_y = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
660:
661: /* if this is a memory pack: */
662: if (TME_M68K_INSN_OPCODE & TME_BIT(3)) {
663: ireg_x += TME_M68K_IREG_A0;
664: ireg_y += TME_M68K_IREG_A0;
665:
666: /* do the predecrement read of one byte: */
667: if (!TME_M68K_SEQUENCE_RESTARTING) {
668: ic->tme_m68k_ireg_uint32(ireg_x) -= sizeof(tme_uint8_t);
669: ic->_tme_m68k_ea_function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
670: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(ireg_x);
671: }
672: tme_m68k_read_memx8(ic);
673:
674: /* unpack the byte and add the extension: */
675: value = ic->tme_m68k_ireg_memx8;
676: value = ((value & 0x0f) | ((value & 0xf0) << 4)) + TME_M68K_INSN_SPECOP;
677:
678: /* do the predecrement write of two bytes: */
679: if (!TME_M68K_SEQUENCE_RESTARTING) {
680: ic->tme_m68k_ireg_uint32(ireg_y) -= sizeof(tme_uint16_t);
681: ic->_tme_m68k_ea_function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
682: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(ireg_y);
683: ic->tme_m68k_ireg_memx16 = value;
684: }
685: tme_m68k_write_memx16(ic);
686: }
687:
688: /* if this is a register pack: */
689: else {
690: ireg_x += TME_M68K_IREG_D0;
691: ireg_y += TME_M68K_IREG_D0;
692: value = ic->tme_m68k_ireg_uint8(ireg_x << 2);
693: value = ((value & 0x0f) | ((value & 0xf0) << 4)) + TME_M68K_INSN_SPECOP;
694: ic->tme_m68k_ireg_uint16(ireg_y << 1) = value;
695: }
696:
697: TME_M68K_INSN_OK;
698: }
699:
700: #include "m68k-bus-auto.c"
701:
702: #include "m68k-insns-auto.c"
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.