|
|
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.