Annotation of nono/m88xx0/m88100ops.cpp, revision 1.1.1.5

1.1       root        1: //
                      2: // nono
1.1.1.2   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
1.1.1.2   root        7: #include "m88100acc.h"
1.1.1.5 ! root        8: #include <cfenv>
        !             9: #include <cmath>
1.1.1.2   root       10: 
1.1       root       11: // 命令のフィールド取り出し
1.1.1.2   root       12: #define FLD_D  m88100opf_D(opX)
                     13: #define FLD_S1 m88100opf_S1(opX)
                     14: #define FLD_S2 m88100opf_S2(opX)
                     15: #define FLD_CR m88100opf_CR(opX)
                     16: #define B5             m88100opf_B5(opX)
                     17: #define M5             m88100opf_M5(opX)
                     18: #define W5             m88100opf_W5(opX)
                     19: #define O5             m88100opf_O5(opX)
                     20: #define IMM16  m88100opf_IMM16(opX)
                     21: #define VEC9   m88100opf_VEC9(opX)
1.1       root       22: 
                     23: // 符号拡張・シフト済みのディスプレースメント
                     24: // XXX: (負数の右シフト)GCC only
                     25: #define D16            (((int32)(int16)opX) << 2)
                     26: #define D26            (((int32)(opX << 6) >> 4))
                     27: #define IsCO   ((opX >> 8) & 1)
                     28: #define IsCI   ((opX >> 9) & 1)
                     29: 
                     30: // レジスタアクセス
                     31: #define rD     (r[FLD_D])
                     32: #define rS1    (r[FLD_S1])
                     33: #define rS2    (r[FLD_S2])
1.1.1.4   root       34: // ダブルワードの2ワード目
1.1.1.5 ! root       35: #define FLD_D2 ((FLD_D + 1) & 0x1f)
        !            36: #define rD2    (r[FLD_D2])
1.1       root       37: 
1.1.1.5 ! root       38: // FP フィールド
        !            39: #define FP_T1  m88100opf_FP_T1(opX)
        !            40: #define FP_T2  m88100opf_FP_T2(opX)
        !            41: #define FP_TD  m88100opf_FP_TD(opX)
        !            42: 
        !            43: // XXX: 暫定
        !            44: #include "fp.h"
        !            45: #define FP_GET(v, t, n)        \
        !            46: do {   \
        !            47:        if (t == 0) {   \
        !            48:                v = u2f(r[n]);  \
        !            49:        } else if (t == 1) {    \
        !            50:                if (n == 31) {  \
        !            51:                        FPException(M88K_FPEXCEP_FUNIMP);       \
        !            52:                        return; \
        !            53:                }       \
        !            54:                v = u2d(((uint64)r[n] << 32) | r[n + 1]);       \
        !            55:        } else {        \
        !            56:                FPException(M88K_FPEXCEP_FROP); \
        !            57:                return; \
        !            58:        }       \
        !            59: } while (0)
        !            60: 
        !            61: #define FP_SET(t, n, v)        \
        !            62: do {   \
        !            63:        if (t == 0) {   \
        !            64:                r[n] = f2u(v);  \
        !            65:        } else if (t == 1) {    \
        !            66:                if (n == 31) {  \
        !            67:                        FPException(M88K_FPEXCEP_FUNIMP);       \
        !            68:                        return; \
        !            69:                }       \
        !            70:                uint64 tmp = d2u(v);    \
        !            71:                r[n] = tmp >> 32;       \
        !            72:                r[n + 1] = (uint32)tmp; \
        !            73:        } else {        \
        !            74:                FPException(M88K_FPEXCEP_FROP); \
        !            75:                return; \
        !            76:        }       \
        !            77: } while (0)
1.1       root       78: 
                     79: // ブランチ命令入り口
                     80: inline void
1.1.1.4   root       81: m88kcpu::EnterBranch(uint32 toaddr)
1.1.1.2   root       82: {
                     83:        // ブランチヒストリに登録しつつ、
                     84:        // ブランチヒストリからブランチ状況を取得
1.1.1.5 ! root       85:        auto e = brhist.AddEntry(xip | (IsSuper() ? 1 : 0), toaddr, opX);
1.1.1.2   root       86:        fip = toaddr;
                     87: 
                     88:        // STOP 検出。
                     89:        // m88k には STOP 状態 (何もせず割り込みだけ待つ状態。m68k の STOP 命令
                     90:        // による STOP 状態に相当するもの) は存在せず、割り込みが起きるまで NOP
                     91:        // 相当の命令を無限ループで実行し続ける方法が一般的にとられる。
                     92:        // 実機であれば (電力が無駄なこと以外は) これで特段困らないかも知れないが
                     93:        // エミュレータ (特に高速モード) ではこのような無限ループはホストの CPU
                     94:        // がぶん回る状況になるため避けたい。そのためこの無限ループを検出したい。
                     95:        // ただし特定の(または定番の)命令列があるわけではなく、任意の無限ループが
                     96:        // 用いられているため、汎用的に自動検出する必要がある。
                     97: 
                     98:        // ループの 1 回目のブランチで初期化して、
                     99:        // 2 回目のブランチで STOP だったかどうかをチェックする。
                    100:        // 3 回目以降の場合は STOP でなかったので、もうチェックする必要はない。
                    101: 
                    102:        // m68k の STOP 命令が特権命令なので、それに倣ってここでも特権状態のみを
                    103:        // 対象とする。
                    104: 
                    105:        // 通常のブランチで来る回数がはるかに多いと考えられるので、
                    106:        // 先にカウント数をチェック対象かどうか調べる。
                    107:        if (e.count < 3 && IsSuper()) {
                    108:                if (e.count == 1) {
                    109:                        // 新規ブランチ
                    110:                        // 初期化
                    111:                        nop_counter = 0;
                    112:                } else {
                    113:                        // e.count == 2 のときだけ STOP の検証をすれば良い。
                    114: 
                    115:                        // d はブランチ間の命令数
                    116:                        uint32 d = (xip - toaddr) / sizeof(uint32);
                    117:                        // 遅延ブランチなら 1 命令余分に実行するはずなので 1 足す
                    118:                        if (opX & (1 << 26)) {
                    119:                                d++;
                    120:                        }
                    121:                        // ブランチ間の命令がすべて NOP なら STOP ということにする。
                    122:                        if (nop_counter == d) {
                    123:                                atomic_reqflag |= CPU_REQ_STOP;
                    124:                        }
                    125:                }
                    126:                // STOP ではなかったら、あとは放置していい
                    127:        }
                    128: }
                    129: 
1.1       root      130: // 通常(即時)ブランチ出口
                    131: inline void
                    132: m88kcpu::ExitBranch()
                    133: {
                    134:        // re-fetch branched instruction
                    135:        fetch();
                    136: }
                    137: 
                    138: // 遅延ブランチ出口
1.1.1.4   root      139: // 速度を稼ぐため、ビット反転だけでこれを区別しているので、
                    140: // 同じ op 中で複数回呼び出さないこと。
1.1       root      141: inline void
                    142: m88kcpu::ExitDelayBranch()
                    143: {
1.1.1.4   root      144:        opF ^= DELAYSLOT;
1.1       root      145: }
                    146: 
                    147: // ロードストアユニットの usr の処理。
                    148: // 正常なら true を返す (ので呼び出し側は実行継続)、
                    149: // 例外が起きたら処理して false を返すので呼び出し側は即リターンすること。
                    150: inline bool
1.1.1.2   root      151: m88kcpu::ldst_usr(uint32& usr)
1.1       root      152: {
                    153:        usr = (opX & (1 << 8)) ? DM_USR : 0;
                    154:        if (IsUser() && usr) {
                    155:                Exception(M88K_EXCEP_PRIV);
                    156:                return false;
                    157:        }
                    158:        return true;
                    159: }
                    160: 
1.1.1.2   root      161: // MEMO: ロードストアでの usr の処理で、CMMU に対して
                    162: // usr を引数ではなくSetSuper() の呼び出しで渡すようにしている。
                    163: // データのロードストアだけがあるのなら usr を引数で渡すほうが
                    164: // 効率的だが、CMMU は 命令/データで同じものを使うため、
                    165: // 命令 CMMU では 100% 無駄な引数の引き渡しが必要になってしまう。
                    166: // そして命令アクセスのほうが何倍も比率が多い。
                    167: // .usr 指定は比率としてはレアなので、状態変更メソッドによる
                    168: // 方法にしてみた。
                    169: 
1.1       root      170: // ロードストアユニットの scale の処理。addr を返す。
                    171: inline uint32
                    172: m88kcpu::ldst_scale(uint32 size)
                    173: {
                    174:        if (opX & (1 << 9)) {
                    175:                return rS1 + rS2 * size;
                    176:        } else {
                    177:                return rS1 + rS2;
                    178:        }
                    179: }
                    180: 
                    181: // ロードストアユニットの align の処理。
                    182: // 正常なら true を返す (ので呼び出し側は実行継続)、
                    183: // 例外が起きたら処理して false を返すので呼び出し側は即リターンすること。
                    184: inline bool
                    185: m88kcpu::ldst_align(uint32 size, uint32& addr)
                    186: {
                    187:        if (addr & (size - 1)) {
                    188:                if (IsMXM()) {
                    189:                        addr &= ~(size - 1);
                    190:                } else {
                    191:                        Exception(M88K_EXCEP_MISALIGNED);
                    192:                        return false;
                    193:                }
                    194:        }
                    195:        return true;
                    196: }
                    197: 
                    198: // ロードストアユニットの usr と scale の処理 (呼び出し用マクロ)
                    199: #define LDST_USR_SCALE(size) do {                              \
