Annotation of nono/m680x0/m68030acc.h, revision 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.