Annotation of nono/m680x0/m68030acc.cpp, revision 1.1.1.3

1.1       root        1: //
                      2: // nono
1.1.1.2   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
1.1.1.3 ! root        7: #include "mpu680x0.h"
1.1       root        8: #include "m68030acc.h"
                      9: 
1.1.1.3 ! root       10: /*static*/ inline uint32
        !            11: m68030acc::vflag_add_8(uint32 src, uint32 dst, uint32 res)
        !            12: {
        !            13:        return vflag_add_32(src, dst, res) << 24;
        !            14: }
        !            15: 
        !            16: /*static*/ inline uint32
        !            17: m68030acc::vflag_add_16(uint32 src, uint32 dst, uint32 res)
        !            18: {
        !            19:        return vflag_add_32(src, dst, res) << 16;
        !            20: }
        !            21: 
        !            22: /*static*/ inline uint32
        !            23: m68030acc::vflag_add_32(uint32 src, uint32 dst, uint32 res)
        !            24: {
        !            25:        return (src ^ res) & (dst ^ res);
        !            26: }
        !            27: 
        !            28: // src + dst を計算し、XNZVC フラグをセットして結果を返す。
        !            29: // src, dst の上位ビットはクリアしておくこと。
        !            30: // 戻り値の上位ビットはクリアされている。
        !            31: uint32
        !            32: m68030acc::add_8(uint32 src, uint32 dst)
        !            33: {
        !            34:        Z = dst + src;
        !            35:        C = Z >> 8;
        !            36:        X = C;
        !            37:        N = Z << 24;
        !            38:        Z &= 0xff;
        !            39:        V = vflag_add_8(src, dst, Z);
        !            40:        return Z;
        !            41: }
        !            42: 
        !            43: // src + dst を計算し、XNZVC フラグをセットして結果を返す。
        !            44: // src, dst の上位ビットはクリアしておくこと。
        !            45: // 戻り値の上位ビットはクリアされている。
        !            46: uint32
        !            47: m68030acc::add_16(uint32 src, uint32 dst)
        !            48: {
        !            49:        Z = dst + src;
        !            50:        C = Z >> 16;
        !            51:        X = C;
        !            52:        N = Z << 16;
        !            53:        Z &= 0xffff;
        !            54:        V = vflag_add_16(src, dst, Z);
        !            55:        return Z;
        !            56: }
        !            57: 
        !            58: // src + dst を計算し、XNZVC フラグをセットして結果を返す。
        !            59: uint32
        !            60: m68030acc::add_32(uint32 src, uint32 dst)
        !            61: {
        !            62:        CZ = (uint64)dst + (uint64)src;
        !            63:        X = C;
        !            64:        V = vflag_add_32(src, dst, Z);
        !            65:        N = Z;
        !            66:        return Z;
        !            67: }
        !            68: 
        !            69: // src + dst + X を計算し、XNZVC フラグをセットして結果を返す。
        !            70: // src, dst の上位ビットはクリアしておくこと。
        !            71: // 戻り値の上位ビットはクリアされている。
        !            72: uint32
        !            73: m68030acc::addx_8(uint32 src, uint32 dst)
        !            74: {
        !            75:        uint32 res = dst + src + (IsX() ? 1 : 0);
        !            76:        C = res >> 8;
        !            77:        X = C;
        !            78:        N = res << 24;
        !            79:        // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない
        !            80:        if (N != 0) {
        !            81:                Z = N;
        !            82:        }
        !            83:        V = vflag_add_8(src, dst, res);
        !            84:        return res & 0xff;
        !            85: }
        !            86: 
        !            87: // src + dst + X を計算し、XNZVC フラグをセットして結果を返す。
        !            88: // src, dst の上位ビットはクリアしておくこと。
        !            89: // 戻り値の上位ビットはクリアされている。
        !            90: uint32
        !            91: m68030acc::addx_16(uint32 src, uint32 dst)
        !            92: {
        !            93:        uint32 res = dst + src + (IsX() ? 1 : 0);
        !            94:        C = res >> 16;
        !            95:        X = C;
        !            96:        N = res << 16;
        !            97:        // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない
        !            98:        if (N != 0) {
        !            99:                Z = N;
        !           100:        }
        !           101:        V = vflag_add_16(src, dst, res);
        !           102:        return res & 0xffff;
        !           103: }
        !           104: 
        !           105: // src + dst + X を計算し、XNZVC フラグをセットして結果を返す。
        !           106: uint32
        !           107: m68030acc::addx_32(uint32 src, uint32 dst)
        !           108: {
        !           109:        uint64 res = (uint64)dst + (uint64)src + (IsX() ? 1 : 0);
        !           110:        C = res >> 32;
        !           111:        X = C;
        !           112:        N = res;
        !           113:        // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない
        !           114:        if (N != 0) {
        !           115:                Z = N;
        !           116:        }
        !           117:        V = vflag_add_32(src, dst, res);
        !           118:        return res;
        !           119: }
        !           120: 
        !           121: 
        !           122: /*static*/ inline uint32
        !           123: m68030acc::vflag_sub_8(uint32 src, uint32 dst, uint32 res)
        !           124: {
        !           125:        return vflag_sub_32(src, dst, res) << 24;
        !           126: }
        !           127: 
        !           128: /*static*/ inline uint32
        !           129: m68030acc::vflag_sub_16(uint32 src, uint32 dst, uint32 res)
        !           130: {
        !           131:        return vflag_sub_32(src, dst, res) << 16;
        !           132: }
        !           133: 
        !           134: /*static*/ inline uint32
        !           135: m68030acc::vflag_sub_32(uint32 src, uint32 dst, uint32 res)
        !           136: {
        !           137:        return (src ^ dst) & (dst ^ res);
        !           138: }
        !           139: 
        !           140: // dst - src を計算し、NZVC フラグをセットして結果を返す。
        !           141: // src, dst の上位ビットはクリアしておくこと。
        !           142: // 戻り値の上位ビットはクリアされている。
        !           143: uint32
        !           144: m68030acc::cmp_8(uint32 src, uint32 dst)
        !           145: {
        !           146:        Z = dst - src;
        !           147:        C = Z >> 8;
        !           148:        N = Z << 24;
        !           149:        Z &= 0xff;
        !           150:        V = vflag_sub_8(src, dst, Z);
        !           151:        return Z;
        !           152: }
        !           153: 
        !           154: // dst - src を計算し、NZVC フラグをセットして結果を返す。
        !           155: // src, dst の上位ビットはクリアしておくこと。
        !           156: // 戻り値の上位ビットはクリアされている。
        !           157: uint32
        !           158: m68030acc::cmp_16(uint32 src, uint32 dst)
        !           159: {
        !           160:        Z = dst - src;
        !           161:        C = Z >> 16;
        !           162:        N = Z << 16;
        !           163:        Z &= 0xffff;
        !           164:        V = vflag_sub_16(src, dst, Z);
        !           165:        return Z;
        !           166: }