1.1.1.2   root      200:        if (ldst_usr(usr) == false)                                     \
1.1       root      201:                return;                                                                 \
                    202:        addr = ldst_scale(size);                                        \
                    203: } while (0)
                    204: 
                    205: // ロードストアユニットの align の処理 (呼び出し用マクロ)
                    206: #define LDST_ALIGN(size) do {                                  \
                    207:        if (ldst_align(size, addr) == false)            \
                    208:                return;                                                                 \
                    209: } while (0)
                    210: 
                    211: // ロードストアユニットのまとめたもの
                    212: #define LDST_USR_SCALE_ALIGN(size) do {                        \
                    213:        LDST_USR_SCALE(size);                                           \
                    214:        LDST_ALIGN(size);                                                       \
                    215: } while (0)
                    216: 
                    217: // 幅規制付き算術左シフト
                    218: static inline uint32
                    219: ASL(uint32 a, int n)
                    220: {
                    221:        if (n <= 0)
                    222:                return a;
                    223:        if (n >= 32)
                    224:                return 0;
                    225:        return a << n;
                    226: }
                    227: 
                    228: // 幅規制付き算術右シフト
                    229: static inline uint32
                    230: ASR(uint32 a, int n)
                    231: {
                    232:        if (n <= 0)
                    233:                return a;
                    234:        if (n >= 32)
                    235:                return (int32)a < 0 ? -1 : 0;
                    236:        // XXX: 負数の右シフト
                    237:        return (int32)a >> n;
                    238: }
                    239: 
                    240: // 幅規制付き論理右シフト
                    241: static inline uint32
                    242: LSR(uint32 a, int n)
                    243: {
                    244:        if (n <= 0)
                    245:                return a;
                    246:        if (n >= 32)
                    247:                return 0;
                    248:        return a >> n;
                    249: }
                    250: 
                    251: 
                    252: // 右ローテート
                    253: static inline uint32
                    254: ROR(uint32 a, int n)
                    255: {
                    256:        // TODO: 各種コンパイラごとにビルトインがあったりなかったりするらしい
                    257:        n &= 31;
                    258:        if (n == 0) {
                    259:                return a;
                    260:        } else {
                    261:                return (a >> n) | (a << (32 - n));
                    262:        }
                    263: }
                    264: 
                    265: // add でのオーバーフロー条件
                    266: static inline bool
                    267: isovf_add(uint32 s1, uint32 s2, uint32 res)
                    268: {
                    269:        return (int32)((s1 ^ res) & (s2 ^ res)) < 0;
                    270: }
                    271: // sub でのオーバーフロー条件
                    272: static inline bool
                    273: isovf_sub(uint32 s1, uint32 s2, uint32 res)
                    274: {
                    275:        return (int32)((s1 ^ s2) & (s1 ^ res)) < 0;
                    276: }
                    277: 
                    278: // bcnd のやつ
                    279: static inline int
                    280: acc_cnd(uint32 r)
                    281: {
                    282:        int rv;
                    283:        if (r & 0x80000000) {
                    284:                if (r == 0x80000000) {
                    285:                        rv = 0x8;
                    286:                } else {
                    287:                        rv = 0x4;
                    288:                }
                    289:        } else {
                    290:                if (r == 0) {
                    291:                        rv = 0x2;
                    292:                } else {
                    293:                        rv = 0x1;
                    294:                }
                    295:        }
                    296:        return rv;
                    297: }
                    298: 
                    299: // bitfield
                    300: static inline uint32
                    301: acc_bf(int w, int ofs)
                    302: {
                    303:        uint32 m;
                    304:        if (w == 0) {
                    305:                m = 0xFFFFFFFFU;
                    306:        } else {
                    307:                m = ~(0xFFFFFFFFU << w);
                    308:        }
                    309:        return m << ofs;
                    310: }
                    311: 
                    312: // ここから命令定義
                    313: 
                    314: // 000000_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    315: OP_DEF(xmem_bu_imm)
                    316: {
                    317:        uint32 addr;
                    318:        uint64 tmp;
                    319: 
                    320:        addr = rS1 + IMM16;
                    321:        LDST_ALIGN(1);
                    322: 
1.1.1.5 ! root      323:        AddCycle(4);    // Table.7-3
1.1.1.4   root      324: 
1.1       root      325:        lastaddr = addr;
1.1.1.2   root      326:        tmp = cmmu[1].xmem_8(addr, rD);
1.1       root      327:        if ((int64)tmp < 0) {
1.1.1.5 ! root      328:                XmemDataException(addr, DM_BU | DM_LOCK);
1.1       root      329:                return;
                    330:        }
                    331:        if (FLD_D == 0)
                    332:                return;
                    333:        rD = tmp;
                    334: }
                    335: 
                    336: // 000001_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    337: OP_DEF(xmem_w_imm)
                    338: {
                    339:        uint32 addr;
                    340:        uint64 tmp;
                    341: 
                    342:        addr = rS1 + IMM16;
                    343:        LDST_ALIGN(4);
                    344: 
1.1.1.5 ! root      345:        AddCycle(4);    // Table.7-3
1.1.1.4   root      346: 
1.1       root      347:        lastaddr = addr;
1.1.1.2   root      348:        tmp = cmmu[1].xmem_32(addr, rD);
1.1       root      349:        if ((int64)tmp < 0) {
1.1.1.5 ! root      350:                XmemDataException(addr, DM_W | DM_LOCK);
1.1       root      351:                return;
                    352:        }
                    353:        if (FLD_D == 0)
                    354:                return;
                    355:        rD = tmp;
                    356: }
                    357: 
                    358: // 000010_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    359: OP_DEF(ld_hu_imm)
                    360: {
                    361:        uint32 addr;
1.1.1.4   root      362:        uint64 data;
1.1       root      363: 
                    364:        addr = rS1 + IMM16;
                    365:        LDST_ALIGN(2);
                    366: 
1.1.1.5 ! root      367:        AddCycle(3);    // Table.7-3
1.1.1.4   root      368: 
1.1       root      369:        lastaddr = addr;
1.1.1.4   root      370:        data = cmmu[1].load_16(addr);
                    371:        if ((int64)data < 0) {
1.1.1.5 ! root      372:                ReadDataException32(addr, DM_HU);
1.1       root      373:                return;
                    374:        }
                    375:        if (FLD_D == 0)
                    376:                return;
1.1.1.4   root      377:        rD = data;
1.1       root      378: }
                    379: 
                    380: // 000011_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    381: OP_DEF(ld_bu_imm)
                    382: {
                    383:        uint32 addr;
1.1.1.4   root      384:        uint64 data;
1.1       root      385: 
                    386:        addr = rS1 + IMM16;
                    387:        LDST_ALIGN(1);
                    388: 
1.1.1.5 ! root      389:        AddCycle(3);    // Table.7-3
1.1.1.4   root      390: 
1.1       root      391:        lastaddr = addr;
1.1.1.4   root      392:        data = cmmu[1].load_8(addr);
                    393:        if ((int64)data < 0) {
1.1.1.5 ! root      394:                ReadDataException32(addr, DM_BU);
1.1       root      395:                return;
                    396:        }
                    397:        if (FLD_D == 0)
                    398:                return;
1.1.1.4   root      399:        rD = data;
1.1       root      400: }
                    401: 
                    402: // 000100_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    403: OP_DEF(ld_d_imm)
                    404: {
                    405:        uint32 addr;
1.1.1.4   root      406:        uint64 data1, data2;
1.1       root      407: 
                    408:        addr = rS1 + IMM16;
                    409:        LDST_ALIGN(8);
                    410: 
1.1.1.5 ! root      411:        AddCycle(4);    // Table.7-3
1.1.1.4   root      412: 
1.1       root      413:        lastaddr = addr;
1.1.1.4   root      414:        data1 = cmmu[1].load_32(addr);
                    415:        if ((int64)data1 < 0) {
1.1.1.5 ! root      416:                ReadDataException64(addr, DM_D1);
1.1       root      417:                return;
                    418:        }
                    419:        addr += 4;
1.1.1.4   root      420:        data2 = cmmu[1].load_32(addr);
                    421:        if ((int64)data2 < 0) {
1.1.1.5 ! root      422:                ReadDataException64(addr, DM_D2);
1.1       root      423:                return;
                    424:        }
                    425: 
1.1.1.4   root      426:        rD  = data1;
                    427:        rD2 = data2;
1.1       root      428:        r[0] = 0;
                    429: }
                    430: 
                    431: // 000101_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    432: OP_DEF(ld_w_imm)
                    433: {
                    434:        uint32 addr;
1.1.1.4   root      435:        uint64 data;
1.1       root      436: 
                    437:        addr = rS1 + IMM16;
                    438:        LDST_ALIGN(4);
                    439: 
1.1.1.5 ! root      440:        AddCycle(3);    // Table.7-3
1.1.1.4   root      441: 
1.1       root      442:        lastaddr = addr;
1.1.1.4   root      443:        data = cmmu[1].load_32(addr);
                    444:        if ((int64)data < 0) {
1.1.1.5 ! root      445:                ReadDataException32(addr, DM_W);
1.1       root      446:                return;
                    447:        }
                    448:        if (FLD_D == 0)
                    449:                return;
1.1.1.4   root      450:        rD = data;
1.1       root      451: }
                    452: 
                    453: // 000110_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    454: OP_DEF(ld_h_imm)
                    455: {
                    456:        uint32 addr;
1.1.1.4   root      457:        uint64 data;
1.1       root      458: 
                    459:        addr = rS1 + IMM16;
                    460:        LDST_ALIGN(2);
                    461: 
1.1.1.5 ! root      462:        AddCycle(3);    // Table.7-3
1.1.1.4   root      463: 
1.1       root      464:        lastaddr = addr;
1.1.1.4   root      465:        data = cmmu[1].load_16(addr);
                    466:        if ((int64)data < 0) {
1.1.1.5 ! root      467:                ReadDataException32(addr, DM_H);
1.1       root      468:                return;
                    469:        }
                    470:        if (FLD_D == 0)
                    471:                return;
1.1.1.4   root      472:        rD = (uint32)(int32)(int16)data;
1.1       root      473: }
                    474: 
                    475: // 000111_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    476: OP_DEF(ld_b_imm)
                    477: {
                    478:        uint32 addr;
1.1.1.4   root      479:        uint64 data;
1.1       root      480: 
                    481:        addr = rS1 + IMM16;
                    482:        LDST_ALIGN(1);
                    483: 
1.1.1.5 ! root      484:        AddCycle(3);    // Table.7-3
1.1.1.4   root      485: 
1.1       root      486:        lastaddr = addr;
1.1.1.4   root      487:        data = cmmu[1].load_8(addr);
                    488:        if ((int64)data < 0) {
1.1.1.5 ! root      489:                ReadDataException32(addr, DM_B);
1.1       root      490:                return;
                    491:        }
                    492:        if (FLD_D == 0)
                    493:                return;
1.1.1.4   root      494:        rD = (uint32)(int32)(int8)data;
1.1       root      495: }
                    496: 
                    497: // 001000_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    498: OP_DEF(st_d_imm)
                    499: {
                    500:        uint32 addr;
1.1.1.4   root      501:        uint64 rv;
1.1       root      502: 
                    503:        addr = rS1 + IMM16;
                    504:        LDST_ALIGN(8);
                    505: 
1.1.1.5 ! root      506:        AddCycle(1 + 4);        // Table.7-3
1.1.1.4   root      507: 
1.1       root      508:        lastaddr = addr;
1.1.1.4   root      509:        rv = cmmu[1].store_32(addr, rD);
                    510:        if ((int64)rv < 0) {
1.1.1.5 ! root      511:                WriteDataException64(addr, DM_D1);
1.1       root      512:                return;
                    513:        }
                    514:        addr += 4;
1.1.1.4   root      515:        rv = cmmu[1].store_32(addr, rD2);
                    516:        if ((int64)rv < 0) {
1.1.1.5 ! root      517:                WriteDataException64(addr, DM_D2);
1.1       root      518:                return;
                    519:        }
                    520: }
                    521: 
                    522: // 001001_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    523: OP_DEF(st_w_imm)
                    524: {
                    525:        uint32 addr;
1.1.1.4   root      526:        uint64 rv;
1.1       root      527: 
                    528:        addr = rS1 + IMM16;
                    529:        LDST_ALIGN(4);
                    530: 
1.1.1.5 ! root      531:        AddCycle(3);    // Table.7-3
1.1.1.4   root      532: 
1.1       root      533:        lastaddr = addr;
1.1.1.4   root      534:        rv = cmmu[1].store_32(addr, rD);
                    535:        if ((int64)rv < 0) {
1.1.1.5 ! root      536:                WriteDataException32(addr, DM_W);
1.1       root      537:                return;
                    538:        }
                    539: }
                    540: 
                    541: // 001010_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    542: OP_DEF(st_h_imm)
                    543: {
                    544:        uint32 addr;
1.1.1.4   root      545:        uint64 rv;
1.1       root      546: 
                    547:        addr = rS1 + IMM16;
                    548:        LDST_ALIGN(2);
                    549: 
1.1.1.5 ! root      550:        AddCycle(3);    // Table.7-3
1.1.1.4   root      551: 
1.1       root      552:        lastaddr = addr;
1.1.1.5 ! root      553:        rv = cmmu[1].store_16(addr, rD & 0xffff);
1.1.1.4   root      554:        if ((int64)rv < 0) {
1.1.1.5 ! root      555:                WriteDataException32(addr, DM_H);
1.1       root      556:                return;
                    557:        }
                    558: }
                    559: 
                    560: // 001011_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    561: OP_DEF(st_b_imm)
                    562: {
                    563:        uint32 addr;
1.1.1.4   root      564:        uint64 rv;
1.1       root      565: 
                    566:        addr = rS1 + IMM16;
                    567:        LDST_ALIGN(1);
                    568: 
1.1.1.5 ! root      569:        AddCycle(3);    // Table.7-3
1.1.1.4   root      570: 
1.1       root      571:        lastaddr = addr;
1.1.1.5 ! root      572:        rv = cmmu[1].store_8(addr, rD & 0xff);
1.1.1.4   root      573:        if ((int64)rv < 0) {
1.1.1.5 ! root      574:                WriteDataException32(addr, DM_B);
1.1       root      575:                return;
                    576:        }
                    577: }
                    578: 
                    579: // 001100_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    580: OP_DEF(lda_d_imm)
                    581: {
                    582:        if (FLD_D == 0)
                    583:                return;
                    584:        rD = rS1 + IMM16;
                    585: }
                    586: 
                    587: // 001101_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    588: OP_DEF(lda_w_imm)
                    589: {
                    590:        if (FLD_D == 0)
                    591:                return;
                    592:        rD = rS1 + IMM16;
                    593: }
                    594: 
                    595: // 001110_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    596: OP_DEF(lda_h_imm)
                    597: {
                    598:        if (FLD_D == 0)
                    599:                return;
                    600:        rD = rS1 + IMM16;
                    601: }
                    602: 
                    603: // 001111_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    604: OP_DEF(lda_b_imm)
                    605: {
                    606:        if (FLD_D == 0)
                    607:                return;
                    608:        rD = rS1 + IMM16;
                    609: }
                    610: 
                    611: // 010000_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    612: OP_DEF(and_imm)
                    613: {
                    614:        if (FLD_D == 0)
                    615:                return;
                    616:        rD = rS1 & (IMM16 | 0xffff0000U);
                    617: }
                    618: 
                    619: // 010001_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    620: OP_DEF(and_u_imm)
                    621: {
                    622:        if (FLD_D == 0)
                    623:                return;
                    624:        rD = rS1 & ((IMM16 << 16) | 0x0000ffffU);
                    625: }
                    626: 
                    627: // 010010_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    628: OP_DEF(mask_imm)
                    629: {
                    630:        if (FLD_D == 0)
                    631:                return;
                    632:        rD = rS1 & IMM16;
                    633: }
                    634: 
                    635: // 010011_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    636: OP_DEF(mask_u_imm)
                    637: {
                    638:        if (FLD_D == 0)
                    639:                return;
                    640:        rD = rS1 & (IMM16 << 16);
                    641: }
                    642: 
                    643: // 010100_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    644: OP_DEF(xor_imm)
                    645: {
                    646:        if (FLD_D == 0)
                    647:                return;
                    648:        rD = rS1 ^ IMM16;
                    649: }
                    650: 
                    651: // 010101_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    652: OP_DEF(xor_u_imm)
                    653: {
                    654:        if (FLD_D == 0)
                    655:                return;
                    656:        rD = rS1 ^ (IMM16 << 16);
                    657: }
                    658: 
                    659: // 010110_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    660: OP_DEF(or_imm)
                    661: {
                    662:        if (FLD_D == 0)
                    663:                return;
                    664:        rD = rS1 | IMM16;
                    665: }
                    666: 
                    667: // 010111_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    668: OP_DEF(or_u_imm)
                    669: {
                    670:        if (FLD_D == 0)
                    671:                return;
                    672:        rD = rS1 | (IMM16 << 16);
                    673: }
                    674: 
                    675: // 011000_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    676: OP_DEF(addu_imm)
                    677: {
                    678:        if (FLD_D == 0)
                    679:                return;
                    680:        rD = rS1 + IMM16;
                    681: }
                    682: 
                    683: // 011001_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    684: OP_DEF(subu_imm)
                    685: {
                    686:        if (FLD_D == 0)
                    687:                return;
                    688:        rD = rS1 - IMM16;
                    689: }
                    690: 
                    691: // 011010_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    692: OP_DEF(divu_imm)
                    693: {
                    694:        if (!IsFPUEnable()) {
                    695:                fpu_unimpl();
                    696:                return;
                    697:        }
1.1.1.4   root      698: 
1.1.1.5 ! root      699:        AddCycle(38);   // Table.7-6 (ただしざっくり)
1.1.1.4   root      700: 
1.1       root      701:        if (IMM16 == 0) {
                    702:                Exception(M88K_EXCEP_INT_DIV);
                    703:                return;
                    704:        }
                    705:        if (FLD_D == 0)
                    706:                return;
                    707:        rD = rS1 / IMM16;
                    708: }
                    709: 
                    710: // 011011_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    711: OP_DEF(mul_imm)
                    712: {
                    713:        if (!IsFPUEnable()) {
                    714:                fpu_unimpl();
                    715:                return;
                    716:        }
1.1.1.4   root      717: 
1.1.1.5 ! root      718:        AddCycle(4);    // Table.7-6 (ただしざっくり)
1.1.1.4   root      719: 
1.1       root      720:        if (FLD_D == 0)
                    721:                return;
                    722:        rD = rS1 * IMM16;
                    723: }
                    724: 
                    725: // 011100_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    726: OP_DEF(add_imm)
                    727: {
                    728:        uint32 imm = IMM16;
                    729:        uint32 res = rS1 + imm;
                    730:        if (isovf_add(rS1, imm, res)) {
                    731:                Exception(M88K_EXCEP_INT_OVF);
                    732:                return;
                    733:        }
                    734:        if (FLD_D == 0)
                    735:                return;
                    736:        rD = res;
                    737: }
                    738: 
                    739: // 011101_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    740: OP_DEF(sub_imm)
                    741: {
                    742:        uint32 imm = IMM16;
                    743:        uint32 res = rS1 - imm;
                    744:        if (isovf_sub(rS1, imm, res)) {
                    745:                Exception(M88K_EXCEP_INT_OVF);
                    746:                return;
                    747:        }
                    748:        if (FLD_D == 0)
                    749:                return;
                    750:        rD = res;
                    751: }
                    752: 
                    753: // 011110_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    754: OP_DEF(div_imm)
                    755: {
                    756:        if (!IsFPUEnable()) {
                    757:                fpu_unimpl();
                    758:                return;
                    759:        }
1.1.1.4   root      760: 
1.1.1.5 ! root      761:        AddCycle(38);   // Table.7-6 (ただしざっくり)
1.1.1.4   root      762: 
1.1.1.2   root      763:        if ((int32)rS1 < 0 || IMM16 == 0) {
1.1       root      764:                Exception(M88K_EXCEP_INT_DIV);
                    765:                return;
                    766:        }
                    767:        if (FLD_D == 0)
                    768:                return;
                    769:        rD = rS1 / IMM16;
                    770: }
                    771: 
                    772: // 011111_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    773: OP_DEF(cmp_imm)
                    774: {
                    775:        if (FLD_D == 0)
                    776:                return;
                    777:        rD = acc_cmp(rS1, IMM16);
                    778: }
                    779: 
                    780: // 100000_DDDDDzzzzz_01000n_nnnnnzzzzz
                    781: OP_DEF(ldcr)
                    782: {
                    783:        if (IsUser()) {
                    784:                Exception(M88K_EXCEP_PRIV);
                    785:                return;
                    786:        }
                    787:        if (FLD_CR > countof(cr)) {
                    788:                // 88100 undocumented,
                    789:                // 88110 compatible
                    790:                Exception(M88K_EXCEP_UNIMPL_OP);
                    791:                return;
                    792:        }
                    793:        if (FLD_D == 0)
                    794:                return;
                    795:        rD = cr[FLD_CR];
                    796: }
                    797: 
                    798: // 100000_DDDDDzzzzz_01001n_nnnnnzzzzz
                    799: OP_DEF(fldcr)
                    800: {
                    801:        int n = FLD_CR;
                    802: 
                    803:        if (IsUser()) {
                    804:                // fcr62, 63 はユーザモードでアクセスできる
                    805:                // それ以外はスーパバイザ用。
                    806:                if (n < 62) {
                    807:                        Exception(M88K_EXCEP_PRIV);
                    808:                        return;
                    809:                }
                    810:        }
                    811: 
                    812:        if (8 < n && n < 62) {
                    813:                // 未実装 FCR
                    814:                // 88100 undocumented,
                    815:                // 88110 compatible
                    816:                Exception(M88K_EXCEP_UNIMPL_OP);
                    817:                return;
                    818:        }
                    819: 
                    820:        // fcr は 62,63 の配置に細工がしてある
                    821:        if (n >= 62) {
                    822:                n = n - 62 + 9;
                    823:        }
                    824:        if (FLD_D == 0)
                    825:                return;
                    826:        rD = fcr[n];
                    827: }
                    828: 
                    829: // 100000_zzzzzSSSSS_10000n_nnnnnsssss
                    830: OP_DEF(stcr)
                    831: {
                    832:        if (IsUser()) {
                    833:                Exception(M88K_EXCEP_PRIV);
                    834:                return;
                    835:        }
                    836:        if (FLD_CR > countof(cr)) {
                    837:                // 88100 undocumented,
                    838:                // 88110 unimpl_op
                    839:                Exception(M88K_EXCEP_UNIMPL_OP);
                    840:                return;
                    841:        }
                    842:        cr[FLD_CR] = rS1;
1.1.1.2   root      843:        if (FLD_CR == 1) {
1.1.1.4   root      844:                SetPSR();
1.1.1.2   root      845:        }
1.1       root      846: }
                    847: 
                    848: // 100000_zzzzzSSSSS_10001n_nnnnnsssss
                    849: OP_DEF(fstcr)
                    850: {
                    851:        int n = FLD_CR;
                    852: 
                    853:        if (IsUser()) {
                    854:                // fcr62, 63 はユーザモードでアクセスできる
                    855:                // それ以外はスーパバイザ用。
                    856:                if (n < 62) {
                    857:                        Exception(M88K_EXCEP_PRIV);
                    858:                        return;
                    859:                }
                    860:        }
                    861: 
                    862:        if (8 < n && n < 62) {
                    863:                // 未実装 FCR
                    864:                // 88100 null op
                    865:                // 88110 fpu-unimpl
                    866:                return;
                    867:        }
                    868: 
                    869:        // fcr は 62,63 の配置に細工がしてある
                    870:        if (n >= 62) {
                    871:                n = n - 62 + 9;
                    872:        }
                    873:        fcr[n] = rS1;
                    874: }
                    875: 
                    876: // 100000_DDDDDSSSSS_11000n_nnnnnsssss
                    877: OP_DEF(xcr)
                    878: {
                    879:        uint32 tmp;
                    880: 
                    881:        if (IsUser()) {
                    882:                Exception(M88K_EXCEP_PRIV);
                    883:                return;
                    884:        }
                    885:        if (FLD_CR > countof(cr)) {
                    886:                // 88100 undocumented,
                    887:                // 88110 unimpl_op
                    888:                Exception(M88K_EXCEP_UNIMPL_OP);
                    889:                return;
                    890:        }
                    891:        tmp = rS1;
                    892:        rD = cr[FLD_CR];
                    893:        cr[FLD_CR] = tmp;
1.1.1.2   root      894:        if (FLD_CR == 1) {
1.1.1.4   root      895:                SetPSR();
1.1.1.2   root      896:        }
1.1       root      897:        r[0] = 0;
                    898: }
                    899: 
                    900: // 100000_DDDDDSSSSS_11001n_nnnnnsssss
                    901: OP_DEF(fxcr)
                    902: {
                    903:        uint32 tmp;
                    904:        int n = FLD_CR;
                    905: 
                    906:        if (IsUser()) {
                    907:                // fcr62, 63 はユーザモードでアクセスできる
                    908:                // それ以外はスーパバイザ用。
                    909:                if (n < 62) {
                    910:                        Exception(M88K_EXCEP_PRIV);
                    911:                        return;
                    912:                }
                    913:        }
                    914: 
                    915:        if (8 < n && n < 62) {
                    916:                // 未実装 FCR
                    917:                // 88100 null op
                    918:                // 88110 fpu-unimpl
                    919:                return;
                    920:        }
                    921: 
                    922:        // fcr は 62,63 の配置に細工がしてある
                    923:        if (n >= 62) {
                    924:                n = n - 62 + 9;
                    925:        }
                    926:        tmp = rS1;
                    927:        rD = fcr[n];
                    928:        fcr[n] = tmp;
                    929:        r[0] = 0;
                    930: }
                    931: 
                    932: // 100001_DDDDDSSSSS_00000n_nnnnnsssss
                    933: OP_DEF(fmul)
                    934: {
1.1.1.5 ! root      935:        // 暫定
        !           936:        double s1;
        !           937:        double s2;
        !           938: 
        !           939:        if (FLD_D == 0) {
        !           940:                FPException(M88K_FPEXCEP_FUNIMP);
        !           941:                return;
        !           942:        }
        !           943: 
        !           944:        FP_GET(s1, FP_T1, FLD_S1);
        !           945:        FP_GET(s2, FP_T2, FLD_S2);
        !           946:        FP_SET(FP_TD, FLD_D, s1 * s2);
1.1       root      947: }
                    948: 
                    949: // 100001_DDDDD00000_001000_000nnsssss
                    950: OP_DEF(flt)
                    951: {
1.1.1.5 ! root      952:        // 暫定
        !           953:        if (FLD_D == 0) {
        !           954:                FPException(M88K_FPEXCEP_FUNIMP);
        !           955:                return;
        !           956:        }
        !           957: 
        !           958:        FP_SET(FP_TD, FLD_D, (double)rS2);
1.1       root      959: }
                    960: 
