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

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

unix.superglobalmegacorp.com

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