Annotation of nono/m680x0/m68030acc.h, revision 1.1.1.2

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: 
                      7: #pragma once
                      8: 
                      9: extern void acc_chk2cmp2_32(m68kcpu *cpu, uint32, uint32, uint32);
                     10: extern bool acc_divu_32_16(m68kcpu *cpu, uint32, uint32, uint32 *, uint32 *);
                     11: extern bool acc_divu_32_32(m68kcpu *cpu, uint32, uint32, uint32 *, uint32 *);
                     12: extern bool acc_divu_64_32(m68kcpu *cpu, uint32, uint64, uint32 *, uint32 *);
                     13: extern bool acc_divs_32_16(m68kcpu *cpu, uint32, uint32, uint32 *, uint32 *);
                     14: extern bool acc_divs_32_32(m68kcpu *cpu, uint32, uint32, uint32 *, uint32 *);
                     15: extern bool acc_divs_64_32(m68kcpu *cpu, uint32, uint64, uint32 *, uint32 *);
                     16: extern uint32 acc_abcd_8(m68kcpu *cpu, uint32 src ,uint32 dst);
                     17: extern uint32 acc_sbcd_8(m68kcpu *cpu, uint32 src, uint32 dst);
                     18: 
                     19: // ビットフィールド命令
                     20: class acc_bf
                     21: {
                     22:  public:
                     23:        acc_bf(m68kcpu *);
                     24:        // デストラクタは無し。
                     25: 
                     26:        void LoadReg(uint n);           // Dn から値を読み込む
                     27:        void LoadMem(uint32 addr);      // メモリから値を読み込む
                     28: 
                     29:        // レジスタまたはメモリにストアする
                     30:        void Store(uint n) {
                     31:                if (n < 8) {
                     32:                        StoreReg(n);
                     33:                } else {
                     34:                        StoreMem();
                     35:                }
1.1.1.2 ! root       36:        }
1.1       root       37: 
                     38:        uint32 data = 0;                        // 32bit 左詰めデータ
                     39:        int32 offset = 0;                       // (第2ワードで指定された) オフセット
                     40:        uint32 width = 0;                       // 幅
                     41: 
                     42:  private:
                     43:        void StoreReg(uint n);          // 値を Dn に書き出す
                     44:        void StoreMem();                        // 値をメモリに書き出す
                     45: 
                     46:        // 32ビットの val を count ビット左ローテートした値を返す。
                     47:        // count は 0..31。
                     48:        // 実際には count==0 の時 (val>>32) となりこれは未定義動作なのだが
                     49:        // ぶっちゃけこの形式はローテート命令一発に変換されると知っているので
                     50:        // とりあえず放置しておく。C++20 になったら std::rotl() を検討。
                     51:        NO_SANITIZE("undefined")
                     52:        uint32 ROL32(uint32 val, uint count) {
                     53:                return (val << count) | (val >> (32 - count));
                     54:        }
                     55: 
                     56:        // 32ビットの val を count ビット右ローテートした値を返す。
                     57:        // count は 0..31。
                     58:        // 実際には count==0 の時 (val>>32) となりこれは未定義動作なのだが
                     59:        // ぶっちゃけこの形式はローテート命令一発に変換されると知っているので
                     60:        // とりあえず放置しておく。C++20 になったら std::rotr() を検討。
                     61:        NO_SANITIZE("undefined")
                     62:        uint32 ROR32(uint32 val, uint count) {
                     63:                return (val >> count) | (val << (32 - count));
                     64:        }
                     65: 
                     66:        m68kcpu *cpu = NULL;
                     67: 
                     68:        uint32 mask = 0;                // 32ビット左詰めマスク
                     69:        uint32 ea = 0;                  // オフセット計算後の EA
                     70:        int32 local_offset = 0; // 内部(32bit or 8bit 内)オフセット
                     71:        int bytes = 0;                  // アクセスバイト数
                     72:        uint64 buf = 0;                 // 40ビットのメモリバッファ
                     73: };
                     74: 
                     75: // res を元に NZVC フラグをセットする。
                     76: // res の上位ビットは無視される。
                     77: static inline void
                     78: acc_move_8(m68kcpu *cpu, uint32 res)
                     79: {
                     80:        CCR.z = res << 24;
                     81:        CCR.n = CCR.z;
                     82:        CCR.c = 0;
                     83:        CCR.v = 0;
                     84: }
                     85: 
                     86: // res を元に NZVC フラグをセットする。
                     87: // res の上位ビットは無視される。
                     88: static inline void
                     89: acc_move_16(m68kcpu *cpu, uint32 res)
                     90: {
                     91:        CCR.z = res << 16;
                     92:        CCR.n = CCR.z;
                     93:        CCR.c = 0;
                     94:        CCR.v = 0;
                     95: }
                     96: 
                     97: // res を元に NZVC フラグをセットする。
                     98: static inline void
                     99: acc_move_32(m68kcpu *cpu, uint32 res)
                    100: {
                    101:        CCR.z = res;
                    102:        CCR.n = res;
                    103:        CCR.c = 0;
                    104:        CCR.v = 0;
                    105: }
                    106: 
                    107: 
                    108: #define vflag_add_8(src, dst, res)     (vflag_add_32(src, dst, res) << 24)
                    109: #define vflag_add_16(src, dst, res)    (vflag_add_32(src, dst, res) << 16)
                    110: #define vflag_add_32(src, dst, res) (((src) ^ (res)) & ((dst) ^ (res)))
                    111: 
                    112: // src + dst を計算し、XNZVC フラグをセットして結果を返す。
                    113: // src, dst の上位ビットはクリアしておくこと。
                    114: // 戻り値の上位ビットはクリアされている。
                    115: static inline uint32
                    116: acc_add_8(m68kcpu *cpu, uint32 src, uint32 dst)
                    117: {
                    118:        CCR.z = dst + src;
                    119:        CCR.c = CCR.z >> 8;
                    120:        CCR.x = CCR.c;
                    121:        CCR.n = CCR.z << 24;
                    122:        CCR.z &= 0xff;
                    123:        CCR.v = vflag_add_8(src, dst, CCR.z);
                    124:        return CCR.z;
                    125: }
                    126: 
                    127: // src + dst を計算し、XNZVC フラグをセットして結果を返す。
                    128: // src, dst の上位ビットはクリアしておくこと。
                    129: // 戻り値の上位ビットはクリアされている。
                    130: static inline uint32
                    131: acc_add_16(m68kcpu *cpu, uint32 src, uint32 dst)
                    132: {
                    133:        CCR.z = dst + src;
                    134:        CCR.c = CCR.z >> 16;
                    135:        CCR.x = CCR.c;
                    136:        CCR.n = CCR.z << 16;
                    137:        CCR.z &= 0xffff;
                    138:        CCR.v = vflag_add_16(src, dst, CCR.z);
                    139:        return CCR.z;
                    140: }
                    141: 
                    142: // src + dst を計算し、XNZVC フラグをセットして結果を返す。
                    143: static inline uint32
                    144: acc_add_32(m68kcpu *cpu, uint32 src, uint32 dst)
                    145: {
                    146:        CCR.cz = (uint64)dst + (uint64)src;
                    147:        CCR.x = CCR.c;
                    148:        CCR.v = vflag_add_32(src, dst, CCR.z);
                    149:        CCR.n = CCR.z;
                    150:        return CCR.z;
                    151: }
                    152: 
                    153: // src + dst + X を計算し、XNZVC フラグをセットして結果を返す。
                    154: // src, dst の上位ビットはクリアしておくこと。
                    155: // 戻り値の上位ビットはクリアされている。
                    156: static inline uint32
                    157: acc_addx_8(m68kcpu *cpu, uint32 src, uint32 dst)
                    158: {
                    159:        uint32 res = dst + src + (CCR.IsX() ? 1 : 0);
                    160:        CCR.c = res >> 8;
                    161:        CCR.x = CCR.c;
                    162:        CCR.n = res << 24;
                    163:        // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない
                    164:        if (CCR.n != 0) {
                    165:                CCR.z = CCR.n;
                    166:        }
                    167:        CCR.v = vflag_add_8(src, dst, res);
                    168:        return res & 0xff;
                    169: }
                    170: 
                    171: // src + dst + X を計算し、XNZVC フラグをセットして結果を返す。
                    172: // src, dst の上位ビットはクリアしておくこと。
                    173: // 戻り値の上位ビットはクリアされている。
                    174: static inline uint32
                    175: acc_addx_16(m68kcpu *cpu, uint32 src, uint32 dst)
                    176: {
                    177:        uint32 res = dst + src + (CCR.IsX() ? 1 : 0);
                    178:        CCR.c = res >> 16;
                    179:        CCR.x = CCR.c;
                    180:        CCR.n = res << 16;
                    181:        // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない
                    182:        if (CCR.n != 0) {
                    183:                CCR.z = CCR.n;
                    184:        }
                    185:        CCR.v = vflag_add_16(src, dst, res);
                    186:        return res & 0xffff;
                    187: }
                    188: 
                    189: // src + dst + X を計算し、XNZVC フラグをセットして結果を返す。
                    190: static inline uint32
                    191: acc_addx_32(m68kcpu *cpu, uint32 src, uint32 dst)
                    192: {
                    193:        uint64 res = (uint64)dst + (uint64)src + (CCR.IsX() ? 1 : 0);
                    194:        CCR.c = res >> 32;
                    195:        CCR.x = CCR.c;
                    196:        CCR.n = res;
                    197:        // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない
                    198:        if (CCR.n != 0) {
                    199:                CCR.z = CCR.n;
                    200:        }
                    201:        CCR.v = vflag_add_32(src, dst, res);
                    202:        return res;
                    203: }
                    204: 
                    205: 
                    206: #define vflag_sub_8(src, dst, res)     (vflag_sub_32(src, dst, res) << 24)
                    207: #define vflag_sub_16(src, dst, res)    (vflag_sub_32(src, dst, res) << 16)
                    208: #define vflag_sub_32(src, dst, res)    (((src) ^ (dst)) & ((dst) ^ (res)))
                    209: 
                    210: // dst - src を計算し、NZVC フラグをセットして結果を返す。
                    211: // src, dst の上位ビットはクリアしておくこと。
                    212: // 戻り値の上位ビットはクリアされている。
                    213: static inline uint32
                    214: acc_cmp_8(m68kcpu *cpu, uint32 src, uint32 dst)
                    215: {
                    216:        CCR.z = dst - src;
                    217:        CCR.c = CCR.z >> 8;
                    218:        CCR.n = CCR.z << 24;
                    219:        CCR.z &= 0xff;
                    220:        CCR.v = vflag_sub_8(src, dst, CCR.z);
                    221:        return CCR.z;
                    222: }
                    223: 
                    224: // dst - src を計算し、NZVC フラグをセットして結果を返す。
                    225: // src, dst の上位ビットはクリアしておくこと。
                    226: // 戻り値の上位ビットはクリアされている。
                    227: static inline uint32
                    228: acc_cmp_16(m68kcpu *cpu, uint32 src, uint32 dst)
                    229: {
                    230:        CCR.z = dst - src;
                    231:        CCR.c = CCR.z >> 16;
                    232:        CCR.n = CCR.z << 16;
                    233:        CCR.z &= 0xffff;
                    234:        CCR.v = vflag_sub_16(src, dst, CCR.z);
                    235:        return CCR.z;
                    236: }
                    237: 
                    238: // dst - src を計算し、NZVC フラグをセットして結果を返す。
                    239: static inline uint32
                    240: acc_cmp_32(m68kcpu *cpu, uint32 src, uint32 dst)
                    241: {
                    242:        CCR.cz = (uint64)dst - (uint64)src;
                    243:        CCR.n = CCR.z;
                    244:        CCR.v = vflag_sub_32(src, dst, CCR.z);
                    245:        return CCR.z;
                    246: }
                    247: 
                    248: // dst - src を計算し、XNZVC フラグをセットして結果を返す。
                    249: // src, dst の上位ビットはクリアしておくこと。
                    250: // 戻り値の上位ビットはクリアされている。
                    251: static inline uint32
                    252: acc_sub_8(m68kcpu *cpu, uint32 src, uint32 dst)
                    253: {
                    254:        uint32 res = acc_cmp_8(cpu, src, dst);
                    255:        CCR.x = CCR.c;
                    256:        return res;
                    257: }
                    258: 
                    259: // dst - src を計算し、XNZVC フラグをセットして結果を返す。
                    260: // src, dst の上位ビットはクリアしておくこと。
                    261: // 戻り値の上位ビットはクリアされている。
                    262: static inline uint32
                    263: acc_sub_16(m68kcpu *cpu, uint32 src, uint32 dst)
                    264: {
                    265:        uint32 res = acc_cmp_16(cpu, src, dst);
                    266:        CCR.x = CCR.c;
                    267:        return res;
                    268: }
                    269: 
                    270: // dst - src を計算し、XNZVC フラグをセットして結果を返す。
                    271: static inline uint32
                    272: acc_sub_32(m68kcpu *cpu, uint32 src, uint32 dst)
                    273: {
                    274:        uint32 res = acc_cmp_32(cpu, src, dst);
                    275:        CCR.x = CCR.c;
                    276:        return res;
                    277: }
                    278: 
                    279: // src - dst - X を計算し、XNZVC フラグをセットして結果を返す。
                    280: // src, dst の上位ビットはクリアしておくこと。
                    281: // 戻り値 res の上位ビットはクリアされている。
                    282: static inline uint32
                    283: acc_subx_8(m68kcpu *cpu, uint32 src, uint32 dst)
                    284: {
                    285:        uint32 res = dst - src - (CCR.IsX() ? 1 : 0);
                    286:        CCR.c = res >> 8;
                    287:        CCR.x = CCR.c;
                    288:        CCR.n = res << 24;
                    289:        // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない
                    290:        if (CCR.n != 0) {
                    291:                CCR.z = CCR.n;
                    292:        }
                    293:        CCR.v = vflag_sub_8(src, dst, res);
                    294:        return res & 0xff;
                    295: }
                    296: 
                    297: // src - dst - X を計算し、XNZVC フラグをセットして結果を返す。
                    298: // src, dst の上位ビットはクリアしておくこと。
                    299: // 戻り値 res の上位ビットはクリアされている。
                    300: static inline uint32
                    301: acc_subx_16(m68kcpu *cpu, uint32 src, uint32 dst)
                    302: {
                    303:        uint32 res = dst - src - (CCR.IsX() ? 1 : 0);
                    304:        CCR.c = res >> 16;
                    305:        CCR.x = CCR.c;
                    306:        CCR.n = res << 16;
                    307:        // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない
                    308:        if (CCR.n != 0) {
                    309:                CCR.z = CCR.n;
                    310:        }
                    311:        CCR.v = vflag_sub_16(src, dst, res);
                    312:        return res & 0xffff;
                    313: }
                    314: 
                    315: // src - dst - X を計算し、XNZVC フラグをセットして結果を返す。
                    316: static inline uint32
                    317: acc_subx_32(m68kcpu *cpu, uint32 src, uint32 dst)
                    318: {
                    319:        uint64 res = (uint64)dst - (uint64)src - (CCR.IsX() ? 1 : 0);
                    320:        CCR.c = res >> 32;
                    321:        CCR.x = CCR.c;
                    322:        CCR.n = res;
                    323:        // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない
                    324:        if (CCR.n != 0) {
                    325:                CCR.z = CCR.n;
                    326:        }
                    327:        CCR.v = vflag_sub_32(src, dst, res);
                    328:        return res;
                    329: }
                    330: 
                    331: // src(u16) * dst(u16) を計算し、NZVC フラグをセットして結果(u32)を返す。
                    332: // src, dst の上位ビットはクリアしておくこと。
                    333: static inline uint32
                    334: acc_mulu_16(m68kcpu *cpu, uint32 src, uint32 dst)
                    335: {
                    336:        uint32 res = src * dst;
                    337:        // 16x16->32 ではオーバーフローは起きないので acc_move でよい
                    338:        acc_move_32(cpu, res);
                    339:        return res;
                    340: }
                    341: 
                    342: // src(s16) * dst(s16) を計算し、NZVC フラグをセットして結果(u32)を返す。
                    343: // src, dst の上位ビットはクリアしておくこと。
                    344: static inline uint32
                    345: acc_muls_16(m68kcpu *cpu, uint32 src, uint32 dst)
                    346: {
                    347:        int32 res = (int32)(int16)src * (int32)(int16)dst;
                    348:        // 16x16->32 ではオーバーフローは起きないので acc_move でよい
                    349:        acc_move_32(cpu, res);
                    350:        return res;
                    351: }
                    352: 
                    353: // src(u32) * dst(u32) を計算し、NZVC フラグをセットして結果(32bit)を返す。
                    354: static inline uint32
                    355: acc_mulu_32(m68kcpu *cpu, uint32 src, uint32 dst)
                    356: {
                    357:        uint64 res = (uint64)src * (uint64)dst;
                    358:        CCR.z = res;
                    359:        CCR.n = res;
                    360:        CCR.c = 0;
                    361:        if (res > 0xffffffffUL) {
                    362:                CCR.v = m68030ccr::V_BIT;
                    363:        } else {
                    364:                CCR.v = 0;
                    365:        }
                    366:        return (uint32)res;
                    367: }
                    368: 
                    369: // src(s32) * dst(s32) を計算し、NZVC フラグをセットして結果(32bit)を返す。
                    370: static inline uint32
                    371: acc_muls_32(m68kcpu *cpu, uint32 src, uint32 dst)
                    372: {
                    373:        int64 res = (int64)(int32)src * (int64)(int32)dst;
                    374:        CCR.z = res;
                    375:        CCR.n = res;
                    376:        CCR.c = 0;
                    377:        // V フラグは64ビット演算結果の上位32ビットが
                    378:        // 下位32ビットの符号拡張になっていなかった場合に立つ。
                    379:        // つまり符号付き整数で 32bit 表現と 64bit 表現が一致していなければ立つ。
                    380:        int32 tmp = res;
                    381:        if (res != tmp) {
                    382:                CCR.v = m68030ccr::V_BIT;
                    383:        } else {
                    384:                CCR.v = 0;
                    385:        }
                    386:        return (uint32)res;
                    387: }
                    388: 
                    389: // src(u32) * dst(u32) を計算し、NZVC フラグをセットして結果(64bit)を返す。
                    390: static inline uint64
                    391: acc_mulu_64(m68kcpu *cpu, uint32 src, uint32 dst)
                    392: {
                    393:        uint64 res = (uint64)src * (uint64)dst;
                    394:        CCR.n = res >> 32;
                    395:        CCR.z = CCR.n | res;
                    396:        CCR.v = 0;
                    397:        CCR.c = 0;
                    398:        return res;
                    399: }
                    400: 
                    401: // src(s32) * dst(s32) を計算し、NZVC フラグをセットして結果(64bit)を返す。
                    402: static inline uint64
                    403: acc_muls_64(m68kcpu *cpu, uint32 src, uint32 dst)
                    404: {
                    405:        int64 res = (int64)(int32)src * (int64)(int32)dst;
                    406:        CCR.n = res >> 32;
                    407:        CCR.z = CCR.n | res;
                    408:        CCR.v = 0;
                    409:        CCR.c = 0;
                    410:        return res;
                    411: }
                    412: 
                    413: static inline void
                    414: acc_btst(m68kcpu *cpu, uint32 data, int n)
                    415: {
                    416:        CCR.z = data & (1 << n);
                    417: }
                    418: 
                    419: static inline uint32
                    420: acc_bchg(m68kcpu *cpu, uint32 data, int n)
                    421: {
                    422:        CCR.z = data & (1 << n);
                    423:        data ^= (1 << n);
                    424:        return data;
                    425: }
                    426: 
                    427: static inline uint32
                    428: acc_bclr(m68kcpu *cpu, uint32 data, int n)
                    429: {
                    430:        CCR.z = data & (1 << n);
                    431:        data &= ~(1 << n);
                    432:        return data;
                    433: }
                    434: 
                    435: static inline uint32
                    436: acc_bset(m68kcpu *cpu, uint32 data, int n)
                    437: {
                    438:        CCR.z = data & (1 << n);
                    439:        data |= (1 << n);
                    440:        return data;
                    441: }
                    442: 
                    443: 
                    444: // data を count ビット算術左シフトし、XNZVC フラグを反映して結果を返す。
                    445: // count は 0..63。data の上位はクリアしておくこと。
                    446: static inline uint32
                    447: acc_asl_8(m68kcpu *cpu, uint32 data, int count)
                    448: {
                    449:        if (count == 0) {
                    450:                acc_move_8(cpu, data);
                    451:                return data;
                    452:        }
                    453:        int64 tmps = (int64)(int8)data;
                    454:        if (count > 8) count = 9;
                    455:        uint64 tmp = (uint64)tmps << count;
                    456:        CCR.x = CCR.c = tmp >> 8;
                    457:        CCR.n = tmp << 24;
                    458:        CCR.z = CCR.n;
                    459:        // 送り出された全てのビットが元の MSB と一致すれば V=0
                    460:        CCR.PutV(((int64)tmp >> 7) != (tmps >> 8));
                    461:        return tmp & 0xff;
                    462: }
                    463: 
                    464: // data を count ビット算術左シフトし、XNZVC フラグを反映して結果を返す。
                    465: // count は 0..63。data の上位はクリアしておくこと。
                    466: static inline uint32
                    467: acc_asl_16(m68kcpu *cpu, uint32 data, int count)
                    468: {
                    469:        if (count == 0) {
                    470:                acc_move_16(cpu, data);
                    471:                return data;
                    472:        }
                    473:        int64 tmps = (int64)(int16)data;
                    474:        if (count > 16) count = 17;
                    475:        uint64 tmp = (uint64)tmps << count;
                    476:        CCR.x = CCR.c = tmp >> 16;
                    477:        CCR.n = tmp << 16;
                    478:        CCR.z = CCR.n;
                    479:        // 送り出された全てのビットが元の MSB と一致すれば V=0
                    480:        CCR.PutV(((int64)tmp >> 15) != (tmps >> 16));
                    481:        return tmp & 0xffff;
                    482: }
                    483: 
                    484: // data を count ビット算術左シフトし、XNZVC フラグを反映して結果を返す。
                    485: // count は 0..63
                    486: static inline uint32
                    487: acc_asl_32(m68kcpu *cpu, uint32 data, int count)
                    488: {
                    489:        if (count == 0) {
                    490:                acc_move_32(cpu, data);
                    491:                return data;
                    492:        }
                    493:        int64 tmps = (int64)(int32)data;
                    494:        if (count > 32) count = 33;
                    495:        uint64 tmp = (uint64)tmps << count;
                    496:        CCR.x = CCR.c = tmp >> 32;
                    497:        CCR.n = CCR.z = tmp;
                    498:        // 送り出された全てのビットが元の MSB と一致すれば V=0
                    499:        CCR.PutV(((int64)tmp >> 31) != (tmps >> 32));
                    500:        return tmp;
                    501: }
                    502: 
                    503: // data を count ビット左シフトし、NZVC フラグを反映して結果を返す。
                    504: // count は 0..63。data の上位はクリアしておくこと。
                    505: static inline uint32
                    506: acc_lsl_8(m68kcpu *cpu, uint32 data, int count)
                    507: {
                    508:        if (count == 0) {
                    509:                acc_move_8(cpu, data);
                    510:                return data;
                    511:        }
                    512:        uint64 tmp = (uint64)data << count;
                    513:        CCR.x = CCR.c = tmp >> 8;
                    514:        CCR.n = tmp << 24;
                    515:        CCR.z = tmp & 0xff;
                    516:        CCR.v = 0;
                    517:        return CCR.z;
                    518: }
                    519: 
                    520: // data を count ビット左シフトし、NZVC フラグを反映して結果を返す。
                    521: // count は 0..63。data の上位はクリアしておくこと。
                    522: static inline uint32
                    523: acc_lsl_16(m68kcpu *cpu, uint32 data, int count)
                    524: {
                    525:        if (count == 0) {
                    526:                acc_move_16(cpu, data);
                    527:                return data;
                    528:        }
                    529:        uint64 tmp = (uint64)data << count;
                    530:        CCR.x = CCR.c = tmp >> 16;
                    531:        CCR.n = tmp << 16;
                    532:        CCR.z = tmp & 0xffff;
                    533:        CCR.v = 0;
                    534:        return CCR.z;
                    535: }
                    536: 
                    537: // data を count ビット左シフトし、NZVC フラグを反映して結果を返す。
                    538: // count は 0..63
                    539: static inline uint32
                    540: acc_lsl_32(m68kcpu *cpu, uint32 data, int count)
                    541: {
                    542:        if (count == 0) {
                    543:                acc_move_32(cpu, data);
                    544:                return data;
                    545:        }
                    546:        uint64 tmp = (uint64)data << count;
                    547:        CCR.x = CCR.c = tmp >> 32;
                    548:        CCR.n = tmp;
                    549:        CCR.z = tmp;
                    550:        CCR.v = 0;
                    551:        return CCR.z;
                    552: }
                    553: 
                    554: // data:X を count ビット左ローテートし、XNZVC フラグを反映して結果を返す。
                    555: // count は 0..63
                    556: static inline uint32
                    557: acc_roxl_8(m68kcpu *cpu, uint32 data, int count)
                    558: {
                    559:        count %= 9;
                    560:        if (count == 0) {
                    561:                CCR.z = data;
                    562:                CCR.n = data << 24;
                    563:                CCR.v = 0;
                    564:                CCR.c = CCR.x;
                    565:                return CCR.z;
                    566:        }
                    567:        uint32 x = CCR.x & 1;
                    568:        CCR.z = (data << count) | (data >> (9 - count)) | (x << (count - 1));
                    569:        CCR.c = CCR.x = CCR.z >> 8;
                    570:        CCR.z &= 0xff;
                    571:        CCR.n = CCR.z << 24;
                    572:        CCR.v = 0;
                    573:        return CCR.z;
                    574: }
                    575: 
                    576: // data:X を count ビット左ローテートし、XNZVC フラグを反映して結果を返す。
                    577: // count は 0..63
                    578: static inline uint32
                    579: acc_roxl_16(m68kcpu *cpu, uint32 data, int count)
                    580: {
                    581:        count %= 17;
                    582:        if (count == 0) {
                    583:                CCR.z = data;
                    584:                CCR.n = data << 16;
                    585:                CCR.v = 0;
                    586:                CCR.c = CCR.x;
                    587:                return CCR.z;
                    588:        }
                    589:        uint32 x = CCR.x & 1;
                    590:        CCR.z = (data << count) | (data >> (17 - count)) | (x << (count - 1));
                    591:        CCR.c = CCR.x = CCR.z >> 16;
                    592:        CCR.z &= 0xffff;
                    593:        CCR.n = CCR.z << 16;
                    594:        CCR.v = 0;
                    595:        return CCR.z;
                    596: }
                    597: 
                    598: // data:X を count ビット左ローテートし、XNZVC フラグを反映して結果を返す。
                    599: // count は 0..63
                    600: static inline uint32
                    601: acc_roxl_32(m68kcpu *cpu, uint32 data, int count)
                    602: {
                    603:        count %= 33;
                    604:        if (count == 0) {
                    605:                CCR.z = data;
                    606:                CCR.n = data;
                    607:                CCR.v = 0;
                    608:                CCR.c = CCR.x;
                    609:                return CCR.z;
                    610:        }
                    611:        // 32bit値の 32ビットシフトは未定義動作なので 64bit値を使用
                    612:        uint64 data64 = data;
                    613:        uint32 x = CCR.x & 1;
                    614:        CCR.z = (data64 << count) | (data64 >> (33 - count)) | (x << (count - 1));
                    615:        CCR.c = CCR.x = data64 >> (32 - count);
                    616:        CCR.n = CCR.z;
                    617:        CCR.v = 0;
                    618:        return CCR.z;
                    619: }
                    620: 
                    621: // data を count ビット左ローテートし、NZVC フラグを反映して結果を返す。
                    622: // count は 0..63。data の上位はクリアしておくこと
                    623: static inline uint32
                    624: acc_rol_8(m68kcpu *cpu, uint32 data, int count)
                    625: {
                    626:        if (count == 0) {
                    627:                acc_move_8(cpu, data);
                    628:                return data;
                    629:        }
                    630: 
                    631:        count %= 8;
                    632:        int count2 = (8 - count) % 8;
                    633:        uint8 tmp = (data << count) | (data >> count2);
                    634:        CCR.z = tmp;
                    635:        CCR.n = (uint32)tmp << 24;
                    636:        CCR.c = data >> count2;
                    637:        CCR.v = 0;
                    638:        return CCR.z;
                    639: }
                    640: 
                    641: // data を count ビット左ローテートし、NZVC フラグを反映して結果を返す。
                    642: // count は 0..63。data の上位はクリアしておくこと
                    643: static inline uint32
                    644: acc_rol_16(m68kcpu *cpu, uint32 data, int count)
                    645: {
                    646:        if (count == 0) {
                    647:                acc_move_16(cpu, data);
                    648:                return data;
                    649:        }
                    650: 
                    651:        count %= 16;
                    652:        int count2 = (16 - count) % 16;
                    653:        uint16 tmp = (data << count) | (data >> count2);
                    654:        CCR.z = tmp;
                    655:        CCR.n = (uint32)tmp << 16;
                    656:        CCR.c = data >> count2;
                    657:        CCR.v = 0;
                    658:        return CCR.z;
                    659: }
                    660: 
                    661: // data を count ビット左ローテートし、NZVC フラグを反映して結果を返す。
                    662: // count は 0..63
                    663: static inline uint32
                    664: acc_rol_32(m68kcpu *cpu, uint32 data, int count)
                    665: {
                    666:        if (count == 0) {
                    667:                acc_move_32(cpu, data);
                    668:                return data;
                    669:        }
                    670: 
                    671:        count %= 32;
                    672:        int count2 = (32 - count) % 32;
                    673:        uint64 data64 = (uint64)data;
                    674:        uint64 tmp = (data << count) | (data >> count2);
                    675:        CCR.z = tmp;
                    676:        CCR.n = CCR.z;
                    677:        CCR.c = data64 >> count2;
                    678:        CCR.v = 0;
                    679:        return CCR.z;
                    680: }
                    681: 
                    682: // data を count ビット算術右シフトし、XNZVC フラグを反映して結果を返す。
                    683: // count は 0..64。data の上位はクリアしておくこと。
                    684: static inline uint32
                    685: acc_asr_8(m68kcpu *cpu, uint32 data, int count)
                    686: {
                    687:        if (count == 0) {
                    688:                acc_move_8(cpu, data);
                    689:                return data;
                    690:        }
                    691:        if (count > 8) {
                    692:                if ((int8)data < 0) {
                    693:                        data = 0xff;
                    694:                } else {
                    695:                        data = 0;
                    696:                }
                    697:                CCR.x = CCR.c = CCR.z = data;
                    698:                CCR.n = data << 24;
                    699:                CCR.v = 0;
                    700:                return data;
                    701:        }
                    702:        // data >>> count の結果が tmp の上位32ビット中の下位8ビットに入る
                    703:        uint64 tmp = (uint64)(int64)(int8)data << (32 - count);
                    704:        CCR.x = CCR.c = tmp >> 31;
                    705:        CCR.n = tmp >> 8;
                    706:        CCR.z = (tmp >> 32) & 0xff;
                    707:        CCR.v = 0;
                    708:        return CCR.z;
                    709: }
                    710: 
                    711: // data を count ビット算術右シフトし、XNZVC フラグを反映して結果を返す。
                    712: // count は 0..64。data の上位はクリアしておくこと。
                    713: static inline uint32
                    714: acc_asr_16(m68kcpu *cpu, uint32 data, int count)
                    715: {
                    716:        if (count == 0) {
                    717:                acc_move_16(cpu, data);
                    718:                return data;
                    719:        }
                    720:        if (count > 16) {
                    721:                if ((int16)data < 0) {
                    722:                        data = 0xffff;
                    723:                } else {
                    724:                        data = 0;
                    725:                }
                    726:                CCR.x = CCR.c = CCR.z = data;
                    727:                CCR.n = data << 16;
                    728:                CCR.v = 0;
                    729:                return data;
                    730:        }
                    731:        // data >>> count の結果が tmp の上位32ビット中の下位16ビットに入る
                    732:        uint64 tmp = (uint64)(int64)(int16)data << (32 - count);
                    733:        CCR.x = CCR.c = tmp >> 31;
                    734:        CCR.n = tmp >> 16;
                    735:        CCR.z = (tmp >> 32) & 0xffff;
                    736:        CCR.v = 0;
                    737:        return CCR.z;
                    738: }
                    739: 
                    740: // data を count ビット算術右シフトし、XNZVC フラグを反映して結果を返す。
                    741: // count は 0..64
                    742: static inline uint32
                    743: acc_asr_32(m68kcpu *cpu, uint32 data, int count)
                    744: {
                    745:        if (count == 0) {
                    746:                acc_move_32(cpu, data);
                    747:                return data;
                    748:        }
                    749:        if (count > 32) {
                    750:                if ((int32)data < 0) {
                    751:                        data = 0xffffffff;
                    752:                } else {
                    753:                        data = 0;
                    754:                }
                    755:                CCR.x = CCR.c = CCR.z = data;
                    756:                CCR.n = data;
                    757:                CCR.v = 0;
                    758:                return data;
                    759:        }
                    760:        // data >>> count の結果が tmp の上位32ビットに入る
                    761:        uint64 tmp = (uint64)(int64)(int32)data << (32 - count);
                    762:        CCR.x = CCR.c = tmp >> 31;
                    763:        CCR.z = CCR.n = tmp >> 32;
                    764:        CCR.v = 0;
                    765:        return CCR.z;
                    766: }
                    767: 
                    768: // data を count ビット論理右シフトし、XNZVC フラグを反映して結果を返す。
                    769: // count は 0..63
                    770: static inline uint32
                    771: acc_lsr_8(m68kcpu *cpu, uint32 data, int count)
                    772: {
                    773:        if (count == 0) {
                    774:                acc_move_8(cpu, data);
                    775:                return data;
                    776:        }
                    777:        if (count > 8) {
                    778:                CCR.x = CCR.c = 0;
                    779:                acc_move_8(cpu, 0);
                    780:                return 0;
                    781:        }
                    782:        // data >> count の結果が tmp の上位32ビットに入る
                    783:        uint64 tmp = (uint64)data << (32 - count);
                    784:        CCR.x = CCR.c = tmp >> 31;
                    785:        CCR.n = tmp >> 8;
                    786:        CCR.z = (tmp >> 32) & 0xff;
                    787:        CCR.v = 0;
                    788:        return CCR.z;
                    789: }
                    790: 
                    791: // data を count ビット論理右シフトし、XNZVC フラグを反映して結果を返す。
                    792: // count は 0..63
                    793: static inline uint32
                    794: acc_lsr_16(m68kcpu *cpu, uint32 data, int count)
                    795: {
                    796:        if (count == 0) {
                    797:                acc_move_16(cpu, data);
                    798:                return data;
                    799:        }
                    800:        if (count > 16) {
                    801:                CCR.x = CCR.c = 0;
                    802:                acc_move_16(cpu, 0);
                    803:                return 0;
                    804:        }
                    805:        // data >> count の結果が tmp の上位32ビットに入る
                    806:        uint64 tmp = (uint64)data << (32 - count);
                    807:        CCR.x = CCR.c = tmp >> 31;
                    808:        CCR.n = tmp >> 16;
                    809:        CCR.z = (tmp >> 32) & 0xffff;
                    810:        CCR.v = 0;
                    811:        return CCR.z;
                    812: }
                    813: 
                    814: // data を count ビット論理右シフトし、XNZVC フラグを反映して結果を返す。
                    815: // count は 0..63
                    816: static inline uint32
                    817: acc_lsr_32(m68kcpu *cpu, uint32 data, int count)
                    818: {
                    819:        if (count == 0) {
                    820:                acc_move_32(cpu, data);
                    821:                return data;
                    822:        }
                    823:        if (count > 32) {
                    824:                CCR.x = CCR.c = 0;
                    825:                acc_move_32(cpu, 0);
                    826:                return 0;
                    827:        }
                    828:        // data >> count の結果が tmp の上位32ビットに入る
                    829:        uint64 tmp = (uint64)data << (32 - count);
                    830:        CCR.x = CCR.c = tmp >> 31;
                    831:        CCR.z = CCR.n = tmp >> 32;
                    832:        CCR.v = 0;
                    833:        return CCR.z;
                    834: }
                    835: 
                    836: // data:C を count ビット右ローテートし、NZVC フラグを反映して結果を返す。
                    837: // count は 0..63
                    838: static inline uint32
                    839: acc_roxr_8(m68kcpu *cpu, uint32 data, int count)
                    840: {
                    841:        count %= 9;
                    842:        if (count == 0) {
                    843:                CCR.z = data;
                    844:                CCR.n = data << 24;
                    845:                CCR.v = 0;
                    846:                CCR.c = CCR.x;
                    847:                return CCR.z;
                    848:        }
                    849:        uint32 rot = data & ((1 << (count - 1)) - 1);
                    850:        uint32 x = CCR.x & 1;
                    851:        CCR.z = (data >> count) | (rot << (9 - count)) | (x << (8 - count));
                    852:        CCR.c = CCR.x = data >> (count - 1);
                    853:        CCR.n = CCR.z << 24;
                    854:        CCR.v = 0;
                    855:        return CCR.z;
                    856: }
                    857: 
                    858: // data:C を count ビット右ローテートし、NZVC フラグを反映して結果を返す。
                    859: // count は 0..63
                    860: static inline uint32
                    861: acc_roxr_16(m68kcpu *cpu, uint32 data, int count)
                    862: {
                    863:        count %= 17;
                    864:        if (count == 0) {
                    865:                CCR.z = data;
                    866:                CCR.n = data << 16;
                    867:                CCR.v = 0;
                    868:                CCR.c = CCR.x;
                    869:                return CCR.z;
                    870:        }
                    871:        uint32 rot = data & ((1 << (count - 1)) - 1);
                    872:        uint32 x = CCR.x & 1;
                    873:        CCR.z = (data >> count) | (rot << (17 - count)) | (x << (16 - count));
                    874:        CCR.c = CCR.x = data >> (count - 1);
                    875:        CCR.n = CCR.z << 16;
                    876:        CCR.v = 0;
                    877:        return CCR.z;
                    878: }
                    879: 
                    880: // data:C を count ビット右ローテートし、NZVC フラグを反映して結果を返す。
                    881: // count は 0..63
                    882: static inline uint32
                    883: acc_roxr_32(m68kcpu *cpu, uint32 data, int count)
                    884: {
                    885:        count %= 33;
                    886:        if (count == 0) {
                    887:                CCR.z = data;
                    888:                CCR.n = data;
                    889:                CCR.v = 0;
                    890:                CCR.c = CCR.x;
                    891:                return CCR.z;
                    892:        }
                    893:        // 32bit値の 32ビットシフトは未定義動作なので 64bit値を使用
                    894:        uint64 data64 = data;
                    895:        uint64 rot = data64 & ((1 << (count - 1)) - 1);
                    896:        uint32 x = CCR.x & 1;
                    897:        CCR.z = (data64 >> count) | (rot << (33 - count)) | (x << (32 - count));
                    898:        CCR.c = CCR.x = data64 >> (count - 1);
                    899:        CCR.n = CCR.z;
                    900:        CCR.v = 0;
                    901:        return CCR.z;
                    902: }
                    903: 
                    904: // data を count ビット右ローテートし、NZVC フラグを反映して結果を返す。
                    905: // count は 0..63
                    906: static inline uint32
                    907: acc_ror_8(m68kcpu *cpu, uint32 data, int count)
                    908: {
                    909:        if (count == 0) {
                    910:                acc_move_8(cpu, data);
                    911:                return data;
                    912:        }
                    913: 
                    914:        count %= 8;
                    915:        uint8 tmp = (data >> count) | (data << (8 - count));
                    916:        CCR.z = tmp;
                    917:        CCR.n = (uint32)tmp << 24;
                    918:        // 7 0 1 2 3 4 5 6
                    919:        CCR.c = data >> ((count + 7) % 8);
                    920:        CCR.v = 0;
                    921:        return tmp;
                    922: }
                    923: 
                    924: // data を count ビット右ローテートし、NZVC フラグを反映して結果を返す。
                    925: // count は 0..63
                    926: static inline uint32
                    927: acc_ror_16(m68kcpu *cpu, uint32 data, int count)
                    928: {
                    929:        if (count == 0) {
                    930:                acc_move_16(cpu, data);
                    931:                return data;
                    932:        }
                    933: 
                    934:        count %= 16;
                    935:        uint16 tmp = (data >> count) | (data << (16 - count));
                    936:        CCR.z = tmp;
                    937:        CCR.n = (uint32)tmp << 16;
                    938:        CCR.c = data >> ((count + 15) % 16);
                    939:        CCR.v = 0;
                    940:        return tmp;
                    941: }
                    942: 
                    943: // data を count ビット右ローテートし、NZVC フラグを反映して結果を返す。
                    944: // count は 0..63
                    945: static inline uint32
                    946: acc_ror_32(m68kcpu *cpu, uint32 data, int count)
                    947: {
                    948:        if (count == 0) {
                    949:                acc_move_32(cpu, data);
                    950:                return data;
                    951:        }
                    952: 
                    953:        count %= 32;
                    954:        uint64 data64 = (uint64)data;
                    955:        uint64 tmp = (data >> count) | (data << (32 - count));
                    956:        CCR.z = tmp;
                    957:        CCR.n = tmp;
                    958:        CCR.c = data64 >> ((count + 31) % 32);
                    959:        CCR.v = 0;
                    960:        return tmp;
                    961: }

unix.superglobalmegacorp.com

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