1.1.1.5 ! root      961: 
1.1       root      962: // 100001_DDDDDSSSSS_00101n_nnnnnsssss
                    963: OP_DEF(fadd)
                    964: {
1.1.1.5 ! root      965:        // 暫定
        !           966:        double s1;
        !           967:        double s2;
        !           968: 
        !           969:        if (FLD_D == 0) {
        !           970:                FPException(M88K_FPEXCEP_FUNIMP);
        !           971:                return;
        !           972:        }
        !           973: 
        !           974:        FP_GET(s1, FP_T1, FLD_S1);
        !           975:        FP_GET(s2, FP_T2, FLD_S2);
        !           976:        FP_SET(FP_TD, FLD_D, s1 + s2);
1.1       root      977: }
                    978: 
                    979: // 100001_DDDDDSSSSS_00110n_nnnnnsssss
                    980: OP_DEF(fsub)
                    981: {
1.1.1.5 ! root      982:        // 暫定
        !           983:        double s1;
        !           984:        double s2;
        !           985: 
        !           986:        if (FLD_D == 0) {
        !           987:                FPException(M88K_FPEXCEP_FUNIMP);
        !           988:                return;
        !           989:        }
        !           990: 
        !           991:        FP_GET(s1, FP_T1, FLD_S1);
        !           992:        FP_GET(s2, FP_T2, FLD_S2);
        !           993:        FP_SET(FP_TD, FLD_D, s1 - s2);
1.1       root      994: }
                    995: 
                    996: // 100001_DDDDDSSSSS_00111n_nnnnnsssss
                    997: OP_DEF(fcmp)
                    998: {
1.1.1.5 ! root      999:        // 暫定
        !          1000:        double s1;
        !          1001:        double s2;
        !          1002: 
        !          1003:        if (FLD_D == 0) {
        !          1004:                FPException(M88K_FPEXCEP_FUNIMP);
        !          1005:                return;
        !          1006:        }
        !          1007: 
        !          1008:        FP_GET(s1, FP_T1, FLD_S1);
        !          1009:        FP_GET(s2, FP_T2, FLD_S2);
        !          1010:        rD = acc_fcmp(s1, s2);
1.1       root     1011: }
                   1012: 
                   1013: // 100001_DDDDD00000_010010_0nn00sssss
                   1014: OP_DEF(int)
                   1015: {
1.1.1.5 ! root     1016:        // 暫定
        !          1017:        double s2;
        !          1018: 
        !          1019:        if (FLD_D == 0) {
        !          1020:                FPException(M88K_FPEXCEP_FUNIMP);
        !          1021:                return;
        !          1022:        }
        !          1023: 
        !          1024:        FP_GET(s2, FP_T2, FLD_S2);
        !          1025: 
        !          1026:        int mode = (fpcr >> 14) & 3;
        !          1027:        switch (mode) {
        !          1028:         case 0:
        !          1029:                std::fesetround(FE_TONEAREST);
        !          1030:                rD = (uint32)(int32)std::nearbyint(s2);
        !          1031:                break;
        !          1032:         case 1:
        !          1033:                rD = (uint32)(int32)std::trunc(s2);
        !          1034:                break;
        !          1035:         case 2:
        !          1036:                rD = (uint32)(int32)std::floor(s2);
        !          1037:                break;
        !          1038:         case 3:
        !          1039:                rD = (uint32)(int32)std::ceil(s2);
        !          1040:                break;
        !          1041:        }
1.1       root     1042: }
                   1043: 
                   1044: // 100001_DDDDD00000_010100_0nn00sssss
                   1045: OP_DEF(nint)
                   1046: {
1.1.1.5 ! root     1047:        // 暫定
        !          1048:        double s2;
        !          1049: 
        !          1050:        if (FLD_D == 0) {
        !          1051:                FPException(M88K_FPEXCEP_FUNIMP);
        !          1052:                return;
        !          1053:        }
        !          1054: 
        !          1055:        FP_GET(s2, FP_T2, FLD_S2);
        !          1056:        std::fesetround(FE_TONEAREST);
        !          1057:        rD = (uint32)(int32)std::nearbyint(s2);
1.1       root     1058: }
                   1059: 
                   1060: // 100001_DDDDD00000_010110_0nn00sssss
                   1061: OP_DEF(trnc)
                   1062: {
1.1.1.5 ! root     1063:        // 暫定
        !          1064:        double s2;
        !          1065: 
        !          1066:        if (FLD_D == 0) {
        !          1067:                FPException(M88K_FPEXCEP_FUNIMP);
        !          1068:                return;
        !          1069:        }
        !          1070: 
        !          1071:        FP_GET(s2, FP_T2, FLD_S2);
        !          1072: printf("trunc(%f) => %f\n", s2, std::trunc(s2));
        !          1073:        rD = (uint32)(int32)std::trunc(s2);
1.1       root     1074: }
                   1075: 
                   1076: // 100001_DDDDDSSSSS_01110n_nnnnnsssss
                   1077: OP_DEF(fdiv)
                   1078: {
1.1.1.5 ! root     1079:        // 暫定
        !          1080:        double s1;
        !          1081:        double s2;
        !          1082: 
        !          1083:        if (FLD_D == 0) {
        !          1084:                FPException(M88K_FPEXCEP_FUNIMP);
        !          1085:                return;
        !          1086:        }
        !          1087: 
        !          1088:        FP_GET(s1, FP_T1, FLD_S1);
        !          1089:        FP_GET(s2, FP_T2, FLD_S2);
        !          1090:        FP_SET(FP_TD, FLD_D, s1 / s2);
1.1       root     1091: }
                   1092: 
                   1093: // 110000_nnnnnnnnnn_nnnnnn_nnnnnnnnnn
                   1094: OP_DEF(br)
                   1095: {
1.1.1.5 ! root     1096:        AddCycle(1);    // Table.7-5
1.1.1.4   root     1097:        EnterBranch(xip + D26);
1.1       root     1098:        ExitBranch();
                   1099: }
                   1100: 
                   1101: // 110001_nnnnnnnnnn_nnnnnn_nnnnnnnnnn
                   1102: OP_DEF(br_n)
                   1103: {
1.1.1.5 ! root     1104:        AddCycle(0);    // Table.7-5
1.1.1.4   root     1105:        EnterBranch(xip + D26);
1.1       root     1106:        ExitDelayBranch();
                   1107: }
                   1108: 
                   1109: // 110010_nnnnnnnnnn_nnnnnn_nnnnnnnnnn
                   1110: OP_DEF(bsr)
                   1111: {
1.1.1.5 ! root     1112:        AddCycle(1);    // Table.7-5
1.1.1.4   root     1113:        EnterBranch(xip + D26);
1.1       root     1114:        r[1] = nip;
                   1115:        ExitBranch();
                   1116: }
                   1117: 
                   1118: // 110011_nnnnnnnnnn_nnnnnn_nnnnnnnnnn
                   1119: OP_DEF(bsr_n)
                   1120: {
1.1.1.5 ! root     1121:        AddCycle(0);    // Table.7-5
1.1.1.4   root     1122:        EnterBranch(xip + D26);
1.1       root     1123:        r[1] = nip + 4;
                   1124:        ExitDelayBranch();
                   1125: }
                   1126: 
                   1127: // 110100_nnnnnSSSSS_nnnnnn_nnnnnnnnnn
                   1128: OP_DEF(bb0)
                   1129: {
                   1130:        if ((rS1 & (1 << B5)) == 0) {
1.1.1.5 ! root     1131:                AddCycle(1);    // Table.7-5
1.1.1.4   root     1132:                EnterBranch(xip + D16);
1.1       root     1133:                ExitBranch();
                   1134:        }
                   1135: }
                   1136: 
                   1137: // 110101_nnnnnSSSSS_nnnnnn_nnnnnnnnnn
                   1138: OP_DEF(bb0_n)
                   1139: {
                   1140:        if ((rS1 & (1 << B5)) == 0) {
1.1.1.4   root     1141:                EnterBranch(xip + D16);
1.1       root     1142:                ExitDelayBranch();
                   1143:        }
                   1144: }
                   1145: 
                   1146: // 110110_nnnnnSSSSS_nnnnnn_nnnnnnnnnn
                   1147: OP_DEF(bb1)
                   1148: {
                   1149:        if ((rS1 & (1 << B5)) != 0) {
1.1.1.5 ! root     1150:                AddCycle(1);    // Table.7-5
1.1.1.4   root     1151:                EnterBranch(xip + D16);
1.1       root     1152:                ExitBranch();
                   1153:        }
                   1154: }
                   1155: 
                   1156: // 110111_nnnnnSSSSS_nnnnnn_nnnnnnnnnn
                   1157: OP_DEF(bb1_n)
                   1158: {
                   1159:        if ((rS1 & (1 << B5)) != 0) {
1.1.1.4   root     1160:                EnterBranch(xip + D16);
1.1       root     1161:                ExitDelayBranch();
                   1162:        }
                   1163: }
                   1164: 
                   1165: // 111010_MMMMMSSSSS_nnnnnn_nnnnnnnnnn
                   1166: OP_DEF(bcnd)
                   1167: {
                   1168:        if (acc_cnd(rS1) & M5) {
1.1.1.5 ! root     1169:                AddCycle(1);    // Table.7-5
1.1.1.4   root     1170:                EnterBranch(xip + D16);
1.1       root     1171:                ExitBranch();
                   1172:        }
                   1173: }
                   1174: 
                   1175: // 111011_MMMMMSSSSS_nnnnnn_nnnnnnnnnn
                   1176: OP_DEF(bcnd_n)
                   1177: {
                   1178:        if (acc_cnd(rS1) & M5) {
1.1.1.4   root     1179:                EnterBranch(xip + D16);
1.1       root     1180:                ExitDelayBranch();
                   1181:        }
                   1182: }
                   1183: 
                   1184: // 111100_DDDDDSSSSS_100000_wwwwwooooo
                   1185: OP_DEF(clr_1)
                   1186: {
                   1187:        if (FLD_D == 0)
                   1188:                return;
                   1189:        rD = rS1 & ~acc_bf(W5, O5);
                   1190: }
                   1191: 
                   1192: // 111100_DDDDDSSSSS_100010_wwwwwooooo
                   1193: OP_DEF(set_1)
                   1194: {
                   1195:        if (FLD_D == 0)
                   1196:                return;
                   1197:        rD = rS1 | acc_bf(W5, O5);
                   1198: }
                   1199: 
                   1200: // 111100_DDDDDSSSSS_100100_wwwwwooooo
                   1201: OP_DEF(ext_1)
                   1202: {
                   1203:        int w, o, left;
                   1204:        uint32 tmp;
                   1205: 
                   1206:        if (FLD_D == 0)
                   1207:                return;
                   1208:        w = W5;
                   1209:        if (w == 0)
                   1210:                w = 32;
                   1211:        o = O5;
                   1212:        left = 32 - w - o;
                   1213:        tmp = ASL(rS1, left);
                   1214:        tmp = ASR(tmp, left);
                   1215:        rD = ASR(tmp, o);
                   1216: }
                   1217: 
                   1218: // 111100_DDDDDSSSSS_100110_wwwwwooooo
                   1219: OP_DEF(extu_1)
                   1220: {
                   1221:        int w, o, left;
                   1222:        uint32 tmp;
                   1223: 
                   1224:        if (FLD_D == 0)
                   1225:                return;
                   1226:        w = W5;
                   1227:        if (w == 0)
                   1228:                w = 32;
                   1229:        o = O5;
                   1230:        left = 32 - w - o;
                   1231:        tmp = ASL(rS1, left);
                   1232:        tmp = LSR(tmp, left);
                   1233:        rD = tmp >> o;
                   1234: }
                   1235: 
                   1236: // 111100_DDDDDSSSSS_101000_wwwwwooooo
                   1237: OP_DEF(mak_1)
                   1238: {
                   1239:        if (FLD_D == 0)
                   1240:                return;
                   1241:        rD = (rS1 << O5) & acc_bf(W5, O5);
                   1242: }
                   1243: 
                   1244: // 111100_DDDDDSSSSS_101010_zzzzzooooo
                   1245: OP_DEF(rot_1)
                   1246: {
                   1247:        if (FLD_D == 0)
                   1248:                return;
                   1249:        rD = ROR(rS1, O5);
                   1250: }
                   1251: 
                   1252: // 111100_bbbbbSSSSS_110100_0vvvvvvvvv
                   1253: OP_DEF(tb0)
                   1254: {
                   1255:        if (IsUser() && VEC9 < 128) {
                   1256:                Exception(M88K_EXCEP_PRIV);
                   1257:                return;
                   1258:        }
                   1259:        if ((rS1 & (1 << B5)) == 0) {
                   1260:                ExceptionCore(VEC9, ExceptionKind::TRAP);
                   1261:        }
                   1262: }
                   1263: 
                   1264: // 111100_bbbbbSSSSS_110110_0vvvvvvvvv
                   1265: OP_DEF(tb1)
                   1266: {
                   1267:        if (IsUser() && VEC9 < 128) {
                   1268:                Exception(M88K_EXCEP_PRIV);
                   1269:                return;
                   1270:        }
                   1271:        if ((rS1 & (1 << B5)) != 0) {
                   1272:                ExceptionCore(VEC9, ExceptionKind::TRAP);
                   1273:        }
                   1274: }
                   1275: 
                   1276: // 111100_MMMMMSSSSS_111010_0vvvvvvvvv
                   1277: OP_DEF(tcnd)
                   1278: {
                   1279:        if (IsUser() && VEC9 < 128) {
                   1280:                Exception(M88K_EXCEP_PRIV);
                   1281:                return;
                   1282:        }
                   1283:        if (acc_cnd(rS1) & M5) {
                   1284:                ExceptionCore(VEC9, ExceptionKind::TRAP);
                   1285:        }
                   1286: }
                   1287: 
                   1288: // 111101_DDDDDSSSSS_000000_xU000sssss
                   1289: OP_DEF(xmem_bu)
                   1290: {
                   1291:        uint64 tmp;
                   1292:        uint32 addr;
                   1293:        uint32 usr;
                   1294: 
                   1295:        LDST_USR_SCALE_ALIGN(1);
                   1296: 
1.1.1.5 ! root     1297:        AddCycle(4);    // Table.7-3
1.1.1.4   root     1298: 
1.1       root     1299:        lastaddr = addr;
1.1.1.2   root     1300: 
                   1301:        // 例外安全のために都度 S/U ビットを制御
                   1302:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
                   1303:        tmp = cmmu[1].xmem_8(addr, rD);
                   1304:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
1.1       root     1305:        if ((int64)tmp < 0) {
1.1.1.5 ! root     1306:                XmemDataException(addr, DM_BU | DM_LOCK | usr);
1.1       root     1307:                return;
                   1308:        }
                   1309:        if (FLD_D == 0)
                   1310:                return;
                   1311:        rD = tmp;
                   1312: }
                   1313: 
                   1314: // 111101_DDDDDSSSSS_000001_xU000sssss
                   1315: OP_DEF(xmem_w)
                   1316: {
                   1317:        uint64 tmp;
                   1318:        uint32 addr;
                   1319:        uint32 usr;
                   1320: 
                   1321:        LDST_USR_SCALE_ALIGN(4);
                   1322: 
1.1.1.5 ! root     1323:        AddCycle(4);    // Table.7-3
1.1.1.4   root     1324: 
1.1       root     1325:        lastaddr = addr;
1.1.1.2   root     1326: 
                   1327:        // 例外安全のために都度 S/U ビットを制御
                   1328:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
                   1329:        tmp = cmmu[1].xmem_32(addr, rD);
                   1330:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
1.1       root     1331:        if ((int64)tmp < 0) {
1.1.1.5 ! root     1332:                XmemDataException(addr, DM_W | DM_LOCK | usr);
1.1       root     1333:                return;
                   1334:        }
1.1.1.2   root     1335: 
1.1       root     1336:        if (FLD_D == 0)
                   1337:                return;
                   1338:        rD = tmp;
                   1339: }
                   1340: 
                   1341: // 111101_DDDDDSSSSS_000010_xU000sssss
                   1342: OP_DEF(ld_hu)
                   1343: {
1.1.1.4   root     1344:        uint64 data;
1.1       root     1345:        uint32 addr;
                   1346:        uint32 usr;
                   1347: 
                   1348:        LDST_USR_SCALE_ALIGN(2);
                   1349: 
1.1.1.5 ! root     1350:        AddCycle(3);    // Table.7-3
1.1.1.4   root     1351: 
1.1       root     1352:        lastaddr = addr;
1.1.1.2   root     1353: 
                   1354:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.4   root     1355:        data = cmmu[1].load_16(addr);
1.1.1.2   root     1356:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1357: 
1.1.1.4   root     1358:        if ((int64)data < 0) {
1.1.1.5 ! root     1359:                ReadDataException32(addr, DM_HU | usr);
1.1       root     1360:                return;
                   1361:        }
                   1362:        if (FLD_D == 0)
                   1363:                return;
1.1.1.4   root     1364:        rD = data;
1.1       root     1365: }
                   1366: 
                   1367: // 111101_DDDDDSSSSS_000011_xU000sssss
                   1368: OP_DEF(ld_bu)
                   1369: {
1.1.1.4   root     1370:        uint64 data;
1.1       root     1371:        uint32 addr;
                   1372:        uint32 usr;
                   1373: 
                   1374:        LDST_USR_SCALE_ALIGN(1);
                   1375: 
1.1.1.5 ! root     1376:        AddCycle(3);    // Table.7-3
1.1.1.4   root     1377: 
1.1       root     1378:        lastaddr = addr;
1.1.1.2   root     1379: 
                   1380:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.4   root     1381:        data = cmmu[1].load_8(addr);
1.1.1.2   root     1382:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1383: 
1.1.1.4   root     1384:        if ((int64)data < 0) {
1.1.1.5 ! root     1385:                ReadDataException32(addr, DM_BU | usr);
1.1       root     1386:                return;
                   1387:        }
                   1388:        if (FLD_D == 0)
                   1389:                return;
1.1.1.4   root     1390:        rD = data;
1.1       root     1391: }
                   1392: 
                   1393: // 111101_DDDDDSSSSS_000100_xU000sssss
                   1394: OP_DEF(ld_d)
                   1395: {
1.1.1.4   root     1396:        uint64 data1, data2;
1.1       root     1397:        uint32 addr;
                   1398:        uint32 usr;
                   1399: 
                   1400:        LDST_USR_SCALE_ALIGN(8);
                   1401: 
1.1.1.5 ! root     1402:        AddCycle(4);    // Table.7-3
1.1.1.4   root     1403: 
1.1       root     1404:        lastaddr = addr;
1.1.1.2   root     1405: 
                   1406:        // 例外安全のために都度 S/U ビットを制御
                   1407:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.4   root     1408:        data1 = cmmu[1].load_32(addr);
1.1.1.2   root     1409:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1410: 
1.1.1.4   root     1411:        if ((int64)data1 < 0) {
1.1.1.5 ! root     1412:                ReadDataException64(addr, DM_D1 | usr);
1.1       root     1413:                return;
                   1414:        }
                   1415:        addr += 4;
1.1.1.2   root     1416: 
                   1417:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.4   root     1418:        data2 = cmmu[1].load_32(addr);
1.1.1.2   root     1419:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1420: 
1.1.1.4   root     1421:        if ((int64)data2 < 0) {
1.1.1.5 ! root     1422:                ReadDataException64(addr, DM_D2 | usr);
1.1       root     1423:                return;
                   1424:        }
1.1.1.4   root     1425:        rD  = data1;
                   1426:        rD2 = data2;
1.1       root     1427:        r[0] = 0;
                   1428: }
                   1429: 
                   1430: // 111101_DDDDDSSSSS_000101_xU000sssss
                   1431: OP_DEF(ld_w)
                   1432: {
1.1.1.4   root     1433:        uint64 data;
1.1       root     1434:        uint32 addr;
                   1435:        uint32 usr;
                   1436: 
                   1437:        LDST_USR_SCALE_ALIGN(4);
                   1438: 
1.1.1.5 ! root     1439:        AddCycle(3);    // Table.7-3
1.1.1.4   root     1440: 
1.1       root     1441:        lastaddr = addr;
1.1.1.2   root     1442: 
                   1443:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.4   root     1444:        data = cmmu[1].load_32(addr);
1.1.1.2   root     1445:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1446: 
1.1.1.4   root     1447:        if ((int64)data < 0) {
1.1.1.5 ! root     1448:                ReadDataException32(addr, DM_W | usr);
1.1       root     1449:                return;
                   1450:        }
                   1451:        if (FLD_D == 0)
                   1452:                return;
1.1.1.4   root     1453:        rD = data;
1.1       root     1454: }
                   1455: 
                   1456: // 111101_DDDDDSSSSS_000110_xU000sssss
                   1457: OP_DEF(ld_h)
                   1458: {
1.1.1.4   root     1459:        uint64 data;
1.1       root     1460:        uint32 addr;
                   1461:        uint32 usr;
                   1462: 
                   1463:        LDST_USR_SCALE_ALIGN(2);
                   1464: 
1.1.1.5 ! root     1465:        AddCycle(3);    // Table.7-3
1.1.1.4   root     1466: 
1.1       root     1467:        lastaddr = addr;
1.1.1.2   root     1468: 
                   1469:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.4   root     1470:        data = cmmu[1].load_16(addr);
1.1.1.2   root     1471:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1472: 
1.1.1.4   root     1473:        if ((int64)data < 0) {
1.1.1.5 ! root     1474:                ReadDataException32(addr, DM_H | usr);
1.1       root     1475:                return;
                   1476:        }
                   1477:        if (FLD_D == 0)
                   1478:                return;
1.1.1.4   root     1479:        rD = (uint32)(int32)(int16)data;
1.1       root     1480: }
                   1481: 
                   1482: // 111101_DDDDDSSSSS_000111_xU000sssss
                   1483: OP_DEF(ld_b)
                   1484: {
1.1.1.4   root     1485:        uint64 data;
1.1       root     1486:        uint32 addr;
                   1487:        uint32 usr;
                   1488: 
                   1489:        LDST_USR_SCALE_ALIGN(1);
                   1490: 
1.1.1.5 ! root     1491:        AddCycle(3);    // Table.7-3
1.1.1.4   root     1492: 
1.1       root     1493:        lastaddr = addr;
1.1.1.2   root     1494: 
                   1495:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.4   root     1496:        data = cmmu[1].load_8(addr);
1.1.1.2   root     1497:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1498: 
1.1.1.4   root     1499:        if ((int64)data < 0) {
1.1.1.5 ! root     1500:                ReadDataException32(addr, DM_B | usr);
1.1       root     1501:                return;
                   1502:        }
                   1503:        if (FLD_D == 0)
                   1504:                return;
1.1.1.4   root     1505:        rD = (uint32)(int32)(int8)data;
1.1       root     1506: }
                   1507: 
                   1508: // 111101_DDDDDSSSSS_001000_xU000sssss
                   1509: OP_DEF(st_d)
                   1510: {
1.1.1.4   root     1511:        uint64 rv;
1.1       root     1512:        uint32 addr;
                   1513:        uint32 usr;
                   1514: 
                   1515:        LDST_USR_SCALE_ALIGN(8);
                   1516: 
1.1.1.5 ! root     1517:        AddCycle(1 + 4);        // Table.7-3
1.1.1.4   root     1518: 
1.1       root     1519:        lastaddr = addr;
1.1.1.2   root     1520: 
                   1521:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.4   root     1522:        rv = cmmu[1].store_32(addr, rD);
1.1.1.2   root     1523:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1524: 
1.1.1.4   root     1525:        if ((int64)rv < 0) {
1.1.1.5 ! root     1526:                WriteDataException64(addr, DM_D1 | usr);
1.1       root     1527:                return;
                   1528:        }
1.1.1.2   root     1529: 
1.1       root     1530:        addr += 4;
1.1.1.2   root     1531: 
                   1532:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.4   root     1533:        rv = cmmu[1].store_32(addr, rD2);
1.1.1.2   root     1534:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1535: 
1.1.1.4   root     1536:        if ((int64)rv < 0) {
1.1.1.5 ! root     1537:                WriteDataException64(addr, DM_D2 | usr);
1.1       root     1538:                return;
                   1539:        }
                   1540: }
                   1541: 
                   1542: // 111101_DDDDDSSSSS_001001_xU000sssss
                   1543: OP_DEF(st_w)
                   1544: {
1.1.1.4   root     1545:        uint64 rv;
1.1       root     1546:        uint32 addr;
                   1547:        uint32 usr;
                   1548: 
                   1549:        LDST_USR_SCALE_ALIGN(4);
                   1550: 
1.1.1.5 ! root     1551:        AddCycle(3);    // Table.7-3
1.1.1.4   root     1552: 
1.1       root     1553:        lastaddr = addr;
1.1.1.2   root     1554: 
                   1555:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.4   root     1556:        rv = cmmu[1].store_32(addr, rD);
1.1.1.2   root     1557:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1558: 
1.1.1.4   root     1559:        if ((int64)rv < 0) {
1.1.1.5 ! root     1560:                WriteDataException32(addr, DM_W | usr);
1.1       root     1561:                return;
                   1562:        }
                   1563: }
                   1564: 
                   1565: // 111101_DDDDDSSSSS_001010_xU000sssss
                   1566: OP_DEF(st_h)
                   1567: {
1.1.1.4   root     1568:        uint64 rv;
1.1       root     1569:        uint32 addr;
                   1570:        uint32 usr;
                   1571: 
                   1572:        LDST_USR_SCALE_ALIGN(2);
                   1573: 
1.1.1.5 ! root     1574:        AddCycle(3);    // Table.7-3
1.1.1.4   root     1575: 
1.1       root     1576:        lastaddr = addr;
1.1.1.2   root     1577: 
                   1578:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.5 ! root     1579:        rv = cmmu[1].store_16(addr, rD & 0xffff);
1.1.1.2   root     1580:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1581: 
1.1.1.4   root     1582:        if ((int64)rv < 0) {
1.1.1.5 ! root     1583:                WriteDataException32(addr, DM_H | usr);
1.1       root     1584:                return;
                   1585:        }
                   1586: }
                   1587: 
                   1588: // 111101_DDDDDSSSSS_001011_xU000sssss
                   1589: OP_DEF(st_b)
                   1590: {
1.1.1.4   root     1591:        uint64 rv;
1.1       root     1592:        uint32 addr;
                   1593:        uint32 usr;
                   1594: 
                   1595:        LDST_USR_SCALE_ALIGN(1);
                   1596: 
1.1.1.5 ! root     1597:        AddCycle(3);    // Table.7-3
1.1.1.4   root     1598: 
1.1       root     1599:        lastaddr = addr;
1.1.1.2   root     1600: 
                   1601:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.5 ! root     1602:        rv = cmmu[1].store_8(addr, rD & 0xff);
1.1.1.2   root     1603:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1604: 
1.1.1.4   root     1605:        if ((int64)rv < 0) {
1.1.1.5 ! root     1606:                WriteDataException32(addr, DM_B | usr);
1.1       root     1607:                return;
                   1608:        }
                   1609: }
                   1610: 
                   1611: // 111101_DDDDDSSSSS_001100_xU000sssss
                   1612: OP_DEF(lda_d)
                   1613: {
                   1614:        uint32 addr;
                   1615:        uint32 usr;
                   1616: 
                   1617:        LDST_USR_SCALE(8);
                   1618: 
                   1619:        if (FLD_D == 0)
                   1620:                return;
                   1621:        rD = addr;
                   1622: }
                   1623: 
                   1624: // 111101_DDDDDSSSSS_001101_xU000sssss
                   1625: OP_DEF(lda_w)
                   1626: {
                   1627:        uint32 addr;
                   1628:        uint32 usr;
                   1629: 
                   1630:        LDST_USR_SCALE(4);
                   1631: 
                   1632:        if (FLD_D == 0)
                   1633:                return;
                   1634:        rD = addr;
                   1635: }
                   1636: 
                   1637: // 111101_DDDDDSSSSS_001110_xU000sssss
                   1638: OP_DEF(lda_h)
                   1639: {
                   1640:        uint32 addr;
                   1641:        uint32 usr;
                   1642: 
                   1643:        LDST_USR_SCALE(2);
                   1644: 
                   1645:        if (FLD_D == 0)
                   1646:                return;
                   1647:        rD = addr;
                   1648: }
                   1649: 
                   1650: // 111101_DDDDDSSSSS_001111_xU000sssss
                   1651: OP_DEF(lda_b)
                   1652: {
                   1653:        uint32 addr;
                   1654:        uint32 usr;
                   1655: 
                   1656:        LDST_USR_SCALE(1);
                   1657: 
                   1658:        if (FLD_D == 0)
                   1659:                return;
                   1660:        rD = addr;
                   1661: }
                   1662: 
                   1663: // 111101_DDDDDSSSSS_010000_00000sssss
                   1664: OP_DEF(and)
                   1665: {
                   1666:        if (FLD_D == 0)
                   1667:                return;
                   1668:        rD = rS1 & rS2;
                   1669: }
                   1670: 
                   1671: // 111101_DDDDDSSSSS_010001_00000sssss
                   1672: OP_DEF(and_c)
                   1673: {
                   1674:        if (FLD_D == 0)
                   1675:                return;
                   1676:        rD = rS1 & ~rS2;
                   1677: }
                   1678: 
                   1679: // 111101_DDDDDSSSSS_010100_00000sssss
                   1680: OP_DEF(xor)
                   1681: {
                   1682:        if (FLD_D == 0)
                   1683:                return;
                   1684:        rD = rS1 ^ rS2;
                   1685: }
                   1686: 
                   1687: // 111101_DDDDDSSSSS_010101_00000sssss
                   1688: OP_DEF(xor_c)
                   1689: {
                   1690:        if (FLD_D == 0)
                   1691:                return;
                   1692:        rD = rS1 ^ ~rS2;
                   1693: }
                   1694: 
                   1695: // 111101_DDDDDSSSSS_010110_00000sssss
                   1696: OP_DEF(or)
                   1697: {
1.1.1.2   root     1698:        if (FLD_D == 0) {
                   1699:                nop_counter++;
1.1       root     1700:                return;
1.1.1.2   root     1701:        }
1.1       root     1702:        rD = rS1 | rS2;
                   1703: }
                   1704: 
                   1705: // 111101_DDDDDSSSSS_010111_00000sssss
                   1706: OP_DEF(or_c)
                   1707: {
                   1708:        if (FLD_D == 0)
                   1709:                return;
                   1710:        rD = rS1 | ~rS2;
                   1711: }
                   1712: 
                   1713: // 111101_DDDDDSSSSS_011000_nn000sssss
                   1714: OP_DEF(addu)
                   1715: {
1.1.1.2   root     1716:        uint64 res = (uint64)rS1 + rS2;
1.1       root     1717:        if (IsCI) {
                   1718:                res += GetCY();
                   1719:        }
                   1720:        if (IsCO) {
1.1.1.4   root     1721:                SetCY(res >> 32);
1.1       root     1722:        }
                   1723:        if (FLD_D == 0)
                   1724:                return;
                   1725:        rD = res;
                   1726: }
                   1727: 
                   1728: // 111101_DDDDDSSSSS_011001_nn000sssss
                   1729: OP_DEF(subu)
                   1730: {
1.1.1.2   root     1731:        // sub 命令では CY ビットは Z80 とかと逆で、0 ならボロー発生。
                   1732:        // 88100 のマニュアルには書いてない。88110 のマニュアルにある。
                   1733: 
                   1734:        // 1 の補数をとって足す。
                   1735:        uint64 res = (uint64)rS1 + (~rS2);
1.1       root     1736:        if (IsCI) {
1.1.1.2   root     1737:                res += GetCY();
                   1738:        } else {
                   1739:                res += 1;
1.1       root     1740:        }
                   1741:        if (IsCO) {
1.1.1.4   root     1742:                SetCY(res >> 32);
1.1       root     1743:        }
                   1744:        if (FLD_D == 0)
                   1745:                return;
                   1746:        rD = res;
                   1747: }
                   1748: 
                   1749: // 111101_DDDDDSSSSS_011010_zz000sssss
                   1750: OP_DEF(divu)
                   1751: {
                   1752:        if (!IsFPUEnable()) {
                   1753:                fpu_unimpl();
                   1754:                return;
                   1755:        }
1.1.1.4   root     1756: 
1.1.1.5 ! root     1757:        AddCycle(38);   // Table.7-6 (ただしざっくり)
1.1.1.4   root     1758: 
1.1       root     1759:        if (rS2 == 0) {
                   1760:                Exception(M88K_EXCEP_INT_DIV);
                   1761:                return;
                   1762:        }
                   1763:        if (FLD_D == 0)
                   1764:                return;
                   1765:        rD = rS1 / rS2;
                   1766: }
                   1767: 
                   1768: // 111101_DDDDDSSSSS_011011_zz000sssss
                   1769: OP_DEF(mul)
                   1770: {
                   1771:        if (!IsFPUEnable()) {
                   1772:                fpu_unimpl();
                   1773:                return;
                   1774:        }
1.1.1.4   root     1775: 
1.1.1.5 ! root     1776:        AddCycle(4);    // Table.7-6 (ただしざっくり)
1.1.1.4   root     1777: 
1.1       root     1778:        if (FLD_D == 0)
                   1779:                return;
                   1780:        rD = rS1 * rS2;
                   1781: }
                   1782: 
                   1783: // 111101_DDDDDSSSSS_011100_nn000sssss
                   1784: OP_DEF(add)
                   1785: {
1.1.1.2   root     1786:        uint64 res = (uint64)rS1 + rS2;
1.1       root     1787:        if (IsCI) {
                   1788:                res += GetCY();
                   1789:        }
                   1790:        // XXX: オーバーフローが起きたときにキャリーが更新されるかどうか
                   1791:        //      ドキュメントされてない気がする
                   1792:        if (IsCO) {
1.1.1.4   root     1793:                SetCY(res >> 32);
1.1       root     1794:        }
                   1795:        if (isovf_add(rS1, rS2, res)) {
                   1796:                Exception(M88K_EXCEP_INT_OVF);
                   1797:                return;
                   1798:        }
                   1799:        if (FLD_D == 0)
                   1800:                return;
                   1801:        rD = res;
                   1802: }
                   1803: 
                   1804: // 111101_DDDDDSSSSS_011101_nn000sssss
                   1805: OP_DEF(sub)
                   1806: {
1.1.1.2   root     1807:        // sub 命令では CY ビットは Z80 とかと逆で、0 ならボロー発生。
                   1808:        // 88100 のマニュアルには書いてない。88110 のマニュアルにある。
                   1809: 
                   1810:        // 1 の補数をとって足す。
                   1811:        uint64 res = (uint64)rS1 + (~rS2);
1.1       root     1812:        if (IsCI) {
1.1.1.2   root     1813:                res += GetCY();
                   1814:        } else {
                   1815:                res += 1;
1.1       root     1816:        }
                   1817:        // XXX: オーバーフローが起きたときにキャリーが更新されるかどうか
                   1818:        //      ドキュメントされてない気がする
                   1819:        if (IsCO) {
1.1.1.4   root     1820:                SetCY(res >> 32);
1.1       root     1821:        }
                   1822:        if (isovf_sub(rS1, rS2, res)) {
                   1823:                Exception(M88K_EXCEP_INT_OVF);
                   1824:                return;
                   1825:        }
                   1826:        if (FLD_D == 0)
                   1827:                return;
                   1828:        rD = res;
                   1829: }
                   1830: 
                   1831: // 111101_DDDDDSSSSS_011110_zz000sssss
                   1832: OP_DEF(div)
                   1833: {
                   1834:        if (!IsFPUEnable()) {
                   1835:                fpu_unimpl();
                   1836:                return;
                   1837:        }
1.1.1.4   root     1838: 
1.1.1.5 ! root     1839:        AddCycle(38);   // Table.7-6 (ただしざっくり)
1.1.1.4   root     1840: 
1.1.1.2   root     1841:        if ((int32)rS1 < 0 || (int32)rS2 <= 0) {
1.1       root     1842:                Exception(M88K_EXCEP_INT_DIV);
                   1843:                return;
                   1844:        }
                   1845:        if (FLD_D == 0)
                   1846:                return;
                   1847:        rD = rS1 / rS2;
                   1848: }
                   1849: 
                   1850: // 111101_DDDDDSSSSS_011111_zz000sssss
                   1851: OP_DEF(cmp)
                   1852: {
                   1853:        if (FLD_D == 0)
                   1854:                return;
                   1855:        rD = acc_cmp(rS1, rS2);
                   1856: }
                   1857: 
                   1858: // 111101_DDDDDSSSSS_100000_00000sssss
                   1859: OP_DEF(clr_2)
                   1860: {
                   1861:        if (FLD_D == 0)
                   1862:                return;
                   1863:        rD = rS1 & ~acc_bf((rS2 >> 5) & 0x1f, rS2 & 0x1f);
                   1864: }
                   1865: 
                   1866: // 111101_DDDDDSSSSS_100010_00000sssss
                   1867: OP_DEF(set_2)
                   1868: {
                   1869:        if (FLD_D == 0)
                   1870:                return;
                   1871:        rD = rS1 | acc_bf((rS2 >> 5) & 0x1f, rS2 & 0x1f);
                   1872: }
                   1873: 
                   1874: // 111101_DDDDDSSSSS_100100_00000sssss
                   1875: OP_DEF(ext_2)
                   1876: {
                   1877:        int w, o, left;
                   1878:        uint32 tmp;
                   1879: 
                   1880:        if (FLD_D == 0)
                   1881:                return;
                   1882:        w = (rS2 >> 5) & 0x1f;
                   1883:        if (w == 0)
                   1884:                w = 32;
                   1885:        o = (rS2     ) & 0x1f;
                   1886:        left = 32 - w - o;
                   1887:        tmp = ASL(rS1, left);
                   1888:        tmp = ASR(tmp, left);
                   1889:        rD = ASR(tmp, o);
                   1890: }
                   1891: 
                   1892: // 111101_DDDDDSSSSS_100110_00000sssss
                   1893: OP_DEF(extu_2)
                   1894: {
                   1895:        int w, o, left;
                   1896:        uint32 tmp;
                   1897: 
                   1898:        if (FLD_D == 0)
                   1899:                return;
                   1900:        w = (rS2 >> 5) & 0x1f;
                   1901:        if (w == 0)
                   1902:                w = 32;
                   1903:        o = (rS2     ) & 0x1f;
                   1904:        left = 32 - w - o;
                   1905:        tmp = ASL(rS1, left);
                   1906:        tmp = LSR(tmp, left);
                   1907:        rD = tmp >> o;
                   1908: }
                   1909: 
                   1910: // 111101_DDDDDSSSSS_101000_00000sssss
                   1911: OP_DEF(mak_2)
                   1912: {
                   1913:        if (FLD_D == 0)
                   1914:                return;
                   1915:        int w = (rS2 >> 5) & 0x1f;
                   1916:        int o = (rS2     ) & 0x1f;
                   1917:        rD = (rS1 << o) & acc_bf(w, o);
                   1918: }
                   1919: 
                   1920: // 111101_DDDDDSSSSS_101010_00000sssss
                   1921: OP_DEF(rot_2)
                   1922: {
                   1923:        if (FLD_D == 0)
                   1924:                return;
                   1925:        int o = (rS2    ) & 0x1f;
                   1926:        rD = ROR(rS1, o);
                   1927: }
                   1928: 
                   1929: // 111101_zzzzzzzzzz_110000_00000sssss
                   1930: OP_DEF(jmp)
                   1931: {
1.1.1.5 ! root     1932:        AddCycle(1);    // Table.7-5
1.1.1.4   root     1933:        EnterBranch(rS2);
1.1       root     1934:        ExitBranch();
                   1935: }
                   1936: 
                   1937: // 111101_zzzzzzzzzz_110001_00000sssss
                   1938: OP_DEF(jmp_n)
                   1939: {
1.1.1.5 ! root     1940:        AddCycle(0);    // Table.7-5
1.1.1.4   root     1941:        EnterBranch(rS2);
1.1       root     1942:        ExitDelayBranch();
                   1943: }
                   1944: 
                   1945: // 111101_zzzzzzzzzz_110010_00000sssss
                   1946: OP_DEF(jsr)
                   1947: {
1.1.1.5 ! root     1948:        AddCycle(1);    // Table.7-5
1.1.1.4   root     1949:        EnterBranch(rS2);
1.1       root     1950:        r[1] = nip;
                   1951:        ExitBranch();
                   1952: }
                   1953: 
                   1954: // 111101_zzzzzzzzzz_110011_00000sssss
                   1955: OP_DEF(jsr_n)
                   1956: {
1.1.1.5 ! root     1957:        AddCycle(0);    // Table.7-5
1.1.1.4   root     1958:        EnterBranch(rS2);
1.1       root     1959:        r[1] = nip + 4;
                   1960:        ExitDelayBranch();
                   1961: }
                   1962: 
