summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2018-03-16 19:08:38 +1100
committer Vas Crabb <vas@vastheman.com>2018-03-17 00:58:54 +1100
commit245f822e7d6b71cdba5bd79c6657c0fc6a8d0bfd (patch)
treeb133df97c618c1f40e889a5720986292e905c72b
parente34faf61ffac3f7f5939c3f37e7fd4e5f2c02971 (diff)
use more constexpr and literal classes in UML to give compiler more optimisation opportunities (nw)
-rw-r--r--scripts/src/cpu.lua8
-rw-r--r--scripts/target/mame/arcade.lua2
-rw-r--r--scripts/target/mame/mess.lua2
-rw-r--r--src/devices/cpu/drcfe.cpp42
-rw-r--r--src/devices/cpu/drcfe.h104
-rw-r--r--src/devices/cpu/dsp16/dsp16.cpp2
-rw-r--r--src/devices/cpu/dsp16/dsp16dis.cpp40
-rw-r--r--src/devices/cpu/dsp16/dsp16dis.h8
-rw-r--r--src/devices/cpu/uml.cpp835
-rw-r--r--src/devices/cpu/uml.h222
-rw-r--r--src/tools/unidasm.cpp2
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_device &>(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_device &>(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<opcode_desc> m_desc_live_list; // list of live descriptions
fixed_allocator<opcode_desc> m_desc_allocator; // fixed allocator for descriptions
- std::vector<opcode_desc *> m_desc_array; // array of descriptions in PC order
+ std::vector<opcode_desc *> 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 <offs_t Base> 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 &params)
+offs_t dsp16_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
{
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<drccodeptr *>(drcuml.cache().alloc_near(sizeof(drccodeptr)))),
- m_string(name),
- m_next(nullptr),
- m_drcuml(drcuml)
+ : m_code(reinterpret_cast<drccodeptr *>(drcuml.cache().alloc_near(sizeof(drccodeptr))))
+ , m_string(name)
+ , m_next(nullptr)
+ , m_drcuml(drcuml)
{
if (m_code == nullptr)
throw std::bad_alloc();
@@ -284,28 +284,14 @@ void uml::code_handle::set_codeptr(drccodeptr code)
//**************************************************************************
//-------------------------------------------------
-// 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<char const *>(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 &param) : 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 &param) : 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<parameter_value>(&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<parameter_value>(base)); }
- static inline parameter make_memory(const void *base) { return parameter(PTYPE_MEMORY, reinterpret_cast<parameter_value>(const_cast<void *>(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<parameter_value>(const_cast<char *>(string))); }
- static inline parameter make_cfunc(c_function func) { return parameter(PTYPE_C_FUNCTION, reinterpret_cast<parameter_value>(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<parameter_value>(base)); }
+ static parameter make_memory(void const *base) { return parameter(PTYPE_MEMORY, reinterpret_cast<parameter_value>(const_cast<void *>(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<parameter_value>(const_cast<char *>(string))); }
+ static parameter make_cfunc(c_function func) { return parameter(PTYPE_C_FUNCTION, reinterpret_cast<parameter_value>(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<c_function>(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<const char *>(m_value); }
+ char const *string() const { assert(m_type == PTYPE_STRING); return reinterpret_cast<char const *>(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 &param(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; } },