|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2017 [email protected] ! 4: // ! 5: ! 6: #pragma once ! 7: ! 8: extern void acc_chk2cmp2_32(m68kcpu *cpu, uint32, uint32, uint32); ! 9: extern bool acc_divu_32_16(m68kcpu *cpu, uint32, uint32, uint32 *, uint32 *); ! 10: extern bool acc_divu_32_32(m68kcpu *cpu, uint32, uint32, uint32 *, uint32 *); ! 11: extern bool acc_divu_64_32(m68kcpu *cpu, uint32, uint64, uint32 *, uint32 *); ! 12: extern bool acc_divs_32_16(m68kcpu *cpu, uint32, uint32, uint32 *, uint32 *); ! 13: extern bool acc_divs_32_32(m68kcpu *cpu, uint32, uint32, uint32 *, uint32 *); ! 14: extern bool acc_divs_64_32(m68kcpu *cpu, uint32, uint64, uint32 *, uint32 *); ! 15: extern uint32 acc_abcd_8(m68kcpu *cpu, uint32 src ,uint32 dst); ! 16: extern uint32 acc_sbcd_8(m68kcpu *cpu, uint32 src, uint32 dst); ! 17: ! 18: // ビットフィールド命令 ! 19: class acc_bf ! 20: { ! 21: public: ! 22: acc_bf(m68kcpu *); ! 23: // デストラクタは無し。 ! 24: ! 25: void LoadReg(uint n); // Dn から値を読み込む ! 26: void LoadMem(uint32 addr); // メモリから値を読み込む ! 27: ! 28: // レジスタまたはメモリにストアする ! 29: void Store(uint n) { ! 30: if (n < 8) { ! 31: StoreReg(n); ! 32: } else { ! 33: StoreMem(); ! 34: } ! 35: }; ! 36: ! 37: uint32 data = 0; // 32bit 左詰めデータ ! 38: int32 offset = 0; // (第2ワードで指定された) オフセット ! 39: uint32 width = 0; // 幅 ! 40: ! 41: private: ! 42: void StoreReg(uint n); // 値を Dn に書き出す ! 43: void StoreMem(); // 値をメモリに書き出す ! 44: ! 45: // 32ビットの val を count ビット左ローテートした値を返す。 ! 46: // count は 0..31。 ! 47: // 実際には count==0 の時 (val>>32) となりこれは未定義動作なのだが ! 48: // ぶっちゃけこの形式はローテート命令一発に変換されると知っているので ! 49: // とりあえず放置しておく。C++20 になったら std::rotl() を検討。 ! 50: NO_SANITIZE("undefined") ! 51: uint32 ROL32(uint32 val, uint count) { ! 52: return (val << count) | (val >> (32 - count)); ! 53: } ! 54: ! 55: // 32ビットの val を count ビット右ローテートした値を返す。 ! 56: // count は 0..31。 ! 57: // 実際には count==0 の時 (val>>32) となりこれは未定義動作なのだが ! 58: // ぶっちゃけこの形式はローテート命令一発に変換されると知っているので ! 59: // とりあえず放置しておく。C++20 になったら std::rotr() を検討。 ! 60: NO_SANITIZE("undefined") ! 61: uint32 ROR32(uint32 val, uint count) { ! 62: return (val >> count) | (val << (32 - count)); ! 63: } ! 64: ! 65: m68kcpu *cpu = NULL; ! 66: ! 67: uint32 mask = 0; // 32ビット左詰めマスク ! 68: uint32 ea = 0; // オフセット計算後の EA ! 69: int32 local_offset = 0; // 内部(32bit or 8bit 内)オフセット ! 70: int bytes = 0; // アクセスバイト数 ! 71: uint64 buf = 0; // 40ビットのメモリバッファ ! 72: }; ! 73: ! 74: // res を元に NZVC フラグをセットする。 ! 75: // res の上位ビットは無視される。 ! 76: static inline void ! 77: acc_move_8(m68kcpu *cpu, uint32 res) ! 78: { ! 79: CCR.z = res << 24; ! 80: CCR.n = CCR.z; ! 81: CCR.c = 0; ! 82: CCR.v = 0; ! 83: } ! 84: ! 85: // res を元に NZVC フラグをセットする。 ! 86: // res の上位ビットは無視される。 ! 87: static inline void ! 88: acc_move_16(m68kcpu *cpu, uint32 res) ! 89: { ! 90: CCR.z = res << 16; ! 91: CCR.n = CCR.z; ! 92: CCR.c = 0; ! 93: CCR.v = 0; ! 94: } ! 95: ! 96: // res を元に NZVC フラグをセットする。 ! 97: static inline void ! 98: acc_move_32(m68kcpu *cpu, uint32 res) ! 99: { ! 100: CCR.z = res; ! 101: CCR.n = res; ! 102: CCR.c = 0; ! 103: CCR.v = 0; ! 104: } ! 105: ! 106: ! 107: #define vflag_add_8(src, dst, res) (vflag_add_32(src, dst, res) << 24) ! 108: #define vflag_add_16(src, dst, res) (vflag_add_32(src, dst, res) << 16) ! 109: #define vflag_add_32(src, dst, res) (((src) ^ (res)) & ((dst) ^ (res))) ! 110: ! 111: // src + dst を計算し、XNZVC フラグをセットして結果を返す。 ! 112: // src, dst の上位ビットはクリアしておくこと。 ! 113: // 戻り値の上位ビットはクリアされている。 ! 114: static inline uint32 ! 115: acc_add_8(m68kcpu *cpu, uint32 src, uint32 dst) ! 116: { ! 117: CCR.z = dst + src; ! 118: CCR.c = CCR.z >> 8; ! 119: CCR.x = CCR.c; ! 120: CCR.n = CCR.z << 24; ! 121: CCR.z &= 0xff; ! 122: CCR.v = vflag_add_8(src, dst, CCR.z); ! 123: return CCR.z; ! 124: } ! 125: ! 126: // src + dst を計算し、XNZVC フラグをセットして結果を返す。 ! 127: // src, dst の上位ビットはクリアしておくこと。 ! 128: // 戻り値の上位ビットはクリアされている。 ! 129: static inline uint32 ! 130: acc_add_16(m68kcpu *cpu, uint32 src, uint32 dst) ! 131: { ! 132: CCR.z = dst + src; ! 133: CCR.c = CCR.z >> 16; ! 134: CCR.x = CCR.c; ! 135: CCR.n = CCR.z << 16; ! 136: CCR.z &= 0xffff; ! 137: CCR.v = vflag_add_16(src, dst, CCR.z); ! 138: return CCR.z; ! 139: } ! 140: ! 141: // src + dst を計算し、XNZVC フラグをセットして結果を返す。 ! 142: static inline uint32 ! 143: acc_add_32(m68kcpu *cpu, uint32 src, uint32 dst) ! 144: { ! 145: CCR.cz = (uint64)dst + (uint64)src; ! 146: CCR.x = CCR.c; ! 147: CCR.v = vflag_add_32(src, dst, CCR.z); ! 148: CCR.n = CCR.z; ! 149: return CCR.z; ! 150: } ! 151: ! 152: // src + dst + X を計算し、XNZVC フラグをセットして結果を返す。 ! 153: // src, dst の上位ビットはクリアしておくこと。 ! 154: // 戻り値の上位ビットはクリアされている。 ! 155: static inline uint32 ! 156: acc_addx_8(m68kcpu *cpu, uint32 src, uint32 dst) ! 157: { ! 158: uint32 res = dst + src + (CCR.IsX() ? 1 : 0); ! 159: CCR.c = res >> 8; ! 160: CCR.x = CCR.c; ! 161: CCR.n = res << 24; ! 162: // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない ! 163: if (CCR.n != 0) { ! 164: CCR.z = CCR.n; ! 165: } ! 166: CCR.v = vflag_add_8(src, dst, res); ! 167: return res & 0xff; ! 168: } ! 169: ! 170: // src + dst + X を計算し、XNZVC フラグをセットして結果を返す。 ! 171: // src, dst の上位ビットはクリアしておくこと。 ! 172: // 戻り値の上位ビットはクリアされている。 ! 173: static inline uint32 ! 174: acc_addx_16(m68kcpu *cpu, uint32 src, uint32 dst) ! 175: { ! 176: uint32 res = dst + src + (CCR.IsX() ? 1 : 0); ! 177: CCR.c = res >> 16; ! 178: CCR.x = CCR.c; ! 179: CCR.n = res << 16; ! 180: // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない ! 181: if (CCR.n != 0) { ! 182: CCR.z = CCR.n; ! 183: } ! 184: CCR.v = vflag_add_16(src, dst, res); ! 185: return res & 0xffff; ! 186: } ! 187: ! 188: // src + dst + X を計算し、XNZVC フラグをセットして結果を返す。 ! 189: static inline uint32 ! 190: acc_addx_32(m68kcpu *cpu, uint32 src, uint32 dst) ! 191: { ! 192: uint64 res = (uint64)dst + (uint64)src + (CCR.IsX() ? 1 : 0); ! 193: CCR.c = res >> 32; ! 194: CCR.x = CCR.c; ! 195: CCR.n = res; ! 196: // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない ! 197: if (CCR.n != 0) { ! 198: CCR.z = CCR.n; ! 199: } ! 200: CCR.v = vflag_add_32(src, dst, res); ! 201: return res; ! 202: } ! 203: ! 204: ! 205: #define vflag_sub_8(src, dst, res) (vflag_sub_32(src, dst, res) << 24) ! 206: #define vflag_sub_16(src, dst, res) (vflag_sub_32(src, dst, res) << 16) ! 207: #define vflag_sub_32(src, dst, res) (((src) ^ (dst)) & ((dst) ^ (res))) ! 208: ! 209: // dst - src を計算し、NZVC フラグをセットして結果を返す。 ! 210: // src, dst の上位ビットはクリアしておくこと。 ! 211: // 戻り値の上位ビットはクリアされている。 ! 212: static inline uint32 ! 213: acc_cmp_8(m68kcpu *cpu, uint32 src, uint32 dst) ! 214: { ! 215: CCR.z = dst - src; ! 216: CCR.c = CCR.z >> 8; ! 217: CCR.n = CCR.z << 24; ! 218: CCR.z &= 0xff; ! 219: CCR.v = vflag_sub_8(src, dst, CCR.z); ! 220: return CCR.z; ! 221: } ! 222: ! 223: // dst - src を計算し、NZVC フラグをセットして結果を返す。 ! 224: // src, dst の上位ビットはクリアしておくこと。 ! 225: // 戻り値の上位ビットはクリアされている。 ! 226: static inline uint32 ! 227: acc_cmp_16(m68kcpu *cpu, uint32 src, uint32 dst) ! 228: { ! 229: CCR.z = dst - src; ! 230: CCR.c = CCR.z >> 16; ! 231: CCR.n = CCR.z << 16; ! 232: CCR.z &= 0xffff; ! 233: CCR.v = vflag_sub_16(src, dst, CCR.z); ! 234: return CCR.z; ! 235: } ! 236: ! 237: // dst - src を計算し、NZVC フラグをセットして結果を返す。 ! 238: static inline uint32 ! 239: acc_cmp_32(m68kcpu *cpu, uint32 src, uint32 dst) ! 240: { ! 241: CCR.cz = (uint64)dst - (uint64)src; ! 242: CCR.n = CCR.z; ! 243: CCR.v = vflag_sub_32(src, dst, CCR.z); ! 244: return CCR.z; ! 245: } ! 246: ! 247: // dst - src を計算し、XNZVC フラグをセットして結果を返す。 ! 248: // src, dst の上位ビットはクリアしておくこと。 ! 249: // 戻り値の上位ビットはクリアされている。 ! 250: static inline uint32 ! 251: acc_sub_8(m68kcpu *cpu, uint32 src, uint32 dst) ! 252: { ! 253: uint32 res = acc_cmp_8(cpu, src, dst); ! 254: CCR.x = CCR.c; ! 255: return res; ! 256: } ! 257: ! 258: // dst - src を計算し、XNZVC フラグをセットして結果を返す。 ! 259: // src, dst の上位ビットはクリアしておくこと。 ! 260: // 戻り値の上位ビットはクリアされている。 ! 261: static inline uint32 ! 262: acc_sub_16(m68kcpu *cpu, uint32 src, uint32 dst) ! 263: { ! 264: uint32 res = acc_cmp_16(cpu, src, dst); ! 265: CCR.x = CCR.c; ! 266: return res; ! 267: } ! 268: ! 269: // dst - src を計算し、XNZVC フラグをセットして結果を返す。 ! 270: static inline uint32 ! 271: acc_sub_32(m68kcpu *cpu, uint32 src, uint32 dst) ! 272: { ! 273: uint32 res = acc_cmp_32(cpu, src, dst); ! 274: CCR.x = CCR.c; ! 275: return res; ! 276: } ! 277: ! 278: // src - dst - X を計算し、XNZVC フラグをセットして結果を返す。 ! 279: // src, dst の上位ビットはクリアしておくこと。 ! 280: // 戻り値 res の上位ビットはクリアされている。 ! 281: static inline uint32 ! 282: acc_subx_8(m68kcpu *cpu, uint32 src, uint32 dst) ! 283: { ! 284: uint32 res = dst - src - (CCR.IsX() ? 1 : 0); ! 285: CCR.c = res >> 8; ! 286: CCR.x = CCR.c; ! 287: CCR.n = res << 24; ! 288: // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない ! 289: if (CCR.n != 0) { ! 290: CCR.z = CCR.n; ! 291: } ! 292: CCR.v = vflag_sub_8(src, dst, res); ! 293: return res & 0xff; ! 294: } ! 295: ! 296: // src - dst - X を計算し、XNZVC フラグをセットして結果を返す。 ! 297: // src, dst の上位ビットはクリアしておくこと。 ! 298: // 戻り値 res の上位ビットはクリアされている。 ! 299: static inline uint32 ! 300: acc_subx_16(m68kcpu *cpu, uint32 src, uint32 dst) ! 301: { ! 302: uint32 res = dst - src - (CCR.IsX() ? 1 : 0); ! 303: CCR.c = res >> 16; ! 304: CCR.x = CCR.c; ! 305: CCR.n = res << 16; ! 306: // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない ! 307: if (CCR.n != 0) { ! 308: CCR.z = CCR.n; ! 309: } ! 310: CCR.v = vflag_sub_16(src, dst, res); ! 311: return res & 0xffff; ! 312: } ! 313: ! 314: // src - dst - X を計算し、XNZVC フラグをセットして結果を返す。 ! 315: static inline uint32 ! 316: acc_subx_32(m68kcpu *cpu, uint32 src, uint32 dst) ! 317: { ! 318: uint64 res = (uint64)dst - (uint64)src - (CCR.IsX() ? 1 : 0); ! 319: CCR.c = res >> 32; ! 320: CCR.x = CCR.c; ! 321: CCR.n = res; ! 322: // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない ! 323: if (CCR.n != 0) { ! 324: CCR.z = CCR.n; ! 325: } ! 326: CCR.v = vflag_sub_32(src, dst, res); ! 327: return res; ! 328: } ! 329: ! 330: // src(u16) * dst(u16) を計算し、NZVC フラグをセットして結果(u32)を返す。 ! 331: // src, dst の上位ビットはクリアしておくこと。 ! 332: static inline uint32 ! 333: acc_mulu_16(m68kcpu *cpu, uint32 src, uint32 dst) ! 334: { ! 335: uint32 res = src * dst; ! 336: // 16x16->32 ではオーバーフローは起きないので acc_move でよい ! 337: acc_move_32(cpu, res); ! 338: return res; ! 339: } ! 340: ! 341: // src(s16) * dst(s16) を計算し、NZVC フラグをセットして結果(u32)を返す。 ! 342: // src, dst の上位ビットはクリアしておくこと。 ! 343: static inline uint32 ! 344: acc_muls_16(m68kcpu *cpu, uint32 src, uint32 dst) ! 345: { ! 346: int32 res = (int32)(int16)src * (int32)(int16)dst; ! 347: // 16x16->32 ではオーバーフローは起きないので acc_move でよい ! 348: acc_move_32(cpu, res); ! 349: return res; ! 350: } ! 351: ! 352: // src(u32) * dst(u32) を計算し、NZVC フラグをセットして結果(32bit)を返す。 ! 353: static inline uint32 ! 354: acc_mulu_32(m68kcpu *cpu, uint32 src, uint32 dst) ! 355: { ! 356: uint64 res = (uint64)src * (uint64)dst; ! 357: CCR.z = res; ! 358: CCR.n = res; ! 359: CCR.c = 0; ! 360: if (res > 0xffffffffUL) { ! 361: CCR.v = m68030ccr::V_BIT; ! 362: } else { ! 363: CCR.v = 0; ! 364: } ! 365: return (uint32)res; ! 366: } ! 367: ! 368: // src(s32) * dst(s32) を計算し、NZVC フラグをセットして結果(32bit)を返す。 ! 369: static inline uint32 ! 370: acc_muls_32(m68kcpu *cpu, uint32 src, uint32 dst) ! 371: { ! 372: int64 res = (int64)(int32)src * (int64)(int32)dst; ! 373: CCR.z = res; ! 374: CCR.n = res; ! 375: CCR.c = 0; ! 376: // V フラグは64ビット演算結果の上位32ビットが ! 377: // 下位32ビットの符号拡張になっていなかった場合に立つ。 ! 378: // つまり符号付き整数で 32bit 表現と 64bit 表現が一致していなければ立つ。 ! 379: int32 tmp = res; ! 380: if (res != tmp) { ! 381: CCR.v = m68030ccr::V_BIT; ! 382: } else { ! 383: CCR.v = 0; ! 384: } ! 385: return (uint32)res; ! 386: } ! 387: ! 388: // src(u32) * dst(u32) を計算し、NZVC フラグをセットして結果(64bit)を返す。 ! 389: static inline uint64 ! 390: acc_mulu_64(m68kcpu *cpu, uint32 src, uint32 dst) ! 391: { ! 392: uint64 res = (uint64)src * (uint64)dst; ! 393: CCR.n = res >> 32; ! 394: CCR.z = CCR.n | res; ! 395: CCR.v = 0; ! 396: CCR.c = 0; ! 397: return res; ! 398: } ! 399: ! 400: // src(s32) * dst(s32) を計算し、NZVC フラグをセットして結果(64bit)を返す。 ! 401: static inline uint64 ! 402: acc_muls_64(m68kcpu *cpu, uint32 src, uint32 dst) ! 403: { ! 404: int64 res = (int64)(int32)src * (int64)(int32)dst; ! 405: CCR.n = res >> 32; ! 406: CCR.z = CCR.n | res; ! 407: CCR.v = 0; ! 408: CCR.c = 0; ! 409: return res; ! 410: } ! 411: ! 412: static inline void ! 413: acc_btst(m68kcpu *cpu, uint32 data, int n) ! 414: { ! 415: CCR.z = data & (1 << n); ! 416: } ! 417: ! 418: static inline uint32 ! 419: acc_bchg(m68kcpu *cpu, uint32 data, int n) ! 420: { ! 421: CCR.z = data & (1 << n); ! 422: data ^= (1 << n); ! 423: return data; ! 424: } ! 425: ! 426: static inline uint32 ! 427: acc_bclr(m68kcpu *cpu, uint32 data, int n) ! 428: { ! 429: CCR.z = data & (1 << n); ! 430: data &= ~(1 << n); ! 431: return data; ! 432: } ! 433: ! 434: static inline uint32 ! 435: acc_bset(m68kcpu *cpu, uint32 data, int n) ! 436: { ! 437: CCR.z = data & (1 << n); ! 438: data |= (1 << n); ! 439: return data; ! 440: } ! 441: ! 442: ! 443: // data を count ビット算術左シフトし、XNZVC フラグを反映して結果を返す。 ! 444: // count は 0..63。data の上位はクリアしておくこと。 ! 445: static inline uint32 ! 446: acc_asl_8(m68kcpu *cpu, uint32 data, int count) ! 447: { ! 448: if (count == 0) { ! 449: acc_move_8(cpu, data); ! 450: return data; ! 451: } ! 452: int64 tmps = (int64)(int8)data; ! 453: if (count > 8) count = 9; ! 454: uint64 tmp = (uint64)tmps << count; ! 455: CCR.x = CCR.c = tmp >> 8; ! 456: CCR.n = tmp << 24; ! 457: CCR.z = CCR.n; ! 458: // 送り出された全てのビットが元の MSB と一致すれば V=0 ! 459: CCR.PutV(((int64)tmp >> 7) != (tmps >> 8)); ! 460: return tmp & 0xff; ! 461: } ! 462: ! 463: // data を count ビット算術左シフトし、XNZVC フラグを反映して結果を返す。 ! 464: // count は 0..63。data の上位はクリアしておくこと。 ! 465: static inline uint32 ! 466: acc_asl_16(m68kcpu *cpu, uint32 data, int count) ! 467: { ! 468: if (count == 0) { ! 469: acc_move_16(cpu, data); ! 470: return data; ! 471: } ! 472: int64 tmps = (int64)(int16)data; ! 473: if (count > 16) count = 17; ! 474: uint64 tmp = (uint64)tmps << count; ! 475: CCR.x = CCR.c = tmp >> 16; ! 476: CCR.n = tmp << 16; ! 477: CCR.z = CCR.n; ! 478: // 送り出された全てのビットが元の MSB と一致すれば V=0 ! 479: CCR.PutV(((int64)tmp >> 15) != (tmps >> 16)); ! 480: return tmp & 0xffff; ! 481: } ! 482: ! 483: // data を count ビット算術左シフトし、XNZVC フラグを反映して結果を返す。 ! 484: // count は 0..63 ! 485: static inline uint32 ! 486: acc_asl_32(m68kcpu *cpu, uint32 data, int count) ! 487: { ! 488: if (count == 0) { ! 489: acc_move_32(cpu, data); ! 490: return data; ! 491: } ! 492: int64 tmps = (int64)(int32)data; ! 493: if (count > 32) count = 33; ! 494: uint64 tmp = (uint64)tmps << count; ! 495: CCR.x = CCR.c = tmp >> 32; ! 496: CCR.n = CCR.z = tmp; ! 497: // 送り出された全てのビットが元の MSB と一致すれば V=0 ! 498: CCR.PutV(((int64)tmp >> 31) != (tmps >> 32)); ! 499: return tmp; ! 500: } ! 501: ! 502: // data を count ビット左シフトし、NZVC フラグを反映して結果を返す。 ! 503: // count は 0..63。data の上位はクリアしておくこと。 ! 504: static inline uint32 ! 505: acc_lsl_8(m68kcpu *cpu, uint32 data, int count) ! 506: { ! 507: if (count == 0) { ! 508: acc_move_8(cpu, data); ! 509: return data; ! 510: } ! 511: uint64 tmp = (uint64)data << count; ! 512: CCR.x = CCR.c = tmp >> 8; ! 513: CCR.n = tmp << 24; ! 514: CCR.z = tmp & 0xff; ! 515: CCR.v = 0; ! 516: return CCR.z; ! 517: } ! 518: ! 519: // data を count ビット左シフトし、NZVC フラグを反映して結果を返す。 ! 520: // count は 0..63。data の上位はクリアしておくこと。 ! 521: static inline uint32 ! 522: acc_lsl_16(m68kcpu *cpu, uint32 data, int count) ! 523: { ! 524: if (count == 0) { ! 525: acc_move_16(cpu, data); ! 526: return data; ! 527: } ! 528: uint64 tmp = (uint64)data << count; ! 529: CCR.x = CCR.c = tmp >> 16; ! 530: CCR.n = tmp << 16; ! 531: CCR.z = tmp & 0xffff; ! 532: CCR.v = 0; ! 533: return CCR.z; ! 534: } ! 535: ! 536: // data を count ビット左シフトし、NZVC フラグを反映して結果を返す。 ! 537: // count は 0..63 ! 538: static inline uint32 ! 539: acc_lsl_32(m68kcpu *cpu, uint32 data, int count) ! 540: { ! 541: if (count == 0) { ! 542: acc_move_32(cpu, data); ! 543: return data; ! 544: } ! 545: uint64 tmp = (uint64)data << count; ! 546: CCR.x = CCR.c = tmp >> 32; ! 547: CCR.n = tmp; ! 548: CCR.z = tmp; ! 549: CCR.v = 0; ! 550: return CCR.z; ! 551: } ! 552: ! 553: // data:X を count ビット左ローテートし、XNZVC フラグを反映して結果を返す。 ! 554: // count は 0..63 ! 555: static inline uint32 ! 556: acc_roxl_8(m68kcpu *cpu, uint32 data, int count) ! 557: { ! 558: count %= 9; ! 559: if (count == 0) { ! 560: CCR.z = data; ! 561: CCR.n = data << 24; ! 562: CCR.v = 0; ! 563: CCR.c = CCR.x; ! 564: return CCR.z; ! 565: } ! 566: uint32 x = CCR.x & 1; ! 567: CCR.z = (data << count) | (data >> (9 - count)) | (x << (count - 1)); ! 568: CCR.c = CCR.x = CCR.z >> 8; ! 569: CCR.z &= 0xff; ! 570: CCR.n = CCR.z << 24; ! 571: CCR.v = 0; ! 572: return CCR.z; ! 573: } ! 574: ! 575: // data:X を count ビット左ローテートし、XNZVC フラグを反映して結果を返す。 ! 576: // count は 0..63 ! 577: static inline uint32 ! 578: acc_roxl_16(m68kcpu *cpu, uint32 data, int count) ! 579: { ! 580: count %= 17; ! 581: if (count == 0) { ! 582: CCR.z = data; ! 583: CCR.n = data << 16; ! 584: CCR.v = 0; ! 585: CCR.c = CCR.x; ! 586: return CCR.z; ! 587: } ! 588: uint32 x = CCR.x & 1; ! 589: CCR.z = (data << count) | (data >> (17 - count)) | (x << (count - 1)); ! 590: CCR.c = CCR.x = CCR.z >> 16; ! 591: CCR.z &= 0xffff; ! 592: CCR.n = CCR.z << 16; ! 593: CCR.v = 0; ! 594: return CCR.z; ! 595: } ! 596: ! 597: // data:X を count ビット左ローテートし、XNZVC フラグを反映して結果を返す。 ! 598: // count は 0..63 ! 599: static inline uint32 ! 600: acc_roxl_32(m68kcpu *cpu, uint32 data, int count) ! 601: { ! 602: count %= 33; ! 603: if (count == 0) { ! 604: CCR.z = data; ! 605: CCR.n = data; ! 606: CCR.v = 0; ! 607: CCR.c = CCR.x; ! 608: return CCR.z; ! 609: } ! 610: // 32bit値の 32ビットシフトは未定義動作なので 64bit値を使用 ! 611: uint64 data64 = data; ! 612: uint32 x = CCR.x & 1; ! 613: CCR.z = (data64 << count) | (data64 >> (33 - count)) | (x << (count - 1)); ! 614: CCR.c = CCR.x = data64 >> (32 - count); ! 615: CCR.n = CCR.z; ! 616: CCR.v = 0; ! 617: return CCR.z; ! 618: } ! 619: ! 620: // data を count ビット左ローテートし、NZVC フラグを反映して結果を返す。 ! 621: // count は 0..63。data の上位はクリアしておくこと ! 622: static inline uint32 ! 623: acc_rol_8(m68kcpu *cpu, uint32 data, int count) ! 624: { ! 625: if (count == 0) { ! 626: acc_move_8(cpu, data); ! 627: return data; ! 628: } ! 629: ! 630: count %= 8; ! 631: int count2 = (8 - count) % 8; ! 632: uint8 tmp = (data << count) | (data >> count2); ! 633: CCR.z = tmp; ! 634: CCR.n = (uint32)tmp << 24; ! 635: CCR.c = data >> count2; ! 636: CCR.v = 0; ! 637: return CCR.z; ! 638: } ! 639: ! 640: // data を count ビット左ローテートし、NZVC フラグを反映して結果を返す。 ! 641: // count は 0..63。data の上位はクリアしておくこと ! 642: static inline uint32 ! 643: acc_rol_16(m68kcpu *cpu, uint32 data, int count) ! 644: { ! 645: if (count == 0) { ! 646: acc_move_16(cpu, data); ! 647: return data; ! 648: } ! 649: ! 650: count %= 16; ! 651: int count2 = (16 - count) % 16; ! 652: uint16 tmp = (data << count) | (data >> count2); ! 653: CCR.z = tmp; ! 654: CCR.n = (uint32)tmp << 16; ! 655: CCR.c = data >> count2; ! 656: CCR.v = 0; ! 657: return CCR.z; ! 658: } ! 659: ! 660: // data を count ビット左ローテートし、NZVC フラグを反映して結果を返す。 ! 661: // count は 0..63 ! 662: static inline uint32 ! 663: acc_rol_32(m68kcpu *cpu, uint32 data, int count) ! 664: { ! 665: if (count == 0) { ! 666: acc_move_32(cpu, data); ! 667: return data; ! 668: } ! 669: ! 670: count %= 32; ! 671: int count2 = (32 - count) % 32; ! 672: uint64 data64 = (uint64)data; ! 673: uint64 tmp = (data << count) | (data >> count2); ! 674: CCR.z = tmp; ! 675: CCR.n = CCR.z; ! 676: CCR.c = data64 >> count2; ! 677: CCR.v = 0; ! 678: return CCR.z; ! 679: } ! 680: ! 681: // data を count ビット算術右シフトし、XNZVC フラグを反映して結果を返す。 ! 682: // count は 0..64。data の上位はクリアしておくこと。 ! 683: static inline uint32 ! 684: acc_asr_8(m68kcpu *cpu, uint32 data, int count) ! 685: { ! 686: if (count == 0) { ! 687: acc_move_8(cpu, data); ! 688: return data; ! 689: } ! 690: if (count > 8) { ! 691: if ((int8)data < 0) { ! 692: data = 0xff; ! 693: } else { ! 694: data = 0; ! 695: } ! 696: CCR.x = CCR.c = CCR.z = data; ! 697: CCR.n = data << 24; ! 698: CCR.v = 0; ! 699: return data; ! 700: } ! 701: // data >>> count の結果が tmp の上位32ビット中の下位8ビットに入る ! 702: uint64 tmp = (uint64)(int64)(int8)data << (32 - count); ! 703: CCR.x = CCR.c = tmp >> 31; ! 704: CCR.n = tmp >> 8; ! 705: CCR.z = (tmp >> 32) & 0xff; ! 706: CCR.v = 0; ! 707: return CCR.z; ! 708: } ! 709: ! 710: // data を count ビット算術右シフトし、XNZVC フラグを反映して結果を返す。 ! 711: // count は 0..64。data の上位はクリアしておくこと。 ! 712: static inline uint32 ! 713: acc_asr_16(m68kcpu *cpu, uint32 data, int count) ! 714: { ! 715: if (count == 0) { ! 716: acc_move_16(cpu, data); ! 717: return data; ! 718: } ! 719: if (count > 16) { ! 720: if ((int16)data < 0) { ! 721: data = 0xffff; ! 722: } else { ! 723: data = 0; ! 724: } ! 725: CCR.x = CCR.c = CCR.z = data; ! 726: CCR.n = data << 16; ! 727: CCR.v = 0; ! 728: return data; ! 729: } ! 730: // data >>> count の結果が tmp の上位32ビット中の下位16ビットに入る ! 731: uint64 tmp = (uint64)(int64)(int16)data << (32 - count); ! 732: CCR.x = CCR.c = tmp >> 31; ! 733: CCR.n = tmp >> 16; ! 734: CCR.z = (tmp >> 32) & 0xffff; ! 735: CCR.v = 0; ! 736: return CCR.z; ! 737: } ! 738: ! 739: // data を count ビット算術右シフトし、XNZVC フラグを反映して結果を返す。 ! 740: // count は 0..64 ! 741: static inline uint32 ! 742: acc_asr_32(m68kcpu *cpu, uint32 data, int count) ! 743: { ! 744: if (count == 0) { ! 745: acc_move_32(cpu, data); ! 746: return data; ! 747: } ! 748: if (count > 32) { ! 749: if ((int32)data < 0) { ! 750: data = 0xffffffff; ! 751: } else { ! 752: data = 0; ! 753: } ! 754: CCR.x = CCR.c = CCR.z = data; ! 755: CCR.n = data; ! 756: CCR.v = 0; ! 757: return data; ! 758: } ! 759: // data >>> count の結果が tmp の上位32ビットに入る ! 760: uint64 tmp = (uint64)(int64)(int32)data << (32 - count); ! 761: CCR.x = CCR.c = tmp >> 31; ! 762: CCR.z = CCR.n = tmp >> 32; ! 763: CCR.v = 0; ! 764: return CCR.z; ! 765: } ! 766: ! 767: // data を count ビット論理右シフトし、XNZVC フラグを反映して結果を返す。 ! 768: // count は 0..63 ! 769: static inline uint32 ! 770: acc_lsr_8(m68kcpu *cpu, uint32 data, int count) ! 771: { ! 772: if (count == 0) { ! 773: acc_move_8(cpu, data); ! 774: return data; ! 775: } ! 776: if (count > 8) { ! 777: CCR.x = CCR.c = 0; ! 778: acc_move_8(cpu, 0); ! 779: return 0; ! 780: } ! 781: // data >> count の結果が tmp の上位32ビットに入る ! 782: uint64 tmp = (uint64)data << (32 - count); ! 783: CCR.x = CCR.c = tmp >> 31; ! 784: CCR.n = tmp >> 8; ! 785: CCR.z = (tmp >> 32) & 0xff; ! 786: CCR.v = 0; ! 787: return CCR.z; ! 788: } ! 789: ! 790: // data を count ビット論理右シフトし、XNZVC フラグを反映して結果を返す。 ! 791: // count は 0..63 ! 792: static inline uint32 ! 793: acc_lsr_16(m68kcpu *cpu, uint32 data, int count) ! 794: { ! 795: if (count == 0) { ! 796: acc_move_16(cpu, data); ! 797: return data; ! 798: } ! 799: if (count > 16) { ! 800: CCR.x = CCR.c = 0; ! 801: acc_move_16(cpu, 0); ! 802: return 0; ! 803: } ! 804: // data >> count の結果が tmp の上位32ビットに入る ! 805: uint64 tmp = (uint64)data << (32 - count); ! 806: CCR.x = CCR.c = tmp >> 31; ! 807: CCR.n = tmp >> 16; ! 808: CCR.z = (tmp >> 32) & 0xffff; ! 809: CCR.v = 0; ! 810: return CCR.z; ! 811: } ! 812: ! 813: // data を count ビット論理右シフトし、XNZVC フラグを反映して結果を返す。 ! 814: // count は 0..63 ! 815: static inline uint32 ! 816: acc_lsr_32(m68kcpu *cpu, uint32 data, int count) ! 817: { ! 818: if (count == 0) { ! 819: acc_move_32(cpu, data); ! 820: return data; ! 821: } ! 822: if (count > 32) { ! 823: CCR.x = CCR.c = 0; ! 824: acc_move_32(cpu, 0); ! 825: return 0; ! 826: } ! 827: // data >> count の結果が tmp の上位32ビットに入る ! 828: uint64 tmp = (uint64)data << (32 - count); ! 829: CCR.x = CCR.c = tmp >> 31; ! 830: CCR.z = CCR.n = tmp >> 32; ! 831: CCR.v = 0; ! 832: return CCR.z; ! 833: } ! 834: ! 835: // data:C を count ビット右ローテートし、NZVC フラグを反映して結果を返す。 ! 836: // count は 0..63 ! 837: static inline uint32 ! 838: acc_roxr_8(m68kcpu *cpu, uint32 data, int count) ! 839: { ! 840: count %= 9; ! 841: if (count == 0) { ! 842: CCR.z = data; ! 843: CCR.n = data << 24; ! 844: CCR.v = 0; ! 845: CCR.c = CCR.x; ! 846: return CCR.z; ! 847: } ! 848: uint32 rot = data & ((1 << (count - 1)) - 1); ! 849: uint32 x = CCR.x & 1; ! 850: CCR.z = (data >> count) | (rot << (9 - count)) | (x << (8 - count)); ! 851: CCR.c = CCR.x = data >> (count - 1); ! 852: CCR.n = CCR.z << 24; ! 853: CCR.v = 0; ! 854: return CCR.z; ! 855: } ! 856: ! 857: // data:C を count ビット右ローテートし、NZVC フラグを反映して結果を返す。 ! 858: // count は 0..63 ! 859: static inline uint32 ! 860: acc_roxr_16(m68kcpu *cpu, uint32 data, int count) ! 861: { ! 862: count %= 17; ! 863: if (count == 0) { ! 864: CCR.z = data; ! 865: CCR.n = data << 16; ! 866: CCR.v = 0; ! 867: CCR.c = CCR.x; ! 868: return CCR.z; ! 869: } ! 870: uint32 rot = data & ((1 << (count - 1)) - 1); ! 871: uint32 x = CCR.x & 1; ! 872: CCR.z = (data >> count) | (rot << (17 - count)) | (x << (16 - count)); ! 873: CCR.c = CCR.x = data >> (count - 1); ! 874: CCR.n = CCR.z << 16; ! 875: CCR.v = 0; ! 876: return CCR.z; ! 877: } ! 878: ! 879: // data:C を count ビット右ローテートし、NZVC フラグを反映して結果を返す。 ! 880: // count は 0..63 ! 881: static inline uint32 ! 882: acc_roxr_32(m68kcpu *cpu, uint32 data, int count) ! 883: { ! 884: count %= 33; ! 885: if (count == 0) { ! 886: CCR.z = data; ! 887: CCR.n = data; ! 888: CCR.v = 0; ! 889: CCR.c = CCR.x; ! 890: return CCR.z; ! 891: } ! 892: // 32bit値の 32ビットシフトは未定義動作なので 64bit値を使用 ! 893: uint64 data64 = data; ! 894: uint64 rot = data64 & ((1 << (count - 1)) - 1); ! 895: uint32 x = CCR.x & 1; ! 896: CCR.z = (data64 >> count) | (rot << (33 - count)) | (x << (32 - count)); ! 897: CCR.c = CCR.x = data64 >> (count - 1); ! 898: CCR.n = CCR.z; ! 899: CCR.v = 0; ! 900: return CCR.z; ! 901: } ! 902: ! 903: // data を count ビット右ローテートし、NZVC フラグを反映して結果を返す。 ! 904: // count は 0..63 ! 905: static inline uint32 ! 906: acc_ror_8(m68kcpu *cpu, uint32 data, int count) ! 907: { ! 908: if (count == 0) { ! 909: acc_move_8(cpu, data); ! 910: return data; ! 911: } ! 912: ! 913: count %= 8; ! 914: uint8 tmp = (data >> count) | (data << (8 - count)); ! 915: CCR.z = tmp; ! 916: CCR.n = (uint32)tmp << 24; ! 917: // 7 0 1 2 3 4 5 6 ! 918: CCR.c = data >> ((count + 7) % 8); ! 919: CCR.v = 0; ! 920: return tmp; ! 921: } ! 922: ! 923: // data を count ビット右ローテートし、NZVC フラグを反映して結果を返す。 ! 924: // count は 0..63 ! 925: static inline uint32 ! 926: acc_ror_16(m68kcpu *cpu, uint32 data, int count) ! 927: { ! 928: if (count == 0) { ! 929: acc_move_16(cpu, data); ! 930: return data; ! 931: } ! 932: ! 933: count %= 16; ! 934: uint16 tmp = (data >> count) | (data << (16 - count)); ! 935: CCR.z = tmp; ! 936: CCR.n = (uint32)tmp << 16; ! 937: CCR.c = data >> ((count + 15) % 16); ! 938: CCR.v = 0; ! 939: return tmp; ! 940: } ! 941: ! 942: // data を count ビット右ローテートし、NZVC フラグを反映して結果を返す。 ! 943: // count は 0..63 ! 944: static inline uint32 ! 945: acc_ror_32(m68kcpu *cpu, uint32 data, int count) ! 946: { ! 947: if (count == 0) { ! 948: acc_move_32(cpu, data); ! 949: return data; ! 950: } ! 951: ! 952: count %= 32; ! 953: uint64 data64 = (uint64)data; ! 954: uint64 tmp = (data >> count) | (data << (32 - count)); ! 955: CCR.z = tmp; ! 956: CCR.n = tmp; ! 957: CCR.c = data64 >> ((count + 31) % 32); ! 958: CCR.v = 0; ! 959: return tmp; ! 960: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.