1.1.1.2   root     1963: // 111101_DDDDDzzzzz_111010_00000sssss
                   1964: OP_DEF(ff1)
                   1965: {
                   1966:        int i;
                   1967:        uint32 m = 0x80000000U;
                   1968: 
                   1969:        if (FLD_D == 0)
                   1970:                return;
                   1971: 
                   1972:        if (rS2 == 0) {
                   1973:                rD = 32;
                   1974:        } else {
                   1975:                for (i = 31; i >= 0; i--, m >>= 1) {
                   1976:                        if ((rS2 & m) != 0) {
                   1977:                                break;
                   1978:                        }
                   1979:                }
                   1980:                rD = i;
                   1981:        }
                   1982: 
                   1983: }
                   1984: 
                   1985: // 111101_DDDDDzzzzz_111011_00000sssss
                   1986: OP_DEF(ff0)
                   1987: {
                   1988:        int i;
                   1989:        uint32 m = 0x80000000U;
                   1990: 
                   1991:        if (FLD_D == 0)
                   1992:                return;
                   1993: 
                   1994:        if (rS2 == 0xffffffffU) {
                   1995:                rD = 32;
                   1996:        } else {
                   1997:                for (i = 31; i >= 0; i--, m >>= 1) {
                   1998:                        if ((rS2 & m) == 0) {
                   1999:                                break;
                   2000:                        }
                   2001:                }
                   2002:                rD = i;
                   2003:        }
                   2004: }
                   2005: 
