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

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.6 ! root      326:        tmp = cmmu[1].xmem_8(addr, rD & 0xff);
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:        rD = (uint32)(int32)std::trunc(s2);
1.1       root     1073: }
                   1074: 
                   1075: // 100001_DDDDDSSSSS_01110n_nnnnnsssss
                   1076: OP_DEF(fdiv)
                   1077: {
1.1.1.5   root     1078:        // 暫定
                   1079:        double s1;
                   1080:        double s2;
                   1081: 
                   1082:        if (FLD_D == 0) {
                   1083:                FPException(M88K_FPEXCEP_FUNIMP);
                   1084:                return;
                   1085:        }
                   1086: 
                   1087:        FP_GET(s1, FP_T1, FLD_S1);
                   1088:        FP_GET(s2, FP_T2, FLD_S2);
                   1089:        FP_SET(FP_TD, FLD_D, s1 / s2);
1.1       root     1090: }
                   1091: 
                   1092: // 110000_nnnnnnnnnn_nnnnnn_nnnnnnnnnn
                   1093: OP_DEF(br)
                   1094: {
1.1.1.5   root     1095:        AddCycle(1);    // Table.7-5
1.1.1.4   root     1096:        EnterBranch(xip + D26);
1.1       root     1097:        ExitBranch();
                   1098: }
                   1099: 
                   1100: // 110001_nnnnnnnnnn_nnnnnn_nnnnnnnnnn
                   1101: OP_DEF(br_n)
                   1102: {
1.1.1.5   root     1103:        AddCycle(0);    // Table.7-5
1.1.1.4   root     1104:        EnterBranch(xip + D26);
1.1       root     1105:        ExitDelayBranch();
                   1106: }
                   1107: 
                   1108: // 110010_nnnnnnnnnn_nnnnnn_nnnnnnnnnn
                   1109: OP_DEF(bsr)
                   1110: {
1.1.1.5   root     1111:        AddCycle(1);    // Table.7-5
1.1.1.4   root     1112:        EnterBranch(xip + D26);
1.1       root     1113:        r[1] = nip;
                   1114:        ExitBranch();
                   1115: }
                   1116: 
                   1117: // 110011_nnnnnnnnnn_nnnnnn_nnnnnnnnnn
                   1118: OP_DEF(bsr_n)
                   1119: {
1.1.1.5   root     1120:        AddCycle(0);    // Table.7-5
1.1.1.4   root     1121:        EnterBranch(xip + D26);
1.1       root     1122:        r[1] = nip + 4;
                   1123:        ExitDelayBranch();
                   1124: }
                   1125: 
                   1126: // 110100_nnnnnSSSSS_nnnnnn_nnnnnnnnnn
                   1127: OP_DEF(bb0)
                   1128: {
                   1129:        if ((rS1 & (1 << B5)) == 0) {
1.1.1.5   root     1130:                AddCycle(1);    // Table.7-5
1.1.1.4   root     1131:                EnterBranch(xip + D16);
1.1       root     1132:                ExitBranch();
                   1133:        }
                   1134: }
                   1135: 
                   1136: // 110101_nnnnnSSSSS_nnnnnn_nnnnnnnnnn
                   1137: OP_DEF(bb0_n)
                   1138: {
                   1139:        if ((rS1 & (1 << B5)) == 0) {
1.1.1.4   root     1140:                EnterBranch(xip + D16);
1.1       root     1141:                ExitDelayBranch();
                   1142:        }
                   1143: }
                   1144: 
                   1145: // 110110_nnnnnSSSSS_nnnnnn_nnnnnnnnnn
                   1146: OP_DEF(bb1)
                   1147: {
                   1148:        if ((rS1 & (1 << B5)) != 0) {
1.1.1.5   root     1149:                AddCycle(1);    // Table.7-5
1.1.1.4   root     1150:                EnterBranch(xip + D16);
1.1       root     1151:                ExitBranch();
                   1152:        }
                   1153: }
                   1154: 
                   1155: // 110111_nnnnnSSSSS_nnnnnn_nnnnnnnnnn
                   1156: OP_DEF(bb1_n)
                   1157: {
                   1158:        if ((rS1 & (1 << B5)) != 0) {
1.1.1.4   root     1159:                EnterBranch(xip + D16);
1.1       root     1160:                ExitDelayBranch();
                   1161:        }
                   1162: }
                   1163: 
                   1164: // 111010_MMMMMSSSSS_nnnnnn_nnnnnnnnnn
                   1165: OP_DEF(bcnd)
                   1166: {
                   1167:        if (acc_cnd(rS1) & M5) {
1.1.1.5   root     1168:                AddCycle(1);    // Table.7-5
1.1.1.4   root     1169:                EnterBranch(xip + D16);
1.1       root     1170:                ExitBranch();
                   1171:        }
                   1172: }
                   1173: 
                   1174: // 111011_MMMMMSSSSS_nnnnnn_nnnnnnnnnn
                   1175: OP_DEF(bcnd_n)
                   1176: {
                   1177:        if (acc_cnd(rS1) & M5) {
1.1.1.4   root     1178:                EnterBranch(xip + D16);
1.1       root     1179:                ExitDelayBranch();
                   1180:        }
                   1181: }
                   1182: 
                   1183: // 111100_DDDDDSSSSS_100000_wwwwwooooo
                   1184: OP_DEF(clr_1)
                   1185: {
                   1186:        if (FLD_D == 0)
                   1187:                return;
                   1188:        rD = rS1 & ~acc_bf(W5, O5);
                   1189: }
                   1190: 
                   1191: // 111100_DDDDDSSSSS_100010_wwwwwooooo
                   1192: OP_DEF(set_1)
                   1193: {
                   1194:        if (FLD_D == 0)
                   1195:                return;
                   1196:        rD = rS1 | acc_bf(W5, O5);
                   1197: }
                   1198: 
                   1199: // 111100_DDDDDSSSSS_100100_wwwwwooooo
                   1200: OP_DEF(ext_1)
                   1201: {
                   1202:        int w, o, left;
                   1203:        uint32 tmp;
                   1204: 
                   1205:        if (FLD_D == 0)
                   1206:                return;
                   1207:        w = W5;
                   1208:        if (w == 0)
                   1209:                w = 32;
                   1210:        o = O5;
                   1211:        left = 32 - w - o;
                   1212:        tmp = ASL(rS1, left);
                   1213:        tmp = ASR(tmp, left);
                   1214:        rD = ASR(tmp, o);
                   1215: }
                   1216: 
                   1217: // 111100_DDDDDSSSSS_100110_wwwwwooooo
                   1218: OP_DEF(extu_1)
                   1219: {
                   1220:        int w, o, left;
                   1221:        uint32 tmp;
                   1222: 
                   1223:        if (FLD_D == 0)
                   1224:                return;
                   1225:        w = W5;
                   1226:        if (w == 0)
                   1227:                w = 32;
                   1228:        o = O5;
                   1229:        left = 32 - w - o;
                   1230:        tmp = ASL(rS1, left);
                   1231:        tmp = LSR(tmp, left);
                   1232:        rD = tmp >> o;
                   1233: }
                   1234: 
                   1235: // 111100_DDDDDSSSSS_101000_wwwwwooooo
                   1236: OP_DEF(mak_1)
                   1237: {
                   1238:        if (FLD_D == 0)
                   1239:                return;
                   1240:        rD = (rS1 << O5) & acc_bf(W5, O5);
                   1241: }
                   1242: 
                   1243: // 111100_DDDDDSSSSS_101010_zzzzzooooo
                   1244: OP_DEF(rot_1)
                   1245: {
                   1246:        if (FLD_D == 0)
                   1247:                return;
                   1248:        rD = ROR(rS1, O5);
                   1249: }
                   1250: 
                   1251: // 111100_bbbbbSSSSS_110100_0vvvvvvvvv
                   1252: OP_DEF(tb0)
                   1253: {
                   1254:        if (IsUser() && VEC9 < 128) {
                   1255:                Exception(M88K_EXCEP_PRIV);
                   1256:                return;
                   1257:        }
                   1258:        if ((rS1 & (1 << B5)) == 0) {
                   1259:                ExceptionCore(VEC9, ExceptionKind::TRAP);
                   1260:        }
                   1261: }
                   1262: 
                   1263: // 111100_bbbbbSSSSS_110110_0vvvvvvvvv
                   1264: OP_DEF(tb1)
                   1265: {
                   1266:        if (IsUser() && VEC9 < 128) {
                   1267:                Exception(M88K_EXCEP_PRIV);
                   1268:                return;
                   1269:        }
                   1270:        if ((rS1 & (1 << B5)) != 0) {
                   1271:                ExceptionCore(VEC9, ExceptionKind::TRAP);
                   1272:        }
                   1273: }
                   1274: 
                   1275: // 111100_MMMMMSSSSS_111010_0vvvvvvvvv
                   1276: OP_DEF(tcnd)
                   1277: {
                   1278:        if (IsUser() && VEC9 < 128) {
                   1279:                Exception(M88K_EXCEP_PRIV);
                   1280:                return;
                   1281:        }
                   1282:        if (acc_cnd(rS1) & M5) {
                   1283:                ExceptionCore(VEC9, ExceptionKind::TRAP);
                   1284:        }
                   1285: }
                   1286: 
                   1287: // 111101_DDDDDSSSSS_000000_xU000sssss
                   1288: OP_DEF(xmem_bu)
                   1289: {
                   1290:        uint64 tmp;
                   1291:        uint32 addr;
                   1292:        uint32 usr;
                   1293: 
                   1294:        LDST_USR_SCALE_ALIGN(1);
                   1295: 
1.1.1.5   root     1296:        AddCycle(4);    // Table.7-3
1.1.1.4   root     1297: 
1.1       root     1298:        lastaddr = addr;
1.1.1.2   root     1299: 
                   1300:        // 例外安全のために都度 S/U ビットを制御
                   1301:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.6 ! root     1302:        tmp = cmmu[1].xmem_8(addr, rD & 0xff);
1.1.1.2   root     1303:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
1.1       root     1304:        if ((int64)tmp < 0) {
1.1.1.5   root     1305:                XmemDataException(addr, DM_BU | DM_LOCK | usr);
1.1       root     1306:                return;
                   1307:        }
                   1308:        if (FLD_D == 0)
                   1309:                return;
                   1310:        rD = tmp;
                   1311: }
                   1312: 
                   1313: // 111101_DDDDDSSSSS_000001_xU000sssss
                   1314: OP_DEF(xmem_w)
                   1315: {
                   1316:        uint64 tmp;
                   1317:        uint32 addr;
                   1318:        uint32 usr;
                   1319: 
                   1320:        LDST_USR_SCALE_ALIGN(4);
                   1321: 
1.1.1.5   root     1322:        AddCycle(4);    // Table.7-3
1.1.1.4   root     1323: 
1.1       root     1324:        lastaddr = addr;
1.1.1.2   root     1325: 
                   1326:        // 例外安全のために都度 S/U ビットを制御
                   1327:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
                   1328:        tmp = cmmu[1].xmem_32(addr, rD);
                   1329:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
1.1       root     1330:        if ((int64)tmp < 0) {
1.1.1.5   root     1331:                XmemDataException(addr, DM_W | DM_LOCK | usr);
1.1       root     1332:                return;
                   1333:        }
1.1.1.2   root     1334: 
1.1       root     1335:        if (FLD_D == 0)
                   1336:                return;
                   1337:        rD = tmp;
                   1338: }
                   1339: 
                   1340: // 111101_DDDDDSSSSS_000010_xU000sssss
                   1341: OP_DEF(ld_hu)
                   1342: {
1.1.1.4   root     1343:        uint64 data;
1.1       root     1344:        uint32 addr;
                   1345:        uint32 usr;
                   1346: 
                   1347:        LDST_USR_SCALE_ALIGN(2);
                   1348: 
1.1.1.5   root     1349:        AddCycle(3);    // Table.7-3
1.1.1.4   root     1350: 
1.1       root     1351:        lastaddr = addr;
1.1.1.2   root     1352: 
                   1353:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.4   root     1354:        data = cmmu[1].load_16(addr);
1.1.1.2   root     1355:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1356: 
1.1.1.4   root     1357:        if ((int64)data < 0) {
1.1.1.5   root     1358:                ReadDataException32(addr, DM_HU | usr);
1.1       root     1359:                return;
                   1360:        }
                   1361:        if (FLD_D == 0)
                   1362:                return;
1.1.1.4   root     1363:        rD = data;
1.1       root     1364: }
                   1365: 
                   1366: // 111101_DDDDDSSSSS_000011_xU000sssss
                   1367: OP_DEF(ld_bu)
                   1368: {
1.1.1.4   root     1369:        uint64 data;
1.1       root     1370:        uint32 addr;
                   1371:        uint32 usr;
                   1372: 
                   1373:        LDST_USR_SCALE_ALIGN(1);
                   1374: 
1.1.1.5   root     1375:        AddCycle(3);    // Table.7-3
1.1.1.4   root     1376: 
1.1       root     1377:        lastaddr = addr;
1.1.1.2   root     1378: 
                   1379:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.4   root     1380:        data = cmmu[1].load_8(addr);
1.1.1.2   root     1381:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1382: 
1.1.1.4   root     1383:        if ((int64)data < 0) {
1.1.1.5   root     1384:                ReadDataException32(addr, DM_BU | usr);
1.1       root     1385:                return;
                   1386:        }
                   1387:        if (FLD_D == 0)
                   1388:                return;
1.1.1.4   root     1389:        rD = data;
1.1       root     1390: }
                   1391: 
                   1392: // 111101_DDDDDSSSSS_000100_xU000sssss
                   1393: OP_DEF(ld_d)
                   1394: {
1.1.1.4   root     1395:        uint64 data1, data2;
1.1       root     1396:        uint32 addr;
                   1397:        uint32 usr;
                   1398: 
                   1399:        LDST_USR_SCALE_ALIGN(8);
                   1400: 
1.1.1.5   root     1401:        AddCycle(4);    // Table.7-3
1.1.1.4   root     1402: 
1.1       root     1403:        lastaddr = addr;
1.1.1.2   root     1404: 
                   1405:        // 例外安全のために都度 S/U ビットを制御
                   1406:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.4   root     1407:        data1 = cmmu[1].load_32(addr);
1.1.1.2   root     1408:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1409: 
1.1.1.4   root     1410:        if ((int64)data1 < 0) {
1.1.1.5   root     1411:                ReadDataException64(addr, DM_D1 | usr);
1.1       root     1412:                return;
                   1413:        }
                   1414:        addr += 4;
1.1.1.2   root     1415: 
                   1416:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.4   root     1417:        data2 = cmmu[1].load_32(addr);
1.1.1.2   root     1418:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1419: 
1.1.1.4   root     1420:        if ((int64)data2 < 0) {
1.1.1.5   root     1421:                ReadDataException64(addr, DM_D2 | usr);
1.1       root     1422:                return;
                   1423:        }
1.1.1.4   root     1424:        rD  = data1;
                   1425:        rD2 = data2;
1.1       root     1426:        r[0] = 0;
                   1427: }
                   1428: 
                   1429: // 111101_DDDDDSSSSS_000101_xU000sssss
                   1430: OP_DEF(ld_w)
                   1431: {
1.1.1.4   root     1432:        uint64 data;
1.1       root     1433:        uint32 addr;
                   1434:        uint32 usr;
                   1435: 
                   1436:        LDST_USR_SCALE_ALIGN(4);
                   1437: 
1.1.1.5   root     1438:        AddCycle(3);    // Table.7-3
1.1.1.4   root     1439: 
1.1       root     1440:        lastaddr = addr;
1.1.1.2   root     1441: 
                   1442:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.4   root     1443:        data = cmmu[1].load_32(addr);
1.1.1.2   root     1444:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1445: 
1.1.1.4   root     1446:        if ((int64)data < 0) {
1.1.1.5   root     1447:                ReadDataException32(addr, DM_W | usr);
1.1       root     1448:                return;
                   1449:        }
                   1450:        if (FLD_D == 0)
                   1451:                return;
1.1.1.4   root     1452:        rD = data;
1.1       root     1453: }
                   1454: 
                   1455: // 111101_DDDDDSSSSS_000110_xU000sssss
                   1456: OP_DEF(ld_h)
                   1457: {
1.1.1.4   root     1458:        uint64 data;
1.1       root     1459:        uint32 addr;
                   1460:        uint32 usr;
                   1461: 
                   1462:        LDST_USR_SCALE_ALIGN(2);
                   1463: 
1.1.1.5   root     1464:        AddCycle(3);    // Table.7-3
1.1.1.4   root     1465: 
1.1       root     1466:        lastaddr = addr;
1.1.1.2   root     1467: 
                   1468:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.4   root     1469:        data = cmmu[1].load_16(addr);
1.1.1.2   root     1470:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1471: 
1.1.1.4   root     1472:        if ((int64)data < 0) {
1.1.1.5   root     1473:                ReadDataException32(addr, DM_H | usr);
1.1       root     1474:                return;
                   1475:        }
                   1476:        if (FLD_D == 0)
                   1477:                return;
1.1.1.4   root     1478:        rD = (uint32)(int32)(int16)data;
1.1       root     1479: }
                   1480: 
                   1481: // 111101_DDDDDSSSSS_000111_xU000sssss
                   1482: OP_DEF(ld_b)
                   1483: {
1.1.1.4   root     1484:        uint64 data;
1.1       root     1485:        uint32 addr;
                   1486:        uint32 usr;
                   1487: 
                   1488:        LDST_USR_SCALE_ALIGN(1);
                   1489: 
1.1.1.5   root     1490:        AddCycle(3);    // Table.7-3
1.1.1.4   root     1491: 
1.1       root     1492:        lastaddr = addr;
1.1.1.2   root     1493: 
                   1494:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.4   root     1495:        data = cmmu[1].load_8(addr);
1.1.1.2   root     1496:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1497: 
1.1.1.4   root     1498:        if ((int64)data < 0) {
1.1.1.5   root     1499:                ReadDataException32(addr, DM_B | usr);
1.1       root     1500:                return;
                   1501:        }
                   1502:        if (FLD_D == 0)
                   1503:                return;
1.1.1.4   root     1504:        rD = (uint32)(int32)(int8)data;
1.1       root     1505: }
                   1506: 
                   1507: // 111101_DDDDDSSSSS_001000_xU000sssss
                   1508: OP_DEF(st_d)
                   1509: {
1.1.1.4   root     1510:        uint64 rv;
1.1       root     1511:        uint32 addr;
                   1512:        uint32 usr;
                   1513: 
                   1514:        LDST_USR_SCALE_ALIGN(8);
                   1515: 
1.1.1.5   root     1516:        AddCycle(1 + 4);        // Table.7-3
1.1.1.4   root     1517: 
1.1       root     1518:        lastaddr = addr;
1.1.1.2   root     1519: 
                   1520:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.4   root     1521:        rv = cmmu[1].store_32(addr, rD);
1.1.1.2   root     1522:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1523: 
1.1.1.4   root     1524:        if ((int64)rv < 0) {
1.1.1.5   root     1525:                WriteDataException64(addr, DM_D1 | usr);
1.1       root     1526:                return;
                   1527:        }
1.1.1.2   root     1528: 
1.1       root     1529:        addr += 4;
1.1.1.2   root     1530: 
                   1531:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.4   root     1532:        rv = cmmu[1].store_32(addr, rD2);
1.1.1.2   root     1533:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1534: 
1.1.1.4   root     1535:        if ((int64)rv < 0) {
1.1.1.5   root     1536:                WriteDataException64(addr, DM_D2 | usr);
1.1       root     1537:                return;
                   1538:        }
                   1539: }
                   1540: 
                   1541: // 111101_DDDDDSSSSS_001001_xU000sssss
                   1542: OP_DEF(st_w)
                   1543: {
1.1.1.4   root     1544:        uint64 rv;
1.1       root     1545:        uint32 addr;
                   1546:        uint32 usr;
                   1547: 
                   1548:        LDST_USR_SCALE_ALIGN(4);
                   1549: 
1.1.1.5   root     1550:        AddCycle(3);    // Table.7-3
1.1.1.4   root     1551: 
1.1       root     1552:        lastaddr = addr;
1.1.1.2   root     1553: 
                   1554:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.4   root     1555:        rv = cmmu[1].store_32(addr, rD);
1.1.1.2   root     1556:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1557: 
1.1.1.4   root     1558:        if ((int64)rv < 0) {
1.1.1.5   root     1559:                WriteDataException32(addr, DM_W | usr);
1.1       root     1560:                return;
                   1561:        }
                   1562: }
                   1563: 
                   1564: // 111101_DDDDDSSSSS_001010_xU000sssss
                   1565: OP_DEF(st_h)
                   1566: {
1.1.1.4   root     1567:        uint64 rv;
1.1       root     1568:        uint32 addr;
                   1569:        uint32 usr;
                   1570: 
                   1571:        LDST_USR_SCALE_ALIGN(2);
                   1572: 
1.1.1.5   root     1573:        AddCycle(3);    // Table.7-3
1.1.1.4   root     1574: 
1.1       root     1575:        lastaddr = addr;
1.1.1.2   root     1576: 
                   1577:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.5   root     1578:        rv = cmmu[1].store_16(addr, rD & 0xffff);
1.1.1.2   root     1579:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1580: 
1.1.1.4   root     1581:        if ((int64)rv < 0) {
1.1.1.5   root     1582:                WriteDataException32(addr, DM_H | usr);
1.1       root     1583:                return;
                   1584:        }
                   1585: }
                   1586: 
                   1587: // 111101_DDDDDSSSSS_001011_xU000sssss
                   1588: OP_DEF(st_b)
                   1589: {
1.1.1.4   root     1590:        uint64 rv;
1.1       root     1591:        uint32 addr;
                   1592:        uint32 usr;
                   1593: 
                   1594:        LDST_USR_SCALE_ALIGN(1);
                   1595: 
1.1.1.5   root     1596:        AddCycle(3);    // Table.7-3
1.1.1.4   root     1597: 
1.1       root     1598:        lastaddr = addr;
1.1.1.2   root     1599: 
                   1600:        if (__predict_false(usr)) cmmu[1].SetSuper(false);
1.1.1.5   root     1601:        rv = cmmu[1].store_8(addr, rD & 0xff);
1.1.1.2   root     1602:        if (__predict_false(usr)) cmmu[1].SetSuper(true);
                   1603: 
1.1.1.4   root     1604:        if ((int64)rv < 0) {
1.1.1.5   root     1605:                WriteDataException32(addr, DM_B | usr);
1.1       root     1606:                return;
                   1607:        }
                   1608: }
                   1609: 
                   1610: // 111101_DDDDDSSSSS_001100_xU000sssss
                   1611: OP_DEF(lda_d)
                   1612: {
                   1613:        uint32 addr;
                   1614:        uint32 usr;
                   1615: 
                   1616:        LDST_USR_SCALE(8);
                   1617: 
                   1618:        if (FLD_D == 0)
                   1619:                return;
                   1620:        rD = addr;
                   1621: }
                   1622: 
                   1623: // 111101_DDDDDSSSSS_001101_xU000sssss
                   1624: OP_DEF(lda_w)
                   1625: {
                   1626:        uint32 addr;
                   1627:        uint32 usr;
                   1628: 
                   1629:        LDST_USR_SCALE(4);
                   1630: 
                   1631:        if (FLD_D == 0)
                   1632:                return;
                   1633:        rD = addr;
                   1634: }
                   1635: 
                   1636: // 111101_DDDDDSSSSS_001110_xU000sssss
                   1637: OP_DEF(lda_h)
                   1638: {
                   1639:        uint32 addr;
                   1640:        uint32 usr;
                   1641: 
                   1642:        LDST_USR_SCALE(2);
                   1643: 
                   1644:        if (FLD_D == 0)
                   1645:                return;
                   1646:        rD = addr;
                   1647: }
                   1648: 
                   1649: // 111101_DDDDDSSSSS_001111_xU000sssss
                   1650: OP_DEF(lda_b)
                   1651: {
                   1652:        uint32 addr;
                   1653:        uint32 usr;
                   1654: 
                   1655:        LDST_USR_SCALE(1);
                   1656: 
                   1657:        if (FLD_D == 0)
                   1658:                return;
                   1659:        rD = addr;
                   1660: }
                   1661: 
                   1662: // 111101_DDDDDSSSSS_010000_00000sssss
                   1663: OP_DEF(and)
                   1664: {
                   1665:        if (FLD_D == 0)
                   1666:                return;
                   1667:        rD = rS1 & rS2;
                   1668: }
                   1669: 
                   1670: // 111101_DDDDDSSSSS_010001_00000sssss
                   1671: OP_DEF(and_c)
                   1672: {
                   1673:        if (FLD_D == 0)
                   1674:                return;
                   1675:        rD = rS1 & ~rS2;
                   1676: }
                   1677: 
                   1678: // 111101_DDDDDSSSSS_010100_00000sssss
                   1679: OP_DEF(xor)
                   1680: {
                   1681:        if (FLD_D == 0)
                   1682:                return;
                   1683:        rD = rS1 ^ rS2;
                   1684: }
                   1685: 
                   1686: // 111101_DDDDDSSSSS_010101_00000sssss
                   1687: OP_DEF(xor_c)
                   1688: {
                   1689:        if (FLD_D == 0)
                   1690:                return;
                   1691:        rD = rS1 ^ ~rS2;
                   1692: }
                   1693: 
                   1694: // 111101_DDDDDSSSSS_010110_00000sssss
                   1695: OP_DEF(or)
                   1696: {
1.1.1.2   root     1697:        if (FLD_D == 0) {
                   1698:                nop_counter++;
1.1       root     1699:                return;
1.1.1.2   root     1700:        }
1.1       root     1701:        rD = rS1 | rS2;
                   1702: }
                   1703: 
                   1704: // 111101_DDDDDSSSSS_010111_00000sssss
                   1705: OP_DEF(or_c)
                   1706: {
                   1707:        if (FLD_D == 0)
                   1708:                return;
                   1709:        rD = rS1 | ~rS2;
                   1710: }
                   1711: 
                   1712: // 111101_DDDDDSSSSS_011000_nn000sssss
                   1713: OP_DEF(addu)
                   1714: {
1.1.1.2   root     1715:        uint64 res = (uint64)rS1 + rS2;
1.1       root     1716:        if (IsCI) {
                   1717:                res += GetCY();
                   1718:        }
                   1719:        if (IsCO) {
1.1.1.4   root     1720:                SetCY(res >> 32);
1.1       root     1721:        }
                   1722:        if (FLD_D == 0)
                   1723:                return;
                   1724:        rD = res;
                   1725: }
                   1726: 
                   1727: // 111101_DDDDDSSSSS_011001_nn000sssss
                   1728: OP_DEF(subu)
                   1729: {
1.1.1.2   root     1730:        // sub 命令では CY ビットは Z80 とかと逆で、0 ならボロー発生。
                   1731:        // 88100 のマニュアルには書いてない。88110 のマニュアルにある。
                   1732: 
                   1733:        // 1 の補数をとって足す。
                   1734:        uint64 res = (uint64)rS1 + (~rS2);
1.1       root     1735:        if (IsCI) {
1.1.1.2   root     1736:                res += GetCY();
                   1737:        } else {
                   1738:                res += 1;
1.1       root     1739:        }
                   1740:        if (IsCO) {
1.1.1.4   root     1741:                SetCY(res >> 32);
1.1       root     1742:        }
                   1743:        if (FLD_D == 0)
                   1744:                return;
                   1745:        rD = res;
                   1746: }
                   1747: 
                   1748: // 111101_DDDDDSSSSS_011010_zz000sssss
                   1749: OP_DEF(divu)
                   1750: {
                   1751:        if (!IsFPUEnable()) {
                   1752:                fpu_unimpl();
                   1753:                return;
                   1754:        }
1.1.1.4   root     1755: 
1.1.1.5   root     1756:        AddCycle(38);   // Table.7-6 (ただしざっくり)
1.1.1.4   root     1757: 
1.1       root     1758:        if (rS2 == 0) {
                   1759:                Exception(M88K_EXCEP_INT_DIV);
                   1760:                return;
                   1761:        }
                   1762:        if (FLD_D == 0)
                   1763:                return;
                   1764:        rD = rS1 / rS2;
                   1765: }
                   1766: 
                   1767: // 111101_DDDDDSSSSS_011011_zz000sssss
                   1768: OP_DEF(mul)
                   1769: {
                   1770:        if (!IsFPUEnable()) {
                   1771:                fpu_unimpl();
                   1772:                return;
                   1773:        }
1.1.1.4   root     1774: 
1.1.1.5   root     1775:        AddCycle(4);    // Table.7-6 (ただしざっくり)
1.1.1.4   root     1776: 
1.1       root     1777:        if (FLD_D == 0)
                   1778:                return;
                   1779:        rD = rS1 * rS2;
                   1780: }
                   1781: 
                   1782: // 111101_DDDDDSSSSS_011100_nn000sssss
                   1783: OP_DEF(add)
                   1784: {
1.1.1.2   root     1785:        uint64 res = (uint64)rS1 + rS2;
1.1       root     1786:        if (IsCI) {
                   1787:                res += GetCY();
                   1788:        }
                   1789:        // XXX: オーバーフローが起きたときにキャリーが更新されるかどうか
                   1790:        //      ドキュメントされてない気がする
                   1791:        if (IsCO) {
1.1.1.4   root     1792:                SetCY(res >> 32);
1.1       root     1793:        }
                   1794:        if (isovf_add(rS1, rS2, res)) {
                   1795:                Exception(M88K_EXCEP_INT_OVF);
                   1796:                return;
                   1797:        }
                   1798:        if (FLD_D == 0)
                   1799:                return;
                   1800:        rD = res;
                   1801: }
                   1802: 
                   1803: // 111101_DDDDDSSSSS_011101_nn000sssss
                   1804: OP_DEF(sub)
                   1805: {
1.1.1.2   root     1806:        // sub 命令では CY ビットは Z80 とかと逆で、0 ならボロー発生。
                   1807:        // 88100 のマニュアルには書いてない。88110 のマニュアルにある。
                   1808: 
                   1809:        // 1 の補数をとって足す。
                   1810:        uint64 res = (uint64)rS1 + (~rS2);
1.1       root     1811:        if (IsCI) {
1.1.1.2   root     1812:                res += GetCY();
                   1813:        } else {
                   1814:                res += 1;
1.1       root     1815:        }
                   1816:        // XXX: オーバーフローが起きたときにキャリーが更新されるかどうか
                   1817:        //      ドキュメントされてない気がする
                   1818:        if (IsCO) {
1.1.1.4   root     1819:                SetCY(res >> 32);
1.1       root     1820:        }
                   1821:        if (isovf_sub(rS1, rS2, res)) {
                   1822:                Exception(M88K_EXCEP_INT_OVF);
                   1823:                return;
                   1824:        }
                   1825:        if (FLD_D == 0)
                   1826:                return;
                   1827:        rD = res;
                   1828: }
                   1829: 
                   1830: // 111101_DDDDDSSSSS_011110_zz000sssss
                   1831: OP_DEF(div)
                   1832: {
                   1833:        if (!IsFPUEnable()) {
                   1834:                fpu_unimpl();
                   1835:                return;
                   1836:        }
1.1.1.4   root     1837: 
1.1.1.5   root     1838:        AddCycle(38);   // Table.7-6 (ただしざっくり)
1.1.1.4   root     1839: 
1.1.1.2   root     1840:        if ((int32)rS1 < 0 || (int32)rS2 <= 0) {
1.1       root     1841:                Exception(M88K_EXCEP_INT_DIV);
                   1842:                return;
                   1843:        }
                   1844:        if (FLD_D == 0)
                   1845:                return;
                   1846:        rD = rS1 / rS2;
                   1847: }
                   1848: 
                   1849: // 111101_DDDDDSSSSS_011111_zz000sssss
                   1850: OP_DEF(cmp)
                   1851: {
                   1852:        if (FLD_D == 0)
                   1853:                return;
                   1854:        rD = acc_cmp(rS1, rS2);
                   1855: }
                   1856: 
                   1857: // 111101_DDDDDSSSSS_100000_00000sssss
                   1858: OP_DEF(clr_2)
                   1859: {
                   1860:        if (FLD_D == 0)
                   1861:                return;
                   1862:        rD = rS1 & ~acc_bf((rS2 >> 5) & 0x1f, rS2 & 0x1f);
                   1863: }
                   1864: 
                   1865: // 111101_DDDDDSSSSS_100010_00000sssss
                   1866: OP_DEF(set_2)
                   1867: {
                   1868:        if (FLD_D == 0)
                   1869:                return;
                   1870:        rD = rS1 | acc_bf((rS2 >> 5) & 0x1f, rS2 & 0x1f);
                   1871: }
                   1872: 
                   1873: // 111101_DDDDDSSSSS_100100_00000sssss
                   1874: OP_DEF(ext_2)
                   1875: {
                   1876:        int w, o, left;
                   1877:        uint32 tmp;
                   1878: 
                   1879:        if (FLD_D == 0)
                   1880:                return;
                   1881:        w = (rS2 >> 5) & 0x1f;
                   1882:        if (w == 0)
                   1883:                w = 32;
                   1884:        o = (rS2     ) & 0x1f;
                   1885:        left = 32 - w - o;
                   1886:        tmp = ASL(rS1, left);
                   1887:        tmp = ASR(tmp, left);
                   1888:        rD = ASR(tmp, o);
                   1889: }
                   1890: 
                   1891: // 111101_DDDDDSSSSS_100110_00000sssss
                   1892: OP_DEF(extu_2)
                   1893: {
                   1894:        int w, o, left;
                   1895:        uint32 tmp;
                   1896: 
                   1897:        if (FLD_D == 0)
                   1898:                return;
                   1899:        w = (rS2 >> 5) & 0x1f;
                   1900:        if (w == 0)
                   1901:                w = 32;
                   1902:        o = (rS2     ) & 0x1f;
                   1903:        left = 32 - w - o;
                   1904:        tmp = ASL(rS1, left);
                   1905:        tmp = LSR(tmp, left);
                   1906:        rD = tmp >> o;
                   1907: }
                   1908: 
                   1909: // 111101_DDDDDSSSSS_101000_00000sssss
                   1910: OP_DEF(mak_2)
                   1911: {
                   1912:        if (FLD_D == 0)
                   1913:                return;
                   1914:        int w = (rS2 >> 5) & 0x1f;
                   1915:        int o = (rS2     ) & 0x1f;
                   1916:        rD = (rS1 << o) & acc_bf(w, o);
                   1917: }
                   1918: 
                   1919: // 111101_DDDDDSSSSS_101010_00000sssss
                   1920: OP_DEF(rot_2)
                   1921: {
                   1922:        if (FLD_D == 0)
                   1923:                return;
                   1924:        int o = (rS2    ) & 0x1f;
                   1925:        rD = ROR(rS1, o);
                   1926: }
                   1927: 
                   1928: // 111101_zzzzzzzzzz_110000_00000sssss
                   1929: OP_DEF(jmp)
                   1930: {
1.1.1.5   root     1931:        AddCycle(1);    // Table.7-5
1.1.1.4   root     1932:        EnterBranch(rS2);
1.1       root     1933:        ExitBranch();
                   1934: }
                   1935: 
                   1936: // 111101_zzzzzzzzzz_110001_00000sssss
                   1937: OP_DEF(jmp_n)
                   1938: {
1.1.1.5   root     1939:        AddCycle(0);    // Table.7-5
1.1.1.4   root     1940:        EnterBranch(rS2);
1.1       root     1941:        ExitDelayBranch();
                   1942: }
                   1943: 
                   1944: // 111101_zzzzzzzzzz_110010_00000sssss
                   1945: OP_DEF(jsr)
                   1946: {
1.1.1.5   root     1947:        AddCycle(1);    // Table.7-5
1.1.1.4   root     1948:        EnterBranch(rS2);
1.1       root     1949:        r[1] = nip;
                   1950:        ExitBranch();
                   1951: }
                   1952: 
                   1953: // 111101_zzzzzzzzzz_110011_00000sssss
                   1954: OP_DEF(jsr_n)
                   1955: {
1.1.1.5   root     1956:        AddCycle(0);    // Table.7-5
1.1.1.4   root     1957:        EnterBranch(rS2);
1.1       root     1958:        r[1] = nip + 4;
                   1959:        ExitDelayBranch();
                   1960: }
                   1961: 