1.1       root      167: 
1.1.1.3 ! root      168: // dst - src を計算し、NZVC フラグをセットして結果を返す。
        !           169: uint32
        !           170: m68030acc::cmp_32(uint32 src, uint32 dst)
        !           171: {
        !           172:        CZ = (uint64)dst - (uint64)src;
        !           173:        N = Z;
        !           174:        V = vflag_sub_32(src, dst, Z);
        !           175:        return Z;
        !           176: }
1.1       root      177: 
1.1.1.3 ! root      178: // dst - src を計算し、XNZVC フラグをセットして結果を返す。
        !           179: // src, dst の上位ビットはクリアしておくこと。
        !           180: // 戻り値の上位ビットはクリアされている。
        !           181: uint32
        !           182: m68030acc::sub_8(uint32 src, uint32 dst)
        !           183: {
        !           184:        uint32 res = cmp_8(src, dst);
        !           185:        X = C;
        !           186:        return res;
        !           187: }
1.1       root      188: 
1.1.1.3 ! root      189: // dst - src を計算し、XNZVC フラグをセットして結果を返す。
        !           190: // src, dst の上位ビットはクリアしておくこと。
        !           191: // 戻り値の上位ビットはクリアされている。
        !           192: uint32
        !           193: m68030acc::sub_16(uint32 src, uint32 dst)
1.1       root      194: {
1.1.1.3 ! root      195:        uint32 res = cmp_16(src, dst);
        !           196:        X = C;
        !           197:        return res;
        !           198: }
1.1       root      199: 
1.1.1.3 ! root      200: // dst - src を計算し、XNZVC フラグをセットして結果を返す。
        !           201: uint32
        !           202: m68030acc::sub_32(uint32 src, uint32 dst)
        !           203: {
        !           204:        uint32 res = cmp_32(src, dst);
        !           205:        X = C;
        !           206:        return res;
        !           207: }
