From 245f822e7d6b71cdba5bd79c6657c0fc6a8d0bfd Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Fri, 16 Mar 2018 19:08:38 +1100 Subject: use more constexpr and literal classes in UML to give compiler more optimisation opportunities (nw) --- scripts/src/cpu.lua | 8 +- scripts/target/mame/arcade.lua | 2 +- scripts/target/mame/mess.lua | 2 +- src/devices/cpu/drcfe.cpp | 42 +- src/devices/cpu/drcfe.h | 104 +++-- src/devices/cpu/dsp16/dsp16.cpp | 2 +- src/devices/cpu/dsp16/dsp16dis.cpp | 40 +- src/devices/cpu/dsp16/dsp16dis.h | 8 +- src/devices/cpu/uml.cpp | 835 ++++++++++++++++++------------------- src/devices/cpu/uml.h | 222 +++++----- src/tools/unidasm.cpp | 2 +- 11 files changed, 623 insertions(+), 644 deletions(-) diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua index 39f2bdd75f5..ee4ebc3328f 100644 --- a/scripts/src/cpu.lua +++ b/scripts/src/cpu.lua @@ -253,18 +253,18 @@ if (CPUS["APEXC"]~=null or _OPTIONS["with-tools"]) then end -------------------------------------------------- --- AT&T DSP16A ---@src/devices/cpu/dsp16/dsp16.h,CPUS["DSP16A"] = true +-- WE|AT&T DSP16 +--@src/devices/cpu/dsp16/dsp16.h,CPUS["DSP16"] = true -------------------------------------------------- -if (CPUS["DSP16A"]~=null) then +if (CPUS["DSP16"]~=null) then files { MAME_DIR .. "src/devices/cpu/dsp16/dsp16.cpp", MAME_DIR .. "src/devices/cpu/dsp16/dsp16.h", } end -if (CPUS["DSP16A"]~=null or _OPTIONS["with-tools"]) then +if (CPUS["DSP16"]~=null or _OPTIONS["with-tools"]) then table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/dsp16/dsp16dis.cpp") table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/dsp16/dsp16dis.h") end diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 1f2ab550f8c..809ea30252e 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -61,7 +61,7 @@ CPUS["MIPS"] = true CPUS["R3000"] = true CPUS["PSX"] = true CPUS["SH"] = true -CPUS["DSP16A"] = true +CPUS["DSP16"] = true CPUS["DSP32C"] = true CPUS["PIC16C5X"] = true CPUS["PIC16C62X"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 3c4e1f49a0d..375c3bc9221 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -61,7 +61,7 @@ CPUS["MIPS"] = true CPUS["R3000"] = true CPUS["PSX"] = true CPUS["SH"] = true -CPUS["DSP16A"] = true +CPUS["DSP16"] = true CPUS["DSP32C"] = true CPUS["PIC16C5X"] = true CPUS["PIC16C62X"] = true diff --git a/src/devices/cpu/drcfe.cpp b/src/devices/cpu/drcfe.cpp index dc743f01253..a09ae5c2890 100644 --- a/src/devices/cpu/drcfe.cpp +++ b/src/devices/cpu/drcfe.cpp @@ -19,11 +19,13 @@ #include "drcfe.h" +namespace { + //************************************************************************** // CONSTANTS //************************************************************************** -const uint32_t MAX_STACK_DEPTH = 100; +constexpr u32 MAX_STACK_DEPTH = 100; @@ -38,6 +40,8 @@ struct pc_stack_entry offs_t srcpc; }; +} // anonymous namespace + //************************************************************************** @@ -48,14 +52,14 @@ struct pc_stack_entry // drc_frontend - constructor //------------------------------------------------- -drc_frontend::drc_frontend(device_t &cpu, uint32_t window_start, uint32_t window_end, uint32_t max_sequence) - : m_window_start(window_start), - m_window_end(window_end), - m_max_sequence(max_sequence), - m_cpudevice(downcast(cpu)), - m_program(m_cpudevice.space(AS_PROGRAM)), - m_pageshift(m_cpudevice.space_config(AS_PROGRAM)->m_page_shift), - m_desc_array(window_end + window_start + 2, nullptr) +drc_frontend::drc_frontend(device_t &cpu, u32 window_start, u32 window_end, u32 max_sequence) + : m_window_start(window_start) + , m_window_end(window_end) + , m_max_sequence(max_sequence) + , m_cpudevice(downcast(cpu)) + , m_program(m_cpudevice.space(AS_PROGRAM)) + , m_pageshift(m_cpudevice.space_config(AS_PROGRAM)->m_page_shift) + , m_desc_array(window_end + window_start + 2, nullptr) { } @@ -90,12 +94,12 @@ const opcode_desc *drc_frontend::describe_code(offs_t startpc) pcstackptr++; // loop while we still have a stack - offs_t minpc = startpc - std::min(m_window_start, startpc); - offs_t maxpc = startpc + std::min(m_window_end, 0xffffffff - startpc); + offs_t const minpc = startpc - (std::min)(m_window_start, startpc); + offs_t const maxpc = startpc + (std::min)(m_window_end, 0xffffffff - startpc); while (pcstackptr != &pcstack[0]) { // if we've already hit this PC, just mark it a branch target and continue - pc_stack_entry *curstack = --pcstackptr; + pc_stack_entry *const curstack = --pcstackptr; opcode_desc *curdesc = m_desc_array[curstack->targetpc - minpc]; if (curdesc != nullptr) { @@ -156,10 +160,10 @@ const opcode_desc *drc_frontend::describe_code(offs_t startpc) // slots of branches as well //------------------------------------------------- -opcode_desc *drc_frontend::describe_one(offs_t curpc, const opcode_desc *prevdesc, bool in_delay_slot) +opcode_desc *drc_frontend::describe_one(offs_t curpc, opcode_desc const *prevdesc, bool in_delay_slot) { // initialize the description - opcode_desc *desc = m_desc_allocator.alloc(); + opcode_desc *const desc = m_desc_allocator.alloc(); desc->m_next = nullptr; desc->branch = nullptr; desc->delay.reset(); @@ -208,7 +212,7 @@ opcode_desc *drc_frontend::describe_one(offs_t curpc, const opcode_desc *prevdes } } opcode_desc *prev = desc; - for (uint8_t slotnum = 0; slotnum < desc->delayslots; slotnum++) + for (u8 slotnum = 0; slotnum < desc->delayslots; slotnum++) { // recursively describe the next instruction opcode_desc *delaydesc = describe_one(delaypc, prev, true); @@ -237,7 +241,7 @@ opcode_desc *drc_frontend::describe_one(offs_t curpc, const opcode_desc *prevdes // of instructions //------------------------------------------------- -void drc_frontend::build_sequence(int start, int end, uint32_t endflag) +void drc_frontend::build_sequence(int start, int end, u32 endflag) { // iterate in order from start to end, picking up all non-NULL instructions int consecutive = 0; @@ -250,7 +254,7 @@ void drc_frontend::build_sequence(int start, int end, uint32_t endflag) opcode_desc *curdesc = m_desc_array[descnum]; int nextdescnum = descnum + curdesc->length; opcode_desc *nextdesc = (nextdescnum < end) ? m_desc_array[nextdescnum] : nullptr; - for (uint8_t skipnum = 0; skipnum < curdesc->skipslots && nextdesc != nullptr; skipnum++) + for (u8 skipnum = 0; skipnum < curdesc->skipslots && nextdesc != nullptr; skipnum++) { nextdescnum = nextdescnum + nextdesc->length; nextdesc = (nextdescnum < end) ? m_desc_array[nextdescnum] : nullptr; @@ -302,7 +306,7 @@ void drc_frontend::build_sequence(int start, int end, uint32_t endflag) if (curdesc->flags & OPFLAG_END_SEQUENCE) { // figure out which registers we *must* generate, assuming at the end all must be - uint32_t reqmask[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; + u32 reqmask[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; if (seqstart != -1) for (int backdesc = descnum; backdesc != seqstart - 1; backdesc--) if (m_desc_array[backdesc] != nullptr) @@ -342,7 +346,7 @@ void drc_frontend::build_sequence(int start, int end, uint32_t endflag) // walking in a backwards direction //------------------------------------------------- -void drc_frontend::accumulate_required_backwards(opcode_desc &desc, uint32_t *reqmask) +void drc_frontend::accumulate_required_backwards(opcode_desc &desc, u32 *reqmask) { // recursively handle delay slots if (desc.delay.first() != nullptr) diff --git a/src/devices/cpu/drcfe.h b/src/devices/cpu/drcfe.h index 66b55bcf4fb..a781f6d1156 100644 --- a/src/devices/cpu/drcfe.h +++ b/src/devices/cpu/drcfe.h @@ -28,55 +28,54 @@ a linked list and returned for further processing by the backend. ***************************************************************************/ +#ifndef MAME_CPU_DRCFE_H +#define MAME_CPU_DRCFE_H #pragma once -#ifndef __DRCFE_H__ -#define __DRCFE_H__ - //************************************************************************** // CONSTANTS //************************************************************************** // this defines a branch targetpc that is dynamic at runtime -const offs_t BRANCH_TARGET_DYNAMIC = ~0; +constexpr offs_t BRANCH_TARGET_DYNAMIC = ~offs_t(0); // opcode branch flags -const uint32_t OPFLAG_IS_UNCONDITIONAL_BRANCH = 0x00000001; // instruction is unconditional branch -const uint32_t OPFLAG_IS_CONDITIONAL_BRANCH = 0x00000002; // instruction is conditional branch -const uint32_t OPFLAG_IS_BRANCH = (OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_IS_CONDITIONAL_BRANCH); -const uint32_t OPFLAG_IS_BRANCH_TARGET = 0x00000004; // instruction is the target of a branch -const uint32_t OPFLAG_IN_DELAY_SLOT = 0x00000008; // instruction is in the delay slot of a branch -const uint32_t OPFLAG_INTRABLOCK_BRANCH = 0x00000010; // instruction branches within the block +constexpr u32 OPFLAG_IS_UNCONDITIONAL_BRANCH = 0x00000001; // instruction is unconditional branch +constexpr u32 OPFLAG_IS_CONDITIONAL_BRANCH = 0x00000002; // instruction is conditional branch +constexpr u32 OPFLAG_IS_BRANCH = (OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_IS_CONDITIONAL_BRANCH); +constexpr u32 OPFLAG_IS_BRANCH_TARGET = 0x00000004; // instruction is the target of a branch +constexpr u32 OPFLAG_IN_DELAY_SLOT = 0x00000008; // instruction is in the delay slot of a branch +constexpr u32 OPFLAG_INTRABLOCK_BRANCH = 0x00000010; // instruction branches within the block // opcode exception flags -const uint32_t OPFLAG_CAN_TRIGGER_SW_INT = 0x00000020; // instruction can trigger a software interrupt -const uint32_t OPFLAG_CAN_EXPOSE_EXTERNAL_INT = 0x00000040; // instruction can expose an external interrupt -const uint32_t OPFLAG_CAN_CAUSE_EXCEPTION = 0x00000080; // instruction may generate exception -const uint32_t OPFLAG_WILL_CAUSE_EXCEPTION = 0x00000100; // instruction will generate exception -const uint32_t OPFLAG_PRIVILEGED = 0x00000200; // instruction is privileged +constexpr u32 OPFLAG_CAN_TRIGGER_SW_INT = 0x00000020; // instruction can trigger a software interrupt +constexpr u32 OPFLAG_CAN_EXPOSE_EXTERNAL_INT = 0x00000040; // instruction can expose an external interrupt +constexpr u32 OPFLAG_CAN_CAUSE_EXCEPTION = 0x00000080; // instruction may generate exception +constexpr u32 OPFLAG_WILL_CAUSE_EXCEPTION = 0x00000100; // instruction will generate exception +constexpr u32 OPFLAG_PRIVILEGED = 0x00000200; // instruction is privileged // opcode virtual->physical translation flags -const uint32_t OPFLAG_VALIDATE_TLB = 0x00000400; // instruction must validate TLB before execution -const uint32_t OPFLAG_MODIFIES_TRANSLATION = 0x00000800; // instruction modifies the TLB -const uint32_t OPFLAG_COMPILER_PAGE_FAULT = 0x00001000; // compiler hit a page fault when parsing -const uint32_t OPFLAG_COMPILER_UNMAPPED = 0x00002000; // compiler hit unmapped memory when parsing +constexpr u32 OPFLAG_VALIDATE_TLB = 0x00000400; // instruction must validate TLB before execution +constexpr u32 OPFLAG_MODIFIES_TRANSLATION = 0x00000800; // instruction modifies the TLB +constexpr u32 OPFLAG_COMPILER_PAGE_FAULT = 0x00001000; // compiler hit a page fault when parsing +constexpr u32 OPFLAG_COMPILER_UNMAPPED = 0x00002000; // compiler hit unmapped memory when parsing // opcode flags -const uint32_t OPFLAG_INVALID_OPCODE = 0x00004000; // instruction is invalid -const uint32_t OPFLAG_VIRTUAL_NOOP = 0x00008000; // instruction is a virtual no-op +constexpr u32 OPFLAG_INVALID_OPCODE = 0x00004000; // instruction is invalid +constexpr u32 OPFLAG_VIRTUAL_NOOP = 0x00008000; // instruction is a virtual no-op // opcode sequence flow flags -const uint32_t OPFLAG_REDISPATCH = 0x00010000; // instruction must redispatch after completion -const uint32_t OPFLAG_RETURN_TO_START = 0x00020000; // instruction must jump back to the beginning after completion -const uint32_t OPFLAG_END_SEQUENCE = 0x00040000; // this is the last instruction in a sequence -const uint32_t OPFLAG_CAN_CHANGE_MODES = 0x00080000; // instruction can change modes +constexpr u32 OPFLAG_REDISPATCH = 0x00010000; // instruction must redispatch after completion +constexpr u32 OPFLAG_RETURN_TO_START = 0x00020000; // instruction must jump back to the beginning after completion +constexpr u32 OPFLAG_END_SEQUENCE = 0x00040000; // this is the last instruction in a sequence +constexpr u32 OPFLAG_CAN_CHANGE_MODES = 0x00080000; // instruction can change modes // execution semantics -const uint32_t OPFLAG_READS_MEMORY = 0x00100000; // instruction reads memory -const uint32_t OPFLAG_WRITES_MEMORY = 0x00200000; // instruction writes memory +constexpr u32 OPFLAG_READS_MEMORY = 0x00100000; // instruction reads memory +constexpr u32 OPFLAG_WRITES_MEMORY = 0x00200000; // instruction writes memory @@ -102,25 +101,25 @@ struct opcode_desc // copy of up to 16 bytes of opcode union { - uint8_t b[16]; - uint16_t w[8]; - uint32_t l[4]; - uint64_t q[2]; + u8 b[16]; + u16 w[8]; + u32 l[4]; + u64 q[2]; } opptr; // pointer to opcode memory // information about this instruction's execution - uint8_t length; // length in bytes of this opcode - uint8_t delayslots; // number of delay slots (for branches) - uint8_t skipslots; // number of skip slots (for branches) - uint32_t flags; // OPFLAG_* opcode flags - uint32_t userflags; // core specific flags - uint32_t userdata0; // core specific data - uint32_t cycles; // number of cycles needed to execute + u8 length; // length in bytes of this opcode + u8 delayslots; // number of delay slots (for branches) + u8 skipslots; // number of skip slots (for branches) + u32 flags; // OPFLAG_* opcode flags + u32 userflags; // core specific flags + u32 userdata0; // core specific data + u32 cycles; // number of cycles needed to execute // register usage information - uint32_t regin[4]; // input registers - uint32_t regout[4]; // output registers - uint32_t regreq[4]; // required output registers + u32 regin[4]; // input registers + u32 regout[4]; // output registers + u32 regreq[4]; // required output registers }; @@ -129,27 +128,27 @@ class drc_frontend { public: // construction/destruction - drc_frontend(device_t &cpu, uint32_t window_start, uint32_t window_end, uint32_t max_sequence); + drc_frontend(device_t &cpu, u32 window_start, u32 window_end, u32 max_sequence); virtual ~drc_frontend(); // describe a block - const opcode_desc *describe_code(offs_t startpc); + opcode_desc const *describe_code(offs_t startpc); protected: // required overrides - virtual bool describe(opcode_desc &desc, const opcode_desc *prev) = 0; + virtual bool describe(opcode_desc &desc, opcode_desc const *prev) = 0; private: // internal helpers - opcode_desc *describe_one(offs_t curpc, const opcode_desc *prevdesc, bool in_delay_slot = false); - void build_sequence(int start, int end, uint32_t endflag); - void accumulate_required_backwards(opcode_desc &desc, uint32_t *reqmask); + opcode_desc *describe_one(offs_t curpc, opcode_desc const *prevdesc, bool in_delay_slot = false); + void build_sequence(int start, int end, u32 endflag); + void accumulate_required_backwards(opcode_desc &desc, u32 *reqmask); void release_descriptions(); // configuration parameters - uint32_t m_window_start; // code window start offset = startpc - window_start - uint32_t m_window_end; // code window end offset = startpc + window_end - uint32_t m_max_sequence; // maximum instructions to include in a sequence + u32 m_window_start; // code window start offset = startpc - window_start + u32 m_window_end; // code window end offset = startpc + window_end + u32 m_max_sequence; // maximum instructions to include in a sequence // CPU parameters cpu_device & m_cpudevice; // CPU device object @@ -159,8 +158,7 @@ private: // opcode descriptor arrays simple_list m_desc_live_list; // list of live descriptions fixed_allocator m_desc_allocator; // fixed allocator for descriptions - std::vector m_desc_array; // array of descriptions in PC order + std::vector m_desc_array; // array of descriptions in PC order }; - -#endif /* __DRCFE_H__ */ +#endif // MAME_CPU_DRCFE_H diff --git a/src/devices/cpu/dsp16/dsp16.cpp b/src/devices/cpu/dsp16/dsp16.cpp index 8501bafd9a0..1fca79a8c14 100644 --- a/src/devices/cpu/dsp16/dsp16.cpp +++ b/src/devices/cpu/dsp16/dsp16.cpp @@ -622,7 +622,7 @@ void dsp16_device_base::state_export(device_state_entry const &entry) util::disasm_interface *dsp16_device_base::create_disassembler() { - return new dsp16a_disassembler; + return new dsp16_disassembler; } template READ16_MEMBER(dsp16_device_base::external_memory_r) diff --git a/src/devices/cpu/dsp16/dsp16dis.cpp b/src/devices/cpu/dsp16/dsp16dis.cpp index f5fc87c9afc..683fe488d1a 100644 --- a/src/devices/cpu/dsp16/dsp16dis.cpp +++ b/src/devices/cpu/dsp16/dsp16dis.cpp @@ -3,7 +3,7 @@ #include "emu.h" #include "dsp16dis.h" -std::string dsp16a_disassembler::disasmF1Field(u8 F1, u8 D, u8 S) +std::string dsp16_disassembler::disasmF1Field(u8 F1, u8 D, u8 S) { switch (F1) { @@ -27,7 +27,7 @@ std::string dsp16a_disassembler::disasmF1Field(u8 F1, u8 D, u8 S) return "UNKNOWN"; } -std::string dsp16a_disassembler::disasmYField(u8 Y) +std::string dsp16_disassembler::disasmYField(u8 Y) { switch (Y & 0x03U) { @@ -39,7 +39,7 @@ std::string dsp16a_disassembler::disasmYField(u8 Y) return "UNKNOWN"; } -std::string dsp16a_disassembler::disasmZField(u8 Z) +std::string dsp16_disassembler::disasmZField(u8 Z) { switch (Z & 0x03U) { @@ -51,7 +51,7 @@ std::string dsp16a_disassembler::disasmZField(u8 Z) return "UNKNOWN"; } -std::string dsp16a_disassembler::disasmF2Field(u8 F2, u8 D, u8 S) +std::string dsp16_disassembler::disasmF2Field(u8 F2, u8 D, u8 S) { switch (F2) { @@ -75,7 +75,7 @@ std::string dsp16a_disassembler::disasmF2Field(u8 F2, u8 D, u8 S) return "UNKNOWN"; } -std::string dsp16a_disassembler::disasmCONField(u8 CON) +std::string dsp16_disassembler::disasmCONField(u8 CON) { switch (CON) { @@ -102,7 +102,7 @@ std::string dsp16a_disassembler::disasmCONField(u8 CON) } } -std::string dsp16a_disassembler::disasmBField(u8 B, uint32_t &dasmflags) +std::string dsp16_disassembler::disasmBField(u8 B, u32 &dasmflags) { switch (B) { @@ -118,7 +118,7 @@ std::string dsp16a_disassembler::disasmBField(u8 B, uint32_t &dasmflags) return "UNKNOWN"; } -std::string dsp16a_disassembler::disasmRImmediateField(u8 R) +std::string dsp16_disassembler::disasmRImmediateField(u8 R) { switch (R) { @@ -134,7 +134,7 @@ std::string dsp16a_disassembler::disasmRImmediateField(u8 R) return "UNKNOWN"; } -std::string dsp16a_disassembler::disasmRField(u8 R) +std::string dsp16_disassembler::disasmRField(u8 R) { switch (R) { @@ -170,7 +170,7 @@ std::string dsp16a_disassembler::disasmRField(u8 R) } } -std::string dsp16a_disassembler::disasmIField(u8 I) +std::string dsp16_disassembler::disasmIField(u8 I) { switch (I) { @@ -183,7 +183,7 @@ std::string dsp16a_disassembler::disasmIField(u8 I) } } -bool dsp16a_disassembler::disasmSIField(u8 SI) +bool dsp16_disassembler::disasmSIField(u8 SI) { switch (SI) { @@ -194,27 +194,27 @@ bool dsp16a_disassembler::disasmSIField(u8 SI) } -u32 dsp16a_disassembler::interface_flags() const +u32 dsp16_disassembler::interface_flags() const { return PAGED; } -u32 dsp16a_disassembler::page_address_bits() const +u32 dsp16_disassembler::page_address_bits() const { return 12U; } -u32 dsp16a_disassembler::opcode_alignment() const +u32 dsp16_disassembler::opcode_alignment() const { return 1U; } -offs_t dsp16a_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +offs_t dsp16_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { u8 opSize = 1; - uint32_t dasmflags = 0; - uint16_t op = opcodes.r16(pc); - uint16_t op2 = opcodes.r16(pc+1); + u32 dasmflags = 0; + u16 op = opcodes.r16(pc); + u16 op2 = opcodes.r16(pc+1); // TODO: Test for previous "if CON" instruction and tab the next instruction in? @@ -394,13 +394,13 @@ offs_t dsp16a_disassembler::disassemble(std::ostream &stream, offs_t pc, const d // Format 4: Branch Direct Group case 0x00: case 0x01: // goto JA { - const uint16_t JA = (op & 0x0fff) | (pc & 0xf000); + const u16 JA = (op & 0x0fff) | (pc & 0xf000); util::stream_format(stream, "goto 0x%04x", JA); } break; case 0x10: case 0x11: // call JA { - const uint16_t JA = (op & 0x0fff) | (pc & 0xf000); + const u16 JA = (op & 0x0fff) | (pc & 0xf000); util::stream_format(stream, "call 0x%04x", JA); dasmflags |= STEP_OVER; } @@ -492,7 +492,7 @@ offs_t dsp16a_disassembler::disassemble(std::ostream &stream, offs_t pc, const d // Format 9: Short Immediate Group case 0x02: case 0x03: // R = M { - const uint16_t M = (op & 0x01ff); + const u16 M = (op & 0x01ff); const u8 R = (op & 0x0e00) >> 9; std::string rString = disasmRImmediateField(R); util::stream_format(stream, "set %s = 0x%04x", rString, M); diff --git a/src/devices/cpu/dsp16/dsp16dis.h b/src/devices/cpu/dsp16/dsp16dis.h index 00fafe67a17..09b480733a9 100644 --- a/src/devices/cpu/dsp16/dsp16dis.h +++ b/src/devices/cpu/dsp16/dsp16dis.h @@ -5,11 +5,11 @@ #pragma once -class dsp16a_disassembler : public util::disasm_interface +class dsp16_disassembler : public util::disasm_interface { public: - dsp16a_disassembler() = default; - virtual ~dsp16a_disassembler() = default; + dsp16_disassembler() = default; + virtual ~dsp16_disassembler() = default; virtual u32 interface_flags() const override; virtual u32 page_address_bits() const override; @@ -22,7 +22,7 @@ private: std::string disasmZField(u8 Z); std::string disasmF2Field(u8 F2, u8 D, u8 S); std::string disasmCONField(u8 CON); - std::string disasmBField(u8 B, uint32_t &dasmflags); + std::string disasmBField(u8 B, u32 &dasmflags); std::string disasmRImmediateField(u8 R); std::string disasmRField(u8 R); std::string disasmIField(u8 I); diff --git a/src/devices/cpu/uml.cpp b/src/devices/cpu/uml.cpp index c066e254d1d..6555eff161d 100644 --- a/src/devices/cpu/uml.cpp +++ b/src/devices/cpu/uml.cpp @@ -124,7 +124,7 @@ using namespace uml; #define OPINFO4(op,str,sizes,cond,iflag,oflag,mflag,p0,p1,p2,p3) { OP_##op, str, sizes, cond, OPFLAGS_##iflag, OPFLAGS_##oflag, OPFLAGS_##mflag, { p0, p1, p2, p3 } }, // opcode validation table -const opcode_info instruction::s_opcode_info_table[OP_MAX] = +opcode_info const instruction::s_opcode_info_table[OP_MAX] = { OPINFO0(INVALID, "invalid", 4, false, NONE, NONE, NONE) @@ -227,7 +227,7 @@ const opcode_info instruction::s_opcode_info_table[OP_MAX] = // rol32 - perform a 32-bit left rotate //------------------------------------------------- -inline uint32_t rol32(uint32_t source, uint8_t count) +inline u32 rol32(u32 source, u8 count) { count &= 31; return (source << count) | (source >> (32 - count)); @@ -238,7 +238,7 @@ inline uint32_t rol32(uint32_t source, uint8_t count) // rol64 - perform a 64-bit left rotate //------------------------------------------------- -inline uint64_t rol64(uint64_t source, uint8_t count) +inline u64 rol64(u64 source, u8 count) { count &= 63; return (source << count) | (source >> (64 - count)); @@ -255,10 +255,10 @@ inline uint64_t rol64(uint64_t source, uint8_t count) //------------------------------------------------- uml::code_handle::code_handle(drcuml_state &drcuml, const char *name) - : m_code(reinterpret_cast(drcuml.cache().alloc_near(sizeof(drccodeptr)))), - m_string(name), - m_next(nullptr), - m_drcuml(drcuml) + : m_code(reinterpret_cast(drcuml.cache().alloc_near(sizeof(drccodeptr)))) + , m_string(name) + , m_next(nullptr) + , m_drcuml(drcuml) { if (m_code == nullptr) throw std::bad_alloc(); @@ -283,29 +283,15 @@ void uml::code_handle::set_codeptr(drccodeptr code) // UML INSTRUCTION //************************************************************************** -//------------------------------------------------- -// instruction - constructor -//------------------------------------------------- - -uml::instruction::instruction() - : m_opcode(OP_INVALID), - m_condition(COND_ALWAYS), - m_flags(0), - m_size(4), - m_numparams(0) -{ -} - - //------------------------------------------------- // configure - configure an opcode with no // parameters //------------------------------------------------- -void uml::instruction::configure(opcode_t op, uint8_t size, condition_t condition) +void uml::instruction::configure(opcode_t op, u8 size, condition_t condition) { // fill in the instruction - m_opcode = (opcode_t)(uint8_t)op; + m_opcode = opcode_t(u8(op)); m_size = size; m_condition = condition; m_flags = 0; @@ -321,10 +307,10 @@ void uml::instruction::configure(opcode_t op, uint8_t size, condition_t conditio // parameter //------------------------------------------------- -void uml::instruction::configure(opcode_t op, uint8_t size, parameter p0, condition_t condition) +void uml::instruction::configure(opcode_t op, u8 size, parameter p0, condition_t condition) { // fill in the instruction - m_opcode = (opcode_t)(uint8_t)op; + m_opcode = opcode_t(u8(op)); m_size = size; m_condition = condition; m_flags = 0; @@ -341,10 +327,10 @@ void uml::instruction::configure(opcode_t op, uint8_t size, parameter p0, condit // parameters //------------------------------------------------- -void uml::instruction::configure(opcode_t op, uint8_t size, parameter p0, parameter p1, condition_t condition) +void uml::instruction::configure(opcode_t op, u8 size, parameter p0, parameter p1, condition_t condition) { // fill in the instruction - m_opcode = (opcode_t)(uint8_t)op; + m_opcode = opcode_t(u8(op)); m_size = size; m_condition = condition; m_flags = 0; @@ -362,10 +348,10 @@ void uml::instruction::configure(opcode_t op, uint8_t size, parameter p0, parame // parameters //------------------------------------------------- -void uml::instruction::configure(opcode_t op, uint8_t size, parameter p0, parameter p1, parameter p2, condition_t condition) +void uml::instruction::configure(opcode_t op, u8 size, parameter p0, parameter p1, parameter p2, condition_t condition) { // fill in the instruction - m_opcode = (opcode_t)(uint8_t)op; + m_opcode = opcode_t(u8(op)); m_size = size; m_condition = condition; m_flags = 0; @@ -384,10 +370,10 @@ void uml::instruction::configure(opcode_t op, uint8_t size, parameter p0, parame // parameters //------------------------------------------------- -void uml::instruction::configure(opcode_t op, uint8_t size, parameter p0, parameter p1, parameter p2, parameter p3, condition_t condition) +void uml::instruction::configure(opcode_t op, u8 size, parameter p0, parameter p1, parameter p2, parameter p3, condition_t condition) { // fill in the instruction - m_opcode = (opcode_t)(uint8_t)op; + m_opcode = opcode_t(u8(op)); m_size = size; m_condition = condition; m_flags = 0; @@ -414,8 +400,8 @@ void uml::instruction::simplify() if (m_flags != 0) return; - static const uint64_t instsizemask[] = { 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0xffffffffffffffffU }; - static const uint64_t paramsizemask[] = { 0xff, 0xffff, 0xffffffff, 0xffffffffffffffffU }; + static constexpr u64 instsizemask[] = { 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0xffffffffffffffffU }; + static constexpr u64 paramsizemask[] = { 0xff, 0xffff, 0xffffffff, 0xffffffffffffffffU }; // loop until we've simplified all we can opcode_t origop; @@ -425,316 +411,316 @@ void uml::instruction::simplify() origop = m_opcode; switch (m_opcode) { - // READM: convert to READ if the mask is wide open - case OP_READM: - if (m_param[2].is_immediate_value(paramsizemask[m_param[3].size()])) - { - m_opcode = OP_READ; - m_numparams = 2; - m_param[2] = m_param[3]; - } - break; - - // WRITEM: convert to WRITE if the mask is wide open - case OP_WRITEM: - if (m_param[2].is_immediate_value(paramsizemask[m_param[3].size()])) - { - m_opcode = OP_WRITE; - m_numparams = 2; - m_param[2] = m_param[3]; - } - break; - - // SET: convert to MOV if constant condition - case OP_SET: - if (m_condition == COND_ALWAYS) - convert_to_mov_immediate(1); - break; - - // MOV: convert to NOP if move-to-self - case OP_MOV: - if (m_param[0] == m_param[1]) - nop(); - break; - - // SEXT: convert immediates to MOV - case OP_SEXT: - if (m_param[1].is_immediate()) - switch (m_param[2].size()) - { - case SIZE_BYTE: convert_to_mov_immediate((int8_t)m_param[1].immediate()); break; - case SIZE_WORD: convert_to_mov_immediate((int16_t)m_param[1].immediate()); break; - case SIZE_DWORD: convert_to_mov_immediate((int32_t)m_param[1].immediate()); break; - case SIZE_QWORD: convert_to_mov_immediate((int64_t)m_param[1].immediate()); break; - case SIZE_DQWORD: fatalerror("Invalid SEXT target size\n"); - } - break; - - // ROLAND: convert to MOV if all immediate, or to ROL or AND if one is not needed, or to SHL/SHR if the mask is right - case OP_ROLAND: - if (m_param[1].is_immediate() && m_param[2].is_immediate() && m_param[3].is_immediate()) - { - assert(m_size == 4 || m_size == 8); - if (m_size == 4) - convert_to_mov_immediate(rol32(m_param[1].immediate(), m_param[2].immediate()) & m_param[3].immediate()); - else - convert_to_mov_immediate(rol64(m_param[1].immediate(), m_param[2].immediate()) & m_param[3].immediate()); - } - else if (m_param[2].is_immediate_value(0)) - { - m_opcode = OP_AND; - m_numparams = 3; - m_param[2] = m_param[3]; - } - else if (m_param[3].is_immediate_value(instsizemask[m_size])) - { - m_opcode = OP_ROL; - m_numparams = 3; - } - else if (m_param[2].is_immediate() && m_param[3].is_immediate_value((0xffffffffffffffffU << m_param[2].immediate()) & instsizemask[m_size])) - { - m_opcode = OP_SHL; - m_numparams = 3; - } - else if (m_param[2].is_immediate() && m_param[3].is_immediate_value(instsizemask[m_size] >> (8 * m_size - m_param[2].immediate()))) - { - m_opcode = OP_SHR; - m_numparams = 3; - m_param[2] = 8 * m_size - m_param[2].immediate(); - } - break; - - // ROLINS: convert to ROLAND if the mask is full - case OP_ROLINS: - if (m_param[3].is_immediate_value(instsizemask[m_size])) - m_opcode = OP_ROLAND; - break; - - // ADD: convert to MOV if immediate, or if adding 0 - case OP_ADD: - if (m_param[1].is_immediate() && m_param[2].is_immediate()) - convert_to_mov_immediate(m_param[1].immediate() + m_param[2].immediate()); - else if (m_param[1].is_immediate_value(0)) - convert_to_mov_param(2); - else if (m_param[2].is_immediate_value(0)) - convert_to_mov_param(1); - break; - - // SUB: convert to MOV if immediate, or if subtracting 0 - case OP_SUB: - if (m_param[1].is_immediate() && m_param[2].is_immediate()) - convert_to_mov_immediate(m_param[1].immediate() - m_param[2].immediate()); - else if (m_param[2].is_immediate_value(0)) - convert_to_mov_param(1); - break; - - // CMP: no-op if no flags needed, compare i0 to i0 if the parameters are equal - case OP_CMP: - if (m_flags == 0) - nop(); - else if (m_param[0] == m_param[1]) - cmp(I0, I0); - break; - - // MULU: convert simple form to MOV if immediate, or if multiplying by 0 - case OP_MULU: - if (m_param[0] == m_param[1]) - { - if (m_param[2].is_immediate_value(0) || m_param[3].is_immediate_value(0)) - convert_to_mov_immediate(0); - else if (m_param[2].is_immediate() && m_param[3].is_immediate()) - { - if (m_size == 4) - convert_to_mov_immediate((uint32_t)((uint32_t)m_param[1].immediate() * (uint32_t)m_param[2].immediate())); - else if (m_size == 8) - convert_to_mov_immediate((uint64_t)((uint64_t)m_param[1].immediate() * (uint64_t)m_param[2].immediate())); - } - } - break; - - // MULS: convert simple form to MOV if immediate, or if multiplying by 0 - case OP_MULS: - if (m_param[0] == m_param[1]) - { - if (m_param[2].is_immediate_value(0) || m_param[3].is_immediate_value(0)) - convert_to_mov_immediate(0); - else if (m_param[2].is_immediate() && m_param[3].is_immediate()) - { - if (m_size == 4) - convert_to_mov_immediate((int32_t)((int32_t)m_param[1].immediate() * (int32_t)m_param[2].immediate())); - else if (m_size == 8) - convert_to_mov_immediate((int64_t)((int64_t)m_param[1].immediate() * (int64_t)m_param[2].immediate())); - } - } - break; - - // DIVU: convert simple form to MOV if immediate, or if dividing with 0 - case OP_DIVU: - if (m_param[0] == m_param[1] && !m_param[3].is_immediate_value(0)) - { - if (m_param[2].is_immediate_value(0)) - convert_to_mov_immediate(0); - else if (m_param[2].is_immediate() && m_param[3].is_immediate()) - { - if (m_size == 4) - convert_to_mov_immediate((uint32_t)((uint32_t)m_param[1].immediate() / (uint32_t)m_param[2].immediate())); - else if (m_size == 8) - convert_to_mov_immediate((uint64_t)((uint64_t)m_param[1].immediate() / (uint64_t)m_param[2].immediate())); - } - } - break; + // READM: convert to READ if the mask is wide open + case OP_READM: + if (m_param[2].is_immediate_value(paramsizemask[m_param[3].size()])) + { + m_opcode = OP_READ; + m_numparams = 2; + m_param[2] = m_param[3]; + } + break; - // DIVS: convert simple form to MOV if immediate, or if dividing with 0 - case OP_DIVS: - if (m_param[0] == m_param[1] && !m_param[3].is_immediate_value(0)) + // WRITEM: convert to WRITE if the mask is wide open + case OP_WRITEM: + if (m_param[2].is_immediate_value(paramsizemask[m_param[3].size()])) + { + m_opcode = OP_WRITE; + m_numparams = 2; + m_param[2] = m_param[3]; + } + break; + + // SET: convert to MOV if constant condition + case OP_SET: + if (m_condition == COND_ALWAYS) + convert_to_mov_immediate(1); + break; + + // MOV: convert to NOP if move-to-self + case OP_MOV: + if (m_param[0] == m_param[1]) + nop(); + break; + + // SEXT: convert immediates to MOV + case OP_SEXT: + if (m_param[1].is_immediate()) + switch (m_param[2].size()) { - if (m_param[2].is_immediate_value(0)) - convert_to_mov_immediate(0); - else if (m_param[2].is_immediate() && m_param[3].is_immediate()) - { - if (m_size == 4) - convert_to_mov_immediate((int32_t)((int32_t)m_param[1].immediate() / (int32_t)m_param[2].immediate())); - else if (m_size == 8) - convert_to_mov_immediate((int64_t)((int64_t)m_param[1].immediate() / (int64_t)m_param[2].immediate())); - } + case SIZE_BYTE: convert_to_mov_immediate(s8(m_param[1].immediate())); break; + case SIZE_WORD: convert_to_mov_immediate(s16(m_param[1].immediate())); break; + case SIZE_DWORD: convert_to_mov_immediate(s32(m_param[1].immediate())); break; + case SIZE_QWORD: convert_to_mov_immediate(s64(m_param[1].immediate())); break; + case SIZE_DQWORD: fatalerror("Invalid SEXT target size\n"); } - break; + break; - // AND: convert to MOV if immediate, or if anding against 0 or 0xffffffff - case OP_AND: - if (m_param[1].is_immediate_value(0) || m_param[2].is_immediate_value(0)) + // ROLAND: convert to MOV if all immediate, or to ROL or AND if one is not needed, or to SHL/SHR if the mask is right + case OP_ROLAND: + if (m_param[1].is_immediate() && m_param[2].is_immediate() && m_param[3].is_immediate()) + { + assert(m_size == 4 || m_size == 8); + if (m_size == 4) + convert_to_mov_immediate(rol32(m_param[1].immediate(), m_param[2].immediate()) & m_param[3].immediate()); + else + convert_to_mov_immediate(rol64(m_param[1].immediate(), m_param[2].immediate()) & m_param[3].immediate()); + } + else if (m_param[2].is_immediate_value(0)) + { + m_opcode = OP_AND; + m_numparams = 3; + m_param[2] = m_param[3]; + } + else if (m_param[3].is_immediate_value(instsizemask[m_size])) + { + m_opcode = OP_ROL; + m_numparams = 3; + } + else if (m_param[2].is_immediate() && m_param[3].is_immediate_value((0xffffffffffffffffU << m_param[2].immediate()) & instsizemask[m_size])) + { + m_opcode = OP_SHL; + m_numparams = 3; + } + else if (m_param[2].is_immediate() && m_param[3].is_immediate_value(instsizemask[m_size] >> (8 * m_size - m_param[2].immediate()))) + { + m_opcode = OP_SHR; + m_numparams = 3; + m_param[2] = 8 * m_size - m_param[2].immediate(); + } + break; + + // ROLINS: convert to ROLAND if the mask is full + case OP_ROLINS: + if (m_param[3].is_immediate_value(instsizemask[m_size])) + m_opcode = OP_ROLAND; + break; + + // ADD: convert to MOV if immediate, or if adding 0 + case OP_ADD: + if (m_param[1].is_immediate() && m_param[2].is_immediate()) + convert_to_mov_immediate(m_param[1].immediate() + m_param[2].immediate()); + else if (m_param[1].is_immediate_value(0)) + convert_to_mov_param(2); + else if (m_param[2].is_immediate_value(0)) + convert_to_mov_param(1); + break; + + // SUB: convert to MOV if immediate, or if subtracting 0 + case OP_SUB: + if (m_param[1].is_immediate() && m_param[2].is_immediate()) + convert_to_mov_immediate(m_param[1].immediate() - m_param[2].immediate()); + else if (m_param[2].is_immediate_value(0)) + convert_to_mov_param(1); + break; + + // CMP: no-op if no flags needed, compare i0 to i0 if the parameters are equal + case OP_CMP: + if (m_flags == 0) + nop(); + else if (m_param[0] == m_param[1]) + cmp(I0, I0); + break; + + // MULU: convert simple form to MOV if immediate, or if multiplying by 0 + case OP_MULU: + if (m_param[0] == m_param[1]) + { + if (m_param[2].is_immediate_value(0) || m_param[3].is_immediate_value(0)) convert_to_mov_immediate(0); - else if (m_param[1].is_immediate() && m_param[2].is_immediate()) - convert_to_mov_immediate(m_param[1].immediate() & m_param[2].immediate()); - else if (m_param[1].is_immediate_value(instsizemask[m_size])) - convert_to_mov_param(2); - else if (m_param[2].is_immediate_value(instsizemask[m_size])) - convert_to_mov_param(1); - break; - - // TEST: no-op if no flags needed - case OP_TEST: - if (m_flags == 0) - nop(); - break; - - // OR: convert to MOV if immediate, or if oring against 0 or 0xffffffff - case OP_OR: - if (m_param[1].is_immediate_value(instsizemask[m_size]) || m_param[2].is_immediate_value(instsizemask[m_size])) - convert_to_mov_immediate(instsizemask[m_size]); - else if (m_param[1].is_immediate() && m_param[2].is_immediate()) - convert_to_mov_immediate(m_param[1].immediate() | m_param[2].immediate()); - else if (m_param[1].is_immediate_value(0)) - convert_to_mov_param(2); - else if (m_param[2].is_immediate_value(0)) - convert_to_mov_param(1); - break; - - // XOR: convert to MOV if immediate, or if xoring against 0 - case OP_XOR: - if (m_param[1].is_immediate() && m_param[2].is_immediate()) - convert_to_mov_immediate(m_param[1].immediate() ^ m_param[2].immediate()); - else if (m_param[1].is_immediate_value(0)) - convert_to_mov_param(2); - else if (m_param[2].is_immediate_value(0)) - convert_to_mov_param(1); - break; - - // LZCNT: convert to MOV if immediate - case OP_LZCNT: - if (m_param[1].is_immediate()) + else if (m_param[2].is_immediate() && m_param[3].is_immediate()) { if (m_size == 4) - convert_to_mov_immediate(count_leading_zeros(m_param[1].immediate())); + convert_to_mov_immediate(u32(u32(m_param[1].immediate()) * u32(m_param[2].immediate()))); else if (m_size == 8) - { - if ((m_param[1].immediate() >> 32) == 0) - convert_to_mov_immediate(32 + count_leading_zeros(m_param[1].immediate())); - else - convert_to_mov_immediate(count_leading_zeros(m_param[1].immediate() >> 32)); - } + convert_to_mov_immediate(u64(u64(m_param[1].immediate()) * u64(m_param[2].immediate()))); } - break; + } + break; - // BSWAP: convert to MOV if immediate - case OP_BSWAP: - if (m_param[1].is_immediate()) - { - if (m_size == 4) - convert_to_mov_immediate(flipendian_int32(m_param[1].immediate())); - else if (m_size == 8) - convert_to_mov_immediate(flipendian_int64(m_param[1].immediate())); - } - break; - - // SHL: convert to MOV if immediate or shifting by 0 - case OP_SHL: - if (m_param[1].is_immediate() && m_param[2].is_immediate()) - convert_to_mov_immediate(m_param[1].immediate() << m_param[2].immediate()); - else if (m_param[2].is_immediate_value(0)) - convert_to_mov_param(1); - break; - - // SHR: convert to MOV if immediate or shifting by 0 - case OP_SHR: - if (m_param[1].is_immediate() && m_param[2].is_immediate()) + // MULS: convert simple form to MOV if immediate, or if multiplying by 0 + case OP_MULS: + if (m_param[0] == m_param[1]) + { + if (m_param[2].is_immediate_value(0) || m_param[3].is_immediate_value(0)) + convert_to_mov_immediate(0); + else if (m_param[2].is_immediate() && m_param[3].is_immediate()) { if (m_size == 4) - convert_to_mov_immediate((uint32_t)m_param[1].immediate() >> m_param[2].immediate()); + convert_to_mov_immediate(s32(s32(m_param[1].immediate()) * s32(m_param[2].immediate()))); else if (m_size == 8) - convert_to_mov_immediate((uint64_t)m_param[1].immediate() >> m_param[2].immediate()); + convert_to_mov_immediate(s64(s64(m_param[1].immediate()) * s64(m_param[2].immediate()))); } - else if (m_param[2].is_immediate_value(0)) - convert_to_mov_param(1); - break; + } + break; - // SAR: convert to MOV if immediate or shifting by 0 - case OP_SAR: - if (m_param[1].is_immediate() && m_param[2].is_immediate()) + // DIVU: convert simple form to MOV if immediate, or if dividing with 0 + case OP_DIVU: + if (m_param[0] == m_param[1] && !m_param[3].is_immediate_value(0)) + { + if (m_param[2].is_immediate_value(0)) + convert_to_mov_immediate(0); + else if (m_param[2].is_immediate() && m_param[3].is_immediate()) { if (m_size == 4) - convert_to_mov_immediate((int32_t)m_param[1].immediate() >> m_param[2].immediate()); + convert_to_mov_immediate(u32(u32(m_param[1].immediate()) / u32(m_param[2].immediate()))); else if (m_size == 8) - convert_to_mov_immediate((int64_t)m_param[1].immediate() >> m_param[2].immediate()); + convert_to_mov_immediate(u64(u64(m_param[1].immediate()) / u64(m_param[2].immediate()))); } - else if (m_param[2].is_immediate_value(0)) - convert_to_mov_param(1); - break; + } + break; - // ROL: convert to NOP if immediate or rotating by 0 - case OP_ROL: - if (m_param[1].is_immediate() && m_param[2].is_immediate()) + // DIVS: convert simple form to MOV if immediate, or if dividing with 0 + case OP_DIVS: + if (m_param[0] == m_param[1] && !m_param[3].is_immediate_value(0)) + { + if (m_param[2].is_immediate_value(0)) + convert_to_mov_immediate(0); + else if (m_param[2].is_immediate() && m_param[3].is_immediate()) { if (m_size == 4) - convert_to_mov_immediate(rol32(m_param[1].immediate(), m_param[2].immediate())); + convert_to_mov_immediate(s32(s32(m_param[1].immediate()) / s32(m_param[2].immediate()))); else if (m_size == 8) - convert_to_mov_immediate(rol64(m_param[1].immediate(), m_param[2].immediate())); + convert_to_mov_immediate(s64(s64(m_param[1].immediate()) / s64(m_param[2].immediate()))); } - else if (m_param[2].is_immediate_value(0)) - convert_to_mov_param(1); - break; - - // ROR: convert to NOP if immediate or rotating by 0 - case OP_ROR: - if (m_param[1].is_immediate() && m_param[2].is_immediate()) + } + break; + + // AND: convert to MOV if immediate, or if anding against 0 or 0xffffffff + case OP_AND: + if (m_param[1].is_immediate_value(0) || m_param[2].is_immediate_value(0)) + convert_to_mov_immediate(0); + else if (m_param[1].is_immediate() && m_param[2].is_immediate()) + convert_to_mov_immediate(m_param[1].immediate() & m_param[2].immediate()); + else if (m_param[1].is_immediate_value(instsizemask[m_size])) + convert_to_mov_param(2); + else if (m_param[2].is_immediate_value(instsizemask[m_size])) + convert_to_mov_param(1); + break; + + // TEST: no-op if no flags needed + case OP_TEST: + if (m_flags == 0) + nop(); + break; + + // OR: convert to MOV if immediate, or if oring against 0 or 0xffffffff + case OP_OR: + if (m_param[1].is_immediate_value(instsizemask[m_size]) || m_param[2].is_immediate_value(instsizemask[m_size])) + convert_to_mov_immediate(instsizemask[m_size]); + else if (m_param[1].is_immediate() && m_param[2].is_immediate()) + convert_to_mov_immediate(m_param[1].immediate() | m_param[2].immediate()); + else if (m_param[1].is_immediate_value(0)) + convert_to_mov_param(2); + else if (m_param[2].is_immediate_value(0)) + convert_to_mov_param(1); + break; + + // XOR: convert to MOV if immediate, or if xoring against 0 + case OP_XOR: + if (m_param[1].is_immediate() && m_param[2].is_immediate()) + convert_to_mov_immediate(m_param[1].immediate() ^ m_param[2].immediate()); + else if (m_param[1].is_immediate_value(0)) + convert_to_mov_param(2); + else if (m_param[2].is_immediate_value(0)) + convert_to_mov_param(1); + break; + + // LZCNT: convert to MOV if immediate + case OP_LZCNT: + if (m_param[1].is_immediate()) + { + if (m_size == 4) + convert_to_mov_immediate(count_leading_zeros(m_param[1].immediate())); + else if (m_size == 8) { - if (m_size == 4) - convert_to_mov_immediate(rol32(m_param[1].immediate(), 32 - m_param[2].immediate())); - else if (m_size == 8) - convert_to_mov_immediate(rol64(m_param[1].immediate(), 64 - m_param[2].immediate())); + if ((m_param[1].immediate() >> 32) == 0) + convert_to_mov_immediate(32 + count_leading_zeros(m_param[1].immediate())); + else + convert_to_mov_immediate(count_leading_zeros(m_param[1].immediate() >> 32)); } - else if (m_param[2].is_immediate_value(0)) - convert_to_mov_param(1); - break; - - // FMOV: convert to NOP if move-to-self - case OP_FMOV: - if (m_param[0] == m_param[1]) - nop(); - break; - - default: - break; + } + break; + + // BSWAP: convert to MOV if immediate + case OP_BSWAP: + if (m_param[1].is_immediate()) + { + if (m_size == 4) + convert_to_mov_immediate(flipendian_int32(m_param[1].immediate())); + else if (m_size == 8) + convert_to_mov_immediate(flipendian_int64(m_param[1].immediate())); + } + break; + + // SHL: convert to MOV if immediate or shifting by 0 + case OP_SHL: + if (m_param[1].is_immediate() && m_param[2].is_immediate()) + convert_to_mov_immediate(m_param[1].immediate() << m_param[2].immediate()); + else if (m_param[2].is_immediate_value(0)) + convert_to_mov_param(1); + break; + + // SHR: convert to MOV if immediate or shifting by 0 + case OP_SHR: + if (m_param[1].is_immediate() && m_param[2].is_immediate()) + { + if (m_size == 4) + convert_to_mov_immediate(u32(m_param[1].immediate()) >> m_param[2].immediate()); + else if (m_size == 8) + convert_to_mov_immediate(u64(m_param[1].immediate()) >> m_param[2].immediate()); + } + else if (m_param[2].is_immediate_value(0)) + convert_to_mov_param(1); + break; + + // SAR: convert to MOV if immediate or shifting by 0 + case OP_SAR: + if (m_param[1].is_immediate() && m_param[2].is_immediate()) + { + if (m_size == 4) + convert_to_mov_immediate(s32(m_param[1].immediate()) >> m_param[2].immediate()); + else if (m_size == 8) + convert_to_mov_immediate(s64(m_param[1].immediate()) >> m_param[2].immediate()); + } + else if (m_param[2].is_immediate_value(0)) + convert_to_mov_param(1); + break; + + // ROL: convert to NOP if immediate or rotating by 0 + case OP_ROL: + if (m_param[1].is_immediate() && m_param[2].is_immediate()) + { + if (m_size == 4) + convert_to_mov_immediate(rol32(m_param[1].immediate(), m_param[2].immediate())); + else if (m_size == 8) + convert_to_mov_immediate(rol64(m_param[1].immediate(), m_param[2].immediate())); + } + else if (m_param[2].is_immediate_value(0)) + convert_to_mov_param(1); + break; + + // ROR: convert to NOP if immediate or rotating by 0 + case OP_ROR: + if (m_param[1].is_immediate() && m_param[2].is_immediate()) + { + if (m_size == 4) + convert_to_mov_immediate(rol32(m_param[1].immediate(), 32 - m_param[2].immediate())); + else if (m_size == 8) + convert_to_mov_immediate(rol64(m_param[1].immediate(), 64 - m_param[2].immediate())); + } + else if (m_param[2].is_immediate_value(0)) + convert_to_mov_param(1); + break; + + // FMOV: convert to NOP if move-to-self + case OP_FMOV: + if (m_param[0] == m_param[1]) + nop(); + break; + + default: + break; } /* @@ -782,7 +768,7 @@ void uml::instruction::validate() // make sure we aren't missing any parameters if (m_numparams < ARRAY_LENGTH(opinfo.param)) assert(opinfo.param[m_numparams].typemask == 0); -#endif +#endif // MAME_DEBUG } @@ -792,9 +778,9 @@ void uml::instruction::validate() // instruction //------------------------------------------------- -uint8_t uml::instruction::input_flags() const +u8 uml::instruction::input_flags() const { - static const uint8_t flags_for_condition[] = + static constexpr u8 flags_for_condition[] = { FLAG_Z, // COND_Z FLAG_Z, // COND_NZ @@ -814,7 +800,7 @@ uint8_t uml::instruction::input_flags() const FLAG_S | FLAG_V // COND_GE }; - uint8_t flags = s_opcode_info_table[m_opcode].inflags; + u8 flags = s_opcode_info_table[m_opcode].inflags; if (flags & 0x80) flags = m_param[flags - OPFLAGS_P1].immediate() & OPFLAGS_ALL; if (m_condition != COND_ALWAYS) @@ -829,9 +815,9 @@ uint8_t uml::instruction::input_flags() const // instruction //------------------------------------------------- -uint8_t uml::instruction::output_flags() const +u8 uml::instruction::output_flags() const { - uint8_t flags = s_opcode_info_table[m_opcode].outflags; + u8 flags = s_opcode_info_table[m_opcode].outflags; if (flags & 0x80) flags = m_param[flags - OPFLAGS_P1].immediate() & OPFLAGS_ALL; return flags; @@ -844,7 +830,7 @@ uint8_t uml::instruction::output_flags() const // instruction //------------------------------------------------- -uint8_t uml::instruction::modified_flags() const +u8 uml::instruction::modified_flags() const { return s_opcode_info_table[m_opcode].modflags; } @@ -857,20 +843,20 @@ uint8_t uml::instruction::modified_flags() const std::string uml::instruction::disasm(drcuml_state *drcuml) const { - static const char *const conditions[] = { "z", "nz", "s", "ns", "c", "nc", "v", "nv", "u", "nu", "a", "be", "g", "le", "l", "ge" }; - static const char *const pound_size[] = { "?", "?", "?", "?", "s", "?", "?", "?", "d" }; - static const char *const bang_size[] = { "?", "b", "h", "?", "", "?", "?", "?", "d" }; - static const char *const fmods[] = { "trunc", "round", "ceil", "floor", "default" }; - static const char *const spaces[] = { "program", "data", "io", "3", "4", "5", "6", "7" }; - static const char *const sizes[] = { "byte", "word", "dword", "qword" }; - - const opcode_info &opinfo = s_opcode_info_table[m_opcode]; + static char const *const conditions[] = { "z", "nz", "s", "ns", "c", "nc", "v", "nv", "u", "nu", "a", "be", "g", "le", "l", "ge" }; + static char const *const pound_size[] = { "?", "?", "?", "?", "s", "?", "?", "?", "d" }; + static char const *const bang_size[] = { "?", "b", "h", "?", "", "?", "?", "?", "d" }; + static char const *const fmods[] = { "trunc", "round", "ceil", "floor", "default" }; + static char const *const spaces[] = { "program", "data", "io", "3", "4", "5", "6", "7" }; + static char const *const sizes[] = { "byte", "word", "dword", "qword" }; assert(m_opcode != OP_INVALID && m_opcode < OP_MAX); + opcode_info const &opinfo = s_opcode_info_table[m_opcode]; + // start with the raw mnemonic and substitute sizes std::ostringstream buffer; - for (const char *opsrc = opinfo.mnemonic; *opsrc != 0; opsrc++) + for (char const *opsrc = opinfo.mnemonic; *opsrc != 0; opsrc++) if (*opsrc == '!') util::stream_format(buffer, "%s", bang_size[m_size]); else if (*opsrc == '#') @@ -879,12 +865,8 @@ std::string uml::instruction::disasm(drcuml_state *drcuml) const util::stream_format(buffer, "%c", *opsrc); // pad to 8 spaces - int pad = 8 - buffer.tellp(); - while (pad > 0) - { + for (int pad = 8 - buffer.tellp(); (pad > 0); --pad) buffer.put(' '); - pad--; - } // iterate through parameters for (int pnum = 0; pnum < m_numparams; pnum++) @@ -898,82 +880,79 @@ std::string uml::instruction::disasm(drcuml_state *drcuml) const // ouput based on type switch (param.type()) { - // immediates have several special cases - case parameter::PTYPE_IMMEDIATE: + // immediates have several special cases + case parameter::PTYPE_IMMEDIATE: + { + // determine the size of the immediate + int size; + switch (opinfo.param[pnum].size) { - // determine the size of the immediate - int size; - switch (opinfo.param[pnum].size) - { - case PSIZE_4: size = 4; break; - case PSIZE_8: size = 8; break; - case PSIZE_P1: size = 1 << m_param[0].size(); break; - case PSIZE_P2: size = 1 << m_param[1].size(); break; - case PSIZE_P3: size = 1 << m_param[2].size(); break; - case PSIZE_P4: size = 1 << m_param[3].size(); break; - default: - case PSIZE_OP: size = m_size; break; - } - - // truncate to size - uint64_t value = param.immediate(); - if (size == 1) value = (uint8_t)value; - if (size == 2) value = (uint16_t)value; - if (size == 4) value = (uint32_t)value; - if ((uint32_t)value == value) - util::stream_format(buffer, "$%X", (uint32_t)value); - else - util::stream_format(buffer, "$%X%08X", (uint32_t)(value >> 32), (uint32_t)value); + case PSIZE_4: size = 4; break; + case PSIZE_8: size = 8; break; + case PSIZE_P1: size = 1 << m_param[0].size(); break; + case PSIZE_P2: size = 1 << m_param[1].size(); break; + case PSIZE_P3: size = 1 << m_param[2].size(); break; + case PSIZE_P4: size = 1 << m_param[3].size(); break; + default: + case PSIZE_OP: size = m_size; break; } - break; - // immediates have several special cases - case parameter::PTYPE_SIZE: - util::stream_format(buffer, "%s", sizes[param.size()]); - break; + // truncate to size + u64 value = param.immediate(); + if (size == 1) value = u8(value); + if (size == 2) value = u16(value); + if (size == 4) value = u32(value); + util::stream_format(buffer, "$%X", value); + } + break; - // size + address space immediate - case parameter::PTYPE_SIZE_SPACE: - util::stream_format(buffer, "%s_%s", spaces[param.space()], sizes[param.size()]); - break; + // immediates have several special cases + case parameter::PTYPE_SIZE: + util::stream_format(buffer, "%s", sizes[param.size()]); + break; - // size + scale immediate - case parameter::PTYPE_SIZE_SCALE: - { - int scale = param.scale(); - int size = param.size(); - if (scale == size) - util::stream_format(buffer, "%s", sizes[size]); - else - util::stream_format(buffer, "%s_x%d", sizes[size], 1 << scale); - } - break; - - // fmod immediate - case parameter::PTYPE_ROUNDING: - util::stream_format(buffer, "%s", fmods[param.rounding()]); - break; - - // integer registers - case parameter::PTYPE_INT_REGISTER: - util::stream_format(buffer, "i%d", param.ireg() - REG_I0); - break; - - // floating point registers - case parameter::PTYPE_FLOAT_REGISTER: - util::stream_format(buffer, "f%d", param.freg() - REG_F0); - break; - - // map variables - case parameter::PTYPE_MAPVAR: - util::stream_format(buffer, "m%d", param.mapvar() - MAPVAR_M0); - break; - - // memory - case parameter::PTYPE_MEMORY: + // size + address space immediate + case parameter::PTYPE_SIZE_SPACE: + util::stream_format(buffer, "%s_%s", spaces[param.space()], sizes[param.size()]); + break; + + // size + scale immediate + case parameter::PTYPE_SIZE_SCALE: + { + int const scale = param.scale(); + int const size = param.size(); + if (scale == size) + util::stream_format(buffer, "%s", sizes[size]); + else + util::stream_format(buffer, "%s_x%d", sizes[size], 1 << scale); + } + break; + + // fmod immediate + case parameter::PTYPE_ROUNDING: + util::stream_format(buffer, "%s", fmods[param.rounding()]); + break; + + // integer registers + case parameter::PTYPE_INT_REGISTER: + util::stream_format(buffer, "i%d", param.ireg() - REG_I0); + break; + + // floating point registers + case parameter::PTYPE_FLOAT_REGISTER: + util::stream_format(buffer, "f%d", param.freg() - REG_F0); + break; + + // map variables + case parameter::PTYPE_MAPVAR: + util::stream_format(buffer, "m%d", param.mapvar() - MAPVAR_M0); + break; + + // memory + case parameter::PTYPE_MEMORY: { const char *symbol; - uint32_t symoffset; + u32 symoffset; // symbol if (drcuml != nullptr && (symbol = drcuml->symbol_find(param.memory(), &symoffset)) != nullptr) @@ -986,32 +965,32 @@ std::string uml::instruction::disasm(drcuml_state *drcuml) const // cache memory else if (drcuml != nullptr && drcuml->cache().contains_pointer(param.memory())) - util::stream_format(buffer, "[+$%X]", (uint32_t)(uintptr_t)((drccodeptr)param.memory() - drcuml->cache().near())); + util::stream_format(buffer, "[+$%X]", u32(uintptr_t(drccodeptr(param.memory()) - drcuml->cache().near()))); // general memory else util::stream_format(buffer, "[[$%p]]", param.memory()); - break; } - - // string pointer - case parameter::PTYPE_STRING: - util::stream_format(buffer, "%s", (const char *)(uintptr_t)param.string()); - break; - - // handle pointer - case parameter::PTYPE_CODE_HANDLE: - util::stream_format(buffer, "%s", param.handle().string()); - break; - - // label - case parameter::PTYPE_CODE_LABEL: - util::stream_format(buffer, "$%8X", param.label().label()); - break; - - default: - util::stream_format(buffer, "???"); - break; + break; + + // string pointer + case parameter::PTYPE_STRING: + util::stream_format(buffer, "%s", reinterpret_cast(uintptr_t(param.string()))); + break; + + // handle pointer + case parameter::PTYPE_CODE_HANDLE: + util::stream_format(buffer, "%s", param.handle().string()); + break; + + // label + case parameter::PTYPE_CODE_LABEL: + util::stream_format(buffer, "$%8X", param.label().label()); + break; + + default: + util::stream_format(buffer, "???"); + break; } } diff --git a/src/devices/cpu/uml.h b/src/devices/cpu/uml.h index be32dedd724..4c1fcd1c477 100644 --- a/src/devices/cpu/uml.h +++ b/src/devices/cpu/uml.h @@ -7,12 +7,11 @@ Universal machine language definitions and classes. ***************************************************************************/ +#ifndef MAME_CPU_UML_H +#define MAME_CPU_UML_H #pragma once -#ifndef __UML_H__ -#define __UML_H__ - #include "drccache.h" @@ -31,31 +30,31 @@ struct drcuml_machine_state; namespace uml { // integer registers - const int REG_I0 = 0x400; - const int REG_I_COUNT = 10; - const int REG_I_END = REG_I0 + REG_I_COUNT; + constexpr int REG_I0 = 0x400; + constexpr int REG_I_COUNT = 10; + constexpr int REG_I_END = REG_I0 + REG_I_COUNT; // floating point registers - const int REG_F0 = 0x800; - const int REG_F_COUNT = 10; - const int REG_F_END = REG_F0 + REG_F_COUNT; + constexpr int REG_F0 = 0x800; + constexpr int REG_F_COUNT = 10; + constexpr int REG_F_END = REG_F0 + REG_F_COUNT; // vector registers - const int REG_V0 = 0xc00; - const int REG_V_COUNT = 10; - const int REG_V_END = REG_V0 + REG_V_COUNT; + constexpr int REG_V0 = 0xc00; + constexpr int REG_V_COUNT = 10; + constexpr int REG_V_END = REG_V0 + REG_V_COUNT; // map variables - const int MAPVAR_M0 = 0x1000; - const int MAPVAR_COUNT = 10; - const int MAPVAR_END = MAPVAR_M0 + MAPVAR_COUNT; + constexpr int MAPVAR_M0 = 0x1000; + constexpr int MAPVAR_COUNT = 10; + constexpr int MAPVAR_END = MAPVAR_M0 + MAPVAR_COUNT; // flag definitions - const uint8_t FLAG_C = 0x01; // carry flag - const uint8_t FLAG_V = 0x02; // overflow flag (defined for integer only) - const uint8_t FLAG_Z = 0x04; // zero flag - const uint8_t FLAG_S = 0x08; // sign flag (defined for integer only) - const uint8_t FLAG_U = 0x10; // unordered flag (defined for FP only) + constexpr u8 FLAG_C = 0x01; // carry flag + constexpr u8 FLAG_V = 0x02; // overflow flag (defined for integer only) + constexpr u8 FLAG_Z = 0x04; // zero flag + constexpr u8 FLAG_S = 0x08; // sign flag (defined for integer only) + constexpr u8 FLAG_U = 0x10; // unordered flag (defined for FP only) // testable conditions; note that these are defined such that (condition ^ 1) is // always the opposite @@ -242,7 +241,7 @@ namespace uml code_handle *next() const { return m_next; } drccodeptr codeptr() const { return *m_code; } drccodeptr *codeptr_addr() { return m_code; } - const char *string() const { return m_string.c_str(); } + char const *string() const { return m_string.c_str(); } // setters void set_codeptr(drccodeptr code); @@ -260,18 +259,18 @@ namespace uml { public: // construction - code_label(uint32_t label = 0) : m_label(label) { } + constexpr code_label(u32 label = 0) : m_label(label) { } // operators - operator uint32_t &() { return m_label; } - bool operator==(const code_label &rhs) const { return (m_label == rhs.m_label); } - bool operator!=(const code_label &rhs) const { return (m_label != rhs.m_label); } + operator u32 &() { return m_label; } + constexpr bool operator==(code_label const &rhs) const { return (m_label == rhs.m_label); } + constexpr bool operator!=(code_label const &rhs) const { return (m_label != rhs.m_label); } // getters - uint32_t label() const { return m_label; } + constexpr u32 label() const { return m_label; } private: - uint32_t m_label; + u32 m_label; }; // a parameter for a UML instruction is encoded like this @@ -300,36 +299,36 @@ namespace uml }; // represents the value of an opcode parameter - typedef uint64_t parameter_value; + typedef u64 parameter_value; // construction - parameter() : m_type(PTYPE_NONE), m_value(0) { } - parameter(const parameter ¶m) : m_type(param.m_type), m_value(param.m_value) { } - parameter(uint64_t val) : m_type(PTYPE_IMMEDIATE), m_value(val) { } + constexpr parameter() : m_type(PTYPE_NONE), m_value(0) { } + constexpr parameter(parameter const ¶m) : m_type(param.m_type), m_value(param.m_value) { } + constexpr parameter(u64 val) : m_type(PTYPE_IMMEDIATE), m_value(val) { } parameter(operand_size size, memory_scale scale) : m_type(PTYPE_SIZE_SCALE), m_value((scale << 4) | size) { assert(size >= SIZE_BYTE && size <= SIZE_DQWORD); assert(scale >= SCALE_x1 && scale <= SCALE_x8); } parameter(operand_size size, memory_space space) : m_type(PTYPE_SIZE_SPACE), m_value((space << 4) | size) { assert(size >= SIZE_BYTE && size <= SIZE_DQWORD); assert(space >= SPACE_PROGRAM && space <= SPACE_IO); } parameter(code_handle &handle) : m_type(PTYPE_CODE_HANDLE), m_value(reinterpret_cast(&handle)) { } - parameter(code_label &label) : m_type(PTYPE_CODE_LABEL), m_value(label) { } + constexpr parameter(code_label &label) : m_type(PTYPE_CODE_LABEL), m_value(label) { } // creators for types that don't safely default - static inline parameter make_ireg(int regnum) { assert(regnum >= REG_I0 && regnum < REG_I_END); return parameter(PTYPE_INT_REGISTER, regnum); } - static inline parameter make_freg(int regnum) { assert(regnum >= REG_F0 && regnum < REG_F_END); return parameter(PTYPE_FLOAT_REGISTER, regnum); } - static inline parameter make_vreg(int regnum) { assert(regnum >= REG_V0 && regnum < REG_V_END); return parameter(PTYPE_VECTOR_REGISTER, regnum); } - static inline parameter make_mapvar(int mvnum) { assert(mvnum >= MAPVAR_M0 && mvnum < MAPVAR_END); return parameter(PTYPE_MAPVAR, mvnum); } - static inline parameter make_memory(void *base) { return parameter(PTYPE_MEMORY, reinterpret_cast(base)); } - static inline parameter make_memory(const void *base) { return parameter(PTYPE_MEMORY, reinterpret_cast(const_cast(base))); } - static inline parameter make_size(operand_size size) { assert(size >= SIZE_BYTE && size <= SIZE_DQWORD); return parameter(PTYPE_SIZE, size); } - static inline parameter make_string(const char *string) { return parameter(PTYPE_STRING, reinterpret_cast(const_cast(string))); } - static inline parameter make_cfunc(c_function func) { return parameter(PTYPE_C_FUNCTION, reinterpret_cast(func)); } - static inline parameter make_rounding(float_rounding_mode mode) { assert(mode >= ROUND_TRUNC && mode <= ROUND_DEFAULT); return parameter(PTYPE_ROUNDING, mode); } + static parameter make_ireg(int regnum) { assert(regnum >= REG_I0 && regnum < REG_I_END); return parameter(PTYPE_INT_REGISTER, regnum); } + static parameter make_freg(int regnum) { assert(regnum >= REG_F0 && regnum < REG_F_END); return parameter(PTYPE_FLOAT_REGISTER, regnum); } + static parameter make_vreg(int regnum) { assert(regnum >= REG_V0 && regnum < REG_V_END); return parameter(PTYPE_VECTOR_REGISTER, regnum); } + static parameter make_mapvar(int mvnum) { assert(mvnum >= MAPVAR_M0 && mvnum < MAPVAR_END); return parameter(PTYPE_MAPVAR, mvnum); } + static parameter make_memory(void *base) { return parameter(PTYPE_MEMORY, reinterpret_cast(base)); } + static parameter make_memory(void const *base) { return parameter(PTYPE_MEMORY, reinterpret_cast(const_cast(base))); } + static parameter make_size(operand_size size) { assert(size >= SIZE_BYTE && size <= SIZE_DQWORD); return parameter(PTYPE_SIZE, size); } + static parameter make_string(char const *string) { return parameter(PTYPE_STRING, reinterpret_cast(const_cast(string))); } + static parameter make_cfunc(c_function func) { return parameter(PTYPE_C_FUNCTION, reinterpret_cast(func)); } + static parameter make_rounding(float_rounding_mode mode) { assert(mode >= ROUND_TRUNC && mode <= ROUND_DEFAULT); return parameter(PTYPE_ROUNDING, mode); } // operators - bool operator==(const parameter &rhs) const { return (m_type == rhs.m_type && m_value == rhs.m_value); } - bool operator!=(const parameter &rhs) const { return (m_type != rhs.m_type || m_value != rhs.m_value); } + constexpr bool operator==(parameter const &rhs) const { return (m_type == rhs.m_type) && (m_value == rhs.m_value); } + constexpr bool operator!=(parameter const &rhs) const { return (m_type != rhs.m_type) || (m_value != rhs.m_value); } // getters - parameter_type type() const { return m_type; } - uint64_t immediate() const { assert(m_type == PTYPE_IMMEDIATE); return m_value; } + constexpr parameter_type type() const { return m_type; } + u64 immediate() const { assert(m_type == PTYPE_IMMEDIATE); return m_value; } int ireg() const { assert(m_type == PTYPE_INT_REGISTER); assert(m_value >= REG_I0 && m_value < REG_I_END); return m_value; } int freg() const { assert(m_type == PTYPE_FLOAT_REGISTER); assert(m_value >= REG_F0 && m_value < REG_F_END); return m_value; } int vreg() const { assert(m_type == PTYPE_VECTOR_REGISTER); assert(m_value >= REG_V0 && m_value < REG_V_END); return m_value; } @@ -342,26 +341,26 @@ namespace uml code_label label() const { assert(m_type == PTYPE_CODE_LABEL); return code_label(m_value); } c_function cfunc() const { assert(m_type == PTYPE_C_FUNCTION); return reinterpret_cast(m_value); } float_rounding_mode rounding() const { assert(m_type == PTYPE_ROUNDING); return float_rounding_mode(m_value); } - const char *string() const { assert(m_type == PTYPE_STRING); return reinterpret_cast(m_value); } + char const *string() const { assert(m_type == PTYPE_STRING); return reinterpret_cast(m_value); } // type queries - bool is_immediate() const { return (m_type == PTYPE_IMMEDIATE); } - bool is_int_register() const { return (m_type == PTYPE_INT_REGISTER); } - bool is_float_register() const { return (m_type == PTYPE_FLOAT_REGISTER); } - bool is_vector_register() const { return (m_type == PTYPE_VECTOR_REGISTER); } - bool is_mapvar() const { return (m_type == PTYPE_MAPVAR); } - bool is_memory() const { return (m_type == PTYPE_MEMORY); } - bool is_size() const { return (m_type == PTYPE_SIZE); } - bool is_size_scale() const { return (m_type == PTYPE_SIZE_SCALE); } - bool is_size_space() const { return (m_type == PTYPE_SIZE_SPACE); } - bool is_code_handle() const { return (m_type == PTYPE_CODE_HANDLE); } - bool is_code_label() const { return (m_type == PTYPE_CODE_LABEL); } - bool is_c_function() const { return (m_type == PTYPE_C_FUNCTION); } - bool is_rounding() const { return (m_type == PTYPE_ROUNDING); } - bool is_string() const { return (m_type == PTYPE_STRING); } + constexpr bool is_immediate() const { return m_type == PTYPE_IMMEDIATE; } + constexpr bool is_int_register() const { return m_type == PTYPE_INT_REGISTER; } + constexpr bool is_float_register() const { return m_type == PTYPE_FLOAT_REGISTER; } + constexpr bool is_vector_register() const { return m_type == PTYPE_VECTOR_REGISTER; } + constexpr bool is_mapvar() const { return m_type == PTYPE_MAPVAR; } + constexpr bool is_memory() const { return m_type == PTYPE_MEMORY; } + constexpr bool is_size() const { return m_type == PTYPE_SIZE; } + constexpr bool is_size_scale() const { return m_type == PTYPE_SIZE_SCALE; } + constexpr bool is_size_space() const { return m_type == PTYPE_SIZE_SPACE; } + constexpr bool is_code_handle() const { return m_type == PTYPE_CODE_HANDLE; } + constexpr bool is_code_label() const { return m_type == PTYPE_CODE_LABEL; } + constexpr bool is_c_function() const { return m_type == PTYPE_C_FUNCTION; } + constexpr bool is_rounding() const { return m_type == PTYPE_ROUNDING; } + constexpr bool is_string() const { return m_type == PTYPE_STRING; } // other queries - bool is_immediate_value(uint64_t value) const { return (m_type == PTYPE_IMMEDIATE && m_value == value); } + constexpr bool is_immediate_value(u64 value) const { return (m_type == PTYPE_IMMEDIATE) && (m_value == value); } private: // private constructor @@ -377,18 +376,18 @@ namespace uml { struct parameter_info { - uint8_t output; // input or output? - uint8_t size; // size of the parameter - uint16_t typemask; // types allowed + u8 output; // input or output? + u8 size; // size of the parameter + u16 typemask; // types allowed }; opcode_t opcode; // the opcode itself - const char * mnemonic; // mnemonic string - uint8_t sizes; // allowed sizes + char const * mnemonic; // mnemonic string + u8 sizes; // allowed sizes bool condition; // conditions allowed? - uint8_t inflags; // input flags - uint8_t outflags; // output flags - uint8_t modflags; // modified flags + u8 inflags; // input flags + u8 outflags; // output flags + u8 modflags; // modified flags parameter_info param[4]; // information about parameters }; @@ -397,37 +396,37 @@ namespace uml { public: // construction/destruction - instruction(); + constexpr instruction() { } // getters - opcode_t opcode() const { return m_opcode; } - condition_t condition() const { return m_condition; } - uint8_t flags() const { return m_flags; } - uint8_t size() const { return m_size; } - uint8_t numparams() const { return m_numparams; } + constexpr opcode_t opcode() const { return m_opcode; } + constexpr condition_t condition() const { return m_condition; } + constexpr u8 flags() const { return m_flags; } + constexpr u8 size() const { return m_size; } + constexpr u8 numparams() const { return m_numparams; } const parameter ¶m(int index) const { assert(index < m_numparams); return m_param[index]; } // setters - void set_flags(uint8_t flags) { m_flags = flags; } - void set_mapvar(int paramnum, uint32_t value) { assert(paramnum < m_numparams); assert(m_param[paramnum].is_mapvar()); m_param[paramnum] = value; } + void set_flags(u8 flags) { m_flags = flags; } + void set_mapvar(int paramnum, u32 value) { assert(paramnum < m_numparams); assert(m_param[paramnum].is_mapvar()); m_param[paramnum] = value; } // misc std::string disasm(drcuml_state *drcuml = nullptr) const; - uint8_t input_flags() const; - uint8_t output_flags() const; - uint8_t modified_flags() const; + u8 input_flags() const; + u8 output_flags() const; + u8 modified_flags() const; void simplify(); // compile-time opcodes void handle(code_handle &hand) { configure(OP_HANDLE, 4, hand); } - void hash(uint32_t mode, uint32_t pc) { configure(OP_HASH, 4, mode, pc); } + void hash(u32 mode, u32 pc) { configure(OP_HASH, 4, mode, pc); } void label(code_label lab) { configure(OP_LABEL, 4, lab); } - void comment(const char *string) { configure(OP_COMMENT, 4, parameter::make_string(string)); } - void mapvar(parameter mapvar, uint32_t value) { assert(mapvar.is_mapvar()); configure(OP_MAPVAR, 4, mapvar, value); } + void comment(char const *string) { configure(OP_COMMENT, 4, parameter::make_string(string)); } + void mapvar(parameter mapvar, u32 value) { assert(mapvar.is_mapvar()); configure(OP_MAPVAR, 4, mapvar, value); } // control flow operations void nop() { configure(OP_NOP, 4); } - void debug(uint32_t pc) { configure(OP_DEBUG, 4, pc); } + void debug(u32 pc) { configure(OP_DEBUG, 4, pc); } void exit(parameter param) { configure(OP_EXIT, 4, param); } void exit(condition_t cond, parameter param) { configure(OP_EXIT, 4, param, cond); } void hashjmp(parameter mode, parameter pc, code_handle &handle) { configure(OP_HASHJMP, 4, mode, pc, handle); } @@ -447,13 +446,13 @@ namespace uml void setfmod(parameter mode) { configure(OP_SETFMOD, 4, mode); } void getfmod(parameter dst) { configure(OP_GETFMOD, 4, dst); } void getexp(parameter dst) { configure(OP_GETEXP, 4, dst); } - void getflgs(parameter dst, uint32_t flags) { configure(OP_GETFLGS, 4, dst, flags); } + void getflgs(parameter dst, u32 flags) { configure(OP_GETFLGS, 4, dst, flags); } void save(drcuml_machine_state *dst) { configure(OP_SAVE, 4, parameter::make_memory(dst)); } void restore(drcuml_machine_state *src) { configure(OP_RESTORE, 4, parameter::make_memory(src)); } // 32-bit integer operations - void load(parameter dst, const void *base, parameter index, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_LOAD, 4, dst, parameter::make_memory(base), index, parameter(size, scale)); } - void loads(parameter dst, const void *base, parameter index, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_LOADS, 4, dst, parameter::make_memory(base), index, parameter(size, scale)); } + void load(parameter dst, void const *base, parameter index, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_LOAD, 4, dst, parameter::make_memory(base), index, parameter(size, scale)); } + void loads(parameter dst, void const *base, parameter index, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_LOADS, 4, dst, parameter::make_memory(base), index, parameter(size, scale)); } void store(void *base, parameter index, parameter src1, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_STORE, 4, parameter::make_memory(base), index, src1, parameter(size, scale)); } void read(parameter dst, parameter src1, operand_size size, memory_space space = SPACE_PROGRAM) { configure(OP_READ, 4, dst, src1, parameter(size, space)); } void readm(parameter dst, parameter src1, parameter mask, operand_size size, memory_space space = SPACE_PROGRAM) { configure(OP_READM, 4, dst, src1, mask, parameter(size, space)); } @@ -491,8 +490,8 @@ namespace uml void rorc(parameter dst, parameter src, parameter count) { configure(OP_RORC, 4, dst, src, count); } // 64-bit integer operations - void dload(parameter dst, const void *base, parameter index, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_LOAD, 8, dst, parameter::make_memory(base), index, parameter(size, scale)); } - void dloads(parameter dst, const void *base, parameter index, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_LOADS, 8, dst, parameter::make_memory(base), index, parameter(size, scale)); } + void dload(parameter dst, void const *base, parameter index, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_LOAD, 8, dst, parameter::make_memory(base), index, parameter(size, scale)); } + void dloads(parameter dst, void const *base, parameter index, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_LOADS, 8, dst, parameter::make_memory(base), index, parameter(size, scale)); } void dstore(void *base, parameter index, parameter src1, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_STORE, 8, parameter::make_memory(base), index, src1, parameter(size, scale)); } void dread(parameter dst, parameter src1, operand_size size, memory_space space = SPACE_PROGRAM) { configure(OP_READ, 8, dst, src1, parameter(size, space)); } void dreadm(parameter dst, parameter src1, parameter mask, operand_size size, memory_space space = SPACE_PROGRAM) { configure(OP_READM, 8, dst, src1, mask, parameter(size, space)); } @@ -530,7 +529,7 @@ namespace uml void drorc(parameter dst, parameter src, parameter count) { configure(OP_RORC, 8, dst, src, count); } // 32-bit floating point operations - void fsload(parameter dst, const void *base, parameter index) { configure(OP_FLOAD, 4, dst, parameter::make_memory(base), index); } + void fsload(parameter dst, void const *base, parameter index) { configure(OP_FLOAD, 4, dst, parameter::make_memory(base), index); } void fsstore(void *base, parameter index, parameter src1) { configure(OP_FSTORE, 4, parameter::make_memory(base), index, src1); } void fsread(parameter dst, parameter src1, memory_space space) { configure(OP_FREAD, 4, dst, src1, parameter(SIZE_SHORT, space)); } void fswrite(parameter dst, parameter src1, memory_space space) { configure(OP_FWRITE, 4, dst, src1, parameter(SIZE_SHORT, space)); } @@ -553,7 +552,7 @@ namespace uml void icopyfs(parameter dst, parameter src) { configure(OP_ICOPYF, 4, dst, src); } // 64-bit floating point operations - void fdload(parameter dst, const void *base, parameter index) { configure(OP_FLOAD, 8, dst, parameter::make_memory(base), index); } + void fdload(parameter dst, void const *base, parameter index) { configure(OP_FLOAD, 8, dst, parameter::make_memory(base), index); } void fdstore(void *base, parameter index, parameter src1) { configure(OP_FSTORE, 8, parameter::make_memory(base), index, src1); } void fdread(parameter dst, parameter src1, memory_space space) { configure(OP_FREAD, 8, dst, src1, parameter(SIZE_DOUBLE, space)); } void fdwrite(parameter dst, parameter src1, memory_space space) { configure(OP_FWRITE, 8, dst, src1, parameter(SIZE_DOUBLE, space)); } @@ -577,38 +576,38 @@ namespace uml void icopyfd(parameter dst, parameter src) { configure(OP_ICOPYF, 8, dst, src); } // constants - static const int MAX_PARAMS = 4; + static constexpr int MAX_PARAMS = 4; private: // internal configuration - void configure(opcode_t op, uint8_t size, condition_t cond = COND_ALWAYS); - void configure(opcode_t op, uint8_t size, parameter p0, condition_t cond = COND_ALWAYS); - void configure(opcode_t op, uint8_t size, parameter p0, parameter p1, condition_t cond = COND_ALWAYS); - void configure(opcode_t op, uint8_t size, parameter p0, parameter p1, parameter p2, condition_t cond = COND_ALWAYS); - void configure(opcode_t op, uint8_t size, parameter p0, parameter p1, parameter p2, parameter p3, condition_t cond = COND_ALWAYS); + void configure(opcode_t op, u8 size, condition_t cond = COND_ALWAYS); + void configure(opcode_t op, u8 size, parameter p0, condition_t cond = COND_ALWAYS); + void configure(opcode_t op, u8 size, parameter p0, parameter p1, condition_t cond = COND_ALWAYS); + void configure(opcode_t op, u8 size, parameter p0, parameter p1, parameter p2, condition_t cond = COND_ALWAYS); + void configure(opcode_t op, u8 size, parameter p0, parameter p1, parameter p2, parameter p3, condition_t cond = COND_ALWAYS); // opcode validation and simplification void validate(); - void convert_to_mov_immediate(uint64_t immediate) { m_opcode = OP_MOV; m_numparams = 2; m_param[1] = immediate; } + void convert_to_mov_immediate(u64 immediate) { m_opcode = OP_MOV; m_numparams = 2; m_param[1] = immediate; } void convert_to_mov_param(int pnum) { m_opcode = OP_MOV; m_numparams = 2; m_param[1] = m_param[pnum]; } // internal state - opcode_t m_opcode; // opcode - condition_t m_condition; // condition - uint8_t m_flags; // flags - uint8_t m_size; // operation size - uint8_t m_numparams; // number of parameters - parameter m_param[MAX_PARAMS];// up to 4 parameters - - static const opcode_info s_opcode_info_table[OP_MAX]; + opcode_t m_opcode = OP_INVALID; // opcode + condition_t m_condition = COND_ALWAYS; // condition + u8 m_flags = 0; // flags + u8 m_size = 4; // operation size + u8 m_numparams = 0; // number of parameters + parameter m_param[MAX_PARAMS]; // up to 4 parameters + + static opcode_info const s_opcode_info_table[OP_MAX]; }; // structure describing rules for parameter encoding struct parameter_info { - uint8_t output; // input or output? - uint8_t size; // size of the parameter - uint16_t typemask; // types allowed + u8 output; // input or output? + u8 size; // size of the parameter + u16 typemask; // types allowed }; // global inline functions to specify a register parameter by index @@ -666,5 +665,4 @@ namespace uml const parameter M9(parameter::make_mapvar(MAPVAR_M0 + 9)); } - -#endif /* __UML_H__ */ +#endif // MAME_CPU_UML_H diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp index 14f4d75eec4..84603cd59f2 100644 --- a/src/tools/unidasm.cpp +++ b/src/tools/unidasm.cpp @@ -313,7 +313,7 @@ static const dasm_table_entry dasm_table[] = { "cquestrot", be, -3, []() -> util::disasm_interface * { return new cquestrot_disassembler; } }, { "cquestsnd", be, -3, []() -> util::disasm_interface * { return new cquestsnd_disassembler; } }, { "ds5002fp", le, 0, []() -> util::disasm_interface * { return new ds5002fp_disassembler; } }, - { "dsp16a", le, -1, []() -> util::disasm_interface * { return new dsp16a_disassembler; } }, + { "dsp16", le, -1, []() -> util::disasm_interface * { return new dsp16_disassembler; } }, { "dsp32c", le, 0, []() -> util::disasm_interface * { return new dsp32c_disassembler; } }, { "dsp56k", le, -1, []() -> util::disasm_interface * { return new dsp56k_disassembler; } }, { "e0c6200", be, -1, []() -> util::disasm_interface * { return new e0c6200_disassembler; } }, -- cgit v1.2.3