From e8bbea1fc6e94e14768509d322f6c624403ffb36 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Sun, 22 Aug 2021 09:06:15 +1000 Subject: formats, osd, util: Started refactoring file I/O stuff. (#8456) Added more modern generic I/O interfaces with implementation backed by stdio, osd_file and core_file, replacing io_generic. Also replaced core_file's build-in zlib compression with a filter. unzip.cpp, un7z.cpp: Added option to supply abstract I/O interface rather than filename. Converted osd_file, core_file, archive_file, chd_file and device_image_interface to use std::error_condition rather than their own error enums. Allow mounting TI-99 RPK from inside archives. --- src/tools/unidasm.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/tools/unidasm.cpp') diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp index 14e7dbf2c6d..5395bc6ae01 100644 --- a/src/tools/unidasm.cpp +++ b/src/tools/unidasm.cpp @@ -1219,9 +1219,9 @@ int main(int argc, char *argv[]) void *data = nullptr; u32 length = 0; if(std::strcmp(opts.filename, "-") != 0) { - osd_file::error filerr = util::core_file::load(opts.filename, &data, length); - if(filerr != osd_file::error::NONE) { - std::fprintf(stderr, "Error opening file '%s'\n", opts.filename); + std::error_condition filerr = util::core_file::load(opts.filename, &data, length); + if(filerr) { + std::fprintf(stderr, "Error opening file '%s' (%s)\n", opts.filename, filerr.message().c_str()); return 1; } } -- cgit v1.2.3 From ccaa00b3ed00d63b4781270c992e00b63811c85d Mon Sep 17 00:00:00 2001 From: AJR Date: Tue, 31 Aug 2021 12:30:11 -0400 Subject: Move endianness type into lib/util header --- scripts/src/lib.lua | 1 + src/devices/cpu/mips/mips1.cpp | 8 ++-- src/emu/debug/dvmemory.cpp | 2 +- src/emu/emucore.cpp | 2 - src/emu/emucore.h | 44 ++++++++++----------- src/emu/emumem.h | 31 +-------------- src/emu/emumem_mud.cpp | 2 +- src/emu/emumem_mud.h | 6 +-- src/emu/memarray.cpp | 54 +++++++++++++------------- src/frontend/mame/luaengine_mem.cpp | 12 +----- src/lib/util/endianness.h | 76 +++++++++++++++++++++++++++++++++++++ src/tools/unidasm.cpp | 6 ++- 12 files changed, 139 insertions(+), 105 deletions(-) create mode 100644 src/lib/util/endianness.h (limited to 'src/tools/unidasm.cpp') diff --git a/scripts/src/lib.lua b/scripts/src/lib.lua index c24bb015cd4..fd8c5be2c27 100644 --- a/scripts/src/lib.lua +++ b/scripts/src/lib.lua @@ -61,6 +61,7 @@ project "utils" MAME_DIR .. "src/lib/util/delegate.h", MAME_DIR .. "src/lib/util/disasmintf.cpp", MAME_DIR .. "src/lib/util/disasmintf.h", + MAME_DIR .. "src/lib/util/endianness.h", MAME_DIR .. "src/lib/util/flac.cpp", MAME_DIR .. "src/lib/util/flac.h", MAME_DIR .. "src/lib/util/harddisk.cpp", diff --git a/src/devices/cpu/mips/mips1.cpp b/src/devices/cpu/mips/mips1.cpp index c5f18b2989e..9b041123d4d 100644 --- a/src/devices/cpu/mips/mips1.cpp +++ b/src/devices/cpu/mips/mips1.cpp @@ -1057,7 +1057,7 @@ void mips1core_device_base::lwl(u32 const op) offs_t const offset = SIMMVAL + m_r[RSREG]; load(offset, [this, op, offset](u32 temp) { - unsigned const shift = ((offset & 3) ^ ENDIAN_VALUE_LE_BE(m_endianness, 3, 0)) << 3; + unsigned const shift = ((offset & 3) ^ (m_endianness == ENDIANNESS_LITTLE ? 3 : 0)) << 3; m_r[RTREG] = (m_r[RTREG] & ~u32(0xffffffffU << shift)) | (temp << shift); }); @@ -1068,7 +1068,7 @@ void mips1core_device_base::lwr(u32 const op) offs_t const offset = SIMMVAL + m_r[RSREG]; load(offset, [this, op, offset](u32 temp) { - unsigned const shift = ((offset & 0x3) ^ ENDIAN_VALUE_LE_BE(m_endianness, 0, 3)) << 3; + unsigned const shift = ((offset & 0x3) ^ (m_endianness == ENDIANNESS_LITTLE ? 0 : 3)) << 3; m_r[RTREG] = (m_r[RTREG] & ~u32(0xffffffffU >> shift)) | (temp >> shift); }); @@ -1077,7 +1077,7 @@ void mips1core_device_base::lwr(u32 const op) void mips1core_device_base::swl(u32 const op) { offs_t const offset = SIMMVAL + m_r[RSREG]; - unsigned const shift = ((offset & 3) ^ ENDIAN_VALUE_LE_BE(m_endianness, 3, 0)) << 3; + unsigned const shift = ((offset & 3) ^ (m_endianness == ENDIANNESS_LITTLE ? 3 : 0)) << 3; store(offset, m_r[RTREG] >> shift, 0xffffffffU >> shift); } @@ -1085,7 +1085,7 @@ void mips1core_device_base::swl(u32 const op) void mips1core_device_base::swr(u32 const op) { offs_t const offset = SIMMVAL + m_r[RSREG]; - unsigned const shift = ((offset & 3) ^ ENDIAN_VALUE_LE_BE(m_endianness, 0, 3)) << 3; + unsigned const shift = ((offset & 3) ^ (m_endianness == ENDIANNESS_LITTLE ? 0 : 3)) << 3; store(offset, m_r[RTREG] << shift, 0xffffffffU << shift); } diff --git a/src/emu/debug/dvmemory.cpp b/src/emu/debug/dvmemory.cpp index fea8def590e..2e384e90866 100644 --- a/src/emu/debug/dvmemory.cpp +++ b/src/emu/debug/dvmemory.cpp @@ -70,7 +70,7 @@ debug_view_memory_source::debug_view_memory_source(std::string &&name, memory_re , m_blocklength(region.bytes()) , m_numblocks(1) , m_blockstride(0) - , m_offsetxor(ENDIAN_VALUE_NE_NNE(region.endianness(), 0, region.bytewidth() - 1)) + , m_offsetxor(region.endianness() == ENDIANNESS_NATIVE ? 0 : region.bytewidth() - 1) , m_endianness(region.endianness()) , m_prefsize(std::min(region.bytewidth(), 8)) { diff --git a/src/emu/emucore.cpp b/src/emu/emucore.cpp index 84eb5cf11c6..bc6139fe3cf 100644 --- a/src/emu/emucore.cpp +++ b/src/emu/emucore.cpp @@ -13,8 +13,6 @@ #include "emucore.h" #include "osdcore.h" -const char *const endianness_names[2] = { "little", "big" }; - emu_fatalerror::emu_fatalerror(util::format_argument_pack const &args) : emu_fatalerror(0, args) { diff --git a/src/emu/emucore.h b/src/emu/emucore.h index 6c446b812b7..2be0f2f4221 100644 --- a/src/emu/emucore.h +++ b/src/emu/emucore.h @@ -37,6 +37,7 @@ #include "osdcomm.h" #include "coretmpl.h" #include "bitmap.h" +#include "endianness.h" #include "strformat.h" #include "vecstream.h" @@ -78,6 +79,21 @@ using util::bitswap; using util::iabs; using util::string_format; +using endianness_t = util::endianness; + +using util::BYTE_XOR_BE; +using util::BYTE_XOR_LE; +using util::BYTE4_XOR_BE; +using util::BYTE4_XOR_LE; +using util::WORD_XOR_BE; +using util::WORD_XOR_LE; +using util::BYTE8_XOR_BE; +using util::BYTE8_XOR_LE; +using util::WORD2_XOR_BE; +using util::WORD2_XOR_LE; +using util::DWORD_XOR_BE; +using util::DWORD_XOR_LE; + // pen_t is used to represent pixel values in bitmaps typedef u32 pen_t; @@ -150,21 +166,9 @@ union PAIR64 // COMMON CONSTANTS //************************************************************************** -// constants for expression endianness -enum endianness_t -{ - ENDIANNESS_LITTLE, - ENDIANNESS_BIG -}; - -extern const char *const endianness_names[2]; - -// declare native endianness to be one or the other -#ifdef LSB_FIRST -const endianness_t ENDIANNESS_NATIVE = ENDIANNESS_LITTLE; -#else -const endianness_t ENDIANNESS_NATIVE = ENDIANNESS_BIG; -#endif +constexpr endianness_t ENDIANNESS_LITTLE = util::endianness::little; +constexpr endianness_t ENDIANNESS_BIG = util::endianness::big; +constexpr endianness_t ENDIANNESS_NATIVE = util::endianness::native; // M_PI is not part of the C/C++ standards and is not present on @@ -264,16 +268,6 @@ template constexpr auto RADIAN_TO_DEGREE(T const &x) { return (180. template constexpr auto DEGREE_TO_RADIAN(T const &x) { return (M_PI / 180.0) * x; } -// endian-based value: first value is if 'endian' is little-endian, second is if 'endian' is big-endian -#define ENDIAN_VALUE_LE_BE(endian,leval,beval) (((endian) == ENDIANNESS_LITTLE) ? (leval) : (beval)) - -// endian-based value: first value is if native endianness is little-endian, second is if native is big-endian -#define NATIVE_ENDIAN_VALUE_LE_BE(leval,beval) ENDIAN_VALUE_LE_BE(ENDIANNESS_NATIVE, leval, beval) - -// endian-based value: first value is if 'endian' matches native, second is if 'endian' doesn't match native -#define ENDIAN_VALUE_NE_NNE(endian,neval,nneval) (((endian) == ENDIANNESS_NATIVE) ? (neval) : (nneval)) - - //************************************************************************** // EXCEPTION CLASSES //************************************************************************** diff --git a/src/emu/emumem.h b/src/emu/emumem.h index b5deae3dd23..9d56a14ce3c 100644 --- a/src/emu/emumem.h +++ b/src/emu/emumem.h @@ -1567,7 +1567,7 @@ public: fatalerror("Requesting cache() with data width %d while the config says %d\n", 8 << Width, m_config.data_width()); if(Endian != m_config.endianness()) fatalerror("Requesting cache() with endianness %s while the config says %s\n", - endianness_names[Endian], endianness_names[m_config.endianness()]); + util::endian_to_string_view(Endian), util::endian_to_string_view(m_config.endianness())); v.set(this, get_cache_info()); } @@ -1581,7 +1581,7 @@ public: fatalerror("Requesting specific() with data width %d while the config says %d\n", 8 << Width, m_config.data_width()); if(Endian != m_config.endianness()) fatalerror("Requesting spefific() with endianness %s while the config says %s\n", - endianness_names[Endian], endianness_names[m_config.endianness()]); + util::endian_to_string_view(Endian), util::endian_to_string_view(m_config.endianness())); v.set(this, get_specific_info()); } @@ -1966,33 +1966,6 @@ private: #define ACCESSING_BITS_32_63 ((mem_mask & 0xffffffff00000000U) != 0) -// macros for accessing bytes and words within larger chunks - -// read/write a byte to a 16-bit space -#define BYTE_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)) -#define BYTE_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,1)) - -// read/write a byte to a 32-bit space -#define BYTE4_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(3,0)) -#define BYTE4_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,3)) - -// read/write a word to a 32-bit space -#define WORD_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(2,0)) -#define WORD_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,2)) - -// read/write a byte to a 64-bit space -#define BYTE8_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(7,0)) -#define BYTE8_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,7)) - -// read/write a word to a 64-bit space -#define WORD2_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(6,0)) -#define WORD2_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,6)) - -// read/write a dword to a 64-bit space -#define DWORD_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(4,0)) -#define DWORD_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,4)) - - // helpers for checking address alignment #define WORD_ALIGNED(a) (((a) & 1) == 0) #define DWORD_ALIGNED(a) (((a) & 3) == 0) diff --git a/src/emu/emumem_mud.cpp b/src/emu/emumem_mud.cpp index 094e6663a04..b8fed565eea 100644 --- a/src/emu/emumem_mud.cpp +++ b/src/emu/emumem_mud.cpp @@ -35,7 +35,7 @@ template<> u8 mask_to_ukey(u64 mask) (mask & 0x00000000000000ff ? 0x01 : 0x00); } -template memory_units_descriptor::memory_units_descriptor(u8 access_width, u8 access_endian, handler_entry *handler, offs_t addrstart, offs_t addrend, offs_t mask, typename emu::detail::handler_entry_size::uX unitmask, int cswidth) : m_handler(handler), m_access_width(access_width), m_access_endian(access_endian) +template memory_units_descriptor::memory_units_descriptor(u8 access_width, endianness_t access_endian, handler_entry *handler, offs_t addrstart, offs_t addrend, offs_t mask, typename emu::detail::handler_entry_size::uX unitmask, int cswidth) : m_handler(handler), m_access_width(access_width), m_access_endian(access_endian) { u32 bits_per_access = 8 << access_width; constexpr u32 NATIVE_MASK = Width + AddrShift >= 0 ? make_bitmask(Width + AddrShift) : 0; diff --git a/src/emu/emumem_mud.h b/src/emu/emumem_mud.h index 5a95af1a49f..12c8cf92eb5 100644 --- a/src/emu/emumem_mud.h +++ b/src/emu/emumem_mud.h @@ -15,7 +15,7 @@ public: u8 m_offset; }; - memory_units_descriptor(u8 access_width, u8 access_endian, handler_entry *handler, offs_t addrstart, offs_t addrend, offs_t mask, uX unitmask, int cswidth); + memory_units_descriptor(u8 access_width, endianness_t access_endian, handler_entry *handler, offs_t addrstart, offs_t addrend, offs_t mask, uX unitmask, int cswidth); offs_t get_handler_start() const { return m_handler_start; } offs_t get_handler_mask() const { return m_handler_mask; } @@ -24,7 +24,7 @@ public: const std::vector &get_entries_for_key(u8 key) const { return m_entries_for_key.find(key)->second; } u8 get_subunit_width() const { return m_access_width; } - u8 get_subunit_endian() const { return m_access_endian; } + endianness_t get_subunit_endian() const { return m_access_endian; } void set_subunit_handler(handler_entry *handler) { m_handler = handler; } handler_entry *get_subunit_handler() const { return m_handler; } @@ -35,7 +35,7 @@ private: handler_entry *m_handler; std::array m_keymap; u8 m_access_width; - u8 m_access_endian; + endianness_t m_access_endian; void generate(u8 ukey, uX gumask, uX umask, u32 cswidth, u32 bits_per_access, u8 base_shift, s8 shift, u32 active_count); }; diff --git a/src/emu/memarray.cpp b/src/emu/memarray.cpp index 48fde5f90ba..22bfa17b80a 100644 --- a/src/emu/memarray.cpp +++ b/src/emu/memarray.cpp @@ -52,34 +52,34 @@ void memory_array::set(void *base, u32 bytes, int membits, endianness_t endianne m_bytes_per_entry = bpe; // derive data - switch (bpe*1000 + membits*10 + endianness) + switch (bpe*1000 + membits*10 + (endianness == ENDIANNESS_LITTLE ? 0 : 1)) { - case 1*1000 + 8*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read8_from_8; m_write_entry = &memory_array::write8_to_8; break; - case 1*1000 + 8*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read8_from_8; m_write_entry = &memory_array::write8_to_8; break; - case 1*1000 + 16*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read8_from_16le; m_write_entry = &memory_array::write8_to_16le; break; - case 1*1000 + 16*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read8_from_16be; m_write_entry = &memory_array::write8_to_16be; break; - case 1*1000 + 32*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read8_from_32le; m_write_entry = &memory_array::write8_to_32le; break; - case 1*1000 + 32*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read8_from_32be; m_write_entry = &memory_array::write8_to_32be; break; - case 1*1000 + 64*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read8_from_64le; m_write_entry = &memory_array::write8_to_64le; break; - case 1*1000 + 64*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read8_from_64be; m_write_entry = &memory_array::write8_to_64be; break; - - case 2*1000 + 8*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read16_from_8le; m_write_entry = &memory_array::write16_to_8le; break; - case 2*1000 + 8*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read16_from_8be; m_write_entry = &memory_array::write16_to_8be; break; - case 2*1000 + 16*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read16_from_16; m_write_entry = &memory_array::write16_to_16; break; - case 2*1000 + 16*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read16_from_16; m_write_entry = &memory_array::write16_to_16; break; - case 2*1000 + 32*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read16_from_32le; m_write_entry = &memory_array::write16_to_32le; break; - case 2*1000 + 32*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read16_from_32be; m_write_entry = &memory_array::write16_to_32be; break; - case 2*1000 + 64*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read16_from_64le; m_write_entry = &memory_array::write16_to_64le; break; - case 2*1000 + 64*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read16_from_64be; m_write_entry = &memory_array::write16_to_64be; break; - - case 4*1000 + 8*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read32_from_8le; m_write_entry = &memory_array::write32_to_8le; break; - case 4*1000 + 8*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read32_from_8be; m_write_entry = &memory_array::write32_to_8be; break; - case 4*1000 + 16*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read32_from_16le; m_write_entry = &memory_array::write32_to_16le; break; - case 4*1000 + 16*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read32_from_16be; m_write_entry = &memory_array::write32_to_16be; break; - case 4*1000 + 32*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read32_from_32; m_write_entry = &memory_array::write32_to_32; break; - case 4*1000 + 32*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read32_from_32; m_write_entry = &memory_array::write32_to_32; break; - case 4*1000 + 64*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read32_from_64le; m_write_entry = &memory_array::write32_to_64le; break; - case 4*1000 + 64*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read32_from_64be; m_write_entry = &memory_array::write32_to_64be; break; + case 1*1000 + 8*10 + 0: m_read_entry = &memory_array::read8_from_8; m_write_entry = &memory_array::write8_to_8; break; + case 1*1000 + 8*10 + 1: m_read_entry = &memory_array::read8_from_8; m_write_entry = &memory_array::write8_to_8; break; + case 1*1000 + 16*10 + 0: m_read_entry = &memory_array::read8_from_16le; m_write_entry = &memory_array::write8_to_16le; break; + case 1*1000 + 16*10 + 1: m_read_entry = &memory_array::read8_from_16be; m_write_entry = &memory_array::write8_to_16be; break; + case 1*1000 + 32*10 + 0: m_read_entry = &memory_array::read8_from_32le; m_write_entry = &memory_array::write8_to_32le; break; + case 1*1000 + 32*10 + 1: m_read_entry = &memory_array::read8_from_32be; m_write_entry = &memory_array::write8_to_32be; break; + case 1*1000 + 64*10 + 0: m_read_entry = &memory_array::read8_from_64le; m_write_entry = &memory_array::write8_to_64le; break; + case 1*1000 + 64*10 + 1: m_read_entry = &memory_array::read8_from_64be; m_write_entry = &memory_array::write8_to_64be; break; + + case 2*1000 + 8*10 + 0: m_read_entry = &memory_array::read16_from_8le; m_write_entry = &memory_array::write16_to_8le; break; + case 2*1000 + 8*10 + 1: m_read_entry = &memory_array::read16_from_8be; m_write_entry = &memory_array::write16_to_8be; break; + case 2*1000 + 16*10 + 0: m_read_entry = &memory_array::read16_from_16; m_write_entry = &memory_array::write16_to_16; break; + case 2*1000 + 16*10 + 1: m_read_entry = &memory_array::read16_from_16; m_write_entry = &memory_array::write16_to_16; break; + case 2*1000 + 32*10 + 0: m_read_entry = &memory_array::read16_from_32le; m_write_entry = &memory_array::write16_to_32le; break; + case 2*1000 + 32*10 + 1: m_read_entry = &memory_array::read16_from_32be; m_write_entry = &memory_array::write16_to_32be; break; + case 2*1000 + 64*10 + 0: m_read_entry = &memory_array::read16_from_64le; m_write_entry = &memory_array::write16_to_64le; break; + case 2*1000 + 64*10 + 1: m_read_entry = &memory_array::read16_from_64be; m_write_entry = &memory_array::write16_to_64be; break; + + case 4*1000 + 8*10 + 0: m_read_entry = &memory_array::read32_from_8le; m_write_entry = &memory_array::write32_to_8le; break; + case 4*1000 + 8*10 + 1: m_read_entry = &memory_array::read32_from_8be; m_write_entry = &memory_array::write32_to_8be; break; + case 4*1000 + 16*10 + 0: m_read_entry = &memory_array::read32_from_16le; m_write_entry = &memory_array::write32_to_16le; break; + case 4*1000 + 16*10 + 1: m_read_entry = &memory_array::read32_from_16be; m_write_entry = &memory_array::write32_to_16be; break; + case 4*1000 + 32*10 + 0: m_read_entry = &memory_array::read32_from_32; m_write_entry = &memory_array::write32_to_32; break; + case 4*1000 + 32*10 + 1: m_read_entry = &memory_array::read32_from_32; m_write_entry = &memory_array::write32_to_32; break; + case 4*1000 + 64*10 + 0: m_read_entry = &memory_array::read32_from_64le; m_write_entry = &memory_array::write32_to_64le; break; + case 4*1000 + 64*10 + 1: m_read_entry = &memory_array::read32_from_64be; m_write_entry = &memory_array::write32_to_64be; break; default: throw emu_fatalerror("Illegal memory bits/bus width combo in memory_array"); } diff --git a/src/frontend/mame/luaengine_mem.cpp b/src/frontend/mame/luaengine_mem.cpp index 4016ce1d20f..f95ebdb37c2 100644 --- a/src/frontend/mame/luaengine_mem.cpp +++ b/src/frontend/mame/luaengine_mem.cpp @@ -179,17 +179,7 @@ int sol_lua_push(sol::types, lua_State *L, map_handler_type && int sol_lua_push(sol::types, lua_State *L, endianness_t &&value) { - char const *endianness = "unknown"; - switch (value) - { - case endianness_t::ENDIANNESS_BIG: - endianness = "big"; - break; - case endianness_t::ENDIANNESS_LITTLE: - endianness = "little"; - break; - } - return sol::stack::push(L, endianness); + return sol::stack::push(L, util::endian_to_string_view(value)); } diff --git a/src/lib/util/endianness.h b/src/lib/util/endianness.h new file mode 100644 index 00000000000..ec9b226ec5a --- /dev/null +++ b/src/lib/util/endianness.h @@ -0,0 +1,76 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + endianness.h + + Endianness types and utility functions. + +***************************************************************************/ + +#ifndef MAME_LIB_UTIL_ENDIANNESS_H +#define MAME_LIB_UTIL_ENDIANNESS_H + +#pragma once + +#include + + +namespace util { + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// constants for expression endianness +enum class endianness +{ + little, + big, +#ifdef LSB_FIRST + native = little +#else + native = big +#endif +}; + + +//************************************************************************** +// MACROS AND INLINE FUNCTIONS +//************************************************************************** + +constexpr std::string_view endian_to_string_view(endianness e) { return e == endianness::little ? "little" : "big"; } + +// endian-based value: first value is if native endianness is little-endian, second is if native is big-endian +#define NATIVE_ENDIAN_VALUE_LE_BE(leval,beval) ((util::endianness::native == util::endianness::little) ? (leval) : (beval)) + + +// inline functions for accessing bytes and words within larger chunks + +// read/write a byte to a 16-bit space +template constexpr T BYTE_XOR_BE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0); } +template constexpr T BYTE_XOR_LE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(0,1); } + +// read/write a byte to a 32-bit space +template constexpr T BYTE4_XOR_BE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(3,0); } +template constexpr T BYTE4_XOR_LE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(0,3); } + +// read/write a word to a 32-bit space +template constexpr T WORD_XOR_BE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(2,0); } +template constexpr T WORD_XOR_LE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(0,2); } + +// read/write a byte to a 64-bit space +template constexpr T BYTE8_XOR_BE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(7,0); } +template constexpr T BYTE8_XOR_LE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(0,7); } + +// read/write a word to a 64-bit space +template constexpr T WORD2_XOR_BE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(6,0); } +template constexpr T WORD2_XOR_LE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(0,6); } + +// read/write a dword to a 64-bit space +template constexpr T DWORD_XOR_BE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(4,0); } +template constexpr T DWORD_XOR_LE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(0,4); } + +} // namespace util + +#endif // MAME_LIB_UTIL_ENDIANNESS_H diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp index 5395bc6ae01..a78816f87c9 100644 --- a/src/tools/unidasm.cpp +++ b/src/tools/unidasm.cpp @@ -197,6 +197,7 @@ using util::BIT; #include "corefile.h" #include "corestr.h" #include "eminline.h" +#include "endianness.h" #include #include @@ -334,12 +335,13 @@ struct nec_unidasm_t : nec_disassembler::config } nec_unidasm; -enum endianness { le, be }; +static constexpr auto le = util::endianness::little; +static constexpr auto be = util::endianness::big; struct dasm_table_entry { const char * name; - endianness endian; + util::endianness endian; int8_t pcshift; std::function alloc; }; -- cgit v1.2.3 From fb6b0f0cc40210b967743a3b94df81766a7f206c Mon Sep 17 00:00:00 2001 From: AJR Date: Fri, 3 Sep 2021 13:27:48 -0400 Subject: unidasm: Add disassembler for DEC VAX architecture --- scripts/src/cpu.lua | 10 + src/devices/cpu/vax/vaxdasm.cpp | 1120 +++++++++++++++++++++++++++++++++++++++ src/devices/cpu/vax/vaxdasm.h | 38 ++ src/tools/unidasm.cpp | 2 + 4 files changed, 1170 insertions(+) create mode 100644 src/devices/cpu/vax/vaxdasm.cpp create mode 100644 src/devices/cpu/vax/vaxdasm.h (limited to 'src/tools/unidasm.cpp') diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua index a8969301246..0252aef5bc6 100644 --- a/scripts/src/cpu.lua +++ b/scripts/src/cpu.lua @@ -3251,6 +3251,16 @@ if opt_tool(CPUS, "DSP56000") then table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/dsp56000/dsp56000d.h") end +-------------------------------------------------- +-- DEC VAX, disassembler only +--@src/devices/cpu/vax/vax.h,CPUS["VAX"] = true +-------------------------------------------------- + +if opt_tool(CPUS, "VAX") then + table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/vax/vaxdasm.cpp") + table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/vax/vaxdasm.h") +end + -------------------------------------------------- -- DEC VT50/VT52 --@src/devices/cpu/vt50/vt50.h,CPUS["VT50"] = true diff --git a/src/devices/cpu/vax/vaxdasm.cpp b/src/devices/cpu/vax/vaxdasm.cpp new file mode 100644 index 00000000000..d016901692c --- /dev/null +++ b/src/devices/cpu/vax/vaxdasm.cpp @@ -0,0 +1,1120 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + DEC VAX disassembler + + TODO: + * Floating point literal formats + * Vector instruction notation + +***************************************************************************/ + +#include "emu.h" +#include "vaxdasm.h" + +vax_disassembler::vax_disassembler() + : util::disasm_interface() +{ +} + +u32 vax_disassembler::opcode_alignment() const +{ + return 1; +} + +enum class vax_disassembler::mode : u8 +{ + none, + rb, srb, urb, cntb, rw, srw, urw, mskw, rl, srl, url, posl, prl, rq, srq, urq, ro, uro, + mb, mw, ml, mq, mo, + wb, ww, wl, wq, wo, + ab, aw, al, aq, ao, + bb, bw, + vb +}; + +namespace { + +using namespace std::literals; +using mode = vax_disassembler::mode; + +static constexpr bool is_read_mode(mode m) +{ + switch (m) + { + case mode::rb: case mode::srb: case mode::urb: case mode::cntb: + case mode::rw: case mode::srw: case mode::urw: case mode::mskw: + case mode::rl: case mode::srl: case mode::url: case mode::posl: case mode::prl: + case mode::rq: case mode::urq: + case mode::ro: case mode::uro: + return true; + default: + return false; + } +} + +static constexpr bool is_address_mode(mode m) +{ + return m == mode::ab || m == mode::aw || m == mode::al || m == mode::aq || m == mode::ao; +} + +static const std::string_view s_gpr_names[0x10] = +{ + "R0"sv, + "R1"sv, + "R2"sv, + "R3"sv, + "R4"sv, + "R5"sv, + "R6"sv, + "R7"sv, + "R8"sv, + "R9"sv, + "R10"sv, + "R11"sv, + "AP"sv, + "FP"sv, + "SP"sv, + "PC"sv +}; + +static const std::string_view s_pr_names[0xf3] = +{ + "KSP"sv, + "ESP"sv, + "SSP"sv, + "USP"sv, + "ISP"sv, + {}, + "ASN"sv, + "SPTEP"sv, + + "P0BR"sv, + "P0LR"sv, + "P1BR"sv, + "P1LR"sv, + "SBR"sv, + "SLR"sv, + "CPUID"sv, + "WHAMI"sv, + + "PCBB"sv, + "SCBB"sv, + "IPL"sv, + "ASTLVL"sv, + "SIRR"sv, + "SISR"sv, + "IPIR"sv, + "CMIERR"sv, + + "ICCS"sv, + "NICR"sv, + "ICR"sv, + "TODR"sv, + "CSRS"sv, + "CSRD"sv, + "CSTS"sv, + "CSTD"sv, + + "RXCS"sv, + "RXDB"sv, + "TXCS"sv, + "TXDB"sv, + "TBDR"sv, + "CADR"sv, + "MCESR"sv, + "CAER"sv, + + "ACCS"sv, + "SAVGPR"sv, // or ACCR or SAVISP + "SAVPC"sv, + "SAVPSL"sv, + "WCSA"sv, // or MCESR + "WCSD"sv, // or BCWBLK + "WCSL"sv, // or PCIBLK + "TBTAG"sv, + + "SBIFS"sv, + "SBIS"sv, + "SBISC"sv, + "SBIMT"sv, + "SBIER"sv, + "SBITA"sv, + "SBIQC"sv, + "IORESET"sv, + + "MAPEN"sv, + "TBIA"sv, + "TBIS"sv, + "TBDATA"sv, // or TBIASN + "MBRK"sv, // or TBISYS + "PME"sv, + "SID"sv, + "TBCHK"sv, + + "PAMACC"sv, + "PAMLOC"sv, + "CSWP"sv, + "MDECC"sv, + "MENA"sv, + "MDCTL"sv, + "MCCTL"sv, + "MERG"sv, + + "CRBT"sv, + "DFI"sv, + "EHSR"sv, + {}, + "STXCS"sv, + "STXDB"sv, + "ESPA"sv, + "ESPD"sv, + + "RXCS1"sv, + "RXDB1"sv, + "TXCS1"sv, + "TXDB1"sv, + "RXCS2"sv, + "RXDB2"sv, + "TXCS2"sv, + "TXDB2"sv, + + "RXCS3"sv, + "RXDB3"sv, + "TXCS3"sv, + "TXDB3"sv, + "RXCD"sv, + "CACHEX"sv, + "BINID"sv, + "BISTOP"sv, + + {}, + {}, + {}, + {}, + "MEMSIZE"sv, + "KCALL"sv, + "VMPSL"sv, + {}, + + {}, + {}, + "CPUCNF"sv, + "ICIR"sv, + "RXFCT"sv, + "RXPRM"sv, + "TXFCT"sv, + "TXPRM"sv, + + "BCIDX"sv, + "BCBTS"sv, // or BCSTS + "BCP1TS"sv, // or BCCTL + "BCP2TS"sv, // or BCERA + "BCRFR"sv, // or BCBTS + "BCIDX"sv, // or BCDET + "BCSTS"sv, // or BCERT + "BCCTL"sv, + + "BCERR"sv, + "BCFBTS"sv, + "BCFPTS"sv, + "VINTSR"sv, + "PCTAG"sv, // or JTAGCR + "PCIDX"sv, // or ECR + "PCERR"sv, + "PCSTS"sv, + + "NMICTL"sv, + "INOP"sv, + "NMIFSR"sv, + "NMISILO"sv, + "NMIEAR"sv, + "COR"sv, + "REVR1"sv, + "REVR2"sv, // or VPAMODE + + "CLRTOSTS"sv, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + + "VPSR"sv, + "VAER"sv, + "VMAC"sv, + "VTBIA"sv, + "VSAR"sv, + {}, + {}, + {}, + + {}, + {}, + {}, + {}, + {}, + "VIADR"sv, + "VIDLO"sv, + "VIDHI"sv, + + "CCTL"sv, + {}, + "BDCECC"sv, + "BCETSTS"sv, + "BCETIDX"sv, + "BCETAG"sv, + "BCEDSTS"sv, + "BCEDIDX"sv, + + "BCEDHI"sv, + "BCEDLO"sv, + "BCEDECC"sv, + "CEFADR"sv, + "CEFSTS"sv, + {}, + {}, + {}, + + "NESTS"sv, + "NEOADR"sv, + "NEOCMD"sv, + "NEDATHI"sv, + "NEDATLO"sv, + "NEICMD"sv, + {}, + {}, + + "VADR"sv, + "VCMD"sv, + "VQWLO"sv, + "VQWHI"sv, + {}, + {}, + {}, + {}, + + {}, {}, {}, {}, {}, {}, {}, {}, + {}, {}, {}, {}, {}, {}, {}, {}, + + "VMAR"sv, + "VTAG"sv, + "VDATA"sv, + "ICSR"sv, + {}, + {}, + {}, + {}, + + {}, {}, {}, {}, {}, {}, {}, {}, + + {}, + {}, + {}, + {}, + {}, + {}, + {}, + "PAMODE"sv, + + "MMEADR"sv, + "MMEPTE"sv, + "MMESTS"sv, + {}, + "TBADR"sv, + "TBSTS"sv, + {}, + {}, + + "PCADR"sv, + "PCSTS"sv, + "PCCTL"sv +}; + +static const vax_disassembler::opdef s_nonprefix_ops[0x100 - 3] = +{ + { "HALT"sv, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "NOP"sv, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "REI"sv, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, vax_disassembler::STEP_OUT }, + { "BPT"sv, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "RET"sv, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, vax_disassembler::STEP_OUT }, + { "RSB"sv, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, vax_disassembler::STEP_OUT }, + { "LDPCTX"sv, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, vax_disassembler::STEP_OUT }, + { "SVPCTX"sv, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTPS"sv, { mode::rw, mode::ab, mode::rw, mode::ab, mode::none, mode::none }, 0 }, + { "CVTSP"sv, { mode::rw, mode::ab, mode::rw, mode::ab, mode::none, mode::none }, 0 }, + { "INDEX"sv, { mode::rl, mode::rl, mode::rl, mode::rl, mode::rl, mode::wl }, 0 }, + { "CRC"sv, { mode::ab, mode::rl, mode::rw, mode::ab, mode::none, mode::none }, 0 }, + { "PROBER"sv, { mode::rl, mode::rw, mode::ab, mode::none, mode::none, mode::none }, 0 }, + { "PROBEW"sv, { mode::rl, mode::rw, mode::ab, mode::none, mode::none, mode::none }, 0 }, + { "INSQUE"sv, { mode::ab, mode::ab, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "REMQUE"sv, { mode::ab, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + + { "BSBB"sv, { mode::bb, mode::none, mode::none, mode::none, mode::none, mode::none }, vax_disassembler::STEP_OUT }, + { "BRB"sv, { mode::bb, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "BNEQ"sv, { mode::bb, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, // or BNEQU + { "BEQL"sv, { mode::bb, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, // or BEQLU + { "BGTR"sv, { mode::bb, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "BLEQ"sv, { mode::bb, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "JSB"sv, { mode::ab, mode::none, mode::none, mode::none, mode::none, mode::none }, vax_disassembler::STEP_OVER }, + { "JMP"sv, { mode::ab, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "BGEQ"sv, { mode::bb, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "BLSS"sv, { mode::bb, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "BGTRU"sv, { mode::bb, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "BLEQU"sv, { mode::bb, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "BVC"sv, { mode::bb, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "BVS"sv, { mode::bb, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "BCC"sv, { mode::bb, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, // or BGEQU + { "BCS"sv, { mode::bb, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, // or BLSSU + + { "ADDP4"sv, { mode::rw, mode::ab, mode::rw, mode::ab, mode::none, mode::none }, 0 }, + { "ADDP6"sv, { mode::rw, mode::ab, mode::rw, mode::ab, mode::rw, mode::ab }, 0 }, + { "SUBP4"sv, { mode::rw, mode::ab, mode::rw, mode::ab, mode::none, mode::none }, 0 }, + { "SUBP6"sv, { mode::rw, mode::ab, mode::rw, mode::ab, mode::rw, mode::ab }, 0 }, + { "CVTPT"sv, { mode::rw, mode::ab, mode::ab, mode::rw, mode::ab, mode::none }, 0 }, + { "MULP"sv, { mode::rw, mode::ab, mode::rw, mode::ab, mode::rw, mode::ab }, 0 }, + { "CVTTP"sv, { mode::rw, mode::ab, mode::ab, mode::rw, mode::ab, mode::none }, 0 }, + { "DIVP"sv, { mode::rw, mode::ab, mode::rw, mode::ab, mode::rw, mode::ab }, 0 }, + { "MOVC3"sv, { mode::rw, mode::ab, mode::ab, mode::none, mode::none, mode::none }, 0 }, + { "CMPC3"sv, { mode::rw, mode::ab, mode::ab, mode::none, mode::none, mode::none }, 0 }, + { "SCANC"sv, { mode::rw, mode::ab, mode::ab, mode::rb, mode::none, mode::none }, 0 }, + { "SPANC"sv, { mode::rw, mode::ab, mode::ab, mode::rb, mode::none, mode::none }, 0 }, + { "MOVC5"sv, { mode::rw, mode::ab, mode::rb, mode::rw, mode::ab, mode::none }, 0 }, + { "CMPC5"sv, { mode::rw, mode::ab, mode::rb, mode::rw, mode::ab, mode::none }, 0 }, + { "MOVTC"sv, { mode::rw, mode::ab, mode::rb, mode::ab, mode::rw, mode::ab }, 0 }, + { "MOVTUC"sv, { mode::rw, mode::ab, mode::rb, mode::ab, mode::rw, mode::ab }, 0 }, + + { "BSBW"sv, { mode::bw, mode::none, mode::none, mode::none, mode::none, mode::none }, vax_disassembler::STEP_OVER }, + { "BRW"sv, { mode::bw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTWL"sv, { mode::srw, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTWB"sv, { mode::srw, mode::wb, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MOVP"sv, { mode::rw, mode::ab, mode::ab, mode::none, mode::none, mode::none }, 0 }, + { "CMPP3"sv, { mode::rw, mode::ab, mode::ab, mode::none, mode::none, mode::none }, 0 }, + { "CVTPL"sv, { mode::rw, mode::ab, mode::wl, mode::none, mode::none, mode::none }, 0 }, + { "CMPP4"sv, { mode::rw, mode::ab, mode::rw, mode::ab, mode::none, mode::none }, 0 }, + { "EDITPC"sv, { mode::rw, mode::ab, mode::ab, mode::ab, mode::none, mode::none }, 0 }, + { "MATCHC"sv, { mode::rw, mode::ab, mode::rw, mode::ab, mode::none, mode::none }, 0 }, + { "LOCC"sv, { mode::rb, mode::rw, mode::ab, mode::none, mode::none, mode::none }, 0 }, + { "SKPC"sv, { mode::rb, mode::rw, mode::ab, mode::none, mode::none, mode::none }, 0 }, + { "MOVZWL"sv, { mode::rw, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "ACBW"sv, { mode::srw, mode::srw, mode::mw, mode::bw, mode::none, mode::none }, 0 }, + { "MOVAW"sv, { mode::aw, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "PUSHAW"sv, { mode::aw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + + { "ADDF2"sv, { mode::rl, mode::ml, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "ADDF3"sv, { mode::rl, mode::rl, mode::wl, mode::none, mode::none, mode::none }, 0 }, + { "SUBF2"sv, { mode::rl, mode::ml, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "SUBF3"sv, { mode::rl, mode::rl, mode::wl, mode::none, mode::none, mode::none }, 0 }, + { "MULF2"sv, { mode::rl, mode::ml, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MULF3"sv, { mode::rl, mode::rl, mode::wl, mode::none, mode::none, mode::none }, 0 }, + { "DIVF2"sv, { mode::rl, mode::ml, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "DIVF3"sv, { mode::rl, mode::rl, mode::wl, mode::none, mode::none, mode::none }, 0 }, + { "CVTFB"sv, { mode::rl, mode::wb, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTFW"sv, { mode::rl, mode::ww, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTFL"sv, { mode::rl, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTRFL"sv, { mode::rl, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTBF"sv, { mode::srb, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTWF"sv, { mode::srw, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTLF"sv, { mode::srl, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "ACBF"sv, { mode::rl, mode::rl, mode::ml, mode::bw, mode::none, mode::none }, 0 }, + + { "MOVF"sv, { mode::rl, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CMPF"sv, { mode::rl, mode::rl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MNEGF"sv, { mode::rl, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "TSTF"sv, { mode::rl, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "EMODF"sv, { mode::rl, mode::rb, mode::rl, mode::wl, mode::wl, mode::none }, 0 }, + { "POLYF"sv, { mode::rl, mode::rw, mode::ab, mode::none, mode::none, mode::none }, 0 }, + { "CVTFD"sv, { mode::rl, mode::wq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "ADAWI"sv, { mode::rw, mode::mw, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "INSQHI"sv, { mode::ab, mode::aq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "INSQTI"sv, { mode::ab, mode::aq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "REMQHI"sv, { mode::aq, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "REMQTI"sv, { mode::aq, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + + { "ADDD2"sv, { mode::rq, mode::mq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "ADDD3"sv, { mode::rq, mode::rq, mode::wq, mode::none, mode::none, mode::none }, 0 }, + { "SUBD2"sv, { mode::rq, mode::mq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "SUBD3"sv, { mode::rq, mode::rq, mode::wq, mode::none, mode::none, mode::none }, 0 }, + { "MULD2"sv, { mode::rq, mode::mq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MULD3"sv, { mode::rq, mode::rq, mode::wq, mode::none, mode::none, mode::none }, 0 }, + { "DIVD2"sv, { mode::rq, mode::mq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "DIVD3"sv, { mode::rq, mode::rq, mode::wq, mode::none, mode::none, mode::none }, 0 }, + { "CVTDB"sv, { mode::rq, mode::wb, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTDW"sv, { mode::rq, mode::ww, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTDL"sv, { mode::rq, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTRDL"sv, { mode::rq, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTBD"sv, { mode::srb, mode::wq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTWD"sv, { mode::srw, mode::wq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTLD"sv, { mode::srl, mode::wq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "ACBD"sv, { mode::rq, mode::rq, mode::mq, mode::bw, mode::none, mode::none }, 0 }, + + { "MOVD"sv, { mode::rq, mode::wq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CMPD"sv, { mode::rq, mode::rq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MNEGD"sv, { mode::rq, mode::wq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "TSTD"sv, { mode::rq, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "EMODD"sv, { mode::rq, mode::rb, mode::rq, mode::wl, mode::wq, mode::none }, 0 }, + { "POLYD"sv, { mode::rq, mode::rw, mode::ab, mode::none, mode::none, mode::none }, 0 }, + { "CVTDF"sv, { mode::rq, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "ASHL"sv, { mode::cntb, mode::rl, mode::wl, mode::none, mode::none, mode::none }, 0 }, + { "ASHQ"sv, { mode::cntb, mode::rq, mode::wq, mode::none, mode::none, mode::none }, 0 }, + { "EMUL"sv, { mode::rl, mode::rl, mode::rl, mode::wq, mode::none, mode::none }, 0 }, + { "EDIV"sv, { mode::rl, mode::rq, mode::wl, mode::wl, mode::none, mode::none }, 0 }, + { "CLRQ"sv, { mode::wq, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, // or CLRD or CLRG + { "MOVQ"sv, { mode::urq, mode::wq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MOVAQ"sv, { mode::aq, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, // or MOVAD or MOVAG + { "PUSHAQ"sv, { mode::aq, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, // or PUSHAD or PUSHAG + + { "ADDB2"sv, { mode::srb, mode::mb, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "ADDB3"sv, { mode::srb, mode::srb, mode::wb, mode::none, mode::none, mode::none }, 0 }, + { "SUBB2"sv, { mode::srb, mode::mb, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "SUBB3"sv, { mode::srb, mode::srb, mode::wb, mode::none, mode::none, mode::none }, 0 }, + { "MULB2"sv, { mode::srb, mode::mb, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MULB3"sv, { mode::srb, mode::srb, mode::wb, mode::none, mode::none, mode::none }, 0 }, + { "DIVB2"sv, { mode::srb, mode::mb, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "DIVB3"sv, { mode::srb, mode::srb, mode::wb, mode::none, mode::none, mode::none }, 0 }, + { "BISB2"sv, { mode::urb, mode::mb, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "BISB3"sv, { mode::urb, mode::urb, mode::wb, mode::none, mode::none, mode::none }, 0 }, + { "BICB2"sv, { mode::urb, mode::mb, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "BICB3"sv, { mode::urb, mode::urb, mode::wb, mode::none, mode::none, mode::none }, 0 }, + { "XORB2"sv, { mode::urb, mode::mb, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "XORB3"sv, { mode::urb, mode::urb, mode::wb, mode::none, mode::none, mode::none }, 0 }, + { "MNEGB"sv, { mode::srb, mode::wb, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CASEB"sv, { mode::rb, mode::rb, mode::rb, mode::none, mode::none, mode::none }, 0 }, + + { "MOVB"sv, { mode::urb, mode::wb, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CMPB"sv, { mode::srb, mode::srb, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MCOMB"sv, { mode::rb, mode::wb, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "BITB"sv, { mode::urb, mode::urb, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CLRB"sv, { mode::wb, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "TSTB"sv, { mode::rb, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "INCB"sv, { mode::mb, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "DECB"sv, { mode::mb, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTBL"sv, { mode::srb, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTBW"sv, { mode::srb, mode::ww, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MOVZBL"sv, { mode::rb, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MOVZBW"sv, { mode::rb, mode::ww, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "ROTL"sv, { mode::cntb, mode::rl, mode::wl, mode::none, mode::none, mode::none }, 0 }, + { "ACBB"sv, { mode::srb, mode::srb, mode::mb, mode::bw, mode::none, mode::none }, 0 }, + { "MOVAB"sv, { mode::ab, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "PUSHAB"sv, { mode::ab, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + + { "ADDW2"sv, { mode::srw, mode::mw, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "ADDW3"sv, { mode::srw, mode::srw, mode::ww, mode::none, mode::none, mode::none }, 0 }, + { "SUBW2"sv, { mode::srw, mode::mw, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "SUBW3"sv, { mode::srw, mode::srw, mode::ww, mode::none, mode::none, mode::none }, 0 }, + { "MULW2"sv, { mode::srw, mode::mw, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MULW3"sv, { mode::srw, mode::srw, mode::ww, mode::none, mode::none, mode::none }, 0 }, + { "DIVW2"sv, { mode::srw, mode::mw, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "DIVW3"sv, { mode::srw, mode::srw, mode::ww, mode::none, mode::none, mode::none }, 0 }, + { "BISW2"sv, { mode::urw, mode::mw, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "BISW3"sv, { mode::urw, mode::urw, mode::ww, mode::none, mode::none, mode::none }, 0 }, + { "BICW2"sv, { mode::urw, mode::mw, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "BICW3"sv, { mode::urw, mode::urw, mode::ww, mode::none, mode::none, mode::none }, 0 }, + { "XORW2"sv, { mode::urw, mode::mw, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "XORW3"sv, { mode::urw, mode::urw, mode::ww, mode::none, mode::none, mode::none }, 0 }, + { "MNEGW"sv, { mode::srw, mode::ww, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CASEW"sv, { mode::rw, mode::rw, mode::rw, mode::none, mode::none, mode::none }, 0 }, + + { "MOVW"sv, { mode::urw, mode::ww, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CMPW"sv, { mode::srw, mode::srw, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MCOMW"sv, { mode::rw, mode::ww, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "BITW"sv, { mode::urw, mode::urw, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CLRW"sv, { mode::ww, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "TSTW"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "INCW"sv, { mode::mw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "DECW"sv, { mode::mw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "BISPSW"sv, { mode::urw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "BICPSW"sv, { mode::urw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "POPR"sv, { mode::mskw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "PUSHR"sv, { mode::mskw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CHMK"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CHME"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CHMS"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CHMU"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + + { "ADDL2"sv, { mode::srl, mode::ml, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "ADDL3"sv, { mode::srl, mode::srl, mode::wl, mode::none, mode::none, mode::none }, 0 }, + { "SUBL2"sv, { mode::srl, mode::ml, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "SUBL3"sv, { mode::srl, mode::srl, mode::wl, mode::none, mode::none, mode::none }, 0 }, + { "MULL2"sv, { mode::srl, mode::ml, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MULL3"sv, { mode::srl, mode::srl, mode::wl, mode::none, mode::none, mode::none }, 0 }, + { "DIVL2"sv, { mode::srl, mode::ml, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "DIVL3"sv, { mode::srl, mode::srl, mode::wl, mode::none, mode::none, mode::none }, 0 }, + { "BISL2"sv, { mode::url, mode::ml, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "BISL3"sv, { mode::url, mode::url, mode::wl, mode::none, mode::none, mode::none }, 0 }, + { "BICL2"sv, { mode::url, mode::ml, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "BICL3"sv, { mode::url, mode::url, mode::wl, mode::none, mode::none, mode::none }, 0 }, + { "XORL2"sv, { mode::url, mode::ml, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "XORL3"sv, { mode::url, mode::url, mode::wl, mode::none, mode::none, mode::none }, 0 }, + { "MNEGL"sv, { mode::srl, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CASEL"sv, { mode::rl, mode::rl, mode::rl, mode::none, mode::none, mode::none }, 0 }, + + { "MOVL"sv, { mode::url, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CMPL"sv, { mode::srl, mode::srl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MCOML"sv, { mode::rl, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "BITL"sv, { mode::url, mode::url, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CLRL"sv, { mode::wl, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, // or CLRF + { "TSTL"sv, { mode::rl, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "INCL"sv, { mode::ml, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "DECL"sv, { mode::ml, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "ADWC"sv, { mode::rl, mode::ml, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "SBWC"sv, { mode::rl, mode::ml, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MTPR"sv, { mode::url, mode::prl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MFPR"sv, { mode::prl, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MOVPSL"sv, { mode::wl, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "PUSHL"sv, { mode::rl, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MOVAL"sv, { mode::al, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, // or MOVAF + { "PUSHAL"sv, { mode::al, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, // or PUSHAF + + { "BBS"sv, { mode::posl, mode::vb, mode::bb, mode::none, mode::none, mode::none }, 0 }, + { "BBC"sv, { mode::posl, mode::vb, mode::bb, mode::none, mode::none, mode::none }, 0 }, + { "BBSS"sv, { mode::posl, mode::vb, mode::bb, mode::none, mode::none, mode::none }, 0 }, + { "BBCS"sv, { mode::posl, mode::vb, mode::bb, mode::none, mode::none, mode::none }, 0 }, + { "BBSC"sv, { mode::posl, mode::vb, mode::bb, mode::none, mode::none, mode::none }, 0 }, + { "BBCC"sv, { mode::posl, mode::vb, mode::bb, mode::none, mode::none, mode::none }, 0 }, + { "BBSSI"sv, { mode::posl, mode::vb, mode::bb, mode::none, mode::none, mode::none }, 0 }, + { "BBCCI"sv, { mode::posl, mode::vb, mode::bb, mode::none, mode::none, mode::none }, 0 }, + { "BLBS"sv, { mode::posl, mode::bb, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "BLBC"sv, { mode::posl, mode::bb, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "FFS"sv, { mode::posl, mode::cntb, mode::vb, mode::wl, mode::none, mode::none }, 0 }, + { "FFC"sv, { mode::posl, mode::cntb, mode::vb, mode::wl, mode::none, mode::none }, 0 }, + { "CMPV"sv, { mode::posl, mode::cntb, mode::vb, mode::rl, mode::none, mode::none }, 0 }, + { "CMPZV"sv, { mode::posl, mode::cntb, mode::vb, mode::rl, mode::none, mode::none }, 0 }, + { "EXTV"sv, { mode::posl, mode::cntb, mode::vb, mode::wl, mode::none, mode::none }, 0 }, + { "EXTZV"sv, { mode::posl, mode::cntb, mode::vb, mode::wl, mode::none, mode::none }, 0 }, + + { "INSV"sv, { mode::rl, mode::posl, mode::cntb, mode::vb, mode::none, mode::none }, 0 }, + { "ACBL"sv, { mode::srl, mode::srl, mode::ml, mode::bw, mode::none, mode::none }, 0 }, + { "AOBLSS"sv, { mode::srl, mode::ml, mode::bb, mode::none, mode::none, mode::none }, 0 }, + { "AOBLEQ"sv, { mode::srl, mode::ml, mode::bb, mode::none, mode::none, mode::none }, 0 }, + { "SOBGEQ"sv, { mode::ml, mode::bb, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "SOBGTR"sv, { mode::ml, mode::bb, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTLB"sv, { mode::srl, mode::wb, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTLW"sv, { mode::srl, mode::ww, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "ASHP"sv, { mode::cntb, mode::rw, mode::ab, mode::rb, mode::rw, mode::ab }, 0 }, + { "CVTLP"sv, { mode::srb, mode::rw, mode::ab, mode::none, mode::none, mode::none }, 0 }, + { "CALLG"sv, { mode::ab, mode::ab, mode::none, mode::none, mode::none, mode::none }, vax_disassembler::STEP_OVER }, + { "CALLS"sv, { mode::rl, mode::ab, mode::none, mode::none, mode::none, mode::none }, vax_disassembler::STEP_OVER }, + { "XFC"sv, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 } +}; + +static const vax_disassembler::opdef s_fdprefix_ops[0x100 - 0x31] = +{ + { "MFVP"sv, { mode::rw, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTDH"sv, { mode::rq, mode::wo, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTGF"sv, { mode::rq, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VLDL"sv, { mode::rw, mode::ab, mode::rl, mode::none, mode::none, mode::none }, 0 }, + { "VGATHL"sv, { mode::rw, mode::ab, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VLDQ"sv, { mode::rw, mode::ab, mode::rl, mode::none, mode::none, mode::none }, 0 }, + { "VLGATHQ"sv,{ mode::rw, mode::ab, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + + { "ADDG2"sv, { mode::rq, mode::mq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "ADDG3"sv, { mode::rq, mode::rq, mode::wq, mode::none, mode::none, mode::none }, 0 }, + { "SUBG2"sv, { mode::rq, mode::mq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "SUBG3"sv, { mode::rq, mode::rq, mode::wq, mode::none, mode::none, mode::none }, 0 }, + { "MULG2"sv, { mode::rq, mode::mq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MULG3"sv, { mode::rq, mode::rq, mode::wq, mode::none, mode::none, mode::none }, 0 }, + { "DIVG2"sv, { mode::rq, mode::mq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "DIVG3"sv, { mode::rq, mode::rq, mode::wq, mode::none, mode::none, mode::none }, 0 }, + { "CVTGB"sv, { mode::rq, mode::wb, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTGW"sv, { mode::rq, mode::ww, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTGL"sv, { mode::rq, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTRGL"sv, { mode::rq, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTBG"sv, { mode::srb, mode::wq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTWG"sv, { mode::srw, mode::wq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTLG"sv, { mode::srl, mode::wq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "ACBG"sv, { mode::rq, mode::rq, mode::mq, mode::bw, mode::none, mode::none }, 0 }, + + { "MOVG"sv, { mode::rq, mode::wq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CMPG"sv, { mode::rq, mode::rq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MNEGG"sv, { mode::rq, mode::wq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "TSTG"sv, { mode::rq, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "EMODG"sv, { mode::rq, mode::rb, mode::rq, mode::wl, mode::wq, mode::none }, 0 }, + { "POLYG"sv, { mode::rq, mode::rw, mode::ab, mode::none, mode::none, mode::none }, 0 }, + { "CVTGH"sv, { mode::rq, mode::wo, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + + { "ADDH2"sv, { mode::ro, mode::wo, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "ADDH3"sv, { mode::ro, mode::ro, mode::wo, mode::none, mode::none, mode::none }, 0 }, + { "SUBH2"sv, { mode::ro, mode::mo, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "SUBH3"sv, { mode::ro, mode::ro, mode::wo, mode::none, mode::none, mode::none }, 0 }, + { "MULH2"sv, { mode::ro, mode::mo, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MULH3"sv, { mode::ro, mode::ro, mode::wo, mode::none, mode::none, mode::none }, 0 }, + { "DIVH2"sv, { mode::ro, mode::mo, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "DIVH3"sv, { mode::ro, mode::ro, mode::wo, mode::none, mode::none, mode::none }, 0 }, + { "CVTHB"sv, { mode::ro, mode::wb, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTHW"sv, { mode::ro, mode::ww, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTHL"sv, { mode::ro, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTRHL"sv, { mode::ro, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTBH"sv, { mode::srb, mode::wo, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTWH"sv, { mode::srw, mode::wo, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTLH"sv, { mode::srl, mode::wo, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "ACBH"sv, { mode::ro, mode::ro, mode::mq, mode::bw, mode::none, mode::none }, 0 }, + + { "MOVH"sv, { mode::ro, mode::wo, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CMPH"sv, { mode::ro, mode::ro, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MNEGH"sv, { mode::ro, mode::wo, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "TSTH"sv, { mode::ro, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "EMODH"sv, { mode::ro, mode::rb, mode::ro, mode::wl, mode::wo, mode::none }, 0 }, + { "POLYH"sv, { mode::ro, mode::rw, mode::ab, mode::none, mode::none, mode::none }, 0 }, + { "CVTHG"sv, { mode::ro, mode::wq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CLRO"sv, { mode::wo, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, // or CLRH + { "MOVO"sv, { mode::uro, mode::wo, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "MOVAO"sv, { mode::ao, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, // or MOVAH + { "PUSHAO"sv, { mode::ao, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, // or PUSHAH + + { "VVADDL"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSADDL"sv, { mode::rw, mode::rl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVADDG"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSADDG"sv, { mode::rw, mode::rq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVADDF"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSADDF"sv, { mode::rw, mode::rl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVADDD"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSADDD"sv, { mode::rw, mode::rq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVSUBL"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSSUBL"sv, { mode::rw, mode::rl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVSUBG"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSSUBG"sv, { mode::rw, mode::rq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVSUBF"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSSUBF"sv, { mode::rw, mode::rl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVSUBD"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSSUBD"sv, { mode::rw, mode::rq, mode::none, mode::none, mode::none, mode::none }, 0 }, + + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTFH"sv, { mode::rl, mode::wo, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTFG"sv, { mode::rl, mode::wq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "PROBEVMR"sv, { mode::rb, mode::ab, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "PROBEVMW"sv, { mode::rb, mode::ab, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSTL"sv, { mode::rw, mode::ab, mode::rl, mode::none, mode::none, mode::none }, 0 }, + { "VSCATL"sv, { mode::rw, mode::ab, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSTQ"sv, { mode::rw, mode::ab, mode::rl, mode::none, mode::none, mode::none }, 0 }, + { "VSCATQ"sv, { mode::rw, mode::ab, mode::none, mode::none, mode::none, mode::none }, 0 }, + + { "VVMULL"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSMULL"sv, { mode::rw, mode::rl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVMULG"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSMULG"sv, { mode::rw, mode::rq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVMULF"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSMULF"sv, { mode::rw, mode::rl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVMULD"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSMULD"sv, { mode::rw, mode::rq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVDIVL"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSDIVL"sv, { mode::rw, mode::rl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVDIVG"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSDIVG"sv, { mode::rw, mode::rq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVDIVF"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSDIVF"sv, { mode::rw, mode::rl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVDIVD"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSDIVD"sv, { mode::rw, mode::rq, mode::none, mode::none, mode::none, mode::none }, 0 }, + + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + + { "VVCMPL"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSCMPL"sv, { mode::rw, mode::rl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVCMPG"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSCMPG"sv, { mode::rw, mode::rq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVCMPF"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSCMPF"sv, { mode::rw, mode::rl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVCMPD"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSCMPD"sv, { mode::rw, mode::rq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVBISL"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSBISL"sv, { mode::rw, mode::rl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVBICL"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSBICL"sv, { mode::rw, mode::rl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + + { "VVSRLL"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSSRLL"sv, { mode::rw, mode::posl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVSLLL"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSSLLL"sv, { mode::rw, mode::posl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVXORL"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSXORL"sv, { mode::rw, mode::rl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVCNT"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "IOTA"sv, { mode::rw, mode::rl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VVMERGE"sv, { mode::rw, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "VSMERGE"sv, { mode::rw, mode::rq, mode::none, mode::none, mode::none, mode::none }, 0 }, + + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTHF"sv, { mode::ro, mode::wl, mode::none, mode::none, mode::none, mode::none }, 0 }, + { "CVTHD"sv, { mode::ro, mode::wq, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 }, + { {}, { mode::none, mode::none, mode::none, mode::none, mode::none, mode::none }, 0 } +}; + +} // anonymous namespace + +void vax_disassembler::format_immediate(std::ostream &stream, u32 i) const +{ + stream << '#'; + if (i > 9) + stream << "^X"; + util::stream_format(stream, "%X", i); +} + +void vax_disassembler::format_signed(std::ostream &stream, s32 value) const +{ + if (value < 0) + { + stream << '-'; + value = -value; + } + if (u32(value) > 9) + stream << "^X"; + util::stream_format(stream, "%X", u32(value)); +} + +void vax_disassembler::format_relative(std::ostream &stream, u32 pc, s32 displ) const +{ + util::stream_format(stream, "^X%08X", pc + displ); +} + +void vax_disassembler::format_register_mask(std::ostream &stream, u16 mask) const +{ + stream << "^M<"; + + for (int n = 0; mask != 0; n++) + { + assert(n < 16); + if (BIT(mask, n)) + { + stream << s_gpr_names[n]; + mask &= ~(1 << n); + if (mask != 0) + stream << ','; + } + } + + stream << '>'; +} + +offs_t vax_disassembler::disassemble_inst(std::ostream &stream, const vax_disassembler::opdef &inst, offs_t &pc, offs_t ppc, const vax_disassembler::data_buffer &opcodes) const +{ + if (inst.operand[0] == mode::none) + stream << inst.mnemonic; + else + util::stream_format(stream, "%-7s ", inst.mnemonic); + for (int n = 0; n < 6 && inst.operand[n] != mode::none; n++) + { + if (n != 0) + stream << ", "; + if (inst.operand[n] == mode::bb) + { + s8 displacement = opcodes.r8(pc++); + format_relative(stream, pc, s32(displacement)); + } + else if (inst.operand[n] == mode::bw) + { + s16 displacement = opcodes.r16(pc); + pc += 2; + format_relative(stream, pc, s32(displacement)); + } + else + { + u8 opmode = opcodes.r8(pc++); + u8 idxmode = 0; + if (opmode >= 0x40 && opmode < 0x4f) + { + // Indexed mode + idxmode = opmode; + opmode = opcodes.r8(pc++); + } + if (opmode < 0x40 && is_read_mode(inst.operand[n]) && idxmode == 0) + { + // Literal mode + if (inst.operand[n] == mode::mskw) + format_register_mask(stream, opmode); + else if (inst.operand[n] == mode::prl && !s_pr_names[opmode].empty()) + stream << s_pr_names[opmode]; + else if (inst.operand[n] == mode::urb) + util::stream_format(stream, "#^X%02X", opmode); + else if (inst.operand[n] == mode::cntb || inst.operand[n] == mode::posl) + util::stream_format(stream, "#%d", opmode); + else + format_immediate(stream, opmode); + } + else if (opmode < 0x50) + stream << ""; + else if (opmode < 0x60) + { + // Register mode + if (idxmode != 0 || is_address_mode(inst.operand[n])) + stream << ""; + else + stream << s_gpr_names[opmode & 0x0f]; + } + else + { + if (opmode < 0x80) + { + // Register deferred or autodecrement mode + if (opmode >= 0x70) + stream << '-'; + util::stream_format(stream, "(%s)", s_gpr_names[opmode & 0x0f]); + } + else if (opmode < 0xa0) + { + // Autoincrement mode + if (BIT(opmode, 4)) + stream << '@'; + if (opmode == 0x9f) + { + util::stream_format(stream, "#^X%08X", opcodes.r32(pc)); + pc += 4; + } + else if (opmode != 0x8f) + util::stream_format(stream, "(%s)+", s_gpr_names[opmode & 0x0f]); + else switch (inst.operand[n]) + { + case mode::rb: + format_immediate(stream, opcodes.r8(pc++)); + break; + + case mode::srb: + stream << '#'; + format_signed(stream, s8(opcodes.r8(pc++))); + break; + + case mode::urb: + util::stream_format(stream, "#^X%02X", opcodes.r8(pc++)); + break; + + case mode::cntb: + util::stream_format(stream, "#%d", s8(opcodes.r8(pc++))); + break; + + case mode::rw: + format_immediate(stream, opcodes.r16(pc)); + pc += 2; + break; + + case mode::srw: + stream << '#'; + format_signed(stream, s16(opcodes.r16(pc))); + pc += 2; + break; + + case mode::urw: + util::stream_format(stream, "#^X%04X", opcodes.r16(pc)); + pc += 2; + break; + + case mode::mskw: + format_register_mask(stream, opcodes.r16(pc)); + pc += 2; + break; + + case mode::rl: case mode::posl: + format_immediate(stream, opcodes.r32(pc)); + pc += 4; + break; + + case mode::srl: + stream << '#'; + format_signed(stream, s32(opcodes.r32(pc))); + pc += 4; + break; + + case mode::url: + util::stream_format(stream, "#^X%08X", opcodes.r32(pc)); + pc += 4; + break; + + case mode::prl: + { + u32 i = opcodes.r32(pc); + pc += 4; + if (i < std::size(s_pr_names) && !s_pr_names[i].empty()) + stream << s_pr_names[i]; + else + util::stream_format(stream, "#^X%X", i); + break; + } + + case mode::rq: case mode::urq: + util::stream_format(stream, "#^X%016X", opcodes.r64(pc)); + pc += 8; + break; + + case mode::ro: case mode::uro: + util::stream_format(stream, "#^X%016X%016X", opcodes.r64(pc), opcodes.r64(pc + 4)); + pc += 16; + break; + + default: + stream << "(PC)+"; + break; + } + } + else + { + if (BIT(opmode, 4)) + stream << '@'; + + s32 displ; + if (opmode < 0xc0) + { + // Byte displacement mode + displ = s32(s8(opcodes.r8(pc++))); + } + else if (opmode < 0xe0) + { + // Word displacement mode + displ = s32(s16(opcodes.r16(pc))); + pc += 2; + } + else + { + // Long displacement mode + displ = s32(opcodes.r32(pc)); + pc += 4; + } + + if ((opmode & 0x0f) != 0x0f) + { + if (opmode >= 0xe0) + util::stream_format(stream, "^X%X", displ); + else + format_signed(stream, displ); + util::stream_format(stream, "(%s)", s_gpr_names[opmode & 0x0f]); + } + else + format_relative(stream, pc, displ); + } + if (idxmode != 0) + util::stream_format(stream, "[%s]", s_gpr_names[idxmode & 0x0f]); + } + } + } + return (pc - ppc) | inst.flags | SUPPORTED; +} + +offs_t vax_disassembler::disassemble(std::ostream &stream, offs_t pc, const vax_disassembler::data_buffer &opcodes, const vax_disassembler::data_buffer ¶ms) +{ + offs_t ppc = pc; + u8 op = opcodes.r8(pc++); + + if (op >= 0xfd) + { + u8 op2 = opcodes.r8(pc++); + if (op == 0xfd) + { + if (op2 == 0x02) + { + stream << "WAIT"; + return 2 | SUPPORTED; + } + else if (op2 >= 0x31 && !s_fdprefix_ops[op2 - 0x31].mnemonic.empty()) + return disassemble_inst(stream, s_fdprefix_ops[op2 - 0x31], pc, ppc, opcodes); + } + else if (op == 0xff) + { + if (op2 == 0xfe) + { + stream << "BUGW"; + return 2 | SUPPORTED; + } + else if (op2 == 0xfd) + { + stream << "BUGL"; + return 2 | SUPPORTED; + } + } + util::stream_format(stream, "%-8s^X%02X%02X", ".WORD", op2, op); + return 2 | SUPPORTED; + } + else if (s_nonprefix_ops[op].mnemonic.empty()) + { + util::stream_format(stream, "%-8s^X%02X", ".BYTE", op); + return 1 | SUPPORTED; + } + else + return disassemble_inst(stream, s_nonprefix_ops[op], pc, ppc, opcodes); +} diff --git a/src/devices/cpu/vax/vaxdasm.h b/src/devices/cpu/vax/vaxdasm.h new file mode 100644 index 00000000000..e5549d4d59f --- /dev/null +++ b/src/devices/cpu/vax/vaxdasm.h @@ -0,0 +1,38 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +#ifndef MAME_CPU_VAX_VAXDASM_H +#define MAME_CPU_VAX_VAXDASM_H + +#pragma once + +class vax_disassembler : public util::disasm_interface +{ +public: + enum class mode : u8; + + struct opdef + { + std::string_view mnemonic; + mode operand[6]; + u32 flags; + }; + + // construction/destruction + vax_disassembler(); + +protected: + // disassembler overrides + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + // internal helpers + void format_immediate(std::ostream &stream, u32 i) const; + void format_signed(std::ostream &stream, s32 value) const; + void format_relative(std::ostream &stream, u32 pc, s32 displ) const; + void format_register_mask(std::ostream &stream, u16 mask) const; + offs_t disassemble_inst(std::ostream &stream, const opdef &inst, offs_t &pc, offs_t ppc, const data_buffer &opcodes) const; +}; + +#endif // MAME_CPU_VAX_VAXDASM_H diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp index a78816f87c9..dca4793aeac 100644 --- a/src/tools/unidasm.cpp +++ b/src/tools/unidasm.cpp @@ -185,6 +185,7 @@ using util::BIT; #include "cpu/v60/v60d.h" #include "cpu/v810/v810dasm.h" #include "cpu/v850/v850dasm.h" +#include "cpu/vax/vaxdasm.h" #include "cpu/vt50/vt50dasm.h" #include "cpu/vt61/vt61dasm.h" #include "cpu/we32000/we32100d.h" @@ -638,6 +639,7 @@ static const dasm_table_entry dasm_table[] = { "v850", le, 0, []() -> util::disasm_interface * { return new v850_disassembler; } }, { "v850es", le, 0, []() -> util::disasm_interface * { return new v850es_disassembler; } }, { "v850e2", le, 0, []() -> util::disasm_interface * { return new v850e2_disassembler; } }, + { "vax", le, 0, []() -> util::disasm_interface * { return new vax_disassembler; } }, { "vt50", le, 0, []() -> util::disasm_interface * { return new vt50_disassembler; } }, { "vt52", le, 0, []() -> util::disasm_interface * { return new vt52_disassembler; } }, { "vt61", le, -1, []() -> util::disasm_interface * { return new vt61_disassembler; } }, -- cgit v1.2.3