1.1       root      208: 
1.1.1.3 ! root      209: // src - dst - X を計算し、XNZVC フラグをセットして結果を返す。
        !           210: // src, dst の上位ビットはクリアしておくこと。
        !           211: // 戻り値 res の上位ビットはクリアされている。
        !           212: uint32
        !           213: m68030acc::subx_8(uint32 src, uint32 dst)
        !           214: {
        !           215:        uint32 res = dst - src - (IsX() ? 1 : 0);
        !           216:        C = res >> 8;
        !           217:        X = C;
        !           218:        N = res << 24;
        !           219:        // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない
        !           220:        if (N != 0) {
        !           221:                Z = N;
        !           222:        }
        !           223:        V = vflag_sub_8(src, dst, res);
        !           224:        return res & 0xff;
        !           225: }
        !           226: 
        !           227: // src - dst - X を計算し、XNZVC フラグをセットして結果を返す。
        !           228: // src, dst の上位ビットはクリアしておくこと。
        !           229: // 戻り値 res の上位ビットはクリアされている。
        !           230: uint32
        !           231: m68030acc::subx_16(uint32 src, uint32 dst)
        !           232: {
        !           233:        uint32 res = dst - src - (IsX() ? 1 : 0);
        !           234:        C = res >> 16;
        !           235:        X = C;
        !           236:        N = res << 16;
        !           237:        // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない
        !           238:        if (N != 0) {
        !           239:                Z = N;
        !           240:        }
        !           241:        V = vflag_sub_16(src, dst, res);
        !           242:        return res & 0xffff;
        !           243: }
        !           244: 
        !           245: // src - dst - X を計算し、XNZVC フラグをセットして結果を返す。
        !           246: uint32
        !           247: m68030acc::subx_32(uint32 src, uint32 dst)
        !           248: {
        !           249:        uint64 res = (uint64)dst - (uint64)src - (IsX() ? 1 : 0);
        !           250:        C = res >> 32;
        !           251:        X = C;
        !           252:        N = res;
        !           253:        // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない
        !           254:        if (N != 0) {
        !           255:                Z = N;
        !           256:        }
        !           257:        V = vflag_sub_32(src, dst, res);
        !           258:        return res;
        !           259: }
        !           260: 
        !           261: // src(u16) * dst(u16) を計算し、NZVC フラグをセットして結果(u32)を返す。
        !           262: // src, dst の上位ビットはクリアしておくこと。
        !           263: uint32
        !           264: m68030acc::mulu_16(uint32 src, uint32 dst)
        !           265: {
        !           266:        uint32 res = src * dst;
        !           267:        // 16x16->32 ではオーバーフローは起きないので move でよい
        !           268:        move_32(res);
        !           269:        return res;
        !           270: }
        !           271: 
        !           272: // src(s16) * dst(s16) を計算し、NZVC フラグをセットして結果(u32)を返す。
        !           273: // src, dst の上位ビットはクリアしておくこと。
        !           274: uint32
        !           275: m68030acc::muls_16(uint32 src, uint32 dst)
        !           276: {
        !           277:        int32 res = (int32)(int16)src * (int32)(int16)dst;
        !           278:        // 16x16->32 ではオーバーフローは起きないので move でよい
        !           279:        move_32(res);
        !           280:        return res;
        !           281: }
        !           282: 
        !           283: // src(u32) * dst(u32) を計算し、NZVC フラグをセットして結果(32bit)を返す。
        !           284: uint32
        !           285: m68030acc::mulu_32(uint32 src, uint32 dst)
        !           286: {
        !           287:        uint64 res = (uint64)src * (uint64)dst;
        !           288:        Z = res;
        !           289:        N = res;
        !           290:        C = 0;
        !           291:        if (res > 0xffffffffUL) {
        !           292:                V = V_BIT;
1.1       root      293:        } else {
1.1.1.3 ! root      294:                V = 0;
1.1       root      295:        }
1.1.1.3 ! root      296:        return (uint32)res;
        !           297: }
1.1       root      298: 
1.1.1.3 ! root      299: // src(s32) * dst(s32) を計算し、NZVC フラグをセットして結果(32bit)を返す。
        !           300: uint32
        !           301: m68030acc::muls_32(uint32 src, uint32 dst)
        !           302: {
        !           303:        int64 res = (int64)(int32)src * (int64)(int32)dst;
        !           304:        Z = res;
        !           305:        N = res;
        !           306:        C = 0;
        !           307:        // V フラグは64ビット演算結果の上位32ビットが
        !           308:        // 下位32ビットの符号拡張になっていなかった場合に立つ。
        !           309:        // つまり符号付き整数で 32bit 表現と 64bit 表現が一致していなければ立つ。
        !           310:        int32 tmp = res;
        !           311:        if (res != tmp) {
        !           312:                V = V_BIT;
        !           313:        } else {
        !           314:                V = 0;
1.1       root      315:        }
1.1.1.3 ! root      316:        return (uint32)res;
1.1       root      317: }
                    318: 
1.1.1.3 ! root      319: // src(u32) * dst(u32) を計算し、NZVC フラグをセットして結果(64bit)を返す。
        !           320: uint64
        !           321: m68030acc::mulu_64(uint32 src, uint32 dst)
1.1       root      322: {
1.1.1.3 ! root      323:        uint64 res = (uint64)src * (uint64)dst;
        !           324:        N = res >> 32;
        !           325:        Z = N | res;
        !           326:        V = 0;
        !           327:        C = 0;
        !           328:        return res;
        !           329: }
        !           330: 
        !           331: // src(s32) * dst(s32) を計算し、NZVC フラグをセットして結果(64bit)を返す。
        !           332: uint64
        !           333: m68030acc::muls_64(uint32 src, uint32 dst)
        !           334: {
        !           335:        int64 res = (int64)(int32)src * (int64)(int32)dst;
        !           336:        N = res >> 32;
        !           337:        Z = N | res;
        !           338:        V = 0;
        !           339:        C = 0;
        !           340:        return res;
1.1       root      341: }
                    342: 
                    343: void
