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

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

unix.superglobalmegacorp.com

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