Annotation of nono/m88xx0/m88100disasm.cpp, revision 1.1.1.7

1.1       root        1: //
                      2: // nono
1.1.1.2   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
                      7: #include "m88100disasm.h"
1.1.1.2   root        8: #include "m88100acc.h"
1.1       root        9: #include "bus.h"
1.1.1.7 ! root       10: #include "config.h"
1.1       root       11: 
                     12: #define OP_DEF(name)   void __CONCAT(m88100disasm::op_,name)()
                     13: #define OP_FUNC(name)  __CONCAT(op_,name)()
                     14: 
                     15: // コンストラクタ
1.1.1.4   root       16: m88100disasm::m88100disasm(DebuggerMemoryStream& mem_)
                     17:        : inherited(mem_)
1.1       root       18: {
1.1.1.7 ! root       19:        // XXX どこでやるか
        !            20:        use_altname = gConfig->Find(".m88k-altname").AsInt();
1.1       root       21: }
                     22: 
                     23: // デストラクタ
                     24: m88100disasm::~m88100disasm()
                     25: {
                     26: }
                     27: 
                     28: // 逆アセンブルを実行
                     29: bool
1.1.1.4   root       30: m88100disasm::Exec()
1.1       root       31: {
                     32:        ExecInit();
                     33: 
                     34:        opX = 0;
                     35:        name.clear();
                     36:        arg0.clear();
                     37:        arg1.clear();
                     38:        arg2.clear();
1.1.1.7 ! root       39:        altname.clear();
        !            40:        altarg0.clear();
        !            41:        altarg1.clear();
        !            42:        altarg2.clear();
1.1       root       43: 
1.1.1.4   root       44:        xip = (uint32)mem.laddr;
1.1       root       45: 
1.1.1.4   root       46:        opX = mem.FetchInst();
                     47:        uint32 op12 = m88kcpu::op32_to_12(opX);
1.1       root       48:        switch (op12) {
                     49: #include "m88100switch.inc"
                     50:         default:
1.1.1.2   root       51:                name = "illegal";
                     52:                break;
                     53:                //OP_FUNC(illegal);
1.1       root       54:        }
                     55: 
                     56:        // 出力文字列(ダンプ)
                     57:        dump = string_format("%08x ", opX);
                     58: 
                     59:        // 出力文字列(命令)
                     60:        text = name;
                     61:        if (!arg0.empty() || !arg1.empty() || !arg2.empty()) {
                     62:                // オペランドがどれかでもあればインデントする
                     63:                int len = text.length();
                     64:                if (len < 8) {
                     65:                        text += std::string(8 - len, ' ');
                     66:                } else {
                     67:                        text += ' ';
                     68:                }
                     69: 
                     70:                // arg0,1,2 の空でないやつを追加
                     71:                std::string args;
                     72:                if (!arg0.empty()) {
                     73:                        args += arg0;
                     74:                }
                     75:                if (!arg1.empty()) {
                     76:                        if (!args.empty()) {
                     77:                                args += ",";
1.1.1.6   root       78:                                while (args.length() % 4 != 0)
1.1       root       79:                                        args += " ";
                     80:                        }
                     81:                        args += arg1;
                     82:                }
                     83:                if (!arg2.empty()) {
                     84:                        if (!args.empty()) {
                     85:                                args += ",";
1.1.1.6   root       86:                                while (args.length() % 4 != 0)
1.1       root       87:                                        args += " ";
                     88:                        }
                     89:                        args += arg2;
                     90:                }
                     91: 
                     92:                text += args;
                     93:        }
                     94: 
1.1.1.7 ! root       95:        // 出力文字列(別名)
        !            96:        if (use_altname && !altname.empty()) {
        !            97:                if (altarg1.empty() && !altarg2.empty()) {
        !            98:                        altarg1 = altarg2;
        !            99:                        altarg2.clear();
        !           100:                }
        !           101:                // {mov rn, rn} -> {nop} は無条件に置換できるのでここでやる
        !           102:                if (altname == "mov" && altarg0 == altarg1 && altarg2.empty()) {
        !           103:                        altname = "nop";
        !           104:                        altarg0.clear();
        !           105:                        altarg1.clear();
        !           106:                }
        !           107: 
        !           108:                alttext += "{" + altname;
        !           109: 
        !           110:                if (!altarg0.empty() || !altarg1.empty() || !altarg2.empty()) {
        !           111:                        // オペランドがあればインデントする
        !           112:                        int len = alttext.length();
        !           113:                        if (len < 8) {
        !           114:                                alttext += std::string(8 - len, ' ');
        !           115:                        } else {
        !           116:                                alttext += ' ';
        !           117:                        }
        !           118: 
        !           119:                        // altarg0,1,2 の空でないやつを追加
        !           120:                        std::string altargs;
        !           121:                        if (!altarg0.empty()) {
        !           122:                                altargs += altarg0;
        !           123:                        }
        !           124:                        if (!altarg1.empty()) {
        !           125:                                if (!altargs.empty()) {
        !           126:                                        altargs += ',';
        !           127:                                        while (altargs.length() % 4 != 0)
        !           128:                                                altargs += ' ';
        !           129:                                }
        !           130:                                altargs += altarg1;
        !           131:                        }
        !           132:                        if (!altarg2.empty()) {
        !           133:                                if (!altargs.empty()) {
        !           134:                                        altargs += ',';
        !           135:                                        while (altargs.length() % 4 != 0)
        !           136:                                                altargs += ' ';
        !           137:                                }
        !           138:                                altargs += altarg2;
        !           139:                        }
        !           140: 
        !           141:                        alttext += altargs;
        !           142:                }
        !           143:                alttext += '}';
        !           144:        }
        !           145: 
1.1       root      146:        // 出力バイナリ列
                    147:        // bin は vector<uint8>。
                    148:        bin.push_back( opX >> 24);
                    149:        bin.push_back((opX >> 16) & 0xff);
                    150:        bin.push_back((opX >>  8) & 0xff);
                    151:        bin.push_back( opX        & 0xff);
                    152: 
                    153:        return true;
                    154: }
                    155: 
                    156: // フィールド部品
1.1.1.7 ! root      157: #define DD             ((opX >> 21) & 0x1f)
        !           158: #define S1             ((opX >> 16) & 0x1f)
        !           159: #define S2             ( opX        & 0x1f)
1.1       root      160: #define B5             ((opX >> 21) & 0x1f)
                    161: #define M5             ((opX >> 21) & 0x1f)
                    162: #define W5             ((opX >>  5) & 0x1f)
                    163: #define O5             ((opX      ) & 0x1f)
1.1.1.7 ! root      164: #define CIO            ((opX >>  8) & 0x03)
        !           165: #define IMM16  (opX & 0x0000ffffU)
1.1       root      166: #define VEC9   (opX & 0x000001ffU)
                    167: #define D16            (((int32)(int16)opX) << 2)
                    168: #define D26            (((int32)(opX << 6)) >> 4)
                    169: 
                    170: std::string
                    171: m88100disasm::rd()
                    172: {
                    173:        return string_format("r%d", (opX >> 21) & 0x1f);
                    174: }
                    175: 
                    176: std::string
                    177: m88100disasm::rs1()
                    178: {
                    179:        return string_format("r%d", (opX >> 16) & 0x1f);
                    180: }
                    181: 
                    182: std::string
                    183: m88100disasm::rs2()
                    184: {
                    185:        return string_format("r%d", (opX      ) & 0x1f);
                    186: }
                    187: 
                    188: std::string
                    189: m88100disasm::imm16()
                    190: {
                    191:        return string_format("#0x%04x", (opX & 0x0000ffff));
                    192: }
                    193: 
                    194: std::string
                    195: m88100disasm::d16()
                    196: {
                    197:        return string_format("0x%08x", xip + D16);
                    198: }
                    199: 
1.1.1.6   root      200: std::string
                    201: m88100disasm::d26()
                    202: {
                    203:        return string_format("0x%08x", xip + D26);
                    204: }
                    205: 
1.1       root      206: // 制御レジスタ名
                    207: std::string
                    208: m88100disasm::crs()
                    209: {
1.1.1.2   root      210:        // CRS フィールドは 6 bit。ただし CR20 までしか存在しない
1.1       root      211:        uint32 cr = (opX >> 5) & 0x3f;
                    212:        static const char *crnames[] = {
                    213:                "pid",  "psr",  "epsr", "ssbr",         // cr0..3
                    214:                "sxip", "snip", "sfip", "vbr",          // cr4..7
                    215:                "dmt0", "dmd0", "dma0",                         // cr8..10
                    216:                "dmt1", "dmd1", "dma1",                         // cr11..13
                    217:                "dmt2", "dmd2", "dma2",                         // cr14..16
1.1.1.2   root      218:                "sr0",  "sr1",  "sr2",  "sr3",          // cr17..20
1.1       root      219:        };
                    220: 
                    221:        if (cr < countof(crnames)) {
                    222:                return std::string(crnames[cr]);
                    223:        } else {
                    224:                return string_format("cr%d", cr);       // こうなのか?
                    225:        }
                    226: }
                    227: 
                    228: // FPU 制御レジスタ名
                    229: std::string
                    230: m88100disasm::fcrs()
                    231: {
                    232:        uint32 cr = (opX >> 5) & 0x3f;
                    233:        static const char *fcrnames[] = {
                    234:                "fpecr",        // fcr0
                    235:                "fphs1",        // fcr1
                    236:                "fpls1",        // fcr2
                    237:                "fphs2",        // fcr3
                    238:                "fpls2",        // fcr4
                    239:                "fppt",         // fcr5
                    240:                "fprh",         // fcr6
                    241:                "fprl",         // fcr7
                    242:                "fpit",         // fcr8
                    243:        };
                    244:        if (cr < countof(fcrnames)) {
                    245:                return std::string(fcrnames[cr]);
                    246:        } else if (cr == 62) {
                    247:                return "fpsr";
                    248:        } else if (cr == 63) {
                    249:                return "fpcr";
                    250:        } else {
                    251:                return string_format("fcr%d", cr);
                    252:        }
                    253: }
                    254: 
                    255: #define TD     (5)
                    256: #define T1     (9)
                    257: #define T2     (7)
                    258: 
                    259: // FPU サイズサフィックス t は TD、T1、T2
                    260: std::string
                    261: m88100disasm::fsize(uint32 t)
                    262: {
                    263:        uint32 sz = (opX >> t) & 3;
                    264:        return sz == 1 ? "d" : "s";
                    265: }
                    266: 
                    267: // FPU サイズサフィックス (全部入り)
                    268: std::string
                    269: m88100disasm::fsize()
                    270: {
                    271:        return fsize(TD) + fsize(T1) + fsize(T2);
                    272: }
                    273: 
                    274: // "Width<Offset>"
                    275: std::string
                    276: m88100disasm::wo5()
                    277: {
                    278:        uint32 w5 = W5 ?: 32;
                    279:        uint32 o5 = O5;
                    280:        return string_format("%d<%d>", w5, o5);
                    281: }
                    282: 
                    283: // キャリーサフィックス
                    284: std::string
                    285: m88100disasm::cio()
                    286: {
                    287:        uint32 c = (opX >> 8) & 3;
                    288:        static const char *carrystr[] = {
                    289:                "",
                    290:                ".co",
1.1.1.2   root      291:                ".ci",
1.1       root      292:                ".cio",
                    293:        };
                    294:        return std::string(carrystr[c]);
                    295: }
                    296: 
                    297: std::string
                    298: m88100disasm::b5()
                    299: {
                    300:        return string_format("#%d", B5);
                    301: }
                    302: 
                    303: std::string
                    304: m88100disasm::m5()
                    305: {
                    306:        uint32 m = M5;
                    307:        switch (m) {
                    308:         case 0x02:     return "eq0";
                    309:         case 0x0d:     return "ne0";
                    310:         case 0x01:     return "gt0";
                    311:         case 0x0c:     return "lt0";
                    312:         case 0x03:     return "ge0";
                    313:         case 0x0e:     return "le0";
                    314:         default:
                    315:                break;
                    316:        }
                    317:        return string_format("0x%02x", m);      // ?
                    318: }
                    319: 
                    320: std::string
                    321: m88100disasm::vec9()
                    322: {
                    323:        return string_format("#0x%03x", VEC9);
                    324: }
                    325: 
                    326: // エミュレータ的未実装 (最終的にはなくなる)
                    327: void
                    328: m88100disasm::op_unimpl()
                    329: {
                    330:        name = "unimplemented";
                    331: }
                    332: 