1.1.1.3 ! root      344: m68030acc::btst(uint32 data, int n)
1.1       root      345: {
1.1.1.3 ! root      346:        Z = data & (1 << n);
        !           347: }
        !           348: 
        !           349: uint32
        !           350: m68030acc::bchg(uint32 data, int n)
        !           351: {
        !           352:        Z = data & (1 << n);
        !           353:        data ^= (1 << n);
        !           354:        return data;
        !           355: }
        !           356: 
        !           357: uint32
        !           358: m68030acc::bclr(uint32 data, int n)
        !           359: {
        !           360:        Z = data & (1 << n);
        !           361:        data &= ~(1 << n);
        !           362:        return data;
        !           363: }
        !           364: 
        !           365: uint32
        !           366: m68030acc::bset(uint32 data, int n)
        !           367: {
        !           368:        Z = data & (1 << n);
        !           369:        data |= (1 << n);
        !           370:        return data;
        !           371: }
        !           372: 
        !           373: 
        !           374: // data を count ビット算術左シフトし、XNZVC フラグを反映して結果を返す。
        !           375: // count は 0..63。data の上位はクリアしておくこと。
        !           376: uint32
        !           377: m68030acc::asl_8(uint32 data, int count)
        !           378: {
        !           379:        if (count == 0) {
        !           380:                move_8(data);
        !           381:                return data;
        !           382:        }
        !           383:        int64 tmps = (int64)(int8)data;
        !           384:        if (count > 8) count = 9;
        !           385:        uint64 tmp = (uint64)tmps << count;
        !           386:        X = C = tmp >> 8;
        !           387:        N = tmp << 24;
        !           388:        Z = N;
        !           389:        // 送り出された全てのビットが元の MSB と一致すれば V=0
        !           390:        SetV(((int64)tmp >> 7) != (tmps >> 8));
        !           391:        return tmp & 0xff;
        !           392: }
        !           393: 
        !           394: // data を count ビット算術左シフトし、XNZVC フラグを反映して結果を返す。
        !           395: // count は 0..63。data の上位はクリアしておくこと。
        !           396: uint32
        !           397: m68030acc::asl_16(uint32 data, int count)
        !           398: {
        !           399:        if (count == 0) {
        !           400:                move_16(data);
        !           401:                return data;
        !           402:        }
        !           403:        int64 tmps = (int64)(int16)data;
        !           404:        if (count > 16) count = 17;
        !           405:        uint64 tmp = (uint64)tmps << count;
        !           406:        X = C = tmp >> 16;
        !           407:        N = tmp << 16;
        !           408:        Z = N;
        !           409:        // 送り出された全てのビットが元の MSB と一致すれば V=0
        !           410:        SetV(((int64)tmp >> 15) != (tmps >> 16));
        !           411:        return tmp & 0xffff;
        !           412: }
        !           413: 
        !           414: // data を count ビット算術左シフトし、XNZVC フラグを反映して結果を返す。
        !           415: // count は 0..63
        !           416: uint32
        !           417: m68030acc::asl_32(uint32 data, int count)
        !           418: {
        !           419:        if (count == 0) {
        !           420:                move_32(data);
        !           421:                return data;
        !           422:        }
        !           423:        int64 tmps = (int64)(int32)data;
        !           424:        if (count > 32) count = 33;
        !           425:        uint64 tmp = (uint64)tmps << count;
        !           426:        X = C = tmp >> 32;
        !           427:        N = Z = tmp;
        !           428:        // 送り出された全てのビットが元の MSB と一致すれば V=0
        !           429:        SetV(((int64)tmp >> 31) != (tmps >> 32));
        !           430:        return tmp;
        !           431: }
        !           432: 
        !           433: // data を count ビット左シフトし、NZVC フラグを反映して結果を返す。
        !           434: // count は 0..63。data の上位はクリアしておくこと。
        !           435: uint32
        !           436: m68030acc::lsl_8(uint32 data, int count)
        !           437: {
        !           438:        if (count == 0) {
        !           439:                move_8(data);
        !           440:                return data;
        !           441:        }
        !           442:        uint64 tmp = (uint64)data << count;
        !           443:        X = C = tmp >> 8;
        !           444:        N = tmp << 24;
        !           445:        Z = tmp & 0xff;
        !           446:        V = 0;
        !           447:        return Z;
        !           448: }
        !           449: 
        !           450: // data を count ビット左シフトし、NZVC フラグを反映して結果を返す。
        !           451: // count は 0..63。data の上位はクリアしておくこと。
        !           452: uint32
        !           453: m68030acc::lsl_16(uint32 data, int count)
        !           454: {
        !           455:        if (count == 0) {
        !           456:                move_16(data);
        !           457:                return data;
        !           458:        }
        !           459:        uint64 tmp = (uint64)data << count;
        !           460:        X = C = tmp >> 16;
        !           461:        N = tmp << 16;
        !           462:        Z = tmp & 0xffff;
        !           463:        V = 0;
        !           464:        return Z;
        !           465: }
        !           466: 
        !           467: // data を count ビット左シフトし、NZVC フラグを反映して結果を返す。
        !           468: // count は 0..63
        !           469: uint32
        !           470: m68030acc::lsl_32(uint32 data, int count)
        !           471: {
        !           472:        if (count == 0) {
        !           473:                move_32(data);
        !           474:                return data;
        !           475:        }
        !           476:        uint64 tmp = (uint64)data << count;
        !           477:        X = C = tmp >> 32;
        !           478:        N = tmp;
        !           479:        Z = tmp;
        !           480:        V = 0;
        !           481:        return Z;
        !           482: }
        !           483: 
        !           484: // data:X を count ビット左ローテートし、XNZVC フラグを反映して結果を返す。
        !           485: // count は 0..63
        !           486: uint32
        !           487: m68030acc::roxl_8(uint32 data, int count)
        !           488: {
        !           489:        count %= 9;
        !           490:        if (count == 0) {
        !           491:                Z = data;
        !           492:                N = data << 24;
        !           493:                V = 0;
        !           494:                C = X;
        !           495:                return Z;
        !           496:        }
        !           497:        uint32 xbit = X & 1;
        !           498:        Z = (data << count) | (data >> (9 - count)) | (xbit << (count - 1));
        !           499:        C = X = Z >> 8;
        !           500:        Z &= 0xff;
        !           501:        N = Z << 24;
        !           502:        V = 0;
        !           503:        return Z;
        !           504: }
        !           505: 
        !           506: // data:X を count ビット左ローテートし、XNZVC フラグを反映して結果を返す。
        !           507: // count は 0..63
        !           508: uint32
        !           509: m68030acc::roxl_16(uint32 data, int count)
        !           510: {
        !           511:        count %= 17;
        !           512:        if (count == 0) {
        !           513:                Z = data;
        !           514:                N = data << 16;
        !           515:                V = 0;
        !           516:                C = X;
        !           517:                return Z;
        !           518:        }
        !           519:        uint32 xbit = X & 1;
        !           520:        Z = (data << count) | (data >> (17 - count)) | (xbit << (count - 1));
        !           521:        C = X = Z >> 16;
        !           522:        Z &= 0xffff;
        !           523:        N = Z << 16;
        !           524:        V = 0;
        !           525:        return Z;
        !           526: }
        !           527: 
        !           528: // data:X を count ビット左ローテートし、XNZVC フラグを反映して結果を返す。
        !           529: // count は 0..63
        !           530: uint32
        !           531: m68030acc::roxl_32(uint32 data, int count)
        !           532: {
        !           533:        count %= 33;
        !           534:        if (count == 0) {
        !           535:                Z = data;
        !           536:                N = data;
        !           537:                V = 0;
        !           538:                C = X;
        !           539:                return Z;
        !           540:        }
        !           541:        // 32bit値の 32ビットシフトは未定義動作なので 64bit値を使用
        !           542:        uint64 data64 = data;
        !           543:        uint32 xbit = X & 1;
        !           544:        Z = (data64 << count) | (data64 >> (33 - count)) | (xbit << (count - 1));
        !           545:        C = X = data64 >> (32 - count);
        !           546:        N = Z;
        !           547:        V = 0;
        !           548:        return Z;
        !           549: }
        !           550: 
        !           551: // data を count ビット左ローテートし、NZVC フラグを反映して結果を返す。
        !           552: // count は 0..63。data の上位はクリアしておくこと
        !           553: uint32
        !           554: m68030acc::rol_8(uint32 data, int count)
        !           555: {
        !           556:        if (count == 0) {
        !           557:                move_8(data);
        !           558:                return data;
1.1       root      559:        }
                    560: 
1.1.1.3 ! root      561:        count %= 8;
        !           562:        int count2 = (8 - count) % 8;
        !           563:        uint8 tmp = (data << count) | (data >> count2);
        !           564:        Z = tmp;
        !           565:        N = (uint32)tmp << 24;
        !           566:        C = data >> count2;
        !           567:        V = 0;
        !           568:        return Z;
1.1       root      569: }
                    570: 
