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

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

unix.superglobalmegacorp.com

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