1.1.1.6   root      333: // ld_imm, st_imm, xmem_imm の共通部
                    334: // namebase にはサイズプレフィックスを含む。
                    335: void
                    336: m88100disasm::ops_ldst_imm(const std::string& namebase)
1.1       root      337: {
1.1.1.6   root      338:        name = namebase;
1.1       root      339:        arg0 = rd();
                    340:        arg1 = rs1();
                    341:        arg2 = imm16();
1.1.1.7 ! root      342: 
        !           343:        altname = namebase;
        !           344:        altarg0 = rd();
        !           345:        if (IMM16 == 0) {
        !           346:                altarg1 = rs1();
        !           347:        } else {
        !           348:                altarg1 = rs1() + "," + imm16();
        !           349:        }
        !           350:        // 3文字目が 'a' になるのは lda しかない
        !           351:        if (namebase[2] != 'a') {
        !           352:                altarg1 = "(" + altarg1 + ")";
        !           353:        }
1.1       root      354: }
                    355: 
1.1.1.6   root      356: // 000000_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    357: OP_DEF(xmem_bu_imm)
                    358: {
                    359:        ops_ldst_imm("xmem.bu");
                    360: }
                    361: 
1.1       root      362: // 000001_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    363: OP_DEF(xmem_w_imm)
                    364: {
1.1.1.6   root      365:        ops_ldst_imm("xmem");
1.1       root      366: }
                    367: 
                    368: // 000010_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    369: OP_DEF(ld_hu_imm)
                    370: {
1.1.1.6   root      371:        ops_ldst_imm("ld.hu");
1.1       root      372: }
                    373: 
                    374: // 000011_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    375: OP_DEF(ld_bu_imm)
                    376: {
1.1.1.6   root      377:        ops_ldst_imm("ld.bu");
1.1       root      378: }
                    379: 
                    380: // 000100_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    381: OP_DEF(ld_d_imm)
                    382: {
1.1.1.6   root      383:        ops_ldst_imm("ld.d");
1.1       root      384: }
                    385: 
                    386: // 000101_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    387: OP_DEF(ld_w_imm)
                    388: {
1.1.1.6   root      389:        ops_ldst_imm("ld");
1.1       root      390: }
                    391: 
                    392: // 000110_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    393: OP_DEF(ld_h_imm)
                    394: {
1.1.1.6   root      395:        ops_ldst_imm("ld.h");
1.1       root      396: }
                    397: 
                    398: // 000111_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    399: OP_DEF(ld_b_imm)
                    400: {
1.1.1.6   root      401:        ops_ldst_imm("ld.b");
1.1       root      402: }
                    403: 
                    404: // 001000_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    405: OP_DEF(st_d_imm)
                    406: {
1.1.1.6   root      407:        ops_ldst_imm("st.d");
1.1       root      408: }
                    409: 
                    410: // 001001_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    411: OP_DEF(st_w_imm)
                    412: {
1.1.1.6   root      413:        ops_ldst_imm("st");
1.1       root      414: }
                    415: 
                    416: // 001010_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    417: OP_DEF(st_h_imm)
                    418: {
1.1.1.6   root      419:        ops_ldst_imm("st.h");
1.1       root      420: }
                    421: 
                    422: // 001011_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    423: OP_DEF(st_b_imm)
                    424: {
1.1.1.6   root      425:        ops_ldst_imm("st.b");
1.1       root      426: }
                    427: 
                    428: // 001100_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    429: OP_DEF(lda_d_imm)
                    430: {
1.1.1.6   root      431:        ops_ldst_imm("lda.d");
1.1       root      432: }
                    433: 
                    434: // 001101_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    435: OP_DEF(lda_w_imm)
                    436: {
1.1.1.6   root      437:        ops_ldst_imm("lda");
1.1       root      438: }
                    439: 
                    440: // 001110_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    441: OP_DEF(lda_h_imm)
                    442: {
1.1.1.6   root      443:        ops_ldst_imm("lda.h");
1.1       root      444: }
                    445: 
                    446: // 001111_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    447: OP_DEF(lda_b_imm)
                    448: {
1.1.1.6   root      449:        ops_ldst_imm("lda.b");
1.1       root      450: }
                    451: 
                    452: // 010000_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    453: OP_DEF(and_imm)
                    454: {
                    455:        name = "and";
                    456:        arg0 = rd();
                    457:        arg1 = rs1();
                    458:        arg2 = imm16();
1.1.1.7 ! root      459: 
        !           460:        // rd s1 imm
        !           461:        // ----------
        !           462:        // r0 *  *              nop
        !           463:        // rd r0 #imm   clr     rd
        !           464:        // rd rd #imm   and rd, #ffff'imm
        !           465:        // rd s1 #imm   and rd, s1, #ffff'imm
        !           466: 
        !           467:        if (DD == 0) {
        !           468:                altname = "nop";
        !           469:        } else if (S1 == 0) {
        !           470:                altname = "clr";
        !           471:                altarg0 = rd();
        !           472:        } else {
        !           473:                altname = "and";
        !           474:                altarg0 = rd();
        !           475:                if (DD != S1) {
        !           476:                        altarg1 = rs1();
        !           477:                }
        !           478:                altarg2 = string_format("#0xffff%04x", IMM16);
        !           479:        }
1.1       root      480: }
                    481: 
                    482: // 010001_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    483: OP_DEF(and_u_imm)
                    484: {
                    485:        name = "and.u";
                    486:        arg0 = rd();
                    487:        arg1 = rs1();
                    488:        arg2 = imm16();
1.1.1.7 ! root      489: 
        !           490:        // rd s1 imm
        !           491:        // ----------
        !           492:        // r0 *  *              nop
        !           493:        // rd r0 #imm   clr     rd
        !           494:        // rd rd #imm   and rd, #imm'ffff
        !           495:        // rd s1 #imm   and rd, s1, #imm'ffff
        !           496: 
        !           497:        if (DD == 0) {
        !           498:                altname = "nop";
        !           499:        } else if (S1 == 0) {
        !           500:                altname = "clr";
        !           501:                altarg0 = rd();
        !           502:        } else {
        !           503:                altname = "and";
        !           504:                altarg0 = rd();
        !           505:                if (DD != S1) {
        !           506:                        altarg1 = rs1();
        !           507:                }
        !           508:                altarg2 = imm16() + "ffff";
        !           509:        }
1.1       root      510: }
                    511: 
                    512: // 010010_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    513: OP_DEF(mask_imm)
                    514: {
                    515:        name = "mask";
                    516:        arg0 = rd();
                    517:        arg1 = rs1();
                    518:        arg2 = imm16();
1.1.1.7 ! root      519: 
        !           520:        // rd s1 imm
        !           521:        // ----------
        !           522:        // r0 *  *              nop
        !           523:        // rd r0 #imm   clr rd
        !           524:        // rd rd #imm   and rd, #0000'imm
        !           525:        // rd s1 #imm   and rd, s1, #0000'imm
        !           526: 
        !           527:        if (DD == 0) {
        !           528:                altname = "nop";
        !           529:        } else if (S1 == 0) {
        !           530:                altname = "clr";
        !           531:                altarg0 = rd();
        !           532:        } else {
        !           533:                altname = "and";
        !           534:                altarg0 = rd();
        !           535:                if (DD != S1) {
        !           536:                        altarg1 = rs1();
        !           537:                }
        !           538:                altarg2 = string_format("#0x0000%04x", IMM16);
        !           539:        }
1.1       root      540: }
                    541: 
                    542: // 010011_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    543: OP_DEF(mask_u_imm)
                    544: {
                    545:        name = "mask.u";
                    546:        arg0 = rd();
                    547:        arg1 = rs1();
                    548:        arg2 = imm16();
1.1.1.7 ! root      549: 
        !           550:        // rd s1 imm
        !           551:        // ----------
        !           552:        // r0 *  *              nop
        !           553:        // rd r0 #imm   clr rd
        !           554:        // rd rd #imm   and rd, #imm'0000
        !           555:        // rd s1 #imm   and rd, s1, #imm'0000
        !           556: 
        !           557:        if (DD == 0) {
        !           558:                altname = "nop";
        !           559:        } else if (S1 == 0) {
        !           560:                altname = "clr";
        !           561:                altarg0 = rd();
        !           562:        } else {
        !           563:                altname = "and";
        !           564:                altarg0 = rd();
        !           565:                if (DD != S1) {
        !           566:                        altarg1 = rs1();
        !           567:                }
        !           568:                altarg2 = imm16() + "0000";
        !           569:        }
1.1       root      570: }
                    571: 
                    572: // 010100_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    573: OP_DEF(xor_imm)
                    574: {
                    575:        name = "xor";
                    576:        arg0 = rd();
                    577:        arg1 = rs1();
                    578:        arg2 = imm16();
1.1.1.7 ! root      579: 
        !           580:        // rd s1 imm
        !           581:        // ----------
        !           582:        // r0 *  *              nop
        !           583:        // rd r0 #imm   mov     rd, #imm
        !           584:        // rd rd #imm   xor rd, #imm
        !           585:        // rd s1 #imm   xor rd, s1, #imm
        !           586: 
        !           587:        if (DD == 0) {
        !           588:                altname = "nop";
        !           589:        } else if (S1 == 0) {
        !           590:                altname = "mov";
        !           591:                altarg0 = rd();
        !           592:                altarg1 = imm16();
        !           593:        } else {
        !           594:                altname = "xor";
        !           595:                altarg0 = rd();
        !           596:                if (DD != S1) {
        !           597:                        altarg1 = rs1();
        !           598:                }
        !           599:                altarg2 = imm16();
        !           600:        }
1.1       root      601: }
                    602: 
                    603: // 010101_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    604: OP_DEF(xor_u_imm)
                    605: {
                    606:        name = "xor.u";
                    607:        arg0 = rd();
                    608:        arg1 = rs1();
                    609:        arg2 = imm16();
1.1.1.7 ! root      610: 
        !           611:        // rd s1 imm
        !           612:        // ----------
        !           613:        // r0 *  *              nop
        !           614:        // rd r0 #imm   mov     rd, #imm'0000
        !           615:        // rd rd #imm   xor rd, #imm'0000
        !           616:        // rd s1 #imm   xor rd, s1, #imm'0000
        !           617: 
        !           618:        if (DD == 0) {
        !           619:                altname = "nop";
        !           620:        } else if (S1 == 0) {
        !           621:                altname = "mov";
        !           622:                altarg0 = rd();
        !           623:                altarg1 = imm16() + "0000";
        !           624:        } else {
        !           625:                altname = "xor";
        !           626:                altarg0 = rd();
        !           627:                if (DD != S1) {
        !           628:                        altarg1 = rs1();
        !           629:                }
        !           630:                altarg2 = imm16() + "0000";
        !           631:        }
1.1       root      632: }
                    633: 
                    634: // 010110_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    635: OP_DEF(or_imm)
                    636: {
                    637:        name = "or";
                    638:        arg0 = rd();
                    639:        arg1 = rs1();
                    640:        arg2 = imm16();
1.1.1.7 ! root      641: 
        !           642:        // rd s1 imm
        !           643:        // ----------
        !           644:        // r0 *  *              nop
        !           645:        // rd r0 #imm   mov rd, #imm
        !           646:        // rd rd #imm   or      rd, #imm
        !           647:        // rd s1 #imm   or      rd, s1, #imm
        !           648: 
        !           649:        if (DD == 0) {
        !           650:                altname = "nop";
        !           651:        } else if (S1 == 0) {
        !           652:                altname = "mov";
        !           653:                altarg0 = rd();
        !           654:                altarg1 = imm16();
        !           655:        } else {
        !           656:                altname = "or";
        !           657:                altarg0 = rd();
        !           658:                if (DD != S1) {
        !           659:                        altarg1 = rs1();
        !           660:                }
        !           661:                altarg2 = imm16();
        !           662:        }
1.1       root      663: }
                    664: 
                    665: // 010111_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    666: OP_DEF(or_u_imm)
                    667: {
                    668:        name = "or.u";
                    669:        arg0 = rd();
                    670:        arg1 = rs1();
                    671:        arg2 = imm16();
1.1.1.7 ! root      672: 
        !           673:        // rd s1 imm
        !           674:        // ----------
        !           675:        // r0 *  *              nop
        !           676:        // rd r0 #imm   mov rd, #imm'0000
        !           677:        // rd rd #imm   or      rd, #imm'0000
        !           678:        // rd s1 #imm   or      rd, s1, #imm'0000
        !           679: 
        !           680:        if (DD == 0) {
        !           681:                altname = "nop";
        !           682:        } else if (S1 == 0) {
        !           683:                altname = "mov";
        !           684:                altarg0 = rd();
        !           685:                altarg1 = imm16() + "0000";
        !           686:        } else {
        !           687:                altname = "or";
        !           688:                altarg0 = rd();
        !           689:                if (DD != S1) {
        !           690:                        altarg1 = rs1();
        !           691:                }
        !           692:                altarg2 = imm16() + "0000";
        !           693:        }
1.1       root      694: }
                    695: 
                    696: // 011000_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    697: OP_DEF(addu_imm)
                    698: {
                    699:        name = "addu";
                    700:        arg0 = rd();
                    701:        arg1 = rs1();
                    702:        arg2 = imm16();
1.1.1.7 ! root      703: 
        !           704:        // rd s1 imm
        !           705:        // ----------
        !           706:        // r0 *  *              nop
        !           707:        // rd r0 #imm   mov  rd, #0000'imm
        !           708:        // rd rd #imm   addu rd, #0000'imm
        !           709:        // rd s1 #imm   addu rd, s1, #0000'imm
        !           710: 
        !           711:        if (DD == 0) {
        !           712:                altname = "nop";
        !           713:        } else if (S1 == 0) {
        !           714:                altname = "mov";
        !           715:                altarg0 = rd();
        !           716:                altarg1 = string_format("#0x0000%04x", IMM16);
        !           717:        } else {
        !           718:                altname = "addu";
        !           719:                altarg0 = rd();
        !           720:                if (DD != S1) {
        !           721:                        altarg1 = rs1();
        !           722:                }
        !           723:                altarg2 = string_format("#0x0000%04x", IMM16);
        !           724:        }
1.1       root      725: }
                    726: 
                    727: // 011001_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    728: OP_DEF(subu_imm)
                    729: {
                    730:        name = "subu";
                    731:        arg0 = rd();
                    732:        arg1 = rs1();
                    733:        arg2 = imm16();
1.1.1.7 ! root      734: 
        !           735:        // rd s1 imm
        !           736:        // ----------
        !           737:        // r0 *  *              nop
        !           738:        // rd r0 #imm   mov  rd, #-imm
        !           739:        // rd rd #imm   subu rd, #0000'imm
        !           740:        // rd s1 #imm   subu rd, s1, #0000'imm
        !           741: 
        !           742:        if (DD == 0) {
        !           743:                altname = "nop";
        !           744:        } else if (S1 == 0) {
        !           745:                altname = "mov";
        !           746:                altarg0 = rd();
        !           747:                altarg1 = string_format("#0x%08x", -(int32)(uint32)IMM16);
        !           748:        } else {
        !           749:                altname = "subu";
        !           750:                altarg0 = rd();
        !           751:                if (DD != S1) {
        !           752:                        altarg1 = rs1();
        !           753:                }
        !           754:                altarg2 = string_format("#0x0000%04x", IMM16);
        !           755:        }
1.1       root      756: }
                    757: 
                    758: // 011010_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    759: OP_DEF(divu_imm)
                    760: {
                    761:        name = "divu";
                    762:        arg0 = rd();
                    763:        arg1 = rs1();
                    764:        arg2 = imm16();
1.1.1.7 ! root      765: 
        !           766:        // 例外発生の可能性があるので r0 を含んでいたとしても別名にしない
        !           767:        altname = "divu";
        !           768:        altarg0 = rd();
        !           769:        if (DD != S1) {
        !           770:                altarg1 = rs1();
        !           771:        }
        !           772:        altarg2 = string_format("#0x0000%04x", IMM16);
1.1       root      773: }
                    774: 
                    775: // 011011_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    776: OP_DEF(mul_imm)
                    777: {
                    778:        name = "mul";
                    779:        arg0 = rd();
                    780:        arg1 = rs1();
                    781:        arg2 = imm16();
1.1.1.7 ! root      782: 
        !           783:        // 例外発生の可能性があるので r0 を含んでいたとしても別名にしない
        !           784:        altname = "mul";
        !           785:        altarg0 = rd();
        !           786:        if (DD != S1) {
        !           787:                altarg1 = rs1();
        !           788:        }
        !           789:        altarg2 = string_format("#0x0000%04x", IMM16);
1.1       root      790: }
                    791: 
                    792: // 011100_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    793: OP_DEF(add_imm)
                    794: {
                    795:        name = "add";
                    796:        arg0 = rd();
                    797:        arg1 = rs1();
                    798:        arg2 = imm16();
1.1.1.7 ! root      799: 
        !           800:        // 例外発生の可能性があるので r0 を含んでいたとしても別名にしない
        !           801:        altname = "adds";
        !           802:        altarg0 = rd();
        !           803:        if (DD != S1) {
        !           804:                altarg1 = rs1();
        !           805:        }
        !           806:        altarg2 = string_format("#0x0000%04x", IMM16);
1.1       root      807: }
                    808: 
                    809: // 011101_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    810: OP_DEF(sub_imm)
                    811: {
                    812:        name = "sub";
                    813:        arg0 = rd();
                    814:        arg1 = rs1();
                    815:        arg2 = imm16();
1.1.1.7 ! root      816: 
        !           817:        // 例外発生の可能性があるので r0 を含んでいたとしても別名にしない
        !           818:        altname = "subs";
        !           819:        altarg0 = rd();
        !           820:        if (DD != S1) {
        !           821:                altarg1 = rs1();
        !           822:        }
        !           823:        altarg2 = string_format("#0x0000%04x", IMM16);
1.1       root      824: }
                    825: 
                    826: // 011110_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    827: OP_DEF(div_imm)
                    828: {
                    829:        name = "div";
                    830:        arg0 = rd();
                    831:        arg1 = rs1();
                    832:        arg2 = imm16();
1.1.1.7 ! root      833: 
        !           834:        // 例外発生の可能性があるので r0 を含んでいたとしても別名にしない
        !           835:        altname = "div";
        !           836:        altarg0 = rd();
        !           837:        if (DD != S1) {
        !           838:                altarg1 = rs1();
        !           839:        }
        !           840:        altarg2 = string_format("#0x0000%04x", IMM16);
1.1       root      841: }
                    842: 
                    843: // 011111_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
                    844: OP_DEF(cmp_imm)
                    845: {
                    846:        name = "cmp";
                    847:        arg0 = rd();
                    848:        arg1 = rs1();
                    849:        arg2 = imm16();
1.1.1.7 ! root      850: 
        !           851:        if (DD == 0) {
        !           852:                altname = "nop";
        !           853:        } else {
        !           854:                altname = "cmp";
        !           855:                altarg0 = rd();
        !           856:                altarg1 = rs1();
        !           857:                altarg2 = string_format("#0x0000%04x", IMM16);
        !           858:        }
1.1       root      859: }
                    860: 
                    861: // 100000_DDDDDzzzzz_01000n_nnnnnzzzzz
                    862: OP_DEF(ldcr)
                    863: {
                    864:        name = "ldcr";
                    865:        arg0 = rd();
                    866:        arg1 = crs();
                    867: }
                    868: 
                    869: // 100000_DDDDDzzzzz_01001n_nnnnnzzzzz
                    870: OP_DEF(fldcr)
                    871: {
                    872:        name = "fldcr";
                    873:        arg0 = rd();
                    874:        arg1 = fcrs();
                    875: }
                    876: 
                    877: // 100000_zzzzzSSSSS_10000n_nnnnnsssss
                    878: OP_DEF(stcr)
                    879: {
                    880:        uint32 s1 = (opX >> 16) & 0x1f;
                    881:        uint32 s2 = (opX      ) & 0x1f;
                    882:        if (s1 == s2) {
                    883:                name = "stcr";
                    884:                arg1 = rs1();
                    885:                arg2 = crs();
                    886:        } else {
                    887:                // どうすべ
                    888:                OP_FUNC(unimpl);
                    889:        }
                    890: }
                    891: 
                    892: // 100000_zzzzzSSSSS_10001n_nnnnnsssss
                    893: OP_DEF(fstcr)
                    894: {
                    895:        uint32 s1 = (opX >> 16) & 0x1f;
                    896:        uint32 s2 = (opX      ) & 0x1f;
                    897:        if (s1 == s2) {
                    898:                name = "fstcr";
                    899:                arg1 = rs1();
                    900:                arg2 = fcrs();
                    901:        } else {
                    902:                // どうすべ
                    903:                OP_FUNC(unimpl);
                    904:        }
                    905: }
                    906: 
                    907: // 100000_DDDDDSSSSS_11000n_nnnnnsssss
                    908: OP_DEF(xcr)
                    909: {
                    910:        uint32 s1 = (opX >> 16) & 0x1f;
                    911:        uint32 s2 = (opX      ) & 0x1f;
                    912:        if (s1 == s2) {
                    913:                name = "xcr";
                    914:                arg0 = rd();
                    915:                arg1 = rs1();
1.1.1.2   root      916:                arg2 = crs();
1.1       root      917:        } else {
                    918:                // どうすべ
                    919:                OP_FUNC(unimpl);
                    920:        }
                    921: }
                    922: 
                    923: // 100000_DDDDDSSSSS_11001n_nnnnnsssss
                    924: OP_DEF(fxcr)
                    925: {
                    926:        uint32 s1 = (opX >> 16) & 0x1f;
                    927:        uint32 s2 = (opX      ) & 0x1f;
                    928:        if (s1 == s2) {
                    929:                name = "fxcr";
                    930:                arg0 = rd();
                    931:                arg1 = rs1();
                    932:                arg2 = fcrs();
                    933:        } else {
                    934:                // どうすべ
                    935:                OP_FUNC(unimpl);
                    936:        }
                    937: }
                    938: 
                    939: // 100001_DDDDDSSSSS_00000n_nnnnnsssss
                    940: OP_DEF(fmul)
                    941: {
                    942:        name = "fmul." + fsize();
                    943:        arg0 = rd();
                    944:        arg1 = rs1();
                    945:        arg2 = rs2();
                    946: }
                    947: 
                    948: // 100001_DDDDD00000_001000_000nnsssss
                    949: OP_DEF(flt)
                    950: {
                    951:        name = "flt." + fsize(TD) + "s";
                    952:        arg0 = rd();
                    953:        arg2 = rs2();
                    954: }
                    955: 
                    956: // 100001_DDDDDSSSSS_00101n_nnnnnsssss
                    957: OP_DEF(fadd)
                    958: {
                    959:        name = "fadd." + fsize();
                    960:        arg0 = rd();
                    961:        arg1 = rs1();
                    962:        arg2 = rs2();
                    963: }
                    964: 
                    965: // 100001_DDDDDSSSSS_00110n_nnnnnsssss
                    966: OP_DEF(fsub)
                    967: {
                    968:        name = "fsub." + fsize();
                    969:        arg0 = rd();
                    970:        arg1 = rs1();
                    971:        arg2 = rs2();
                    972: }
                    973: 
                    974: // 100001_DDDDDSSSSS_00111n_nnnnnsssss
                    975: OP_DEF(fcmp)
                    976: {
                    977:        name = "fcmp.s" + fsize(T1) + fsize(T2);
                    978:        arg0 = rd();
                    979:        arg1 = rs1();
                    980:        arg2 = rs2();
                    981: }
                    982: 
                    983: // 100001_DDDDD00000_010010_0nn00sssss
                    984: OP_DEF(int)
                    985: {
                    986:        name = "int.s" + fsize(T2);
                    987:        arg0 = rd();
                    988:        arg1 = rs2();
                    989: }
                    990: 
                    991: // 100001_DDDDD00000_010100_0nn00sssss
                    992: OP_DEF(nint)
                    993: {
                    994:        name = "nint.s" + fsize(T2);
                    995:        arg0 = rd();
                    996:        arg1 = rs2();
                    997: }
                    998: 
                    999: // 100001_DDDDD00000_010110_0nn00sssss
                   1000: OP_DEF(trnc)
                   1001: {
                   1002:        name = "trnc.s" + fsize(T2);
                   1003:        arg0 = rd();
                   1004:        arg2 = rs2();
                   1005: }
                   1006: 
                   1007: // 100001_DDDDDSSSSS_01110n_nnnnnsssss
                   1008: OP_DEF(fdiv)
                   1009: {
                   1010:        name = "fdiv." + fsize();
                   1011:        arg0 = rd();
                   1012:        arg1 = rs1();
                   1013:        arg2 = rs2();
                   1014: }
                   1015: 
                   1016: // 110000_nnnnnnnnnn_nnnnnn_nnnnnnnnnn
                   1017: OP_DEF(br)
                   1018: {
                   1019:        name = "br";
1.1.1.6   root     1020:        arg0 = d26();
1.1       root     1021: }
                   1022: 
                   1023: // 110001_nnnnnnnnnn_nnnnnn_nnnnnnnnnn
                   1024: OP_DEF(br_n)
                   1025: {
                   1026:        name = "br.n";
1.1.1.6   root     1027:        arg0 = d26();
1.1       root     1028: }
                   1029: 
                   1030: // 110010_nnnnnnnnnn_nnnnnn_nnnnnnnnnn
                   1031: OP_DEF(bsr)
                   1032: {
                   1033:        name = "bsr";
1.1.1.6   root     1034:        arg0 = d26();
1.1       root     1035: }
                   1036: 
                   1037: // 110011_nnnnnnnnnn_nnnnnn_nnnnnnnnnn
                   1038: OP_DEF(bsr_n)
                   1039: {
                   1040:        name = "bsr.n";
1.1.1.6   root     1041:        arg0 = d26();
1.1       root     1042: }
                   1043: 
                   1044: // bb の共通部
                   1045: void
                   1046: m88100disasm::ops_bb(std::string namebase)
                   1047: {
                   1048:        name = namebase;
                   1049:        arg0 = b5();
                   1050:        arg1 = rs1();
                   1051:        arg2 = d16();
                   1052: }
                   1053: 
                   1054: // 110100_nnnnnSSSSS_nnnnnn_nnnnnnnnnn
                   1055: OP_DEF(bb0)
                   1056: {
                   1057:        ops_bb("bb0");
                   1058: }
                   1059: 
                   1060: // 110101_nnnnnSSSSS_nnnnnn_nnnnnnnnnn
                   1061: OP_DEF(bb0_n)
                   1062: {
                   1063:        ops_bb("bb0.n");
                   1064: }
                   1065: 
                   1066: // 110110_nnnnnSSSSS_nnnnnn_nnnnnnnnnn
                   1067: OP_DEF(bb1)
                   1068: {
                   1069:        ops_bb("bb1");
                   1070: }
                   1071: 
                   1072: // 110111_nnnnnSSSSS_nnnnnn_nnnnnnnnnn
                   1073: OP_DEF(bb1_n)
                   1074: {
                   1075:        ops_bb("bb1.n");
                   1076: }
                   1077: 
                   1078: void
                   1079: m88100disasm::ops_bcnd(std::string namebase)
                   1080: {
                   1081:        name = namebase;
                   1082:        arg0 = m5();
                   1083:        arg1 = rs1();
                   1084:        arg2 = d16();
                   1085: }
                   1086: 
                   1087: // 111010_MMMMMSSSSS_nnnnnn_nnnnnnnnnn
                   1088: OP_DEF(bcnd)
                   1089: {
                   1090:        ops_bcnd("bcnd");
                   1091: }
                   1092: 
                   1093: // 111011_MMMMMSSSSS_nnnnnn_nnnnnnnnnn
                   1094: OP_DEF(bcnd_n)
                   1095: {
                   1096:        ops_bcnd("bcnd.n");
                   1097: }
                   1098: 
                   1099: // 111100_DDDDDSSSSS_100000_wwwwwooooo
                   1100: OP_DEF(clr_1)
                   1101: {
                   1102:        name = "clr";
                   1103:        arg0 = rd();
                   1104:        arg1 = rs1();
                   1105:        arg2 = wo5();
1.1.1.7 ! root     1106: 
        !          1107:        if (DD == 0) {
        !          1108:                altname = "nop";
        !          1109:        } else {
        !          1110:                altarg0 = rd();
        !          1111:                altarg1 = rs1();
        !          1112:                auto w5 = W5 ?: 32;
        !          1113:                if (w5 == 1) {
        !          1114:                        altname = "bitclr";
        !          1115:                        altarg2 = string_format("#%d", O5);
        !          1116:                } else {
        !          1117:                        // XXX 表記はもうちょっと考える…
        !          1118:                        altname = "bfclr";
        !          1119:                        altarg2 = wo5();
        !          1120:                }
        !          1121:        }
1.1       root     1122: }
                   1123: 
                   1124: // 111100_DDDDDSSSSS_100010_wwwwwooooo
                   1125: OP_DEF(set_1)
                   1126: {
                   1127:        name = "set";
                   1128:        arg0 = rd();
                   1129:        arg1 = rs1();
                   1130:        arg2 = wo5();
1.1.1.7 ! root     1131: 
        !          1132:        if (DD == 0) {
        !          1133:                altname = "nop";
        !          1134:        } else {
        !          1135:                altarg0 = rd();
        !          1136:                altarg1 = rs1();
        !          1137:                auto w5 = W5 ?: 32;
        !          1138:                if (w5 == 1) {
        !          1139:                        altname = "bitset";
        !          1140:                        altarg2 = string_format("#%d", O5);
        !          1141:                } else {
        !          1142:                        // XXX 表記はもうちょっと考える…
        !          1143:                        altname = "bfset";
        !          1144:                        altarg2 = wo5();
        !          1145:                }
        !          1146:        }
1.1       root     1147: }
                   1148: 
                   1149: // 111100_DDDDDSSSSS_100100_wwwwwooooo
                   1150: OP_DEF(ext_1)
                   1151: {
                   1152:        name = "ext";
                   1153:        arg0 = rd();
                   1154:        arg1 = rs1();
                   1155:        arg2 = wo5();
1.1.1.7 ! root     1156: 
        !          1157:        // rd s1 imm
        !          1158:        // ----------
        !          1159:        // r0 *  *              nop
        !          1160:        // rd r0 w:o    clr rd
        !          1161:        // rd rd 32:o   asr rd, #o
        !          1162:        // rd s1 32:o   asr rd, s1, #o
        !          1163:        // rd rd w:o    bfexts rd, w:o
        !          1164:        // rd s1 w:o    bfexts rd, s1, w:o
        !          1165: 
        !          1166:        if (DD == 0) {
        !          1167:                altname = "nop";
        !          1168:        } else if (S1 == 0) {
        !          1169:                altname = "clr";
        !          1170:                altarg0 = rd();
        !          1171:        } else if (W5 == 0 || W5 + O5 >= 32) {
        !          1172:                // W5 + O5 >= 32 なら単純なシフトに相当
        !          1173:                altname = "asr";
        !          1174:                altarg0 = rd();
        !          1175:                if (DD != S1) {
        !          1176:                        altarg1 = rs1();
        !          1177:                }
        !          1178:                altarg2 = string_format("#%d", O5);
        !          1179:        } else {
        !          1180:                altname = "bfexts";
        !          1181:                altarg0 = rd();
        !          1182:                if (DD != S1) {
        !          1183:                        altarg1 = rs1();
        !          1184:                }
        !          1185:                altarg2 = wo5();
        !          1186:        }
1.1       root     1187: }
                   1188: 
                   1189: // 111100_DDDDDSSSSS_100110_wwwwwooooo
                   1190: OP_DEF(extu_1)
                   1191: {
                   1192:        name = "extu";
                   1193:        arg0 = rd();
                   1194:        arg1 = rs1();
                   1195:        arg2 = wo5();
1.1.1.7 ! root     1196: 
        !          1197:        // rd s1 imm
        !          1198:        // ----------
        !          1199:        // r0 *  *              nop
        !          1200:        // rd r0 w:o    clr rd
        !          1201:        // rd rd 32:o   lsr rd, #o
        !          1202:        // rd s1 32:o   lsr rd, s1, #o
        !          1203:        // rd rd w:o    bfextu rd, w:o
        !          1204:        // rd s1 w:o    bfextu rd, s1, w:o
        !          1205: 
        !          1206:        if (DD == 0) {
        !          1207:                altname = "nop";
        !          1208:        } else if (S1 == 0) {
        !          1209:                altname = "clr";
        !          1210:                altarg0 = rd();
        !          1211:        } else if (W5 == 0 || W5 + O5 >= 32) {
        !          1212:                // W5 + O5 >= 32 なら単純なシフトに相当
        !          1213:                altname = "lsr";
        !          1214:                altarg0 = rd();
        !          1215:                if (DD != S1) {
        !          1216:                        altarg1 = rs1();
        !          1217:                }
        !          1218:                altarg2 = string_format("#%d", O5);
        !          1219:        } else {
        !          1220:                altname = "bfextu";
        !          1221:                altarg0 = rd();
        !          1222:                if (DD != S1) {
        !          1223:                        altarg1 = rs1();
        !          1224:                }
        !          1225:                altarg2 = wo5();
        !          1226:        }
1.1       root     1227: }
                   1228: 
                   1229: // 111100_DDDDDSSSSS_101000_wwwwwooooo
                   1230: OP_DEF(mak_1)
                   1231: {
                   1232:        name = "mak";
                   1233:        arg0 = rd();
                   1234:        arg1 = rs1();
                   1235:        arg2 = wo5();
1.1.1.7 ! root     1236: 
        !          1237:        // rd s1 imm
        !          1238:        // ----------
        !          1239:        // r0 *  *              nop
        !          1240:        // rd r0 w:o    clr rd
        !          1241:        // rd rd 32:o   lsl rd, #o
        !          1242:        // rd s1 32:o   lsl rd, s1, #o
        !          1243:        // rd rd w:o    bfmak rd, w:o
        !          1244:        // rd s1 w:o    bfmak rd, s1, w:o
        !          1245: 
        !          1246:        if (DD == 0) {
        !          1247:                altname = "nop";
        !          1248:        } else if (S1 == 0) {
        !          1249:                altname = "clr";
        !          1250:                altarg0 = rd();
        !          1251:        } else if (W5 == 0 || W5 + O5 >= 32) {
        !          1252:                // W5 + O5 >= 32 なら単純なシフトに相当
        !          1253:                altname = "lsl";
        !          1254:                altarg0 = rd();
        !          1255:                if (DD != S1) {
        !          1256:                        altarg1 = rs1();
        !          1257:                }
        !          1258:                altarg2 = string_format("#%d", O5);
        !          1259:        } else {
        !          1260:                // XXX 名前から動作が想像しづらいのがつらいのだが、とりあえず後回し
        !          1261:                altname = "bfmak";
        !          1262:                altarg0 = rd();
        !          1263:                if (DD != S1) {
        !          1264:                        altarg1 = rs1();
        !          1265:                }
        !          1266:                altarg2 = wo5();
        !          1267:        }
1.1       root     1268: }
                   1269: 
                   1270: // 111100_DDDDDSSSSS_101010_zzzzzooooo
                   1271: OP_DEF(rot_1)
                   1272: {
                   1273:        name = "rot";
                   1274:        arg0 = rd();
                   1275:        arg1 = rs1();
                   1276:        arg2 = string_format("<%d>", O5);
1.1.1.7 ! root     1277: 
        !          1278:        // rd s1 offset
        !          1279:        // ----------
        !          1280:        // r0 *  *              nop
        !          1281:        // rd rd #0             nop
        !          1282:        // rd r0 *              clr rd
        !          1283:        // rd rd 1-16   ror rd, #1-16
        !          1284:        // rd s1 1-16   ror rd, s1, #1-16
        !          1285:        // rd rd 17-31  rol rd, #1-15
        !          1286:        // rd s1 17-31  rol rd, s1, #1-15
        !          1287: 
        !          1288:        if (DD == 0) {
        !          1289:                altname = "nop";
        !          1290:        } else if (S1 == 0) {
        !          1291:                altname = "clr";
        !          1292:                altarg0 = rd();
        !          1293:        } else if (O5 == 0) {
        !          1294:                if (DD == S1) {
        !          1295:                        altname = "nop";
        !          1296:                } else {
        !          1297:                        altname = "clr";
        !          1298:                        altarg0 = rd();
        !          1299:                }
        !          1300:        } else {
        !          1301:                // どう表記するのがいいかは状況によるかも知れないが
        !          1302:                // 1-16ビット(右)ローテートなら  ror #0-16、
        !          1303:                // 17-31ビット(右)ローテートなら rol #1-15 としてみる
        !          1304:                auto offset = O5;
        !          1305:                if (offset > 16) {
        !          1306:                        altname = "rol";
        !          1307:                        offset = 32 - offset;
        !          1308:                } else {
        !          1309:                        altname = "ror";
        !          1310:                }
        !          1311:                altarg0 = rd();
        !          1312:                if (DD != S1) {
        !          1313:                        altarg1 = rs1();
        !          1314:                }
        !          1315:                altarg2 = string_format("#%d", offset);
        !          1316:        }
1.1       root     1317: }
                   1318: 
                   1319: void
                   1320: m88100disasm::ops_tb(std::string namebase)
                   1321: {
                   1322:        name = namebase;
                   1323:        arg0 = b5();
                   1324:        arg1 = rs1();
                   1325:        arg2 = vec9();
                   1326: }
                   1327: 
                   1328: // 111100_bbbbbSSSSS_110100_0vvvvvvvvv
                   1329: OP_DEF(tb0)
                   1330: {
                   1331:        ops_tb("tb0");
                   1332: }
                   1333: 
                   1334: // 111100_bbbbbSSSSS_110110_0vvvvvvvvv
                   1335: OP_DEF(tb1)
                   1336: {
1.1.1.7 ! root     1337:        ops_tb("tb1");
        !          1338: 
        !          1339:        if (S1 == 0) {
1.1.1.2   root     1340:                // tb1 *,r0,* はパイプライン同期を目的として使われる。
                   1341:                // この形式はトラップは発生しない。
                   1342:                if (VEC9 < 128) {
1.1.1.7 ! root     1343:                        altname = "ssync";
1.1.1.2   root     1344:                } else {
1.1.1.7 ! root     1345:                        altname = "usync";
1.1.1.2   root     1346:                }
                   1347:        }
1.1       root     1348: }
                   1349: 
                   1350: // 111100_MMMMMSSSSS_111010_0vvvvvvvvv
                   1351: OP_DEF(tcnd)
                   1352: {
                   1353:        name = "tcnd";
                   1354:        arg0 = m5();
                   1355:        arg1 = rs1();
                   1356:        arg2 = vec9();
                   1357: }
                   1358: 
                   1359: // ld_reg, st_reg, xmem_reg の共通部