1.1.1.3 ! root      571: // data を count ビット左ローテートし、NZVC フラグを反映して結果を返す。
        !           572: // count は 0..63。data の上位はクリアしておくこと
        !           573: uint32
        !           574: m68030acc::rol_16(uint32 data, int count)
1.1       root      575: {
1.1.1.3 ! root      576:        if (count == 0) {
        !           577:                move_16(data);
        !           578:                return data;
        !           579:        }
1.1       root      580: 
1.1.1.3 ! root      581:        count %= 16;
        !           582:        int count2 = (16 - count) % 16;
        !           583:        uint16 tmp = (data << count) | (data >> count2);
        !           584:        Z = tmp;
        !           585:        N = (uint32)tmp << 16;
        !           586:        C = data >> count2;
        !           587:        V = 0;
        !           588:        return Z;
1.1       root      589: }
                    590: 
1.1.1.3 ! root      591: // data を count ビット左ローテートし、NZVC フラグを反映して結果を返す。
        !           592: // count は 0..63
        !           593: uint32
        !           594: m68030acc::rol_32(uint32 data, int count)
        !           595: {
        !           596:        if (count == 0) {
        !           597:                move_32(data);
        !           598:                return data;
        !           599:        }
        !           600: 
        !           601:        count %= 32;
        !           602:        int count2 = (32 - count) % 32;
        !           603:        uint64 data64 = (uint64)data;
        !           604:        uint64 tmp = (data << count) | (data >> count2);
        !           605:        Z = tmp;
        !           606:        N = Z;
        !           607:        C = data64 >> count2;
        !           608:        V = 0;
        !           609:        return Z;
        !           610: }
        !           611: 
        !           612: // data を count ビット算術右シフトし、XNZVC フラグを反映して結果を返す。
        !           613: // count は 0..64。data の上位はクリアしておくこと。
        !           614: uint32
        !           615: m68030acc::asr_8(uint32 data, int count)
