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

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

unix.superglobalmegacorp.com

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