1.1.1.7 ! root     1360: // size は ".bu" などドットを含むサイズプレフィックス。
1.1       root     1361: void
1.1.1.7 ! root     1362: m88100disasm::ops_ldst_reg(const std::string& namebase, std::string size)
1.1       root     1363: {
                   1364:        uint32 u      = (opX >>  8) & 1;
                   1365:        uint32 scaled = (opX >>  9) & 1;
                   1366: 
1.1.1.7 ! root     1367:        name = namebase + size;
1.1       root     1368:        if (u) {
                   1369:                name += ".usr";
                   1370:        }
                   1371:        arg0 = rd();
                   1372:        arg1 = rs1();
                   1373:        if (scaled == 0) {
                   1374:                arg2 = rs2();
                   1375:        } else {
                   1376:                arg1 += "[" + rs2() + "]";
                   1377:        }
1.1.1.7 ! root     1378: 
        !          1379:        // 別名
        !          1380:        // ld.bu.usr はサフィックスの使い方が節操なさすぎるし
        !          1381:        // ld と ld.usr はわりと違う命令なので、違う命令のように見せる。
        !          1382:        altname = namebase;
        !          1383:        if (u) {
        !          1384:                altname += "usr";
        !          1385:        }
        !          1386:        altname += size;
        !          1387:        altarg0 = rd();
        !          1388: 
        !          1389:        // メモリアクセスはは括弧を付けて表す。
        !          1390:        // lda はメモリアクセスではないので括弧なしのまま。
        !          1391:        //
        !          1392:        // rs1 rs2 scaled
        !          1393:        // --------------
        !          1394:        // r*  r0  *            ld rd, (r*)
        !          1395:        // r0  s2  no           ld rd, (s2)
        !          1396:        // s1  s2  no           ld rd, (s1,s2)
        !          1397:        // r0  s2  yes          ld rd, (r0[s2])
        !          1398:        // s1  s2  yes          ld rd, (s1[s2])
        !          1399:        if (S2 == 0) {
        !          1400:                altarg1 = rs1();
        !          1401:        } else {
        !          1402:                if (scaled == 0) {
        !          1403:                        if (S1 == 0) {
        !          1404:                                altarg1 = rs2();
        !          1405:                        } else {
        !          1406:                                altarg1 = rs1() + "," + rs2();
        !          1407:                        }
        !          1408:                } else {
        !          1409:                        altarg1 = rs1() + "[" + rs2() + "]";
        !          1410:                }
        !          1411:        }
        !          1412:        // 3文字目が 'a' になるのは lda しかない
        !          1413:        if (namebase[2] != 'a') {
        !          1414:                altarg1 = "(" + altarg1 + ")";
        !          1415:        }
1.1       root     1416: }
                   1417: 
                   1418: // 111101_DDDDDSSSSS_000000_xU000sssss
                   1419: OP_DEF(xmem_bu)
                   1420: {
1.1.1.7 ! root     1421:        ops_ldst_reg("xmem", ".bu");
1.1       root     1422: }
                   1423: 
                   1424: // 111101_DDDDDSSSSS_000001_xU000sssss
                   1425: OP_DEF(xmem_w)
                   1426: {
1.1.1.7 ! root     1427:        ops_ldst_reg("xmem", "");
1.1       root     1428: }
                   1429: 
                   1430: // 111101_DDDDDSSSSS_000010_xU000sssss
                   1431: OP_DEF(ld_hu)
                   1432: {
1.1.1.7 ! root     1433:        ops_ldst_reg("ld", ".hu");
1.1       root     1434: }
                   1435: 
                   1436: // 111101_DDDDDSSSSS_000011_xU000sssss
                   1437: OP_DEF(ld_bu)
                   1438: {
1.1.1.7 ! root     1439:        ops_ldst_reg("ld", ".bu");
1.1       root     1440: }
                   1441: 
                   1442: // 111101_DDDDDSSSSS_000100_xU000sssss
                   1443: OP_DEF(ld_d)
                   1444: {
1.1.1.7 ! root     1445:        ops_ldst_reg("ld", ".d");
1.1       root     1446: }
                   1447: 
                   1448: // 111101_DDDDDSSSSS_000101_xU000sssss
                   1449: OP_DEF(ld_w)
                   1450: {
1.1.1.7 ! root     1451:        ops_ldst_reg("ld", "");
1.1       root     1452: }
                   1453: 
                   1454: // 111101_DDDDDSSSSS_000110_xU000sssss
                   1455: OP_DEF(ld_h)
                   1456: {
1.1.1.7 ! root     1457:        ops_ldst_reg("ld", ".h");
1.1       root     1458: }
                   1459: 
                   1460: // 111101_DDDDDSSSSS_000111_xU000sssss
                   1461: OP_DEF(ld_b)
                   1462: {
1.1.1.7 ! root     1463:        ops_ldst_reg("ld", ".b");
1.1       root     1464: }
                   1465: 
                   1466: // 111101_DDDDDSSSSS_001000_xU000sssss
                   1467: OP_DEF(st_d)
                   1468: {
1.1.1.7 ! root     1469:        ops_ldst_reg("st", ".d");
1.1       root     1470: }
                   1471: 
                   1472: // 111101_DDDDDSSSSS_001001_xU000sssss
                   1473: OP_DEF(st_w)
                   1474: {
1.1.1.7 ! root     1475:        ops_ldst_reg("st", "");
1.1       root     1476: }
                   1477: 
                   1478: // 111101_DDDDDSSSSS_001010_xU000sssss
                   1479: OP_DEF(st_h)
                   1480: {
1.1.1.7 ! root     1481:        ops_ldst_reg("st", ".h");
1.1       root     1482: }
                   1483: 
                   1484: // 111101_DDDDDSSSSS_001011_xU000sssss
                   1485: OP_DEF(st_b)
                   1486: {
1.1.1.7 ! root     1487:        ops_ldst_reg("st", ".b");
1.1       root     1488: }
                   1489: 
                   1490: // 111101_DDDDDSSSSS_001100_xU000sssss
                   1491: OP_DEF(lda_d)
                   1492: {
                   1493:        // XXX bit8 が 1 だとどうなるのか
1.1.1.7 ! root     1494:        ops_ldst_reg("lda", ".d");
1.1       root     1495: }
                   1496: 
                   1497: // 111101_DDDDDSSSSS_001101_xU000sssss
                   1498: OP_DEF(lda_w)
                   1499: {
                   1500:        // XXX bit8 が 1 だとどうなるのか
1.1.1.7 ! root     1501:        ops_ldst_reg("lda", "");
1.1       root     1502: }
                   1503: 
                   1504: // 111101_DDDDDSSSSS_001110_xU000sssss
                   1505: OP_DEF(lda_h)
                   1506: {
                   1507:        // XXX bit8 が 1 だとどうなるのか
1.1.1.7 ! root     1508:        ops_ldst_reg("lda", ".h");
1.1       root     1509: }
                   1510: 
                   1511: // 111101_DDDDDSSSSS_001111_xU000sssss
                   1512: OP_DEF(lda_b)
                   1513: {
                   1514:        // XXX bit8 が 1 だとどうなるのか
1.1.1.7 ! root     1515:        ops_ldst_reg("lda", ".b");
1.1       root     1516: }
                   1517: 
                   1518: // 111101_DDDDDSSSSS_010000_00000sssss
                   1519: OP_DEF(and)
                   1520: {
                   1521:        name = "and";
                   1522:        arg0 = rd();
                   1523:        arg1 = rs1();
                   1524:        arg2 = rs2();
1.1.1.7 ! root     1525: 
        !          1526:        // rd s1 s2
        !          1527:        // ----------
        !          1528:        // r0 *  *              nop
        !          1529:        // rd r0 *              clr     rd
        !          1530:        // rd *  r0             clr rd
        !          1531:        // rd rd rd             nop
        !          1532:        // rd s1 s1             mov rd, s1
        !          1533:        // rd rd s2             and rd, s2
        !          1534:        // rd s1 s2             and rd, s1, s2
        !          1535: 
        !          1536:        if (DD == 0) {
        !          1537:                altname = "nop";
        !          1538:        } else if (S1 == 0 || S2 == 0) {
        !          1539:                altname = "clr";
        !          1540:                altarg0 = rd();
        !          1541:        } else if (S1 == S2) {
        !          1542:                altname = "mov";
        !          1543:                altarg0 = rd();
        !          1544:                altarg1 = rs1();
        !          1545:        } else {
        !          1546:                altname = "and";
        !          1547:                altarg0 = rd();
        !          1548:                if (DD != S1) {
        !          1549:                        altarg1 = rs1();
        !          1550:                }
        !          1551:                if (DD != S2) {
        !          1552:                        altarg2 = rs2();
        !          1553:                }
        !          1554:        }
1.1       root     1555: }
                   1556: 
                   1557: // 111101_DDDDDSSSSS_010001_00000sssss
                   1558: OP_DEF(and_c)
                   1559: {
                   1560:        name = "and.c";
                   1561:        arg0 = rd();
                   1562:        arg1 = rs1();
                   1563:        arg2 = rs2();
1.1.1.7 ! root     1564: 
        !          1565:        // rd s1 s2
        !          1566:        // ----------
        !          1567:        // r0 *  *              nop
        !          1568:        // rd r0 *              clr     rd
        !          1569:        // rd s1 r0             mov rd, s1
        !          1570:        // rd rd r0             nop
        !          1571:        // rd s1 s1             clr rd
        !          1572:        // rd s1 s2             and rd, s1, ~s2
        !          1573: 
        !          1574:        if (DD == 0) {
        !          1575:                altname = "nop";
        !          1576:        } else if (S1 == 0) {
        !          1577:                altname = "clr";
        !          1578:                altarg0 = rd();
        !          1579:        } else if (S2 == 0) {
        !          1580:                altname = "mov";
        !          1581:                altarg0 = rd();
        !          1582:                altarg1 = rs1();
        !          1583:        } else if (S1 == S2) {
        !          1584:                altname = "clr";
        !          1585:                altarg0 = rd();
        !          1586:        } else {
        !          1587:                altname = "and";
        !          1588:                altarg0 = rd();
        !          1589:                if (DD != S1) {
        !          1590:                        altarg1 = rs1();
        !          1591:                }
        !          1592:                altarg2 = "~" + rs2();
        !          1593:        }
1.1       root     1594: }
                   1595: 
                   1596: // 111101_DDDDDSSSSS_010100_00000sssss
                   1597: OP_DEF(xor)
                   1598: {
                   1599:        name = "xor";
                   1600:        arg0 = rd();
                   1601:        arg1 = rs1();
                   1602:        arg2 = rs2();
1.1.1.7 ! root     1603: 
        !          1604:        // rd s1 s2
        !          1605:        // ----------
        !          1606:        // r0 *  *              nop
        !          1607:        // rd s1 s1             clr rd
        !          1608:        // rd r0 s2             mov rd, s2
        !          1609:        // rd s1 r0             mov rd, s1
        !          1610:        // rd s1 s2             xor rd, s1, s2
        !          1611: 
        !          1612:        if (DD == 0) {
        !          1613:                altname = "nop";
        !          1614:        } else if (S1 == S2) {
        !          1615:                altname = "clr";
        !          1616:                altarg0 = rd();
        !          1617:        } else if (S1 == 0) {
        !          1618:                altname = "mov";
        !          1619:                altarg0 = rd();
        !          1620:                altarg1 = rs2();
        !          1621:        } else if (S2 == 0) {
        !          1622:                altname = "mov";
        !          1623:                altarg0 = rd();
        !          1624:                altarg1 = rs1();
        !          1625:        } else {
        !          1626:                altname = "xor";
        !          1627:                altarg0 = rd();
        !          1628:                if (DD != S1) {
        !          1629:                        altarg1 = rs1();
        !          1630:                }
        !          1631:                if (DD != S2) {
        !          1632:                        altarg2 = rs2();
        !          1633:                }
        !          1634:        }
1.1       root     1635: }
                   1636: 
                   1637: // 111101_DDDDDSSSSS_010101_00000sssss
                   1638: OP_DEF(xor_c)
                   1639: {
                   1640:        name = "xor.c";
                   1641:        arg0 = rd();
                   1642:        arg1 = rs1();
                   1643:        arg2 = rs2();
1.1.1.7 ! root     1644: 
        !          1645:        // rd s1 s2
        !          1646:        // ----------
        !          1647:        // r0 *  *              nop
        !          1648:        // rd s1 s1             mov rd, #0xffffffff
        !          1649:        // rd r0 s2             not rd, s2
        !          1650:        // rd s1 r0             not rd, s1
        !          1651:        // rd s1 s2             xor rd, s1, ~s2
        !          1652: 
        !          1653:        if (DD == 0) {
        !          1654:                altname = "nop";
        !          1655:        } else if (S1 == S2) {
        !          1656:                altname = "mov";
        !          1657:                altarg0 = rd();
        !          1658:                altarg1 = "#0xffffffff";
        !          1659:        } else if (S1 == 0) {
        !          1660:                altname = "not";
        !          1661:                altarg0 = rd();
        !          1662:                if (DD != S2) {
        !          1663:                        altarg1 = rs2();
        !          1664:                }
        !          1665:        } else if (S2 == 0) {
        !          1666:                altname = "not";
        !          1667:                altarg0 = rd();
        !          1668:                if (DD != S1) {
        !          1669:                        altarg1 = rs1();
        !          1670:                }
        !          1671:        } else {
        !          1672:                altname = "xor";
        !          1673:                altarg0 = rd();
        !          1674:                if (DD != S1) {
        !          1675:                        altarg1 = rs1();
        !          1676:                }
        !          1677:                altarg2 = "~" + rs2();
        !          1678:        }
1.1       root     1679: }
                   1680: 
                   1681: // 111101_DDDDDSSSSS_010110_00000sssss
                   1682: OP_DEF(or)
                   1683: {
1.1.1.7 ! root     1684:        name = "or";
        !          1685:        arg0 = rd();
        !          1686:        arg1 = rs1();
        !          1687:        arg2 = rs2();
        !          1688: 
        !          1689:        // rd s1 s2
        !          1690:        // ----------
        !          1691:        // r0 *  *              nop
        !          1692:        // rd r0 r0             clr rd
        !          1693:        // rd s1 s1             mov rd, s1
        !          1694:        // rd s1 r0             mov rd, s1
        !          1695:        // rd r0 s2             mov rd, s2
        !          1696:        // rd s1 s2             or  rd, s1, s2
        !          1697: 
        !          1698:        if (DD == 0) {
        !          1699:                altname = "nop";
        !          1700:        } else if (S1 == 0 && S2 == 0) {
        !          1701:                altname = "clr";
        !          1702:                altarg0 = rd();
        !          1703:        } else if (S1 == S2 || S2 == 0) {
        !          1704:                altname = "mov";
        !          1705:                altarg0 = rd();
        !          1706:                altarg1 = rs1();
        !          1707:        } else if (S1 == 0) {
        !          1708:                altname = "mov";
        !          1709:                altarg0 = rd();
        !          1710:                altarg1 = rs2();
1.1.1.2   root     1711:        } else {
1.1.1.7 ! root     1712:                altname = "or";
        !          1713:                altarg0 = rd();
        !          1714:                if (DD != S1) {
        !          1715:                        altarg1 = rs1();
        !          1716:                }
        !          1717:                if (DD != S2) {
        !          1718:                        altarg2 = rs2();
        !          1719:                }
1.1.1.2   root     1720:        }
1.1       root     1721: }
                   1722: 
                   1723: // 111101_DDDDDSSSSS_010111_00000sssss
                   1724: OP_DEF(or_c)
                   1725: {
                   1726:        name = "or.c";
                   1727:        arg0 = rd();
                   1728:        arg1 = rs1();
                   1729:        arg2 = rs2();
1.1.1.7 ! root     1730: 
        !          1731:        // rd s1 s2
        !          1732:        // ----------
        !          1733:        // r0 *  *              nop
        !          1734:        // rd s1 r0             mov rd, #0xffffffff
        !          1735:        // rd s1 s1             mov rd, #0xffffffff
        !          1736:        // rd r0 s2             not rd, s2
        !          1737:        // rd s1 s2             or  rd, s1, ~s2
        !          1738: 
        !          1739:        if (DD == 0) {
        !          1740:                altname = "nop";
        !          1741:        } else if (S2 == 0 || S1 == S2) {
        !          1742:                altname = "mov";
        !          1743:                altarg0 = rd();
        !          1744:                altarg1 = "#0xffffffff";
        !          1745:        } else if (S1 == 0) {
        !          1746:                altname = "not";
        !          1747:                altarg0 = rd();
        !          1748:                if (DD != S2) {
        !          1749:                        altarg1 = rs2();
        !          1750:                }
        !          1751:        } else {
        !          1752:                altname = "or";
        !          1753:                altarg0 = rd();
        !          1754:                if (DD != S1) {
        !          1755:                        altarg1 = rs1();
        !          1756:                }
        !          1757:                altarg2 = "~" + rs2();
        !          1758:        }
1.1       root     1759: }
                   1760: 
                   1761: // 111101_DDDDDSSSSS_011000_nn000sssss
                   1762: OP_DEF(addu)
                   1763: {
                   1764:        name = "addu" + cio();
                   1765:        arg0 = rd();
                   1766:        arg1 = rs1();
                   1767:        arg2 = rs2();
1.1.1.7 ! root     1768: 
        !          1769:        if (CIO == 0) {
        !          1770:                // addu 無印の場合
        !          1771:                //
        !          1772:                // rd s1 s2
        !          1773:                // ----------
        !          1774:                // r0 *  *              nop
        !          1775:                // rd r0 r0             clr rd
        !          1776:                // rd s1 r0             mov rd, s1
        !          1777:                // rd r0 s2             mov rd, s2
        !          1778:                // rd s1 s2             add rd, s1, s2
        !          1779: 
        !          1780:                if (DD == 0) {
        !          1781:                        altname = "nop";
        !          1782:                } else if (S1 == 0 && S2 == 0) {
        !          1783:                        altname = "clr";
        !          1784:                        altarg0 = rd();
        !          1785:                } else if (S1 == 0 || S2 == 0) {
        !          1786:                        altname = "mov";
        !          1787:                        altarg0 = rd();
        !          1788:                        if (S1 == 0) {
        !          1789:                                altarg1 = rs2();
        !          1790:                        }
        !          1791:                        if (S2 == 0) {
        !          1792:                                altarg1 = rs1();
        !          1793:                        }
        !          1794:                } else if (DD == S1 && DD == S2) {
        !          1795:                        altname = "addu";
        !          1796:                        altarg0 = rd();
        !          1797:                        altarg1 = rs2();
        !          1798:                } else {
        !          1799:                        altname = "addu";
        !          1800:                        altarg0 = rd();
        !          1801:                        if (DD != S1) {
        !          1802:                                altarg1 = rs1();
        !          1803:                        }
        !          1804:                        if (DD != S2) {
        !          1805:                                altarg2 = rs2();
        !          1806:                        }
        !          1807:                }
        !          1808:        } else {
        !          1809:                // addu キャリー込み .ci/co/cio のほうは 2 オペランドへの省略のみ。
        !          1810:                // XXX addu の2項は交換可なので addu r1, r2, r1 は addu r1, r2 と
        !          1811:                //     省略できていいがそれには未対応。
        !          1812:                altname = "addu" + cio();
        !          1813:                altarg0 = rd();
        !          1814:                if (DD != S1) {
        !          1815:                        altarg1 = rs1();
        !          1816:                }
        !          1817:                altarg2 = rs2();
        !          1818:        }
1.1       root     1819: }
                   1820: 
                   1821: // 111101_DDDDDSSSSS_011001_nn000sssss
                   1822: OP_DEF(subu)
                   1823: {
                   1824:        name = "subu" + cio();
                   1825:        arg0 = rd();
                   1826:        arg1 = rs1();
                   1827:        arg2 = rs2();
1.1.1.7 ! root     1828: 
        !          1829:        if (CIO == 0) {
        !          1830:                // subu 無印の場合
        !          1831:                //
        !          1832:                // rd s1 s2
        !          1833:                // ----------
        !          1834:                // r0 *  *              nop
        !          1835:                // rd s1 s1             clr  rd
        !          1836:                // rd s1 r0             mov  rd, s1
        !          1837:                // rd s1 s2             subu rd, s1, s2
        !          1838: 
        !          1839:                if (DD == 0) {
        !          1840:                        altname = "nop";
        !          1841:                } else if (S1 == S2) {
        !          1842:                        altname = "clr";
        !          1843:                        altarg0 = rd();
        !          1844:                } else if (S2 == 0) {
        !          1845:                        altname = "mov";
        !          1846:                        altarg0 = rd();
        !          1847:                        altarg1 = rs1();
        !          1848:                } else {
        !          1849:                        altname = "subu";
        !          1850:                        altarg0 = rd();
        !          1851:                        if (DD != S1) {
        !          1852:                                altarg1 = rs1();
        !          1853:                        }
        !          1854:                        altarg2 = rs2();
        !          1855:                }
        !          1856:        } else {
        !          1857:                // subu キャリー込み .ci/co/cio のほうは 2 オペランドへの省略のみ。
        !          1858:                altname = "subu" + cio();
        !          1859:                altarg0 = rd();
        !          1860:                if (DD != S1) {
        !          1861:                        altarg1 = rs1();
        !          1862:                }
        !          1863:                altarg2 = rs2();
        !          1864:        }
1.1       root     1865: }
                   1866: 
                   1867: // 111101_DDDDDSSSSS_011010_zz000sssss
                   1868: OP_DEF(divu)
                   1869: {
                   1870:        name = "divu";
                   1871:        arg0 = rd();
                   1872:        arg1 = rs1();
                   1873:        arg2 = rs2();
1.1.1.7 ! root     1874: 
        !          1875:        // 例外が起きる可能性があるので 2オペランドへの省略のみ
        !          1876:        altname = "divu";
        !          1877:        altarg0 = rd();
        !          1878:        if (DD != S1) {
        !          1879:                altarg1 = rs1();
        !          1880:        }
        !          1881:        altarg2 = rs2();
1.1       root     1882: }
                   1883: 
                   1884: // 111101_DDDDDSSSSS_011011_zz000sssss
                   1885: OP_DEF(mul)
                   1886: {
                   1887:        name = "mul";
                   1888:        arg0 = rd();
                   1889:        arg1 = rs1();
                   1890:        arg2 = rs2();
1.1.1.7 ! root     1891: 
        !          1892:        // 例外が起きる可能性があるので 2オペランドへの省略のみ
        !          1893:        altname = "mul";
        !          1894:        altarg0 = rd();
        !          1895:        if (DD != S1) {
        !          1896:                altarg1 = rs1();
        !          1897:        }
        !          1898:        altarg2 = rs2();
1.1       root     1899: }
                   1900: 
                   1901: // 111101_DDDDDSSSSS_011100_nn000sssss
                   1902: OP_DEF(add)
                   1903: {
                   1904:        name = "add" + cio();
                   1905:        arg0 = rd();
                   1906:        arg1 = rs1();
                   1907:        arg2 = rs2();
1.1.1.7 ! root     1908: 
        !          1909:        if (CIO == 0) {
        !          1910:                // add 無印は符号付きなので、より明示的な adds を使う。
        !          1911:                // 符号付き加算ではオーバーフローが起きる可能性があるため、
        !          1912:                // rD が r0 であってもただちに nop とはならない。
        !          1913:                // 一方 r0 を加算する場合は何も起きないので圧縮表記したい。
        !          1914: 
        !          1915:                // rd s1 s2
        !          1916:                // ----------
        !          1917:                // rd r0 r0             clr  rd
        !          1918:                // r0 r0 rd             nop
        !          1919:                // rd r0 rd             nop
        !          1920:                // rd r0 s2             mov  rd, s2
        !          1921:                // rd rd r0             nop
        !          1922:                // rd s1 r0             mov  rd, s1
        !          1923:                // rd s1 s2             adds rd, s1, s2
        !          1924: 
        !          1925:                if (S1 == 0 && S2 == 0) {
        !          1926:                        if (DD == 0) {
        !          1927:                                altname = "nop";
        !          1928:                        } else {
        !          1929:                                altname = "clr";
        !          1930:                                altarg0 = rd();
        !          1931:                        }
        !          1932:                } else if (S1 == 0) {
        !          1933:                        if (DD == 0) {
        !          1934:                                altname = "nop";
        !          1935:                        } else {
        !          1936:                                altname = "mov";
        !          1937:                                altarg0 = rd();
        !          1938:                                altarg1 = rs2();
        !          1939:                        }
        !          1940:                } else if (S2 == 0) {
        !          1941:                        if (DD == 0) {
        !          1942:                                altname = "nop";
        !          1943:                        } else {
        !          1944:                                altname = "mov";
        !          1945:                                altarg0 = rd();
        !          1946:                                altarg1 = rs1();
        !          1947:                        }
        !          1948:                } else {
        !          1949:                        altname = "adds";
        !          1950:                        altarg0 = rd();
        !          1951:                        if (DD != S1) {
        !          1952:                                altarg1 = rs1();
        !          1953:                        }
        !          1954:                        altarg2 = rs2();
        !          1955:                }
        !          1956:        } else {
        !          1957:                // adds キャリー込み .ci/co/cio のほうは 2 オペランドへの省略のみ。
        !          1958:                altname = "adds" + cio();
        !          1959:                altarg0 = rd();
        !          1960:                if (DD != S1) {
        !          1961:                        altarg1 = rs1();
        !          1962:                }
        !          1963:                altarg2 = rs2();
        !          1964:        }
1.1       root     1965: }
                   1966: 
                   1967: // 111101_DDDDDSSSSS_011101_nn000sssss
                   1968: OP_DEF(sub)
                   1969: {
                   1970:        name = "sub" + cio();
                   1971:        arg0 = rd();
                   1972:        arg1 = rs1();
                   1973:        arg2 = rs2();
1.1.1.7 ! root     1974: 
        !          1975:        if (CIO == 0) {
        !          1976:                // sub 無印は符号付きなので、より明示的な subs を使う。
        !          1977:                // 符号付き減算ではオーバーフローが起きる可能性があるため、
        !          1978:                // rD が r0 であってもただちに nop とはならない。
        !          1979:                // 一方 r0 を減算する場合は何も起きないので圧縮表記したい。
        !          1980: 
        !          1981:                // rd s1 s2
        !          1982:                // ----------
        !          1983:                // rd rd r0             nop
        !          1984:                // rd r0 r0             clr  rd
        !          1985:                // rd s1 r0             mov  rd, s1
        !          1986:                // rd s1 s2             subs rd, s1, s2
        !          1987: 
        !          1988:                if (S1 == 0 && S2 == 0) {
        !          1989:                        if (DD == 0) {
        !          1990:                                altname = "nop";
        !          1991:                        } else {
        !          1992:                                altname = "clr";
        !          1993:                                altarg0 = rd();
        !          1994:                        }
        !          1995:                } else if (S2 == 0) {
        !          1996:                        if (DD == 0) {
        !          1997:                                altname = "nop";
        !          1998:                        } else {
        !          1999:                                altname = "mov";
        !          2000:                                altarg0 = rd();
        !          2001:                                altarg1 = rs1();
        !          2002:                        }
        !          2003:                } else {
        !          2004:                        altname = "subs";
        !          2005:                        altarg0 = rd();
        !          2006:                        if (DD != S1) {
        !          2007:                                altarg1 = rs1();
        !          2008:                        }
        !          2009:                        altarg2 = rs2();
        !          2010:                }
        !          2011:        } else {
        !          2012:                // subs キャリー込み .ci/co/cio のほうは 2 オペランドへの省略のみ。
        !          2013:                altname = "subs" + cio();
        !          2014:                altarg0 = rd();
        !          2015:                if (DD != S1) {
        !          2016:                        altarg1 = rs1();
        !          2017:                }
        !          2018:                altarg2 = rs2();
        !          2019:        }
1.1       root     2020: }
                   2021: 
                   2022: // 111101_DDDDDSSSSS_011110_zz000sssss
                   2023: OP_DEF(div)
                   2024: {
                   2025:        name = "div";
                   2026:        arg0 = rd();
                   2027:        arg1 = rs1();
                   2028:        arg2 = rs2();
1.1.1.7 ! root     2029: 
        !          2030:        // 例外が起きる可能性があるので 2オペランドへの省略のみ
        !          2031:        altname = "div";
        !          2032:        altarg0 = rd();
        !          2033:        if (DD != S1) {
        !          2034:                altarg1 = rs1();
        !          2035:        }
        !          2036:        altarg2 = rs2();
1.1       root     2037: }
                   2038: 
                   2039: // 111101_DDDDDSSSSS_011111_zz000sssss
                   2040: OP_DEF(cmp)
                   2041: {
                   2042:        name = "cmp";
                   2043:        arg0 = rd();
                   2044:        arg1 = rs1();
                   2045:        arg2 = rs2();
1.1.1.7 ! root     2046: 
        !          2047:        // cmp r0,*,* 以外は別表記を用意する必要ない
        !          2048:        if (DD == 0) {
        !          2049:                altname = "nop";
        !          2050:        }
1.1       root     2051: }
                   2052: 
                   2053: // 111101_DDDDDSSSSS_100000_00000sssss
                   2054: OP_DEF(clr_2)
                   2055: {
                   2056:        name = "clr";
                   2057:        arg0 = rd();
                   2058:        arg1 = rs1();
                   2059:        arg2 = rs2();
1.1.1.7 ! root     2060: 
        !          2061:        // rd s1 s2
        !          2062:        // ----------
        !          2063:        // r0 *  *              nop
        !          2064:        // rd r0 s2             clr  rd
        !          2065:        // rd s1 r0             mov  rd, s1
        !          2066:        // rd rd s2             bfclr rd, s2
        !          2067:        // rd s1 s2             bfclr rd, s1, s2
        !          2068: 
        !          2069:        if (DD == 0) {
        !          2070:                altname = "nop";
        !          2071:        } else if (S1 == 0) {
        !          2072:                altname = "clr";
        !          2073:                altarg0 = rd();
        !          2074:        } else if (S2 == 0) {
        !          2075:                altname = "mov";
        !          2076:                altarg0 = rd();
        !          2077:                altarg1 = rs1();
        !          2078:        } else {
        !          2079:                altname = "bfclr";
        !          2080:                altarg0 = rd();
        !          2081:                if (DD != S1) {
        !          2082:                        altarg1 = rs1();
        !          2083:                }
        !          2084:                altarg2 = rs2();
        !          2085:        }
1.1       root     2086: }
                   2087: 
                   2088: // 111101_DDDDDSSSSS_100010_00000sssss
                   2089: OP_DEF(set_2)
                   2090: {
                   2091:        name = "set";
                   2092:        arg0 = rd();
                   2093:        arg1 = rs1();
                   2094:        arg2 = rs2();
1.1.1.7 ! root     2095: 
        !          2096:        // rd s1 s2
        !          2097:        // ----------
        !          2098:        // r0 *  *              nop
        !          2099:        // rd s1 r0             mov   rd, #0xffffffff
        !          2100:        // rd rd s2             bfset rd, s2
        !          2101:        // rd s1 s2             bfset rd, s1, s2
        !          2102: 
        !          2103:        if (DD == 0) {
        !          2104:                altname = "nop";
        !          2105:        } else if (S2 == 0) {
        !          2106:                altname = "mov";
        !          2107:                altarg0 = rd();
        !          2108:                altarg1 = "#0xffffffff";
        !          2109:        } else {
        !          2110:                altname = "bfset";
        !          2111:                altarg0 = rd();
        !          2112:                if (DD != S1) {
        !          2113:                        altarg1 = rs1();
        !          2114:                }
        !          2115:                altarg2 = rs2();
        !          2116:        }
1.1       root     2117: }
                   2118: 
                   2119: // 111101_DDDDDSSSSS_100100_00000sssss
                   2120: OP_DEF(ext_2)
                   2121: {
                   2122:        name = "ext";
                   2123:        arg0 = rd();
                   2124:        arg1 = rs1();
                   2125:        arg2 = rs2();
1.1.1.7 ! root     2126: 
        !          2127:        // rd s1 s2
        !          2128:        // ----------
        !          2129:        // r0 *  *              nop
        !          2130:        // rd s1 r0             mov  rd, s1
        !          2131:        // rd rd s2             bfexts rd, s2
        !          2132:        // rd s1 s2             bfexts rd, s1, s2
        !          2133: 
        !          2134:        if (DD == 0) {
        !          2135:                altname = "nop";
        !          2136:        } else if (S2 == 0) {
        !          2137:                altname = "mov";
        !          2138:                altarg0 = rd();
        !          2139:                altarg1 = rs1();
        !          2140:        } else {
        !          2141:                altname = "bfexts";
        !          2142:                altarg0 = rd();
        !          2143:                if (DD != S1) {
        !          2144:                        altarg1 = rs1();
        !          2145:                }
        !          2146:                altarg2 = rs2();
        !          2147:        }
1.1       root     2148: }
                   2149: 
                   2150: // 111101_DDDDDSSSSS_100110_00000sssss
                   2151: OP_DEF(extu_2)
                   2152: {
                   2153:        name = "extu";
                   2154:        arg0 = rd();
                   2155:        arg1 = rs1();
                   2156:        arg2 = rs2();
1.1.1.7 ! root     2157: 
        !          2158:        // rd s1 s2
        !          2159:        // ----------
        !          2160:        // r0 *  *              nop
        !          2161:        // rd s1 r0             mov  rd, s1
        !          2162:        // rd rd s2             bfextu rd, s2
        !          2163:        // rd s1 s2             bfextu rd, s1, s2
        !          2164: 
        !          2165:        if (DD == 0) {
        !          2166:                altname = "nop";
        !          2167:        } else if (S2 == 0) {
        !          2168:                altname = "mov";
        !          2169:                altarg0 = rd();
        !          2170:                altarg1 = rs1();
        !          2171:        } else {
        !          2172:                altname = "bfextu";
        !          2173:                altarg0 = rd();
        !          2174:                if (DD != S1) {
        !          2175:                        altarg1 = rs1();
        !          2176:                }
        !          2177:                altarg2 = rs2();
        !          2178:        }
1.1       root     2179: }
                   2180: 
                   2181: // 111101_DDDDDSSSSS_101000_00000sssss
                   2182: OP_DEF(mak_2)
                   2183: {
                   2184:        name = "mak";
                   2185:        arg0 = rd();
                   2186:        arg1 = rs1();
                   2187:        arg2 = rs2();
1.1.1.7 ! root     2188: 
        !          2189:        // rd s1 s2
        !          2190:        // ----------
        !          2191:        // r0 *  *              nop
        !          2192:        // rd r0 s2             clr rd
        !          2193:        // rd s1 r0             mov rd, s1
        !          2194:        // rd s1 s2             bfmak rd, s1, s2
        !          2195: 
        !          2196:        if (DD == 0) {
        !          2197:                altname = "nop";
        !          2198:        } else if (S1 == 0) {
        !          2199:                altname = "clr";
        !          2200:                altarg0 = rd();
        !          2201:        } else if (S2 == 0) {
        !          2202:                altname = "mov";
        !          2203:                altarg0 = rd();
        !          2204:                altarg1 = rs1();
        !          2205:        } else {
        !          2206:                altname = "bfmak";
        !          2207:                altarg0 = rd();
        !          2208:                if (DD != S1) {
        !          2209:                        altarg1 = rs1();
        !          2210:                }
        !          2211:                altarg2 = rs2();
        !          2212:        }
1.1       root     2213: }
                   2214: 
                   2215: // 111101_DDDDDSSSSS_101010_00000sssss
                   2216: OP_DEF(rot_2)
                   2217: {
                   2218:        name = "rot";
                   2219:        arg0 = rd();
                   2220:        arg1 = rs1();
                   2221:        arg2 = rs2();
1.1.1.7 ! root     2222: 
        !          2223:        // rd s1 s2
        !          2224:        // ----------
        !          2225:        // r0 *  *              nop
        !          2226:        // rd r0 s2             clr rd
        !          2227:        // rd s1 r0             mov rd, s1
        !          2228:        // rd s1 s2             ror rd, s1, s2
        !          2229: 
        !          2230:        if (DD == 0) {
        !          2231:                altname = "nop";
        !          2232:        } else if (S1 == 0) {
        !          2233:                altname = "clr";
        !          2234:                altarg0 = rd();
        !          2235:        } else if (S2 == 0) {
        !          2236:                altname = "mov";
        !          2237:                altarg0 = rd();
        !          2238:                altarg1 = rs1();
        !          2239:        } else {
        !          2240:                altname = "ror";
        !          2241:                altarg0 = rd();
        !          2242:                if (DD != S1) {
        !          2243:                        altarg1 = rs1();
        !          2244:                }
        !          2245:                altarg2 = rs2();
        !          2246:        }
1.1       root     2247: }
                   2248: 
                   2249: // 111101_zzzzzzzzzz_110000_00000sssss
                   2250: OP_DEF(jmp)
                   2251: {
                   2252:        name = "jmp";
                   2253:        arg0 = rs2();
                   2254: }
                   2255: 
                   2256: // 111101_zzzzzzzzzz_110001_00000sssss
                   2257: OP_DEF(jmp_n)
                   2258: {
                   2259:        name = "jmp.n";
                   2260:        arg0 = rs2();
                   2261: }
                   2262: 
                   2263: // 111101_zzzzzzzzzz_110010_00000sssss
                   2264: OP_DEF(jsr)
                   2265: {
                   2266:        name = "jsr";
                   2267:        arg0 = rs2();
                   2268: }
                   2269: 
                   2270: // 111101_zzzzzzzzzz_110011_00000sssss
                   2271: OP_DEF(jsr_n)
                   2272: {
                   2273:        name = "jsr.n";
                   2274:        arg0 = rs2();
                   2275: }
                   2276: 