1.1       root      616: {
1.1.1.3 ! root      617:        if (count == 0) {
        !           618:                move_8(data);
        !           619:                return data;
        !           620:        }
        !           621:        if (count > 8) {
        !           622:                if ((int8)data < 0) {
        !           623:                        data = 0xff;
1.1       root      624:                } else {
1.1.1.3 ! root      625:                        data = 0;
1.1       root      626:                }
1.1.1.3 ! root      627:                X = C = Z = data;
        !           628:                N = data << 24;
        !           629:                V = 0;
        !           630:                return data;
        !           631:        }
        !           632:        // data >>> count の結果が tmp の上位32ビット中の下位8ビットに入る
        !           633:        uint64 tmp = (uint64)(int64)(int8)data << (32 - count);
        !           634:        X = C = tmp >> 31;
        !           635:        N = tmp >> 8;
        !           636:        Z = (tmp >> 32) & 0xff;
        !           637:        V = 0;
        !           638:        return Z;
        !           639: }
        !           640: 
        !           641: // data を count ビット算術右シフトし、XNZVC フラグを反映して結果を返す。
        !           642: // count は 0..64。data の上位はクリアしておくこと。
        !           643: uint32
        !           644: m68030acc::asr_16(uint32 data, int count)
        !           645: {
        !           646:        if (count == 0) {
        !           647:                move_16(data);
        !           648:                return data;
        !           649:        }
        !           650:        if (count > 16) {
        !           651:                if ((int16)data < 0) {
        !           652:                        data = 0xffff;
1.1       root      653:                } else {
1.1.1.3 ! root      654:                        data = 0;
1.1       root      655:                }
1.1.1.3 ! root      656:                X = C = Z = data;
        !           657:                N = data << 16;
        !           658:                V = 0;
        !           659:                return data;
        !           660:        }
        !           661:        // data >>> count の結果が tmp の上位32ビット中の下位16ビットに入る
        !           662:        uint64 tmp = (uint64)(int64)(int16)data << (32 - count);
        !           663:        X = C = tmp >> 31;
        !           664:        N = tmp >> 16;
        !           665:        Z = (tmp >> 32) & 0xffff;
        !           666:        V = 0;
        !           667:        return Z;
        !           668: }
        !           669: 
        !           670: // data を count ビット算術右シフトし、XNZVC フラグを反映して結果を返す。
        !           671: // count は 0..64
        !           672: uint32
        !           673: m68030acc::asr_32(uint32 data, int count)
        !           674: {
        !           675:        if (count == 0) {
        !           676:                move_32(data);
        !           677:                return data;
        !           678:        }
        !           679:        if (count > 32) {
        !           680:                if ((int32)data < 0) {
        !           681:                        data = 0xffffffff;
        !           682:                } else {
        !           683:                        data = 0;
        !           684:                }
        !           685:                X = C = Z = data;
        !           686:                N = data;
        !           687:                V = 0;
        !           688:                return data;
        !           689:        }
        !           690:        // data >>> count の結果が tmp の上位32ビットに入る
        !           691:        uint64 tmp = (uint64)(int64)(int32)data << (32 - count);
        !           692:        X = C = tmp >> 31;
        !           693:        Z = N = tmp >> 32;
        !           694:        V = 0;
        !           695:        return Z;
        !           696: }
        !           697: 
        !           698: // data を count ビット論理右シフトし、XNZVC フラグを反映して結果を返す。
        !           699: // count は 0..63
        !           700: uint32
        !           701: m68030acc::lsr_8(uint32 data, int count)
        !           702: {
        !           703:        if (count == 0) {
        !           704:                move_8(data);
        !           705:                return data;
        !           706:        }
        !           707:        if (count > 8) {
        !           708:                X = C = 0;
        !           709:                move_8(0);
        !           710:                return 0;
        !           711:        }
        !           712:        // data >> count の結果が tmp の上位32ビットに入る
        !           713:        uint64 tmp = (uint64)data << (32 - count);
        !           714:        X = C = tmp >> 31;
        !           715:        N = tmp >> 8;
        !           716:        Z = (tmp >> 32) & 0xff;
        !           717:        V = 0;
        !           718:        return Z;
        !           719: }
        !           720: 
        !           721: // data を count ビット論理右シフトし、XNZVC フラグを反映して結果を返す。
        !           722: // count は 0..63
        !           723: uint32
        !           724: m68030acc::lsr_16(uint32 data, int count)
        !           725: {
        !           726:        if (count == 0) {
        !           727:                move_16(data);
        !           728:                return data;
        !           729:        }
        !           730:        if (count > 16) {
        !           731:                X = C = 0;
        !           732:                move_16(0);
        !           733:                return 0;
        !           734:        }
        !           735:        // data >> count の結果が tmp の上位32ビットに入る
        !           736:        uint64 tmp = (uint64)data << (32 - count);
        !           737:        X = C = tmp >> 31;
        !           738:        N = tmp >> 16;
        !           739:        Z = (tmp >> 32) & 0xffff;
        !           740:        V = 0;
        !           741:        return Z;
        !           742: }
        !           743: 
        !           744: // data を count ビット論理右シフトし、XNZVC フラグを反映して結果を返す。
        !           745: // count は 0..63
        !           746: uint32
        !           747: m68030acc::lsr_32(uint32 data, int count)
        !           748: {
        !           749:        if (count == 0) {
        !           750:                move_32(data);
        !           751:                return data;
        !           752:        }
        !           753:        if (count > 32) {
        !           754:                X = C = 0;
        !           755:                move_32(0);
        !           756:                return 0;
        !           757:        }
        !           758:        // data >> count の結果が tmp の上位32ビットに入る
        !           759:        uint64 tmp = (uint64)data << (32 - count);
        !           760:        X = C = tmp >> 31;
        !           761:        Z = N = tmp >> 32;
        !           762:        V = 0;
        !           763:        return Z;
        !           764: }
        !           765: 
        !           766: // data:C を count ビット右ローテートし、NZVC フラグを反映して結果を返す。
        !           767: // count は 0..63
        !           768: uint32
        !           769: m68030acc::roxr_8(uint32 data, int count)
        !           770: {
        !           771:        count %= 9;
        !           772:        if (count == 0) {
        !           773:                Z = data;
        !           774:                N = data << 24;
        !           775:                V = 0;
        !           776:                C = X;
        !           777:                return Z;
        !           778:        }
        !           779:        uint32 rot = data & ((1 << (count - 1)) - 1);
        !           780:        uint32 xbit = X & 1;
        !           781:        Z = (data >> count) | (rot << (9 - count)) | (xbit << (8 - count));
        !           782:        C = X = data >> (count - 1);
        !           783:        N = Z << 24;
        !           784:        V = 0;
        !           785:        return Z;
        !           786: }
        !           787: 
        !           788: // data:C を count ビット右ローテートし、NZVC フラグを反映して結果を返す。
        !           789: // count は 0..63
        !           790: uint32
        !           791: m68030acc::roxr_16(uint32 data, int count)
        !           792: {
        !           793:        count %= 17;
        !           794:        if (count == 0) {
        !           795:                Z = data;
        !           796:                N = data << 16;
        !           797:                V = 0;
        !           798:                C = X;
        !           799:                return Z;
        !           800:        }
        !           801:        uint32 rot = data & ((1 << (count - 1)) - 1);
        !           802:        uint32 xbit = X & 1;
        !           803:        Z = (data >> count) | (rot << (17 - count)) | (xbit << (16 - count));
        !           804:        C = X = data >> (count - 1);
        !           805:        N = Z << 16;
        !           806:        V = 0;
        !           807:        return Z;
        !           808: }
        !           809: 
        !           810: // data:C を count ビット右ローテートし、NZVC フラグを反映して結果を返す。
        !           811: // count は 0..63
        !           812: uint32
        !           813: m68030acc::roxr_32(uint32 data, int count)
        !           814: {
        !           815:        count %= 33;
        !           816:        if (count == 0) {
        !           817:                Z = data;
        !           818:                N = data;
        !           819:                V = 0;
        !           820:                C = X;
        !           821:                return Z;
        !           822:        }
        !           823:        // 32bit値の 32ビットシフトは未定義動作なので 64bit値を使用
        !           824:        uint64 data64 = data;
        !           825:        uint64 rot = data64 & ((1 << (count - 1)) - 1);
        !           826:        uint32 xbit = X & 1;
        !           827:        Z = (data64 >> count) | (rot << (33 - count)) | (xbit << (32 - count));
        !           828:        C = X = data64 >> (count - 1);
        !           829:        N = Z;
        !           830:        V = 0;
        !           831:        return Z;
        !           832: }
        !           833: 
        !           834: // data を count ビット右ローテートし、NZVC フラグを反映して結果を返す。
        !           835: // count は 0..63
        !           836: uint32
        !           837: m68030acc::ror_8(uint32 data, int count)
        !           838: {
        !           839:        if (count == 0) {
        !           840:                move_8(data);
        !           841:                return data;
1.1       root      842:        }
1.1.1.3 ! root      843: 
        !           844:        count %= 8;
        !           845:        uint8 tmp = (data >> count) | (data << (8 - count));
        !           846:        Z = tmp;
        !           847:        N = (uint32)tmp << 24;
        !           848:        // 7 0 1 2 3 4 5 6
        !           849:        C = data >> ((count + 7) % 8);
        !           850:        V = 0;
        !           851:        return tmp;
        !           852: }
        !           853: 
        !           854: // data を count ビット右ローテートし、NZVC フラグを反映して結果を返す。
        !           855: // count は 0..63
        !           856: uint32
        !           857: m68030acc::ror_16(uint32 data, int count)
        !           858: {
        !           859:        if (count == 0) {
        !           860:                move_16(data);
        !           861:                return data;
        !           862:        }
        !           863: 
        !           864:        count %= 16;
        !           865:        uint16 tmp = (data >> count) | (data << (16 - count));
        !           866:        Z = tmp;
        !           867:        N = (uint32)tmp << 16;
        !           868:        C = data >> ((count + 15) % 16);
        !           869:        V = 0;
        !           870:        return tmp;
        !           871: }
        !           872: 
        !           873: // data を count ビット右ローテートし、NZVC フラグを反映して結果を返す。
        !           874: // count は 0..63
        !           875: uint32
        !           876: m68030acc::ror_32(uint32 data, int count)
        !           877: {
        !           878:        if (count == 0) {
        !           879:                move_32(data);
        !           880:                return data;
        !           881:        }
        !           882: 
        !           883:        count %= 32;
        !           884:        uint64 data64 = (uint64)data;
        !           885:        uint64 tmp = (data >> count) | (data << (32 - count));
        !           886:        Z = tmp;
        !           887:        N = tmp;
        !           888:        C = data64 >> ((count + 31) % 32);
        !           889:        V = 0;
        !           890:        return tmp;
1.1       root      891: }
                    892: 
                    893: void
