From 1be6b82b346cd9a966449a3c0eaa8a7b31c71c5e Mon Sep 17 00:00:00 2001 From: Patrick Mackinlay Date: Tue, 5 Feb 2019 19:19:30 +0700 Subject: alpha: disassembler improvements (nw) * added palcode disassembly * added standard pseudo-opcode forms --- src/devices/cpu/alpha/alpha.cpp | 13 +- src/devices/cpu/alpha/alpha.h | 10 +- src/devices/cpu/alpha/alphad.cpp | 431 ++++++++++++++++++++++++++++++++++++--- src/devices/cpu/alpha/alphad.h | 15 +- src/tools/unidasm.cpp | 3 + 5 files changed, 431 insertions(+), 41 deletions(-) diff --git a/src/devices/cpu/alpha/alpha.cpp b/src/devices/cpu/alpha/alpha.cpp index 1dc11ca7292..62fbd1bb584 100644 --- a/src/devices/cpu/alpha/alpha.cpp +++ b/src/devices/cpu/alpha/alpha.cpp @@ -15,10 +15,10 @@ #include "emu.h" #include "alpha.h" -#include "alphad.h" #include "debugger.h" +#include "softfloat3/source/include/softfloat.h" #define LOG_GENERAL (1U << 0) #define LOG_EXCEPTION (1U << 1) @@ -38,6 +38,7 @@ dec_21064_device::dec_21064_device(const machine_config &mconfig, const char *ta alpha_device::alpha_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : cpu_device(mconfig, type, tag, owner, clock) , m_main_config("main", ENDIANNESS_LITTLE, 64, 32, 0) + , m_dasm_type(alpha_disassembler::dasm_type::TYPE_UNKNOWN) , m_icount(0) { } @@ -66,11 +67,17 @@ void alpha_device::device_start() void alpha_device::device_reset() { + m_pc = 0; } void alpha_device::execute_run() { - m_icount = 0; + while (m_icount > 0) + { + debugger_instruction_hook(m_pc); + + m_icount--; + } } void alpha_device::execute_set_input(int inputnum, int state) @@ -89,5 +96,5 @@ bool alpha_device::memory_translate(int spacenum, int intention, offs_t &address std::unique_ptr alpha_device::create_disassembler() { - return std::make_unique(); + return std::make_unique(m_dasm_type); } diff --git a/src/devices/cpu/alpha/alpha.h b/src/devices/cpu/alpha/alpha.h index a4d66e806c7..b4f5db3712b 100644 --- a/src/devices/cpu/alpha/alpha.h +++ b/src/devices/cpu/alpha/alpha.h @@ -6,13 +6,12 @@ #pragma once -#include -#include "softfloat/milieu.h" -#include "softfloat/softfloat.h" +#include "alphad.h" class alpha_device : public cpu_device { public: + void set_dasm_type(alpha_disassembler::dasm_type type) { m_dasm_type = type; } protected: alpha_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); @@ -36,8 +35,11 @@ protected: virtual std::unique_ptr create_disassembler() override; private: - // emulation state + // configuration address_space_config m_main_config; + alpha_disassembler::dasm_type m_dasm_type; + + // emulation state int m_icount; u64 m_pc; diff --git a/src/devices/cpu/alpha/alphad.cpp b/src/devices/cpu/alpha/alphad.cpp index 3282036ba0a..73e74294a0e 100644 --- a/src/devices/cpu/alpha/alphad.cpp +++ b/src/devices/cpu/alpha/alphad.cpp @@ -30,11 +30,13 @@ #define OPERATE_FR(opcode, ra, rc) util::stream_format(stream, "%-10s %s, %s", opcode, F[ra], R[rc]) #define OPERATE_IR(opcode, im, rc) util::stream_format(stream, "%-10s #%d, %s", opcode, im, R[rc]) #define OPERATE_R(opcode, rc) util::stream_format(stream, "%-10s %s", opcode, R[rc]) +#define OPERATE_F(opcode, rc) util::stream_format(stream, "%-10s %s", opcode, F[rc]) #define MEMORY_R(opcode, ra, disp, rb) util::stream_format(stream, "%-10s %s, %d(%s)", opcode, R[ra], disp, R[rb]) #define MEMORY_F(opcode, ra, disp, rb) util::stream_format(stream, "%-10s %s, %d(%s)", opcode, F[ra], disp, R[rb]) #define BRANCH_R(opcode, ra, offset) util::stream_format(stream, "%-10s %s, 0x%x", opcode, R[ra], pc + 4 + offset) #define BRANCH_F(opcode, ra, offset) util::stream_format(stream, "%-10s %s, 0x%x", opcode, F[ra], pc + 4 + offset) +#define BRANCH(opcode, offset) util::stream_format(stream, "%-10s 0x%x", opcode, pc + 4 + offset) #define JUMP(opcode, ra, rb) util::stream_format(stream, "%-10s %s, (%s)", opcode, R[ra], R[rb]) @@ -76,13 +78,211 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da { // pal format case 0x00: - switch (instruction & 0x03ffffff) + switch (m_dasm_type) { + case TYPE_UNKNOWN: + switch (instruction & 0x03ffffff) + { case 0x0000: PAL_0("halt"); break; case 0x0002: PAL_0("draina"); break; case 0x0086: PAL_0("imb"); break; - default: PAL("call_pal", instruction & 0x03ffffff); break; // CALL_PAL + default: PAL("call_pal", instruction & 0x03ffffff); break; + } + break; + + case TYPE_NT: + switch (instruction & 0x03ffffff) + { + // Windows NT unprivileged PALcode + case 0x0080: PAL_0("bpt"); break; // breakpoint trap + case 0x0083: PAL_0("callsys"); break; // call system service + case 0x0086: PAL_0("imb"); break; // instruction memory barrier + case 0x00aa: PAL_0("gentrap"); break; // generate trap + case 0x00ab: PAL_0("rdteb"); break; // read TEB internal processor register + case 0x00ac: PAL_0("kbpt"); break; // kernel breakpoint trap + case 0x00ad: PAL_0("callkd"); break; // call kernel debugger + + // Windows NT privileged PALcode + case 0x0000: PAL_0("halt"); break; // trap to illegal instruction + case 0x0001: PAL_0("restart"); break; // restart the processor + case 0x0002: PAL_0("draina"); break; // drain aborts + case 0x0003: PAL_0("reboot"); break; // transfer to console firmware + case 0x0004: PAL_0("initpal"); break; // initialize the PALcode + case 0x0005: PAL_0("wrentry"); break; // write system entry + case 0x0006: PAL_0("swpirql"); break; // swap IRQL + case 0x0007: PAL_0("rdirql"); break; // read current IRQL + case 0x0008: PAL_0("di"); break; // disable interrupts + case 0x0009: PAL_0("ei"); break; // enable interrupts + case 0x000a: PAL_0("swppal"); break; // swap PALcode + case 0x000c: PAL_0("ssir"); break; // set software interrupt request + case 0x000d: PAL_0("csir"); break; // clear software interrupt request + case 0x000e: PAL_0("rfe"); break; // return from exception + case 0x000f: PAL_0("retsys"); break; // return from system service call + case 0x0010: PAL_0("swpctx"); break; // swap privileged thread context + case 0x0011: PAL_0("swpprocess"); break; // swap privileged process context + case 0x0012: PAL_0("rdmces"); break; // read machine check error summary + case 0x0013: PAL_0("wrmces"); break; // write machine check error summary + case 0x0014: PAL_0("tbia"); break; // translation buffer invalidate all + case 0x0015: PAL_0("tbis"); break; // translation buffer invalidate single + case 0x0016: PAL_0("dtbis"); break; // data translation buffer invalidate single + case 0x0017: PAL_0("tbisasn"); break; // translation buffer invalidate single ASN + case 0x0018: PAL_0("rdksp"); break; // read initial kernel stack + case 0x0019: PAL_0("swpksp"); break; // swap initial kernel stack + case 0x001a: PAL_0("rdpsr"); break; // read processor status register + case 0x001c: PAL_0("rdpcr"); break; // read PCR (processor control registers) + case 0x001e: PAL_0("rdthread"); break; // read the current thread value + case 0x0020: PAL_0("wrperfmon"); break; // write performance monitoring values + case 0x0030: PAL_0("rdcounters"); break; // read PALcode event counters + case 0x0031: PAL_0("rdstate"); break; // read internal processor state + + default: PAL("call_pal", instruction & 0x03ffffff); break; + } + break; + + case TYPE_UNIX: + switch (instruction & 0x03ffffff) + { + // Digital UNIX unprivileged PALcode + case 0x0080: PAL_0("bpt"); break; // breakpoint trap + case 0x0081: PAL_0("bugchk"); break; // bugcheck + case 0x0083: PAL_0("callsys"); break; // system call + case 0x0086: PAL_0("imb"); break; // i-stream memory barrier + case 0x0092: PAL_0("urti"); break; // return from user mode trap + case 0x009e: PAL_0("rdunique"); break; // read unique value + case 0x009f: PAL_0("wrunique"); break; // write unique value + case 0x00aa: PAL_0("gentrap"); break; // generate software trap + case 0x00ae: PAL_0("clrfen"); break; // clear floating-point enable + + // Digital UNIX privileged PALcode + case 0x0000: PAL_0("halt"); break; // halt the processor + case 0x0001: PAL_0("cflush"); break; // cache flush + case 0x0002: PAL_0("draina"); break; // drain aborts + case 0x0009: PAL_0("cserve"); break; // console service + case 0x000a: PAL_0("swppal"); break; // swap PALcode image + case 0x000d: PAL_0("wripir"); break; // write interprocessor interrupt request + case 0x0010: PAL_0("rdmces"); break; // read machine check error summary register + case 0x0011: PAL_0("wrmces"); break; // write machine check error summary register + case 0x002b: PAL_0("wrfen"); break; // write floating-point enable + case 0x002d: PAL_0("wrvptptr"); break; // write virtual page table pointer + case 0x0030: PAL_0("swpctx"); break; // swap privileged context + case 0x0031: PAL_0("wrval"); break; // write system value + case 0x0032: PAL_0("rdval"); break; // read system value + case 0x0033: PAL_0("tbi"); break; // translation buffer invalidate + case 0x0034: PAL_0("wrent"); break; // write system entry address + case 0x0035: PAL_0("swpipl"); break; // swap interrupt priority level + case 0x0036: PAL_0("rdps"); break; // read processor status + case 0x0037: PAL_0("wrkgp"); break; // write kernel global pointer + case 0x0038: PAL_0("wrusp"); break; // write user stack pointer + case 0x0039: PAL_0("wrperfmon"); break; // performance monitoring function + case 0x003a: PAL_0("rdusp"); break; // read user stack pointer + case 0x003c: PAL_0("whami"); break; // who am I + case 0x003d: PAL_0("retsys"); break; // return from system call + case 0x003e: PAL_0("wtint"); break; // wait for interrupt + case 0x003f: PAL_0("rti"); break; // return from trap or interrupt + + default: PAL("call_pal", instruction & 0x03ffffff); break; + } + break; + + case TYPE_VMS: + switch (instruction & 0x03ffffff) + { + // OpenVMS unprivileged PALcode + case 0x0080: PAL_0("bpt"); break; // breakpoint + case 0x0081: PAL_0("bugchk"); break; // bugcheck + case 0x0082: PAL_0("chme"); break; // change mode to executive + case 0x0083: PAL_0("chmk"); break; // change mode to kernel + case 0x0084: PAL_0("chms"); break; // change mode to supervisor + case 0x0085: PAL_0("chmu"); break; // change mode to user + case 0x0086: PAL_0("imb"); break; // i-stream memory barrier + case 0x0087: PAL_0("insqhil"); break; // insert into longword queue at head interlocked + case 0x0088: PAL_0("insqtil"); break; // insert into longword queue at tail interlocked + case 0x0089: PAL_0("insqhiq"); break; // insert into quadword queue at head interlocked + case 0x008a: PAL_0("insqtiq"); break; // insert into quadword queue at tail interlocked + case 0x008b: PAL_0("insquel"); break; // insert entry into longword queue + case 0x008c: PAL_0("insqueq"); break; // insert entry into quadword queue + case 0x008d: PAL_0("insquel/d"); break; // insert entry into longword queue deferred + case 0x008e: PAL_0("insqueq/d"); break; // insert entry into quadword queue deferred + case 0x008f: PAL_0("prober"); break; // probe for read access + case 0x0090: PAL_0("probew"); break; // probe for write access + case 0x0091: PAL_0("rd_ps"); break; // move processor status + case 0x0092: PAL_0("rei"); break; // return from exception or interrupt + case 0x0093: PAL_0("remqhil"); break; // remove from longword queue at head interlocked + case 0x0094: PAL_0("remqtil"); break; // remove from longword queue at tail interlocked + case 0x0095: PAL_0("remqhiq"); break; // remove from quadword queue at head interlocked + case 0x0096: PAL_0("remqtiq"); break; // remove from quadword queue at tail interlocked + case 0x0097: PAL_0("remquel"); break; // remove entry from longword queue + case 0x0098: PAL_0("remqueq"); break; // remove entry from quadword queue + case 0x0099: PAL_0("remquel/d"); break; // remove entry from longword queue deferred + case 0x009a: PAL_0("remqueq/d"); break; // remove entry from quadword queue deferred + case 0x009b: PAL_0("swasten"); break; // swap AST enable for current mode + case 0x009c: PAL_0("wr_ps_sw"); break; // write processor status software field + case 0x009d: PAL_0("rscc"); break; // read system cycle counter + case 0x009e: PAL_0("read_unq"); break; // read unique context + case 0x009f: PAL_0("write_unq"); break; // write unique context + case 0x00a0: PAL_0("amovrr"); break; // atomic move from register to register + case 0x00a1: PAL_0("amovrm"); break; // atomic move from register to memory + case 0x00a2: PAL_0("insqhilr"); break; // insert into longword queue at head interlocked resident + case 0x00a3: PAL_0("insqtilr"); break; // insert into longword queue at tail interlocked resident + case 0x00a4: PAL_0("insqhiqr"); break; // insert into quadword queue at head interlocked resident + case 0x00a5: PAL_0("insqtiqr"); break; // insert into quadword queue at tail interlocked resident + case 0x00a6: PAL_0("remqhilr"); break; // remove from longword queue at head interlocked resident + case 0x00a7: PAL_0("remqtilr"); break; // remove from longword queue at tail interlocked resident + case 0x00a8: PAL_0("remqhiqr"); break; // remove from quadword queue at head interlocked resident + case 0x00a9: PAL_0("remqtiqr"); break; // remove from quadword queue at tail interlocked resident + case 0x00aa: PAL_0("gentrap"); break; // generate software trap + case 0x00ae: PAL_0("clrfen"); break; // clear floating-point enable + + // OpenVMS privileged PALcode + case 0x0000: PAL_0("halt"); break; // halt processor + case 0x0001: PAL_0("cflush"); break; // cache flush + case 0x0002: PAL_0("draina"); break; // drain aborts + case 0x0003: PAL_0("ldqp"); break; // load quadword physical + case 0x0004: PAL_0("stqp"); break; // store quadword physical + case 0x0005: PAL_0("swpctx"); break; // swap privileged context + case 0x0006: PAL_0("mfpr_asn"); break; // move from processor register ASN + case 0x0009: PAL_0("cserve"); break; // console service + case 0x000a: PAL_0("swppal"); break; // swap PALcode image + case 0x000b: PAL_0("mfpr_fen"); break; // move from processor register FEN + case 0x000c: PAL_0("mtpr_fen"); break; // move to processor register FEN + case 0x000d: PAL_0("mtpr_ipir"); break; // move to processor register IPRI + case 0x000e: PAL_0("mfpr_ipl"); break; // move from processor register IPL + case 0x000f: PAL_0("mtpr_ipl"); break; // move to processor register IPL + case 0x0010: PAL_0("mfpr_mces"); break; // move from processor register MCES + case 0x0011: PAL_0("mtpr_mces"); break; // move to processor register MCES + case 0x0012: PAL_0("mfpr_pcbb"); break; // move from processor register PCBB + case 0x0013: PAL_0("mfpr_prbr"); break; // move from processor register PRBR + case 0x0014: PAL_0("mtpr_prbr"); break; // move to processor register PRBR + case 0x0015: PAL_0("mfpr_ptbr"); break; // move from processor register PTBR + case 0x0016: PAL_0("mfpr_scbb"); break; // move from processor register SCBB + case 0x0017: PAL_0("mtpr_scbb"); break; // move to processor register SCBB + case 0x0018: PAL_0("mtpr_sirr"); break; // move to processor register SIRR + case 0x0019: PAL_0("mfpr_sisr"); break; // move from processor register SISR + case 0x001a: PAL_0("mfpr_tbchk"); break; // move from processor register TBCHK + case 0x001b: PAL_0("mtpr_tbia"); break; // move to processor register TBIA + case 0x001c: PAL_0("mtpr_tbiap"); break; // move to processor register TBIAP + case 0x001d: PAL_0("mtpr_tbis"); break; // move to processor register TBIS + case 0x001e: PAL_0("mfpr_esp"); break; // move from processor register ESP + case 0x001f: PAL_0("mtpr_esp"); break; // move to processor register ESP + case 0x0020: PAL_0("mfpr_ssp"); break; // move from processor register SSP + case 0x0021: PAL_0("mtpr_ssp"); break; // move to processor register SSP + case 0x0022: PAL_0("mfpr_usp"); break; // move from processor register USP + case 0x0023: PAL_0("mtpr_usp"); break; // move to processor register USP + case 0x0024: PAL_0("mtpr_tbisd"); break; // move to processor register TBISD + case 0x0025: PAL_0("mtpr_tbisi"); break; // move to processor register TBISI + case 0x0026: PAL_0("mtpr_asten"); break; // move to processor register ASTEN + case 0x0027: PAL_0("mtpr_astsr"); break; // move to processor register ASTSR + case 0x0029: PAL_0("mfpr_vptb"); break; // move from processor register VPTB + case 0x002a: PAL_0("mtpr_vptb"); break; // move to processor register VPTB + case 0x002b: PAL_0("mtpr_perfmon"); break; // move to processor register PERFMON + case 0x002e: PAL_0("mtpr_datfx"); break; // move to processor register DATFX + case 0x003e: PAL_0("wtint"); break; // wait for interrupt + case 0x003f: PAL_0("mfpr_whami"); break; // move from processor register WHAMI + + default: PAL("call_pal", instruction & 0x03ffffff); break; + } + break; } break; @@ -96,10 +296,20 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da case 0x07: RESERVED("opc07"); break; // OPC07 // memory format - case 0x08: MEMORY_R("lda", Ra(instruction), Disp_M(instruction), Rb(instruction)); break; // LDA + case 0x08: + if (Rb(instruction) == 31) + OPERATE_IR("mov", Disp_M(instruction), Ra(instruction)); + else + MEMORY_R("lda", Ra(instruction), Disp_M(instruction), Rb(instruction)); // LDA + break; case 0x09: MEMORY_R("ldah", Ra(instruction), Disp_M(instruction), Rb(instruction)); break; // LDAH case 0x0a: MEMORY_R("ldbu", Ra(instruction), Disp_M(instruction), Rb(instruction)); break; // LDBU (BWX) - case 0x0b: MEMORY_R("ldq_u", Ra(instruction), Disp_M(instruction), Rb(instruction)); break; // LDQ_U + case 0x0b: + if (Ra(instruction) == 31 && Disp_M(instruction) == 0) + MISC_0("unop"); + else + MEMORY_R("ldq_u", Ra(instruction), Disp_M(instruction), Rb(instruction)); // LDQ_U + break; case 0x0c: MEMORY_R("ldwu", Ra(instruction), Disp_M(instruction), Rb(instruction)); break; // LDWU (BWX) case 0x0d: MEMORY_R("stw", Ra(instruction), Disp_M(instruction), Rb(instruction)); break; // STW (BWX) case 0x0e: MEMORY_R("stb", Ra(instruction), Disp_M(instruction), Rb(instruction)); break; // STB (BWX) @@ -110,9 +320,19 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da switch ((instruction >> 5) & 0xff) { // register variants - case 0x00: OPERATE_RRR("addl", Ra(instruction), Rb(instruction), Rc(instruction)); break; // ADDL + case 0x00: + if (Ra(instruction) == 31) + OPERATE_RR("sextl", Rb(instruction), Rc(instruction)); + else + OPERATE_RRR("addl", Ra(instruction), Rb(instruction), Rc(instruction)); // ADDL + break; case 0x02: OPERATE_RRR("s4addl", Ra(instruction), Rb(instruction), Rc(instruction)); break; // S4ADDL - case 0x09: OPERATE_RRR("subl", Ra(instruction), Rb(instruction), Rc(instruction)); break; // SUBL + case 0x09: + if (Ra(instruction) == 31) + OPERATE_RR("negl", Rb(instruction), Rc(instruction)); + else + OPERATE_RRR("subl", Ra(instruction), Rb(instruction), Rc(instruction)); // SUBL + break; case 0x0b: OPERATE_RRR("s4subl", Ra(instruction), Rb(instruction), Rc(instruction)); break; // S4SUBL case 0x0f: OPERATE_RRR("cmpbge", Ra(instruction), Rb(instruction), Rc(instruction)); break; // CMPBGE case 0x12: OPERATE_RRR("s8addl", Ra(instruction), Rb(instruction), Rc(instruction)); break; // S8ADDL @@ -120,23 +340,48 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da case 0x1d: OPERATE_RRR("cmpult", Ra(instruction), Rb(instruction), Rc(instruction)); break; // CMPULT case 0x20: OPERATE_RRR("addq", Ra(instruction), Rb(instruction), Rc(instruction)); break; // ADDQ case 0x22: OPERATE_RRR("s4addq", Ra(instruction), Rb(instruction), Rc(instruction)); break; // S4ADDQ - case 0x29: OPERATE_RRR("subq", Ra(instruction), Rb(instruction), Rc(instruction)); break; // SUBQ + case 0x29: + if (Ra(instruction) == 31) + OPERATE_RR("negq", Rb(instruction), Rc(instruction)); + else + OPERATE_RRR("subq", Ra(instruction), Rb(instruction), Rc(instruction)); // SUBQ + break; case 0x2b: OPERATE_RRR("s4subq", Ra(instruction), Rb(instruction), Rc(instruction)); break; // S4SUBQ case 0x2d: OPERATE_RRR("cmpeq", Ra(instruction), Rb(instruction), Rc(instruction)); break; // CMPEQ case 0x32: OPERATE_RRR("s8addq", Ra(instruction), Rb(instruction), Rc(instruction)); break; // S8ADDQ case 0x3b: OPERATE_RRR("s8subq", Ra(instruction), Rb(instruction), Rc(instruction)); break; // S8SUBQ case 0x3d: OPERATE_RRR("cmpule", Ra(instruction), Rb(instruction), Rc(instruction)); break; // CMPULE case 0x40: OPERATE_RRR("addl/v", Ra(instruction), Rb(instruction), Rc(instruction)); break; // ADDL/V - case 0x49: OPERATE_RRR("subl/v", Ra(instruction), Rb(instruction), Rc(instruction)); break; // SUBL/V + case 0x49: + if (Ra(instruction) == 31) + OPERATE_RR("negl/v", Rb(instruction), Rc(instruction)); + else + OPERATE_RRR("subl/v", Ra(instruction), Rb(instruction), Rc(instruction)); // SUBL/V + break; case 0x4d: OPERATE_RRR("cmplt", Ra(instruction), Rb(instruction), Rc(instruction)); break; // CMPLT case 0x60: OPERATE_RRR("addq/v", Ra(instruction), Rb(instruction), Rc(instruction)); break; // ADDQ/V - case 0x69: OPERATE_RRR("subq/v", Ra(instruction), Rb(instruction), Rc(instruction)); break; // SUBQ/V + case 0x69: + if (Ra(instruction) == 31) + OPERATE_RR("negq/v", Rb(instruction), Rc(instruction)); + else + OPERATE_RRR("subq/v", Ra(instruction), Rb(instruction), Rc(instruction)); // SUBQ/V + break; case 0x6d: OPERATE_RRR("cmple", Ra(instruction), Rb(instruction), Rc(instruction)); break; // CMPLE // immediate variants - case 0x80: OPERATE_RIR("addl", Ra(instruction), Im(instruction), Rc(instruction)); break; // ADDL + case 0x80: + if (Ra(instruction) == 31) + OPERATE_IR("sextl", Im(instruction), Rc(instruction)); + else + OPERATE_RIR("addl", Ra(instruction), Im(instruction), Rc(instruction)); // ADDL + break; case 0x82: OPERATE_RIR("s4addl", Ra(instruction), Im(instruction), Rc(instruction)); break; // S4ADDL - case 0x89: OPERATE_RIR("subl", Ra(instruction), Im(instruction), Rc(instruction)); break; // SUBL + case 0x89: + if (Ra(instruction) == 31) + OPERATE_IR("negl", Im(instruction), Rc(instruction)); + else + OPERATE_RIR("subl", Ra(instruction), Im(instruction), Rc(instruction)); // SUBL + break; case 0x8b: OPERATE_RIR("s4subl", Ra(instruction), Im(instruction), Rc(instruction)); break; // S4SUBL case 0x8f: OPERATE_RIR("cmpbge", Ra(instruction), Im(instruction), Rc(instruction)); break; // CMPBGE case 0x92: OPERATE_RIR("s8addl", Ra(instruction), Im(instruction), Rc(instruction)); break; // S8ADDL @@ -144,17 +389,32 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da case 0x9d: OPERATE_RIR("cmpult", Ra(instruction), Im(instruction), Rc(instruction)); break; // CMPULT case 0xa0: OPERATE_RIR("addq", Ra(instruction), Im(instruction), Rc(instruction)); break; // ADDQ case 0xa2: OPERATE_RIR("s4addq", Ra(instruction), Im(instruction), Rc(instruction)); break; // S4ADDQ - case 0xa9: OPERATE_RIR("subq", Ra(instruction), Im(instruction), Rc(instruction)); break; // SUBQ + case 0xa9: + if (Ra(instruction) == 31) + OPERATE_IR("negq", Im(instruction), Rc(instruction)); + else + OPERATE_RIR("subq", Ra(instruction), Im(instruction), Rc(instruction)); // SUBQ + break; case 0xab: OPERATE_RIR("s4subq", Ra(instruction), Im(instruction), Rc(instruction)); break; // S4SUBQ case 0xad: OPERATE_RIR("cmpeq", Ra(instruction), Im(instruction), Rc(instruction)); break; // CMPEQ case 0xb2: OPERATE_RIR("s8addq", Ra(instruction), Im(instruction), Rc(instruction)); break; // S8ADDQ case 0xbb: OPERATE_RIR("s8subq", Ra(instruction), Im(instruction), Rc(instruction)); break; // S8SUBQ case 0xbd: OPERATE_RIR("cmpule", Ra(instruction), Im(instruction), Rc(instruction)); break; // CMPULE case 0xc0: OPERATE_RIR("addl/v", Ra(instruction), Im(instruction), Rc(instruction)); break; // ADDL/V - case 0xc9: OPERATE_RIR("subl/v", Ra(instruction), Im(instruction), Rc(instruction)); break; // SUBL/V + case 0xc9: + if (Ra(instruction) == 31) + OPERATE_IR("negl/v", Im(instruction), Rc(instruction)); + else + OPERATE_RIR("subl/v", Ra(instruction), Im(instruction), Rc(instruction)); // SUBL/V + break; case 0xcd: OPERATE_RIR("cmplt", Ra(instruction), Im(instruction), Rc(instruction)); break; // CMPLT case 0xe0: OPERATE_RIR("addq/v", Ra(instruction), Im(instruction), Rc(instruction)); break; // ADDQ/V - case 0xe9: OPERATE_RIR("subq/v", Ra(instruction), Im(instruction), Rc(instruction)); break; // SUBQ/V + case 0xe9: + if (Ra(instruction) == 31) + OPERATE_IR("negq/v", Im(instruction), Rc(instruction)); + else + OPERATE_RIR("subq/v", Ra(instruction), Im(instruction), Rc(instruction)); // SUBQ/V + break; case 0xed: OPERATE_RIR("cmple", Ra(instruction), Im(instruction), Rc(instruction)); break; // CMPLE default: UNKNOWN("inta*"); break; @@ -168,10 +428,24 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da case 0x08: OPERATE_RRR("bic", Ra(instruction), Rb(instruction), Rc(instruction)); break; // BIC case 0x14: OPERATE_RRR("cmovlbs", Ra(instruction), Rb(instruction), Rc(instruction)); break; // CMOVLBS case 0x16: OPERATE_RRR("cmovlbc", Ra(instruction), Rb(instruction), Rc(instruction)); break; // CMOVLBC - case 0x20: OPERATE_RRR("bis", Ra(instruction), Rb(instruction), Rc(instruction)); break; // BIS + case 0x20: + if (Ra(instruction) == 31 && Rb(instruction) == 31 && Rc(instruction) == 31) + MISC_0("nop"); + else if (Ra(instruction) == 31 && Rb(instruction) == 31) + OPERATE_R("clr", Rc(instruction)); + else if (Ra(instruction) == Rb(instruction)) + OPERATE_RR("mov", Rb(instruction), Rc(instruction)); + else + OPERATE_RRR("bis", Ra(instruction), Rb(instruction), Rc(instruction)); // BIS + break; case 0x24: OPERATE_RRR("cmoveq", Ra(instruction), Rb(instruction), Rc(instruction)); break; // CMOVEQ case 0x26: OPERATE_RRR("cmovne", Ra(instruction), Rb(instruction), Rc(instruction)); break; // CMOVNE - case 0x28: OPERATE_RRR("ornot", Ra(instruction), Rb(instruction), Rc(instruction)); break; // ORNOT + case 0x28: + if (Ra(instruction) == 31) + OPERATE_RR("not", Rb(instruction), Rc(instruction)); + else + OPERATE_RRR("ornot", Ra(instruction), Rb(instruction), Rc(instruction)); // ORNOT + break; case 0x40: OPERATE_RRR("xor", Ra(instruction), Rb(instruction), Rc(instruction)); break; // XOR case 0x44: OPERATE_RRR("cmovlt", Ra(instruction), Rb(instruction), Rc(instruction)); break; // CMOVLT case 0x46: OPERATE_RRR("cmovge", Ra(instruction), Rb(instruction), Rc(instruction)); break; // CMOVGE @@ -185,10 +459,20 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da case 0x88: OPERATE_RIR("bic", Ra(instruction), Im(instruction), Rc(instruction)); break; // BIC case 0x94: OPERATE_RIR("cmovlbs", Ra(instruction), Im(instruction), Rc(instruction)); break; // CMOVLBS case 0x96: OPERATE_RIR("cmovlbc", Ra(instruction), Im(instruction), Rc(instruction)); break; // CMOVLBC - case 0xa0: OPERATE_RIR("bis", Ra(instruction), Im(instruction), Rc(instruction)); break; // BIS + case 0xa0: + if (Ra(instruction) == 31) + OPERATE_IR("mov", Im(instruction), Rc(instruction)); + else + OPERATE_RIR("bis", Ra(instruction), Im(instruction), Rc(instruction)); // BIS + break; case 0xa4: OPERATE_RIR("cmoveq", Ra(instruction), Im(instruction), Rc(instruction)); break; // CMOVEQ case 0xa6: OPERATE_RIR("cmovne", Ra(instruction), Im(instruction), Rc(instruction)); break; // CMOVNE - case 0xa8: OPERATE_RIR("ornot", Ra(instruction), Im(instruction), Rc(instruction)); break; // ORNOT + case 0xa8: + if (Ra(instruction) == 31) + OPERATE_IR("not", Im(instruction), Rc(instruction)); + else + OPERATE_RIR("ornot", Ra(instruction), Im(instruction), Rc(instruction)); // ORNOT + break; case 0xc0: OPERATE_RIR("xor", Ra(instruction), Im(instruction), Rc(instruction)); break; // XOR case 0xc4: OPERATE_RIR("cmovlt", Ra(instruction), Im(instruction), Rc(instruction)); break; // CMOVLT case 0xc6: OPERATE_RIR("cmovge", Ra(instruction), Im(instruction), Rc(instruction)); break; // CMOVGE @@ -359,12 +643,22 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da case 0x03c: OPERATE_FF("cvtqf/c", Rb(instruction), Rc(instruction)); break; // CVTQF/C case 0x03e: OPERATE_FF("cvtqg/c", Rb(instruction), Rc(instruction)); break; // CVTQG/C case 0x080: OPERATE_FFF("addf", Ra(instruction), Rb(instruction), Rc(instruction)); break; // ADDF - case 0x081: OPERATE_FFF("subf", Ra(instruction), Rb(instruction), Rc(instruction)); break; // SUBF + case 0x081: + if (Ra(instruction) == 31) + OPERATE_FF("negf", Rb(instruction), Rc(instruction)); + else + OPERATE_FFF("subf", Ra(instruction), Rb(instruction), Rc(instruction)); // SUBF + break; case 0x082: OPERATE_FFF("mulf", Ra(instruction), Rb(instruction), Rc(instruction)); break; // MULF case 0x083: OPERATE_FFF("divf", Ra(instruction), Rb(instruction), Rc(instruction)); break; // DIVF case 0x09e: OPERATE_FF("cvtdg", Rb(instruction), Rc(instruction)); break; // CVTDG case 0x0a0: OPERATE_FFF("addg", Ra(instruction), Rb(instruction), Rc(instruction)); break; // ADDG - case 0x0a1: OPERATE_FFF("subg", Ra(instruction), Rb(instruction), Rc(instruction)); break; // SUBG + case 0x0a1: + if (Ra(instruction) == 31) + OPERATE_FF("negg", Rb(instruction), Rc(instruction)); + else + OPERATE_FFF("subg", Ra(instruction), Rb(instruction), Rc(instruction)); // SUBG + break; case 0x0a2: OPERATE_FFF("mulg", Ra(instruction), Rb(instruction), Rc(instruction)); break; // MULG case 0x0a3: OPERATE_FFF("divg", Ra(instruction), Rb(instruction), Rc(instruction)); break; // DIVG case 0x0a5: OPERATE_FFF("cmpgeq", Ra(instruction), Rb(instruction), Rc(instruction)); break; // CMPGEQ @@ -412,12 +706,22 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da case 0x42d: OPERATE_FF("cvtgd/sc", Rb(instruction), Rc(instruction)); break; // CVTGD/SC case 0x42f: OPERATE_FF("cvtgq/sc", Rb(instruction), Rc(instruction)); break; // CVTGQ/SC case 0x480: OPERATE_FFF("addf/s", Ra(instruction), Rb(instruction), Rc(instruction)); break; // ADDF/S - case 0x481: OPERATE_FFF("subf/s", Ra(instruction), Rb(instruction), Rc(instruction)); break; // SUBF/S + case 0x481: + if (Ra(instruction) == 31) + OPERATE_FF("negf/s", Rb(instruction), Rc(instruction)); + else + OPERATE_FFF("subf/s", Ra(instruction), Rb(instruction), Rc(instruction)); // SUBF/S + break; case 0x482: OPERATE_FFF("mulf/s", Ra(instruction), Rb(instruction), Rc(instruction)); break; // MULF/S case 0x483: OPERATE_FFF("divf/s", Ra(instruction), Rb(instruction), Rc(instruction)); break; // DIVF/S case 0x49e: OPERATE_FF("cvtdg/s", Rb(instruction), Rc(instruction)); break; // CVTDG/S case 0x4a0: OPERATE_FFF("addg/s", Ra(instruction), Rb(instruction), Rc(instruction)); break; // ADDG/S - case 0x4a1: OPERATE_FFF("subg/s", Ra(instruction), Rb(instruction), Rc(instruction)); break; // SUBG/S + case 0x4a1: + if (Ra(instruction) == 31) + OPERATE_FF("negg/s", Rb(instruction), Rc(instruction)); + else + OPERATE_FFF("subg/s", Ra(instruction), Rb(instruction), Rc(instruction)); // SUBG/S + break; case 0x4a2: OPERATE_FFF("mulg/s", Ra(instruction), Rb(instruction), Rc(instruction)); break; // MULG/S case 0x4a3: OPERATE_FFF("divg/s", Ra(instruction), Rb(instruction), Rc(instruction)); break; // DIVG/S case 0x4a5: OPERATE_FFF("cmpgeq/s", Ra(instruction), Rb(instruction), Rc(instruction)); break; // CMPGEQ/S @@ -482,11 +786,21 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da case 0x07c: OPERATE_FF("cvtqs/m", Rb(instruction), Rc(instruction)); break; // CVTQS/M case 0x07e: OPERATE_FF("cvtqt/m", Rb(instruction), Rc(instruction)); break; // CVTQT/M case 0x080: OPERATE_FFF("adds", Ra(instruction), Rb(instruction), Rc(instruction)); break; // ADDS - case 0x081: OPERATE_FFF("subs", Ra(instruction), Rb(instruction), Rc(instruction)); break; // SUBS + case 0x081: + if (Ra(instruction) == 31) + OPERATE_FF("negs", Rb(instruction), Rc(instruction)); + else + OPERATE_FFF("subs", Ra(instruction), Rb(instruction), Rc(instruction)); // SUBS + break; case 0x082: OPERATE_FFF("muls", Ra(instruction), Rb(instruction), Rc(instruction)); break; // MULS case 0x083: OPERATE_FFF("divs", Ra(instruction), Rb(instruction), Rc(instruction)); break; // DIVS case 0x0a0: OPERATE_FFF("addt", Ra(instruction), Rb(instruction), Rc(instruction)); break; // ADDT - case 0x0a1: OPERATE_FFF("subt", Ra(instruction), Rb(instruction), Rc(instruction)); break; // SUBT + case 0x0a1: + if (Ra(instruction) == 31) + OPERATE_FF("negt", Rb(instruction), Rc(instruction)); + else + OPERATE_FFF("subt", Ra(instruction), Rb(instruction), Rc(instruction)); // SUBT + break; case 0x0a2: OPERATE_FFF("mult", Ra(instruction), Rb(instruction), Rc(instruction)); break; // MULT case 0x0a3: OPERATE_FFF("divt", Ra(instruction), Rb(instruction), Rc(instruction)); break; // DIVT case 0x0a4: OPERATE_FFF("cmptun", Ra(instruction), Rb(instruction), Rc(instruction)); break; // CMPTUN @@ -571,11 +885,21 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da case 0x56c: OPERATE_FF("cvttts/sum", Rb(instruction), Rc(instruction)); break; // CVTTS/SUM case 0x56f: OPERATE_FF("cvttq/svm", Rb(instruction), Rc(instruction)); break; // CVTTQ/SVM case 0x580: OPERATE_FFF("adds/su", Ra(instruction), Rb(instruction), Rc(instruction)); break; // ADDS/SU - case 0x581: OPERATE_FFF("subs/su", Ra(instruction), Rb(instruction), Rc(instruction)); break; // SUBS/SU + case 0x581: + if (Ra(instruction) == 31) + OPERATE_FF("negs/su", Rb(instruction), Rc(instruction)); + else + OPERATE_FFF("subs/su", Ra(instruction), Rb(instruction), Rc(instruction)); // SUBS/SU + break; case 0x582: OPERATE_FFF("muls/su", Ra(instruction), Rb(instruction), Rc(instruction)); break; // MULS/SU case 0x583: OPERATE_FFF("divs/su", Ra(instruction), Rb(instruction), Rc(instruction)); break; // DIVS/SU case 0x5a0: OPERATE_FFF("addt/su", Ra(instruction), Rb(instruction), Rc(instruction)); break; // ADDT/SU - case 0x5a1: OPERATE_FFF("subt/su", Ra(instruction), Rb(instruction), Rc(instruction)); break; // SUBT/SU + case 0x5a1: + if (Ra(instruction) == 31) + OPERATE_FF("negt/su", Rb(instruction), Rc(instruction)); + else + OPERATE_FFF("subt/su", Ra(instruction), Rb(instruction), Rc(instruction)); // SUBT/SU + break; case 0x5a2: OPERATE_FFF("mult/su", Ra(instruction), Rb(instruction), Rc(instruction)); break; // MULT/SU case 0x5a3: OPERATE_FFF("divt/su", Ra(instruction), Rb(instruction), Rc(instruction)); break; // DIVT/SU case 0x5a4: OPERATE_FFF("cmptun/su", Ra(instruction), Rb(instruction), Rc(instruction)); break; // CMPTUN/SU @@ -620,11 +944,21 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da case 0x77c: OPERATE_FF("cvtqs/suim", Rb(instruction), Rc(instruction)); break; // CVTQS/SUIM case 0x77e: OPERATE_FF("cvtqt/suim", Rb(instruction), Rc(instruction)); break; // CVTQT/SUIM case 0x780: OPERATE_FFF("adds/sui", Ra(instruction), Rb(instruction), Rc(instruction)); break; // ADDS/SUI - case 0x781: OPERATE_FFF("subs/sui", Ra(instruction), Rb(instruction), Rc(instruction)); break; // SUBS/SUI + case 0x781: + if (Ra(instruction) == 31) + OPERATE_FF("negs/sui", Rb(instruction), Rc(instruction)); + else + OPERATE_FFF("subs/sui", Ra(instruction), Rb(instruction), Rc(instruction)); // SUBS/SUI + break; case 0x782: OPERATE_FFF("muls/sui", Ra(instruction), Rb(instruction), Rc(instruction)); break; // MULS/SUI case 0x783: OPERATE_FFF("divs/sui", Ra(instruction), Rb(instruction), Rc(instruction)); break; // DIVS/SUI case 0x7a0: OPERATE_FFF("addt/sui", Ra(instruction), Rb(instruction), Rc(instruction)); break; // ADDT/SUI - case 0x7a1: OPERATE_FFF("subt/sui", Ra(instruction), Rb(instruction), Rc(instruction)); break; // SUBT/SUI + case 0x7a1: + if (Ra(instruction) == 31) + OPERATE_FF("negt/sui", Rb(instruction), Rc(instruction)); + else + OPERATE_FFF("subt/sui", Ra(instruction), Rb(instruction), Rc(instruction)); // SUBT/SUI + break; case 0x7a2: OPERATE_FFF("mult/sui", Ra(instruction), Rb(instruction), Rc(instruction)); break; // MULT/SUI case 0x7a3: OPERATE_FFF("divt/sui", Ra(instruction), Rb(instruction), Rc(instruction)); break; // DIVT/SUI case 0x7ac: OPERATE_FF("cvttts/sui", Rb(instruction), Rc(instruction)); break; // CVTTS/SUI @@ -651,11 +985,37 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da switch ((instruction >> 5) & 0x7ff) { case 0x010: OPERATE_FF("cvtlq", Rb(instruction), Rc(instruction)); break; // CVTLQ - case 0x020: OPERATE_FFF("cpys", Ra(instruction), Rb(instruction), Rc(instruction)); break; // CPYS - case 0x021: OPERATE_FFF("cpysn", Ra(instruction), Rb(instruction), Rc(instruction)); break; // CPYSN + case 0x020: + if (Ra(instruction) == 31 && Rb(instruction) == 31 && Rc(instruction) == 31) + MISC_0("fnop"); + else if (Ra(instruction) == 31 && Rb(instruction) == 31) + OPERATE_F("fclr", Rc(instruction)); + else if (Ra(instruction) == 31) + OPERATE_FF("fabs", Rb(instruction), Rc(instruction)); + else if (Ra(instruction) == Rb(instruction)) + OPERATE_FF("fmov", Rb(instruction), Rc(instruction)); + else + OPERATE_FFF("cpys", Ra(instruction), Rb(instruction), Rc(instruction)); // CPYS + break; + case 0x021: + if (Ra(instruction) == Rb(instruction)) + OPERATE_FF("fneg", Rb(instruction), Rc(instruction)); + else + OPERATE_FFF("cpysn", Ra(instruction), Rb(instruction), Rc(instruction)); // CPYSN + break; case 0x022: OPERATE_FFF("cpyse", Ra(instruction), Rb(instruction), Rc(instruction)); break; // CPYSE - case 0x024: OPERATE_FFF("mt_fpcr", Ra(instruction), Rb(instruction), Rc(instruction)); break; // MT_FPCR - case 0x025: OPERATE_FFF("mf_fpcr", Ra(instruction), Rb(instruction), Rc(instruction)); break; // MF_FPCR + case 0x024: + if (Ra(instruction) == Rb(instruction) && Rb(instruction) == Rc(instruction)) + OPERATE_F("mt_fpcr", Rc(instruction)); + else + OPERATE_FFF("mt_fpcr", Ra(instruction), Rb(instruction), Rc(instruction)); // MT_FPCR + break; + case 0x025: + if (Ra(instruction) == Rb(instruction) && Rb(instruction) == Rc(instruction)) + OPERATE_F("mf_fpcr", Rc(instruction)); + else + OPERATE_FFF("mf_fpcr", Ra(instruction), Rb(instruction), Rc(instruction)); // MF_FPCR + break; case 0x02a: OPERATE_FFF("fcmoveq", Ra(instruction), Rb(instruction), Rc(instruction)); break; // FCMOVEQ case 0x02b: OPERATE_FFF("fcmovne", Ra(instruction), Rb(instruction), Rc(instruction)); break; // FCMOVNE case 0x02c: OPERATE_FFF("fcmovlt", Ra(instruction), Rb(instruction), Rc(instruction)); break; // FCMOVLT @@ -761,7 +1121,12 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da case 0x2f: MEMORY_R("stq_c", Ra(instruction), Disp_M(instruction), Rb(instruction)); break; // STQ_C // branch format - case 0x30: BRANCH_R("br", Ra(instruction), Disp_B(instruction)); break; // BR + case 0x30: + if (Ra(instruction) == 31) + BRANCH("br", Disp_B(instruction)); + else + BRANCH_R("br", Ra(instruction), Disp_B(instruction)); // BR + break; case 0x31: BRANCH_F("fbeq", Ra(instruction), Disp_B(instruction)); break; // FBEQ case 0x32: BRANCH_F("fblt", Ra(instruction), Disp_B(instruction)); break; // FBLT case 0x33: BRANCH_F("fble", Ra(instruction), Disp_B(instruction)); break; // FBLE diff --git a/src/devices/cpu/alpha/alphad.h b/src/devices/cpu/alpha/alphad.h index 09fa4b8a63a..2c6ee827503 100644 --- a/src/devices/cpu/alpha/alphad.h +++ b/src/devices/cpu/alpha/alphad.h @@ -9,7 +9,18 @@ class alpha_disassembler : public util::disasm_interface { public: - alpha_disassembler() = default; + enum dasm_type : unsigned + { + TYPE_UNKNOWN = 0, + TYPE_NT = 1, + TYPE_UNIX = 2, + TYPE_VMS = 3, + }; + + alpha_disassembler(alpha_disassembler::dasm_type type = TYPE_UNKNOWN) + : m_dasm_type(type) + { + }; virtual ~alpha_disassembler() = default; virtual u32 opcode_alignment() const override { return 4; }; @@ -18,6 +29,8 @@ public: private: static char const *const R[]; static char const *const F[]; + + dasm_type const m_dasm_type; }; #endif // MAME_CPU_ALPHA_ALPHAD_H diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp index e0f4bd0b7a2..432a762c028 100644 --- a/src/tools/unidasm.cpp +++ b/src/tools/unidasm.cpp @@ -303,6 +303,9 @@ static const dasm_table_entry dasm_table[] = { "8x300", be, -1, []() -> util::disasm_interface * { return new n8x300_disassembler; } }, { "adsp21xx", le, -2, []() -> util::disasm_interface * { return new adsp21xx_disassembler; } }, { "alpha", le, 0, []() -> util::disasm_interface * { return new alpha_disassembler; } }, + { "alpha_nt", le, 0, []() -> util::disasm_interface * { return new alpha_disassembler(alpha_disassembler::TYPE_NT); } }, + { "alpha_unix", le, 0, []() -> util::disasm_interface * { return new alpha_disassembler(alpha_disassembler::TYPE_UNIX); } }, + { "alpha_vms", le, 0, []() -> util::disasm_interface * { return new alpha_disassembler(alpha_disassembler::TYPE_VMS); } }, { "alpha8201", le, 0, []() -> util::disasm_interface * { return new alpha8201_disassembler; } }, { "alto2", be, -2, []() -> util::disasm_interface * { return new alto2_disassembler; } }, { "am29000", be, 0, []() -> util::disasm_interface * { return new am29000_disassembler; } }, -- cgit v1.2.3