1.1.1.2   root     2277: // 111101_DDDDDzzzzz_111010_00000sssss
                   2278: OP_DEF(ff1)
                   2279: {
                   2280:        name = "ff1";
                   2281:        arg0 = rd();
                   2282:        arg1 = rs2();
1.1.1.7 ! root     2283: 
        !          2284:        // rd s2
        !          2285:        // ------
        !          2286:        // r0 *         nop
        !          2287:        // rd r0        mov rd, #32
        !          2288:        // rd s2        ff1 rd, s2
        !          2289: 
        !          2290:        if (DD == 0) {
        !          2291:                altname = "nop";
        !          2292:        } else if (S2 == 0) {
        !          2293:                altname = "mov";
        !          2294:                altarg0 = rd();
        !          2295:                altarg1 = "#32";
        !          2296:        } else {
        !          2297:                altname = "ff1";
        !          2298:                altarg0 = rd();
        !          2299:                altarg1 = rs2();
        !          2300:        }
1.1.1.2   root     2301: }
                   2302: 
                   2303: // 111101_DDDDDzzzzz_111011_00000sssss
                   2304: OP_DEF(ff0)
                   2305: {
                   2306:        name = "ff0";
                   2307:        arg0 = rd();
                   2308:        arg1 = rs2();
1.1.1.7 ! root     2309: 
        !          2310:        // rd s2
        !          2311:        // ------
        !          2312:        // r0 *         nop
        !          2313:        // rd r0        clr rd
        !          2314:        // rd s2        ff0 rd, s2
        !          2315: 
        !          2316:        if (DD == 0) {
        !          2317:                altname = "nop";
        !          2318:        } else if (S2 == 0) {
        !          2319:                altname = "clr";
        !          2320:                altarg0 = rd();
        !          2321:        } else {
        !          2322:                altname = "ff0";
        !          2323:                altarg0 = rd();
        !          2324:                altarg1 = rs2();
        !          2325:        }
1.1.1.2   root     2326: }
                   2327: 