1.1.1.3 ! root      894: m68030acc::chk2cmp2_32(uint32 compare, uint32 lower, uint32 upper)
1.1       root      895: {
                    896:        // 実機の実行結果をじっと睨んだ結果、このロジックで
                    897:        // cmp2 は実行していると考えられる。
                    898:        // オペランド順はフラグに影響する。
                    899:        // なぜ 68k のデザイナが順序を入れ替えたのかは不明。
                    900:        // なんかの都合があったんだろうな...
                    901: 
                    902:        // この cmp は通常の if で代替できるけど、
                    903:        // あえて MPU 内部の動作をエミュレート。
1.1.1.3 ! root      904:        cmp_32(lower, upper);
1.1       root      905: 
1.1.1.3 ! root      906:        if (CondCS()) {
        !           907:                cmp_32(compare, upper);
        !           908:                if (CondEQ()) {
1.1       root      909:                        // break
1.1.1.3 ! root      910:                } else if (CondCS()) {
        !           911:                        cmp_32(lower, compare);
1.1       root      912:                } else {
1.1.1.3 ! root      913:                        cmp_32(compare, lower);
1.1       root      914:                }
                    915:        } else {
1.1.1.3 ! root      916:                cmp_32(lower, compare);
        !           917:                if (CondEQ()) {
1.1       root      918:                        // break
1.1.1.3 ! root      919:                } else if (CondCS()) {
1.1       root      920:                        // break
                    921:                } else {
1.1.1.3 ! root      922:                        cmp_32(compare, upper);
1.1       root      923:                }
                    924:        }
                    925: }
                    926: 
                    927: // src_10 + dst_10 + X を計算し、XNZVC フラグをセットして結果を返す。
                    928: // src, dst の上位ビットはクリアしておくこと。
                    929: // 戻り値の上位ビットはクリアされている。
                    930: uint32
