--- nono/m88xx0/m88100disasm.cpp 2026/04/29 17:04:31 1.1.1.1 +++ nono/m88xx0/m88100disasm.cpp 2026/04/29 17:04:52 1.1.1.6 @@ -1,18 +1,19 @@ // // nono -// Copyright (C) 2020 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // #include "m88100disasm.h" +#include "m88100acc.h" #include "bus.h" -#include "mystring.h" #define OP_DEF(name) void __CONCAT(m88100disasm::op_,name)() #define OP_FUNC(name) __CONCAT(op_,name)() // コンストラクタ -m88100disasm::m88100disasm(DebuggerMD *m) - : inherited(m) +m88100disasm::m88100disasm(DebuggerMemoryStream& mem_) + : inherited(mem_) { } @@ -23,7 +24,7 @@ m88100disasm::~m88100disasm() // 逆アセンブルを実行 bool -m88100disasm::Exec(saddr_t laddr) +m88100disasm::Exec() { ExecInit(); @@ -33,15 +34,16 @@ m88100disasm::Exec(saddr_t laddr) arg1.clear(); arg2.clear(); - xip = laddr.addr; - phys_xip = laddr.addr; + xip = (uint32)mem.laddr; - opX = peek(); - uint32 op12 = ((opX >> 20) & 0x0fc0) | ((opX >> 10) & 0x003f); + opX = mem.FetchInst(); + uint32 op12 = m88kcpu::op32_to_12(opX); switch (op12) { #include "m88100switch.inc" default: - __unreachable(); + name = "illegal"; + break; + //OP_FUNC(illegal); } // 出力文字列(ダンプ) @@ -66,7 +68,7 @@ m88100disasm::Exec(saddr_t laddr) if (!arg1.empty()) { if (!args.empty()) { args += ","; - while (args.length() < 4) + while (args.length() % 4 != 0) args += " "; } args += arg1; @@ -74,7 +76,7 @@ m88100disasm::Exec(saddr_t laddr) if (!arg2.empty()) { if (!args.empty()) { args += ","; - while (args.length() < 8) + while (args.length() % 4 != 0) args += " "; } args += arg2; @@ -93,22 +95,6 @@ m88100disasm::Exec(saddr_t laddr) return true; } -// ピーク (IP を進めずワードを取得する) -uint32 -m88100disasm::peek() -{ - // 物理空間から取り込む - return m88200_phys_peek_32(phys_xip); -} - -// フェッチ -uint32 -m88100disasm::fetch() -{ - opX = peek(); - return opX; -} - // フィールド部品 #define B5 ((opX >> 21) & 0x1f) #define M5 ((opX >> 21) & 0x1f) @@ -148,10 +134,17 @@ m88100disasm::d16() return string_format("0x%08x", xip + D16); } +std::string +m88100disasm::d26() +{ + return string_format("0x%08x", xip + D26); +} + // 制御レジスタ名 std::string m88100disasm::crs() { + // CRS フィールドは 6 bit。ただし CR20 までしか存在しない uint32 cr = (opX >> 5) & 0x3f; static const char *crnames[] = { "pid", "psr", "epsr", "ssbr", // cr0..3 @@ -159,7 +152,7 @@ m88100disasm::crs() "dmt0", "dmd0", "dma0", // cr8..10 "dmt1", "dmd1", "dma1", // cr11..13 "dmt2", "dmd2", "dma2", // cr14..16 - "sr0," "sr1", "sr2", "sr3", // cr17..20 + "sr0", "sr1", "sr2", "sr3", // cr17..20 }; if (cr < countof(crnames)) { @@ -231,8 +224,8 @@ m88100disasm::cio() uint32 c = (opX >> 8) & 3; static const char *carrystr[] = { "", - ".ci", ".co", + ".ci", ".cio", }; return std::string(carrystr[c]); @@ -274,148 +267,111 @@ m88100disasm::op_unimpl() name = "unimplemented"; } -// 000000_DDDDDSSSSS_nnnnnn_nnnnnnnnnn -OP_DEF(xmem_bu_imm) +// ld_imm, st_imm, xmem_imm の共通部 +// namebase にはサイズプレフィックスを含む。 +void +m88100disasm::ops_ldst_imm(const std::string& namebase) { - name = "xmem.bu"; + name = namebase; arg0 = rd(); arg1 = rs1(); arg2 = imm16(); } +// 000000_DDDDDSSSSS_nnnnnn_nnnnnnnnnn +OP_DEF(xmem_bu_imm) +{ + ops_ldst_imm("xmem.bu"); +} + // 000001_DDDDDSSSSS_nnnnnn_nnnnnnnnnn OP_DEF(xmem_w_imm) { - name = "xmem"; - arg0 = rd(); - arg1 = rs1(); - arg2 = imm16(); + ops_ldst_imm("xmem"); } // 000010_DDDDDSSSSS_nnnnnn_nnnnnnnnnn OP_DEF(ld_hu_imm) { - name = "ld.hu"; - arg0 = rd(); - arg1 = rs1(); - arg2 = imm16(); + ops_ldst_imm("ld.hu"); } // 000011_DDDDDSSSSS_nnnnnn_nnnnnnnnnn OP_DEF(ld_bu_imm) { - name = "ld.bu"; - arg0 = rd(); - arg1 = rs1(); - arg2 = imm16(); + ops_ldst_imm("ld.bu"); } // 000100_DDDDDSSSSS_nnnnnn_nnnnnnnnnn OP_DEF(ld_d_imm) { - name = "ld.d"; - arg0 = rd(); - arg1 = rs1(); - arg2 = imm16(); + ops_ldst_imm("ld.d"); } // 000101_DDDDDSSSSS_nnnnnn_nnnnnnnnnn OP_DEF(ld_w_imm) { - name = "ld"; - arg0 = rd(); - arg1 = rs1(); - arg2 = imm16(); + ops_ldst_imm("ld"); } // 000110_DDDDDSSSSS_nnnnnn_nnnnnnnnnn OP_DEF(ld_h_imm) { - name = "ld.h"; - arg0 = rd(); - arg1 = rs1(); - arg2 = imm16(); + ops_ldst_imm("ld.h"); } // 000111_DDDDDSSSSS_nnnnnn_nnnnnnnnnn OP_DEF(ld_b_imm) { - name = "ld.b"; - arg0 = rd(); - arg1 = rs1(); - arg2 = imm16(); + ops_ldst_imm("ld.b"); } // 001000_DDDDDSSSSS_nnnnnn_nnnnnnnnnn OP_DEF(st_d_imm) { - name = "st.d"; - arg0 = rd(); - arg1 = rs1(); - arg2 = imm16(); + ops_ldst_imm("st.d"); } // 001001_DDDDDSSSSS_nnnnnn_nnnnnnnnnn OP_DEF(st_w_imm) { - name = "st"; - arg0 = rd(); - arg1 = rs1(); - arg2 = imm16(); + ops_ldst_imm("st"); } // 001010_DDDDDSSSSS_nnnnnn_nnnnnnnnnn OP_DEF(st_h_imm) { - name = "st.h"; - arg0 = rd(); - arg1 = rs1(); - arg2 = imm16(); + ops_ldst_imm("st.h"); } // 001011_DDDDDSSSSS_nnnnnn_nnnnnnnnnn OP_DEF(st_b_imm) { - name = "st.b"; - arg0 = rd(); - arg1 = rs1(); - arg2 = imm16(); + ops_ldst_imm("st.b"); } // 001100_DDDDDSSSSS_nnnnnn_nnnnnnnnnn OP_DEF(lda_d_imm) { - name = "lda.d"; - arg0 = rd(); - arg1 = rs1(); - arg2 = imm16(); + ops_ldst_imm("lda.d"); } // 001101_DDDDDSSSSS_nnnnnn_nnnnnnnnnn OP_DEF(lda_w_imm) { - name = "lda"; - arg0 = rd(); - arg1 = rs1(); - arg2 = imm16(); + ops_ldst_imm("lda"); } // 001110_DDDDDSSSSS_nnnnnn_nnnnnnnnnn OP_DEF(lda_h_imm) { - name = "lda.h"; - arg0 = rd(); - arg1 = rs1(); - arg2 = imm16(); + ops_ldst_imm("lda.h"); } // 001111_DDDDDSSSSS_nnnnnn_nnnnnnnnnn OP_DEF(lda_b_imm) { - name = "lda.b"; - arg0 = rd(); - arg1 = rs1(); - arg2 = imm16(); + ops_ldst_imm("lda.b"); } // 010000_DDDDDSSSSS_nnnnnn_nnnnnnnnnn @@ -617,7 +573,7 @@ OP_DEF(xcr) name = "xcr"; arg0 = rd(); arg1 = rs1(); - arg2 = fcrs(); + arg2 = crs(); } else { // どうすべ OP_FUNC(unimpl); @@ -721,28 +677,28 @@ OP_DEF(fdiv) OP_DEF(br) { name = "br"; - arg0 = string_format("%08x", xip + D26); + arg0 = d26(); } // 110001_nnnnnnnnnn_nnnnnn_nnnnnnnnnn OP_DEF(br_n) { name = "br.n"; - arg0 = string_format("%08x", xip + D26); + arg0 = d26(); } // 110010_nnnnnnnnnn_nnnnnn_nnnnnnnnnn OP_DEF(bsr) { name = "bsr"; - arg0 = string_format("%08x", xip + D26); + arg0 = d26(); } // 110011_nnnnnnnnnn_nnnnnn_nnnnnnnnnn OP_DEF(bsr_n) { name = "bsr.n"; - arg0 = string_format("%08x", xip + D26); + arg0 = d26(); } // bb の共通部 @@ -872,7 +828,17 @@ OP_DEF(tb0) // 111100_bbbbbSSSSS_110110_0vvvvvvvvv OP_DEF(tb1) { - ops_tb("tb1"); + if (opt_alias && m88100opf_S1(opX) == 0) { + // tb1 *,r0,* はパイプライン同期を目的として使われる。 + // この形式はトラップは発生しない。 + if (VEC9 < 128) { + name = "ssync"; + } else { + name = "usync"; + } + } else { + ops_tb("tb1"); + } } // 111100_MMMMMSSSSS_111010_0vvvvvvvvv @@ -1043,10 +1009,17 @@ OP_DEF(xor_c) // 111101_DDDDDSSSSS_010110_00000sssss OP_DEF(or) { - name = "or"; - arg0 = rd(); - arg1 = rs1(); - arg2 = rs2(); + if (opt_alias && m88100opf_D(opX) == 0) { + // or r0,*,* は nop とする + // and とかも nop だが motolora が サンプルコードで + // or r0,r0,r0 を nop として使っているため、or が一般的なようだ。 + name = "nop"; + } else { + name = "or"; + arg0 = rd(); + arg1 = rs1(); + arg2 = rs2(); + } } // 111101_DDDDDSSSSS_010111_00000sssss @@ -1212,6 +1185,22 @@ OP_DEF(jsr_n) arg0 = rs2(); } +// 111101_DDDDDzzzzz_111010_00000sssss +OP_DEF(ff1) +{ + name = "ff1"; + arg0 = rd(); + arg1 = rs2(); +} + +// 111101_DDDDDzzzzz_111011_00000sssss +OP_DEF(ff0) +{ + name = "ff0"; + arg0 = rd(); + arg1 = rs2(); +} + // 111101_zzzzzzzzzz_111111_0000000000 OP_DEF(rte) {