1.1       root     2328: // 111101_zzzzzzzzzz_111111_0000000000
                   2329: OP_DEF(rte)
                   2330: {
                   2331:        name = "rte";
                   2332: }
                   2333: 
                   2334: // 111101_zzzzzSSSSS_111110_00000SSSSS
                   2335: OP_DEF(tbnd_1)
                   2336: {
                   2337:        name = "tbnd";
                   2338:        arg1 = rs1();
                   2339:        arg2 = rs2();
                   2340: }
                   2341: 
                   2342: // 111110_zzzzzSSSSS_nnnnnn_nnnnnnnnnn
                   2343: OP_DEF(tbnd_2)
                   2344: {
                   2345:        name = "tbnd";
                   2346:        arg1 = rs1();
                   2347:        arg2 = imm16();
                   2348: }
                   2349: 
1.1.1.7 ! root     2350: // 111111_DDDDDSSSSS_000001_00nnnnnnnn
        !          2351: OP_DEF(doscall)
1.1       root     2352: {
1.1.1.7 ! root     2353:        name = "doscall";
        !          2354:        arg0 = rd();
        !          2355:        arg1 = rs1();
        !          2356:        arg2 = string_format("#0x%02x", (opX & 0xff));
1.1       root     2357: }

unix.superglobalmegacorp.com

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