|
|
1.1 root 1: /* automatically generated by m68k-insns-auto.sh, do not edit! */ 1.1.1.3 ! root 2: _TME_RCSID("$Id: m68k-insns-auto.sh,v 1.23 2005/03/10 13:26:23 fredette Exp $"); 1.1 root 3: 4: #include "m68k-impl.h" 5: 6: 7: /* this does a 8-bit "add SRC, DST": */ 8: TME_M68K_INSN(tme_m68k_add8) 9: { 10: tme_uint8_t res, op0, op1; 11: tme_uint8_t flags; 12: 13: /* load the operand(s): */ 14: op0 = *((tme_uint8_t *) _op0); 15: op1 = *((tme_uint8_t *) _op1); 16: 17: /* perform the operation: */ 18: res = op1 + op0; 19: 20: /* store the result: */ 21: *((tme_uint8_t *) _op1) = res; 22: 23: /* set the flags: */ 24: flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 25: if (res == 0) flags |= TME_M68K_FLAG_Z; 26: flags |= ((tme_uint8_t) (((op0 ^ op1 ^ 0xff) & (op1 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V; 27: if (op0 > (op1 ^ 0xff)) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X; 28: ic->tme_m68k_ireg_ccr = flags; 29: 30: TME_M68K_INSN_OK; 31: } 32: 33: /* this does a 8-bit "sub SRC, DST": */ 34: TME_M68K_INSN(tme_m68k_sub8) 35: { 36: tme_uint8_t res, op0, op1; 37: tme_uint8_t flags; 38: 39: /* load the operand(s): */ 40: op0 = *((tme_uint8_t *) _op0); 41: op1 = *((tme_uint8_t *) _op1); 42: 43: /* perform the operation: */ 44: res = op1 - op0; 45: 46: /* store the result: */ 47: *((tme_uint8_t *) _op1) = res; 48: 49: /* set the flags: */ 50: flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 51: if (res == 0) flags |= TME_M68K_FLAG_Z; 52: flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V; 53: if (op0 > op1) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X; 54: ic->tme_m68k_ireg_ccr = flags; 55: 56: TME_M68K_INSN_OK; 57: } 58: 59: /* this does a 8-bit "cmp SRC, DST": */ 60: TME_M68K_INSN(tme_m68k_cmp8) 61: { 62: tme_uint8_t res, op0, op1; 63: tme_uint8_t flags; 64: 65: /* load the operand(s): */ 66: op0 = *((tme_uint8_t *) _op0); 67: op1 = *((tme_uint8_t *) _op1); 68: 69: /* perform the operation: */ 70: res = op1 - op0; 71: 72: /* set the flags: */ 73: flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 74: if (res == 0) flags |= TME_M68K_FLAG_Z; 75: flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V; 76: if (op0 > op1) flags |= TME_M68K_FLAG_C; 77: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 78: ic->tme_m68k_ireg_ccr = flags; 79: 80: TME_M68K_INSN_OK; 81: } 82: 83: /* this does a 8-bit "neg DST": */ 84: TME_M68K_INSN(tme_m68k_neg8) 85: { 86: tme_uint8_t res, op1; 87: tme_uint8_t flags; 88: 89: /* load the operand(s): */ 90: op1 = *((tme_uint8_t *) _op1); 91: 92: /* perform the operation: */ 93: res = 0 - op1; 94: 95: /* store the result: */ 96: *((tme_uint8_t *) _op1) = res; 97: 98: /* set the flags: */ 99: flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 100: if (res == 0) flags |= TME_M68K_FLAG_Z; 101: flags |= ((tme_uint8_t) (((op1 ^ 0) & (0 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V; 102: if (op1 > 0) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X; 103: ic->tme_m68k_ireg_ccr = flags; 104: 105: TME_M68K_INSN_OK; 106: } 107: 108: /* this does a 8-bit "or SRC, DST": */ 109: TME_M68K_INSN(tme_m68k_or8) 110: { 111: tme_uint8_t res, op0, op1; 112: tme_uint8_t flags; 113: 114: /* load the operand(s): */ 115: op0 = *((tme_uint8_t *) _op0); 116: op1 = *((tme_uint8_t *) _op1); 117: 118: /* perform the operation: */ 119: res = op1 | op0; 120: 121: /* store the result: */ 122: *((tme_uint8_t *) _op1) = res; 123: 124: /* set the flags: */ 125: flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 126: if (res == 0) flags |= TME_M68K_FLAG_Z; 127: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 128: ic->tme_m68k_ireg_ccr = flags; 129: 130: TME_M68K_INSN_OK; 131: } 132: 133: /* this does a 8-bit "and SRC, DST": */ 134: TME_M68K_INSN(tme_m68k_and8) 135: { 136: tme_uint8_t res, op0, op1; 137: tme_uint8_t flags; 138: 139: /* load the operand(s): */ 140: op0 = *((tme_uint8_t *) _op0); 141: op1 = *((tme_uint8_t *) _op1); 142: 143: /* perform the operation: */ 144: res = op1 & op0; 145: 146: /* store the result: */ 147: *((tme_uint8_t *) _op1) = res; 148: 149: /* set the flags: */ 150: flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 151: if (res == 0) flags |= TME_M68K_FLAG_Z; 152: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 153: ic->tme_m68k_ireg_ccr = flags; 154: 155: TME_M68K_INSN_OK; 156: } 157: 158: /* this does a 8-bit "eor SRC, DST": */ 159: TME_M68K_INSN(tme_m68k_eor8) 160: { 161: tme_uint8_t res, op0, op1; 162: tme_uint8_t flags; 163: 164: /* load the operand(s): */ 165: op0 = *((tme_uint8_t *) _op0); 166: op1 = *((tme_uint8_t *) _op1); 167: 168: /* perform the operation: */ 169: res = op1 ^ op0; 170: 171: /* store the result: */ 172: *((tme_uint8_t *) _op1) = res; 173: 174: /* set the flags: */ 175: flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 176: if (res == 0) flags |= TME_M68K_FLAG_Z; 177: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 178: ic->tme_m68k_ireg_ccr = flags; 179: 180: TME_M68K_INSN_OK; 181: } 182: 183: /* this does a 8-bit "not DST": */ 184: TME_M68K_INSN(tme_m68k_not8) 185: { 186: tme_uint8_t res, op1; 187: tme_uint8_t flags; 188: 189: /* load the operand(s): */ 190: op1 = *((tme_uint8_t *) _op1); 191: 192: /* perform the operation: */ 193: res = ~ op1; 194: 195: /* store the result: */ 196: *((tme_uint8_t *) _op1) = res; 197: 198: /* set the flags: */ 199: flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 200: if (res == 0) flags |= TME_M68K_FLAG_Z; 201: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 202: ic->tme_m68k_ireg_ccr = flags; 203: 204: TME_M68K_INSN_OK; 205: } 206: 207: /* this does a 8-bit "tst DST": */ 208: TME_M68K_INSN(tme_m68k_tst8) 209: { 210: tme_uint8_t res, op1; 211: tme_uint8_t flags; 212: 213: /* load the operand(s): */ 214: op1 = *((tme_uint8_t *) _op1); 215: 216: /* perform the operation: */ 217: res = op1; 218: 219: /* set the flags: */ 220: flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 221: if (res == 0) flags |= TME_M68K_FLAG_Z; 222: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 223: ic->tme_m68k_ireg_ccr = flags; 224: 225: TME_M68K_INSN_OK; 226: } 227: 228: /* this does a 8-bit "move DST": */ 229: TME_M68K_INSN(tme_m68k_move8) 230: { 231: tme_uint8_t res, op1; 232: tme_uint8_t flags; 233: 234: /* load the operand(s): */ 235: op1 = *((tme_uint8_t *) _op1); 236: 237: /* perform the operation: */ 238: res = op1; 239: 240: /* store the result: */ 241: *((tme_uint8_t *) _op0) = res; 242: 243: /* set the flags: */ 244: flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 245: if (res == 0) flags |= TME_M68K_FLAG_Z; 246: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 247: ic->tme_m68k_ireg_ccr = flags; 248: 249: TME_M68K_INSN_OK; 250: } 251: 252: /* this does a 8-bit "clr DST": */ 253: TME_M68K_INSN(tme_m68k_clr8) 254: { 255: tme_uint8_t res; 256: tme_uint8_t flags; 257: 258: /* load the operand(s): */ 259: 260: /* perform the operation: */ 261: res = 0; 262: 263: /* store the result: */ 264: *((tme_uint8_t *) _op1) = res; 265: 266: /* set the flags: */ 267: flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 268: if (res == 0) flags |= TME_M68K_FLAG_Z; 269: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 270: ic->tme_m68k_ireg_ccr = flags; 271: 272: TME_M68K_INSN_OK; 273: } 274: 275: /* this does a 8-bit "negx DST": */ 276: TME_M68K_INSN(tme_m68k_negx8) 277: { 278: tme_uint8_t res, op1; 279: tme_uint8_t flags; 280: 281: /* load the operand(s): */ 282: op1 = *((tme_uint8_t *) _op1); 283: 284: /* perform the operation: */ 285: res = 0 - op1 - ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1); 286: 287: /* store the result: */ 288: *((tme_uint8_t *) _op1) = res; 289: 290: /* set the flags: */ 291: flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 292: if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z); 293: flags |= ((tme_uint8_t) (((op1 ^ 0) & (0 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V; 294: if (op1 > 0 || (op1 == 0 && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X; 295: ic->tme_m68k_ireg_ccr = flags; 296: 297: TME_M68K_INSN_OK; 298: } 299: 300: /* this does a 8-bit "addx SRC, DST": */ 301: TME_M68K_INSN(tme_m68k_addx8) 302: { 303: tme_uint8_t res, op0, op1; 304: tme_uint8_t flags; 305: 306: /* load the operand(s): */ 307: unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic); 308: int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3); 309: int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3); 310: tme_uint32_t ireg_src_adjust = sizeof(tme_uint8_t) + ((ireg_src + 1) >> 3); 311: tme_uint32_t ireg_dst_adjust = sizeof(tme_uint8_t) + ((ireg_dst + 1) >> 3); 312: tme_uint16_t memory; 313: 314: memory = (TME_M68K_INSN_OPCODE & TME_BIT(3)); 315: if (memory) { 316: TME_M68K_INSN_CANFAULT; 317: if (!TME_M68K_SEQUENCE_RESTARTING) { 318: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) -= ireg_dst_adjust; 319: ic->_tme_m68k_ea_function_code = function_code; 320: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst); 321: } 322: tme_m68k_read_memx8(ic); 323: if (!TME_M68K_SEQUENCE_RESTARTING) { 324: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) -= ireg_src_adjust; 325: ic->_tme_m68k_ea_function_code = function_code; 326: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src); 327: } 328: tme_m68k_read_mem8(ic, TME_M68K_IREG_MEMY8); 329: op1 = ic->tme_m68k_ireg_memx8; 330: op0 = ic->tme_m68k_ireg_memy8; 331: } 332: else { 333: op0 = ic->tme_m68k_ireg_uint8((TME_M68K_IREG_D0 + ireg_src) << 2); 334: op1 = ic->tme_m68k_ireg_uint8((TME_M68K_IREG_D0 + ireg_dst) << 2); 335: } 336: 337: /* perform the operation: */ 338: res = op1 + op0 + ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1); 339: 340: /* store the result: */ 341: if (memory) { 342: if (!TME_M68K_SEQUENCE_RESTARTING) { 343: ic->tme_m68k_ireg_memx8 = res; 344: ic->_tme_m68k_ea_function_code = function_code; 345: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst); 346: } 347: tme_m68k_write_memx8(ic); 348: } 349: else { 350: ic->tme_m68k_ireg_uint8((TME_M68K_IREG_D0 + ireg_dst) << 2) = res; 351: } 352: 353: /* set the flags: */ 354: flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 355: if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z); 356: flags |= ((tme_uint8_t) (((op0 ^ op1 ^ 0xff) & (op1 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V; 357: if (op0 > (op1 ^ 0xff) || (op0 == (op1 ^ 0xff) && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X; 358: ic->tme_m68k_ireg_ccr = flags; 359: 360: TME_M68K_INSN_OK; 361: } 362: 363: /* this does a 8-bit "subx SRC, DST": */ 364: TME_M68K_INSN(tme_m68k_subx8) 365: { 366: tme_uint8_t res, op0, op1; 367: tme_uint8_t flags; 368: 369: /* load the operand(s): */ 370: unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic); 371: int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3); 372: int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3); 373: tme_uint32_t ireg_src_adjust = sizeof(tme_uint8_t) + ((ireg_src + 1) >> 3); 374: tme_uint32_t ireg_dst_adjust = sizeof(tme_uint8_t) + ((ireg_dst + 1) >> 3); 375: tme_uint16_t memory; 376: 377: memory = (TME_M68K_INSN_OPCODE & TME_BIT(3)); 378: if (memory) { 379: TME_M68K_INSN_CANFAULT; 380: if (!TME_M68K_SEQUENCE_RESTARTING) { 381: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) -= ireg_dst_adjust; 382: ic->_tme_m68k_ea_function_code = function_code; 383: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst); 384: } 385: tme_m68k_read_memx8(ic); 386: if (!TME_M68K_SEQUENCE_RESTARTING) { 387: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) -= ireg_src_adjust; 388: ic->_tme_m68k_ea_function_code = function_code; 389: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src); 390: } 391: tme_m68k_read_mem8(ic, TME_M68K_IREG_MEMY8); 392: op1 = ic->tme_m68k_ireg_memx8; 393: op0 = ic->tme_m68k_ireg_memy8; 394: } 395: else { 396: op0 = ic->tme_m68k_ireg_uint8((TME_M68K_IREG_D0 + ireg_src) << 2); 397: op1 = ic->tme_m68k_ireg_uint8((TME_M68K_IREG_D0 + ireg_dst) << 2); 398: } 399: 400: /* perform the operation: */ 401: res = op1 - op0 - ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1); 402: 403: /* store the result: */ 404: if (memory) { 405: if (!TME_M68K_SEQUENCE_RESTARTING) { 406: ic->tme_m68k_ireg_memx8 = res; 407: ic->_tme_m68k_ea_function_code = function_code; 408: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst); 409: } 410: tme_m68k_write_memx8(ic); 411: } 412: else { 413: ic->tme_m68k_ireg_uint8((TME_M68K_IREG_D0 + ireg_dst) << 2) = res; 414: } 415: 416: /* set the flags: */ 417: flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 418: if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z); 419: flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V; 420: if (op0 > op1 || (op0 == op1 && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X; 421: ic->tme_m68k_ireg_ccr = flags; 422: 423: TME_M68K_INSN_OK; 424: } 425: 426: /* this does a 8-bit "cmpm SRC, DST": */ 427: TME_M68K_INSN(tme_m68k_cmpm8) 428: { 429: tme_uint8_t res, op0, op1; 430: tme_uint8_t flags; 431: 432: /* load the operand(s): */ 433: unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic); 434: int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3); 435: int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3); 436: tme_uint32_t ireg_src_adjust = sizeof(tme_uint8_t) + ((ireg_src + 1) >> 3); 437: tme_uint32_t ireg_dst_adjust = sizeof(tme_uint8_t) + ((ireg_dst + 1) >> 3); 438: 439: TME_M68K_INSN_CANFAULT; 440: 441: if (!TME_M68K_SEQUENCE_RESTARTING) { 442: ic->_tme_m68k_ea_function_code = function_code; 443: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst); 444: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) += ireg_dst_adjust; 445: } 446: tme_m68k_read_memx8(ic); 447: if (!TME_M68K_SEQUENCE_RESTARTING) { 448: ic->_tme_m68k_ea_function_code = function_code; 449: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src); 450: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) += ireg_src_adjust; 451: } 452: tme_m68k_read_mem8(ic, TME_M68K_IREG_MEMY8); 453: op1 = ic->tme_m68k_ireg_memx8; 454: op0 = ic->tme_m68k_ireg_memy8; 455: 456: /* perform the operation: */ 457: res = op1 - op0; 458: 459: /* set the flags: */ 460: flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 461: if (res == 0) flags |= TME_M68K_FLAG_Z; 462: flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V; 463: if (op0 > op1) flags |= TME_M68K_FLAG_C; 464: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 465: ic->tme_m68k_ireg_ccr = flags; 466: 467: TME_M68K_INSN_OK; 468: } 469: 470: /* the btst function on a 8-byte EA: */ 471: TME_M68K_INSN(tme_m68k_btst8) 472: { 473: tme_uint8_t value, bit; 474: bit = _TME_BIT(tme_uint8_t, TME_M68K_INSN_OP0(tme_uint8_t) & (8 - 1)); 475: value = TME_M68K_INSN_OP1(tme_uint8_t); 476: if (value & bit) { 477: ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z; 478: } 479: else { 480: ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z; 481: } 482: TME_M68K_INSN_OK; 483: } 484: 485: /* the bchg function on a 8-byte EA: */ 486: TME_M68K_INSN(tme_m68k_bchg8) 487: { 488: tme_uint8_t value, bit; 489: bit = _TME_BIT(tme_uint8_t, TME_M68K_INSN_OP0(tme_uint8_t) & (8 - 1)); 490: value = TME_M68K_INSN_OP1(tme_uint8_t); 491: if (value & bit) { 492: ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z; 493: } 494: else { 495: ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z; 496: } 497: TME_M68K_INSN_OP1(tme_uint8_t) = value ^ bit; 498: TME_M68K_INSN_OK; 499: } 500: 501: /* the bclr function on a 8-byte EA: */ 502: TME_M68K_INSN(tme_m68k_bclr8) 503: { 504: tme_uint8_t value, bit; 505: bit = _TME_BIT(tme_uint8_t, TME_M68K_INSN_OP0(tme_uint8_t) & (8 - 1)); 506: value = TME_M68K_INSN_OP1(tme_uint8_t); 507: if (value & bit) { 508: ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z; 509: } 510: else { 511: ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z; 512: } 513: TME_M68K_INSN_OP1(tme_uint8_t) = value & ~bit; 514: TME_M68K_INSN_OK; 515: } 516: 517: /* the bset function on a 8-byte EA: */ 518: TME_M68K_INSN(tme_m68k_bset8) 519: { 520: tme_uint8_t value, bit; 521: bit = _TME_BIT(tme_uint8_t, TME_M68K_INSN_OP0(tme_uint8_t) & (8 - 1)); 522: value = TME_M68K_INSN_OP1(tme_uint8_t); 523: if (value & bit) { 524: ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z; 525: } 526: else { 527: ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z; 528: } 529: TME_M68K_INSN_OP1(tme_uint8_t) = value | bit; 530: TME_M68K_INSN_OK; 531: } 532: 533: /* the asl function on a 8-byte EA: */ 534: TME_M68K_INSN(tme_m68k_asl8) 535: { 536: unsigned int count; 1.1.1.2 root 537: tme_uint8_t sign_bits, sign_bits_mask; 1.1 root 538: tme_uint8_t res; 539: tme_uint8_t flags; 540: 541: /* get the count and operand: */ 542: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 543: res = TME_M68K_INSN_OP1(tme_uint8_t); 544: 545: /* generate the X, V, and C flags assuming the count is zero: */ 546: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 547: 548: /* if the count is nonzero, update the result and 549: generate the X, V, and C flags: */ 550: if (count > 0) { 551: 552: /* we need to see how the sign of the result will change during 553: shifting in order to generate V. 554: 555: in general, the idea is to get all of the bits that will ever 1.1.1.2 root 556: appear in the sign position into sign_bits, with a mask in 557: sign_bits_mask. if (sign_bits & sign_bits_mask) is zero or 558: sign_bits_mask, clear V, else set V. 1.1 root 559: 1.1.1.2 root 560: start by loading the operand into sign_bits and setting 561: sign_bits_mask to all-bits-one. 1.1 root 562: 563: if the shift count is exactly 8 - 1, then all of the bits 564: of the operand will appear in the sign position. 565: 566: if the shift count is less than 8 - 1, then some of the 567: less significant bits of the operand will never appear in the 1.1.1.2 root 568: sign position, so we can shift sign_bits_mask to ignore them. 1.1 root 569: 570: if the shift count is greater than 8 - 1, then all of the 571: bits in the operand, plus at least one zero bit, will appear in 572: the sign position. the only way that the sign bit will never 573: change during the shift is if the operand was zero to begin with. 1.1.1.2 root 574: without any changes to sign_bits or sign_bits_mask, the final 575: test will always work, except when sign_bits is all-bits-one. 576: the magic below clears the least-significant bit of sign_bits 577: iff sign_bits is all-bits-one: */ 1.1 root 578: sign_bits = res; 579: if (63 > SHIFTMAX_INT8_T 580: && count > 8) { 581: res = 0; 582: } 583: res <<= (count - 1); 584: flags = (res >> (8 - 1)); 585: flags *= TME_M68K_FLAG_C; 586: flags |= (flags * TME_M68K_FLAG_X); 587: res <<= 1; 1.1.1.2 root 588: sign_bits_mask = (tme_uint8_t) -1; 1.1 root 589: if (count != 8 - 1) { 590: if (count < 8) { 1.1.1.2 root 591: sign_bits_mask <<= ((8 - 1) - count); 1.1 root 592: } 593: else { 1.1.1.2 root 594: sign_bits ^= !(sign_bits + 1); 1.1 root 595: } 596: } 1.1.1.2 root 597: sign_bits &= sign_bits_mask; 598: if (sign_bits != 0 && sign_bits != sign_bits_mask) { 1.1 root 599: flags |= TME_M68K_FLAG_V; 600: } 601: } 602: 603: /* store the result: */ 604: TME_M68K_INSN_OP1(tme_uint8_t) = res; 605: 606: /* generate the N flag. we cast to tme_uint8_t as soon as we 607: know the bit we want is within the range of the type, to try 608: to affect the generated assembly: */ 609: flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 610: 611: /* generate the Z flag: */ 612: if (res == 0) flags |= TME_M68K_FLAG_Z; 613: 614: /* store the flags: */ 615: ic->tme_m68k_ireg_ccr = flags; 616: TME_M68K_INSN_OK; 617: } 618: 619: /* the asr function on a 8-byte EA: */ 620: TME_M68K_INSN(tme_m68k_asr8) 621: { 622: unsigned int count; 623: tme_int8_t res; 624: tme_uint8_t flags; 625: 626: /* get the count and operand: */ 627: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 628: res = TME_M68K_INSN_OP1(tme_int8_t); 629: 630: /* generate the X, V, and C flags assuming the count is zero: */ 631: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 632: 633: /* if the count is nonzero, update the result and 634: generate the X, V, and C flags: */ 635: if (count > 0) { 636: if (63 > SHIFTMAX_INT8_T 637: && count > 8) { 1.1.1.3 ! root 638: res = 0 - (res < 0); 1.1 root 639: } 1.1.1.3 ! root 640: #ifdef SHIFTSIGNED_INT8_T 1.1 root 641: res >>= (count - 1); 1.1.1.3 ! root 642: #else /* !SHIFTSIGNED_INT8_T */ ! 643: for (; --count > 0; ) { ! 644: res = (res & ~((tme_int8_t) 1)) / 2; ! 645: } ! 646: #endif /* !SHIFTSIGNED_INT8_T */ 1.1 root 647: flags = (res & 1); 648: flags *= TME_M68K_FLAG_C; 649: flags |= (flags * TME_M68K_FLAG_X); 1.1.1.3 ! root 650: #ifdef SHIFTSIGNED_INT8_T 1.1 root 651: res >>= 1; 1.1.1.3 ! root 652: #else /* !SHIFTSIGNED_INT8_T */ ! 653: res = (res & ~((tme_int8_t) 1)) / 2; ! 654: #endif /* !SHIFTSIGNED_INT8_T */ 1.1 root 655: } 656: 657: /* store the result: */ 658: TME_M68K_INSN_OP1(tme_int8_t) = res; 659: 660: /* generate the N flag. we cast to tme_uint8_t as soon as we 661: know the bit we want is within the range of the type, to try 662: to affect the generated assembly: */ 663: flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 664: 665: /* generate the Z flag: */ 666: if (res == 0) flags |= TME_M68K_FLAG_Z; 667: 668: /* store the flags: */ 669: ic->tme_m68k_ireg_ccr = flags; 670: TME_M68K_INSN_OK; 671: } 672: 673: /* the lsl function on a 8-byte EA: */ 674: TME_M68K_INSN(tme_m68k_lsl8) 675: { 676: unsigned int count; 677: tme_uint8_t res; 678: tme_uint8_t flags; 679: 680: /* get the count and operand: */ 681: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 682: res = TME_M68K_INSN_OP1(tme_uint8_t); 683: 684: /* generate the X, V, and C flags assuming the count is zero: */ 685: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 686: 687: /* if the count is nonzero, update the result and 688: generate the X, V, and C flags: */ 689: if (count > 0) { 690: if (63 > SHIFTMAX_INT8_T 691: && count > 8) { 692: res = 0; 693: } 694: res <<= (count - 1); 695: flags = (res >> (8 - 1)); 696: flags *= TME_M68K_FLAG_C; 697: flags |= (flags * TME_M68K_FLAG_X); 698: res <<= 1; 699: } 700: 701: /* store the result: */ 702: TME_M68K_INSN_OP1(tme_uint8_t) = res; 703: 704: /* generate the N flag. we cast to tme_uint8_t as soon as we 705: know the bit we want is within the range of the type, to try 706: to affect the generated assembly: */ 707: flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 708: 709: /* generate the Z flag: */ 710: if (res == 0) flags |= TME_M68K_FLAG_Z; 711: 712: /* store the flags: */ 713: ic->tme_m68k_ireg_ccr = flags; 714: TME_M68K_INSN_OK; 715: } 716: 717: /* the lsr function on a 8-byte EA: */ 718: TME_M68K_INSN(tme_m68k_lsr8) 719: { 720: unsigned int count; 721: tme_uint8_t res; 722: tme_uint8_t flags; 723: 724: /* get the count and operand: */ 725: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 726: res = TME_M68K_INSN_OP1(tme_uint8_t); 727: 728: /* generate the X, V, and C flags assuming the count is zero: */ 729: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 730: 731: /* if the count is nonzero, update the result and 732: generate the X, V, and C flags: */ 733: if (count > 0) { 734: if (63 > SHIFTMAX_INT8_T 735: && count > 8) { 736: res = 0; 737: } 738: res >>= (count - 1); 739: flags = (res & 1); 740: flags *= TME_M68K_FLAG_C; 741: flags |= (flags * TME_M68K_FLAG_X); 742: res >>= 1; 743: } 744: 745: /* store the result: */ 746: TME_M68K_INSN_OP1(tme_uint8_t) = res; 747: 748: /* generate the N flag. we cast to tme_uint8_t as soon as we 749: know the bit we want is within the range of the type, to try 750: to affect the generated assembly: */ 751: flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 752: 753: /* generate the Z flag: */ 754: if (res == 0) flags |= TME_M68K_FLAG_Z; 755: 756: /* store the flags: */ 757: ic->tme_m68k_ireg_ccr = flags; 758: TME_M68K_INSN_OK; 759: } 760: 761: /* the rol function on a 8-byte EA: */ 762: TME_M68K_INSN(tme_m68k_rol8) 763: { 764: unsigned int count; 765: tme_uint8_t res; 766: tme_uint8_t flags; 767: 768: /* get the count and operand: */ 769: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 770: res = TME_M68K_INSN_OP1(tme_uint8_t); 771: 772: /* generate the X, V, and C flags assuming the count is zero: */ 773: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 774: 775: /* if the count is nonzero, update the result and 776: generate the X, V, and C flags: */ 777: if (count > 0) { 778: count &= (8 - 1); 779: res = (res << count) | (res >> (8 - count)); 780: flags |= ((res & 1) * TME_M68K_FLAG_C); 781: } 782: 783: /* store the result: */ 784: TME_M68K_INSN_OP1(tme_uint8_t) = res; 785: 786: /* generate the N flag. we cast to tme_uint8_t as soon as we 787: know the bit we want is within the range of the type, to try 788: to affect the generated assembly: */ 789: flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 790: 791: /* generate the Z flag: */ 792: if (res == 0) flags |= TME_M68K_FLAG_Z; 793: 794: /* store the flags: */ 795: ic->tme_m68k_ireg_ccr = flags; 796: TME_M68K_INSN_OK; 797: } 798: 799: /* the ror function on a 8-byte EA: */ 800: TME_M68K_INSN(tme_m68k_ror8) 801: { 802: unsigned int count; 803: tme_uint8_t res; 804: tme_uint8_t flags; 805: 806: /* get the count and operand: */ 807: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 808: res = TME_M68K_INSN_OP1(tme_uint8_t); 809: 810: /* generate the X, V, and C flags assuming the count is zero: */ 811: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 812: 813: /* if the count is nonzero, update the result and 814: generate the X, V, and C flags: */ 815: if (count > 0) { 816: count &= (8 - 1); 817: res = (res << (8 - count)) | (res >> count); 818: flags |= ((res >> (8 - 1)) * TME_M68K_FLAG_C); 819: } 820: 821: /* store the result: */ 822: TME_M68K_INSN_OP1(tme_uint8_t) = res; 823: 824: /* generate the N flag. we cast to tme_uint8_t as soon as we 825: know the bit we want is within the range of the type, to try 826: to affect the generated assembly: */ 827: flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 828: 829: /* generate the Z flag: */ 830: if (res == 0) flags |= TME_M68K_FLAG_Z; 831: 832: /* store the flags: */ 833: ic->tme_m68k_ireg_ccr = flags; 834: TME_M68K_INSN_OK; 835: } 836: 837: /* the roxl function on a 8-byte EA: */ 838: TME_M68K_INSN(tme_m68k_roxl8) 839: { 840: unsigned int count; 841: tme_uint8_t xbit; 842: tme_uint8_t res; 843: tme_uint8_t flags; 844: 845: /* get the count and operand: */ 846: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 847: res = TME_M68K_INSN_OP1(tme_uint8_t); 848: 849: /* generate the X, V, and C flags assuming the count is zero: */ 850: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 851: xbit = (flags / TME_M68K_FLAG_X); 852: flags |= (xbit * TME_M68K_FLAG_C); 853: 854: /* if the count is nonzero, update the result and 855: generate the X, V, and C flags: */ 856: if (count > 0) { 857: count %= (8 + 1); 858: flags = xbit; 859: if (count > 0) { 860: flags = (res >> (8 - count)) & 1; 861: if (8 > SHIFTMAX_INT8_T 862: && count == 8) { 863: res = 0 | (xbit << (8 - 1)) | (res >> ((8 + 1) - 8)); 864: } 865: else if (8 > SHIFTMAX_INT8_T 866: && count == 1) { 867: res = (res << 1) | (xbit << (1 - 1)) | 0; 868: } 869: else { 870: res = (res << count) | (xbit << (count - 1)) | (res >> ((8 + 1) - count)); 871: } 872: } 873: flags *= TME_M68K_FLAG_C; 874: flags |= (flags * TME_M68K_FLAG_X); 875: } 876: 877: /* store the result: */ 878: TME_M68K_INSN_OP1(tme_uint8_t) = res; 879: 880: /* generate the N flag. we cast to tme_uint8_t as soon as we 881: know the bit we want is within the range of the type, to try 882: to affect the generated assembly: */ 883: flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 884: 885: /* generate the Z flag: */ 886: if (res == 0) flags |= TME_M68K_FLAG_Z; 887: 888: /* store the flags: */ 889: ic->tme_m68k_ireg_ccr = flags; 890: TME_M68K_INSN_OK; 891: } 892: 893: /* the roxr function on a 8-byte EA: */ 894: TME_M68K_INSN(tme_m68k_roxr8) 895: { 896: unsigned int count; 897: tme_uint8_t xbit; 898: tme_uint8_t res; 899: tme_uint8_t flags; 900: 901: /* get the count and operand: */ 902: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 903: res = TME_M68K_INSN_OP1(tme_uint8_t); 904: 905: /* generate the X, V, and C flags assuming the count is zero: */ 906: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 907: xbit = (flags / TME_M68K_FLAG_X); 908: flags |= (xbit * TME_M68K_FLAG_C); 909: 910: /* if the count is nonzero, update the result and 911: generate the X, V, and C flags: */ 912: if (count > 0) { 913: count %= (8 + 1); 914: flags = xbit; 915: if (count > 0) { 916: flags = (res >> (count - 1)) & 1; 917: if (8 > SHIFTMAX_INT8_T 918: && count == 8) { 919: res = (res << ((8 + 1) - 8)) | (xbit << (8 - 8)) | 0; 920: } 921: else if (8 > SHIFTMAX_INT8_T 922: && count == 1) { 923: res = 0 | (xbit << (8 - 1)) | (res >> 1); 924: } 925: else { 926: res = (res << ((8 + 1) - count)) | (xbit << (8 - count)) | (res >> count); 927: } 928: } 929: flags *= TME_M68K_FLAG_C; 930: flags |= (flags * TME_M68K_FLAG_X); 931: } 932: 933: /* store the result: */ 934: TME_M68K_INSN_OP1(tme_uint8_t) = res; 935: 936: /* generate the N flag. we cast to tme_uint8_t as soon as we 937: know the bit we want is within the range of the type, to try 938: to affect the generated assembly: */ 939: flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N; 940: 941: /* generate the Z flag: */ 942: if (res == 0) flags |= TME_M68K_FLAG_Z; 943: 944: /* store the flags: */ 945: ic->tme_m68k_ireg_ccr = flags; 946: TME_M68K_INSN_OK; 947: } 948: 949: /* cas8: */ 950: TME_M68K_INSN(tme_m68k_cas8) 951: { 952: struct tme_m68k_tlb *tlb; 953: int ireg_dc, ireg_du; 954: int do_write; 955: tme_uint16_t specopx = ic->_tme_m68k_insn_specop; 956: 957: /* start the read/modify/write cycle: */ 958: tlb = tme_m68k_rmw_start(ic); 959: if (tlb == NULL) { 960: TME_M68K_INSN_OK; 961: } 962: 963: /* read: */ 964: tme_m68k_read8(ic, tlb, 965: &ic->_tme_m68k_ea_function_code, 966: &ic->_tme_m68k_ea_address, 967: &ic->tme_m68k_ireg_memx8, 968: TME_M68K_BUS_CYCLE_RMW); 969: 970: /* modify: */ 971: ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 0, 3); 972: tme_m68k_cmp8(ic, &ic->tme_m68k_ireg_uint8(ireg_dc), &ic->tme_m68k_ireg_memx8); 973: 974: /* write: */ 975: if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) { 976: ireg_du = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 6, 3); 977: ic->tme_m68k_ireg_memx8 = ic->tme_m68k_ireg_uint8(ireg_du); 978: tme_m68k_write8(ic, tlb, 979: &ic->_tme_m68k_ea_function_code, 980: &ic->_tme_m68k_ea_address, 981: &ic->tme_m68k_ireg_memx8, 982: TME_M68K_BUS_CYCLE_RMW); 983: } 984: else { 985: /* XXX the 68040 always does a write to finish its cycle: */ 986: do_write = FALSE; 987: ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 0, 3); 988: if (do_write) { 989: tme_m68k_write8(ic, tlb, 990: &ic->_tme_m68k_ea_function_code, 991: &ic->_tme_m68k_ea_address, 992: &ic->tme_m68k_ireg_memx8, 993: TME_M68K_BUS_CYCLE_RMW); 994: do_write = FALSE; 995: } 996: ic->tme_m68k_ireg_uint8(ireg_dc) = ic->tme_m68k_ireg_memx8; 997: } 998: 999: /* finish the read/modify/write cycle: */ 1000: tme_m68k_rmw_finish(ic, tlb); 1001: 1002: TME_M68K_INSN_OK; 1003: } 1004: 1005: /* moves8: */ 1006: TME_M68K_INSN(tme_m68k_moves8) 1007: { 1008: int ireg; 1.1.1.3 ! root 1009: unsigned int ea_reg; ! 1010: unsigned int increment; ! 1011: TME_M68K_INSN_PRIV; ! 1012: TME_M68K_INSN_CANFAULT; 1.1 root 1013: ireg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 4); 1.1.1.3 ! root 1014: ! 1015: /* we have to handle postincrement and predecrement ourselves: */ ! 1016: if (!TME_M68K_SEQUENCE_RESTARTING) { ! 1017: ea_reg = TME_M68K_IREG_A0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3); ! 1018: increment = TME_M68K_SIZE_8; ! 1019: if (increment == TME_M68K_SIZE_8 && ea_reg == TME_M68K_IREG_A7) { ! 1020: increment = TME_M68K_SIZE_16; ! 1021: } ! 1022: switch (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 3, 3)) { ! 1023: case 3: ic->tme_m68k_ireg_uint32(ea_reg) += increment; break; ! 1024: case 4: ic->_tme_m68k_ea_address = (ic->tme_m68k_ireg_uint32(ea_reg) -= increment); break; ! 1025: default: break; ! 1026: } ! 1027: } ! 1028: 1.1 root 1029: if (TME_M68K_INSN_SPECOP & TME_BIT(11)) { 1.1.1.3 ! root 1030: if (!TME_M68K_SEQUENCE_RESTARTING) { ! 1031: ic->tme_m68k_ireg_memx8 = ic->tme_m68k_ireg_uint8(ireg << 2); ! 1032: ic->_tme_m68k_ea_function_code = ic->tme_m68k_ireg_dfc; ! 1033: } ! 1034: tme_m68k_write_memx8(ic); 1.1 root 1035: } 1036: else { 1.1.1.3 ! root 1037: if (!TME_M68K_SEQUENCE_RESTARTING) { ! 1038: ic->_tme_m68k_ea_function_code = ic->tme_m68k_ireg_sfc; ! 1039: } ! 1040: tme_m68k_read_memx8(ic); 1.1 root 1041: if (ireg >= TME_M68K_IREG_A0) { 1042: ic->tme_m68k_ireg_uint32(ireg) = 1043: TME_EXT_S8_U32((tme_int8_t) ic->tme_m68k_ireg_memx8); 1044: } 1045: else 1046: ic->tme_m68k_ireg_uint8(ireg << 2) = ic->tme_m68k_ireg_memx8; 1047: } 1048: TME_M68K_INSN_OK; 1049: } 1050: 1051: /* this does a 16-bit "add SRC, DST": */ 1052: TME_M68K_INSN(tme_m68k_add16) 1053: { 1054: tme_uint16_t res, op0, op1; 1055: tme_uint8_t flags; 1056: 1057: /* load the operand(s): */ 1058: op0 = *((tme_uint16_t *) _op0); 1059: op1 = *((tme_uint16_t *) _op1); 1060: 1061: /* perform the operation: */ 1062: res = op1 + op0; 1063: 1064: /* store the result: */ 1065: *((tme_uint16_t *) _op1) = res; 1066: 1067: /* set the flags: */ 1068: flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1069: if (res == 0) flags |= TME_M68K_FLAG_Z; 1070: flags |= ((tme_uint8_t) (((op0 ^ op1 ^ 0xffff) & (op1 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V; 1071: if (op0 > (op1 ^ 0xffff)) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X; 1072: ic->tme_m68k_ireg_ccr = flags; 1073: 1074: TME_M68K_INSN_OK; 1075: } 1076: 1077: /* this does a 16-bit "sub SRC, DST": */ 1078: TME_M68K_INSN(tme_m68k_sub16) 1079: { 1080: tme_uint16_t res, op0, op1; 1081: tme_uint8_t flags; 1082: 1083: /* load the operand(s): */ 1084: op0 = *((tme_uint16_t *) _op0); 1085: op1 = *((tme_uint16_t *) _op1); 1086: 1087: /* perform the operation: */ 1088: res = op1 - op0; 1089: 1090: /* store the result: */ 1091: *((tme_uint16_t *) _op1) = res; 1092: 1093: /* set the flags: */ 1094: flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1095: if (res == 0) flags |= TME_M68K_FLAG_Z; 1096: flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V; 1097: if (op0 > op1) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X; 1098: ic->tme_m68k_ireg_ccr = flags; 1099: 1100: TME_M68K_INSN_OK; 1101: } 1102: 1103: /* this does a 16-bit "cmp SRC, DST": */ 1104: TME_M68K_INSN(tme_m68k_cmp16) 1105: { 1106: tme_uint16_t res, op0, op1; 1107: tme_uint8_t flags; 1108: 1109: /* load the operand(s): */ 1110: op0 = *((tme_uint16_t *) _op0); 1111: op1 = *((tme_uint16_t *) _op1); 1112: 1113: /* perform the operation: */ 1114: res = op1 - op0; 1115: 1116: /* set the flags: */ 1117: flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1118: if (res == 0) flags |= TME_M68K_FLAG_Z; 1119: flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V; 1120: if (op0 > op1) flags |= TME_M68K_FLAG_C; 1121: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 1122: ic->tme_m68k_ireg_ccr = flags; 1123: 1124: TME_M68K_INSN_OK; 1125: } 1126: 1127: /* this does a 16-bit "neg DST": */ 1128: TME_M68K_INSN(tme_m68k_neg16) 1129: { 1130: tme_uint16_t res, op1; 1131: tme_uint8_t flags; 1132: 1133: /* load the operand(s): */ 1134: op1 = *((tme_uint16_t *) _op1); 1135: 1136: /* perform the operation: */ 1137: res = 0 - op1; 1138: 1139: /* store the result: */ 1140: *((tme_uint16_t *) _op1) = res; 1141: 1142: /* set the flags: */ 1143: flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1144: if (res == 0) flags |= TME_M68K_FLAG_Z; 1145: flags |= ((tme_uint8_t) (((op1 ^ 0) & (0 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V; 1146: if (op1 > 0) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X; 1147: ic->tme_m68k_ireg_ccr = flags; 1148: 1149: TME_M68K_INSN_OK; 1150: } 1151: 1152: /* this does a 16-bit "or SRC, DST": */ 1153: TME_M68K_INSN(tme_m68k_or16) 1154: { 1155: tme_uint16_t res, op0, op1; 1156: tme_uint8_t flags; 1157: 1158: /* load the operand(s): */ 1159: op0 = *((tme_uint16_t *) _op0); 1160: op1 = *((tme_uint16_t *) _op1); 1161: 1162: /* perform the operation: */ 1163: res = op1 | op0; 1164: 1165: /* store the result: */ 1166: *((tme_uint16_t *) _op1) = res; 1167: 1168: /* set the flags: */ 1169: flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1170: if (res == 0) flags |= TME_M68K_FLAG_Z; 1171: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 1172: ic->tme_m68k_ireg_ccr = flags; 1173: 1174: TME_M68K_INSN_OK; 1175: } 1176: 1177: /* this does a 16-bit "and SRC, DST": */ 1178: TME_M68K_INSN(tme_m68k_and16) 1179: { 1180: tme_uint16_t res, op0, op1; 1181: tme_uint8_t flags; 1182: 1183: /* load the operand(s): */ 1184: op0 = *((tme_uint16_t *) _op0); 1185: op1 = *((tme_uint16_t *) _op1); 1186: 1187: /* perform the operation: */ 1188: res = op1 & op0; 1189: 1190: /* store the result: */ 1191: *((tme_uint16_t *) _op1) = res; 1192: 1193: /* set the flags: */ 1194: flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1195: if (res == 0) flags |= TME_M68K_FLAG_Z; 1196: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 1197: ic->tme_m68k_ireg_ccr = flags; 1198: 1199: TME_M68K_INSN_OK; 1200: } 1201: 1202: /* this does a 16-bit "eor SRC, DST": */ 1203: TME_M68K_INSN(tme_m68k_eor16) 1204: { 1205: tme_uint16_t res, op0, op1; 1206: tme_uint8_t flags; 1207: 1208: /* load the operand(s): */ 1209: op0 = *((tme_uint16_t *) _op0); 1210: op1 = *((tme_uint16_t *) _op1); 1211: 1212: /* perform the operation: */ 1213: res = op1 ^ op0; 1214: 1215: /* store the result: */ 1216: *((tme_uint16_t *) _op1) = res; 1217: 1218: /* set the flags: */ 1219: flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1220: if (res == 0) flags |= TME_M68K_FLAG_Z; 1221: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 1222: ic->tme_m68k_ireg_ccr = flags; 1223: 1224: TME_M68K_INSN_OK; 1225: } 1226: 1227: /* this does a 16-bit "not DST": */ 1228: TME_M68K_INSN(tme_m68k_not16) 1229: { 1230: tme_uint16_t res, op1; 1231: tme_uint8_t flags; 1232: 1233: /* load the operand(s): */ 1234: op1 = *((tme_uint16_t *) _op1); 1235: 1236: /* perform the operation: */ 1237: res = ~ op1; 1238: 1239: /* store the result: */ 1240: *((tme_uint16_t *) _op1) = res; 1241: 1242: /* set the flags: */ 1243: flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1244: if (res == 0) flags |= TME_M68K_FLAG_Z; 1245: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 1246: ic->tme_m68k_ireg_ccr = flags; 1247: 1248: TME_M68K_INSN_OK; 1249: } 1250: 1251: /* this does a 16-bit "tst DST": */ 1252: TME_M68K_INSN(tme_m68k_tst16) 1253: { 1254: tme_uint16_t res, op1; 1255: tme_uint8_t flags; 1256: 1257: /* load the operand(s): */ 1258: op1 = *((tme_uint16_t *) _op1); 1259: 1260: /* perform the operation: */ 1261: res = op1; 1262: 1263: /* set the flags: */ 1264: flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1265: if (res == 0) flags |= TME_M68K_FLAG_Z; 1266: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 1267: ic->tme_m68k_ireg_ccr = flags; 1268: 1269: TME_M68K_INSN_OK; 1270: } 1271: 1272: /* this does a 16-bit "move DST": */ 1273: TME_M68K_INSN(tme_m68k_move16) 1274: { 1275: tme_uint16_t res, op1; 1276: tme_uint8_t flags; 1277: 1278: /* load the operand(s): */ 1279: op1 = *((tme_uint16_t *) _op1); 1280: 1281: /* perform the operation: */ 1282: res = op1; 1283: 1284: /* store the result: */ 1285: *((tme_uint16_t *) _op0) = res; 1286: 1287: /* set the flags: */ 1288: flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1289: if (res == 0) flags |= TME_M68K_FLAG_Z; 1290: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 1291: ic->tme_m68k_ireg_ccr = flags; 1292: 1293: TME_M68K_INSN_OK; 1294: } 1295: 1296: /* this does a 16-bit "clr DST": */ 1297: TME_M68K_INSN(tme_m68k_clr16) 1298: { 1299: tme_uint16_t res; 1300: tme_uint8_t flags; 1301: 1302: /* load the operand(s): */ 1303: 1304: /* perform the operation: */ 1305: res = 0; 1306: 1307: /* store the result: */ 1308: *((tme_uint16_t *) _op1) = res; 1309: 1310: /* set the flags: */ 1311: flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1312: if (res == 0) flags |= TME_M68K_FLAG_Z; 1313: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 1314: ic->tme_m68k_ireg_ccr = flags; 1315: 1316: TME_M68K_INSN_OK; 1317: } 1318: 1319: /* this does a 16-bit "cmpa SRC, DST": */ 1320: TME_M68K_INSN(tme_m68k_cmpa16) 1321: { 1322: tme_uint32_t res, op0, op1; 1323: tme_uint8_t flags; 1324: 1325: /* load the operand(s): */ 1326: op0 = (tme_uint32_t) ((tme_int32_t) *((tme_int16_t *) _op0)); 1327: op1 = *((tme_uint32_t *) _op1); 1328: 1329: /* perform the operation: */ 1330: res = op1 - op0; 1331: 1332: /* set the flags: */ 1333: flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 1334: if (res == 0) flags |= TME_M68K_FLAG_Z; 1335: flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V; 1336: if (op0 > op1) flags |= TME_M68K_FLAG_C; 1337: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 1338: ic->tme_m68k_ireg_ccr = flags; 1339: 1340: TME_M68K_INSN_OK; 1341: } 1342: 1343: /* this does a 16-bit "negx DST": */ 1344: TME_M68K_INSN(tme_m68k_negx16) 1345: { 1346: tme_uint16_t res, op1; 1347: tme_uint8_t flags; 1348: 1349: /* load the operand(s): */ 1350: op1 = *((tme_uint16_t *) _op1); 1351: 1352: /* perform the operation: */ 1353: res = 0 - op1 - ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1); 1354: 1355: /* store the result: */ 1356: *((tme_uint16_t *) _op1) = res; 1357: 1358: /* set the flags: */ 1359: flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1360: if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z); 1361: flags |= ((tme_uint8_t) (((op1 ^ 0) & (0 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V; 1362: if (op1 > 0 || (op1 == 0 && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X; 1363: ic->tme_m68k_ireg_ccr = flags; 1364: 1365: TME_M68K_INSN_OK; 1366: } 1367: 1368: /* this does a 16-bit "addx SRC, DST": */ 1369: TME_M68K_INSN(tme_m68k_addx16) 1370: { 1371: tme_uint16_t res, op0, op1; 1372: tme_uint8_t flags; 1373: 1374: /* load the operand(s): */ 1375: unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic); 1376: int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3); 1377: int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3); 1378: tme_uint32_t ireg_src_adjust = sizeof(tme_uint16_t); 1379: tme_uint32_t ireg_dst_adjust = sizeof(tme_uint16_t); 1380: tme_uint16_t memory; 1381: 1382: memory = (TME_M68K_INSN_OPCODE & TME_BIT(3)); 1383: if (memory) { 1384: TME_M68K_INSN_CANFAULT; 1385: if (!TME_M68K_SEQUENCE_RESTARTING) { 1386: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) -= ireg_dst_adjust; 1387: ic->_tme_m68k_ea_function_code = function_code; 1388: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst); 1389: } 1390: tme_m68k_read_memx16(ic); 1391: if (!TME_M68K_SEQUENCE_RESTARTING) { 1392: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) -= ireg_src_adjust; 1393: ic->_tme_m68k_ea_function_code = function_code; 1394: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src); 1395: } 1396: tme_m68k_read_mem16(ic, TME_M68K_IREG_MEMY16); 1397: op1 = ic->tme_m68k_ireg_memx16; 1398: op0 = ic->tme_m68k_ireg_memy16; 1399: } 1400: else { 1401: op0 = ic->tme_m68k_ireg_uint16((TME_M68K_IREG_D0 + ireg_src) << 1); 1402: op1 = ic->tme_m68k_ireg_uint16((TME_M68K_IREG_D0 + ireg_dst) << 1); 1403: } 1404: 1405: /* perform the operation: */ 1406: res = op1 + op0 + ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1); 1407: 1408: /* store the result: */ 1409: if (memory) { 1410: if (!TME_M68K_SEQUENCE_RESTARTING) { 1411: ic->tme_m68k_ireg_memx16 = res; 1412: ic->_tme_m68k_ea_function_code = function_code; 1413: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst); 1414: } 1415: tme_m68k_write_memx16(ic); 1416: } 1417: else { 1418: ic->tme_m68k_ireg_uint16((TME_M68K_IREG_D0 + ireg_dst) << 1) = res; 1419: } 1420: 1421: /* set the flags: */ 1422: flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1423: if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z); 1424: flags |= ((tme_uint8_t) (((op0 ^ op1 ^ 0xffff) & (op1 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V; 1425: if (op0 > (op1 ^ 0xffff) || (op0 == (op1 ^ 0xffff) && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X; 1426: ic->tme_m68k_ireg_ccr = flags; 1427: 1428: TME_M68K_INSN_OK; 1429: } 1430: 1431: /* this does a 16-bit "subx SRC, DST": */ 1432: TME_M68K_INSN(tme_m68k_subx16) 1433: { 1434: tme_uint16_t res, op0, op1; 1435: tme_uint8_t flags; 1436: 1437: /* load the operand(s): */ 1438: unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic); 1439: int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3); 1440: int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3); 1441: tme_uint32_t ireg_src_adjust = sizeof(tme_uint16_t); 1442: tme_uint32_t ireg_dst_adjust = sizeof(tme_uint16_t); 1443: tme_uint16_t memory; 1444: 1445: memory = (TME_M68K_INSN_OPCODE & TME_BIT(3)); 1446: if (memory) { 1447: TME_M68K_INSN_CANFAULT; 1448: if (!TME_M68K_SEQUENCE_RESTARTING) { 1449: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) -= ireg_dst_adjust; 1450: ic->_tme_m68k_ea_function_code = function_code; 1451: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst); 1452: } 1453: tme_m68k_read_memx16(ic); 1454: if (!TME_M68K_SEQUENCE_RESTARTING) { 1455: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) -= ireg_src_adjust; 1456: ic->_tme_m68k_ea_function_code = function_code; 1457: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src); 1458: } 1459: tme_m68k_read_mem16(ic, TME_M68K_IREG_MEMY16); 1460: op1 = ic->tme_m68k_ireg_memx16; 1461: op0 = ic->tme_m68k_ireg_memy16; 1462: } 1463: else { 1464: op0 = ic->tme_m68k_ireg_uint16((TME_M68K_IREG_D0 + ireg_src) << 1); 1465: op1 = ic->tme_m68k_ireg_uint16((TME_M68K_IREG_D0 + ireg_dst) << 1); 1466: } 1467: 1468: /* perform the operation: */ 1469: res = op1 - op0 - ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1); 1470: 1471: /* store the result: */ 1472: if (memory) { 1473: if (!TME_M68K_SEQUENCE_RESTARTING) { 1474: ic->tme_m68k_ireg_memx16 = res; 1475: ic->_tme_m68k_ea_function_code = function_code; 1476: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst); 1477: } 1478: tme_m68k_write_memx16(ic); 1479: } 1480: else { 1481: ic->tme_m68k_ireg_uint16((TME_M68K_IREG_D0 + ireg_dst) << 1) = res; 1482: } 1483: 1484: /* set the flags: */ 1485: flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1486: if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z); 1487: flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V; 1488: if (op0 > op1 || (op0 == op1 && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X; 1489: ic->tme_m68k_ireg_ccr = flags; 1490: 1491: TME_M68K_INSN_OK; 1492: } 1493: 1494: /* this does a 16-bit "cmpm SRC, DST": */ 1495: TME_M68K_INSN(tme_m68k_cmpm16) 1496: { 1497: tme_uint16_t res, op0, op1; 1498: tme_uint8_t flags; 1499: 1500: /* load the operand(s): */ 1501: unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic); 1502: int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3); 1503: int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3); 1504: tme_uint32_t ireg_src_adjust = sizeof(tme_uint16_t); 1505: tme_uint32_t ireg_dst_adjust = sizeof(tme_uint16_t); 1506: 1507: TME_M68K_INSN_CANFAULT; 1508: 1509: if (!TME_M68K_SEQUENCE_RESTARTING) { 1510: ic->_tme_m68k_ea_function_code = function_code; 1511: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst); 1512: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) += ireg_dst_adjust; 1513: } 1514: tme_m68k_read_memx16(ic); 1515: if (!TME_M68K_SEQUENCE_RESTARTING) { 1516: ic->_tme_m68k_ea_function_code = function_code; 1517: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src); 1518: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) += ireg_src_adjust; 1519: } 1520: tme_m68k_read_mem16(ic, TME_M68K_IREG_MEMY16); 1521: op1 = ic->tme_m68k_ireg_memx16; 1522: op0 = ic->tme_m68k_ireg_memy16; 1523: 1524: /* perform the operation: */ 1525: res = op1 - op0; 1526: 1527: /* set the flags: */ 1528: flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1529: if (res == 0) flags |= TME_M68K_FLAG_Z; 1530: flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V; 1531: if (op0 > op1) flags |= TME_M68K_FLAG_C; 1532: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 1533: ic->tme_m68k_ireg_ccr = flags; 1534: 1535: TME_M68K_INSN_OK; 1536: } 1537: 1538: /* the suba function on a 16-byte EA: */ 1539: TME_M68K_INSN(tme_m68k_suba16) 1540: { 1541: *((tme_int32_t *) _op1) -= *((tme_int16_t *) _op0); 1542: TME_M68K_INSN_OK; 1543: } 1544: 1545: /* the adda function on a 16-byte EA: */ 1546: TME_M68K_INSN(tme_m68k_adda16) 1547: { 1548: *((tme_int32_t *) _op1) += *((tme_int16_t *) _op0); 1549: TME_M68K_INSN_OK; 1550: } 1551: 1552: /* the movea function on a 16-byte EA: */ 1553: TME_M68K_INSN(tme_m68k_movea16) 1554: { 1555: *((tme_int32_t *) _op0) = *((tme_int16_t *) _op1); 1556: TME_M68K_INSN_OK; 1557: } 1558: 1559: /* the asl function on a 16-byte EA: */ 1560: TME_M68K_INSN(tme_m68k_asl16) 1561: { 1562: unsigned int count; 1.1.1.2 root 1563: tme_uint16_t sign_bits, sign_bits_mask; 1.1 root 1564: tme_uint16_t res; 1565: tme_uint8_t flags; 1566: 1567: /* get the count and operand: */ 1568: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 1569: res = TME_M68K_INSN_OP1(tme_uint16_t); 1570: 1571: /* generate the X, V, and C flags assuming the count is zero: */ 1572: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 1573: 1574: /* if the count is nonzero, update the result and 1575: generate the X, V, and C flags: */ 1576: if (count > 0) { 1577: 1578: /* we need to see how the sign of the result will change during 1579: shifting in order to generate V. 1580: 1581: in general, the idea is to get all of the bits that will ever 1.1.1.2 root 1582: appear in the sign position into sign_bits, with a mask in 1583: sign_bits_mask. if (sign_bits & sign_bits_mask) is zero or 1584: sign_bits_mask, clear V, else set V. 1.1 root 1585: 1.1.1.2 root 1586: start by loading the operand into sign_bits and setting 1587: sign_bits_mask to all-bits-one. 1.1 root 1588: 1589: if the shift count is exactly 16 - 1, then all of the bits 1590: of the operand will appear in the sign position. 1591: 1592: if the shift count is less than 16 - 1, then some of the 1593: less significant bits of the operand will never appear in the 1.1.1.2 root 1594: sign position, so we can shift sign_bits_mask to ignore them. 1.1 root 1595: 1596: if the shift count is greater than 16 - 1, then all of the 1597: bits in the operand, plus at least one zero bit, will appear in 1598: the sign position. the only way that the sign bit will never 1599: change during the shift is if the operand was zero to begin with. 1.1.1.2 root 1600: without any changes to sign_bits or sign_bits_mask, the final 1601: test will always work, except when sign_bits is all-bits-one. 1602: the magic below clears the least-significant bit of sign_bits 1603: iff sign_bits is all-bits-one: */ 1.1 root 1604: sign_bits = res; 1605: if (63 > SHIFTMAX_INT16_T 1606: && count > 16) { 1607: res = 0; 1608: } 1609: res <<= (count - 1); 1610: flags = (res >> (16 - 1)); 1611: flags *= TME_M68K_FLAG_C; 1612: flags |= (flags * TME_M68K_FLAG_X); 1613: res <<= 1; 1.1.1.2 root 1614: sign_bits_mask = (tme_uint16_t) -1; 1.1 root 1615: if (count != 16 - 1) { 1616: if (count < 16) { 1.1.1.2 root 1617: sign_bits_mask <<= ((16 - 1) - count); 1.1 root 1618: } 1619: else { 1.1.1.2 root 1620: sign_bits ^= !(sign_bits + 1); 1.1 root 1621: } 1622: } 1.1.1.2 root 1623: sign_bits &= sign_bits_mask; 1624: if (sign_bits != 0 && sign_bits != sign_bits_mask) { 1.1 root 1625: flags |= TME_M68K_FLAG_V; 1626: } 1627: } 1628: 1629: /* store the result: */ 1630: TME_M68K_INSN_OP1(tme_uint16_t) = res; 1631: 1632: /* generate the N flag. we cast to tme_uint8_t as soon as we 1633: know the bit we want is within the range of the type, to try 1634: to affect the generated assembly: */ 1635: flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1636: 1637: /* generate the Z flag: */ 1638: if (res == 0) flags |= TME_M68K_FLAG_Z; 1639: 1640: /* store the flags: */ 1641: ic->tme_m68k_ireg_ccr = flags; 1642: TME_M68K_INSN_OK; 1643: } 1644: 1645: /* the asr function on a 16-byte EA: */ 1646: TME_M68K_INSN(tme_m68k_asr16) 1647: { 1648: unsigned int count; 1649: tme_int16_t res; 1650: tme_uint8_t flags; 1651: 1652: /* get the count and operand: */ 1653: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 1654: res = TME_M68K_INSN_OP1(tme_int16_t); 1655: 1656: /* generate the X, V, and C flags assuming the count is zero: */ 1657: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 1658: 1659: /* if the count is nonzero, update the result and 1660: generate the X, V, and C flags: */ 1661: if (count > 0) { 1662: if (63 > SHIFTMAX_INT16_T 1663: && count > 16) { 1.1.1.3 ! root 1664: res = 0 - (res < 0); 1.1 root 1665: } 1.1.1.3 ! root 1666: #ifdef SHIFTSIGNED_INT16_T 1.1 root 1667: res >>= (count - 1); 1.1.1.3 ! root 1668: #else /* !SHIFTSIGNED_INT16_T */ ! 1669: for (; --count > 0; ) { ! 1670: res = (res & ~((tme_int16_t) 1)) / 2; ! 1671: } ! 1672: #endif /* !SHIFTSIGNED_INT16_T */ 1.1 root 1673: flags = (res & 1); 1674: flags *= TME_M68K_FLAG_C; 1675: flags |= (flags * TME_M68K_FLAG_X); 1.1.1.3 ! root 1676: #ifdef SHIFTSIGNED_INT16_T 1.1 root 1677: res >>= 1; 1.1.1.3 ! root 1678: #else /* !SHIFTSIGNED_INT16_T */ ! 1679: res = (res & ~((tme_int16_t) 1)) / 2; ! 1680: #endif /* !SHIFTSIGNED_INT16_T */ 1.1 root 1681: } 1682: 1683: /* store the result: */ 1684: TME_M68K_INSN_OP1(tme_int16_t) = res; 1685: 1686: /* generate the N flag. we cast to tme_uint8_t as soon as we 1687: know the bit we want is within the range of the type, to try 1688: to affect the generated assembly: */ 1689: flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1690: 1691: /* generate the Z flag: */ 1692: if (res == 0) flags |= TME_M68K_FLAG_Z; 1693: 1694: /* store the flags: */ 1695: ic->tme_m68k_ireg_ccr = flags; 1696: TME_M68K_INSN_OK; 1697: } 1698: 1699: /* the lsl function on a 16-byte EA: */ 1700: TME_M68K_INSN(tme_m68k_lsl16) 1701: { 1702: unsigned int count; 1703: tme_uint16_t res; 1704: tme_uint8_t flags; 1705: 1706: /* get the count and operand: */ 1707: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 1708: res = TME_M68K_INSN_OP1(tme_uint16_t); 1709: 1710: /* generate the X, V, and C flags assuming the count is zero: */ 1711: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 1712: 1713: /* if the count is nonzero, update the result and 1714: generate the X, V, and C flags: */ 1715: if (count > 0) { 1716: if (63 > SHIFTMAX_INT16_T 1717: && count > 16) { 1718: res = 0; 1719: } 1720: res <<= (count - 1); 1721: flags = (res >> (16 - 1)); 1722: flags *= TME_M68K_FLAG_C; 1723: flags |= (flags * TME_M68K_FLAG_X); 1724: res <<= 1; 1725: } 1726: 1727: /* store the result: */ 1728: TME_M68K_INSN_OP1(tme_uint16_t) = res; 1729: 1730: /* generate the N flag. we cast to tme_uint8_t as soon as we 1731: know the bit we want is within the range of the type, to try 1732: to affect the generated assembly: */ 1733: flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1734: 1735: /* generate the Z flag: */ 1736: if (res == 0) flags |= TME_M68K_FLAG_Z; 1737: 1738: /* store the flags: */ 1739: ic->tme_m68k_ireg_ccr = flags; 1740: TME_M68K_INSN_OK; 1741: } 1742: 1743: /* the lsr function on a 16-byte EA: */ 1744: TME_M68K_INSN(tme_m68k_lsr16) 1745: { 1746: unsigned int count; 1747: tme_uint16_t res; 1748: tme_uint8_t flags; 1749: 1750: /* get the count and operand: */ 1751: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 1752: res = TME_M68K_INSN_OP1(tme_uint16_t); 1753: 1754: /* generate the X, V, and C flags assuming the count is zero: */ 1755: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 1756: 1757: /* if the count is nonzero, update the result and 1758: generate the X, V, and C flags: */ 1759: if (count > 0) { 1760: if (63 > SHIFTMAX_INT16_T 1761: && count > 16) { 1762: res = 0; 1763: } 1764: res >>= (count - 1); 1765: flags = (res & 1); 1766: flags *= TME_M68K_FLAG_C; 1767: flags |= (flags * TME_M68K_FLAG_X); 1768: res >>= 1; 1769: } 1770: 1771: /* store the result: */ 1772: TME_M68K_INSN_OP1(tme_uint16_t) = res; 1773: 1774: /* generate the N flag. we cast to tme_uint8_t as soon as we 1775: know the bit we want is within the range of the type, to try 1776: to affect the generated assembly: */ 1777: flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1778: 1779: /* generate the Z flag: */ 1780: if (res == 0) flags |= TME_M68K_FLAG_Z; 1781: 1782: /* store the flags: */ 1783: ic->tme_m68k_ireg_ccr = flags; 1784: TME_M68K_INSN_OK; 1785: } 1786: 1787: /* the rol function on a 16-byte EA: */ 1788: TME_M68K_INSN(tme_m68k_rol16) 1789: { 1790: unsigned int count; 1791: tme_uint16_t res; 1792: tme_uint8_t flags; 1793: 1794: /* get the count and operand: */ 1795: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 1796: res = TME_M68K_INSN_OP1(tme_uint16_t); 1797: 1798: /* generate the X, V, and C flags assuming the count is zero: */ 1799: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 1800: 1801: /* if the count is nonzero, update the result and 1802: generate the X, V, and C flags: */ 1803: if (count > 0) { 1804: count &= (16 - 1); 1805: res = (res << count) | (res >> (16 - count)); 1806: flags |= ((res & 1) * TME_M68K_FLAG_C); 1807: } 1808: 1809: /* store the result: */ 1810: TME_M68K_INSN_OP1(tme_uint16_t) = res; 1811: 1812: /* generate the N flag. we cast to tme_uint8_t as soon as we 1813: know the bit we want is within the range of the type, to try 1814: to affect the generated assembly: */ 1815: flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1816: 1817: /* generate the Z flag: */ 1818: if (res == 0) flags |= TME_M68K_FLAG_Z; 1819: 1820: /* store the flags: */ 1821: ic->tme_m68k_ireg_ccr = flags; 1822: TME_M68K_INSN_OK; 1823: } 1824: 1825: /* the ror function on a 16-byte EA: */ 1826: TME_M68K_INSN(tme_m68k_ror16) 1827: { 1828: unsigned int count; 1829: tme_uint16_t res; 1830: tme_uint8_t flags; 1831: 1832: /* get the count and operand: */ 1833: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 1834: res = TME_M68K_INSN_OP1(tme_uint16_t); 1835: 1836: /* generate the X, V, and C flags assuming the count is zero: */ 1837: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 1838: 1839: /* if the count is nonzero, update the result and 1840: generate the X, V, and C flags: */ 1841: if (count > 0) { 1842: count &= (16 - 1); 1843: res = (res << (16 - count)) | (res >> count); 1844: flags |= ((res >> (16 - 1)) * TME_M68K_FLAG_C); 1845: } 1846: 1847: /* store the result: */ 1848: TME_M68K_INSN_OP1(tme_uint16_t) = res; 1849: 1850: /* generate the N flag. we cast to tme_uint8_t as soon as we 1851: know the bit we want is within the range of the type, to try 1852: to affect the generated assembly: */ 1853: flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1854: 1855: /* generate the Z flag: */ 1856: if (res == 0) flags |= TME_M68K_FLAG_Z; 1857: 1858: /* store the flags: */ 1859: ic->tme_m68k_ireg_ccr = flags; 1860: TME_M68K_INSN_OK; 1861: } 1862: 1863: /* the roxl function on a 16-byte EA: */ 1864: TME_M68K_INSN(tme_m68k_roxl16) 1865: { 1866: unsigned int count; 1867: tme_uint8_t xbit; 1868: tme_uint16_t res; 1869: tme_uint8_t flags; 1870: 1871: /* get the count and operand: */ 1872: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 1873: res = TME_M68K_INSN_OP1(tme_uint16_t); 1874: 1875: /* generate the X, V, and C flags assuming the count is zero: */ 1876: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 1877: xbit = (flags / TME_M68K_FLAG_X); 1878: flags |= (xbit * TME_M68K_FLAG_C); 1879: 1880: /* if the count is nonzero, update the result and 1881: generate the X, V, and C flags: */ 1882: if (count > 0) { 1883: count %= (16 + 1); 1884: flags = xbit; 1885: if (count > 0) { 1886: flags = (res >> (16 - count)) & 1; 1887: if (16 > SHIFTMAX_INT16_T 1888: && count == 16) { 1889: res = 0 | (xbit << (16 - 1)) | (res >> ((16 + 1) - 16)); 1890: } 1891: else if (16 > SHIFTMAX_INT16_T 1892: && count == 1) { 1893: res = (res << 1) | (xbit << (1 - 1)) | 0; 1894: } 1895: else { 1896: res = (res << count) | (xbit << (count - 1)) | (res >> ((16 + 1) - count)); 1897: } 1898: } 1899: flags *= TME_M68K_FLAG_C; 1900: flags |= (flags * TME_M68K_FLAG_X); 1901: } 1902: 1903: /* store the result: */ 1904: TME_M68K_INSN_OP1(tme_uint16_t) = res; 1905: 1906: /* generate the N flag. we cast to tme_uint8_t as soon as we 1907: know the bit we want is within the range of the type, to try 1908: to affect the generated assembly: */ 1909: flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1910: 1911: /* generate the Z flag: */ 1912: if (res == 0) flags |= TME_M68K_FLAG_Z; 1913: 1914: /* store the flags: */ 1915: ic->tme_m68k_ireg_ccr = flags; 1916: TME_M68K_INSN_OK; 1917: } 1918: 1919: /* the roxr function on a 16-byte EA: */ 1920: TME_M68K_INSN(tme_m68k_roxr16) 1921: { 1922: unsigned int count; 1923: tme_uint8_t xbit; 1924: tme_uint16_t res; 1925: tme_uint8_t flags; 1926: 1927: /* get the count and operand: */ 1928: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 1929: res = TME_M68K_INSN_OP1(tme_uint16_t); 1930: 1931: /* generate the X, V, and C flags assuming the count is zero: */ 1932: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 1933: xbit = (flags / TME_M68K_FLAG_X); 1934: flags |= (xbit * TME_M68K_FLAG_C); 1935: 1936: /* if the count is nonzero, update the result and 1937: generate the X, V, and C flags: */ 1938: if (count > 0) { 1939: count %= (16 + 1); 1940: flags = xbit; 1941: if (count > 0) { 1942: flags = (res >> (count - 1)) & 1; 1943: if (16 > SHIFTMAX_INT16_T 1944: && count == 16) { 1945: res = (res << ((16 + 1) - 16)) | (xbit << (16 - 16)) | 0; 1946: } 1947: else if (16 > SHIFTMAX_INT16_T 1948: && count == 1) { 1949: res = 0 | (xbit << (16 - 1)) | (res >> 1); 1950: } 1951: else { 1952: res = (res << ((16 + 1) - count)) | (xbit << (16 - count)) | (res >> count); 1953: } 1954: } 1955: flags *= TME_M68K_FLAG_C; 1956: flags |= (flags * TME_M68K_FLAG_X); 1957: } 1958: 1959: /* store the result: */ 1960: TME_M68K_INSN_OP1(tme_uint16_t) = res; 1961: 1962: /* generate the N flag. we cast to tme_uint8_t as soon as we 1963: know the bit we want is within the range of the type, to try 1964: to affect the generated assembly: */ 1965: flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N; 1966: 1967: /* generate the Z flag: */ 1968: if (res == 0) flags |= TME_M68K_FLAG_Z; 1969: 1970: /* store the flags: */ 1971: ic->tme_m68k_ireg_ccr = flags; 1972: TME_M68K_INSN_OK; 1973: } 1974: 1975: /* the movep_rm function on a 16-bit dreg: */ 1976: TME_M68K_INSN(tme_m68k_movep_rm16) 1977: { 1978: unsigned int function_code; 1979: tme_uint32_t linear_address; 1980: tme_uint16_t value; 1981: int dreg; 1982: 1983: TME_M68K_INSN_CANFAULT; 1984: 1985: function_code = TME_M68K_FUNCTION_CODE_DATA(ic); 1986: linear_address = TME_M68K_INSN_OP1(tme_uint32_t); 1987: linear_address += (tme_int32_t) ((tme_int16_t) TME_M68K_INSN_SPECOP); 1988: dreg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3); 1989: value = ic->tme_m68k_ireg_uint16(dreg << 1); 1990: if (!TME_M68K_SEQUENCE_RESTARTING) { 1991: ic->_tme_m68k_ea_function_code = function_code; 1992: ic->_tme_m68k_ea_address = linear_address; 1993: ic->tme_m68k_ireg_memx8 = TME_FIELD_EXTRACTU(value, 8, 8); 1994: } 1995: tme_m68k_write_memx8(ic); 1996: linear_address += 2; 1997: if (!TME_M68K_SEQUENCE_RESTARTING) { 1998: ic->_tme_m68k_ea_function_code = function_code; 1999: ic->_tme_m68k_ea_address = linear_address; 2000: ic->tme_m68k_ireg_memx8 = TME_FIELD_EXTRACTU(value, 0, 8); 2001: } 2002: tme_m68k_write_memx8(ic); 2003: linear_address += 2; 2004: TME_M68K_INSN_OK; 2005: } 2006: 2007: /* the movem_rm function on 16-bit registers: */ 2008: TME_M68K_INSN(tme_m68k_movem_rm16) 2009: { 2010: int ireg, direction; 2011: tme_uint16_t mask, bit; 2012: unsigned int ea_mode; 2013: tme_uint32_t addend; 2014: 2015: /* figure out what direction to move in, and where to start from: */ 2016: ea_mode = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 3, 3); 2017: direction = 1; 2018: ireg = TME_M68K_IREG_D0; 2019: if (ea_mode == 4) { 2020: direction = -1; 2021: ireg = TME_M68K_IREG_A7; 2022: if (!TME_M68K_SEQUENCE_RESTARTING) { 2023: ic->_tme_m68k_ea_address -= sizeof(tme_uint16_t); 2024: } 2025: } 2026: addend = (tme_uint32_t) (direction * sizeof(tme_uint16_t)); 2027: 2028: /* do the transfer: */ 2029: mask = TME_M68K_INSN_SPECOP; 1.1.1.2 root 2030: if (mask != 0) { 2031: TME_M68K_INSN_CANFAULT; 2032: } 1.1 root 2033: for (bit = 1; bit != 0; bit <<= 1) { 2034: if (mask & bit) { 2035: if (!TME_M68K_SEQUENCE_RESTARTING) { 2036: ic->tme_m68k_ireg_memx16 = ic->tme_m68k_ireg_uint16(ireg << 1); 2037: } 2038: tme_m68k_write_memx16(ic); 2039: if (!TME_M68K_SEQUENCE_RESTARTING) { 2040: ic->_tme_m68k_ea_address += addend; 2041: } 2042: } 2043: ireg += direction; 2044: } 2045: 2046: /* if this is the predecrement mode, update the address register: */ 2047: if (ea_mode == 4) { 2048: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 2049: + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3)) 2050: = (ic->_tme_m68k_ea_address + sizeof(tme_uint16_t)); 2051: } 2052: TME_M68K_INSN_OK; 2053: } 2054: 2055: /* the movep_mr function on a 16-bit dreg: */ 2056: TME_M68K_INSN(tme_m68k_movep_mr16) 2057: { 2058: unsigned int function_code; 2059: tme_uint32_t linear_address; 2060: int dreg; 2061: 2062: TME_M68K_INSN_CANFAULT; 2063: 2064: function_code = TME_M68K_FUNCTION_CODE_DATA(ic); 2065: linear_address = TME_M68K_INSN_OP1(tme_uint32_t); 2066: linear_address += (tme_int32_t) ((tme_int16_t) TME_M68K_INSN_SPECOP); 2067: dreg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3); 2068: if (!TME_M68K_SEQUENCE_RESTARTING) { 2069: ic->_tme_m68k_ea_function_code = function_code; 2070: ic->_tme_m68k_ea_address = linear_address; 2071: } 2072: tme_m68k_read_memx8(ic); 2073: if (!TME_M68K_SEQUENCE_RESTARTING) { 2074: TME_FIELD_DEPOSIT16(ic->tme_m68k_ireg_uint16(dreg << 1), 8, 8, ic->tme_m68k_ireg_memx8); 2075: } 2076: linear_address += 2; 2077: if (!TME_M68K_SEQUENCE_RESTARTING) { 2078: ic->_tme_m68k_ea_function_code = function_code; 2079: ic->_tme_m68k_ea_address = linear_address; 2080: } 2081: tme_m68k_read_memx8(ic); 2082: if (!TME_M68K_SEQUENCE_RESTARTING) { 2083: TME_FIELD_DEPOSIT16(ic->tme_m68k_ireg_uint16(dreg << 1), 0, 8, ic->tme_m68k_ireg_memx8); 2084: } 2085: linear_address += 2; 2086: TME_M68K_INSN_OK; 2087: } 2088: 2089: /* the movem_mr function on 16-bit registers: */ 2090: TME_M68K_INSN(tme_m68k_movem_mr16) 2091: { 2092: int ireg, direction; 2093: tme_uint16_t mask, bit; 2094: unsigned int ea_mode; 2095: tme_uint32_t addend; 2096: 2097: /* figure out what direction to move in, and where to start from: */ 2098: ea_mode = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 3, 3); 2099: direction = 1; 2100: ireg = TME_M68K_IREG_D0; 2101: addend = (tme_uint32_t) (direction * sizeof(tme_uint16_t)); 2102: 2103: /* do the transfer: */ 2104: mask = TME_M68K_INSN_SPECOP; 1.1.1.2 root 2105: if (mask != 0) { 2106: TME_M68K_INSN_CANFAULT; 2107: } 1.1 root 2108: for (bit = 1; bit != 0; bit <<= 1) { 2109: if (mask & bit) { 2110: tme_m68k_read_memx16(ic); 2111: if (!TME_M68K_SEQUENCE_RESTARTING) { 2112: ic->tme_m68k_ireg_uint32(ireg) = TME_EXT_S16_U32((tme_int16_t) ic->tme_m68k_ireg_memx16); 2113: ic->_tme_m68k_ea_address += addend; 2114: } 2115: } 2116: ireg += direction; 2117: } 2118: 2119: /* if this is the postincrement mode, update the address register: */ 2120: if (ea_mode == 3) { 2121: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 2122: + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3)) 2123: = ic->_tme_m68k_ea_address; 2124: } 2125: TME_M68K_INSN_OK; 2126: } 2127: 2128: /* chk16: */ 2129: TME_M68K_INSN(tme_m68k_chk16) 2130: { 2131: if (*((tme_int16_t *) _op0) < 0) { 2132: ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_N; 1.1.1.3 ! root 2133: ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc; 1.1 root 2134: ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next; 1.1.1.3 ! root 2135: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_CHK)); 1.1 root 2136: } 2137: if (*((tme_int16_t *) _op0) > *((tme_int16_t *) _op1)) { 2138: ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_N; 1.1.1.3 ! root 2139: ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc; 1.1 root 2140: ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next; 1.1.1.3 ! root 2141: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_CHK)); 1.1 root 2142: } 2143: TME_M68K_INSN_OK; 2144: } 2145: 2146: /* cas16: */ 2147: TME_M68K_INSN(tme_m68k_cas16) 2148: { 2149: struct tme_m68k_tlb *tlb; 2150: int ireg_dc, ireg_du; 2151: int do_write; 2152: tme_uint16_t specopx = ic->_tme_m68k_insn_specop; 2153: 2154: /* start the read/modify/write cycle: */ 2155: tlb = tme_m68k_rmw_start(ic); 2156: if (tlb == NULL) { 2157: TME_M68K_INSN_OK; 2158: } 2159: 2160: /* read: */ 2161: tme_m68k_read16(ic, tlb, 2162: &ic->_tme_m68k_ea_function_code, 2163: &ic->_tme_m68k_ea_address, 2164: &ic->tme_m68k_ireg_memx16, 2165: TME_M68K_BUS_CYCLE_RMW); 2166: 2167: /* modify: */ 2168: ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 0, 3); 2169: tme_m68k_cmp16(ic, &ic->tme_m68k_ireg_uint16(ireg_dc), &ic->tme_m68k_ireg_memx16); 2170: 2171: /* write: */ 2172: if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) { 2173: ireg_du = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 6, 3); 2174: ic->tme_m68k_ireg_memx16 = ic->tme_m68k_ireg_uint16(ireg_du); 2175: tme_m68k_write16(ic, tlb, 2176: &ic->_tme_m68k_ea_function_code, 2177: &ic->_tme_m68k_ea_address, 2178: &ic->tme_m68k_ireg_memx16, 2179: TME_M68K_BUS_CYCLE_RMW); 2180: } 2181: else { 2182: /* XXX the 68040 always does a write to finish its cycle: */ 2183: do_write = FALSE; 2184: ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 0, 3); 2185: if (do_write) { 2186: tme_m68k_write16(ic, tlb, 2187: &ic->_tme_m68k_ea_function_code, 2188: &ic->_tme_m68k_ea_address, 2189: &ic->tme_m68k_ireg_memx16, 2190: TME_M68K_BUS_CYCLE_RMW); 2191: do_write = FALSE; 2192: } 2193: ic->tme_m68k_ireg_uint16(ireg_dc) = ic->tme_m68k_ireg_memx16; 2194: } 2195: 2196: /* finish the read/modify/write cycle: */ 2197: tme_m68k_rmw_finish(ic, tlb); 2198: 2199: TME_M68K_INSN_OK; 2200: } 2201: 2202: /* cas2_16: */ 2203: TME_M68K_INSN(tme_m68k_cas2_16) 2204: { 2205: struct tme_m68k_tlb *tlb; 2206: int ireg_dc, ireg_du; 2207: int do_write; 2208: tme_uint16_t specopx = ic->_tme_m68k_insn_specop; 1.1.1.3 ! root 2209: tme_uint16_t specopy = TME_M68K_INSN_OP0(tme_uint16_t); 1.1 root 2210: tme_uint32_t addrx; 2211: tme_uint32_t addry; 2212: 2213: /* get the function code and addresses we'll be dealing with: */ 2214: ic->_tme_m68k_ea_function_code = TME_M68K_FUNCTION_CODE_DATA(ic); 2215: addrx = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_D0 2216: + TME_FIELD_EXTRACTU(specopx, 12, 4)); 2217: addry = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_D0 2218: + TME_FIELD_EXTRACTU(specopy, 12, 4)); 2219: 2220: /* start the read/modify/write cycle: */ 2221: tlb = tme_m68k_rmw_start(ic); 2222: if (tlb == NULL) { 2223: TME_M68K_INSN_OK; 2224: } 2225: 2226: /* read: */ 2227: ic->_tme_m68k_ea_address = addrx; 2228: tme_m68k_read16(ic, tlb, 2229: &ic->_tme_m68k_ea_function_code, 2230: &ic->_tme_m68k_ea_address, 2231: &ic->tme_m68k_ireg_memx16, 2232: TME_M68K_BUS_CYCLE_RMW); 2233: ic->_tme_m68k_ea_address = addry; 2234: tme_m68k_read16(ic, tlb, 2235: &ic->_tme_m68k_ea_function_code, 2236: &ic->_tme_m68k_ea_address, 2237: &ic->tme_m68k_ireg_memy16, 2238: TME_M68K_BUS_CYCLE_RMW); 2239: 2240: /* modify: */ 2241: ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 0, 3); 2242: tme_m68k_cmp16(ic, &ic->tme_m68k_ireg_uint16(ireg_dc), &ic->tme_m68k_ireg_memx16); 2243: if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) { 2244: ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopy, 0, 3); 2245: tme_m68k_cmp16(ic, &ic->tme_m68k_ireg_uint16(ireg_dc), &ic->tme_m68k_ireg_memy16); 2246: } 2247: 2248: /* write: */ 2249: if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) { 2250: ic->_tme_m68k_ea_address = addrx; 2251: ireg_du = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 6, 3); 2252: ic->tme_m68k_ireg_memx16 = ic->tme_m68k_ireg_uint16(ireg_du); 2253: tme_m68k_write16(ic, tlb, 2254: &ic->_tme_m68k_ea_function_code, 2255: &ic->_tme_m68k_ea_address, 2256: &ic->tme_m68k_ireg_memx16, 2257: TME_M68K_BUS_CYCLE_RMW); 2258: ic->_tme_m68k_ea_address = addry; 2259: ireg_du = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopy, 6, 3); 2260: ic->tme_m68k_ireg_memy16 = ic->tme_m68k_ireg_uint16(ireg_du); 2261: tme_m68k_write16(ic, tlb, 2262: &ic->_tme_m68k_ea_function_code, 2263: &ic->_tme_m68k_ea_address, 2264: &ic->tme_m68k_ireg_memy16, 2265: TME_M68K_BUS_CYCLE_RMW); 2266: } 2267: else { 2268: /* XXX the 68040 always does a write to finish its cycle: */ 2269: do_write = FALSE; 2270: ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 0, 3); 2271: if (do_write 2272: && ic->tme_m68k_ireg_memx16 != ic->tme_m68k_ireg_uint16(ireg_dc)) { 2273: ic->_tme_m68k_ea_address = addrx; 2274: tme_m68k_write16(ic, tlb, 2275: &ic->_tme_m68k_ea_function_code, 2276: &ic->_tme_m68k_ea_address, 2277: &ic->tme_m68k_ireg_memx16, 2278: TME_M68K_BUS_CYCLE_RMW); 2279: do_write = FALSE; 2280: } 2281: ic->tme_m68k_ireg_uint16(ireg_dc) = ic->tme_m68k_ireg_memx16; 2282: ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopy, 0, 3); 2283: if (do_write 2284: && ic->tme_m68k_ireg_memy16 != ic->tme_m68k_ireg_uint16(ireg_dc)) { 2285: ic->_tme_m68k_ea_address = addry; 2286: tme_m68k_write16(ic, tlb, 2287: &ic->_tme_m68k_ea_function_code, 2288: &ic->_tme_m68k_ea_address, 2289: &ic->tme_m68k_ireg_memy16, 2290: TME_M68K_BUS_CYCLE_RMW); 2291: do_write = FALSE; 2292: } 2293: ic->tme_m68k_ireg_uint16(ireg_dc) = ic->tme_m68k_ireg_memy16; 2294: } 2295: 2296: /* finish the read/modify/write cycle: */ 2297: tme_m68k_rmw_finish(ic, tlb); 2298: 2299: TME_M68K_INSN_OK; 2300: } 2301: 2302: /* moves16: */ 2303: TME_M68K_INSN(tme_m68k_moves16) 2304: { 2305: int ireg; 1.1.1.3 ! root 2306: unsigned int ea_reg; ! 2307: unsigned int increment; ! 2308: TME_M68K_INSN_PRIV; ! 2309: TME_M68K_INSN_CANFAULT; 1.1 root 2310: ireg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 4); 1.1.1.3 ! root 2311: ! 2312: /* we have to handle postincrement and predecrement ourselves: */ ! 2313: if (!TME_M68K_SEQUENCE_RESTARTING) { ! 2314: ea_reg = TME_M68K_IREG_A0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3); ! 2315: increment = TME_M68K_SIZE_16; ! 2316: if (increment == TME_M68K_SIZE_8 && ea_reg == TME_M68K_IREG_A7) { ! 2317: increment = TME_M68K_SIZE_16; ! 2318: } ! 2319: switch (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 3, 3)) { ! 2320: case 3: ic->tme_m68k_ireg_uint32(ea_reg) += increment; break; ! 2321: case 4: ic->_tme_m68k_ea_address = (ic->tme_m68k_ireg_uint32(ea_reg) -= increment); break; ! 2322: default: break; ! 2323: } ! 2324: } ! 2325: 1.1 root 2326: if (TME_M68K_INSN_SPECOP & TME_BIT(11)) { 1.1.1.3 ! root 2327: if (!TME_M68K_SEQUENCE_RESTARTING) { ! 2328: ic->tme_m68k_ireg_memx16 = ic->tme_m68k_ireg_uint16(ireg << 1); ! 2329: ic->_tme_m68k_ea_function_code = ic->tme_m68k_ireg_dfc; ! 2330: } ! 2331: tme_m68k_write_memx16(ic); 1.1 root 2332: } 2333: else { 1.1.1.3 ! root 2334: if (!TME_M68K_SEQUENCE_RESTARTING) { ! 2335: ic->_tme_m68k_ea_function_code = ic->tme_m68k_ireg_sfc; ! 2336: } ! 2337: tme_m68k_read_memx16(ic); 1.1 root 2338: if (ireg >= TME_M68K_IREG_A0) { 2339: ic->tme_m68k_ireg_uint32(ireg) = 2340: TME_EXT_S16_U32((tme_int16_t) ic->tme_m68k_ireg_memx16); 2341: } 2342: else 2343: ic->tme_m68k_ireg_uint16(ireg << 1) = ic->tme_m68k_ireg_memx16; 2344: } 2345: TME_M68K_INSN_OK; 2346: } 2347: 2348: /* this does a 32-bit "add SRC, DST": */ 2349: TME_M68K_INSN(tme_m68k_add32) 2350: { 2351: tme_uint32_t res, op0, op1; 2352: tme_uint8_t flags; 2353: 2354: /* load the operand(s): */ 2355: op0 = *((tme_uint32_t *) _op0); 2356: op1 = *((tme_uint32_t *) _op1); 2357: 2358: /* perform the operation: */ 2359: res = op1 + op0; 2360: 2361: /* store the result: */ 2362: *((tme_uint32_t *) _op1) = res; 2363: 2364: /* set the flags: */ 2365: flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 2366: if (res == 0) flags |= TME_M68K_FLAG_Z; 2367: flags |= ((tme_uint8_t) (((op0 ^ op1 ^ 0xffffffff) & (op1 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V; 2368: if (op0 > (op1 ^ 0xffffffff)) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X; 2369: ic->tme_m68k_ireg_ccr = flags; 2370: 2371: TME_M68K_INSN_OK; 2372: } 2373: 2374: /* this does a 32-bit "sub SRC, DST": */ 2375: TME_M68K_INSN(tme_m68k_sub32) 2376: { 2377: tme_uint32_t res, op0, op1; 2378: tme_uint8_t flags; 2379: 2380: /* load the operand(s): */ 2381: op0 = *((tme_uint32_t *) _op0); 2382: op1 = *((tme_uint32_t *) _op1); 2383: 2384: /* perform the operation: */ 2385: res = op1 - op0; 2386: 2387: /* store the result: */ 2388: *((tme_uint32_t *) _op1) = res; 2389: 2390: /* set the flags: */ 2391: flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 2392: if (res == 0) flags |= TME_M68K_FLAG_Z; 2393: flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V; 2394: if (op0 > op1) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X; 2395: ic->tme_m68k_ireg_ccr = flags; 2396: 2397: TME_M68K_INSN_OK; 2398: } 2399: 2400: /* this does a 32-bit "cmp SRC, DST": */ 2401: TME_M68K_INSN(tme_m68k_cmp32) 2402: { 2403: tme_uint32_t res, op0, op1; 2404: tme_uint8_t flags; 2405: 2406: /* load the operand(s): */ 2407: op0 = *((tme_uint32_t *) _op0); 2408: op1 = *((tme_uint32_t *) _op1); 2409: 2410: /* perform the operation: */ 2411: res = op1 - op0; 2412: 2413: /* set the flags: */ 2414: flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 2415: if (res == 0) flags |= TME_M68K_FLAG_Z; 2416: flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V; 2417: if (op0 > op1) flags |= TME_M68K_FLAG_C; 2418: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 2419: ic->tme_m68k_ireg_ccr = flags; 2420: 2421: TME_M68K_INSN_OK; 2422: } 2423: 2424: /* this does a 32-bit "neg DST": */ 2425: TME_M68K_INSN(tme_m68k_neg32) 2426: { 2427: tme_uint32_t res, op1; 2428: tme_uint8_t flags; 2429: 2430: /* load the operand(s): */ 2431: op1 = *((tme_uint32_t *) _op1); 2432: 2433: /* perform the operation: */ 2434: res = 0 - op1; 2435: 2436: /* store the result: */ 2437: *((tme_uint32_t *) _op1) = res; 2438: 2439: /* set the flags: */ 2440: flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 2441: if (res == 0) flags |= TME_M68K_FLAG_Z; 2442: flags |= ((tme_uint8_t) (((op1 ^ 0) & (0 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V; 2443: if (op1 > 0) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X; 2444: ic->tme_m68k_ireg_ccr = flags; 2445: 2446: TME_M68K_INSN_OK; 2447: } 2448: 2449: /* this does a 32-bit "or SRC, DST": */ 2450: TME_M68K_INSN(tme_m68k_or32) 2451: { 2452: tme_uint32_t res, op0, op1; 2453: tme_uint8_t flags; 2454: 2455: /* load the operand(s): */ 2456: op0 = *((tme_uint32_t *) _op0); 2457: op1 = *((tme_uint32_t *) _op1); 2458: 2459: /* perform the operation: */ 2460: res = op1 | op0; 2461: 2462: /* store the result: */ 2463: *((tme_uint32_t *) _op1) = res; 2464: 2465: /* set the flags: */ 2466: flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 2467: if (res == 0) flags |= TME_M68K_FLAG_Z; 2468: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 2469: ic->tme_m68k_ireg_ccr = flags; 2470: 2471: TME_M68K_INSN_OK; 2472: } 2473: 2474: /* this does a 32-bit "and SRC, DST": */ 2475: TME_M68K_INSN(tme_m68k_and32) 2476: { 2477: tme_uint32_t res, op0, op1; 2478: tme_uint8_t flags; 2479: 2480: /* load the operand(s): */ 2481: op0 = *((tme_uint32_t *) _op0); 2482: op1 = *((tme_uint32_t *) _op1); 2483: 2484: /* perform the operation: */ 2485: res = op1 & op0; 2486: 2487: /* store the result: */ 2488: *((tme_uint32_t *) _op1) = res; 2489: 2490: /* set the flags: */ 2491: flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 2492: if (res == 0) flags |= TME_M68K_FLAG_Z; 2493: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 2494: ic->tme_m68k_ireg_ccr = flags; 2495: 2496: TME_M68K_INSN_OK; 2497: } 2498: 2499: /* this does a 32-bit "eor SRC, DST": */ 2500: TME_M68K_INSN(tme_m68k_eor32) 2501: { 2502: tme_uint32_t res, op0, op1; 2503: tme_uint8_t flags; 2504: 2505: /* load the operand(s): */ 2506: op0 = *((tme_uint32_t *) _op0); 2507: op1 = *((tme_uint32_t *) _op1); 2508: 2509: /* perform the operation: */ 2510: res = op1 ^ op0; 2511: 2512: /* store the result: */ 2513: *((tme_uint32_t *) _op1) = res; 2514: 2515: /* set the flags: */ 2516: flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 2517: if (res == 0) flags |= TME_M68K_FLAG_Z; 2518: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 2519: ic->tme_m68k_ireg_ccr = flags; 2520: 2521: TME_M68K_INSN_OK; 2522: } 2523: 2524: /* this does a 32-bit "not DST": */ 2525: TME_M68K_INSN(tme_m68k_not32) 2526: { 2527: tme_uint32_t res, op1; 2528: tme_uint8_t flags; 2529: 2530: /* load the operand(s): */ 2531: op1 = *((tme_uint32_t *) _op1); 2532: 2533: /* perform the operation: */ 2534: res = ~ op1; 2535: 2536: /* store the result: */ 2537: *((tme_uint32_t *) _op1) = res; 2538: 2539: /* set the flags: */ 2540: flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 2541: if (res == 0) flags |= TME_M68K_FLAG_Z; 2542: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 2543: ic->tme_m68k_ireg_ccr = flags; 2544: 2545: TME_M68K_INSN_OK; 2546: } 2547: 2548: /* this does a 32-bit "tst DST": */ 2549: TME_M68K_INSN(tme_m68k_tst32) 2550: { 2551: tme_uint32_t res, op1; 2552: tme_uint8_t flags; 2553: 2554: /* load the operand(s): */ 2555: op1 = *((tme_uint32_t *) _op1); 2556: 2557: /* perform the operation: */ 2558: res = op1; 2559: 2560: /* set the flags: */ 2561: flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 2562: if (res == 0) flags |= TME_M68K_FLAG_Z; 2563: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 2564: ic->tme_m68k_ireg_ccr = flags; 2565: 2566: TME_M68K_INSN_OK; 2567: } 2568: 2569: /* this does a 32-bit "move DST": */ 2570: TME_M68K_INSN(tme_m68k_move32) 2571: { 2572: tme_uint32_t res, op1; 2573: tme_uint8_t flags; 2574: 2575: /* load the operand(s): */ 2576: op1 = *((tme_uint32_t *) _op1); 2577: 2578: /* perform the operation: */ 2579: res = op1; 2580: 2581: /* store the result: */ 2582: *((tme_uint32_t *) _op0) = res; 2583: 2584: /* set the flags: */ 2585: flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 2586: if (res == 0) flags |= TME_M68K_FLAG_Z; 2587: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 2588: ic->tme_m68k_ireg_ccr = flags; 2589: 2590: TME_M68K_INSN_OK; 2591: } 2592: 2593: /* this does a 32-bit "moveq DST": */ 2594: TME_M68K_INSN(tme_m68k_moveq32) 2595: { 2596: tme_uint32_t res; 2597: tme_uint8_t flags; 2598: 2599: /* load the operand(s): */ 2600: 2601: /* perform the operation: */ 2602: res = TME_EXT_S8_U32((tme_int8_t) (TME_M68K_INSN_OPCODE & 0xff)); 2603: 2604: /* store the result: */ 2605: *((tme_uint32_t *) _op1) = res; 2606: 2607: /* set the flags: */ 2608: flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 2609: if (res == 0) flags |= TME_M68K_FLAG_Z; 2610: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 2611: ic->tme_m68k_ireg_ccr = flags; 2612: 2613: TME_M68K_INSN_OK; 2614: } 2615: 2616: /* this does a 32-bit "clr DST": */ 2617: TME_M68K_INSN(tme_m68k_clr32) 2618: { 2619: tme_uint32_t res; 2620: tme_uint8_t flags; 2621: 2622: /* load the operand(s): */ 2623: 2624: /* perform the operation: */ 2625: res = 0; 2626: 2627: /* store the result: */ 2628: *((tme_uint32_t *) _op1) = res; 2629: 2630: /* set the flags: */ 2631: flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 2632: if (res == 0) flags |= TME_M68K_FLAG_Z; 2633: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 2634: ic->tme_m68k_ireg_ccr = flags; 2635: 2636: TME_M68K_INSN_OK; 2637: } 2638: 2639: /* this does a 32-bit "negx DST": */ 2640: TME_M68K_INSN(tme_m68k_negx32) 2641: { 2642: tme_uint32_t res, op1; 2643: tme_uint8_t flags; 2644: 2645: /* load the operand(s): */ 2646: op1 = *((tme_uint32_t *) _op1); 2647: 2648: /* perform the operation: */ 2649: res = 0 - op1 - ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1); 2650: 2651: /* store the result: */ 2652: *((tme_uint32_t *) _op1) = res; 2653: 2654: /* set the flags: */ 2655: flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 2656: if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z); 2657: flags |= ((tme_uint8_t) (((op1 ^ 0) & (0 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V; 2658: if (op1 > 0 || (op1 == 0 && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X; 2659: ic->tme_m68k_ireg_ccr = flags; 2660: 2661: TME_M68K_INSN_OK; 2662: } 2663: 2664: /* this does a 32-bit "addx SRC, DST": */ 2665: TME_M68K_INSN(tme_m68k_addx32) 2666: { 2667: tme_uint32_t res, op0, op1; 2668: tme_uint8_t flags; 2669: 2670: /* load the operand(s): */ 2671: unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic); 2672: int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3); 2673: int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3); 2674: tme_uint32_t ireg_src_adjust = sizeof(tme_uint32_t); 2675: tme_uint32_t ireg_dst_adjust = sizeof(tme_uint32_t); 2676: tme_uint16_t memory; 2677: 2678: memory = (TME_M68K_INSN_OPCODE & TME_BIT(3)); 2679: if (memory) { 2680: TME_M68K_INSN_CANFAULT; 2681: if (!TME_M68K_SEQUENCE_RESTARTING) { 2682: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) -= ireg_dst_adjust; 2683: ic->_tme_m68k_ea_function_code = function_code; 2684: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst); 2685: } 2686: tme_m68k_read_memx32(ic); 2687: if (!TME_M68K_SEQUENCE_RESTARTING) { 2688: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) -= ireg_src_adjust; 2689: ic->_tme_m68k_ea_function_code = function_code; 2690: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src); 2691: } 2692: tme_m68k_read_mem32(ic, TME_M68K_IREG_MEMY32); 2693: op1 = ic->tme_m68k_ireg_memx32; 2694: op0 = ic->tme_m68k_ireg_memy32; 2695: } 2696: else { 2697: op0 = ic->tme_m68k_ireg_uint32((TME_M68K_IREG_D0 + ireg_src)); 2698: op1 = ic->tme_m68k_ireg_uint32((TME_M68K_IREG_D0 + ireg_dst)); 2699: } 2700: 2701: /* perform the operation: */ 2702: res = op1 + op0 + ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1); 2703: 2704: /* store the result: */ 2705: if (memory) { 2706: if (!TME_M68K_SEQUENCE_RESTARTING) { 2707: ic->tme_m68k_ireg_memx32 = res; 2708: ic->_tme_m68k_ea_function_code = function_code; 2709: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst); 2710: } 2711: tme_m68k_write_memx32(ic); 2712: } 2713: else { 2714: ic->tme_m68k_ireg_uint32((TME_M68K_IREG_D0 + ireg_dst)) = res; 2715: } 2716: 2717: /* set the flags: */ 2718: flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 2719: if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z); 2720: flags |= ((tme_uint8_t) (((op0 ^ op1 ^ 0xffffffff) & (op1 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V; 2721: if (op0 > (op1 ^ 0xffffffff) || (op0 == (op1 ^ 0xffffffff) && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X; 2722: ic->tme_m68k_ireg_ccr = flags; 2723: 2724: TME_M68K_INSN_OK; 2725: } 2726: 2727: /* this does a 32-bit "subx SRC, DST": */ 2728: TME_M68K_INSN(tme_m68k_subx32) 2729: { 2730: tme_uint32_t res, op0, op1; 2731: tme_uint8_t flags; 2732: 2733: /* load the operand(s): */ 2734: unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic); 2735: int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3); 2736: int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3); 2737: tme_uint32_t ireg_src_adjust = sizeof(tme_uint32_t); 2738: tme_uint32_t ireg_dst_adjust = sizeof(tme_uint32_t); 2739: tme_uint16_t memory; 2740: 2741: memory = (TME_M68K_INSN_OPCODE & TME_BIT(3)); 2742: if (memory) { 2743: TME_M68K_INSN_CANFAULT; 2744: if (!TME_M68K_SEQUENCE_RESTARTING) { 2745: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) -= ireg_dst_adjust; 2746: ic->_tme_m68k_ea_function_code = function_code; 2747: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst); 2748: } 2749: tme_m68k_read_memx32(ic); 2750: if (!TME_M68K_SEQUENCE_RESTARTING) { 2751: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) -= ireg_src_adjust; 2752: ic->_tme_m68k_ea_function_code = function_code; 2753: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src); 2754: } 2755: tme_m68k_read_mem32(ic, TME_M68K_IREG_MEMY32); 2756: op1 = ic->tme_m68k_ireg_memx32; 2757: op0 = ic->tme_m68k_ireg_memy32; 2758: } 2759: else { 2760: op0 = ic->tme_m68k_ireg_uint32((TME_M68K_IREG_D0 + ireg_src)); 2761: op1 = ic->tme_m68k_ireg_uint32((TME_M68K_IREG_D0 + ireg_dst)); 2762: } 2763: 2764: /* perform the operation: */ 2765: res = op1 - op0 - ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1); 2766: 2767: /* store the result: */ 2768: if (memory) { 2769: if (!TME_M68K_SEQUENCE_RESTARTING) { 2770: ic->tme_m68k_ireg_memx32 = res; 2771: ic->_tme_m68k_ea_function_code = function_code; 2772: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst); 2773: } 2774: tme_m68k_write_memx32(ic); 2775: } 2776: else { 2777: ic->tme_m68k_ireg_uint32((TME_M68K_IREG_D0 + ireg_dst)) = res; 2778: } 2779: 2780: /* set the flags: */ 2781: flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 2782: if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z); 2783: flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V; 2784: if (op0 > op1 || (op0 == op1 && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X; 2785: ic->tme_m68k_ireg_ccr = flags; 2786: 2787: TME_M68K_INSN_OK; 2788: } 2789: 2790: /* this does a 32-bit "cmpm SRC, DST": */ 2791: TME_M68K_INSN(tme_m68k_cmpm32) 2792: { 2793: tme_uint32_t res, op0, op1; 2794: tme_uint8_t flags; 2795: 2796: /* load the operand(s): */ 2797: unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic); 2798: int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3); 2799: int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3); 2800: tme_uint32_t ireg_src_adjust = sizeof(tme_uint32_t); 2801: tme_uint32_t ireg_dst_adjust = sizeof(tme_uint32_t); 2802: 2803: TME_M68K_INSN_CANFAULT; 2804: 2805: if (!TME_M68K_SEQUENCE_RESTARTING) { 2806: ic->_tme_m68k_ea_function_code = function_code; 2807: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst); 2808: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) += ireg_dst_adjust; 2809: } 2810: tme_m68k_read_memx32(ic); 2811: if (!TME_M68K_SEQUENCE_RESTARTING) { 2812: ic->_tme_m68k_ea_function_code = function_code; 2813: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src); 2814: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) += ireg_src_adjust; 2815: } 2816: tme_m68k_read_mem32(ic, TME_M68K_IREG_MEMY32); 2817: op1 = ic->tme_m68k_ireg_memx32; 2818: op0 = ic->tme_m68k_ireg_memy32; 2819: 2820: /* perform the operation: */ 2821: res = op1 - op0; 2822: 2823: /* set the flags: */ 2824: flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 2825: if (res == 0) flags |= TME_M68K_FLAG_Z; 2826: flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V; 2827: if (op0 > op1) flags |= TME_M68K_FLAG_C; 2828: flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X); 2829: ic->tme_m68k_ireg_ccr = flags; 2830: 2831: TME_M68K_INSN_OK; 2832: } 2833: 2834: /* the suba function on a 32-byte EA: */ 2835: TME_M68K_INSN(tme_m68k_suba32) 2836: { 2837: *((tme_int32_t *) _op1) -= *((tme_int32_t *) _op0); 2838: TME_M68K_INSN_OK; 2839: } 2840: 2841: /* the adda function on a 32-byte EA: */ 2842: TME_M68K_INSN(tme_m68k_adda32) 2843: { 2844: *((tme_int32_t *) _op1) += *((tme_int32_t *) _op0); 2845: TME_M68K_INSN_OK; 2846: } 2847: 2848: /* the movea function on a 32-byte EA: */ 2849: TME_M68K_INSN(tme_m68k_movea32) 2850: { 2851: *((tme_int32_t *) _op0) = *((tme_int32_t *) _op1); 2852: TME_M68K_INSN_OK; 2853: } 2854: 2855: /* the btst function on a 32-byte EA: */ 2856: TME_M68K_INSN(tme_m68k_btst32) 2857: { 2858: tme_uint32_t value, bit; 2859: bit = _TME_BIT(tme_uint32_t, TME_M68K_INSN_OP0(tme_uint8_t) & (32 - 1)); 2860: value = TME_M68K_INSN_OP1(tme_uint32_t); 2861: if (value & bit) { 2862: ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z; 2863: } 2864: else { 2865: ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z; 2866: } 2867: TME_M68K_INSN_OK; 2868: } 2869: 2870: /* the bchg function on a 32-byte EA: */ 2871: TME_M68K_INSN(tme_m68k_bchg32) 2872: { 2873: tme_uint32_t value, bit; 2874: bit = _TME_BIT(tme_uint32_t, TME_M68K_INSN_OP0(tme_uint8_t) & (32 - 1)); 2875: value = TME_M68K_INSN_OP1(tme_uint32_t); 2876: if (value & bit) { 2877: ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z; 2878: } 2879: else { 2880: ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z; 2881: } 2882: TME_M68K_INSN_OP1(tme_uint32_t) = value ^ bit; 2883: TME_M68K_INSN_OK; 2884: } 2885: 2886: /* the bclr function on a 32-byte EA: */ 2887: TME_M68K_INSN(tme_m68k_bclr32) 2888: { 2889: tme_uint32_t value, bit; 2890: bit = _TME_BIT(tme_uint32_t, TME_M68K_INSN_OP0(tme_uint8_t) & (32 - 1)); 2891: value = TME_M68K_INSN_OP1(tme_uint32_t); 2892: if (value & bit) { 2893: ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z; 2894: } 2895: else { 2896: ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z; 2897: } 2898: TME_M68K_INSN_OP1(tme_uint32_t) = value & ~bit; 2899: TME_M68K_INSN_OK; 2900: } 2901: 2902: /* the bset function on a 32-byte EA: */ 2903: TME_M68K_INSN(tme_m68k_bset32) 2904: { 2905: tme_uint32_t value, bit; 2906: bit = _TME_BIT(tme_uint32_t, TME_M68K_INSN_OP0(tme_uint8_t) & (32 - 1)); 2907: value = TME_M68K_INSN_OP1(tme_uint32_t); 2908: if (value & bit) { 2909: ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z; 2910: } 2911: else { 2912: ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z; 2913: } 2914: TME_M68K_INSN_OP1(tme_uint32_t) = value | bit; 2915: TME_M68K_INSN_OK; 2916: } 2917: 2918: /* the asl function on a 32-byte EA: */ 2919: TME_M68K_INSN(tme_m68k_asl32) 2920: { 2921: unsigned int count; 1.1.1.2 root 2922: tme_uint32_t sign_bits, sign_bits_mask; 1.1 root 2923: tme_uint32_t res; 2924: tme_uint8_t flags; 2925: 2926: /* get the count and operand: */ 2927: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 2928: res = TME_M68K_INSN_OP1(tme_uint32_t); 2929: 2930: /* generate the X, V, and C flags assuming the count is zero: */ 2931: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 2932: 2933: /* if the count is nonzero, update the result and 2934: generate the X, V, and C flags: */ 2935: if (count > 0) { 2936: 2937: /* we need to see how the sign of the result will change during 2938: shifting in order to generate V. 2939: 2940: in general, the idea is to get all of the bits that will ever 1.1.1.2 root 2941: appear in the sign position into sign_bits, with a mask in 2942: sign_bits_mask. if (sign_bits & sign_bits_mask) is zero or 2943: sign_bits_mask, clear V, else set V. 1.1 root 2944: 1.1.1.2 root 2945: start by loading the operand into sign_bits and setting 2946: sign_bits_mask to all-bits-one. 1.1 root 2947: 2948: if the shift count is exactly 32 - 1, then all of the bits 2949: of the operand will appear in the sign position. 2950: 2951: if the shift count is less than 32 - 1, then some of the 2952: less significant bits of the operand will never appear in the 1.1.1.2 root 2953: sign position, so we can shift sign_bits_mask to ignore them. 1.1 root 2954: 2955: if the shift count is greater than 32 - 1, then all of the 2956: bits in the operand, plus at least one zero bit, will appear in 2957: the sign position. the only way that the sign bit will never 2958: change during the shift is if the operand was zero to begin with. 1.1.1.2 root 2959: without any changes to sign_bits or sign_bits_mask, the final 2960: test will always work, except when sign_bits is all-bits-one. 2961: the magic below clears the least-significant bit of sign_bits 2962: iff sign_bits is all-bits-one: */ 1.1 root 2963: sign_bits = res; 2964: if (63 > SHIFTMAX_INT32_T 2965: && count > 32) { 2966: res = 0; 2967: } 2968: res <<= (count - 1); 2969: flags = (res >> (32 - 1)); 2970: flags *= TME_M68K_FLAG_C; 2971: flags |= (flags * TME_M68K_FLAG_X); 2972: res <<= 1; 1.1.1.2 root 2973: sign_bits_mask = (tme_uint32_t) -1; 1.1 root 2974: if (count != 32 - 1) { 2975: if (count < 32) { 1.1.1.2 root 2976: sign_bits_mask <<= ((32 - 1) - count); 1.1 root 2977: } 2978: else { 1.1.1.2 root 2979: sign_bits ^= !(sign_bits + 1); 1.1 root 2980: } 2981: } 1.1.1.2 root 2982: sign_bits &= sign_bits_mask; 2983: if (sign_bits != 0 && sign_bits != sign_bits_mask) { 1.1 root 2984: flags |= TME_M68K_FLAG_V; 2985: } 2986: } 2987: 2988: /* store the result: */ 2989: TME_M68K_INSN_OP1(tme_uint32_t) = res; 2990: 2991: /* generate the N flag. we cast to tme_uint8_t as soon as we 2992: know the bit we want is within the range of the type, to try 2993: to affect the generated assembly: */ 2994: flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 2995: 2996: /* generate the Z flag: */ 2997: if (res == 0) flags |= TME_M68K_FLAG_Z; 2998: 2999: /* store the flags: */ 3000: ic->tme_m68k_ireg_ccr = flags; 3001: TME_M68K_INSN_OK; 3002: } 3003: 3004: /* the asr function on a 32-byte EA: */ 3005: TME_M68K_INSN(tme_m68k_asr32) 3006: { 3007: unsigned int count; 3008: tme_int32_t res; 3009: tme_uint8_t flags; 3010: 3011: /* get the count and operand: */ 3012: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 3013: res = TME_M68K_INSN_OP1(tme_int32_t); 3014: 3015: /* generate the X, V, and C flags assuming the count is zero: */ 3016: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 3017: 3018: /* if the count is nonzero, update the result and 3019: generate the X, V, and C flags: */ 3020: if (count > 0) { 3021: if (63 > SHIFTMAX_INT32_T 3022: && count > 32) { 1.1.1.3 ! root 3023: res = 0 - (res < 0); 1.1 root 3024: } 1.1.1.3 ! root 3025: #ifdef SHIFTSIGNED_INT32_T 1.1 root 3026: res >>= (count - 1); 1.1.1.3 ! root 3027: #else /* !SHIFTSIGNED_INT32_T */ ! 3028: for (; --count > 0; ) { ! 3029: res = (res & ~((tme_int32_t) 1)) / 2; ! 3030: } ! 3031: #endif /* !SHIFTSIGNED_INT32_T */ 1.1 root 3032: flags = (res & 1); 3033: flags *= TME_M68K_FLAG_C; 3034: flags |= (flags * TME_M68K_FLAG_X); 1.1.1.3 ! root 3035: #ifdef SHIFTSIGNED_INT32_T 1.1 root 3036: res >>= 1; 1.1.1.3 ! root 3037: #else /* !SHIFTSIGNED_INT32_T */ ! 3038: res = (res & ~((tme_int32_t) 1)) / 2; ! 3039: #endif /* !SHIFTSIGNED_INT32_T */ 1.1 root 3040: } 3041: 3042: /* store the result: */ 3043: TME_M68K_INSN_OP1(tme_int32_t) = res; 3044: 3045: /* generate the N flag. we cast to tme_uint8_t as soon as we 3046: know the bit we want is within the range of the type, to try 3047: to affect the generated assembly: */ 3048: flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 3049: 3050: /* generate the Z flag: */ 3051: if (res == 0) flags |= TME_M68K_FLAG_Z; 3052: 3053: /* store the flags: */ 3054: ic->tme_m68k_ireg_ccr = flags; 3055: TME_M68K_INSN_OK; 3056: } 3057: 3058: /* the lsl function on a 32-byte EA: */ 3059: TME_M68K_INSN(tme_m68k_lsl32) 3060: { 3061: unsigned int count; 3062: tme_uint32_t res; 3063: tme_uint8_t flags; 3064: 3065: /* get the count and operand: */ 3066: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 3067: res = TME_M68K_INSN_OP1(tme_uint32_t); 3068: 3069: /* generate the X, V, and C flags assuming the count is zero: */ 3070: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 3071: 3072: /* if the count is nonzero, update the result and 3073: generate the X, V, and C flags: */ 3074: if (count > 0) { 3075: if (63 > SHIFTMAX_INT32_T 3076: && count > 32) { 3077: res = 0; 3078: } 3079: res <<= (count - 1); 3080: flags = (res >> (32 - 1)); 3081: flags *= TME_M68K_FLAG_C; 3082: flags |= (flags * TME_M68K_FLAG_X); 3083: res <<= 1; 3084: } 3085: 3086: /* store the result: */ 3087: TME_M68K_INSN_OP1(tme_uint32_t) = res; 3088: 3089: /* generate the N flag. we cast to tme_uint8_t as soon as we 3090: know the bit we want is within the range of the type, to try 3091: to affect the generated assembly: */ 3092: flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 3093: 3094: /* generate the Z flag: */ 3095: if (res == 0) flags |= TME_M68K_FLAG_Z; 3096: 3097: /* store the flags: */ 3098: ic->tme_m68k_ireg_ccr = flags; 3099: TME_M68K_INSN_OK; 3100: } 3101: 3102: /* the lsr function on a 32-byte EA: */ 3103: TME_M68K_INSN(tme_m68k_lsr32) 3104: { 3105: unsigned int count; 3106: tme_uint32_t res; 3107: tme_uint8_t flags; 3108: 3109: /* get the count and operand: */ 3110: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 3111: res = TME_M68K_INSN_OP1(tme_uint32_t); 3112: 3113: /* generate the X, V, and C flags assuming the count is zero: */ 3114: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 3115: 3116: /* if the count is nonzero, update the result and 3117: generate the X, V, and C flags: */ 3118: if (count > 0) { 3119: if (63 > SHIFTMAX_INT32_T 3120: && count > 32) { 3121: res = 0; 3122: } 3123: res >>= (count - 1); 3124: flags = (res & 1); 3125: flags *= TME_M68K_FLAG_C; 3126: flags |= (flags * TME_M68K_FLAG_X); 3127: res >>= 1; 3128: } 3129: 3130: /* store the result: */ 3131: TME_M68K_INSN_OP1(tme_uint32_t) = res; 3132: 3133: /* generate the N flag. we cast to tme_uint8_t as soon as we 3134: know the bit we want is within the range of the type, to try 3135: to affect the generated assembly: */ 3136: flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 3137: 3138: /* generate the Z flag: */ 3139: if (res == 0) flags |= TME_M68K_FLAG_Z; 3140: 3141: /* store the flags: */ 3142: ic->tme_m68k_ireg_ccr = flags; 3143: TME_M68K_INSN_OK; 3144: } 3145: 3146: /* the rol function on a 32-byte EA: */ 3147: TME_M68K_INSN(tme_m68k_rol32) 3148: { 3149: unsigned int count; 3150: tme_uint32_t res; 3151: tme_uint8_t flags; 3152: 3153: /* get the count and operand: */ 3154: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 3155: res = TME_M68K_INSN_OP1(tme_uint32_t); 3156: 3157: /* generate the X, V, and C flags assuming the count is zero: */ 3158: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 3159: 3160: /* if the count is nonzero, update the result and 3161: generate the X, V, and C flags: */ 3162: if (count > 0) { 3163: count &= (32 - 1); 3164: res = (res << count) | (res >> (32 - count)); 3165: flags |= ((res & 1) * TME_M68K_FLAG_C); 3166: } 3167: 3168: /* store the result: */ 3169: TME_M68K_INSN_OP1(tme_uint32_t) = res; 3170: 3171: /* generate the N flag. we cast to tme_uint8_t as soon as we 3172: know the bit we want is within the range of the type, to try 3173: to affect the generated assembly: */ 3174: flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 3175: 3176: /* generate the Z flag: */ 3177: if (res == 0) flags |= TME_M68K_FLAG_Z; 3178: 3179: /* store the flags: */ 3180: ic->tme_m68k_ireg_ccr = flags; 3181: TME_M68K_INSN_OK; 3182: } 3183: 3184: /* the ror function on a 32-byte EA: */ 3185: TME_M68K_INSN(tme_m68k_ror32) 3186: { 3187: unsigned int count; 3188: tme_uint32_t res; 3189: tme_uint8_t flags; 3190: 3191: /* get the count and operand: */ 3192: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 3193: res = TME_M68K_INSN_OP1(tme_uint32_t); 3194: 3195: /* generate the X, V, and C flags assuming the count is zero: */ 3196: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 3197: 3198: /* if the count is nonzero, update the result and 3199: generate the X, V, and C flags: */ 3200: if (count > 0) { 3201: count &= (32 - 1); 3202: res = (res << (32 - count)) | (res >> count); 3203: flags |= ((res >> (32 - 1)) * TME_M68K_FLAG_C); 3204: } 3205: 3206: /* store the result: */ 3207: TME_M68K_INSN_OP1(tme_uint32_t) = res; 3208: 3209: /* generate the N flag. we cast to tme_uint8_t as soon as we 3210: know the bit we want is within the range of the type, to try 3211: to affect the generated assembly: */ 3212: flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 3213: 3214: /* generate the Z flag: */ 3215: if (res == 0) flags |= TME_M68K_FLAG_Z; 3216: 3217: /* store the flags: */ 3218: ic->tme_m68k_ireg_ccr = flags; 3219: TME_M68K_INSN_OK; 3220: } 3221: 3222: /* the roxl function on a 32-byte EA: */ 3223: TME_M68K_INSN(tme_m68k_roxl32) 3224: { 3225: unsigned int count; 3226: tme_uint8_t xbit; 3227: tme_uint32_t res; 3228: tme_uint8_t flags; 3229: 3230: /* get the count and operand: */ 3231: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 3232: res = TME_M68K_INSN_OP1(tme_uint32_t); 3233: 3234: /* generate the X, V, and C flags assuming the count is zero: */ 3235: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 3236: xbit = (flags / TME_M68K_FLAG_X); 3237: flags |= (xbit * TME_M68K_FLAG_C); 3238: 3239: /* if the count is nonzero, update the result and 3240: generate the X, V, and C flags: */ 3241: if (count > 0) { 3242: count %= (32 + 1); 3243: flags = xbit; 3244: if (count > 0) { 3245: flags = (res >> (32 - count)) & 1; 3246: if (32 > SHIFTMAX_INT32_T 3247: && count == 32) { 3248: res = 0 | (xbit << (32 - 1)) | (res >> ((32 + 1) - 32)); 3249: } 3250: else if (32 > SHIFTMAX_INT32_T 3251: && count == 1) { 3252: res = (res << 1) | (xbit << (1 - 1)) | 0; 3253: } 3254: else { 3255: res = (res << count) | (xbit << (count - 1)) | (res >> ((32 + 1) - count)); 3256: } 3257: } 3258: flags *= TME_M68K_FLAG_C; 3259: flags |= (flags * TME_M68K_FLAG_X); 3260: } 3261: 3262: /* store the result: */ 3263: TME_M68K_INSN_OP1(tme_uint32_t) = res; 3264: 3265: /* generate the N flag. we cast to tme_uint8_t as soon as we 3266: know the bit we want is within the range of the type, to try 3267: to affect the generated assembly: */ 3268: flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 3269: 3270: /* generate the Z flag: */ 3271: if (res == 0) flags |= TME_M68K_FLAG_Z; 3272: 3273: /* store the flags: */ 3274: ic->tme_m68k_ireg_ccr = flags; 3275: TME_M68K_INSN_OK; 3276: } 3277: 3278: /* the roxr function on a 32-byte EA: */ 3279: TME_M68K_INSN(tme_m68k_roxr32) 3280: { 3281: unsigned int count; 3282: tme_uint8_t xbit; 3283: tme_uint32_t res; 3284: tme_uint8_t flags; 3285: 3286: /* get the count and operand: */ 3287: count = TME_M68K_INSN_OP0(tme_uint8_t) & 63; 3288: res = TME_M68K_INSN_OP1(tme_uint32_t); 3289: 3290: /* generate the X, V, and C flags assuming the count is zero: */ 3291: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 3292: xbit = (flags / TME_M68K_FLAG_X); 3293: flags |= (xbit * TME_M68K_FLAG_C); 3294: 3295: /* if the count is nonzero, update the result and 3296: generate the X, V, and C flags: */ 3297: if (count > 0) { 3298: count %= (32 + 1); 3299: flags = xbit; 3300: if (count > 0) { 3301: flags = (res >> (count - 1)) & 1; 3302: if (32 > SHIFTMAX_INT32_T 3303: && count == 32) { 3304: res = (res << ((32 + 1) - 32)) | (xbit << (32 - 32)) | 0; 3305: } 3306: else if (32 > SHIFTMAX_INT32_T 3307: && count == 1) { 3308: res = 0 | (xbit << (32 - 1)) | (res >> 1); 3309: } 3310: else { 3311: res = (res << ((32 + 1) - count)) | (xbit << (32 - count)) | (res >> count); 3312: } 3313: } 3314: flags *= TME_M68K_FLAG_C; 3315: flags |= (flags * TME_M68K_FLAG_X); 3316: } 3317: 3318: /* store the result: */ 3319: TME_M68K_INSN_OP1(tme_uint32_t) = res; 3320: 3321: /* generate the N flag. we cast to tme_uint8_t as soon as we 3322: know the bit we want is within the range of the type, to try 3323: to affect the generated assembly: */ 3324: flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N; 3325: 3326: /* generate the Z flag: */ 3327: if (res == 0) flags |= TME_M68K_FLAG_Z; 3328: 3329: /* store the flags: */ 3330: ic->tme_m68k_ireg_ccr = flags; 3331: TME_M68K_INSN_OK; 3332: } 3333: 3334: /* the movep_rm function on a 32-bit dreg: */ 3335: TME_M68K_INSN(tme_m68k_movep_rm32) 3336: { 3337: unsigned int function_code; 3338: tme_uint32_t linear_address; 3339: tme_uint32_t value; 3340: int dreg; 3341: 3342: TME_M68K_INSN_CANFAULT; 3343: 3344: function_code = TME_M68K_FUNCTION_CODE_DATA(ic); 3345: linear_address = TME_M68K_INSN_OP1(tme_uint32_t); 3346: linear_address += (tme_int32_t) ((tme_int16_t) TME_M68K_INSN_SPECOP); 3347: dreg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3); 3348: value = ic->tme_m68k_ireg_uint32(dreg); 3349: if (!TME_M68K_SEQUENCE_RESTARTING) { 3350: ic->_tme_m68k_ea_function_code = function_code; 3351: ic->_tme_m68k_ea_address = linear_address; 3352: ic->tme_m68k_ireg_memx8 = TME_FIELD_EXTRACTU(value, 24, 8); 3353: } 3354: tme_m68k_write_memx8(ic); 3355: linear_address += 2; 3356: if (!TME_M68K_SEQUENCE_RESTARTING) { 3357: ic->_tme_m68k_ea_function_code = function_code; 3358: ic->_tme_m68k_ea_address = linear_address; 3359: ic->tme_m68k_ireg_memx8 = TME_FIELD_EXTRACTU(value, 16, 8); 3360: } 3361: tme_m68k_write_memx8(ic); 3362: linear_address += 2; 3363: if (!TME_M68K_SEQUENCE_RESTARTING) { 3364: ic->_tme_m68k_ea_function_code = function_code; 3365: ic->_tme_m68k_ea_address = linear_address; 3366: ic->tme_m68k_ireg_memx8 = TME_FIELD_EXTRACTU(value, 8, 8); 3367: } 3368: tme_m68k_write_memx8(ic); 3369: linear_address += 2; 3370: if (!TME_M68K_SEQUENCE_RESTARTING) { 3371: ic->_tme_m68k_ea_function_code = function_code; 3372: ic->_tme_m68k_ea_address = linear_address; 3373: ic->tme_m68k_ireg_memx8 = TME_FIELD_EXTRACTU(value, 0, 8); 3374: } 3375: tme_m68k_write_memx8(ic); 3376: linear_address += 2; 3377: TME_M68K_INSN_OK; 3378: } 3379: 3380: /* the movem_rm function on 32-bit registers: */ 3381: TME_M68K_INSN(tme_m68k_movem_rm32) 3382: { 3383: int ireg, direction; 3384: tme_uint16_t mask, bit; 3385: unsigned int ea_mode; 3386: tme_uint32_t addend; 3387: 3388: /* figure out what direction to move in, and where to start from: */ 3389: ea_mode = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 3, 3); 3390: direction = 1; 3391: ireg = TME_M68K_IREG_D0; 3392: if (ea_mode == 4) { 3393: direction = -1; 3394: ireg = TME_M68K_IREG_A7; 3395: if (!TME_M68K_SEQUENCE_RESTARTING) { 3396: ic->_tme_m68k_ea_address -= sizeof(tme_uint32_t); 3397: } 3398: } 3399: addend = (tme_uint32_t) (direction * sizeof(tme_uint32_t)); 3400: 3401: /* do the transfer: */ 3402: mask = TME_M68K_INSN_SPECOP; 1.1.1.2 root 3403: if (mask != 0) { 3404: TME_M68K_INSN_CANFAULT; 3405: } 1.1 root 3406: for (bit = 1; bit != 0; bit <<= 1) { 3407: if (mask & bit) { 3408: if (!TME_M68K_SEQUENCE_RESTARTING) { 3409: ic->tme_m68k_ireg_memx32 = ic->tme_m68k_ireg_uint32(ireg); 3410: } 3411: tme_m68k_write_memx32(ic); 3412: if (!TME_M68K_SEQUENCE_RESTARTING) { 3413: ic->_tme_m68k_ea_address += addend; 3414: } 3415: } 3416: ireg += direction; 3417: } 3418: 3419: /* if this is the predecrement mode, update the address register: */ 3420: if (ea_mode == 4) { 3421: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 3422: + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3)) 3423: = (ic->_tme_m68k_ea_address + sizeof(tme_uint32_t)); 3424: } 3425: TME_M68K_INSN_OK; 3426: } 3427: 3428: /* the movep_mr function on a 32-bit dreg: */ 3429: TME_M68K_INSN(tme_m68k_movep_mr32) 3430: { 3431: unsigned int function_code; 3432: tme_uint32_t linear_address; 3433: int dreg; 3434: 3435: TME_M68K_INSN_CANFAULT; 3436: 3437: function_code = TME_M68K_FUNCTION_CODE_DATA(ic); 3438: linear_address = TME_M68K_INSN_OP1(tme_uint32_t); 3439: linear_address += (tme_int32_t) ((tme_int16_t) TME_M68K_INSN_SPECOP); 3440: dreg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3); 3441: if (!TME_M68K_SEQUENCE_RESTARTING) { 3442: ic->_tme_m68k_ea_function_code = function_code; 3443: ic->_tme_m68k_ea_address = linear_address; 3444: } 3445: tme_m68k_read_memx8(ic); 3446: if (!TME_M68K_SEQUENCE_RESTARTING) { 3447: TME_FIELD_DEPOSIT32(ic->tme_m68k_ireg_uint32(dreg), 24, 8, ic->tme_m68k_ireg_memx8); 3448: } 3449: linear_address += 2; 3450: if (!TME_M68K_SEQUENCE_RESTARTING) { 3451: ic->_tme_m68k_ea_function_code = function_code; 3452: ic->_tme_m68k_ea_address = linear_address; 3453: } 3454: tme_m68k_read_memx8(ic); 3455: if (!TME_M68K_SEQUENCE_RESTARTING) { 3456: TME_FIELD_DEPOSIT32(ic->tme_m68k_ireg_uint32(dreg), 16, 8, ic->tme_m68k_ireg_memx8); 3457: } 3458: linear_address += 2; 3459: if (!TME_M68K_SEQUENCE_RESTARTING) { 3460: ic->_tme_m68k_ea_function_code = function_code; 3461: ic->_tme_m68k_ea_address = linear_address; 3462: } 3463: tme_m68k_read_memx8(ic); 3464: if (!TME_M68K_SEQUENCE_RESTARTING) { 3465: TME_FIELD_DEPOSIT32(ic->tme_m68k_ireg_uint32(dreg), 8, 8, ic->tme_m68k_ireg_memx8); 3466: } 3467: linear_address += 2; 3468: if (!TME_M68K_SEQUENCE_RESTARTING) { 3469: ic->_tme_m68k_ea_function_code = function_code; 3470: ic->_tme_m68k_ea_address = linear_address; 3471: } 3472: tme_m68k_read_memx8(ic); 3473: if (!TME_M68K_SEQUENCE_RESTARTING) { 3474: TME_FIELD_DEPOSIT32(ic->tme_m68k_ireg_uint32(dreg), 0, 8, ic->tme_m68k_ireg_memx8); 3475: } 3476: linear_address += 2; 3477: TME_M68K_INSN_OK; 3478: } 3479: 3480: /* the movem_mr function on 32-bit registers: */ 3481: TME_M68K_INSN(tme_m68k_movem_mr32) 3482: { 3483: int ireg, direction; 3484: tme_uint16_t mask, bit; 3485: unsigned int ea_mode; 3486: tme_uint32_t addend; 3487: 3488: /* figure out what direction to move in, and where to start from: */ 3489: ea_mode = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 3, 3); 3490: direction = 1; 3491: ireg = TME_M68K_IREG_D0; 3492: addend = (tme_uint32_t) (direction * sizeof(tme_uint32_t)); 3493: 3494: /* do the transfer: */ 3495: mask = TME_M68K_INSN_SPECOP; 1.1.1.2 root 3496: if (mask != 0) { 3497: TME_M68K_INSN_CANFAULT; 3498: } 1.1 root 3499: for (bit = 1; bit != 0; bit <<= 1) { 3500: if (mask & bit) { 3501: tme_m68k_read_memx32(ic); 3502: if (!TME_M68K_SEQUENCE_RESTARTING) { 3503: ic->tme_m68k_ireg_uint32(ireg) = ic->tme_m68k_ireg_memx32; 3504: ic->_tme_m68k_ea_address += addend; 3505: } 3506: } 3507: ireg += direction; 3508: } 3509: 3510: /* if this is the postincrement mode, update the address register: */ 3511: if (ea_mode == 3) { 3512: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 3513: + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3)) 3514: = ic->_tme_m68k_ea_address; 3515: } 3516: TME_M68K_INSN_OK; 3517: } 3518: 3519: /* chk32: */ 3520: TME_M68K_INSN(tme_m68k_chk32) 3521: { 3522: if (*((tme_int32_t *) _op0) < 0) { 3523: ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_N; 1.1.1.3 ! root 3524: ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc; 1.1 root 3525: ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next; 1.1.1.3 ! root 3526: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_CHK)); 1.1 root 3527: } 3528: if (*((tme_int32_t *) _op0) > *((tme_int32_t *) _op1)) { 3529: ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_N; 1.1.1.3 ! root 3530: ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc; 1.1 root 3531: ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next; 1.1.1.3 ! root 3532: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_CHK)); 1.1 root 3533: } 3534: TME_M68K_INSN_OK; 3535: } 3536: 3537: /* cas32: */ 3538: TME_M68K_INSN(tme_m68k_cas32) 3539: { 3540: struct tme_m68k_tlb *tlb; 3541: int ireg_dc, ireg_du; 3542: int do_write; 3543: tme_uint16_t specopx = ic->_tme_m68k_insn_specop; 3544: 3545: /* start the read/modify/write cycle: */ 3546: tlb = tme_m68k_rmw_start(ic); 3547: if (tlb == NULL) { 3548: TME_M68K_INSN_OK; 3549: } 3550: 3551: /* read: */ 3552: tme_m68k_read32(ic, tlb, 3553: &ic->_tme_m68k_ea_function_code, 3554: &ic->_tme_m68k_ea_address, 3555: &ic->tme_m68k_ireg_memx32, 3556: TME_M68K_BUS_CYCLE_RMW); 3557: 3558: /* modify: */ 3559: ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 0, 3); 3560: tme_m68k_cmp32(ic, &ic->tme_m68k_ireg_uint32(ireg_dc), &ic->tme_m68k_ireg_memx32); 3561: 3562: /* write: */ 3563: if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) { 3564: ireg_du = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 6, 3); 3565: ic->tme_m68k_ireg_memx32 = ic->tme_m68k_ireg_uint32(ireg_du); 3566: tme_m68k_write32(ic, tlb, 3567: &ic->_tme_m68k_ea_function_code, 3568: &ic->_tme_m68k_ea_address, 3569: &ic->tme_m68k_ireg_memx32, 3570: TME_M68K_BUS_CYCLE_RMW); 3571: } 3572: else { 3573: /* XXX the 68040 always does a write to finish its cycle: */ 3574: do_write = FALSE; 3575: ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 0, 3); 3576: if (do_write) { 3577: tme_m68k_write32(ic, tlb, 3578: &ic->_tme_m68k_ea_function_code, 3579: &ic->_tme_m68k_ea_address, 3580: &ic->tme_m68k_ireg_memx32, 3581: TME_M68K_BUS_CYCLE_RMW); 3582: do_write = FALSE; 3583: } 3584: ic->tme_m68k_ireg_uint32(ireg_dc) = ic->tme_m68k_ireg_memx32; 3585: } 3586: 3587: /* finish the read/modify/write cycle: */ 3588: tme_m68k_rmw_finish(ic, tlb); 3589: 3590: TME_M68K_INSN_OK; 3591: } 3592: 3593: /* cas2_32: */ 3594: TME_M68K_INSN(tme_m68k_cas2_32) 3595: { 3596: struct tme_m68k_tlb *tlb; 3597: int ireg_dc, ireg_du; 3598: int do_write; 3599: tme_uint16_t specopx = ic->_tme_m68k_insn_specop; 1.1.1.3 ! root 3600: tme_uint16_t specopy = TME_M68K_INSN_OP0(tme_uint16_t); 1.1 root 3601: tme_uint32_t addrx; 3602: tme_uint32_t addry; 3603: 3604: /* get the function code and addresses we'll be dealing with: */ 3605: ic->_tme_m68k_ea_function_code = TME_M68K_FUNCTION_CODE_DATA(ic); 3606: addrx = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_D0 3607: + TME_FIELD_EXTRACTU(specopx, 12, 4)); 3608: addry = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_D0 3609: + TME_FIELD_EXTRACTU(specopy, 12, 4)); 3610: 3611: /* start the read/modify/write cycle: */ 3612: tlb = tme_m68k_rmw_start(ic); 3613: if (tlb == NULL) { 3614: TME_M68K_INSN_OK; 3615: } 3616: 3617: /* read: */ 3618: ic->_tme_m68k_ea_address = addrx; 3619: tme_m68k_read32(ic, tlb, 3620: &ic->_tme_m68k_ea_function_code, 3621: &ic->_tme_m68k_ea_address, 3622: &ic->tme_m68k_ireg_memx32, 3623: TME_M68K_BUS_CYCLE_RMW); 3624: ic->_tme_m68k_ea_address = addry; 3625: tme_m68k_read32(ic, tlb, 3626: &ic->_tme_m68k_ea_function_code, 3627: &ic->_tme_m68k_ea_address, 3628: &ic->tme_m68k_ireg_memy32, 3629: TME_M68K_BUS_CYCLE_RMW); 3630: 3631: /* modify: */ 3632: ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 0, 3); 3633: tme_m68k_cmp32(ic, &ic->tme_m68k_ireg_uint32(ireg_dc), &ic->tme_m68k_ireg_memx32); 3634: if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) { 3635: ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopy, 0, 3); 3636: tme_m68k_cmp32(ic, &ic->tme_m68k_ireg_uint32(ireg_dc), &ic->tme_m68k_ireg_memy32); 3637: } 3638: 3639: /* write: */ 3640: if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) { 3641: ic->_tme_m68k_ea_address = addrx; 3642: ireg_du = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 6, 3); 3643: ic->tme_m68k_ireg_memx32 = ic->tme_m68k_ireg_uint32(ireg_du); 3644: tme_m68k_write32(ic, tlb, 3645: &ic->_tme_m68k_ea_function_code, 3646: &ic->_tme_m68k_ea_address, 3647: &ic->tme_m68k_ireg_memx32, 3648: TME_M68K_BUS_CYCLE_RMW); 3649: ic->_tme_m68k_ea_address = addry; 3650: ireg_du = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopy, 6, 3); 3651: ic->tme_m68k_ireg_memy32 = ic->tme_m68k_ireg_uint32(ireg_du); 3652: tme_m68k_write32(ic, tlb, 3653: &ic->_tme_m68k_ea_function_code, 3654: &ic->_tme_m68k_ea_address, 3655: &ic->tme_m68k_ireg_memy32, 3656: TME_M68K_BUS_CYCLE_RMW); 3657: } 3658: else { 3659: /* XXX the 68040 always does a write to finish its cycle: */ 3660: do_write = FALSE; 3661: ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 0, 3); 3662: if (do_write 3663: && ic->tme_m68k_ireg_memx32 != ic->tme_m68k_ireg_uint32(ireg_dc)) { 3664: ic->_tme_m68k_ea_address = addrx; 3665: tme_m68k_write32(ic, tlb, 3666: &ic->_tme_m68k_ea_function_code, 3667: &ic->_tme_m68k_ea_address, 3668: &ic->tme_m68k_ireg_memx32, 3669: TME_M68K_BUS_CYCLE_RMW); 3670: do_write = FALSE; 3671: } 3672: ic->tme_m68k_ireg_uint32(ireg_dc) = ic->tme_m68k_ireg_memx32; 3673: ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopy, 0, 3); 3674: if (do_write 3675: && ic->tme_m68k_ireg_memy32 != ic->tme_m68k_ireg_uint32(ireg_dc)) { 3676: ic->_tme_m68k_ea_address = addry; 3677: tme_m68k_write32(ic, tlb, 3678: &ic->_tme_m68k_ea_function_code, 3679: &ic->_tme_m68k_ea_address, 3680: &ic->tme_m68k_ireg_memy32, 3681: TME_M68K_BUS_CYCLE_RMW); 3682: do_write = FALSE; 3683: } 3684: ic->tme_m68k_ireg_uint32(ireg_dc) = ic->tme_m68k_ireg_memy32; 3685: } 3686: 3687: /* finish the read/modify/write cycle: */ 3688: tme_m68k_rmw_finish(ic, tlb); 3689: 3690: TME_M68K_INSN_OK; 3691: } 3692: 3693: /* moves32: */ 3694: TME_M68K_INSN(tme_m68k_moves32) 3695: { 3696: int ireg; 1.1.1.3 ! root 3697: unsigned int ea_reg; ! 3698: unsigned int increment; ! 3699: TME_M68K_INSN_PRIV; ! 3700: TME_M68K_INSN_CANFAULT; 1.1 root 3701: ireg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 4); 1.1.1.3 ! root 3702: ! 3703: /* we have to handle postincrement and predecrement ourselves: */ ! 3704: if (!TME_M68K_SEQUENCE_RESTARTING) { ! 3705: ea_reg = TME_M68K_IREG_A0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3); ! 3706: increment = TME_M68K_SIZE_32; ! 3707: if (increment == TME_M68K_SIZE_8 && ea_reg == TME_M68K_IREG_A7) { ! 3708: increment = TME_M68K_SIZE_16; ! 3709: } ! 3710: switch (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 3, 3)) { ! 3711: case 3: ic->tme_m68k_ireg_uint32(ea_reg) += increment; break; ! 3712: case 4: ic->_tme_m68k_ea_address = (ic->tme_m68k_ireg_uint32(ea_reg) -= increment); break; ! 3713: default: break; ! 3714: } ! 3715: } ! 3716: 1.1 root 3717: if (TME_M68K_INSN_SPECOP & TME_BIT(11)) { 1.1.1.3 ! root 3718: if (!TME_M68K_SEQUENCE_RESTARTING) { ! 3719: ic->tme_m68k_ireg_memx32 = ic->tme_m68k_ireg_uint32(ireg); ! 3720: ic->_tme_m68k_ea_function_code = ic->tme_m68k_ireg_dfc; ! 3721: } ! 3722: tme_m68k_write_memx32(ic); 1.1 root 3723: } 3724: else { 1.1.1.3 ! root 3725: if (!TME_M68K_SEQUENCE_RESTARTING) { ! 3726: ic->_tme_m68k_ea_function_code = ic->tme_m68k_ireg_sfc; ! 3727: } ! 3728: tme_m68k_read_memx32(ic); 1.1 root 3729: ic->tme_m68k_ireg_uint32(ireg) = ic->tme_m68k_ireg_memx32; 3730: } 3731: TME_M68K_INSN_OK; 3732: } 3733: 3734: /* this reads a 8-bit memx value: */ 3735: void 3736: tme_m68k_read_memx8(struct tme_m68k *ic) 3737: { 3738: unsigned int function_code = ic->_tme_m68k_ea_function_code; 3739: tme_uint32_t linear_address = ic->_tme_m68k_ea_address; 3740: struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address); 3741: 1.1.1.3 ! root 3742: #ifdef _TME_M68K_STATS ! 3743: ic->tme_m68k_stats.tme_m68k_stats_memory_total++; ! 3744: #endif /* _TME_M68K_STATS */ ! 3745: 1.1 root 3746: /* do the bus cycle(s) ourselves from emulator memory if we can. 3747: the emulator memory allocator and TLB filler must guarantee 3748: that all tme_m68k_tlb_emulator_off_read pointers be 32-bit 3749: aligned, so that a 16-bit-aligned linear address gets a 3750: 16-bit-aligned emulator address: */ 3751: if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING 3752: && TME_M68K_TLB_OK_FAST_READ(tlb, 3753: function_code, 3754: linear_address, 3755: linear_address))) { 3756: 3757: /* for an 8-bit transfer we can always do a simple 3758: assignment. the rdlock is unnecessary, since we assume 3759: that 8-bit accesses are always atomic: */ 3760: ic->tme_m68k_ireg_memx8 = *((tme_uint8_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address)); 3761: TME_M68K_SEQUENCE_TRANSFER_STEP; 3762: } 3763: 3764: /* otherwise, do the bus cycles the slow way: */ 3765: else { 3766: tme_m68k_read8(ic, tlb, 3767: &ic->_tme_m68k_ea_function_code, 3768: &ic->_tme_m68k_ea_address, 3769: &ic->tme_m68k_ireg_memx8, 3770: TME_M68K_BUS_CYCLE_NORMAL); 3771: } 3772: 3773: /* log the value read: */ 3774: tme_m68k_verify_mem8(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_memx8, TME_BUS_CYCLE_READ); 3775: tme_m68k_log(ic, 1000, TME_OK, 3776: (TME_M68K_LOG_HANDLE(ic), 3777: _("read_memx8\t%d:0x%08x:\t0x%02x"), 3778: ic->_tme_m68k_ea_function_code, 3779: ic->_tme_m68k_ea_address, 3780: ic->tme_m68k_ireg_memx8)); 3781: } 3782: 3783: /* this reads a 8-bit mem value: */ 3784: void 3785: tme_m68k_read_mem8(struct tme_m68k *ic, int ireg) 3786: { 3787: unsigned int function_code = ic->_tme_m68k_ea_function_code; 3788: tme_uint32_t linear_address = ic->_tme_m68k_ea_address; 3789: struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address); 3790: 1.1.1.3 ! root 3791: #ifdef _TME_M68K_STATS ! 3792: ic->tme_m68k_stats.tme_m68k_stats_memory_total++; ! 3793: #endif /* _TME_M68K_STATS */ ! 3794: 1.1 root 3795: /* do the bus cycle(s) ourselves from emulator memory if we can. 3796: the emulator memory allocator and TLB filler must guarantee 3797: that all tme_m68k_tlb_emulator_off_read pointers be 32-bit 3798: aligned, so that a 16-bit-aligned linear address gets a 3799: 16-bit-aligned emulator address: */ 3800: if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING 3801: && TME_M68K_TLB_OK_FAST_READ(tlb, 3802: function_code, 3803: linear_address, 3804: linear_address))) { 3805: 3806: /* for an 8-bit transfer we can always do a simple 3807: assignment. the rdlock is unnecessary, since we assume 3808: that 8-bit accesses are always atomic: */ 3809: ic->tme_m68k_ireg_uint8(ireg) = *((tme_uint8_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address)); 3810: TME_M68K_SEQUENCE_TRANSFER_STEP; 3811: } 3812: 3813: /* otherwise, do the bus cycles the slow way: */ 3814: else { 3815: tme_m68k_read8(ic, tlb, 3816: &ic->_tme_m68k_ea_function_code, 3817: &ic->_tme_m68k_ea_address, 3818: &ic->tme_m68k_ireg_uint8(ireg), 3819: TME_M68K_BUS_CYCLE_NORMAL); 3820: } 3821: 3822: /* log the value read: */ 3823: tme_m68k_verify_mem8(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_uint8(ireg), TME_BUS_CYCLE_READ); 3824: tme_m68k_log(ic, 1000, TME_OK, 3825: (TME_M68K_LOG_HANDLE(ic), 3826: _("read_mem8\t%d:0x%08x:\t0x%02x"), 3827: ic->_tme_m68k_ea_function_code, 3828: ic->_tme_m68k_ea_address, 3829: ic->tme_m68k_ireg_uint8(ireg))); 3830: } 3831: 3832: /* this writes a 8-bit memx value: */ 3833: void 3834: tme_m68k_write_memx8(struct tme_m68k *ic) 3835: { 3836: unsigned int function_code = ic->_tme_m68k_ea_function_code; 3837: tme_uint32_t linear_address = ic->_tme_m68k_ea_address; 3838: struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address); 3839: 1.1.1.3 ! root 3840: #ifdef _TME_M68K_STATS ! 3841: ic->tme_m68k_stats.tme_m68k_stats_memory_total++; ! 3842: #endif /* _TME_M68K_STATS */ ! 3843: 1.1 root 3844: /* log the value written: */ 3845: tme_m68k_verify_mem8(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_memx8, TME_BUS_CYCLE_WRITE); 3846: tme_m68k_log(ic, 1000, TME_OK, 3847: (TME_M68K_LOG_HANDLE(ic), 3848: _("write_memx8\t%d:0x%08x:\t0x%02x"), 3849: ic->_tme_m68k_ea_function_code, 3850: ic->_tme_m68k_ea_address, 3851: ic->tme_m68k_ireg_memx8)); 3852: 3853: /* do the bus cycle(s) ourselves from emulator memory if we can. 3854: the emulator memory allocator and TLB filler must guarantee 3855: that all tme_m68k_tlb_emulator_off_write pointers be 32-bit 3856: aligned, so that a 16-bit-aligned linear address gets a 3857: 16-bit-aligned emulator address: */ 3858: if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING 3859: && TME_M68K_TLB_OK_FAST_WRITE(tlb, 3860: function_code, 3861: linear_address, 3862: linear_address))) { 3863: 3864: /* for an 8-bit transfer we can always do a simple 3865: assignment. the wrlock is unnecessary, since we assume 3866: that 8-bit accesses are always atomic: */ 3867: *((tme_uint8_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address)) = ic->tme_m68k_ireg_memx8; 3868: TME_M68K_SEQUENCE_TRANSFER_STEP; 3869: } 3870: 3871: /* otherwise, do the bus cycles the slow way: */ 3872: else { 3873: tme_m68k_write8(ic, tlb, 3874: &ic->_tme_m68k_ea_function_code, 3875: &ic->_tme_m68k_ea_address, 3876: &ic->tme_m68k_ireg_memx8, 3877: TME_M68K_BUS_CYCLE_NORMAL); 3878: } 3879: } 3880: 3881: /* this writes a 8-bit mem value: */ 3882: void 3883: tme_m68k_write_mem8(struct tme_m68k *ic, int ireg) 3884: { 3885: unsigned int function_code = ic->_tme_m68k_ea_function_code; 3886: tme_uint32_t linear_address = ic->_tme_m68k_ea_address; 3887: struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address); 3888: 1.1.1.3 ! root 3889: #ifdef _TME_M68K_STATS ! 3890: ic->tme_m68k_stats.tme_m68k_stats_memory_total++; ! 3891: #endif /* _TME_M68K_STATS */ ! 3892: 1.1 root 3893: /* log the value written: */ 3894: tme_m68k_verify_mem8(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_uint8(ireg), TME_BUS_CYCLE_WRITE); 3895: tme_m68k_log(ic, 1000, TME_OK, 3896: (TME_M68K_LOG_HANDLE(ic), 3897: _("write_mem8\t%d:0x%08x:\t0x%02x"), 3898: ic->_tme_m68k_ea_function_code, 3899: ic->_tme_m68k_ea_address, 3900: ic->tme_m68k_ireg_uint8(ireg))); 3901: 3902: /* do the bus cycle(s) ourselves from emulator memory if we can. 3903: the emulator memory allocator and TLB filler must guarantee 3904: that all tme_m68k_tlb_emulator_off_write pointers be 32-bit 3905: aligned, so that a 16-bit-aligned linear address gets a 3906: 16-bit-aligned emulator address: */ 3907: if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING 3908: && TME_M68K_TLB_OK_FAST_WRITE(tlb, 3909: function_code, 3910: linear_address, 3911: linear_address))) { 3912: 3913: /* for an 8-bit transfer we can always do a simple 3914: assignment. the wrlock is unnecessary, since we assume 3915: that 8-bit accesses are always atomic: */ 3916: *((tme_uint8_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address)) = ic->tme_m68k_ireg_uint8(ireg); 3917: TME_M68K_SEQUENCE_TRANSFER_STEP; 3918: } 3919: 3920: /* otherwise, do the bus cycles the slow way: */ 3921: else { 3922: tme_m68k_write8(ic, tlb, 3923: &ic->_tme_m68k_ea_function_code, 3924: &ic->_tme_m68k_ea_address, 3925: &ic->tme_m68k_ireg_uint8(ireg), 3926: TME_M68K_BUS_CYCLE_NORMAL); 3927: } 3928: } 3929: 3930: /* this reads a 16-bit memx value: */ 3931: void 3932: tme_m68k_read_memx16(struct tme_m68k *ic) 3933: { 3934: unsigned int function_code = ic->_tme_m68k_ea_function_code; 3935: tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address; 3936: tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1; 3937: struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); 3938: 1.1.1.3 ! root 3939: #ifdef _TME_M68K_STATS ! 3940: ic->tme_m68k_stats.tme_m68k_stats_memory_total++; ! 3941: #endif /* _TME_M68K_STATS */ ! 3942: 1.1 root 3943: /* do the bus cycle(s) ourselves from emulator memory if we can. 3944: the emulator memory allocator and TLB filler must guarantee 3945: that all tme_m68k_tlb_emulator_off_read pointers be 32-bit 3946: aligned, so that a 16-bit-aligned linear address gets a 3947: 16-bit-aligned emulator address: */ 3948: if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING 3949: && !(linear_address_first & 1) 3950: && TME_M68K_TLB_OK_FAST_READ(tlb, 3951: function_code, 3952: linear_address_first, 3953: linear_address_last))) { 3954: 3955: /* for a 16-bit transfer we can always do a simple 3956: assignment - we tested that the linear address 3957: is 16-bit aligned, which, since the TLB emulator 3958: offset is guaranteed to be 32-bit aligned, guarantees 3959: that the final emulator address is 16-bit aligned. 3960: 3961: we need the rdlock if we're on an architecture 3962: where an aligned access may not be atomic: */ 3963: tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 3964: ic->tme_m68k_ireg_memx16 = tme_betoh_u16(*((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))); 3965: tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 3966: TME_M68K_SEQUENCE_TRANSFER_STEP; 3967: } 3968: 3969: /* otherwise, do the bus cycles the slow way: */ 3970: else { 3971: tme_m68k_read16(ic, tlb, 3972: &ic->_tme_m68k_ea_function_code, 3973: &ic->_tme_m68k_ea_address, 3974: &ic->tme_m68k_ireg_memx16, 3975: TME_M68K_BUS_CYCLE_NORMAL); 3976: } 3977: 3978: /* log the value read: */ 3979: tme_m68k_verify_mem16(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_memx16, TME_BUS_CYCLE_READ); 3980: tme_m68k_log(ic, 1000, TME_OK, 3981: (TME_M68K_LOG_HANDLE(ic), 3982: _("read_memx16\t%d:0x%08x:\t0x%04x"), 3983: ic->_tme_m68k_ea_function_code, 3984: ic->_tme_m68k_ea_address, 3985: ic->tme_m68k_ireg_memx16)); 3986: } 3987: 3988: /* this reads a 16-bit mem value: */ 3989: void 3990: tme_m68k_read_mem16(struct tme_m68k *ic, int ireg) 3991: { 3992: unsigned int function_code = ic->_tme_m68k_ea_function_code; 3993: tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address; 3994: tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1; 3995: struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); 3996: 1.1.1.3 ! root 3997: #ifdef _TME_M68K_STATS ! 3998: ic->tme_m68k_stats.tme_m68k_stats_memory_total++; ! 3999: #endif /* _TME_M68K_STATS */ ! 4000: 1.1 root 4001: /* do the bus cycle(s) ourselves from emulator memory if we can. 4002: the emulator memory allocator and TLB filler must guarantee 4003: that all tme_m68k_tlb_emulator_off_read pointers be 32-bit 4004: aligned, so that a 16-bit-aligned linear address gets a 4005: 16-bit-aligned emulator address: */ 4006: if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING 4007: && !(linear_address_first & 1) 4008: && TME_M68K_TLB_OK_FAST_READ(tlb, 4009: function_code, 4010: linear_address_first, 4011: linear_address_last))) { 4012: 4013: /* for a 16-bit transfer we can always do a simple 4014: assignment - we tested that the linear address 4015: is 16-bit aligned, which, since the TLB emulator 4016: offset is guaranteed to be 32-bit aligned, guarantees 4017: that the final emulator address is 16-bit aligned. 4018: 4019: we need the rdlock if we're on an architecture 4020: where an aligned access may not be atomic: */ 4021: tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 4022: ic->tme_m68k_ireg_uint16(ireg) = tme_betoh_u16(*((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))); 4023: tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4024: TME_M68K_SEQUENCE_TRANSFER_STEP; 4025: } 4026: 4027: /* otherwise, do the bus cycles the slow way: */ 4028: else { 4029: tme_m68k_read16(ic, tlb, 4030: &ic->_tme_m68k_ea_function_code, 4031: &ic->_tme_m68k_ea_address, 4032: &ic->tme_m68k_ireg_uint16(ireg), 4033: TME_M68K_BUS_CYCLE_NORMAL); 4034: } 4035: 4036: /* log the value read: */ 4037: tme_m68k_verify_mem16(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_uint16(ireg), TME_BUS_CYCLE_READ); 4038: tme_m68k_log(ic, 1000, TME_OK, 4039: (TME_M68K_LOG_HANDLE(ic), 4040: _("read_mem16\t%d:0x%08x:\t0x%04x"), 4041: ic->_tme_m68k_ea_function_code, 4042: ic->_tme_m68k_ea_address, 4043: ic->tme_m68k_ireg_uint16(ireg))); 4044: } 4045: 4046: /* this reads a 16-bit inst value: */ 4047: tme_uint16_t 4048: tme_m68k_fetch16(struct tme_m68k *ic, tme_uint32_t pc) 4049: { 4050: unsigned int function_code = TME_M68K_FUNCTION_CODE_PROGRAM(ic); 4051: tme_uint32_t linear_address_first = pc; 4052: tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1; 4053: struct tme_m68k_tlb *tlb = TME_ATOMIC_READ(struct tme_m68k_tlb *, ic->_tme_m68k_itlb); 4054: unsigned int insn_buffer_off = TME_ALIGN(ic->_tme_m68k_insn_buffer_off, sizeof(tme_uint16_t)); 4055: 1.1.1.3 ! root 4056: #ifdef _TME_M68K_STATS ! 4057: ic->tme_m68k_stats.tme_m68k_stats_memory_total++; ! 4058: #endif /* _TME_M68K_STATS */ ! 4059: 1.1 root 4060: /* do the bus cycle(s) ourselves from emulator memory if we can. 4061: the emulator memory allocator and TLB filler must guarantee 4062: that all tme_m68k_tlb_emulator_off_read pointers be 32-bit 4063: aligned, so that a 16-bit-aligned linear address gets a 4064: 16-bit-aligned emulator address: */ 4065: if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING 4066: && !(linear_address_first & 1) 4067: && TME_M68K_TLB_OK_FAST_READ(tlb, 4068: function_code, 4069: linear_address_first, 4070: linear_address_last))) { 4071: 4072: /* for a 16-bit transfer we can always do a simple 4073: assignment - we tested that the linear address 4074: is 16-bit aligned, which, since the TLB emulator 4075: offset is guaranteed to be 32-bit aligned, guarantees 4076: that the final emulator address is 16-bit aligned. 4077: 4078: we need the rdlock if we're on an architecture 4079: where an aligned access may not be atomic: */ 4080: tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 4081: *((tme_uint16_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]) = tme_betoh_u16(*((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))); 4082: tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4083: TME_M68K_SEQUENCE_TRANSFER_STEP; 4084: } 4085: 4086: /* otherwise, do the bus cycles the slow way: */ 4087: else { 4088: tme_m68k_read16(ic, tlb, 4089: &function_code, 4090: &pc, 4091: ((tme_uint16_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]), 4092: TME_M68K_BUS_CYCLE_FETCH); 4093: } 4094: 4095: /* log the value read: */ 4096: tme_m68k_verify_mem16(ic, function_code, pc, *((tme_uint16_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]), TME_BUS_CYCLE_READ); 4097: tme_m68k_log(ic, 1000, TME_OK, 4098: (TME_M68K_LOG_HANDLE(ic), 4099: _("fetch16\t%d:0x%08x:\t0x%04x"), 4100: function_code, 4101: pc, 4102: *((tme_uint16_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]))); 4103: ic->_tme_m68k_insn_buffer_off = insn_buffer_off + sizeof(tme_uint16_t); 4104: return(*((tme_uint16_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off])); 4105: } 4106: 4107: /* this reads a 16-bit stack value: */ 4108: void 4109: tme_m68k_pop16(struct tme_m68k *ic, tme_uint16_t *_value) 4110: { 4111: unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic); 4112: tme_uint32_t linear_address_first = ic->tme_m68k_ireg_a7; 4113: tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1; 4114: struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); 4115: 1.1.1.3 ! root 4116: #ifdef _TME_M68K_STATS ! 4117: ic->tme_m68k_stats.tme_m68k_stats_memory_total++; ! 4118: #endif /* _TME_M68K_STATS */ ! 4119: 1.1 root 4120: /* do the bus cycle(s) ourselves from emulator memory if we can. 4121: the emulator memory allocator and TLB filler must guarantee 4122: that all tme_m68k_tlb_emulator_off_read pointers be 32-bit 4123: aligned, so that a 16-bit-aligned linear address gets a 4124: 16-bit-aligned emulator address: */ 4125: if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING 4126: && !(linear_address_first & 1) 4127: && TME_M68K_TLB_OK_FAST_READ(tlb, 4128: function_code, 4129: linear_address_first, 4130: linear_address_last))) { 4131: 4132: /* for a 16-bit transfer we can always do a simple 4133: assignment - we tested that the linear address 4134: is 16-bit aligned, which, since the TLB emulator 4135: offset is guaranteed to be 32-bit aligned, guarantees 4136: that the final emulator address is 16-bit aligned. 4137: 4138: we need the rdlock if we're on an architecture 4139: where an aligned access may not be atomic: */ 4140: tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 4141: *_value = tme_betoh_u16(*((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))); 4142: tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4143: TME_M68K_SEQUENCE_TRANSFER_STEP; 4144: } 4145: 4146: /* otherwise, do the bus cycles the slow way: */ 4147: else { 4148: tme_m68k_read16(ic, tlb, 4149: &function_code, 4150: &ic->tme_m68k_ireg_a7, 4151: _value, 4152: TME_M68K_BUS_CYCLE_NORMAL); 4153: } 4154: 4155: /* log the value read: */ 4156: tme_m68k_verify_mem16(ic, function_code, ic->tme_m68k_ireg_a7, *_value, TME_BUS_CYCLE_READ); 4157: tme_m68k_log(ic, 1000, TME_OK, 4158: (TME_M68K_LOG_HANDLE(ic), 4159: _("pop16\t%d:0x%08x:\t0x%04x"), 4160: function_code, 4161: ic->tme_m68k_ireg_a7, 4162: *_value)); 4163: if (!TME_M68K_SEQUENCE_RESTARTING) { 4164: ic->tme_m68k_ireg_a7 += sizeof(tme_uint16_t); 4165: } 4166: } 4167: 4168: /* this writes a 16-bit memx value: */ 4169: void 4170: tme_m68k_write_memx16(struct tme_m68k *ic) 4171: { 4172: unsigned int function_code = ic->_tme_m68k_ea_function_code; 4173: tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address; 4174: tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1; 4175: struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); 4176: 1.1.1.3 ! root 4177: #ifdef _TME_M68K_STATS ! 4178: ic->tme_m68k_stats.tme_m68k_stats_memory_total++; ! 4179: #endif /* _TME_M68K_STATS */ ! 4180: 1.1 root 4181: /* log the value written: */ 4182: tme_m68k_verify_mem16(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_memx16, TME_BUS_CYCLE_WRITE); 4183: tme_m68k_log(ic, 1000, TME_OK, 4184: (TME_M68K_LOG_HANDLE(ic), 4185: _("write_memx16\t%d:0x%08x:\t0x%04x"), 4186: ic->_tme_m68k_ea_function_code, 4187: ic->_tme_m68k_ea_address, 4188: ic->tme_m68k_ireg_memx16)); 4189: 4190: /* do the bus cycle(s) ourselves from emulator memory if we can. 4191: the emulator memory allocator and TLB filler must guarantee 4192: that all tme_m68k_tlb_emulator_off_write pointers be 32-bit 4193: aligned, so that a 16-bit-aligned linear address gets a 4194: 16-bit-aligned emulator address: */ 4195: if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING 4196: && !(linear_address_first & 1) 4197: && TME_M68K_TLB_OK_FAST_WRITE(tlb, 4198: function_code, 4199: linear_address_first, 4200: linear_address_last))) { 4201: 4202: /* for a 16-bit transfer we can always do a simple 4203: assignment - we tested that the linear address 4204: is 16-bit aligned, which, since the TLB emulator 4205: offset is guaranteed to be 32-bit aligned, guarantees 4206: that the final emulator address is 16-bit aligned. 4207: 4208: we need the wrlock if we're on an architecture 4209: where an aligned access may not be atomic: */ 4210: tme_memory_aligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock); 4211: *((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u16(ic->tme_m68k_ireg_memx16); 4212: tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4213: TME_M68K_SEQUENCE_TRANSFER_STEP; 4214: } 4215: 4216: /* otherwise, do the bus cycles the slow way: */ 4217: else { 4218: tme_m68k_write16(ic, tlb, 4219: &ic->_tme_m68k_ea_function_code, 4220: &ic->_tme_m68k_ea_address, 4221: &ic->tme_m68k_ireg_memx16, 4222: TME_M68K_BUS_CYCLE_NORMAL); 4223: } 4224: } 4225: 4226: /* this writes a 16-bit mem value: */ 4227: void 4228: tme_m68k_write_mem16(struct tme_m68k *ic, int ireg) 4229: { 4230: unsigned int function_code = ic->_tme_m68k_ea_function_code; 4231: tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address; 4232: tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1; 4233: struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); 4234: 1.1.1.3 ! root 4235: #ifdef _TME_M68K_STATS ! 4236: ic->tme_m68k_stats.tme_m68k_stats_memory_total++; ! 4237: #endif /* _TME_M68K_STATS */ ! 4238: 1.1 root 4239: /* log the value written: */ 4240: tme_m68k_verify_mem16(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_uint16(ireg), TME_BUS_CYCLE_WRITE); 4241: tme_m68k_log(ic, 1000, TME_OK, 4242: (TME_M68K_LOG_HANDLE(ic), 4243: _("write_mem16\t%d:0x%08x:\t0x%04x"), 4244: ic->_tme_m68k_ea_function_code, 4245: ic->_tme_m68k_ea_address, 4246: ic->tme_m68k_ireg_uint16(ireg))); 4247: 4248: /* do the bus cycle(s) ourselves from emulator memory if we can. 4249: the emulator memory allocator and TLB filler must guarantee 4250: that all tme_m68k_tlb_emulator_off_write pointers be 32-bit 4251: aligned, so that a 16-bit-aligned linear address gets a 4252: 16-bit-aligned emulator address: */ 4253: if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING 4254: && !(linear_address_first & 1) 4255: && TME_M68K_TLB_OK_FAST_WRITE(tlb, 4256: function_code, 4257: linear_address_first, 4258: linear_address_last))) { 4259: 4260: /* for a 16-bit transfer we can always do a simple 4261: assignment - we tested that the linear address 4262: is 16-bit aligned, which, since the TLB emulator 4263: offset is guaranteed to be 32-bit aligned, guarantees 4264: that the final emulator address is 16-bit aligned. 4265: 4266: we need the wrlock if we're on an architecture 4267: where an aligned access may not be atomic: */ 4268: tme_memory_aligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock); 4269: *((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u16(ic->tme_m68k_ireg_uint16(ireg)); 4270: tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4271: TME_M68K_SEQUENCE_TRANSFER_STEP; 4272: } 4273: 4274: /* otherwise, do the bus cycles the slow way: */ 4275: else { 4276: tme_m68k_write16(ic, tlb, 4277: &ic->_tme_m68k_ea_function_code, 4278: &ic->_tme_m68k_ea_address, 4279: &ic->tme_m68k_ireg_uint16(ireg), 4280: TME_M68K_BUS_CYCLE_NORMAL); 4281: } 4282: } 4283: 4284: /* this writes a 16-bit stack value: */ 4285: void 4286: tme_m68k_push16(struct tme_m68k *ic, tme_uint16_t value) 4287: { 4288: unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic); 4289: tme_uint32_t linear_address_first = ic->tme_m68k_ireg_a7 - sizeof(tme_uint16_t); 4290: tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1; 4291: struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); 4292: 1.1.1.3 ! root 4293: #ifdef _TME_M68K_STATS ! 4294: ic->tme_m68k_stats.tme_m68k_stats_memory_total++; ! 4295: #endif /* _TME_M68K_STATS */ ! 4296: 1.1 root 4297: /* log the value written: */ 4298: tme_m68k_verify_mem16(ic, function_code, linear_address_first, value, TME_BUS_CYCLE_WRITE); 4299: tme_m68k_log(ic, 1000, TME_OK, 4300: (TME_M68K_LOG_HANDLE(ic), 4301: _("push16\t%d:0x%08x:\t0x%04x"), 4302: function_code, 4303: linear_address_first, 4304: value)); 4305: 4306: /* do the bus cycle(s) ourselves from emulator memory if we can. 4307: the emulator memory allocator and TLB filler must guarantee 4308: that all tme_m68k_tlb_emulator_off_write pointers be 32-bit 4309: aligned, so that a 16-bit-aligned linear address gets a 4310: 16-bit-aligned emulator address: */ 4311: if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING 4312: && !(linear_address_first & 1) 4313: && TME_M68K_TLB_OK_FAST_WRITE(tlb, 4314: function_code, 4315: linear_address_first, 4316: linear_address_last))) { 4317: 4318: /* for a 16-bit transfer we can always do a simple 4319: assignment - we tested that the linear address 4320: is 16-bit aligned, which, since the TLB emulator 4321: offset is guaranteed to be 32-bit aligned, guarantees 4322: that the final emulator address is 16-bit aligned. 4323: 4324: we need the wrlock if we're on an architecture 4325: where an aligned access may not be atomic: */ 4326: tme_memory_aligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock); 4327: *((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u16(value); 4328: tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4329: TME_M68K_SEQUENCE_TRANSFER_STEP; 4330: } 4331: 4332: /* otherwise, do the bus cycles the slow way: */ 4333: else { 4334: tme_m68k_write16(ic, tlb, 4335: &function_code, 4336: &linear_address_first, 4337: &value, 4338: TME_M68K_BUS_CYCLE_NORMAL); 4339: } 4340: if (!TME_M68K_SEQUENCE_RESTARTING) { 4341: ic->tme_m68k_ireg_a7 -= sizeof(tme_uint16_t); 4342: } 4343: } 4344: 4345: /* this reads a 32-bit memx value: */ 4346: void 4347: tme_m68k_read_memx32(struct tme_m68k *ic) 4348: { 4349: unsigned int function_code = ic->_tme_m68k_ea_function_code; 4350: tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address; 4351: tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1; 4352: struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); 4353: 1.1.1.3 ! root 4354: #ifdef _TME_M68K_STATS ! 4355: ic->tme_m68k_stats.tme_m68k_stats_memory_total++; ! 4356: #endif /* _TME_M68K_STATS */ ! 4357: 1.1 root 4358: /* do the bus cycle(s) ourselves from emulator memory if we can. 4359: the emulator memory allocator and TLB filler must guarantee 4360: that all tme_m68k_tlb_emulator_off_read pointers be 32-bit 4361: aligned, so that a 16-bit-aligned linear address gets a 4362: 16-bit-aligned emulator address: */ 4363: if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING 4364: && !(linear_address_first & 1) 4365: && TME_M68K_TLB_OK_FAST_READ(tlb, 4366: function_code, 4367: linear_address_first, 4368: linear_address_last))) { 4369: 4370: /* if the emulator host allows 32-bit quantities to be 4371: transferred from 16-bit aligned addresses, or if this 4372: address is 32-bit aligned, do the transfer as a simple 4373: assignment, otherwise transfer two 16-bit words. 4374: 4375: we need the rdlock if we're on an architecture where 4376: an aligned access may not be atomic, or if we're doing 4377: an unaligned access on an architecture where they may 4378: not be atomic: */ 4379: #if ALIGNOF_INT32_T <= ALIGNOF_INT16_T 4380: #ifdef TME_UNALIGNED_ACCESS_ATOMIC 4381: ic->tme_m68k_ireg_memx32 = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))); 4382: #else /* !TME_UNALIGNED_ACCESS_ATOMIC */ 4383: if ((linear_address_first & (sizeof(tme_uint32_t) - 1))) { 4384: tme_memory_unaligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 4385: ic->tme_m68k_ireg_memx32 = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))); 4386: tme_memory_unaligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4387: } 4388: else { 4389: tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 4390: ic->tme_m68k_ireg_memx32 = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))); 4391: tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4392: } 4393: #endif /* !TME_UNALIGNED_ACCESS_ATOMIC */ 4394: #else /* ALIGNOF_INT32_T > ALIGNOF_INT16_T */ 4395: if (TME_SEQUENCE_ACCESS_NOT_COSTLIER || (linear_address_first & (sizeof(tme_uint32_t) - 1))) { 4396: tme_memory_sequence_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 4397: #ifdef WORDS_BIGENDIAN 4398: ic->tme_m68k_ireg_memx32 = (((tme_uint32_t) ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[0]) << 16) | ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[1]; 4399: #else /* !WORDS_BIGENDIAN */ 4400: ic->tme_m68k_ireg_memx32 = tme_betoh_u32((((tme_uint32_t) ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[1]) << 16) | ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[0]); 4401: #endif /* !WORDS_BIGENDIAN */ 4402: tme_memory_sequence_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4403: } 4404: else { 4405: tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 4406: ic->tme_m68k_ireg_memx32 = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))); 4407: tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4408: } 4409: #endif /* ALIGNOF_INT32_T != 1 */ 4410: TME_M68K_SEQUENCE_TRANSFER_STEP; 4411: } 4412: 4413: /* otherwise, do the bus cycles the slow way: */ 4414: else { 4415: tme_m68k_read32(ic, tlb, 4416: &ic->_tme_m68k_ea_function_code, 4417: &ic->_tme_m68k_ea_address, 4418: &ic->tme_m68k_ireg_memx32, 4419: TME_M68K_BUS_CYCLE_NORMAL); 4420: } 4421: 4422: /* log the value read: */ 4423: tme_m68k_verify_mem32(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_memx32, TME_BUS_CYCLE_READ); 4424: tme_m68k_log(ic, 1000, TME_OK, 4425: (TME_M68K_LOG_HANDLE(ic), 4426: _("read_memx32\t%d:0x%08x:\t0x%08x"), 4427: ic->_tme_m68k_ea_function_code, 4428: ic->_tme_m68k_ea_address, 4429: ic->tme_m68k_ireg_memx32)); 4430: } 4431: 4432: /* this reads a 32-bit mem value: */ 4433: void 4434: tme_m68k_read_mem32(struct tme_m68k *ic, int ireg) 4435: { 4436: unsigned int function_code = ic->_tme_m68k_ea_function_code; 4437: tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address; 4438: tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1; 4439: struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); 4440: 1.1.1.3 ! root 4441: #ifdef _TME_M68K_STATS ! 4442: ic->tme_m68k_stats.tme_m68k_stats_memory_total++; ! 4443: #endif /* _TME_M68K_STATS */ ! 4444: 1.1 root 4445: /* do the bus cycle(s) ourselves from emulator memory if we can. 4446: the emulator memory allocator and TLB filler must guarantee 4447: that all tme_m68k_tlb_emulator_off_read pointers be 32-bit 4448: aligned, so that a 16-bit-aligned linear address gets a 4449: 16-bit-aligned emulator address: */ 4450: if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING 4451: && !(linear_address_first & 1) 4452: && TME_M68K_TLB_OK_FAST_READ(tlb, 4453: function_code, 4454: linear_address_first, 4455: linear_address_last))) { 4456: 4457: /* if the emulator host allows 32-bit quantities to be 4458: transferred from 16-bit aligned addresses, or if this 4459: address is 32-bit aligned, do the transfer as a simple 4460: assignment, otherwise transfer two 16-bit words. 4461: 4462: we need the rdlock if we're on an architecture where 4463: an aligned access may not be atomic, or if we're doing 4464: an unaligned access on an architecture where they may 4465: not be atomic: */ 4466: #if ALIGNOF_INT32_T <= ALIGNOF_INT16_T 4467: #ifdef TME_UNALIGNED_ACCESS_ATOMIC 4468: ic->tme_m68k_ireg_uint32(ireg) = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))); 4469: #else /* !TME_UNALIGNED_ACCESS_ATOMIC */ 4470: if ((linear_address_first & (sizeof(tme_uint32_t) - 1))) { 4471: tme_memory_unaligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 4472: ic->tme_m68k_ireg_uint32(ireg) = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))); 4473: tme_memory_unaligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4474: } 4475: else { 4476: tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 4477: ic->tme_m68k_ireg_uint32(ireg) = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))); 4478: tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4479: } 4480: #endif /* !TME_UNALIGNED_ACCESS_ATOMIC */ 4481: #else /* ALIGNOF_INT32_T > ALIGNOF_INT16_T */ 4482: if (TME_SEQUENCE_ACCESS_NOT_COSTLIER || (linear_address_first & (sizeof(tme_uint32_t) - 1))) { 4483: tme_memory_sequence_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 4484: #ifdef WORDS_BIGENDIAN 4485: ic->tme_m68k_ireg_uint32(ireg) = (((tme_uint32_t) ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[0]) << 16) | ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[1]; 4486: #else /* !WORDS_BIGENDIAN */ 4487: ic->tme_m68k_ireg_uint32(ireg) = tme_betoh_u32((((tme_uint32_t) ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[1]) << 16) | ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[0]); 4488: #endif /* !WORDS_BIGENDIAN */ 4489: tme_memory_sequence_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4490: } 4491: else { 4492: tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 4493: ic->tme_m68k_ireg_uint32(ireg) = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))); 4494: tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4495: } 4496: #endif /* ALIGNOF_INT32_T != 1 */ 4497: TME_M68K_SEQUENCE_TRANSFER_STEP; 4498: } 4499: 4500: /* otherwise, do the bus cycles the slow way: */ 4501: else { 4502: tme_m68k_read32(ic, tlb, 4503: &ic->_tme_m68k_ea_function_code, 4504: &ic->_tme_m68k_ea_address, 4505: &ic->tme_m68k_ireg_uint32(ireg), 4506: TME_M68K_BUS_CYCLE_NORMAL); 4507: } 4508: 4509: /* log the value read: */ 4510: tme_m68k_verify_mem32(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_uint32(ireg), TME_BUS_CYCLE_READ); 4511: tme_m68k_log(ic, 1000, TME_OK, 4512: (TME_M68K_LOG_HANDLE(ic), 4513: _("read_mem32\t%d:0x%08x:\t0x%08x"), 4514: ic->_tme_m68k_ea_function_code, 4515: ic->_tme_m68k_ea_address, 4516: ic->tme_m68k_ireg_uint32(ireg))); 4517: } 4518: 4519: /* this reads a 32-bit inst value: */ 4520: tme_uint32_t 4521: tme_m68k_fetch32(struct tme_m68k *ic, tme_uint32_t pc) 4522: { 4523: unsigned int function_code = TME_M68K_FUNCTION_CODE_PROGRAM(ic); 4524: tme_uint32_t linear_address_first = pc; 4525: tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1; 4526: struct tme_m68k_tlb *tlb = TME_ATOMIC_READ(struct tme_m68k_tlb *, ic->_tme_m68k_itlb); 4527: unsigned int insn_buffer_off = TME_ALIGN(ic->_tme_m68k_insn_buffer_off, sizeof(tme_uint32_t)); 4528: 1.1.1.3 ! root 4529: #ifdef _TME_M68K_STATS ! 4530: ic->tme_m68k_stats.tme_m68k_stats_memory_total++; ! 4531: #endif /* _TME_M68K_STATS */ ! 4532: 1.1 root 4533: /* do the bus cycle(s) ourselves from emulator memory if we can. 4534: the emulator memory allocator and TLB filler must guarantee 4535: that all tme_m68k_tlb_emulator_off_read pointers be 32-bit 4536: aligned, so that a 16-bit-aligned linear address gets a 4537: 16-bit-aligned emulator address: */ 4538: if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING 4539: && !(linear_address_first & 1) 4540: && TME_M68K_TLB_OK_FAST_READ(tlb, 4541: function_code, 4542: linear_address_first, 4543: linear_address_last))) { 4544: 4545: /* if the emulator host allows 32-bit quantities to be 4546: transferred from 16-bit aligned addresses, or if this 4547: address is 32-bit aligned, do the transfer as a simple 4548: assignment, otherwise transfer two 16-bit words. 4549: 4550: we need the rdlock if we're on an architecture where 4551: an aligned access may not be atomic, or if we're doing 4552: an unaligned access on an architecture where they may 4553: not be atomic: */ 4554: #if ALIGNOF_INT32_T <= ALIGNOF_INT16_T 4555: #ifdef TME_UNALIGNED_ACCESS_ATOMIC 4556: *((tme_uint32_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]) = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))); 4557: #else /* !TME_UNALIGNED_ACCESS_ATOMIC */ 4558: if ((linear_address_first & (sizeof(tme_uint32_t) - 1))) { 4559: tme_memory_unaligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 4560: *((tme_uint32_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]) = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))); 4561: tme_memory_unaligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4562: } 4563: else { 4564: tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 4565: *((tme_uint32_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]) = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))); 4566: tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4567: } 4568: #endif /* !TME_UNALIGNED_ACCESS_ATOMIC */ 4569: #else /* ALIGNOF_INT32_T > ALIGNOF_INT16_T */ 4570: if (TME_SEQUENCE_ACCESS_NOT_COSTLIER || (linear_address_first & (sizeof(tme_uint32_t) - 1))) { 4571: tme_memory_sequence_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 4572: #ifdef WORDS_BIGENDIAN 4573: *((tme_uint32_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]) = (((tme_uint32_t) ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[0]) << 16) | ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[1]; 4574: #else /* !WORDS_BIGENDIAN */ 4575: *((tme_uint32_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]) = tme_betoh_u32((((tme_uint32_t) ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[1]) << 16) | ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[0]); 4576: #endif /* !WORDS_BIGENDIAN */ 4577: tme_memory_sequence_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4578: } 4579: else { 4580: tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 4581: *((tme_uint32_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]) = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))); 4582: tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4583: } 4584: #endif /* ALIGNOF_INT32_T != 1 */ 4585: TME_M68K_SEQUENCE_TRANSFER_STEP; 4586: } 4587: 4588: /* otherwise, do the bus cycles the slow way: */ 4589: else { 4590: tme_m68k_read32(ic, tlb, 4591: &function_code, 4592: &pc, 4593: ((tme_uint32_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]), 4594: TME_M68K_BUS_CYCLE_FETCH); 4595: } 4596: 4597: /* log the value read: */ 4598: tme_m68k_verify_mem32(ic, function_code, pc, *((tme_uint32_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]), TME_BUS_CYCLE_READ); 4599: tme_m68k_log(ic, 1000, TME_OK, 4600: (TME_M68K_LOG_HANDLE(ic), 4601: _("fetch32\t%d:0x%08x:\t0x%08x"), 4602: function_code, 4603: pc, 4604: *((tme_uint32_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off]))); 4605: ic->_tme_m68k_insn_buffer_off = insn_buffer_off + sizeof(tme_uint32_t); 4606: return(*((tme_uint32_t *) &ic->_tme_m68k_insn_buffer[insn_buffer_off])); 4607: } 4608: 4609: /* this reads a 32-bit stack value: */ 4610: void 4611: tme_m68k_pop32(struct tme_m68k *ic, tme_uint32_t *_value) 4612: { 4613: unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic); 4614: tme_uint32_t linear_address_first = ic->tme_m68k_ireg_a7; 4615: tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1; 4616: struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); 4617: 1.1.1.3 ! root 4618: #ifdef _TME_M68K_STATS ! 4619: ic->tme_m68k_stats.tme_m68k_stats_memory_total++; ! 4620: #endif /* _TME_M68K_STATS */ ! 4621: 1.1 root 4622: /* do the bus cycle(s) ourselves from emulator memory if we can. 4623: the emulator memory allocator and TLB filler must guarantee 4624: that all tme_m68k_tlb_emulator_off_read pointers be 32-bit 4625: aligned, so that a 16-bit-aligned linear address gets a 4626: 16-bit-aligned emulator address: */ 4627: if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING 4628: && !(linear_address_first & 1) 4629: && TME_M68K_TLB_OK_FAST_READ(tlb, 4630: function_code, 4631: linear_address_first, 4632: linear_address_last))) { 4633: 4634: /* if the emulator host allows 32-bit quantities to be 4635: transferred from 16-bit aligned addresses, or if this 4636: address is 32-bit aligned, do the transfer as a simple 4637: assignment, otherwise transfer two 16-bit words. 4638: 4639: we need the rdlock if we're on an architecture where 4640: an aligned access may not be atomic, or if we're doing 4641: an unaligned access on an architecture where they may 4642: not be atomic: */ 4643: #if ALIGNOF_INT32_T <= ALIGNOF_INT16_T 4644: #ifdef TME_UNALIGNED_ACCESS_ATOMIC 4645: *_value = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))); 4646: #else /* !TME_UNALIGNED_ACCESS_ATOMIC */ 4647: if ((linear_address_first & (sizeof(tme_uint32_t) - 1))) { 4648: tme_memory_unaligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 4649: *_value = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))); 4650: tme_memory_unaligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4651: } 4652: else { 4653: tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 4654: *_value = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))); 4655: tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4656: } 4657: #endif /* !TME_UNALIGNED_ACCESS_ATOMIC */ 4658: #else /* ALIGNOF_INT32_T > ALIGNOF_INT16_T */ 4659: if (TME_SEQUENCE_ACCESS_NOT_COSTLIER || (linear_address_first & (sizeof(tme_uint32_t) - 1))) { 4660: tme_memory_sequence_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 4661: #ifdef WORDS_BIGENDIAN 4662: *_value = (((tme_uint32_t) ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[0]) << 16) | ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[1]; 4663: #else /* !WORDS_BIGENDIAN */ 4664: *_value = tme_betoh_u32((((tme_uint32_t) ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[1]) << 16) | ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))[0]); 4665: #endif /* !WORDS_BIGENDIAN */ 4666: tme_memory_sequence_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4667: } 4668: else { 4669: tme_memory_aligned_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 4670: *_value = tme_betoh_u32(*((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first))); 4671: tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4672: } 4673: #endif /* ALIGNOF_INT32_T != 1 */ 4674: TME_M68K_SEQUENCE_TRANSFER_STEP; 4675: } 4676: 4677: /* otherwise, do the bus cycles the slow way: */ 4678: else { 4679: tme_m68k_read32(ic, tlb, 4680: &function_code, 4681: &ic->tme_m68k_ireg_a7, 4682: _value, 4683: TME_M68K_BUS_CYCLE_NORMAL); 4684: } 4685: 4686: /* log the value read: */ 4687: tme_m68k_verify_mem32(ic, function_code, ic->tme_m68k_ireg_a7, *_value, TME_BUS_CYCLE_READ); 4688: tme_m68k_log(ic, 1000, TME_OK, 4689: (TME_M68K_LOG_HANDLE(ic), 4690: _("pop32\t%d:0x%08x:\t0x%08x"), 4691: function_code, 4692: ic->tme_m68k_ireg_a7, 4693: *_value)); 4694: if (!TME_M68K_SEQUENCE_RESTARTING) { 4695: ic->tme_m68k_ireg_a7 += sizeof(tme_uint32_t); 4696: } 4697: } 4698: 4699: /* this writes a 32-bit memx value: */ 4700: void 4701: tme_m68k_write_memx32(struct tme_m68k *ic) 4702: { 4703: unsigned int function_code = ic->_tme_m68k_ea_function_code; 4704: tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address; 4705: tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1; 4706: struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); 4707: 1.1.1.3 ! root 4708: #ifdef _TME_M68K_STATS ! 4709: ic->tme_m68k_stats.tme_m68k_stats_memory_total++; ! 4710: #endif /* _TME_M68K_STATS */ ! 4711: 1.1 root 4712: /* log the value written: */ 4713: tme_m68k_verify_mem32(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_memx32, TME_BUS_CYCLE_WRITE); 4714: tme_m68k_log(ic, 1000, TME_OK, 4715: (TME_M68K_LOG_HANDLE(ic), 4716: _("write_memx32\t%d:0x%08x:\t0x%08x"), 4717: ic->_tme_m68k_ea_function_code, 4718: ic->_tme_m68k_ea_address, 4719: ic->tme_m68k_ireg_memx32)); 4720: 4721: /* do the bus cycle(s) ourselves from emulator memory if we can. 4722: the emulator memory allocator and TLB filler must guarantee 4723: that all tme_m68k_tlb_emulator_off_write pointers be 32-bit 4724: aligned, so that a 16-bit-aligned linear address gets a 4725: 16-bit-aligned emulator address: */ 4726: if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING 4727: && !(linear_address_first & 1) 4728: && TME_M68K_TLB_OK_FAST_WRITE(tlb, 4729: function_code, 4730: linear_address_first, 4731: linear_address_last))) { 4732: 4733: /* if the emulator host allows 32-bit quantities to be 4734: transferred to 16-bit aligned addresses, or if this 4735: address is 32-bit aligned, do the transfer as a simple 4736: assignment, otherwise transfer two 16-bit words. 4737: 4738: we need the wrlock if we're on an architecture where 4739: an aligned access may not be atomic, or if we're doing 4740: an unaligned access on an architecture where they may 4741: not be atomic: */ 4742: #if ALIGNOF_INT32_T <= ALIGNOF_INT16_T 4743: #ifdef TME_UNALIGNED_ACCESS_ATOMIC 4744: *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(ic->tme_m68k_ireg_memx32); 4745: #else /* !TME_UNALIGNED_ACCESS_ATOMIC */ 4746: if ((linear_address_first & (sizeof(tme_uint32_t) - 1))) { 4747: tme_memory_unaligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock); 4748: *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(ic->tme_m68k_ireg_memx32); 4749: tme_memory_unaligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4750: } 4751: else { 4752: tme_memory_aligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock); 4753: *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(ic->tme_m68k_ireg_memx32); 4754: tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4755: } 4756: #endif /* !TME_UNALIGNED_ACCESS_ATOMIC */ 4757: #else /* ALIGNOF_INT32_T > ALIGNOF_INT16_T */ 4758: if (TME_SEQUENCE_ACCESS_NOT_COSTLIER || (linear_address_first & (sizeof(tme_uint32_t) - 1))) { 4759: tme_memory_sequence_wrlock(tlb->tme_m68k_tlb_bus_rwlock); 4760: ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first))[0] = tme_htobe_u16(ic->tme_m68k_ireg_memx32 >> 16); 4761: ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first))[1] = tme_htobe_u16(ic->tme_m68k_ireg_memx32 & 0xffff); 4762: tme_memory_sequence_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4763: } 4764: else { 4765: tme_memory_aligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock); 4766: *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(ic->tme_m68k_ireg_memx32); 4767: tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4768: } 4769: #endif /* ALIGNOF_INT32_T != 1 */ 4770: TME_M68K_SEQUENCE_TRANSFER_STEP; 4771: } 4772: 4773: /* otherwise, do the bus cycles the slow way: */ 4774: else { 4775: tme_m68k_write32(ic, tlb, 4776: &ic->_tme_m68k_ea_function_code, 4777: &ic->_tme_m68k_ea_address, 4778: &ic->tme_m68k_ireg_memx32, 4779: TME_M68K_BUS_CYCLE_NORMAL); 4780: } 4781: } 4782: 4783: /* this writes a 32-bit mem value: */ 4784: void 4785: tme_m68k_write_mem32(struct tme_m68k *ic, int ireg) 4786: { 4787: unsigned int function_code = ic->_tme_m68k_ea_function_code; 4788: tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address; 4789: tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1; 4790: struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); 4791: 1.1.1.3 ! root 4792: #ifdef _TME_M68K_STATS ! 4793: ic->tme_m68k_stats.tme_m68k_stats_memory_total++; ! 4794: #endif /* _TME_M68K_STATS */ ! 4795: 1.1 root 4796: /* log the value written: */ 4797: tme_m68k_verify_mem32(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_uint32(ireg), TME_BUS_CYCLE_WRITE); 4798: tme_m68k_log(ic, 1000, TME_OK, 4799: (TME_M68K_LOG_HANDLE(ic), 4800: _("write_mem32\t%d:0x%08x:\t0x%08x"), 4801: ic->_tme_m68k_ea_function_code, 4802: ic->_tme_m68k_ea_address, 4803: ic->tme_m68k_ireg_uint32(ireg))); 4804: 4805: /* do the bus cycle(s) ourselves from emulator memory if we can. 4806: the emulator memory allocator and TLB filler must guarantee 4807: that all tme_m68k_tlb_emulator_off_write pointers be 32-bit 4808: aligned, so that a 16-bit-aligned linear address gets a 4809: 16-bit-aligned emulator address: */ 4810: if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING 4811: && !(linear_address_first & 1) 4812: && TME_M68K_TLB_OK_FAST_WRITE(tlb, 4813: function_code, 4814: linear_address_first, 4815: linear_address_last))) { 4816: 4817: /* if the emulator host allows 32-bit quantities to be 4818: transferred to 16-bit aligned addresses, or if this 4819: address is 32-bit aligned, do the transfer as a simple 4820: assignment, otherwise transfer two 16-bit words. 4821: 4822: we need the wrlock if we're on an architecture where 4823: an aligned access may not be atomic, or if we're doing 4824: an unaligned access on an architecture where they may 4825: not be atomic: */ 4826: #if ALIGNOF_INT32_T <= ALIGNOF_INT16_T 4827: #ifdef TME_UNALIGNED_ACCESS_ATOMIC 4828: *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(ic->tme_m68k_ireg_uint32(ireg)); 4829: #else /* !TME_UNALIGNED_ACCESS_ATOMIC */ 4830: if ((linear_address_first & (sizeof(tme_uint32_t) - 1))) { 4831: tme_memory_unaligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock); 4832: *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(ic->tme_m68k_ireg_uint32(ireg)); 4833: tme_memory_unaligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4834: } 4835: else { 4836: tme_memory_aligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock); 4837: *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(ic->tme_m68k_ireg_uint32(ireg)); 4838: tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4839: } 4840: #endif /* !TME_UNALIGNED_ACCESS_ATOMIC */ 4841: #else /* ALIGNOF_INT32_T > ALIGNOF_INT16_T */ 4842: if (TME_SEQUENCE_ACCESS_NOT_COSTLIER || (linear_address_first & (sizeof(tme_uint32_t) - 1))) { 4843: tme_memory_sequence_wrlock(tlb->tme_m68k_tlb_bus_rwlock); 4844: ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first))[0] = tme_htobe_u16(ic->tme_m68k_ireg_uint32(ireg) >> 16); 4845: ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first))[1] = tme_htobe_u16(ic->tme_m68k_ireg_uint32(ireg) & 0xffff); 4846: tme_memory_sequence_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4847: } 4848: else { 4849: tme_memory_aligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock); 4850: *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(ic->tme_m68k_ireg_uint32(ireg)); 4851: tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4852: } 4853: #endif /* ALIGNOF_INT32_T != 1 */ 4854: TME_M68K_SEQUENCE_TRANSFER_STEP; 4855: } 4856: 4857: /* otherwise, do the bus cycles the slow way: */ 4858: else { 4859: tme_m68k_write32(ic, tlb, 4860: &ic->_tme_m68k_ea_function_code, 4861: &ic->_tme_m68k_ea_address, 4862: &ic->tme_m68k_ireg_uint32(ireg), 4863: TME_M68K_BUS_CYCLE_NORMAL); 4864: } 4865: } 4866: 4867: /* this writes a 32-bit stack value: */ 4868: void 4869: tme_m68k_push32(struct tme_m68k *ic, tme_uint32_t value) 4870: { 4871: unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic); 4872: tme_uint32_t linear_address_first = ic->tme_m68k_ireg_a7 - sizeof(tme_uint32_t); 4873: tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1; 4874: struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); 4875: 1.1.1.3 ! root 4876: #ifdef _TME_M68K_STATS ! 4877: ic->tme_m68k_stats.tme_m68k_stats_memory_total++; ! 4878: #endif /* _TME_M68K_STATS */ ! 4879: 1.1 root 4880: /* log the value written: */ 4881: tme_m68k_verify_mem32(ic, function_code, linear_address_first, value, TME_BUS_CYCLE_WRITE); 4882: tme_m68k_log(ic, 1000, TME_OK, 4883: (TME_M68K_LOG_HANDLE(ic), 4884: _("push32\t%d:0x%08x:\t0x%08x"), 4885: function_code, 4886: linear_address_first, 4887: value)); 4888: 4889: /* do the bus cycle(s) ourselves from emulator memory if we can. 4890: the emulator memory allocator and TLB filler must guarantee 4891: that all tme_m68k_tlb_emulator_off_write pointers be 32-bit 4892: aligned, so that a 16-bit-aligned linear address gets a 4893: 16-bit-aligned emulator address: */ 4894: if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING 4895: && !(linear_address_first & 1) 4896: && TME_M68K_TLB_OK_FAST_WRITE(tlb, 4897: function_code, 4898: linear_address_first, 4899: linear_address_last))) { 4900: 4901: /* if the emulator host allows 32-bit quantities to be 4902: transferred to 16-bit aligned addresses, or if this 4903: address is 32-bit aligned, do the transfer as a simple 4904: assignment, otherwise transfer two 16-bit words. 4905: 4906: we need the wrlock if we're on an architecture where 4907: an aligned access may not be atomic, or if we're doing 4908: an unaligned access on an architecture where they may 4909: not be atomic: */ 4910: #if ALIGNOF_INT32_T <= ALIGNOF_INT16_T 4911: #ifdef TME_UNALIGNED_ACCESS_ATOMIC 4912: *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(value); 4913: #else /* !TME_UNALIGNED_ACCESS_ATOMIC */ 4914: if ((linear_address_first & (sizeof(tme_uint32_t) - 1))) { 4915: tme_memory_unaligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock); 4916: *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(value); 4917: tme_memory_unaligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4918: } 4919: else { 4920: tme_memory_aligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock); 4921: *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(value); 4922: tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4923: } 4924: #endif /* !TME_UNALIGNED_ACCESS_ATOMIC */ 4925: #else /* ALIGNOF_INT32_T > ALIGNOF_INT16_T */ 4926: if (TME_SEQUENCE_ACCESS_NOT_COSTLIER || (linear_address_first & (sizeof(tme_uint32_t) - 1))) { 4927: tme_memory_sequence_wrlock(tlb->tme_m68k_tlb_bus_rwlock); 4928: ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first))[0] = tme_htobe_u16(value >> 16); 4929: ((tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first))[1] = tme_htobe_u16(value & 0xffff); 4930: tme_memory_sequence_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4931: } 4932: else { 4933: tme_memory_aligned_wrlock(tlb->tme_m68k_tlb_bus_rwlock); 4934: *((tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first)) = tme_htobe_u32(value); 4935: tme_memory_aligned_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4936: } 4937: #endif /* ALIGNOF_INT32_T != 1 */ 4938: TME_M68K_SEQUENCE_TRANSFER_STEP; 4939: } 4940: 4941: /* otherwise, do the bus cycles the slow way: */ 4942: else { 4943: tme_m68k_write32(ic, tlb, 4944: &function_code, 4945: &linear_address_first, 4946: &value, 4947: TME_M68K_BUS_CYCLE_NORMAL); 4948: } 4949: if (!TME_M68K_SEQUENCE_RESTARTING) { 4950: ic->tme_m68k_ireg_a7 -= sizeof(tme_uint32_t); 4951: } 4952: } 4953: 4954: /* this reads a any-bit mem value: */ 4955: void 4956: tme_m68k_read_mem(struct tme_m68k *ic, tme_uint8_t *buffer, unsigned int count) 4957: { 4958: unsigned int function_code = ic->_tme_m68k_ea_function_code; 4959: tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address; 4960: tme_uint32_t linear_address_last = linear_address_first + count - 1; 4961: struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); 4962: 1.1.1.3 ! root 4963: #ifdef _TME_M68K_STATS ! 4964: ic->tme_m68k_stats.tme_m68k_stats_memory_total++; ! 4965: #endif /* _TME_M68K_STATS */ ! 4966: 1.1 root 4967: /* do the bus cycle(s) ourselves from emulator memory if we can. 4968: the emulator memory allocator and TLB filler must guarantee 4969: that all tme_m68k_tlb_emulator_off_read pointers be 32-bit 4970: aligned, so that a 16-bit-aligned linear address gets a 4971: 16-bit-aligned emulator address: */ 4972: if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING 4973: && !(linear_address_first & 1) 4974: && TME_M68K_TLB_OK_FAST_READ(tlb, 4975: function_code, 4976: linear_address_first, 4977: linear_address_last))) { 4978: 4979: tme_memory_sequence_rdlock(tlb->tme_m68k_tlb_bus_rwlock); 4980: memcpy(buffer, (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first), count); 4981: tme_memory_sequence_unlock(tlb->tme_m68k_tlb_bus_rwlock); 4982: TME_M68K_SEQUENCE_TRANSFER_STEP; 4983: } 4984: 4985: /* otherwise, do the bus cycles the slow way: */ 4986: else { 4987: tme_m68k_read(ic, tlb, &ic->_tme_m68k_ea_function_code, &ic->_tme_m68k_ea_address, buffer, count, TME_M68K_BUS_CYCLE_RAW); 4988: } 4989: 4990: /* log the value read: */ 4991: tme_m68k_verify_mem_any(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, buffer, count, TME_BUS_CYCLE_READ); 4992: tme_m68k_log_start(ic, 1000, TME_OK) { 4993: unsigned int byte_i; 4994: tme_log_part(TME_M68K_LOG_HANDLE(ic), 4995: _("read_mem %d:0x%08x count %d:"), 4996: ic->_tme_m68k_ea_function_code, 4997: ic->_tme_m68k_ea_address, 4998: count); 4999: for (byte_i = 0; byte_i < count ; byte_i++) { 5000: tme_log_part(TME_M68K_LOG_HANDLE(ic), " 0x%02x", (buffer)[byte_i]); 5001: } 5002: } tme_m68k_log_finish(ic); 5003: } 5004: 5005: /* this reads a region of address space using actual bus cycles: */ 5006: void 5007: tme_m68k_read(struct tme_m68k *ic, 5008: struct tme_m68k_tlb *tlb, 5009: unsigned int *_function_code, 5010: tme_uint32_t *_linear_address, 5011: tme_uint8_t *reg, 5012: unsigned int reg_size, 5013: unsigned int flags) 5014: { 5015: unsigned int function_code; 5016: tme_uint32_t linear_address; 5017: tme_bus_addr_t physical_address; 5018: int shift; 5019: struct tme_bus_cycle cycle; 5020: unsigned int transferred, resid, cycle_size; 5021: int exception; 5022: tme_rwlock_t *rmw_rwlock; 5023: int err; 5024: #ifndef WORDS_BIGENDIAN 5025: tme_uint8_t *reg_p; 5026: unsigned int buffer_i; 5027: #endif /* !WORDS_BIGENDIAN */ 5028: 5029: /* if we're not restarting, everything is fresh: */ 5030: if (!TME_M68K_SEQUENCE_RESTARTING) { 5031: function_code = *_function_code; 5032: linear_address = *_linear_address; 5033: transferred = 0; 5034: } 5035: 5036: /* otherwise, if this is the transfer that faulted, restore 5037: our state to the cycle that faulted, then take into account 5038: any data provided by a software rerun of the faulted cycle: */ 5039: else if (ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted 5040: == ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next) { 5041: function_code = *_function_code = ic->_tme_m68k_group0_function_code; 5042: linear_address = ic->_tme_m68k_group0_address; 5043: transferred = ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted_after; 5044: if (transferred >= reg_size) abort(); 5045: *_linear_address = linear_address - transferred; 5046: resid = reg_size - transferred; 5047: if (ic->_tme_m68k_group0_buffer_read_size > resid) abort(); 5048: if (ic->_tme_m68k_group0_buffer_read_softrr > resid) abort(); 5049: if (ic->_tme_m68k_group0_buffer_read_softrr > 0) { 5050: #ifdef WORDS_BIGENDIAN 5051: memcpy(reg + transferred, 5052: ic->_tme_m68k_group0_buffer_read, 5053: ic->_tme_m68k_group0_buffer_read_size); 5054: #else /* !WORDS_BIGENDIAN */ 5055: reg_p = (reg + reg_size - 1) - transferred; 5056: for (buffer_i = 0; 5057: buffer_i < ic->_tme_m68k_group0_buffer_read_size; 5058: buffer_i++) { 5059: *(reg_p--) = ic->_tme_m68k_group0_buffer_read[buffer_i]; 5060: } 5061: #endif /* !WORDS_BIGENDIAN */ 5062: } 5063: transferred += ic->_tme_m68k_group0_buffer_read_softrr; 5064: } 5065: 5066: /* otherwise, a later transfer has faulted. just step the 5067: transfer number and return: */ 5068: else { 5069: TME_M68K_SEQUENCE_TRANSFER_STEP; 5070: return; 5071: } 5072: 5073: /* do as many bus cycles as needed to complete the transfer: */ 5074: rmw_rwlock = tlb->tme_m68k_tlb_bus_rwlock; 5075: exception = TME_M68K_EXCEPTION_NONE; 5076: cycle_size = 0; 5077: for(; transferred < reg_size; ) { 5078: resid = reg_size - transferred; 5079: 5080: /* start the bus cycle structure: */ 5081: cycle.tme_bus_cycle_type = TME_BUS_CYCLE_READ; 5082: if (TME_ENDIAN_NATIVE == TME_ENDIAN_BIG 5083: || (flags & TME_M68K_BUS_CYCLE_RAW)) { 5084: cycle.tme_bus_cycle_buffer = reg + transferred; 5085: cycle.tme_bus_cycle_buffer_increment = 1; 5086: } 5087: else { 5088: cycle.tme_bus_cycle_buffer = reg + reg_size - (1 + transferred); 5089: cycle.tme_bus_cycle_buffer_increment = -1; 5090: } 5091: 5092: /* if we're emulating a CPU with a 16-bit bus interface: */ 5093: if (ic->_tme_m68k_bus_16bit) { 5094: 5095: /* if we're trying to transfer a non-power-of-two 5096: number of bytes, either the CPU is broken (no 5097: instructions ever transfer a non-power-of-two 5098: number of bytes), or this function allowed an 5099: unaligned transfer: */ 5100: assert((resid & (resid - 1)) == 0 5101: || (flags & TME_M68K_BUS_CYCLE_RAW)); 5102: 5103: /* only byte transfers can be unaligned: */ 5104: if (resid > sizeof(tme_uint8_t) 5105: && (linear_address & 1)) { 1.1.1.3 ! root 5106: exception = TME_M68K_EXCEPTION_AERR; 1.1 root 5107: break; 5108: } 5109: 5110: /* set the bus-size specific parts of the bus cycle structure: */ 5111: cycle_size = TME_MIN(resid, sizeof(tme_uint16_t)); 5112: cycle.tme_bus_cycle_size = cycle_size; 5113: cycle.tme_bus_cycle_port = TME_BUS_CYCLE_PORT(0, TME_BUS16_LOG2); 5114: cycle.tme_bus_cycle_lane_routing = 5115: &tme_m68k_router_16[TME_M68K_BUS_ROUTER_INDEX(TME_BUS16_LOG2, cycle_size, linear_address)]; 5116: } 5117: 5118: /* otherwise we're emulating a CPU with a 32-bit bus interface: */ 5119: else { 5120: 5121: /* an instruction fetch must be aligned: */ 5122: if (flags & TME_M68K_BUS_CYCLE_FETCH) { 5123: if (linear_address & 1) { 1.1.1.3 ! root 5124: exception = TME_M68K_EXCEPTION_AERR; 1.1 root 5125: break; 5126: } 5127: assert(!(resid & 1)); 5128: } 5129: 5130: /* set the bus-size specific parts of the bus cycle structure: */ 5131: cycle_size = TME_MIN(resid, sizeof(tme_uint32_t) - (linear_address & (sizeof(tme_uint32_t) - 1))); 5132: cycle.tme_bus_cycle_size = cycle_size; 5133: cycle.tme_bus_cycle_port = TME_BUS_CYCLE_PORT(0, TME_BUS32_LOG2); 5134: cycle.tme_bus_cycle_lane_routing = 5135: &tme_m68k_router_32[TME_M68K_BUS_ROUTER_INDEX(TME_BUS32_LOG2, cycle_size, linear_address)]; 5136: } 5137: 5138: /* reload the TLB entry: */ 5139: if (!TME_M68K_TLB_OK_SLOW_READ(tlb, function_code, linear_address)) { 5140: tme_m68k_tlb_fill(ic, tlb, 5141: function_code, 5142: linear_address, 5143: TME_BUS_CYCLE_READ); 5144: } 5145: 5146: /* if this is a part of a read/modify/write cycle: */ 5147: if (flags & TME_M68K_BUS_CYCLE_RMW) { 5148: 5149: /* if this TLB entry doesn't support fast reads, or 5150: if the TLB lock has changed, that's a bus error. 5151: see the discussion in tme_m68k_rmw_start: */ 5152: if (!TME_M68K_TLB_OK_FAST_READ(tlb, function_code, linear_address, linear_address) 5153: || (rmw_rwlock != NULL 5154: && rmw_rwlock != tlb->tme_m68k_tlb_bus_rwlock)) { 1.1.1.3 ! root 5155: exception = TME_M68K_EXCEPTION_BERR; 1.1 root 5156: break; 5157: } 5158: 5159: /* if we haven't locked this memory yet, do so: */ 5160: if (rmw_rwlock == NULL) { 5161: rmw_rwlock = tlb->tme_m68k_tlb_bus_rwlock; 5162: tme_rwlock_wrlock(rmw_rwlock); 5163: } 5164: } 5165: 5166: /* form the physical address for the bus cycle handler: */ 5167: physical_address = tlb->tme_m68k_tlb_addr_offset + linear_address; 5168: shift = tlb->tme_m68k_tlb_addr_shift; 5169: if (shift < 0) { 5170: physical_address <<= (0 - shift); 5171: } 5172: else if (shift > 0) { 5173: physical_address >>= shift; 5174: } 5175: cycle.tme_bus_cycle_address = physical_address; 5176: 5177: /* run the bus cycle: */ 5178: err = (*tlb->tme_m68k_tlb_bus_tlb.tme_bus_tlb_cycle) 5179: (tlb->tme_m68k_tlb_bus_tlb.tme_bus_tlb_cycle_private, &cycle); 5180: 5181: /* if we deadlocked, we have no locks to release 5182: ourselves, so sleep a while waiting for things 5183: to clear up, then try again: */ 5184: if (err == TME_EDEADLK) { 5185: TME_THREAD_DEADLOCK_SLEEP(); 5186: cycle.tme_bus_cycle_address = physical_address; 5187: } 5188: 1.1.1.3 ! root 5189: /* otherwise, if we didn't get a bus error, but some ! 5190: synchronous event has happened: */ ! 5191: else if (err == TME_BUS_CYCLE_SYNCHRONOUS_EVENT) { ! 5192: ! 5193: /* after the currently executing instruction finishes, check ! 5194: for external resets, halts, or interrupts: */ ! 5195: ic->_tme_m68k_instruction_burst_remaining = 0; ! 5196: } ! 5197: 1.1 root 5198: /* otherwise, any other error might be a bus error: */ 5199: else if (err != TME_OK) { 5200: err = tme_bus_tlb_fault(&tlb->tme_m68k_tlb_bus_tlb, &cycle, err); 5201: if (err != TME_OK) { 1.1.1.3 ! root 5202: exception = TME_M68K_EXCEPTION_BERR; 1.1 root 5203: break; 5204: } 5205: } 5206: 5207: /* update: */ 5208: linear_address += cycle.tme_bus_cycle_size; 5209: transferred += cycle.tme_bus_cycle_size; 5210: } 5211: 5212: /* if we got an exception and there is a locked 5213: read/modify/write rwlock, unlock it: */ 5214: if (exception != TME_M68K_EXCEPTION_NONE 5215: && (flags & TME_M68K_BUS_CYCLE_RMW) 5216: && rmw_rwlock != NULL) { 5217: tme_rwlock_unlock(rmw_rwlock); 5218: } 5219: 5220: /* if we faulted, stash the information the fault stacker 5221: will need and start exception processing: */ 5222: if (exception != TME_M68K_EXCEPTION_NONE) { 5223: ic->_tme_m68k_group0_flags = flags | TME_M68K_BUS_CYCLE_READ; 5224: ic->_tme_m68k_group0_function_code = function_code; 5225: ic->_tme_m68k_group0_address = linear_address; 5226: ic->_tme_m68k_group0_sequence = ic->_tme_m68k_sequence; 5227: ic->_tme_m68k_group0_sequence._tme_m68k_sequence_transfer_faulted_after = transferred; 5228: ic->_tme_m68k_group0_buffer_read_size = cycle_size; 5229: if (ic->_tme_m68k_group0_hook != NULL) { 5230: (*ic->_tme_m68k_group0_hook)(ic); 5231: } 5232: ic->_tme_m68k_group0_sequence._tme_m68k_sequence_transfer_faulted = 5233: ic->_tme_m68k_group0_sequence._tme_m68k_sequence_transfer_next; 5234: tme_m68k_exception(ic, exception); 5235: } 5236: 5237: /* otherwise, this transfer has now completed: */ 5238: TME_M68K_SEQUENCE_TRANSFER_STEP; 5239: } 5240: 5241: /* this writes a any-bit mem value: */ 5242: void 5243: tme_m68k_write_mem(struct tme_m68k *ic, tme_uint8_t *buffer, unsigned int count) 5244: { 5245: unsigned int function_code = ic->_tme_m68k_ea_function_code; 5246: tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address; 5247: tme_uint32_t linear_address_last = linear_address_first + count - 1; 5248: struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); 5249: 1.1.1.3 ! root 5250: #ifdef _TME_M68K_STATS ! 5251: ic->tme_m68k_stats.tme_m68k_stats_memory_total++; ! 5252: #endif /* _TME_M68K_STATS */ ! 5253: 1.1 root 5254: /* log the value written: */ 5255: tme_m68k_verify_mem_any(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, buffer, count, TME_BUS_CYCLE_WRITE); 5256: tme_m68k_log_start(ic, 1000, TME_OK) { 5257: unsigned int byte_i; 5258: tme_log_part(TME_M68K_LOG_HANDLE(ic), 5259: _("write_mem %d:0x%08x count %d:"), 5260: ic->_tme_m68k_ea_function_code, 5261: ic->_tme_m68k_ea_address, 5262: count); 5263: for (byte_i = 0; byte_i < count ; byte_i++) { 5264: tme_log_part(TME_M68K_LOG_HANDLE(ic), " 0x%02x", (buffer)[byte_i]); 5265: } 5266: } tme_m68k_log_finish(ic); 5267: 5268: /* do the bus cycle(s) ourselves from emulator memory if we can. 5269: the emulator memory allocator and TLB filler must guarantee 5270: that all tme_m68k_tlb_emulator_off_write pointers be 32-bit 5271: aligned, so that a 16-bit-aligned linear address gets a 5272: 16-bit-aligned emulator address: */ 5273: if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING 5274: && !(linear_address_first & 1) 5275: && TME_M68K_TLB_OK_FAST_WRITE(tlb, 5276: function_code, 5277: linear_address_first, 5278: linear_address_last))) { 5279: 5280: tme_memory_sequence_wrlock(tlb->tme_m68k_tlb_bus_rwlock); 5281: memcpy((tlb->tme_m68k_tlb_emulator_off_write + linear_address_first), buffer, count); 5282: tme_memory_sequence_unlock(tlb->tme_m68k_tlb_bus_rwlock); 5283: TME_M68K_SEQUENCE_TRANSFER_STEP; 5284: } 5285: 5286: /* otherwise, do the bus cycles the slow way: */ 5287: else { 5288: tme_m68k_write(ic, tlb, &ic->_tme_m68k_ea_function_code, &ic->_tme_m68k_ea_address, buffer, count, TME_M68K_BUS_CYCLE_RAW); 5289: } 5290: } 5291: 5292: /* this writes a region of address space using actual bus cycles: */ 5293: void 5294: tme_m68k_write(struct tme_m68k *ic, 5295: struct tme_m68k_tlb *tlb, 5296: unsigned int *_function_code, 5297: tme_uint32_t *_linear_address, 5298: tme_uint8_t *reg, 5299: unsigned int reg_size, 5300: unsigned int flags) 5301: { 5302: unsigned int function_code; 5303: tme_uint32_t linear_address; 5304: tme_bus_addr_t physical_address; 5305: int shift; 5306: struct tme_bus_cycle cycle; 5307: unsigned int transferred, resid, cycle_size; 5308: int exception; 5309: tme_rwlock_t *rmw_rwlock; 5310: int err; 5311: #ifndef WORDS_BIGENDIAN 5312: tme_uint8_t *reg_p; 5313: unsigned int buffer_i; 5314: #endif /* !WORDS_BIGENDIAN */ 5315: 5316: /* if we're not restarting, everything is fresh: */ 5317: if (!TME_M68K_SEQUENCE_RESTARTING) { 5318: function_code = *_function_code; 5319: linear_address = *_linear_address; 5320: transferred = 0; 5321: } 5322: 5323: /* otherwise, if this is the transfer that faulted, restore 5324: our state to the cycle that faulted, then take into account 5325: any data provided by a software rerun of the faulted cycle: */ 5326: else if (ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted 5327: == ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next) { 5328: function_code = *_function_code = ic->_tme_m68k_group0_function_code; 5329: linear_address = ic->_tme_m68k_group0_address; 5330: transferred = ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted_after; 5331: if (transferred >= reg_size) abort(); 5332: *_linear_address = linear_address - transferred; 5333: resid = reg_size - transferred; 5334: if (ic->_tme_m68k_group0_buffer_write_size > resid) abort(); 5335: if (ic->_tme_m68k_group0_buffer_write_softrr > resid) abort(); 5336: if (ic->_tme_m68k_group0_buffer_write_softrr == 0) { 5337: #ifdef WORDS_BIGENDIAN 5338: memcpy(reg + transferred, 5339: ic->_tme_m68k_group0_buffer_write, 5340: ic->_tme_m68k_group0_buffer_write_size); 5341: #else /* !WORDS_BIGENDIAN */ 5342: reg_p = (reg + reg_size - 1) - transferred; 5343: for (buffer_i = 0; 5344: buffer_i < ic->_tme_m68k_group0_buffer_write_size; 5345: buffer_i++) { 5346: *(reg_p--) = ic->_tme_m68k_group0_buffer_write[buffer_i]; 5347: } 5348: #endif /* !WORDS_BIGENDIAN */ 5349: } 5350: transferred += ic->_tme_m68k_group0_buffer_write_softrr; 5351: } 5352: 5353: /* otherwise, a later transfer has faulted. just step the 5354: transfer number and return: */ 5355: else { 5356: TME_M68K_SEQUENCE_TRANSFER_STEP; 5357: return; 5358: } 5359: 5360: /* do as many bus cycles as needed to complete the transfer: */ 5361: rmw_rwlock = tlb->tme_m68k_tlb_bus_rwlock; 5362: exception = TME_M68K_EXCEPTION_NONE; 5363: cycle_size = 0; 5364: for(; transferred < reg_size; ) { 5365: resid = reg_size - transferred; 5366: 5367: /* start the bus cycle structure: */ 5368: cycle.tme_bus_cycle_type = TME_BUS_CYCLE_WRITE; 5369: if (TME_ENDIAN_NATIVE == TME_ENDIAN_BIG 5370: || (flags & TME_M68K_BUS_CYCLE_RAW)) { 5371: cycle.tme_bus_cycle_buffer = reg + transferred; 5372: cycle.tme_bus_cycle_buffer_increment = 1; 5373: } 5374: else { 5375: cycle.tme_bus_cycle_buffer = reg + reg_size - (1 + transferred); 5376: cycle.tme_bus_cycle_buffer_increment = -1; 5377: } 5378: 5379: /* if we're emulating a CPU with a 16-bit bus interface: */ 5380: if (ic->_tme_m68k_bus_16bit) { 5381: 5382: /* if we're trying to transfer a non-power-of-two 5383: number of bytes, either the CPU is broken (no 5384: instructions ever transfer a non-power-of-two 5385: number of bytes), or this function allowed an 5386: unaligned transfer: */ 5387: assert((resid & (resid - 1)) == 0 5388: || (flags & TME_M68K_BUS_CYCLE_RAW)); 5389: 5390: /* only byte transfers can be unaligned: */ 5391: if (resid > sizeof(tme_uint8_t) 5392: && (linear_address & 1)) { 1.1.1.3 ! root 5393: exception = TME_M68K_EXCEPTION_AERR; 1.1 root 5394: break; 5395: } 5396: 5397: /* set the bus-size specific parts of the bus cycle structure: */ 5398: cycle_size = TME_MIN(resid, sizeof(tme_uint16_t)); 5399: cycle.tme_bus_cycle_size = cycle_size; 5400: cycle.tme_bus_cycle_port = TME_BUS_CYCLE_PORT(0, TME_BUS16_LOG2); 5401: cycle.tme_bus_cycle_lane_routing = 5402: &tme_m68k_router_16[TME_M68K_BUS_ROUTER_INDEX(TME_BUS16_LOG2, cycle_size, linear_address)]; 5403: } 5404: 5405: /* otherwise we're emulating a CPU with a 32-bit bus interface: */ 5406: else { 5407: 5408: /* set the bus-size specific parts of the bus cycle structure: */ 5409: cycle_size = TME_MIN(resid, sizeof(tme_uint32_t) - (linear_address & (sizeof(tme_uint32_t) - 1))); 5410: cycle.tme_bus_cycle_size = cycle_size; 5411: cycle.tme_bus_cycle_port = TME_BUS_CYCLE_PORT(0, TME_BUS32_LOG2); 5412: cycle.tme_bus_cycle_lane_routing = 5413: &tme_m68k_router_32[TME_M68K_BUS_ROUTER_INDEX(TME_BUS32_LOG2, cycle_size, linear_address)]; 5414: } 5415: 5416: /* reload the TLB entry: */ 5417: if (!TME_M68K_TLB_OK_SLOW_WRITE(tlb, function_code, linear_address)) { 5418: tme_m68k_tlb_fill(ic, tlb, 5419: function_code, 5420: linear_address, 5421: TME_BUS_CYCLE_WRITE); 5422: } 5423: 5424: /* if this is a part of a read/modify/write cycle: */ 5425: if (flags & TME_M68K_BUS_CYCLE_RMW) { 5426: 5427: /* if this TLB entry doesn't support fast writes, or 5428: if the TLB lock has changed, that's a bus error. 5429: see the discussion in tme_m68k_rmw_start: */ 5430: if (!TME_M68K_TLB_OK_FAST_WRITE(tlb, function_code, linear_address, linear_address) 5431: || (rmw_rwlock != NULL 5432: && rmw_rwlock != tlb->tme_m68k_tlb_bus_rwlock)) { 1.1.1.3 ! root 5433: exception = TME_M68K_EXCEPTION_BERR; 1.1 root 5434: break; 5435: } 5436: 5437: /* if we haven't locked this memory yet, do so: */ 5438: if (rmw_rwlock == NULL) { 5439: rmw_rwlock = tlb->tme_m68k_tlb_bus_rwlock; 5440: tme_rwlock_wrlock(rmw_rwlock); 5441: } 5442: } 5443: 5444: /* form the physical address for the bus cycle handler: */ 5445: physical_address = tlb->tme_m68k_tlb_addr_offset + linear_address; 5446: shift = tlb->tme_m68k_tlb_addr_shift; 5447: if (shift < 0) { 5448: physical_address <<= (0 - shift); 5449: } 5450: else if (shift > 0) { 5451: physical_address >>= shift; 5452: } 5453: cycle.tme_bus_cycle_address = physical_address; 5454: 5455: /* run the bus cycle: */ 5456: err = (*tlb->tme_m68k_tlb_bus_tlb.tme_bus_tlb_cycle) 5457: (tlb->tme_m68k_tlb_bus_tlb.tme_bus_tlb_cycle_private, &cycle); 5458: 5459: /* if we deadlocked, we have no locks to release 5460: ourselves, so sleep a while waiting for things 5461: to clear up, then try again: */ 5462: if (err == TME_EDEADLK) { 5463: TME_THREAD_DEADLOCK_SLEEP(); 5464: cycle.tme_bus_cycle_address = physical_address; 5465: } 5466: 1.1.1.3 ! root 5467: /* otherwise, if we didn't get a bus error, but some ! 5468: synchronous event has happened: */ ! 5469: else if (err == TME_BUS_CYCLE_SYNCHRONOUS_EVENT) { ! 5470: ! 5471: /* after the currently executing instruction finishes, check ! 5472: for external resets, halts, or interrupts: */ ! 5473: ic->_tme_m68k_instruction_burst_remaining = 0; ! 5474: } ! 5475: 1.1 root 5476: /* otherwise, any other error might be a bus error: */ 5477: else if (err != TME_OK) { 5478: err = tme_bus_tlb_fault(&tlb->tme_m68k_tlb_bus_tlb, &cycle, err); 5479: if (err != TME_OK) { 1.1.1.3 ! root 5480: exception = TME_M68K_EXCEPTION_BERR; 1.1 root 5481: break; 5482: } 5483: } 5484: 5485: /* update: */ 5486: linear_address += cycle.tme_bus_cycle_size; 5487: transferred += cycle.tme_bus_cycle_size; 5488: } 5489: 5490: /* if we got an exception and there is a locked 5491: read/modify/write rwlock, unlock it: */ 5492: if (exception != TME_M68K_EXCEPTION_NONE 5493: && (flags & TME_M68K_BUS_CYCLE_RMW) 5494: && rmw_rwlock != NULL) { 5495: tme_rwlock_unlock(rmw_rwlock); 5496: } 5497: 5498: /* if we faulted, stash the information the fault stacker 5499: will need and start exception processing: */ 5500: if (exception != TME_M68K_EXCEPTION_NONE) { 5501: ic->_tme_m68k_group0_flags = flags; 5502: ic->_tme_m68k_group0_function_code = function_code; 5503: ic->_tme_m68k_group0_address = linear_address; 5504: ic->_tme_m68k_group0_sequence = ic->_tme_m68k_sequence; 5505: ic->_tme_m68k_group0_sequence._tme_m68k_sequence_transfer_faulted_after = transferred; 5506: ic->_tme_m68k_group0_buffer_write_size = cycle_size; 5507: #ifdef WORDS_BIGENDIAN 5508: memcpy(ic->_tme_m68k_group0_buffer_write, 5509: reg + transferred, 5510: ic->_tme_m68k_group0_buffer_write_size); 5511: #else /* !WORDS_BIGENDIAN */ 5512: reg_p = (reg + reg_size - 1) - transferred; 5513: for (buffer_i = 0; 5514: buffer_i < ic->_tme_m68k_group0_buffer_write_size; 5515: buffer_i++) { 5516: ic->_tme_m68k_group0_buffer_write[buffer_i] = *(reg_p--); 5517: } 5518: #endif /* !WORDS_BIGENDIAN */ 5519: if (ic->_tme_m68k_group0_hook != NULL) { 5520: (*ic->_tme_m68k_group0_hook)(ic); 5521: } 5522: ic->_tme_m68k_group0_sequence._tme_m68k_sequence_transfer_faulted = 5523: ic->_tme_m68k_group0_sequence._tme_m68k_sequence_transfer_next; 5524: tme_m68k_exception(ic, exception); 5525: } 5526: 5527: /* otherwise, this transfer has now completed: */ 5528: TME_M68K_SEQUENCE_TRANSFER_STEP; 5529: } 5530: 5531: TME_M68K_INSN(tme_m68k_abcd) 5532: { 5533: tme_uint8_t dst, dst_msd, dst_lsd; 5534: tme_uint8_t src, src_msd, src_lsd; 5535: tme_uint8_t res, res_msd, res_lsd; 5536: tme_uint8_t flags; 5537: int memory; 5538: int rx, ry, function_code; 5539: 5540: TME_M68K_INSN_CANFAULT; 5541: 5542: /* load the operands: */ 5543: rx = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3); 5544: ry = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3); 5545: memory = (TME_M68K_INSN_OPCODE & TME_BIT(3)) != 0; 5546: function_code = TME_M68K_FUNCTION_CODE_DATA(ic); 5547: if (memory) { 5548: if (!TME_M68K_SEQUENCE_RESTARTING) { 5549: ic->_tme_m68k_ea_function_code = function_code; 5550: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + rx); 5551: } 5552: tme_m68k_read_memx8(ic); 5553: if (!TME_M68K_SEQUENCE_RESTARTING) { 5554: ic->_tme_m68k_ea_function_code = function_code; 5555: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ry); 5556: } 5557: tme_m68k_read_mem8(ic, TME_M68K_IREG_MEMY32); 5558: src = ic->tme_m68k_ireg_memx8; 5559: dst = ic->tme_m68k_ireg_memy8; 5560: } 5561: else { 5562: src = ic->tme_m68k_ireg_uint8(rx << 2); 5563: dst = ic->tme_m68k_ireg_uint8(ry << 2); 5564: } 5565: dst_lsd = TME_FIELD_EXTRACTU(dst, 0, 4); 5566: dst_msd = TME_FIELD_EXTRACTU(dst, 4, 4); 5567: src_lsd = TME_FIELD_EXTRACTU(src, 0, 4); 5568: src_msd = TME_FIELD_EXTRACTU(src, 4, 4); 5569: 5570: /* perform the operation: */ 5571: res_lsd = dst_lsd + src_lsd + ((ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X) != 0); 5572: res_msd = dst_msd + src_msd; 5573: flags = 0; 5574: if (res_lsd > 9) { 5575: res_lsd -= 10; 5576: res_msd += 1; 5577: } 5578: if (res_msd > 9) { 5579: res_msd -= 10; 5580: flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X; 5581: } 5582: res = (res_msd << 4) + (res_lsd & 0xf); 5583: if (res == 0) flags |= TME_M68K_FLAG_N; 5584: 5585: /* store the result and set the flags: */ 5586: if (memory) { 5587: if (!TME_M68K_SEQUENCE_RESTARTING) { 5588: ic->tme_m68k_ireg_memx8 = res; 5589: ic->_tme_m68k_ea_function_code = function_code; 5590: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ry); 5591: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + rx) += sizeof(tme_uint8_t) + ((rx + 1) >> 3); 5592: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ry) += sizeof(tme_uint8_t) + ((ry + 1) >> 3); 5593: ic->tme_m68k_ireg_ccr = flags; 5594: } 5595: tme_m68k_write_memx8(ic); 5596: } 5597: else { 5598: ic->tme_m68k_ireg_uint8(ry << 2) = res; 5599: ic->tme_m68k_ireg_ccr = flags; 5600: } 5601: 5602: TME_M68K_INSN_OK; 5603: } 5604: 5605: TME_M68K_INSN(tme_m68k_sbcd) 5606: { 5607: tme_uint8_t dst, dst_msd, dst_lsd; 5608: tme_uint8_t src, src_msd, src_lsd; 5609: tme_uint8_t res, res_msd, res_lsd; 5610: tme_uint8_t flags; 5611: int memory; 5612: int rx, ry, function_code; 5613: 5614: TME_M68K_INSN_CANFAULT; 5615: 5616: /* load the operands: */ 5617: rx = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3); 5618: ry = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3); 5619: memory = (TME_M68K_INSN_OPCODE & TME_BIT(3)) != 0; 5620: function_code = TME_M68K_FUNCTION_CODE_DATA(ic); 5621: if (memory) { 5622: if (!TME_M68K_SEQUENCE_RESTARTING) { 5623: ic->_tme_m68k_ea_function_code = function_code; 5624: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + rx); 5625: } 5626: tme_m68k_read_memx8(ic); 5627: if (!TME_M68K_SEQUENCE_RESTARTING) { 5628: ic->_tme_m68k_ea_function_code = function_code; 5629: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ry); 5630: } 5631: tme_m68k_read_mem8(ic, TME_M68K_IREG_MEMY32); 5632: src = ic->tme_m68k_ireg_memx8; 5633: dst = ic->tme_m68k_ireg_memy8; 5634: } 5635: else { 5636: src = ic->tme_m68k_ireg_uint8(rx << 2); 5637: dst = ic->tme_m68k_ireg_uint8(ry << 2); 5638: } 5639: dst_lsd = TME_FIELD_EXTRACTU(dst, 0, 4); 5640: dst_msd = TME_FIELD_EXTRACTU(dst, 4, 4); 5641: src_lsd = TME_FIELD_EXTRACTU(src, 0, 4); 5642: src_msd = TME_FIELD_EXTRACTU(src, 4, 4); 5643: 5644: /* perform the operation: */ 5645: res_lsd = dst_lsd - src_lsd - ((ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X) != 0); 5646: res_msd = dst_msd - src_msd; 5647: flags = 0; 5648: if (res_lsd > 9) { 5649: res_lsd += 10; 5650: res_msd -= 1; 5651: } 5652: if (res_msd > 9) { 5653: res_msd += 10; 5654: flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X; 5655: } 5656: res = (res_msd << 4) + (res_lsd & 0xf); 5657: if (res == 0) flags |= TME_M68K_FLAG_N; 5658: 5659: /* store the result and set the flags: */ 5660: if (memory) { 5661: if (!TME_M68K_SEQUENCE_RESTARTING) { 5662: ic->tme_m68k_ireg_memx8 = res; 5663: ic->_tme_m68k_ea_function_code = function_code; 5664: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ry); 5665: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + rx) += sizeof(tme_uint8_t) + ((rx + 1) >> 3); 5666: ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ry) += sizeof(tme_uint8_t) + ((ry + 1) >> 3); 5667: ic->tme_m68k_ireg_ccr = flags; 5668: } 5669: tme_m68k_write_memx8(ic); 5670: } 5671: else { 5672: ic->tme_m68k_ireg_uint8(ry << 2) = res; 5673: ic->tme_m68k_ireg_ccr = flags; 5674: } 5675: 5676: TME_M68K_INSN_OK; 5677: } 5678: 5679: TME_M68K_INSN(tme_m68k_nbcd) 5680: { 5681: tme_uint8_t dst, dst_msd, dst_lsd; 5682: tme_uint8_t src, src_msd, src_lsd; 5683: tme_uint8_t res, res_msd, res_lsd; 5684: tme_uint8_t flags; 5685: 5686: dst = 0x00; 5687: src = TME_M68K_INSN_OP1(tme_uint8_t); 5688: dst_lsd = TME_FIELD_EXTRACTU(dst, 0, 4); 5689: dst_msd = TME_FIELD_EXTRACTU(dst, 4, 4); 5690: src_lsd = TME_FIELD_EXTRACTU(src, 0, 4); 5691: src_msd = TME_FIELD_EXTRACTU(src, 4, 4); 5692: 5693: /* perform the operation: */ 5694: res_lsd = dst_lsd - src_lsd - ((ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X) != 0); 5695: res_msd = dst_msd - src_msd; 5696: flags = 0; 5697: if (res_lsd > 9) { 5698: res_lsd += 10; 5699: res_msd -= 1; 5700: } 5701: if (res_msd > 9) { 5702: res_msd += 10; 5703: flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X; 5704: } 5705: res = (res_msd << 4) + (res_lsd & 0xf); 5706: if (res == 0) flags |= TME_M68K_FLAG_N; 5707: 5708: /* store the result and set the flags: */ 5709: TME_M68K_INSN_OP1(tme_uint8_t) = res; 5710: ic->tme_m68k_ireg_ccr = flags; 5711: 5712: TME_M68K_INSN_OK; 5713: } 5714: 5715: TME_M68K_INSN(tme_m68k_ori_ccr) 5716: { 5717: tme_uint8_t reg; 5718: reg = ic->tme_m68k_ireg_ccr | (TME_M68K_INSN_OP0(tme_uint8_t) & TME_M68K_FLAG_CCR); 5719: ic->tme_m68k_ireg_ccr = reg; 5720: TME_M68K_INSN_OK; 5721: } 5722: 5723: TME_M68K_INSN(tme_m68k_andi_ccr) 5724: { 5725: tme_uint8_t reg; 5726: reg = ic->tme_m68k_ireg_ccr & (TME_M68K_INSN_OP0(tme_uint8_t) & TME_M68K_FLAG_CCR); 5727: ic->tme_m68k_ireg_ccr = reg; 5728: TME_M68K_INSN_OK; 5729: } 5730: 5731: TME_M68K_INSN(tme_m68k_eori_ccr) 5732: { 5733: tme_uint8_t reg; 5734: reg = ic->tme_m68k_ireg_ccr ^ (TME_M68K_INSN_OP0(tme_uint8_t) & TME_M68K_FLAG_CCR); 5735: ic->tme_m68k_ireg_ccr = reg; 5736: TME_M68K_INSN_OK; 5737: } 5738: 5739: TME_M68K_INSN(tme_m68k_move_to_ccr) 5740: { 5741: tme_uint8_t reg; 5742: reg = (TME_M68K_INSN_OP1(tme_uint16_t) & TME_M68K_FLAG_CCR); 5743: ic->tme_m68k_ireg_ccr = reg; 5744: TME_M68K_INSN_OK; 5745: } 5746: 5747: TME_M68K_INSN(tme_m68k_ori_sr) 5748: { 5749: tme_uint16_t reg; 5750: reg = ic->tme_m68k_ireg_sr | (TME_M68K_INSN_OP0(tme_uint16_t) & TME_M68K_FLAG_SR); 5751: TME_M68K_INSN_PRIV; 5752: TME_M68K_INSN_CHANGE_SR(reg); 5753: TME_M68K_INSN_OK; 5754: } 5755: 5756: TME_M68K_INSN(tme_m68k_andi_sr) 5757: { 5758: tme_uint16_t reg; 5759: reg = ic->tme_m68k_ireg_sr & (TME_M68K_INSN_OP0(tme_uint16_t) & TME_M68K_FLAG_SR); 5760: TME_M68K_INSN_PRIV; 5761: TME_M68K_INSN_CHANGE_SR(reg); 5762: TME_M68K_INSN_OK; 5763: } 5764: 5765: TME_M68K_INSN(tme_m68k_eori_sr) 5766: { 5767: tme_uint16_t reg; 5768: reg = ic->tme_m68k_ireg_sr ^ (TME_M68K_INSN_OP0(tme_uint16_t) & TME_M68K_FLAG_SR); 5769: TME_M68K_INSN_PRIV; 5770: TME_M68K_INSN_CHANGE_SR(reg); 5771: TME_M68K_INSN_OK; 5772: } 5773: 5774: TME_M68K_INSN(tme_m68k_move_to_sr) 5775: { 5776: tme_uint16_t reg; 5777: reg = (TME_M68K_INSN_OP1(tme_uint16_t) & TME_M68K_FLAG_SR); 5778: TME_M68K_INSN_PRIV; 5779: TME_M68K_INSN_CHANGE_SR(reg); 5780: TME_M68K_INSN_OK; 5781: } 5782: 5783: TME_M68K_INSN(tme_m68k_mulu) 5784: { 5785: int ireg_dl; 5786: tme_uint32_t res; 5787: tme_uint8_t flags; 5788: 5789: /* get the register containing the factor: */ 5790: ireg_dl = TME_M68K_IREG_D0 + TME_M68K_INSN_OP0(tme_uint32_t); 5791: 5792: /* perform the multiplication: */ 5793: res = (((tme_uint32_t) ic->tme_m68k_ireg_uint16(ireg_dl << 1)) 5794: * TME_M68K_INSN_OP1(tme_uint16_t)); 5795: 5796: /* store the result: */ 5797: ic->tme_m68k_ireg_uint32(ireg_dl) = (tme_uint32_t) res; 5798: 5799: /* set the flags: */ 5800: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 5801: if (((tme_int32_t) res) < 0) flags |= TME_M68K_FLAG_N; 5802: if (res == 0) flags |= TME_M68K_FLAG_Z; 5803: ic->tme_m68k_ireg_ccr = flags; 5804: 5805: TME_M68K_INSN_OK; 5806: } 5807: 5808: TME_M68K_INSN(tme_m68k_divu) 5809: { 5810: int ireg_dq; 5811: tme_uint32_t dividend, quotient; 5812: tme_uint16_t divisor, remainder; 5813: tme_uint8_t flags; 5814: 5815: /* get the register(s): */ 5816: ireg_dq = TME_M68K_IREG_D0 + TME_M68K_INSN_OP0(tme_uint32_t); 5817: 5818: /* form the dividend and the divisor: */ 5819: dividend = (tme_uint32_t) ic->tme_m68k_ireg_uint32(ireg_dq); 5820: divisor = TME_M68K_INSN_OP1(tme_uint16_t); 5821: if (divisor == 0) { 1.1.1.3 ! root 5822: ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc; 1.1 root 5823: ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next; 1.1.1.3 ! root 5824: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_DIV0)); 1.1 root 5825: } 5826: 5827: /* do the division: */ 5828: quotient = dividend / divisor; 5829: remainder = dividend % divisor; 5830: 5831: /* set the flags and return the quotient and remainder: */ 5832: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 5833: if (quotient > 0xffff) { 5834: flags |= TME_M68K_FLAG_V; 5835: } 5836: else { 5837: if (((tme_int16_t) quotient) < 0) flags |= TME_M68K_FLAG_N; 5838: if (quotient == 0) flags |= TME_M68K_FLAG_Z; 5839: ic->tme_m68k_ireg_uint16(ireg_dq << 1) = (tme_uint16_t) quotient; 5840: ic->tme_m68k_ireg_uint16((ireg_dq << 1) + 1) = remainder; 5841: } 5842: ic->tme_m68k_ireg_ccr = flags; 5843: 5844: TME_M68K_INSN_OK; 5845: } 5846: 5847: TME_M68K_INSN(tme_m68k_mulul) 5848: { 1.1.1.2 root 5849: #ifndef TME_HAVE_INT64_T 1.1 root 5850: abort(); 1.1.1.2 root 5851: #else /* TME_HAVE_INT64_T */ 1.1 root 5852: unsigned int flag_v; 5853: int ireg_dh; 5854: int ireg_dl; 5855: tme_uint64_t res; 5856: tme_uint8_t flags; 5857: 5858: /* get the register containing the factor: */ 5859: ireg_dl = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 3); 5860: 5861: /* perform the multiplication: */ 5862: res = (((tme_uint64_t) ic->tme_m68k_ireg_uint32(ireg_dl)) 5863: * TME_M68K_INSN_OP1(tme_uint32_t)); 5864: 5865: /* store the result: */ 5866: ic->tme_m68k_ireg_uint32(ireg_dl) = (tme_uint32_t) res; 5867: flag_v = TME_M68K_FLAG_V; 5868: if (TME_M68K_INSN_SPECOP & TME_BIT(10)) { 5869: flag_v = 0; 5870: ireg_dh = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 0, 3); 5871: ic->tme_m68k_ireg_uint32(ireg_dh) = (tme_uint32_t) (res >> 32); 5872: } 5873: 5874: /* set the flags: */ 5875: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 5876: if (((tme_int64_t) res) < 0) flags |= TME_M68K_FLAG_N; 5877: if (res == 0) flags |= TME_M68K_FLAG_Z; 1.1.1.2 root 5878: if (res > 0xffffffffUL) flags |= flag_v; 1.1 root 5879: ic->tme_m68k_ireg_ccr = flags; 5880: 5881: TME_M68K_INSN_OK; 1.1.1.2 root 5882: #endif /* TME_HAVE_INT64_T */ 1.1 root 5883: } 5884: 5885: TME_M68K_INSN(tme_m68k_divul) 5886: { 1.1.1.2 root 5887: #ifndef TME_HAVE_INT64_T 1.1 root 5888: abort(); 1.1.1.2 root 5889: #else /* TME_HAVE_INT64_T */ 1.1 root 5890: int ireg_dr; 5891: int ireg_dq; 5892: tme_uint64_t dividend, quotient; 5893: tme_uint32_t divisor, remainder; 5894: tme_uint8_t flags; 5895: 5896: /* get the register(s): */ 5897: ireg_dq = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 3); 5898: ireg_dr = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 0, 3); 5899: 5900: /* form the dividend and the divisor: */ 5901: if (TME_M68K_INSN_SPECOP & TME_BIT(10)) { 5902: dividend = (tme_uint64_t) 5903: ((((tme_uint64_t) ic->tme_m68k_ireg_uint32(ireg_dr)) << 32) 5904: | ic->tme_m68k_ireg_uint32(ireg_dq)); 5905: } 5906: else 5907: dividend = (tme_uint64_t) ic->tme_m68k_ireg_uint32(ireg_dq); 5908: divisor = TME_M68K_INSN_OP1(tme_uint32_t); 5909: if (divisor == 0) { 1.1.1.3 ! root 5910: ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc; 1.1 root 5911: ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next; 1.1.1.3 ! root 5912: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_DIV0)); 1.1 root 5913: } 5914: 5915: /* do the division: */ 5916: quotient = dividend / divisor; 5917: remainder = dividend % divisor; 5918: 5919: /* set the flags and return the quotient and remainder: */ 5920: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 1.1.1.2 root 5921: if (quotient > 0xffffffffUL) { 1.1 root 5922: flags |= TME_M68K_FLAG_V; 5923: } 5924: else { 5925: if (((tme_int32_t) quotient) < 0) flags |= TME_M68K_FLAG_N; 5926: if (quotient == 0) flags |= TME_M68K_FLAG_Z; 5927: ic->tme_m68k_ireg_uint32(ireg_dq) = (tme_uint32_t) quotient; 5928: if (ireg_dr != ireg_dq) { 5929: ic->tme_m68k_ireg_uint32(ireg_dr) = remainder; 5930: } 5931: } 5932: ic->tme_m68k_ireg_ccr = flags; 5933: 5934: TME_M68K_INSN_OK; 1.1.1.2 root 5935: #endif /* TME_HAVE_INT64_T */ 1.1 root 5936: } 5937: 5938: TME_M68K_INSN(tme_m68k_muls) 5939: { 5940: int ireg_dl; 5941: tme_int32_t res; 5942: tme_uint8_t flags; 5943: 5944: /* get the register containing the factor: */ 5945: ireg_dl = TME_M68K_IREG_D0 + TME_M68K_INSN_OP0(tme_uint32_t); 5946: 5947: /* perform the multiplication: */ 5948: res = (((tme_int32_t) ic->tme_m68k_ireg_int16(ireg_dl << 1)) 5949: * TME_M68K_INSN_OP1(tme_int16_t)); 5950: 5951: /* store the result: */ 5952: ic->tme_m68k_ireg_int32(ireg_dl) = (tme_int32_t) res; 5953: 5954: /* set the flags: */ 5955: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 5956: if (((tme_int32_t) res) < 0) flags |= TME_M68K_FLAG_N; 5957: if (res == 0) flags |= TME_M68K_FLAG_Z; 5958: ic->tme_m68k_ireg_ccr = flags; 5959: 5960: TME_M68K_INSN_OK; 5961: } 5962: 5963: TME_M68K_INSN(tme_m68k_divs) 5964: { 5965: int ireg_dq; 5966: tme_int32_t dividend, quotient; 5967: tme_int16_t divisor, remainder; 5968: tme_uint8_t flags; 5969: 5970: /* get the register(s): */ 5971: ireg_dq = TME_M68K_IREG_D0 + TME_M68K_INSN_OP0(tme_uint32_t); 5972: 5973: /* form the dividend and the divisor: */ 5974: dividend = (tme_int32_t) ic->tme_m68k_ireg_int32(ireg_dq); 5975: divisor = TME_M68K_INSN_OP1(tme_int16_t); 5976: if (divisor == 0) { 1.1.1.3 ! root 5977: ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc; 1.1 root 5978: ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next; 1.1.1.3 ! root 5979: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_DIV0)); 1.1 root 5980: } 5981: 5982: /* do the division: */ 5983: quotient = dividend / divisor; 5984: remainder = dividend % divisor; 5985: 5986: /* set the flags and return the quotient and remainder: */ 5987: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 1.1.1.2 root 5988: if (quotient > 0x7fff || quotient < -32768) { 1.1 root 5989: flags |= TME_M68K_FLAG_V; 5990: } 5991: else { 5992: if (((tme_int16_t) quotient) < 0) flags |= TME_M68K_FLAG_N; 5993: if (quotient == 0) flags |= TME_M68K_FLAG_Z; 5994: ic->tme_m68k_ireg_int16(ireg_dq << 1) = (tme_int16_t) quotient; 5995: ic->tme_m68k_ireg_int16((ireg_dq << 1) + 1) = remainder; 5996: } 5997: ic->tme_m68k_ireg_ccr = flags; 5998: 5999: TME_M68K_INSN_OK; 6000: } 6001: 6002: TME_M68K_INSN(tme_m68k_mulsl) 6003: { 1.1.1.2 root 6004: #ifndef TME_HAVE_INT64_T 1.1 root 6005: abort(); 1.1.1.2 root 6006: #else /* TME_HAVE_INT64_T */ 1.1 root 6007: unsigned int flag_v; 6008: int ireg_dh; 6009: int ireg_dl; 6010: tme_int64_t res; 6011: tme_uint8_t flags; 6012: 6013: /* get the register containing the factor: */ 6014: ireg_dl = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 3); 6015: 6016: /* perform the multiplication: */ 6017: res = (((tme_int64_t) ic->tme_m68k_ireg_int32(ireg_dl)) 6018: * TME_M68K_INSN_OP1(tme_int32_t)); 6019: 6020: /* store the result: */ 6021: ic->tme_m68k_ireg_int32(ireg_dl) = (tme_int32_t) res; 6022: flag_v = TME_M68K_FLAG_V; 6023: if (TME_M68K_INSN_SPECOP & TME_BIT(10)) { 6024: flag_v = 0; 6025: ireg_dh = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 0, 3); 6026: ic->tme_m68k_ireg_int32(ireg_dh) = (tme_int32_t) (res >> 32); 6027: } 6028: 6029: /* set the flags: */ 6030: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 6031: if (((tme_int64_t) res) < 0) flags |= TME_M68K_FLAG_N; 6032: if (res == 0) flags |= TME_M68K_FLAG_Z; 1.1.1.2 root 6033: if (res > 0x7fffffffL || res < ((0L - 0x7fffffffL) - 1L)) flags |= flag_v; 1.1 root 6034: ic->tme_m68k_ireg_ccr = flags; 6035: 6036: TME_M68K_INSN_OK; 1.1.1.2 root 6037: #endif /* TME_HAVE_INT64_T */ 1.1 root 6038: } 6039: 6040: TME_M68K_INSN(tme_m68k_divsl) 6041: { 1.1.1.2 root 6042: #ifndef TME_HAVE_INT64_T 1.1 root 6043: abort(); 1.1.1.2 root 6044: #else /* TME_HAVE_INT64_T */ 1.1 root 6045: int ireg_dr; 6046: int ireg_dq; 6047: tme_int64_t dividend, quotient; 6048: tme_int32_t divisor, remainder; 6049: tme_uint8_t flags; 6050: 6051: /* get the register(s): */ 6052: ireg_dq = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 3); 6053: ireg_dr = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 0, 3); 6054: 6055: /* form the dividend and the divisor: */ 6056: if (TME_M68K_INSN_SPECOP & TME_BIT(10)) { 6057: dividend = (tme_int64_t) 6058: ((((tme_uint64_t) ic->tme_m68k_ireg_uint32(ireg_dr)) << 32) 6059: | ic->tme_m68k_ireg_uint32(ireg_dq)); 6060: } 6061: else 6062: dividend = (tme_int64_t) ic->tme_m68k_ireg_int32(ireg_dq); 6063: divisor = TME_M68K_INSN_OP1(tme_int32_t); 6064: if (divisor == 0) { 1.1.1.3 ! root 6065: ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc; 1.1 root 6066: ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next; 1.1.1.3 ! root 6067: TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_DIV0)); 1.1 root 6068: } 6069: 6070: /* do the division: */ 6071: quotient = dividend / divisor; 6072: remainder = dividend % divisor; 6073: 6074: /* set the flags and return the quotient and remainder: */ 6075: flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X; 1.1.1.2 root 6076: if (quotient > 0x7fffffffL || quotient < ((0L - 0x7fffffffL) - 1L)) { 1.1 root 6077: flags |= TME_M68K_FLAG_V; 6078: } 6079: else { 6080: if (((tme_int32_t) quotient) < 0) flags |= TME_M68K_FLAG_N; 6081: if (quotient == 0) flags |= TME_M68K_FLAG_Z; 6082: ic->tme_m68k_ireg_int32(ireg_dq) = (tme_int32_t) quotient; 6083: if (ireg_dr != ireg_dq) { 6084: ic->tme_m68k_ireg_int32(ireg_dr) = remainder; 6085: } 6086: } 6087: ic->tme_m68k_ireg_ccr = flags; 6088: 6089: TME_M68K_INSN_OK; 1.1.1.2 root 6090: #endif /* TME_HAVE_INT64_T */ 1.1 root 6091: } 6092: /* automatically generated by m68k-misc-auto.sh, do not edit! */ 6093: 6094: /* the flags->conditions mapping: */ 6095: const tme_uint16_t _tme_m68k_conditions[32] = { 6096: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT), 6097: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT), 6098: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE), 6099: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE), 6100: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE), 6101: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE), 6102: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE), 6103: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE), 6104: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE), 6105: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE), 6106: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT), 6107: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT), 6108: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE), 6109: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE), 6110: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE), 6111: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE), 6112: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT), 6113: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT), 6114: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE), 6115: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE), 6116: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE), 6117: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE), 6118: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE), 6119: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE), 6120: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE), 6121: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE), 6122: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT), 6123: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT), 6124: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE), 6125: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE), 6126: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE), 6127: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE), 6128: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.