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

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

unix.superglobalmegacorp.com

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