1.1       root     2006: // 111101_zzzzzzzzzz_111111_0000000000
                   2007: OP_DEF(rte)
                   2008: {
1.1.1.5 ! root     2009:        AddCycle(2);    // Table.7-5
1.1.1.4   root     2010: 
1.1.1.2   root     2011:        SetPSR(epsr);
1.1       root     2012: 
1.1.1.2   root     2013:        // LUNA88K の ROM1.2 は sxip, snip, sfip を制御してくる。
                   2014:        // ROM1.2 の DAE ハンドラは、
                   2015:        // sxip = INVALID
                   2016:        // snip = 0 (INVALID)
                   2017:        // sfip = original sxip
                   2018:        // で rte してくる。
                   2019:        // CPU は sxip は評価しない。snip は 0 なので、無効として nop 扱い。
                   2020:        // (実際はクロックが消費されるかも?)
                   2021:        // sfip が VALID なので、そこから実行を再開する。
                   2022:        if (snip & SIP_V) {
1.1.1.4   root     2023:                EnterBranch(snip & SIP_MASK);
                   2024:                ExitBranch();
1.1.1.2   root     2025:                fip = sfip & SIP_MASK;
                   2026:        } else {
1.1.1.4   root     2027:                EnterBranch(sfip & SIP_MASK);
                   2028:                ExitBranch();
1.1.1.2   root     2029:        }
1.1       root     2030: 
                   2031:        // ディレイスロットにいた命令かどうかをやんわり復元する。
                   2032:        // 88110 ではこの情報が E?IP に保持されているが
                   2033:        // 88100 にはない。
                   2034:        if (nip + 4 != fip) {
1.1.1.4   root     2035:                ExitDelayBranch();
1.1       root     2036:        }
                   2037: }
                   2038: 
                   2039: // 111101_zzzzzSSSSS_111110_00000SSSSS
                   2040: OP_DEF(tbnd_1)
                   2041: {
                   2042:        if (rS1 > rS2) {
                   2043:                Exception(M88K_EXCEP_BOUNDS);
                   2044:        }
                   2045: }
                   2046: 
                   2047: // 111110_zzzzzSSSSS_nnnnnn_nnnnnnnnnn
                   2048: OP_DEF(tbnd_2)
                   2049: {
                   2050:        if (rS1 > IMM16) {
                   2051:                Exception(M88K_EXCEP_BOUNDS);
                   2052:        }
                   2053: }
                   2054: 
                   2055: // 111111_zzzzzzzzzz_000011_zzzzzzzzzz
                   2056: OP_DEF(getc)
                   2057: {
                   2058:        printf("getc inst\n");
                   2059:        int c = getchar();
                   2060:        r[2] = c;
                   2061: }
                   2062: 
                   2063: // 111111_zzzzzzzzzz_000100_zzzzzzzzzz
                   2064: OP_DEF(putc)
                   2065: {
                   2066:        // r3 を表示
                   2067:        putchar(r[3]);
                   2068: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.