|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2020 [email protected] ! 4: // ! 5: ! 6: // 命令のフィールド取り出し ! 7: #define FLD_D ((opX >> 21) & 0x1f) ! 8: #define FLD_S1 ((opX >> 16) & 0x1f) ! 9: #define FLD_S2 ((opX ) & 0x1f) ! 10: #define FLD_CR ((opX >> 5) & 0x2f) ! 11: #define B5 ((opX >> 21) & 0x1f) ! 12: #define M5 ((opX >> 21) & 0x1f) ! 13: #define W5 ((opX >> 5) & 0x1f) ! 14: #define O5 ((opX ) & 0x1f) ! 15: #define IMM16 (opX & 0x0000ffffU) ! 16: #define VEC9 (opX & 0x000001ffU) ! 17: ! 18: // 符号拡張・シフト済みのディスプレースメント ! 19: // XXX: (負数の右シフト)GCC only ! 20: #define D16 (((int32)(int16)opX) << 2) ! 21: #define D26 (((int32)(opX << 6) >> 4)) ! 22: #define IsCO ((opX >> 8) & 1) ! 23: #define IsCI ((opX >> 9) & 1) ! 24: ! 25: // レジスタアクセス ! 26: #define rD (r[FLD_D]) ! 27: #define rS1 (r[FLD_S1]) ! 28: #define rS2 (r[FLD_S2]) ! 29: ! 30: ! 31: // ブランチ命令入り口 ! 32: inline void ! 33: m88kcpu::EnterBranch() ! 34: { ! 35: } ! 36: ! 37: // 通常(即時)ブランチ出口 ! 38: inline void ! 39: m88kcpu::ExitBranch() ! 40: { ! 41: // re-fetch branched instruction ! 42: fetch(); ! 43: } ! 44: ! 45: // 遅延ブランチ出口 ! 46: inline void ! 47: m88kcpu::ExitDelayBranch() ! 48: { ! 49: opF = OpSetDelay(opF); ! 50: } ! 51: ! 52: // ロードストアユニットの usr の処理。 ! 53: // 正常なら true を返す (ので呼び出し側は実行継続)、 ! 54: // 例外が起きたら処理して false を返すので呼び出し側は即リターンすること。 ! 55: inline bool ! 56: m88kcpu::ldst_usr(uint32 size, uint32& usr) ! 57: { ! 58: usr = (opX & (1 << 8)) ? DM_USR : 0; ! 59: if (IsUser() && usr) { ! 60: Exception(M88K_EXCEP_PRIV); ! 61: return false; ! 62: } ! 63: return true; ! 64: } ! 65: ! 66: // ロードストアユニットの scale の処理。addr を返す。 ! 67: inline uint32 ! 68: m88kcpu::ldst_scale(uint32 size) ! 69: { ! 70: if (opX & (1 << 9)) { ! 71: return rS1 + rS2 * size; ! 72: } else { ! 73: return rS1 + rS2; ! 74: } ! 75: } ! 76: ! 77: // ロードストアユニットの align の処理。 ! 78: // 正常なら true を返す (ので呼び出し側は実行継続)、 ! 79: // 例外が起きたら処理して false を返すので呼び出し側は即リターンすること。 ! 80: inline bool ! 81: m88kcpu::ldst_align(uint32 size, uint32& addr) ! 82: { ! 83: if (addr & (size - 1)) { ! 84: if (IsMXM()) { ! 85: addr &= ~(size - 1); ! 86: } else { ! 87: Exception(M88K_EXCEP_MISALIGNED); ! 88: return false; ! 89: } ! 90: } ! 91: return true; ! 92: } ! 93: ! 94: // ロードストアユニットの usr と scale の処理 (呼び出し用マクロ) ! 95: #define LDST_USR_SCALE(size) do { \ ! 96: if (ldst_usr(size, usr) == false) \ ! 97: return; \ ! 98: addr = ldst_scale(size); \ ! 99: } while (0) ! 100: ! 101: // ロードストアユニットの align の処理 (呼び出し用マクロ) ! 102: #define LDST_ALIGN(size) do { \ ! 103: if (ldst_align(size, addr) == false) \ ! 104: return; \ ! 105: } while (0) ! 106: ! 107: // ロードストアユニットのまとめたもの ! 108: #define LDST_USR_SCALE_ALIGN(size) do { \ ! 109: LDST_USR_SCALE(size); \ ! 110: LDST_ALIGN(size); \ ! 111: } while (0) ! 112: ! 113: // 幅規制付き算術左シフト ! 114: static inline uint32 ! 115: ASL(uint32 a, int n) ! 116: { ! 117: if (n <= 0) ! 118: return a; ! 119: if (n >= 32) ! 120: return 0; ! 121: return a << n; ! 122: } ! 123: ! 124: // 幅規制付き算術右シフト ! 125: static inline uint32 ! 126: ASR(uint32 a, int n) ! 127: { ! 128: if (n <= 0) ! 129: return a; ! 130: if (n >= 32) ! 131: return (int32)a < 0 ? -1 : 0; ! 132: // XXX: 負数の右シフト ! 133: return (int32)a >> n; ! 134: } ! 135: ! 136: // 幅規制付き論理右シフト ! 137: static inline uint32 ! 138: LSR(uint32 a, int n) ! 139: { ! 140: if (n <= 0) ! 141: return a; ! 142: if (n >= 32) ! 143: return 0; ! 144: return a >> n; ! 145: } ! 146: ! 147: ! 148: // 右ローテート ! 149: static inline uint32 ! 150: ROR(uint32 a, int n) ! 151: { ! 152: // TODO: 各種コンパイラごとにビルトインがあったりなかったりするらしい ! 153: n &= 31; ! 154: if (n == 0) { ! 155: return a; ! 156: } else { ! 157: return (a >> n) | (a << (32 - n)); ! 158: } ! 159: } ! 160: ! 161: // add でのオーバーフロー条件 ! 162: static inline bool ! 163: isovf_add(uint32 s1, uint32 s2, uint32 res) ! 164: { ! 165: return (int32)((s1 ^ res) & (s2 ^ res)) < 0; ! 166: } ! 167: // sub でのオーバーフロー条件 ! 168: static inline bool ! 169: isovf_sub(uint32 s1, uint32 s2, uint32 res) ! 170: { ! 171: return (int32)((s1 ^ s2) & (s1 ^ res)) < 0; ! 172: } ! 173: ! 174: // cmp のやつ ! 175: static inline uint32 ! 176: acc_cmp(uint32 a, uint32 b) ! 177: { ! 178: uint32 rv = 0; ! 179: if (a >= b) rv |= (1 << 11); ! 180: if (a < b) rv |= (1 << 10); ! 181: if (a <= b) rv |= (1 << 9); ! 182: if (a > b) rv |= (1 << 8); ! 183: if ((int32)a >= (int32)b) rv |= (1 << 7); ! 184: if ((int32)a < (int32)b) rv |= (1 << 6); ! 185: if ((int32)a <= (int32)b) rv |= (1 << 5); ! 186: if ((int32)a > (int32)b) rv |= (1 << 4); ! 187: if ((int32)a != (int32)b) rv |= (1 << 3); ! 188: if ((int32)a == (int32)b) rv |= (1 << 2); ! 189: return rv; ! 190: } ! 191: ! 192: // bcnd のやつ ! 193: static inline int ! 194: acc_cnd(uint32 r) ! 195: { ! 196: int rv; ! 197: if (r & 0x80000000) { ! 198: if (r == 0x80000000) { ! 199: rv = 0x8; ! 200: } else { ! 201: rv = 0x4; ! 202: } ! 203: } else { ! 204: if (r == 0) { ! 205: rv = 0x2; ! 206: } else { ! 207: rv = 0x1; ! 208: } ! 209: } ! 210: return rv; ! 211: } ! 212: ! 213: // bitfield ! 214: static inline uint32 ! 215: acc_bf(int w, int ofs) ! 216: { ! 217: uint32 m; ! 218: if (w == 0) { ! 219: m = 0xFFFFFFFFU; ! 220: } else { ! 221: m = ~(0xFFFFFFFFU << w); ! 222: } ! 223: return m << ofs; ! 224: } ! 225: ! 226: // ここから命令定義 ! 227: ! 228: // 000000_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 229: OP_DEF(xmem_bu_imm) ! 230: { ! 231: uint32 addr; ! 232: uint64 tmp; ! 233: ! 234: addr = rS1 + IMM16; ! 235: LDST_ALIGN(1); ! 236: ! 237: lastaddr = addr; ! 238: tmp = cmmu[1].load_8(addr); ! 239: if ((int64)tmp < 0) { ! 240: ReadDataException(addr, DM_BU | DM_LOCK); ! 241: return; ! 242: } ! 243: if ((int64)cmmu[1].store_8(addr, rD) < 0) { ! 244: WriteDataException(addr, rD, DM_BU | DM_LOCK); ! 245: return; ! 246: } ! 247: if (FLD_D == 0) ! 248: return; ! 249: rD = tmp; ! 250: } ! 251: ! 252: // 000001_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 253: OP_DEF(xmem_w_imm) ! 254: { ! 255: uint32 addr; ! 256: uint64 tmp; ! 257: ! 258: addr = rS1 + IMM16; ! 259: LDST_ALIGN(4); ! 260: ! 261: lastaddr = addr; ! 262: tmp = cmmu[1].load_32(addr); ! 263: if ((int64)tmp < 0) { ! 264: ReadDataException(addr, DM_W | DM_LOCK); ! 265: return; ! 266: } ! 267: if ((int64)cmmu[1].store_32(addr, rD) < 0) { ! 268: WriteDataException(addr, rD, DM_W | DM_LOCK); ! 269: return; ! 270: } ! 271: if (FLD_D == 0) ! 272: return; ! 273: rD = tmp; ! 274: } ! 275: ! 276: // 000010_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 277: OP_DEF(ld_hu_imm) ! 278: { ! 279: uint32 addr; ! 280: uint64 tmp; ! 281: ! 282: addr = rS1 + IMM16; ! 283: LDST_ALIGN(2); ! 284: ! 285: lastaddr = addr; ! 286: tmp = cmmu[1].load_16(addr); ! 287: if ((int64)tmp < 0) { ! 288: ReadDataException(addr, DM_HU); ! 289: return; ! 290: } ! 291: if (FLD_D == 0) ! 292: return; ! 293: rD = tmp; ! 294: } ! 295: ! 296: // 000011_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 297: OP_DEF(ld_bu_imm) ! 298: { ! 299: uint32 addr; ! 300: uint64 tmp; ! 301: ! 302: addr = rS1 + IMM16; ! 303: LDST_ALIGN(1); ! 304: ! 305: lastaddr = addr; ! 306: tmp = cmmu[1].load_8(addr); ! 307: if ((int64)tmp < 0) { ! 308: ReadDataException(addr, DM_BU); ! 309: return; ! 310: } ! 311: if (FLD_D == 0) ! 312: return; ! 313: rD = tmp; ! 314: } ! 315: ! 316: // 000100_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 317: OP_DEF(ld_d_imm) ! 318: { ! 319: uint32 addr; ! 320: uint64 tmp, tmp2; ! 321: ! 322: addr = rS1 + IMM16; ! 323: LDST_ALIGN(8); ! 324: ! 325: lastaddr = addr; ! 326: tmp = cmmu[1].load_32(addr); ! 327: if ((int64)tmp < 0) { ! 328: ReadDataException(addr, DM_D1); ! 329: return; ! 330: } ! 331: addr += 4; ! 332: tmp2 = cmmu[1].load_32(addr); ! 333: if ((int64)tmp2 < 0) { ! 334: ReadDataException(addr, DM_D2); ! 335: return; ! 336: } ! 337: ! 338: rD = tmp; ! 339: r[(FLD_D + 1) & 0x1f] = tmp2; ! 340: r[0] = 0; ! 341: } ! 342: ! 343: // 000101_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 344: OP_DEF(ld_w_imm) ! 345: { ! 346: uint32 addr; ! 347: uint64 tmp; ! 348: ! 349: addr = rS1 + IMM16; ! 350: LDST_ALIGN(4); ! 351: ! 352: lastaddr = addr; ! 353: tmp = cmmu[1].load_32(addr); ! 354: if ((int64)tmp < 0) { ! 355: ReadDataException(addr, DM_W); ! 356: return; ! 357: } ! 358: if (FLD_D == 0) ! 359: return; ! 360: rD = tmp; ! 361: } ! 362: ! 363: // 000110_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 364: OP_DEF(ld_h_imm) ! 365: { ! 366: uint32 addr; ! 367: uint64 tmp; ! 368: ! 369: addr = rS1 + IMM16; ! 370: LDST_ALIGN(2); ! 371: ! 372: lastaddr = addr; ! 373: tmp = cmmu[1].load_16(addr); ! 374: if ((int64)tmp < 0) { ! 375: ReadDataException(addr, DM_H); ! 376: return; ! 377: } ! 378: if (FLD_D == 0) ! 379: return; ! 380: rD = (uint32)(int32)(int16)tmp; ! 381: } ! 382: ! 383: // 000111_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 384: OP_DEF(ld_b_imm) ! 385: { ! 386: uint32 addr; ! 387: uint64 tmp; ! 388: ! 389: addr = rS1 + IMM16; ! 390: LDST_ALIGN(1); ! 391: ! 392: lastaddr = addr; ! 393: tmp = cmmu[1].load_8(addr); ! 394: if ((int64)tmp < 0) { ! 395: ReadDataException(addr, DM_B); ! 396: return; ! 397: } ! 398: if (FLD_D == 0) ! 399: return; ! 400: rD = (uint32)(int32)(int8)tmp; ! 401: } ! 402: ! 403: // 001000_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 404: OP_DEF(st_d_imm) ! 405: { ! 406: uint32 addr; ! 407: ! 408: addr = rS1 + IMM16; ! 409: LDST_ALIGN(8); ! 410: ! 411: lastaddr = addr; ! 412: if ((int64)cmmu[1].store_32(addr, rD) < 0) { ! 413: WriteDataException(addr, rD, DM_D1); ! 414: return; ! 415: } ! 416: addr += 4; ! 417: if ((int64)cmmu[1].store_32(addr, r[(FLD_D + 1) & 0x1f]) < 0) { ! 418: WriteDataException(addr, r[(FLD_D + 1) & 0x1f], DM_D2); ! 419: return; ! 420: } ! 421: } ! 422: ! 423: // 001001_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 424: OP_DEF(st_w_imm) ! 425: { ! 426: uint32 addr; ! 427: ! 428: addr = rS1 + IMM16; ! 429: LDST_ALIGN(4); ! 430: ! 431: lastaddr = addr; ! 432: if ((int64)cmmu[1].store_32(addr, rD) < 0) { ! 433: WriteDataException(addr, rD, DM_W); ! 434: return; ! 435: } ! 436: } ! 437: ! 438: // 001010_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 439: OP_DEF(st_h_imm) ! 440: { ! 441: uint32 addr; ! 442: ! 443: addr = rS1 + IMM16; ! 444: LDST_ALIGN(2); ! 445: ! 446: lastaddr = addr; ! 447: if ((int64)cmmu[1].store_16(addr, rD) < 0) { ! 448: WriteDataException(addr, rD, DM_H); ! 449: return; ! 450: } ! 451: } ! 452: ! 453: // 001011_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 454: OP_DEF(st_b_imm) ! 455: { ! 456: uint32 addr; ! 457: ! 458: addr = rS1 + IMM16; ! 459: LDST_ALIGN(1); ! 460: ! 461: lastaddr = addr; ! 462: if ((int64)cmmu[1].store_8(addr, rD) < 0) { ! 463: WriteDataException(addr, rD, DM_B); ! 464: return; ! 465: } ! 466: } ! 467: ! 468: // 001100_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 469: OP_DEF(lda_d_imm) ! 470: { ! 471: if (FLD_D == 0) ! 472: return; ! 473: rD = rS1 + IMM16; ! 474: } ! 475: ! 476: // 001101_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 477: OP_DEF(lda_w_imm) ! 478: { ! 479: if (FLD_D == 0) ! 480: return; ! 481: rD = rS1 + IMM16; ! 482: } ! 483: ! 484: // 001110_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 485: OP_DEF(lda_h_imm) ! 486: { ! 487: if (FLD_D == 0) ! 488: return; ! 489: rD = rS1 + IMM16; ! 490: } ! 491: ! 492: // 001111_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 493: OP_DEF(lda_b_imm) ! 494: { ! 495: if (FLD_D == 0) ! 496: return; ! 497: rD = rS1 + IMM16; ! 498: } ! 499: ! 500: // 010000_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 501: OP_DEF(and_imm) ! 502: { ! 503: if (FLD_D == 0) ! 504: return; ! 505: rD = rS1 & (IMM16 | 0xffff0000U); ! 506: } ! 507: ! 508: // 010001_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 509: OP_DEF(and_u_imm) ! 510: { ! 511: if (FLD_D == 0) ! 512: return; ! 513: rD = rS1 & ((IMM16 << 16) | 0x0000ffffU); ! 514: } ! 515: ! 516: // 010010_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 517: OP_DEF(mask_imm) ! 518: { ! 519: if (FLD_D == 0) ! 520: return; ! 521: rD = rS1 & IMM16; ! 522: } ! 523: ! 524: // 010011_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 525: OP_DEF(mask_u_imm) ! 526: { ! 527: if (FLD_D == 0) ! 528: return; ! 529: rD = rS1 & (IMM16 << 16); ! 530: } ! 531: ! 532: // 010100_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 533: OP_DEF(xor_imm) ! 534: { ! 535: if (FLD_D == 0) ! 536: return; ! 537: rD = rS1 ^ IMM16; ! 538: } ! 539: ! 540: // 010101_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 541: OP_DEF(xor_u_imm) ! 542: { ! 543: if (FLD_D == 0) ! 544: return; ! 545: rD = rS1 ^ (IMM16 << 16); ! 546: } ! 547: ! 548: // 010110_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 549: OP_DEF(or_imm) ! 550: { ! 551: if (FLD_D == 0) ! 552: return; ! 553: rD = rS1 | IMM16; ! 554: } ! 555: ! 556: // 010111_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 557: OP_DEF(or_u_imm) ! 558: { ! 559: if (FLD_D == 0) ! 560: return; ! 561: rD = rS1 | (IMM16 << 16); ! 562: } ! 563: ! 564: // 011000_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 565: OP_DEF(addu_imm) ! 566: { ! 567: if (FLD_D == 0) ! 568: return; ! 569: rD = rS1 + IMM16; ! 570: } ! 571: ! 572: // 011001_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 573: OP_DEF(subu_imm) ! 574: { ! 575: if (FLD_D == 0) ! 576: return; ! 577: rD = rS1 - IMM16; ! 578: } ! 579: ! 580: // 011010_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 581: OP_DEF(divu_imm) ! 582: { ! 583: if (!IsFPUEnable()) { ! 584: fpu_unimpl(); ! 585: return; ! 586: } ! 587: if (IMM16 == 0) { ! 588: Exception(M88K_EXCEP_INT_DIV); ! 589: return; ! 590: } ! 591: if (FLD_D == 0) ! 592: return; ! 593: rD = rS1 / IMM16; ! 594: } ! 595: ! 596: // 011011_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 597: OP_DEF(mul_imm) ! 598: { ! 599: if (!IsFPUEnable()) { ! 600: fpu_unimpl(); ! 601: return; ! 602: } ! 603: if (FLD_D == 0) ! 604: return; ! 605: rD = rS1 * IMM16; ! 606: } ! 607: ! 608: // 011100_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 609: OP_DEF(add_imm) ! 610: { ! 611: uint32 imm = IMM16; ! 612: uint32 res = rS1 + imm; ! 613: if (isovf_add(rS1, imm, res)) { ! 614: Exception(M88K_EXCEP_INT_OVF); ! 615: return; ! 616: } ! 617: if (FLD_D == 0) ! 618: return; ! 619: rD = res; ! 620: } ! 621: ! 622: // 011101_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 623: OP_DEF(sub_imm) ! 624: { ! 625: uint32 imm = IMM16; ! 626: uint32 res = rS1 - imm; ! 627: if (isovf_sub(rS1, imm, res)) { ! 628: Exception(M88K_EXCEP_INT_OVF); ! 629: return; ! 630: } ! 631: if (FLD_D == 0) ! 632: return; ! 633: rD = res; ! 634: } ! 635: ! 636: // 011110_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 637: OP_DEF(div_imm) ! 638: { ! 639: if (!IsFPUEnable()) { ! 640: fpu_unimpl(); ! 641: return; ! 642: } ! 643: if (rS1 < 0 || IMM16 == 0) { ! 644: Exception(M88K_EXCEP_INT_DIV); ! 645: return; ! 646: } ! 647: if (FLD_D == 0) ! 648: return; ! 649: rD = rS1 / IMM16; ! 650: } ! 651: ! 652: // 011111_DDDDDSSSSS_nnnnnn_nnnnnnnnnn ! 653: OP_DEF(cmp_imm) ! 654: { ! 655: if (FLD_D == 0) ! 656: return; ! 657: rD = acc_cmp(rS1, IMM16); ! 658: } ! 659: ! 660: // 100000_DDDDDzzzzz_01000n_nnnnnzzzzz ! 661: OP_DEF(ldcr) ! 662: { ! 663: if (IsUser()) { ! 664: Exception(M88K_EXCEP_PRIV); ! 665: return; ! 666: } ! 667: if (FLD_CR > countof(cr)) { ! 668: // 88100 undocumented, ! 669: // 88110 compatible ! 670: Exception(M88K_EXCEP_UNIMPL_OP); ! 671: return; ! 672: } ! 673: if (FLD_D == 0) ! 674: return; ! 675: rD = cr[FLD_CR]; ! 676: } ! 677: ! 678: // 100000_DDDDDzzzzz_01001n_nnnnnzzzzz ! 679: OP_DEF(fldcr) ! 680: { ! 681: int n = FLD_CR; ! 682: ! 683: if (IsUser()) { ! 684: // fcr62, 63 はユーザモードでアクセスできる ! 685: // それ以外はスーパバイザ用。 ! 686: if (n < 62) { ! 687: Exception(M88K_EXCEP_PRIV); ! 688: return; ! 689: } ! 690: } ! 691: ! 692: if (8 < n && n < 62) { ! 693: // 未実装 FCR ! 694: // 88100 undocumented, ! 695: // 88110 compatible ! 696: Exception(M88K_EXCEP_UNIMPL_OP); ! 697: return; ! 698: } ! 699: ! 700: // fcr は 62,63 の配置に細工がしてある ! 701: if (n >= 62) { ! 702: n = n - 62 + 9; ! 703: } ! 704: if (FLD_D == 0) ! 705: return; ! 706: rD = fcr[n]; ! 707: } ! 708: ! 709: // 100000_zzzzzSSSSS_10000n_nnnnnsssss ! 710: OP_DEF(stcr) ! 711: { ! 712: if (IsUser()) { ! 713: Exception(M88K_EXCEP_PRIV); ! 714: return; ! 715: } ! 716: if (FLD_CR > countof(cr)) { ! 717: // 88100 undocumented, ! 718: // 88110 unimpl_op ! 719: Exception(M88K_EXCEP_UNIMPL_OP); ! 720: return; ! 721: } ! 722: cr[FLD_CR] = rS1; ! 723: } ! 724: ! 725: // 100000_zzzzzSSSSS_10001n_nnnnnsssss ! 726: OP_DEF(fstcr) ! 727: { ! 728: int n = FLD_CR; ! 729: ! 730: if (IsUser()) { ! 731: // fcr62, 63 はユーザモードでアクセスできる ! 732: // それ以外はスーパバイザ用。 ! 733: if (n < 62) { ! 734: Exception(M88K_EXCEP_PRIV); ! 735: return; ! 736: } ! 737: } ! 738: ! 739: if (8 < n && n < 62) { ! 740: // 未実装 FCR ! 741: // 88100 null op ! 742: // 88110 fpu-unimpl ! 743: return; ! 744: } ! 745: ! 746: // fcr は 62,63 の配置に細工がしてある ! 747: if (n >= 62) { ! 748: n = n - 62 + 9; ! 749: } ! 750: fcr[n] = rS1; ! 751: } ! 752: ! 753: // 100000_DDDDDSSSSS_11000n_nnnnnsssss ! 754: OP_DEF(xcr) ! 755: { ! 756: uint32 tmp; ! 757: ! 758: if (IsUser()) { ! 759: Exception(M88K_EXCEP_PRIV); ! 760: return; ! 761: } ! 762: if (FLD_CR > countof(cr)) { ! 763: // 88100 undocumented, ! 764: // 88110 unimpl_op ! 765: Exception(M88K_EXCEP_UNIMPL_OP); ! 766: return; ! 767: } ! 768: tmp = rS1; ! 769: rD = cr[FLD_CR]; ! 770: cr[FLD_CR] = tmp; ! 771: r[0] = 0; ! 772: } ! 773: ! 774: // 100000_DDDDDSSSSS_11001n_nnnnnsssss ! 775: OP_DEF(fxcr) ! 776: { ! 777: uint32 tmp; ! 778: int n = FLD_CR; ! 779: ! 780: if (IsUser()) { ! 781: // fcr62, 63 はユーザモードでアクセスできる ! 782: // それ以外はスーパバイザ用。 ! 783: if (n < 62) { ! 784: Exception(M88K_EXCEP_PRIV); ! 785: return; ! 786: } ! 787: } ! 788: ! 789: if (8 < n && n < 62) { ! 790: // 未実装 FCR ! 791: // 88100 null op ! 792: // 88110 fpu-unimpl ! 793: return; ! 794: } ! 795: ! 796: // fcr は 62,63 の配置に細工がしてある ! 797: if (n >= 62) { ! 798: n = n - 62 + 9; ! 799: } ! 800: tmp = rS1; ! 801: rD = fcr[n]; ! 802: fcr[n] = tmp; ! 803: r[0] = 0; ! 804: } ! 805: ! 806: // 100001_DDDDDSSSSS_00000n_nnnnnsssss ! 807: OP_DEF(fmul) ! 808: { ! 809: OP_FUNC(unimpl); ! 810: } ! 811: ! 812: // 100001_DDDDD00000_001000_000nnsssss ! 813: OP_DEF(flt) ! 814: { ! 815: OP_FUNC(unimpl); ! 816: } ! 817: ! 818: // 100001_DDDDDSSSSS_00101n_nnnnnsssss ! 819: OP_DEF(fadd) ! 820: { ! 821: OP_FUNC(unimpl); ! 822: } ! 823: ! 824: // 100001_DDDDDSSSSS_00110n_nnnnnsssss ! 825: OP_DEF(fsub) ! 826: { ! 827: OP_FUNC(unimpl); ! 828: } ! 829: ! 830: // 100001_DDDDDSSSSS_00111n_nnnnnsssss ! 831: OP_DEF(fcmp) ! 832: { ! 833: OP_FUNC(unimpl); ! 834: } ! 835: ! 836: // 100001_DDDDD00000_010010_0nn00sssss ! 837: OP_DEF(int) ! 838: { ! 839: OP_FUNC(unimpl); ! 840: } ! 841: ! 842: // 100001_DDDDD00000_010100_0nn00sssss ! 843: OP_DEF(nint) ! 844: { ! 845: OP_FUNC(unimpl); ! 846: } ! 847: ! 848: // 100001_DDDDD00000_010110_0nn00sssss ! 849: OP_DEF(trnc) ! 850: { ! 851: OP_FUNC(unimpl); ! 852: } ! 853: ! 854: // 100001_DDDDDSSSSS_01110n_nnnnnsssss ! 855: OP_DEF(fdiv) ! 856: { ! 857: OP_FUNC(unimpl); ! 858: } ! 859: ! 860: // 110000_nnnnnnnnnn_nnnnnn_nnnnnnnnnn ! 861: OP_DEF(br) ! 862: { ! 863: EnterBranch(); ! 864: fip = xip + D26; ! 865: ExitBranch(); ! 866: } ! 867: ! 868: // 110001_nnnnnnnnnn_nnnnnn_nnnnnnnnnn ! 869: OP_DEF(br_n) ! 870: { ! 871: EnterBranch(); ! 872: fip = xip + D26; ! 873: ExitDelayBranch(); ! 874: } ! 875: ! 876: // 110010_nnnnnnnnnn_nnnnnn_nnnnnnnnnn ! 877: OP_DEF(bsr) ! 878: { ! 879: EnterBranch(); ! 880: fip = xip + D26; ! 881: r[1] = nip; ! 882: ExitBranch(); ! 883: } ! 884: ! 885: // 110011_nnnnnnnnnn_nnnnnn_nnnnnnnnnn ! 886: OP_DEF(bsr_n) ! 887: { ! 888: EnterBranch(); ! 889: fip = xip + D26; ! 890: r[1] = nip + 4; ! 891: ExitDelayBranch(); ! 892: } ! 893: ! 894: // 110100_nnnnnSSSSS_nnnnnn_nnnnnnnnnn ! 895: OP_DEF(bb0) ! 896: { ! 897: if ((rS1 & (1 << B5)) == 0) { ! 898: EnterBranch(); ! 899: fip = xip + D16; ! 900: ExitBranch(); ! 901: } ! 902: } ! 903: ! 904: // 110101_nnnnnSSSSS_nnnnnn_nnnnnnnnnn ! 905: OP_DEF(bb0_n) ! 906: { ! 907: if ((rS1 & (1 << B5)) == 0) { ! 908: EnterBranch(); ! 909: fip = xip + D16; ! 910: ExitDelayBranch(); ! 911: } ! 912: } ! 913: ! 914: // 110110_nnnnnSSSSS_nnnnnn_nnnnnnnnnn ! 915: OP_DEF(bb1) ! 916: { ! 917: if ((rS1 & (1 << B5)) != 0) { ! 918: EnterBranch(); ! 919: fip = xip + D16; ! 920: ExitBranch(); ! 921: } ! 922: } ! 923: ! 924: // 110111_nnnnnSSSSS_nnnnnn_nnnnnnnnnn ! 925: OP_DEF(bb1_n) ! 926: { ! 927: if ((rS1 & (1 << B5)) != 0) { ! 928: EnterBranch(); ! 929: fip = xip + D16; ! 930: ExitDelayBranch(); ! 931: } ! 932: } ! 933: ! 934: // 111010_MMMMMSSSSS_nnnnnn_nnnnnnnnnn ! 935: OP_DEF(bcnd) ! 936: { ! 937: if (acc_cnd(rS1) & M5) { ! 938: EnterBranch(); ! 939: fip = xip + D16; ! 940: ExitBranch(); ! 941: } ! 942: } ! 943: ! 944: // 111011_MMMMMSSSSS_nnnnnn_nnnnnnnnnn ! 945: OP_DEF(bcnd_n) ! 946: { ! 947: if (acc_cnd(rS1) & M5) { ! 948: EnterBranch(); ! 949: fip = xip + D16; ! 950: ExitDelayBranch(); ! 951: } ! 952: } ! 953: ! 954: // 111100_DDDDDSSSSS_100000_wwwwwooooo ! 955: OP_DEF(clr_1) ! 956: { ! 957: if (FLD_D == 0) ! 958: return; ! 959: rD = rS1 & ~acc_bf(W5, O5); ! 960: } ! 961: ! 962: // 111100_DDDDDSSSSS_100010_wwwwwooooo ! 963: OP_DEF(set_1) ! 964: { ! 965: if (FLD_D == 0) ! 966: return; ! 967: rD = rS1 | acc_bf(W5, O5); ! 968: } ! 969: ! 970: // 111100_DDDDDSSSSS_100100_wwwwwooooo ! 971: OP_DEF(ext_1) ! 972: { ! 973: int w, o, left; ! 974: uint32 tmp; ! 975: ! 976: if (FLD_D == 0) ! 977: return; ! 978: w = W5; ! 979: if (w == 0) ! 980: w = 32; ! 981: o = O5; ! 982: left = 32 - w - o; ! 983: tmp = ASL(rS1, left); ! 984: tmp = ASR(tmp, left); ! 985: rD = ASR(tmp, o); ! 986: } ! 987: ! 988: // 111100_DDDDDSSSSS_100110_wwwwwooooo ! 989: OP_DEF(extu_1) ! 990: { ! 991: int w, o, left; ! 992: uint32 tmp; ! 993: ! 994: if (FLD_D == 0) ! 995: return; ! 996: w = W5; ! 997: if (w == 0) ! 998: w = 32; ! 999: o = O5; ! 1000: left = 32 - w - o; ! 1001: tmp = ASL(rS1, left); ! 1002: tmp = LSR(tmp, left); ! 1003: rD = tmp >> o; ! 1004: } ! 1005: ! 1006: // 111100_DDDDDSSSSS_101000_wwwwwooooo ! 1007: OP_DEF(mak_1) ! 1008: { ! 1009: if (FLD_D == 0) ! 1010: return; ! 1011: rD = (rS1 << O5) & acc_bf(W5, O5); ! 1012: } ! 1013: ! 1014: // 111100_DDDDDSSSSS_101010_zzzzzooooo ! 1015: OP_DEF(rot_1) ! 1016: { ! 1017: if (FLD_D == 0) ! 1018: return; ! 1019: rD = ROR(rS1, O5); ! 1020: } ! 1021: ! 1022: // 111100_bbbbbSSSSS_110100_0vvvvvvvvv ! 1023: OP_DEF(tb0) ! 1024: { ! 1025: if (IsUser() && VEC9 < 128) { ! 1026: Exception(M88K_EXCEP_PRIV); ! 1027: return; ! 1028: } ! 1029: if ((rS1 & (1 << B5)) == 0) { ! 1030: ExceptionCore(VEC9, ExceptionKind::TRAP); ! 1031: } ! 1032: } ! 1033: ! 1034: // 111100_bbbbbSSSSS_110110_0vvvvvvvvv ! 1035: OP_DEF(tb1) ! 1036: { ! 1037: if (IsUser() && VEC9 < 128) { ! 1038: Exception(M88K_EXCEP_PRIV); ! 1039: return; ! 1040: } ! 1041: if ((rS1 & (1 << B5)) != 0) { ! 1042: ExceptionCore(VEC9, ExceptionKind::TRAP); ! 1043: } ! 1044: } ! 1045: ! 1046: // 111100_MMMMMSSSSS_111010_0vvvvvvvvv ! 1047: OP_DEF(tcnd) ! 1048: { ! 1049: if (IsUser() && VEC9 < 128) { ! 1050: Exception(M88K_EXCEP_PRIV); ! 1051: return; ! 1052: } ! 1053: if (acc_cnd(rS1) & M5) { ! 1054: ExceptionCore(VEC9, ExceptionKind::TRAP); ! 1055: } ! 1056: } ! 1057: ! 1058: // 111101_DDDDDSSSSS_000000_xU000sssss ! 1059: OP_DEF(xmem_bu) ! 1060: { ! 1061: uint64 tmp; ! 1062: uint32 addr; ! 1063: uint32 usr; ! 1064: ! 1065: LDST_USR_SCALE_ALIGN(1); ! 1066: ! 1067: lastaddr = addr; ! 1068: tmp = cmmu[1].load_8(addr); ! 1069: if ((int64)tmp < 0) { ! 1070: ReadDataException(addr, DM_BU | DM_LOCK | usr); ! 1071: return; ! 1072: } ! 1073: if ((int64)cmmu[1].store_8(addr, rD) < 0) { ! 1074: WriteDataException(addr, rD, DM_BU | DM_LOCK | usr); ! 1075: return; ! 1076: } ! 1077: if (FLD_D == 0) ! 1078: return; ! 1079: rD = tmp; ! 1080: } ! 1081: ! 1082: // 111101_DDDDDSSSSS_000001_xU000sssss ! 1083: OP_DEF(xmem_w) ! 1084: { ! 1085: uint64 tmp; ! 1086: uint32 addr; ! 1087: uint32 usr; ! 1088: ! 1089: LDST_USR_SCALE_ALIGN(4); ! 1090: ! 1091: lastaddr = addr; ! 1092: tmp = cmmu[1].load_32(addr); ! 1093: if ((int64)tmp < 0) { ! 1094: ReadDataException(addr, DM_W | DM_LOCK | usr); ! 1095: return; ! 1096: } ! 1097: if ((int64)cmmu[1].store_32(addr, rD) < 0) { ! 1098: WriteDataException(addr, rD, DM_W | DM_LOCK | usr); ! 1099: return; ! 1100: } ! 1101: if (FLD_D == 0) ! 1102: return; ! 1103: rD = tmp; ! 1104: } ! 1105: ! 1106: // 111101_DDDDDSSSSS_000010_xU000sssss ! 1107: OP_DEF(ld_hu) ! 1108: { ! 1109: uint64 tmp; ! 1110: uint32 addr; ! 1111: uint32 usr; ! 1112: ! 1113: LDST_USR_SCALE_ALIGN(2); ! 1114: ! 1115: lastaddr = addr; ! 1116: tmp = cmmu[1].load_16(addr); ! 1117: if ((int64)tmp < 0) { ! 1118: ReadDataException(addr, DM_HU | usr); ! 1119: return; ! 1120: } ! 1121: if (FLD_D == 0) ! 1122: return; ! 1123: rD = tmp; ! 1124: } ! 1125: ! 1126: // 111101_DDDDDSSSSS_000011_xU000sssss ! 1127: OP_DEF(ld_bu) ! 1128: { ! 1129: uint64 tmp; ! 1130: uint32 addr; ! 1131: uint32 usr; ! 1132: ! 1133: LDST_USR_SCALE_ALIGN(1); ! 1134: ! 1135: lastaddr = addr; ! 1136: tmp = cmmu[1].load_8(addr); ! 1137: if ((int64)tmp < 0) { ! 1138: ReadDataException(addr, DM_BU | usr); ! 1139: return; ! 1140: } ! 1141: if (FLD_D == 0) ! 1142: return; ! 1143: rD = tmp; ! 1144: } ! 1145: ! 1146: // 111101_DDDDDSSSSS_000100_xU000sssss ! 1147: OP_DEF(ld_d) ! 1148: { ! 1149: uint64 tmp, tmp2; ! 1150: uint32 addr; ! 1151: uint32 usr; ! 1152: ! 1153: LDST_USR_SCALE_ALIGN(8); ! 1154: ! 1155: lastaddr = addr; ! 1156: tmp = cmmu[1].load_32(addr); ! 1157: if ((int64)tmp < 0) { ! 1158: ReadDataException(addr, DM_D1 | usr); ! 1159: return; ! 1160: } ! 1161: addr += 4; ! 1162: tmp2 = cmmu[1].load_32(addr); ! 1163: if ((int64)tmp < 0) { ! 1164: ReadDataException(addr, DM_D2 | usr); ! 1165: return; ! 1166: } ! 1167: rD = tmp; ! 1168: r[(FLD_D + 1) & 0x1f] = tmp2; ! 1169: r[0] = 0; ! 1170: } ! 1171: ! 1172: // 111101_DDDDDSSSSS_000101_xU000sssss ! 1173: OP_DEF(ld_w) ! 1174: { ! 1175: uint64 tmp; ! 1176: uint32 addr; ! 1177: uint32 usr; ! 1178: ! 1179: LDST_USR_SCALE_ALIGN(4); ! 1180: ! 1181: lastaddr = addr; ! 1182: tmp = cmmu[1].load_32(addr); ! 1183: if ((int64)tmp < 0) { ! 1184: ReadDataException(addr, DM_W | usr); ! 1185: return; ! 1186: } ! 1187: if (FLD_D == 0) ! 1188: return; ! 1189: rD = tmp; ! 1190: } ! 1191: ! 1192: // 111101_DDDDDSSSSS_000110_xU000sssss ! 1193: OP_DEF(ld_h) ! 1194: { ! 1195: uint64 tmp; ! 1196: uint32 addr; ! 1197: uint32 usr; ! 1198: ! 1199: LDST_USR_SCALE_ALIGN(2); ! 1200: ! 1201: lastaddr = addr; ! 1202: tmp = cmmu[1].load_16(addr); ! 1203: if ((int64)tmp < 0) { ! 1204: ReadDataException(addr, DM_H | usr); ! 1205: return; ! 1206: } ! 1207: if (FLD_D == 0) ! 1208: return; ! 1209: rD = (uint32)(int32)(int16)tmp; ! 1210: } ! 1211: ! 1212: // 111101_DDDDDSSSSS_000111_xU000sssss ! 1213: OP_DEF(ld_b) ! 1214: { ! 1215: uint64 tmp; ! 1216: uint32 addr; ! 1217: uint32 usr; ! 1218: ! 1219: LDST_USR_SCALE_ALIGN(1); ! 1220: ! 1221: lastaddr = addr; ! 1222: tmp = cmmu[1].load_8(addr); ! 1223: if ((int64)tmp < 0) { ! 1224: ReadDataException(addr, DM_B | usr); ! 1225: return; ! 1226: } ! 1227: if (FLD_D == 0) ! 1228: return; ! 1229: rD = (uint32)(int32)(int8)tmp; ! 1230: } ! 1231: ! 1232: // 111101_DDDDDSSSSS_001000_xU000sssss ! 1233: OP_DEF(st_d) ! 1234: { ! 1235: uint32 addr; ! 1236: uint32 usr; ! 1237: ! 1238: LDST_USR_SCALE_ALIGN(8); ! 1239: ! 1240: lastaddr = addr; ! 1241: if ((int64)cmmu[1].store_32(addr, rD) < 0) { ! 1242: WriteDataException(addr, rD, DM_D1 | usr); ! 1243: return; ! 1244: } ! 1245: addr += 4; ! 1246: if ((int64)cmmu[1].store_32(addr, r[(FLD_D + 1) & 0x1f]) < 0) { ! 1247: WriteDataException(addr, r[(FLD_D + 1) & 0x1f], DM_D2 | usr); ! 1248: return; ! 1249: } ! 1250: } ! 1251: ! 1252: // 111101_DDDDDSSSSS_001001_xU000sssss ! 1253: OP_DEF(st_w) ! 1254: { ! 1255: uint32 addr; ! 1256: uint32 usr; ! 1257: ! 1258: LDST_USR_SCALE_ALIGN(4); ! 1259: ! 1260: lastaddr = addr; ! 1261: if ((int64)cmmu[1].store_32(addr, rD) < 0) { ! 1262: WriteDataException(addr, rD, DM_W | usr); ! 1263: return; ! 1264: } ! 1265: } ! 1266: ! 1267: // 111101_DDDDDSSSSS_001010_xU000sssss ! 1268: OP_DEF(st_h) ! 1269: { ! 1270: uint32 addr; ! 1271: uint32 usr; ! 1272: ! 1273: LDST_USR_SCALE_ALIGN(2); ! 1274: ! 1275: lastaddr = addr; ! 1276: if ((int64)cmmu[1].store_16(addr, rD) < 0) { ! 1277: WriteDataException(addr, rD, DM_H | usr); ! 1278: return; ! 1279: } ! 1280: } ! 1281: ! 1282: // 111101_DDDDDSSSSS_001011_xU000sssss ! 1283: OP_DEF(st_b) ! 1284: { ! 1285: uint32 addr; ! 1286: uint32 usr; ! 1287: ! 1288: LDST_USR_SCALE_ALIGN(1); ! 1289: ! 1290: lastaddr = addr; ! 1291: if ((int64)cmmu[1].store_8(addr, rD) < 0) { ! 1292: WriteDataException(addr, rD, DM_B | usr); ! 1293: return; ! 1294: } ! 1295: } ! 1296: ! 1297: // 111101_DDDDDSSSSS_001100_xU000sssss ! 1298: OP_DEF(lda_d) ! 1299: { ! 1300: uint32 addr; ! 1301: uint32 usr; ! 1302: ! 1303: LDST_USR_SCALE(8); ! 1304: ! 1305: if (FLD_D == 0) ! 1306: return; ! 1307: rD = addr; ! 1308: } ! 1309: ! 1310: // 111101_DDDDDSSSSS_001101_xU000sssss ! 1311: OP_DEF(lda_w) ! 1312: { ! 1313: uint32 addr; ! 1314: uint32 usr; ! 1315: ! 1316: LDST_USR_SCALE(4); ! 1317: ! 1318: if (FLD_D == 0) ! 1319: return; ! 1320: rD = addr; ! 1321: } ! 1322: ! 1323: // 111101_DDDDDSSSSS_001110_xU000sssss ! 1324: OP_DEF(lda_h) ! 1325: { ! 1326: uint32 addr; ! 1327: uint32 usr; ! 1328: ! 1329: LDST_USR_SCALE(2); ! 1330: ! 1331: if (FLD_D == 0) ! 1332: return; ! 1333: rD = addr; ! 1334: } ! 1335: ! 1336: // 111101_DDDDDSSSSS_001111_xU000sssss ! 1337: OP_DEF(lda_b) ! 1338: { ! 1339: uint32 addr; ! 1340: uint32 usr; ! 1341: ! 1342: LDST_USR_SCALE(1); ! 1343: ! 1344: if (FLD_D == 0) ! 1345: return; ! 1346: rD = addr; ! 1347: } ! 1348: ! 1349: // 111101_DDDDDSSSSS_010000_00000sssss ! 1350: OP_DEF(and) ! 1351: { ! 1352: if (FLD_D == 0) ! 1353: return; ! 1354: rD = rS1 & rS2; ! 1355: } ! 1356: ! 1357: // 111101_DDDDDSSSSS_010001_00000sssss ! 1358: OP_DEF(and_c) ! 1359: { ! 1360: if (FLD_D == 0) ! 1361: return; ! 1362: rD = rS1 & ~rS2; ! 1363: } ! 1364: ! 1365: // 111101_DDDDDSSSSS_010100_00000sssss ! 1366: OP_DEF(xor) ! 1367: { ! 1368: if (FLD_D == 0) ! 1369: return; ! 1370: rD = rS1 ^ rS2; ! 1371: } ! 1372: ! 1373: // 111101_DDDDDSSSSS_010101_00000sssss ! 1374: OP_DEF(xor_c) ! 1375: { ! 1376: if (FLD_D == 0) ! 1377: return; ! 1378: rD = rS1 ^ ~rS2; ! 1379: } ! 1380: ! 1381: // 111101_DDDDDSSSSS_010110_00000sssss ! 1382: OP_DEF(or) ! 1383: { ! 1384: if (FLD_D == 0) ! 1385: return; ! 1386: rD = rS1 | rS2; ! 1387: } ! 1388: ! 1389: // 111101_DDDDDSSSSS_010111_00000sssss ! 1390: OP_DEF(or_c) ! 1391: { ! 1392: if (FLD_D == 0) ! 1393: return; ! 1394: rD = rS1 | ~rS2; ! 1395: } ! 1396: ! 1397: // 111101_DDDDDSSSSS_011000_nn000sssss ! 1398: OP_DEF(addu) ! 1399: { ! 1400: uint64 res = rS1 + rS2; ! 1401: if (IsCI) { ! 1402: res += GetCY(); ! 1403: } ! 1404: if (IsCO) { ! 1405: SetCY((res >> 32) & 1); ! 1406: } ! 1407: if (FLD_D == 0) ! 1408: return; ! 1409: rD = res; ! 1410: } ! 1411: ! 1412: // 111101_DDDDDSSSSS_011001_nn000sssss ! 1413: OP_DEF(subu) ! 1414: { ! 1415: uint64 res = rS1 - rS2; ! 1416: if (IsCI) { ! 1417: res -= GetCY(); ! 1418: } ! 1419: if (IsCO) { ! 1420: SetCY((res >> 32) & 1); ! 1421: } ! 1422: if (FLD_D == 0) ! 1423: return; ! 1424: rD = res; ! 1425: } ! 1426: ! 1427: // 111101_DDDDDSSSSS_011010_zz000sssss ! 1428: OP_DEF(divu) ! 1429: { ! 1430: if (!IsFPUEnable()) { ! 1431: fpu_unimpl(); ! 1432: return; ! 1433: } ! 1434: if (rS2 == 0) { ! 1435: Exception(M88K_EXCEP_INT_DIV); ! 1436: return; ! 1437: } ! 1438: if (FLD_D == 0) ! 1439: return; ! 1440: rD = rS1 / rS2; ! 1441: } ! 1442: ! 1443: // 111101_DDDDDSSSSS_011011_zz000sssss ! 1444: OP_DEF(mul) ! 1445: { ! 1446: if (!IsFPUEnable()) { ! 1447: fpu_unimpl(); ! 1448: return; ! 1449: } ! 1450: if (FLD_D == 0) ! 1451: return; ! 1452: rD = rS1 * rS2; ! 1453: } ! 1454: ! 1455: // 111101_DDDDDSSSSS_011100_nn000sssss ! 1456: OP_DEF(add) ! 1457: { ! 1458: uint64 res = rS1 + rS2; ! 1459: if (IsCI) { ! 1460: res += GetCY(); ! 1461: } ! 1462: // XXX: オーバーフローが起きたときにキャリーが更新されるかどうか ! 1463: // ドキュメントされてない気がする ! 1464: if (IsCO) { ! 1465: SetCY((res >> 32) & 1); ! 1466: } ! 1467: if (isovf_add(rS1, rS2, res)) { ! 1468: Exception(M88K_EXCEP_INT_OVF); ! 1469: return; ! 1470: } ! 1471: if (FLD_D == 0) ! 1472: return; ! 1473: rD = res; ! 1474: } ! 1475: ! 1476: // 111101_DDDDDSSSSS_011101_nn000sssss ! 1477: OP_DEF(sub) ! 1478: { ! 1479: uint64 res = rS1 - rS2; ! 1480: if (IsCI) { ! 1481: res -= GetCY(); ! 1482: } ! 1483: // XXX: オーバーフローが起きたときにキャリーが更新されるかどうか ! 1484: // ドキュメントされてない気がする ! 1485: if (IsCO) { ! 1486: SetCY((res >> 32) & 1); ! 1487: } ! 1488: if (isovf_sub(rS1, rS2, res)) { ! 1489: Exception(M88K_EXCEP_INT_OVF); ! 1490: return; ! 1491: } ! 1492: if (FLD_D == 0) ! 1493: return; ! 1494: rD = res; ! 1495: } ! 1496: ! 1497: // 111101_DDDDDSSSSS_011110_zz000sssss ! 1498: OP_DEF(div) ! 1499: { ! 1500: if (!IsFPUEnable()) { ! 1501: fpu_unimpl(); ! 1502: return; ! 1503: } ! 1504: if (rS1 < 0 || rS2 <= 0) { ! 1505: Exception(M88K_EXCEP_INT_DIV); ! 1506: return; ! 1507: } ! 1508: if (FLD_D == 0) ! 1509: return; ! 1510: rD = rS1 / rS2; ! 1511: } ! 1512: ! 1513: // 111101_DDDDDSSSSS_011111_zz000sssss ! 1514: OP_DEF(cmp) ! 1515: { ! 1516: if (FLD_D == 0) ! 1517: return; ! 1518: rD = acc_cmp(rS1, rS2); ! 1519: } ! 1520: ! 1521: // 111101_DDDDDSSSSS_100000_00000sssss ! 1522: OP_DEF(clr_2) ! 1523: { ! 1524: if (FLD_D == 0) ! 1525: return; ! 1526: rD = rS1 & ~acc_bf((rS2 >> 5) & 0x1f, rS2 & 0x1f); ! 1527: } ! 1528: ! 1529: // 111101_DDDDDSSSSS_100010_00000sssss ! 1530: OP_DEF(set_2) ! 1531: { ! 1532: if (FLD_D == 0) ! 1533: return; ! 1534: rD = rS1 | acc_bf((rS2 >> 5) & 0x1f, rS2 & 0x1f); ! 1535: } ! 1536: ! 1537: // 111101_DDDDDSSSSS_100100_00000sssss ! 1538: OP_DEF(ext_2) ! 1539: { ! 1540: int w, o, left; ! 1541: uint32 tmp; ! 1542: ! 1543: if (FLD_D == 0) ! 1544: return; ! 1545: w = (rS2 >> 5) & 0x1f; ! 1546: if (w == 0) ! 1547: w = 32; ! 1548: o = (rS2 ) & 0x1f; ! 1549: left = 32 - w - o; ! 1550: tmp = ASL(rS1, left); ! 1551: tmp = ASR(tmp, left); ! 1552: rD = ASR(tmp, o); ! 1553: } ! 1554: ! 1555: // 111101_DDDDDSSSSS_100110_00000sssss ! 1556: OP_DEF(extu_2) ! 1557: { ! 1558: int w, o, left; ! 1559: uint32 tmp; ! 1560: ! 1561: if (FLD_D == 0) ! 1562: return; ! 1563: w = (rS2 >> 5) & 0x1f; ! 1564: if (w == 0) ! 1565: w = 32; ! 1566: o = (rS2 ) & 0x1f; ! 1567: left = 32 - w - o; ! 1568: tmp = ASL(rS1, left); ! 1569: tmp = LSR(tmp, left); ! 1570: rD = tmp >> o; ! 1571: } ! 1572: ! 1573: // 111101_DDDDDSSSSS_101000_00000sssss ! 1574: OP_DEF(mak_2) ! 1575: { ! 1576: if (FLD_D == 0) ! 1577: return; ! 1578: int w = (rS2 >> 5) & 0x1f; ! 1579: int o = (rS2 ) & 0x1f; ! 1580: rD = (rS1 << o) & acc_bf(w, o); ! 1581: } ! 1582: ! 1583: // 111101_DDDDDSSSSS_101010_00000sssss ! 1584: OP_DEF(rot_2) ! 1585: { ! 1586: if (FLD_D == 0) ! 1587: return; ! 1588: int o = (rS2 ) & 0x1f; ! 1589: rD = ROR(rS1, o); ! 1590: } ! 1591: ! 1592: // 111101_zzzzzzzzzz_110000_00000sssss ! 1593: OP_DEF(jmp) ! 1594: { ! 1595: EnterBranch(); ! 1596: fip = rS2; ! 1597: ExitBranch(); ! 1598: } ! 1599: ! 1600: // 111101_zzzzzzzzzz_110001_00000sssss ! 1601: OP_DEF(jmp_n) ! 1602: { ! 1603: EnterBranch(); ! 1604: fip = rS2; ! 1605: ExitDelayBranch(); ! 1606: } ! 1607: ! 1608: // 111101_zzzzzzzzzz_110010_00000sssss ! 1609: OP_DEF(jsr) ! 1610: { ! 1611: EnterBranch(); ! 1612: fip = rS2; ! 1613: r[1] = nip; ! 1614: ExitBranch(); ! 1615: } ! 1616: ! 1617: // 111101_zzzzzzzzzz_110011_00000sssss ! 1618: OP_DEF(jsr_n) ! 1619: { ! 1620: EnterBranch(); ! 1621: fip = rS2; ! 1622: r[1] = nip + 4; ! 1623: ExitDelayBranch(); ! 1624: } ! 1625: ! 1626: // 111101_zzzzzzzzzz_111111_0000000000 ! 1627: OP_DEF(rte) ! 1628: { ! 1629: psr = epsr; ! 1630: ! 1631: fip = snip & SIP_MASK; ! 1632: fetch(); ! 1633: fip = sfip & SIP_MASK; ! 1634: ! 1635: // ディレイスロットにいた命令かどうかをやんわり復元する。 ! 1636: // 88110 ではこの情報が E?IP に保持されているが ! 1637: // 88100 にはない。 ! 1638: if (nip + 4 != fip) { ! 1639: opF = OpSetDelay(opF); ! 1640: } ! 1641: } ! 1642: ! 1643: // 111101_zzzzzSSSSS_111110_00000SSSSS ! 1644: OP_DEF(tbnd_1) ! 1645: { ! 1646: if (rS1 > rS2) { ! 1647: Exception(M88K_EXCEP_BOUNDS); ! 1648: } ! 1649: } ! 1650: ! 1651: // 111110_zzzzzSSSSS_nnnnnn_nnnnnnnnnn ! 1652: OP_DEF(tbnd_2) ! 1653: { ! 1654: if (rS1 > IMM16) { ! 1655: Exception(M88K_EXCEP_BOUNDS); ! 1656: } ! 1657: } ! 1658: ! 1659: // 111111_zzzzzzzzzz_000011_zzzzzzzzzz ! 1660: OP_DEF(getc) ! 1661: { ! 1662: printf("getc inst\n"); ! 1663: int c = getchar(); ! 1664: r[2] = c; ! 1665: } ! 1666: ! 1667: // 111111_zzzzzzzzzz_000100_zzzzzzzzzz ! 1668: OP_DEF(putc) ! 1669: { ! 1670: // r3 を表示 ! 1671: putchar(r[3]); ! 1672: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.