1.1.1.2   root     1962: // 111101_DDDDDzzzzz_111010_00000sssss
                   1963: OP_DEF(ff1)
                   1964: {
                   1965:        int i;
                   1966:        uint32 m = 0x80000000U;
                   1967: 
                   1968:        if (FLD_D == 0)
                   1969:                return;
                   1970: 
                   1971:        if (rS2 == 0) {
                   1972:                rD = 32;
                   1973:        } else {
                   1974:                for (i = 31; i >= 0; i--, m >>= 1) {
                   1975:                        if ((rS2 & m) != 0) {
                   1976:                                break;
                   1977:                        }
                   1978:                }
                   1979:                rD = i;
                   1980:        }
                   1981: 
                   1982: }
                   1983: 
                   1984: // 111101_DDDDDzzzzz_111011_00000sssss
                   1985: OP_DEF(ff0)
                   1986: {
                   1987:        int i;
                   1988:        uint32 m = 0x80000000U;
                   1989: 
                   1990:        if (FLD_D == 0)
                   1991:                return;
                   1992: 
                   1993:        if (rS2 == 0xffffffffU) {
                   1994:                rD = 32;
                   1995:        } else {
                   1996:                for (i = 31; i >= 0; i--, m >>= 1) {
                   1997:                        if ((rS2 & m) == 0) {
                   1998:                                break;
                   1999:                        }
                   2000:                }
                   2001:                rD = i;
                   2002:        }
                   2003: }
                   2004: 