1.1.1.3 ! root      931: m68030acc::abcd_8(uint32 src, uint32 dst)
1.1       root      932: {
                    933:        uint32 res;
                    934:        uint32 tmp;
                    935:        uint32 adj;
                    936:        uint32 low;
1.1.1.3 ! root      937:        uint32 cbit;
1.1       root      938: 
                    939:        adj = 0;
1.1.1.3 ! root      940:        cbit = 0;
1.1       root      941: 
                    942:        // X フラグは LSB なので直接足してよい
1.1.1.3 ! root      943:        tmp = src + dst + (X & X_BIT);
1.1       root      944: 
1.1.1.3 ! root      945:        low = (src & 0x0f) + (dst & 0x0f) + (X & X_BIT);
1.1       root      946:        if (low > 0x09) {
                    947:                adj = 0x06;
                    948:        }
                    949: 
                    950:        if (tmp > 0x99) {
                    951:                adj += 0x60;
1.1.1.3 ! root      952:                cbit = C_BIT;
1.1       root      953:        }
                    954: 
                    955:        res = tmp + adj;
1.1.1.3 ! root      956:        cbit |= res >> 8;
        !           957:        X = C = cbit;
1.1       root      958: 
                    959:        res &= 0xff;
1.1.1.3 ! root      960:        Z |= res;
1.1       root      961: 
                    962:        // V フラグは不定だが 68030 では常にクリア
1.1.1.3 ! root      963:        V = 0;
1.1       root      964:        // N フラグは不定だが 68030 実機合わせ
1.1.1.3 ! root      965:        N = res << 24;
1.1       root      966: 
                    967:        return res;
                    968: }
                    969: 
                    970: // src_10 - dst_10 - X を計算し、XNZVC フラグをセットして結果を返す。
                    971: // src, dst の上位ビットはクリアしておくこと。
                    972: // 戻り値の上位ビットはクリアされている。
                    973: uint32
1.1.1.3 ! root      974: m68030acc::sbcd_8(uint32 src, uint32 dst)
1.1       root      975: {
                    976:        uint32 res;
                    977:        int32 tmp;
                    978:        int32 adj;
                    979:        int32 low;
1.1.1.3 ! root      980:        uint32 cbit;
1.1       root      981: 
                    982:        adj = 0;
1.1.1.3 ! root      983:        cbit = 0;
1.1       root      984: 
                    985:        // X フラグは LSB なので直接引いてよい
1.1.1.3 ! root      986:        tmp = dst - src - (X & X_BIT);
1.1       root      987: 
1.1.1.3 ! root      988:        low = (dst & 0x0f) - (src & 0x0f) - (X & X_BIT);
1.1       root      989:        if (low < 0) {
                    990:                adj = 0x06;
                    991:        }
                    992: 
                    993:        if (tmp < 0) {
                    994:                adj += 0x60;
1.1.1.3 ! root      995:                cbit = C_BIT;
1.1       root      996:        }
                    997: 
                    998:        res = tmp - adj;
1.1.1.3 ! root      999:        cbit |= res >> 8;
        !          1000:        X = C = cbit;
1.1       root     1001: 
                   1002:        res &= 0xff;
1.1.1.3 ! root     1003:        Z |= res;
1.1       root     1004: 
                   1005:        // V フラグは不定だが 68030 では常にクリア
1.1.1.3 ! root     1006:        V = 0;
1.1       root     1007:        // N フラグは不定だが 68030 実機合わせ
1.1.1.3 ! root     1008:        N = res << 24;
1.1       root     1009: 
                   1010:        return res;
                   1011: }

unix.superglobalmegacorp.com

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