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

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

unix.superglobalmegacorp.com

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