1.1       root     2005: // 111101_zzzzzzzzzz_111111_0000000000
                   2006: OP_DEF(rte)
                   2007: {
1.1.1.5   root     2008:        AddCycle(2);    // Table.7-5
1.1.1.4   root     2009: 
1.1.1.2   root     2010:        SetPSR(epsr);
1.1       root     2011: 
1.1.1.2   root     2012:        // LUNA88K の ROM1.2 は sxip, snip, sfip を制御してくる。
                   2013:        // ROM1.2 の DAE ハンドラは、
                   2014:        // sxip = INVALID
                   2015:        // snip = 0 (INVALID)
                   2016:        // sfip = original sxip
                   2017:        // で rte してくる。
                   2018:        // CPU は sxip は評価しない。snip は 0 なので、無効として nop 扱い。
                   2019:        // (実際はクロックが消費されるかも?)
                   2020:        // sfip が VALID なので、そこから実行を再開する。
                   2021:        if (snip & SIP_V) {
1.1.1.4   root     2022:                EnterBranch(snip & SIP_MASK);
                   2023:                ExitBranch();
1.1.1.2   root     2024:                fip = sfip & SIP_MASK;
                   2025:        } else {
1.1.1.4   root     2026:                EnterBranch(sfip & SIP_MASK);
                   2027:                ExitBranch();
1.1.1.2   root     2028:        }
1.1       root     2029: 
                   2030:        // ディレイスロットにいた命令かどうかをやんわり復元する。
                   2031:        // 88110 ではこの情報が E?IP に保持されているが
                   2032:        // 88100 にはない。
                   2033:        if (nip + 4 != fip) {
1.1.1.4   root     2034:                ExitDelayBranch();
1.1       root     2035:        }
                   2036: }
                   2037: 
                   2038: // 111101_zzzzzSSSSS_111110_00000SSSSS
                   2039: OP_DEF(tbnd_1)
                   2040: {
                   2041:        if (rS1 > rS2) {
                   2042:                Exception(M88K_EXCEP_BOUNDS);
                   2043:        }
                   2044: }
                   2045: 
                   2046: // 111110_zzzzzSSSSS_nnnnnn_nnnnnnnnnn
                   2047: OP_DEF(tbnd_2)
                   2048: {
                   2049:        if (rS1 > IMM16) {
                   2050:                Exception(M88K_EXCEP_BOUNDS);
                   2051:        }
                   2052: }
                   2053: 
                   2054: // 111111_zzzzzzzzzz_000011_zzzzzzzzzz
                   2055: OP_DEF(getc)
                   2056: {
                   2057:        printf("getc inst\n");
                   2058:        int c = getchar();
                   2059:        r[2] = c;
                   2060: }
                   2061: 
                   2062: // 111111_zzzzzzzzzz_000100_zzzzzzzzzz
                   2063: OP_DEF(putc)
                   2064: {
                   2065:        // r3 を表示
                   2066:        putchar(r[3]);
                   2067: }

unix.superglobalmegacorp.com

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