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