use more constexpr and literal classes in UML to give compiler more optimisation opportunities (nw)

This commit is contained in:
Vas Crabb 2018-03-16 19:08:38 +11:00
parent e34faf61ff
commit 245f822e7d
11 changed files with 605 additions and 626 deletions

View File

@ -253,18 +253,18 @@ if (CPUS["APEXC"]~=null or _OPTIONS["with-tools"]) then
end end
-------------------------------------------------- --------------------------------------------------
-- AT&T DSP16A -- WE|AT&T DSP16
--@src/devices/cpu/dsp16/dsp16.h,CPUS["DSP16A"] = true --@src/devices/cpu/dsp16/dsp16.h,CPUS["DSP16"] = true
-------------------------------------------------- --------------------------------------------------
if (CPUS["DSP16A"]~=null) then if (CPUS["DSP16"]~=null) then
files { files {
MAME_DIR .. "src/devices/cpu/dsp16/dsp16.cpp", MAME_DIR .. "src/devices/cpu/dsp16/dsp16.cpp",
MAME_DIR .. "src/devices/cpu/dsp16/dsp16.h", MAME_DIR .. "src/devices/cpu/dsp16/dsp16.h",
} }
end 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.cpp")
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/dsp16/dsp16dis.h") table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/dsp16/dsp16dis.h")
end end

View File

@ -61,7 +61,7 @@ CPUS["MIPS"] = true
CPUS["R3000"] = true CPUS["R3000"] = true
CPUS["PSX"] = true CPUS["PSX"] = true
CPUS["SH"] = true CPUS["SH"] = true
CPUS["DSP16A"] = true CPUS["DSP16"] = true
CPUS["DSP32C"] = true CPUS["DSP32C"] = true
CPUS["PIC16C5X"] = true CPUS["PIC16C5X"] = true
CPUS["PIC16C62X"] = true CPUS["PIC16C62X"] = true

View File

@ -61,7 +61,7 @@ CPUS["MIPS"] = true
CPUS["R3000"] = true CPUS["R3000"] = true
CPUS["PSX"] = true CPUS["PSX"] = true
CPUS["SH"] = true CPUS["SH"] = true
CPUS["DSP16A"] = true CPUS["DSP16"] = true
CPUS["DSP32C"] = true CPUS["DSP32C"] = true
CPUS["PIC16C5X"] = true CPUS["PIC16C5X"] = true
CPUS["PIC16C62X"] = true CPUS["PIC16C62X"] = true

View File

@ -19,11 +19,13 @@
#include "drcfe.h" #include "drcfe.h"
namespace {
//************************************************************************** //**************************************************************************
// CONSTANTS // 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; offs_t srcpc;
}; };
} // anonymous namespace
//************************************************************************** //**************************************************************************
@ -48,14 +52,14 @@ struct pc_stack_entry
// drc_frontend - constructor // drc_frontend - constructor
//------------------------------------------------- //-------------------------------------------------
drc_frontend::drc_frontend(device_t &cpu, uint32_t window_start, uint32_t window_end, uint32_t max_sequence) drc_frontend::drc_frontend(device_t &cpu, u32 window_start, u32 window_end, u32 max_sequence)
: m_window_start(window_start), : m_window_start(window_start)
m_window_end(window_end), , m_window_end(window_end)
m_max_sequence(max_sequence), , m_max_sequence(max_sequence)
m_cpudevice(downcast<cpu_device &>(cpu)), , m_cpudevice(downcast<cpu_device &>(cpu))
m_program(m_cpudevice.space(AS_PROGRAM)), , m_program(m_cpudevice.space(AS_PROGRAM))
m_pageshift(m_cpudevice.space_config(AS_PROGRAM)->m_page_shift), , m_pageshift(m_cpudevice.space_config(AS_PROGRAM)->m_page_shift)
m_desc_array(window_end + window_start + 2, nullptr) , m_desc_array(window_end + window_start + 2, nullptr)
{ {
} }
@ -90,12 +94,12 @@ const opcode_desc *drc_frontend::describe_code(offs_t startpc)
pcstackptr++; pcstackptr++;
// loop while we still have a stack // loop while we still have a stack
offs_t minpc = startpc - std::min(m_window_start, startpc); offs_t const minpc = startpc - (std::min)(m_window_start, startpc);
offs_t maxpc = startpc + std::min(m_window_end, 0xffffffff - startpc); offs_t const maxpc = startpc + (std::min)(m_window_end, 0xffffffff - startpc);
while (pcstackptr != &pcstack[0]) while (pcstackptr != &pcstack[0])
{ {
// if we've already hit this PC, just mark it a branch target and continue // 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]; opcode_desc *curdesc = m_desc_array[curstack->targetpc - minpc];
if (curdesc != nullptr) if (curdesc != nullptr)
{ {
@ -156,10 +160,10 @@ const opcode_desc *drc_frontend::describe_code(offs_t startpc)
// slots of branches as well // 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 // initialize the description
opcode_desc *desc = m_desc_allocator.alloc(); opcode_desc *const desc = m_desc_allocator.alloc();
desc->m_next = nullptr; desc->m_next = nullptr;
desc->branch = nullptr; desc->branch = nullptr;
desc->delay.reset(); desc->delay.reset();
@ -208,7 +212,7 @@ opcode_desc *drc_frontend::describe_one(offs_t curpc, const opcode_desc *prevdes
} }
} }
opcode_desc *prev = desc; 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 // recursively describe the next instruction
opcode_desc *delaydesc = describe_one(delaypc, prev, true); 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 // 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 // iterate in order from start to end, picking up all non-NULL instructions
int consecutive = 0; 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]; opcode_desc *curdesc = m_desc_array[descnum];
int nextdescnum = descnum + curdesc->length; int nextdescnum = descnum + curdesc->length;
opcode_desc *nextdesc = (nextdescnum < end) ? m_desc_array[nextdescnum] : nullptr; 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; nextdescnum = nextdescnum + nextdesc->length;
nextdesc = (nextdescnum < end) ? m_desc_array[nextdescnum] : nullptr; 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) if (curdesc->flags & OPFLAG_END_SEQUENCE)
{ {
// figure out which registers we *must* generate, assuming at the end all must be // 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) if (seqstart != -1)
for (int backdesc = descnum; backdesc != seqstart - 1; backdesc--) for (int backdesc = descnum; backdesc != seqstart - 1; backdesc--)
if (m_desc_array[backdesc] != nullptr) 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 // 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 // recursively handle delay slots
if (desc.delay.first() != nullptr) if (desc.delay.first() != nullptr)

View File

@ -28,55 +28,54 @@
a linked list and returned for further processing by the backend. a linked list and returned for further processing by the backend.
***************************************************************************/ ***************************************************************************/
#ifndef MAME_CPU_DRCFE_H
#define MAME_CPU_DRCFE_H
#pragma once #pragma once
#ifndef __DRCFE_H__
#define __DRCFE_H__
//************************************************************************** //**************************************************************************
// CONSTANTS // CONSTANTS
//************************************************************************** //**************************************************************************
// this defines a branch targetpc that is dynamic at runtime // 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 // opcode branch flags
const uint32_t OPFLAG_IS_UNCONDITIONAL_BRANCH = 0x00000001; // instruction is unconditional branch constexpr u32 OPFLAG_IS_UNCONDITIONAL_BRANCH = 0x00000001; // instruction is unconditional branch
const uint32_t OPFLAG_IS_CONDITIONAL_BRANCH = 0x00000002; // instruction is conditional branch constexpr u32 OPFLAG_IS_CONDITIONAL_BRANCH = 0x00000002; // instruction is conditional branch
const uint32_t OPFLAG_IS_BRANCH = (OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_IS_CONDITIONAL_BRANCH); constexpr u32 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 constexpr u32 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 constexpr u32 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_INTRABLOCK_BRANCH = 0x00000010; // instruction branches within the block
// opcode exception flags // opcode exception flags
const uint32_t OPFLAG_CAN_TRIGGER_SW_INT = 0x00000020; // instruction can trigger a software interrupt constexpr u32 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 constexpr u32 OPFLAG_CAN_EXPOSE_EXTERNAL_INT = 0x00000040; // instruction can expose an external interrupt
const uint32_t OPFLAG_CAN_CAUSE_EXCEPTION = 0x00000080; // instruction may generate exception constexpr u32 OPFLAG_CAN_CAUSE_EXCEPTION = 0x00000080; // instruction may generate exception
const uint32_t OPFLAG_WILL_CAUSE_EXCEPTION = 0x00000100; // instruction will generate exception constexpr u32 OPFLAG_WILL_CAUSE_EXCEPTION = 0x00000100; // instruction will generate exception
const uint32_t OPFLAG_PRIVILEGED = 0x00000200; // instruction is privileged constexpr u32 OPFLAG_PRIVILEGED = 0x00000200; // instruction is privileged
// opcode virtual->physical translation flags // opcode virtual->physical translation flags
const uint32_t OPFLAG_VALIDATE_TLB = 0x00000400; // instruction must validate TLB before execution constexpr u32 OPFLAG_VALIDATE_TLB = 0x00000400; // instruction must validate TLB before execution
const uint32_t OPFLAG_MODIFIES_TRANSLATION = 0x00000800; // instruction modifies the TLB constexpr u32 OPFLAG_MODIFIES_TRANSLATION = 0x00000800; // instruction modifies the TLB
const uint32_t OPFLAG_COMPILER_PAGE_FAULT = 0x00001000; // compiler hit a page fault when parsing constexpr u32 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_COMPILER_UNMAPPED = 0x00002000; // compiler hit unmapped memory when parsing
// opcode flags // opcode flags
const uint32_t OPFLAG_INVALID_OPCODE = 0x00004000; // instruction is invalid constexpr u32 OPFLAG_INVALID_OPCODE = 0x00004000; // instruction is invalid
const uint32_t OPFLAG_VIRTUAL_NOOP = 0x00008000; // instruction is a virtual no-op constexpr u32 OPFLAG_VIRTUAL_NOOP = 0x00008000; // instruction is a virtual no-op
// opcode sequence flow flags // opcode sequence flow flags
const uint32_t OPFLAG_REDISPATCH = 0x00010000; // instruction must redispatch after completion constexpr u32 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 constexpr u32 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 constexpr u32 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_CAN_CHANGE_MODES = 0x00080000; // instruction can change modes
// execution semantics // execution semantics
const uint32_t OPFLAG_READS_MEMORY = 0x00100000; // instruction reads memory constexpr u32 OPFLAG_READS_MEMORY = 0x00100000; // instruction reads memory
const uint32_t OPFLAG_WRITES_MEMORY = 0x00200000; // instruction writes 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 // copy of up to 16 bytes of opcode
union union
{ {
uint8_t b[16]; u8 b[16];
uint16_t w[8]; u16 w[8];
uint32_t l[4]; u32 l[4];
uint64_t q[2]; u64 q[2];
} opptr; // pointer to opcode memory } opptr; // pointer to opcode memory
// information about this instruction's execution // information about this instruction's execution
uint8_t length; // length in bytes of this opcode u8 length; // length in bytes of this opcode
uint8_t delayslots; // number of delay slots (for branches) u8 delayslots; // number of delay slots (for branches)
uint8_t skipslots; // number of skip slots (for branches) u8 skipslots; // number of skip slots (for branches)
uint32_t flags; // OPFLAG_* opcode flags u32 flags; // OPFLAG_* opcode flags
uint32_t userflags; // core specific flags u32 userflags; // core specific flags
uint32_t userdata0; // core specific data u32 userdata0; // core specific data
uint32_t cycles; // number of cycles needed to execute u32 cycles; // number of cycles needed to execute
// register usage information // register usage information
uint32_t regin[4]; // input registers u32 regin[4]; // input registers
uint32_t regout[4]; // output registers u32 regout[4]; // output registers
uint32_t regreq[4]; // required output registers u32 regreq[4]; // required output registers
}; };
@ -129,27 +128,27 @@ class drc_frontend
{ {
public: public:
// construction/destruction // 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(); virtual ~drc_frontend();
// describe a block // describe a block
const opcode_desc *describe_code(offs_t startpc); opcode_desc const *describe_code(offs_t startpc);
protected: protected:
// required overrides // 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: private:
// internal helpers // internal helpers
opcode_desc *describe_one(offs_t curpc, const opcode_desc *prevdesc, bool in_delay_slot = false); opcode_desc *describe_one(offs_t curpc, opcode_desc const *prevdesc, bool in_delay_slot = false);
void build_sequence(int start, int end, uint32_t endflag); void build_sequence(int start, int end, u32 endflag);
void accumulate_required_backwards(opcode_desc &desc, uint32_t *reqmask); void accumulate_required_backwards(opcode_desc &desc, u32 *reqmask);
void release_descriptions(); void release_descriptions();
// configuration parameters // configuration parameters
uint32_t m_window_start; // code window start offset = startpc - window_start u32 m_window_start; // code window start offset = startpc - window_start
uint32_t m_window_end; // code window end offset = startpc + window_end u32 m_window_end; // code window end offset = startpc + window_end
uint32_t m_max_sequence; // maximum instructions to include in a sequence u32 m_max_sequence; // maximum instructions to include in a sequence
// CPU parameters // CPU parameters
cpu_device & m_cpudevice; // CPU device object cpu_device & m_cpudevice; // CPU device object
@ -162,5 +161,4 @@ private:
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 // MAME_CPU_DRCFE_H
#endif /* __DRCFE_H__ */

View File

@ -622,7 +622,7 @@ void dsp16_device_base::state_export(device_state_entry const &entry)
util::disasm_interface *dsp16_device_base::create_disassembler() 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) template <offs_t Base> READ16_MEMBER(dsp16_device_base::external_memory_r)

View File

@ -3,7 +3,7 @@
#include "emu.h" #include "emu.h"
#include "dsp16dis.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) switch (F1)
{ {
@ -27,7 +27,7 @@ std::string dsp16a_disassembler::disasmF1Field(u8 F1, u8 D, u8 S)
return "UNKNOWN"; return "UNKNOWN";
} }
std::string dsp16a_disassembler::disasmYField(u8 Y) std::string dsp16_disassembler::disasmYField(u8 Y)
{ {
switch (Y & 0x03U) switch (Y & 0x03U)
{ {
@ -39,7 +39,7 @@ std::string dsp16a_disassembler::disasmYField(u8 Y)
return "UNKNOWN"; return "UNKNOWN";
} }
std::string dsp16a_disassembler::disasmZField(u8 Z) std::string dsp16_disassembler::disasmZField(u8 Z)
{ {
switch (Z & 0x03U) switch (Z & 0x03U)
{ {
@ -51,7 +51,7 @@ std::string dsp16a_disassembler::disasmZField(u8 Z)
return "UNKNOWN"; 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) switch (F2)
{ {
@ -75,7 +75,7 @@ std::string dsp16a_disassembler::disasmF2Field(u8 F2, u8 D, u8 S)
return "UNKNOWN"; return "UNKNOWN";
} }
std::string dsp16a_disassembler::disasmCONField(u8 CON) std::string dsp16_disassembler::disasmCONField(u8 CON)
{ {
switch (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) switch (B)
{ {
@ -118,7 +118,7 @@ std::string dsp16a_disassembler::disasmBField(u8 B, uint32_t &dasmflags)
return "UNKNOWN"; return "UNKNOWN";
} }
std::string dsp16a_disassembler::disasmRImmediateField(u8 R) std::string dsp16_disassembler::disasmRImmediateField(u8 R)
{ {
switch (R) switch (R)
{ {
@ -134,7 +134,7 @@ std::string dsp16a_disassembler::disasmRImmediateField(u8 R)
return "UNKNOWN"; return "UNKNOWN";
} }
std::string dsp16a_disassembler::disasmRField(u8 R) std::string dsp16_disassembler::disasmRField(u8 R)
{ {
switch (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) 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) 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; return PAGED;
} }
u32 dsp16a_disassembler::page_address_bits() const u32 dsp16_disassembler::page_address_bits() const
{ {
return 12U; return 12U;
} }
u32 dsp16a_disassembler::opcode_alignment() const u32 dsp16_disassembler::opcode_alignment() const
{ {
return 1U; 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; u8 opSize = 1;
uint32_t dasmflags = 0; u32 dasmflags = 0;
uint16_t op = opcodes.r16(pc); u16 op = opcodes.r16(pc);
uint16_t op2 = opcodes.r16(pc+1); u16 op2 = opcodes.r16(pc+1);
// TODO: Test for previous "if CON" instruction and tab the next instruction in? // 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 // Format 4: Branch Direct Group
case 0x00: case 0x01: // goto JA 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); util::stream_format(stream, "goto 0x%04x", JA);
} }
break; break;
case 0x10: case 0x11: // call JA 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); util::stream_format(stream, "call 0x%04x", JA);
dasmflags |= STEP_OVER; 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 // Format 9: Short Immediate Group
case 0x02: case 0x03: // R = M case 0x02: case 0x03: // R = M
{ {
const uint16_t M = (op & 0x01ff); const u16 M = (op & 0x01ff);
const u8 R = (op & 0x0e00) >> 9; const u8 R = (op & 0x0e00) >> 9;
std::string rString = disasmRImmediateField(R); std::string rString = disasmRImmediateField(R);
util::stream_format(stream, "set %s = 0x%04x", rString, M); util::stream_format(stream, "set %s = 0x%04x", rString, M);

View File

@ -5,11 +5,11 @@
#pragma once #pragma once
class dsp16a_disassembler : public util::disasm_interface class dsp16_disassembler : public util::disasm_interface
{ {
public: public:
dsp16a_disassembler() = default; dsp16_disassembler() = default;
virtual ~dsp16a_disassembler() = default; virtual ~dsp16_disassembler() = default;
virtual u32 interface_flags() const override; virtual u32 interface_flags() const override;
virtual u32 page_address_bits() const override; virtual u32 page_address_bits() const override;
@ -22,7 +22,7 @@ private:
std::string disasmZField(u8 Z); std::string disasmZField(u8 Z);
std::string disasmF2Field(u8 F2, u8 D, u8 S); std::string disasmF2Field(u8 F2, u8 D, u8 S);
std::string disasmCONField(u8 CON); 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 disasmRImmediateField(u8 R);
std::string disasmRField(u8 R); std::string disasmRField(u8 R);
std::string disasmIField(u8 I); std::string disasmIField(u8 I);

View File

@ -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 } }, #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 // 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) 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 // 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; count &= 31;
return (source << count) | (source >> (32 - count)); 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 // 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; count &= 63;
return (source << count) | (source >> (64 - count)); 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) uml::code_handle::code_handle(drcuml_state &drcuml, const char *name)
: m_code(reinterpret_cast<drccodeptr *>(drcuml.cache().alloc_near(sizeof(drccodeptr)))), : m_code(reinterpret_cast<drccodeptr *>(drcuml.cache().alloc_near(sizeof(drccodeptr))))
m_string(name), , m_string(name)
m_next(nullptr), , m_next(nullptr)
m_drcuml(drcuml) , m_drcuml(drcuml)
{ {
if (m_code == nullptr) if (m_code == nullptr)
throw std::bad_alloc(); throw std::bad_alloc();
@ -283,29 +283,15 @@ void uml::code_handle::set_codeptr(drccodeptr code)
// UML INSTRUCTION // 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 // configure - configure an opcode with no
// parameters // 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 // fill in the instruction
m_opcode = (opcode_t)(uint8_t)op; m_opcode = opcode_t(u8(op));
m_size = size; m_size = size;
m_condition = condition; m_condition = condition;
m_flags = 0; m_flags = 0;
@ -321,10 +307,10 @@ void uml::instruction::configure(opcode_t op, uint8_t size, condition_t conditio
// parameter // 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 // fill in the instruction
m_opcode = (opcode_t)(uint8_t)op; m_opcode = opcode_t(u8(op));
m_size = size; m_size = size;
m_condition = condition; m_condition = condition;
m_flags = 0; m_flags = 0;
@ -341,10 +327,10 @@ void uml::instruction::configure(opcode_t op, uint8_t size, parameter p0, condit
// parameters // 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 // fill in the instruction
m_opcode = (opcode_t)(uint8_t)op; m_opcode = opcode_t(u8(op));
m_size = size; m_size = size;
m_condition = condition; m_condition = condition;
m_flags = 0; m_flags = 0;
@ -362,10 +348,10 @@ void uml::instruction::configure(opcode_t op, uint8_t size, parameter p0, parame
// parameters // 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 // fill in the instruction
m_opcode = (opcode_t)(uint8_t)op; m_opcode = opcode_t(u8(op));
m_size = size; m_size = size;
m_condition = condition; m_condition = condition;
m_flags = 0; m_flags = 0;
@ -384,10 +370,10 @@ void uml::instruction::configure(opcode_t op, uint8_t size, parameter p0, parame
// parameters // 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 // fill in the instruction
m_opcode = (opcode_t)(uint8_t)op; m_opcode = opcode_t(u8(op));
m_size = size; m_size = size;
m_condition = condition; m_condition = condition;
m_flags = 0; m_flags = 0;
@ -414,8 +400,8 @@ void uml::instruction::simplify()
if (m_flags != 0) if (m_flags != 0)
return; return;
static const uint64_t instsizemask[] = { 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0xffffffffffffffffU }; static constexpr u64 instsizemask[] = { 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0xffffffffffffffffU };
static const uint64_t paramsizemask[] = { 0xff, 0xffff, 0xffffffff, 0xffffffffffffffffU }; static constexpr u64 paramsizemask[] = { 0xff, 0xffff, 0xffffffff, 0xffffffffffffffffU };
// loop until we've simplified all we can // loop until we've simplified all we can
opcode_t origop; opcode_t origop;
@ -462,10 +448,10 @@ void uml::instruction::simplify()
if (m_param[1].is_immediate()) if (m_param[1].is_immediate())
switch (m_param[2].size()) switch (m_param[2].size())
{ {
case SIZE_BYTE: convert_to_mov_immediate((int8_t)m_param[1].immediate()); break; case SIZE_BYTE: convert_to_mov_immediate(s8(m_param[1].immediate())); break;
case SIZE_WORD: convert_to_mov_immediate((int16_t)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((int32_t)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((int64_t)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"); case SIZE_DQWORD: fatalerror("Invalid SEXT target size\n");
} }
break; break;
@ -545,9 +531,9 @@ void uml::instruction::simplify()
else if (m_param[2].is_immediate() && m_param[3].is_immediate()) else if (m_param[2].is_immediate() && m_param[3].is_immediate())
{ {
if (m_size == 4) if (m_size == 4)
convert_to_mov_immediate((uint32_t)((uint32_t)m_param[1].immediate() * (uint32_t)m_param[2].immediate())); convert_to_mov_immediate(u32(u32(m_param[1].immediate()) * u32(m_param[2].immediate())));
else if (m_size == 8) else if (m_size == 8)
convert_to_mov_immediate((uint64_t)((uint64_t)m_param[1].immediate() * (uint64_t)m_param[2].immediate())); convert_to_mov_immediate(u64(u64(m_param[1].immediate()) * u64(m_param[2].immediate())));
} }
} }
break; break;
@ -561,9 +547,9 @@ void uml::instruction::simplify()
else if (m_param[2].is_immediate() && m_param[3].is_immediate()) else if (m_param[2].is_immediate() && m_param[3].is_immediate())
{ {
if (m_size == 4) if (m_size == 4)
convert_to_mov_immediate((int32_t)((int32_t)m_param[1].immediate() * (int32_t)m_param[2].immediate())); convert_to_mov_immediate(s32(s32(m_param[1].immediate()) * s32(m_param[2].immediate())));
else if (m_size == 8) else if (m_size == 8)
convert_to_mov_immediate((int64_t)((int64_t)m_param[1].immediate() * (int64_t)m_param[2].immediate())); convert_to_mov_immediate(s64(s64(m_param[1].immediate()) * s64(m_param[2].immediate())));
} }
} }
break; break;
@ -577,9 +563,9 @@ void uml::instruction::simplify()
else if (m_param[2].is_immediate() && m_param[3].is_immediate()) else if (m_param[2].is_immediate() && m_param[3].is_immediate())
{ {
if (m_size == 4) if (m_size == 4)
convert_to_mov_immediate((uint32_t)((uint32_t)m_param[1].immediate() / (uint32_t)m_param[2].immediate())); convert_to_mov_immediate(u32(u32(m_param[1].immediate()) / u32(m_param[2].immediate())));
else if (m_size == 8) else if (m_size == 8)
convert_to_mov_immediate((uint64_t)((uint64_t)m_param[1].immediate() / (uint64_t)m_param[2].immediate())); convert_to_mov_immediate(u64(u64(m_param[1].immediate()) / u64(m_param[2].immediate())));
} }
} }
break; break;
@ -593,9 +579,9 @@ void uml::instruction::simplify()
else if (m_param[2].is_immediate() && m_param[3].is_immediate()) else if (m_param[2].is_immediate() && m_param[3].is_immediate())
{ {
if (m_size == 4) if (m_size == 4)
convert_to_mov_immediate((int32_t)((int32_t)m_param[1].immediate() / (int32_t)m_param[2].immediate())); convert_to_mov_immediate(s32(s32(m_param[1].immediate()) / s32(m_param[2].immediate())));
else if (m_size == 8) else if (m_size == 8)
convert_to_mov_immediate((int64_t)((int64_t)m_param[1].immediate() / (int64_t)m_param[2].immediate())); convert_to_mov_immediate(s64(s64(m_param[1].immediate()) / s64(m_param[2].immediate())));
} }
} }
break; break;
@ -680,9 +666,9 @@ void uml::instruction::simplify()
if (m_param[1].is_immediate() && m_param[2].is_immediate()) if (m_param[1].is_immediate() && m_param[2].is_immediate())
{ {
if (m_size == 4) if (m_size == 4)
convert_to_mov_immediate((uint32_t)m_param[1].immediate() >> m_param[2].immediate()); convert_to_mov_immediate(u32(m_param[1].immediate()) >> m_param[2].immediate());
else if (m_size == 8) else if (m_size == 8)
convert_to_mov_immediate((uint64_t)m_param[1].immediate() >> m_param[2].immediate()); convert_to_mov_immediate(u64(m_param[1].immediate()) >> m_param[2].immediate());
} }
else if (m_param[2].is_immediate_value(0)) else if (m_param[2].is_immediate_value(0))
convert_to_mov_param(1); convert_to_mov_param(1);
@ -693,9 +679,9 @@ void uml::instruction::simplify()
if (m_param[1].is_immediate() && m_param[2].is_immediate()) if (m_param[1].is_immediate() && m_param[2].is_immediate())
{ {
if (m_size == 4) if (m_size == 4)
convert_to_mov_immediate((int32_t)m_param[1].immediate() >> m_param[2].immediate()); convert_to_mov_immediate(s32(m_param[1].immediate()) >> m_param[2].immediate());
else if (m_size == 8) else if (m_size == 8)
convert_to_mov_immediate((int64_t)m_param[1].immediate() >> m_param[2].immediate()); convert_to_mov_immediate(s64(m_param[1].immediate()) >> m_param[2].immediate());
} }
else if (m_param[2].is_immediate_value(0)) else if (m_param[2].is_immediate_value(0))
convert_to_mov_param(1); convert_to_mov_param(1);
@ -782,7 +768,7 @@ void uml::instruction::validate()
// make sure we aren't missing any parameters // make sure we aren't missing any parameters
if (m_numparams < ARRAY_LENGTH(opinfo.param)) if (m_numparams < ARRAY_LENGTH(opinfo.param))
assert(opinfo.param[m_numparams].typemask == 0); assert(opinfo.param[m_numparams].typemask == 0);
#endif #endif // MAME_DEBUG
} }
@ -792,9 +778,9 @@ void uml::instruction::validate()
// instruction // 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_Z
FLAG_Z, // COND_NZ FLAG_Z, // COND_NZ
@ -814,7 +800,7 @@ uint8_t uml::instruction::input_flags() const
FLAG_S | FLAG_V // COND_GE 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) if (flags & 0x80)
flags = m_param[flags - OPFLAGS_P1].immediate() & OPFLAGS_ALL; flags = m_param[flags - OPFLAGS_P1].immediate() & OPFLAGS_ALL;
if (m_condition != COND_ALWAYS) if (m_condition != COND_ALWAYS)
@ -829,9 +815,9 @@ uint8_t uml::instruction::input_flags() const
// instruction // 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) if (flags & 0x80)
flags = m_param[flags - OPFLAGS_P1].immediate() & OPFLAGS_ALL; flags = m_param[flags - OPFLAGS_P1].immediate() & OPFLAGS_ALL;
return flags; return flags;
@ -844,7 +830,7 @@ uint8_t uml::instruction::output_flags() const
// instruction // instruction
//------------------------------------------------- //-------------------------------------------------
uint8_t uml::instruction::modified_flags() const u8 uml::instruction::modified_flags() const
{ {
return s_opcode_info_table[m_opcode].modflags; 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 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 char const *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 char const *const pound_size[] = { "?", "?", "?", "?", "s", "?", "?", "?", "d" };
static const char *const bang_size[] = { "?", "b", "h", "?", "", "?", "?", "?", "d" }; static char const *const bang_size[] = { "?", "b", "h", "?", "", "?", "?", "?", "d" };
static const char *const fmods[] = { "trunc", "round", "ceil", "floor", "default" }; static char const *const fmods[] = { "trunc", "round", "ceil", "floor", "default" };
static const char *const spaces[] = { "program", "data", "io", "3", "4", "5", "6", "7" }; static char const *const spaces[] = { "program", "data", "io", "3", "4", "5", "6", "7" };
static const char *const sizes[] = { "byte", "word", "dword", "qword" }; static char const *const sizes[] = { "byte", "word", "dword", "qword" };
const opcode_info &opinfo = s_opcode_info_table[m_opcode];
assert(m_opcode != OP_INVALID && m_opcode < OP_MAX); 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 // start with the raw mnemonic and substitute sizes
std::ostringstream buffer; std::ostringstream buffer;
for (const char *opsrc = opinfo.mnemonic; *opsrc != 0; opsrc++) for (char const *opsrc = opinfo.mnemonic; *opsrc != 0; opsrc++)
if (*opsrc == '!') if (*opsrc == '!')
util::stream_format(buffer, "%s", bang_size[m_size]); util::stream_format(buffer, "%s", bang_size[m_size]);
else if (*opsrc == '#') else if (*opsrc == '#')
@ -879,12 +865,8 @@ std::string uml::instruction::disasm(drcuml_state *drcuml) const
util::stream_format(buffer, "%c", *opsrc); util::stream_format(buffer, "%c", *opsrc);
// pad to 8 spaces // pad to 8 spaces
int pad = 8 - buffer.tellp(); for (int pad = 8 - buffer.tellp(); (pad > 0); --pad)
while (pad > 0)
{
buffer.put(' '); buffer.put(' ');
pad--;
}
// iterate through parameters // iterate through parameters
for (int pnum = 0; pnum < m_numparams; pnum++) for (int pnum = 0; pnum < m_numparams; pnum++)
@ -916,14 +898,11 @@ std::string uml::instruction::disasm(drcuml_state *drcuml) const
} }
// truncate to size // truncate to size
uint64_t value = param.immediate(); u64 value = param.immediate();
if (size == 1) value = (uint8_t)value; if (size == 1) value = u8(value);
if (size == 2) value = (uint16_t)value; if (size == 2) value = u16(value);
if (size == 4) value = (uint32_t)value; if (size == 4) value = u32(value);
if ((uint32_t)value == value) util::stream_format(buffer, "$%X", value);
util::stream_format(buffer, "$%X", (uint32_t)value);
else
util::stream_format(buffer, "$%X%08X", (uint32_t)(value >> 32), (uint32_t)value);
} }
break; break;
@ -940,8 +919,8 @@ std::string uml::instruction::disasm(drcuml_state *drcuml) const
// size + scale immediate // size + scale immediate
case parameter::PTYPE_SIZE_SCALE: case parameter::PTYPE_SIZE_SCALE:
{ {
int scale = param.scale(); int const scale = param.scale();
int size = param.size(); int const size = param.size();
if (scale == size) if (scale == size)
util::stream_format(buffer, "%s", sizes[size]); util::stream_format(buffer, "%s", sizes[size]);
else else
@ -973,7 +952,7 @@ std::string uml::instruction::disasm(drcuml_state *drcuml) const
case parameter::PTYPE_MEMORY: case parameter::PTYPE_MEMORY:
{ {
const char *symbol; const char *symbol;
uint32_t symoffset; u32 symoffset;
// symbol // symbol
if (drcuml != nullptr && (symbol = drcuml->symbol_find(param.memory(), &symoffset)) != nullptr) if (drcuml != nullptr && (symbol = drcuml->symbol_find(param.memory(), &symoffset)) != nullptr)
@ -986,17 +965,17 @@ std::string uml::instruction::disasm(drcuml_state *drcuml) const
// cache memory // cache memory
else if (drcuml != nullptr && drcuml->cache().contains_pointer(param.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 // general memory
else else
util::stream_format(buffer, "[[$%p]]", param.memory()); util::stream_format(buffer, "[[$%p]]", param.memory());
break;
} }
break;
// string pointer // string pointer
case parameter::PTYPE_STRING: case parameter::PTYPE_STRING:
util::stream_format(buffer, "%s", (const char *)(uintptr_t)param.string()); util::stream_format(buffer, "%s", reinterpret_cast<char const *>(uintptr_t(param.string())));
break; break;
// handle pointer // handle pointer

View File

@ -7,12 +7,11 @@
Universal machine language definitions and classes. Universal machine language definitions and classes.
***************************************************************************/ ***************************************************************************/
#ifndef MAME_CPU_UML_H
#define MAME_CPU_UML_H
#pragma once #pragma once
#ifndef __UML_H__
#define __UML_H__
#include "drccache.h" #include "drccache.h"
@ -31,31 +30,31 @@ struct drcuml_machine_state;
namespace uml namespace uml
{ {
// integer registers // integer registers
const int REG_I0 = 0x400; constexpr int REG_I0 = 0x400;
const int REG_I_COUNT = 10; constexpr int REG_I_COUNT = 10;
const int REG_I_END = REG_I0 + REG_I_COUNT; constexpr int REG_I_END = REG_I0 + REG_I_COUNT;
// floating point registers // floating point registers
const int REG_F0 = 0x800; constexpr int REG_F0 = 0x800;
const int REG_F_COUNT = 10; constexpr int REG_F_COUNT = 10;
const int REG_F_END = REG_F0 + REG_F_COUNT; constexpr int REG_F_END = REG_F0 + REG_F_COUNT;
// vector registers // vector registers
const int REG_V0 = 0xc00; constexpr int REG_V0 = 0xc00;
const int REG_V_COUNT = 10; constexpr int REG_V_COUNT = 10;
const int REG_V_END = REG_V0 + REG_V_COUNT; constexpr int REG_V_END = REG_V0 + REG_V_COUNT;
// map variables // map variables
const int MAPVAR_M0 = 0x1000; constexpr int MAPVAR_M0 = 0x1000;
const int MAPVAR_COUNT = 10; constexpr int MAPVAR_COUNT = 10;
const int MAPVAR_END = MAPVAR_M0 + MAPVAR_COUNT; constexpr int MAPVAR_END = MAPVAR_M0 + MAPVAR_COUNT;
// flag definitions // flag definitions
const uint8_t FLAG_C = 0x01; // carry flag constexpr u8 FLAG_C = 0x01; // carry flag
const uint8_t FLAG_V = 0x02; // overflow flag (defined for integer only) constexpr u8 FLAG_V = 0x02; // overflow flag (defined for integer only)
const uint8_t FLAG_Z = 0x04; // zero flag constexpr u8 FLAG_Z = 0x04; // zero flag
const uint8_t FLAG_S = 0x08; // sign flag (defined for integer only) constexpr u8 FLAG_S = 0x08; // sign flag (defined for integer only)
const uint8_t FLAG_U = 0x10; // unordered flag (defined for FP only) constexpr u8 FLAG_U = 0x10; // unordered flag (defined for FP only)
// testable conditions; note that these are defined such that (condition ^ 1) is // testable conditions; note that these are defined such that (condition ^ 1) is
// always the opposite // always the opposite
@ -242,7 +241,7 @@ namespace uml
code_handle *next() const { return m_next; } code_handle *next() const { return m_next; }
drccodeptr codeptr() const { return *m_code; } drccodeptr codeptr() const { return *m_code; }
drccodeptr *codeptr_addr() { 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 // setters
void set_codeptr(drccodeptr code); void set_codeptr(drccodeptr code);
@ -260,18 +259,18 @@ namespace uml
{ {
public: public:
// construction // construction
code_label(uint32_t label = 0) : m_label(label) { } constexpr code_label(u32 label = 0) : m_label(label) { }
// operators // operators
operator uint32_t &() { return m_label; } operator u32 &() { return m_label; }
bool operator==(const code_label &rhs) const { return (m_label == rhs.m_label); } constexpr bool operator==(code_label const &rhs) const { return (m_label == rhs.m_label); }
bool operator!=(const code_label &rhs) const { return (m_label != rhs.m_label); } constexpr bool operator!=(code_label const &rhs) const { return (m_label != rhs.m_label); }
// getters // getters
uint32_t label() const { return m_label; } constexpr u32 label() const { return m_label; }
private: private:
uint32_t m_label; u32 m_label;
}; };
// a parameter for a UML instruction is encoded like this // a parameter for a UML instruction is encoded like this
@ -300,36 +299,36 @@ namespace uml
}; };
// represents the value of an opcode parameter // represents the value of an opcode parameter
typedef uint64_t parameter_value; typedef u64 parameter_value;
// construction // construction
parameter() : m_type(PTYPE_NONE), m_value(0) { } constexpr parameter() : m_type(PTYPE_NONE), m_value(0) { }
parameter(const parameter &param) : m_type(param.m_type), m_value(param.m_value) { } constexpr parameter(parameter const &param) : m_type(param.m_type), m_value(param.m_value) { }
parameter(uint64_t val) : m_type(PTYPE_IMMEDIATE), m_value(val) { } 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_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(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_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 // 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 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 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 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 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 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 parameter make_memory(void const *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 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 parameter make_string(char const *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 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_rounding(float_rounding_mode mode) { assert(mode >= ROUND_TRUNC && mode <= ROUND_DEFAULT); return parameter(PTYPE_ROUNDING, mode); }
// operators // operators
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); }
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); }
// getters // getters
parameter_type type() const { return m_type; } constexpr parameter_type type() const { return m_type; }
uint64_t immediate() const { assert(m_type == PTYPE_IMMEDIATE); return m_value; } 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 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 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; } 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); } 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); } 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); } 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 // type queries
bool is_immediate() const { return (m_type == PTYPE_IMMEDIATE); } constexpr bool is_immediate() const { return m_type == PTYPE_IMMEDIATE; }
bool is_int_register() const { return (m_type == PTYPE_INT_REGISTER); } constexpr bool is_int_register() const { return m_type == PTYPE_INT_REGISTER; }
bool is_float_register() const { return (m_type == PTYPE_FLOAT_REGISTER); } constexpr bool is_float_register() const { return m_type == PTYPE_FLOAT_REGISTER; }
bool is_vector_register() const { return (m_type == PTYPE_VECTOR_REGISTER); } constexpr bool is_vector_register() const { return m_type == PTYPE_VECTOR_REGISTER; }
bool is_mapvar() const { return (m_type == PTYPE_MAPVAR); } constexpr bool is_mapvar() const { return m_type == PTYPE_MAPVAR; }
bool is_memory() const { return (m_type == PTYPE_MEMORY); } constexpr bool is_memory() const { return m_type == PTYPE_MEMORY; }
bool is_size() const { return (m_type == PTYPE_SIZE); } constexpr bool is_size() const { return m_type == PTYPE_SIZE; }
bool is_size_scale() const { return (m_type == PTYPE_SIZE_SCALE); } constexpr bool is_size_scale() const { return m_type == PTYPE_SIZE_SCALE; }
bool is_size_space() const { return (m_type == PTYPE_SIZE_SPACE); } constexpr bool is_size_space() const { return m_type == PTYPE_SIZE_SPACE; }
bool is_code_handle() const { return (m_type == PTYPE_CODE_HANDLE); } constexpr bool is_code_handle() const { return m_type == PTYPE_CODE_HANDLE; }
bool is_code_label() const { return (m_type == PTYPE_CODE_LABEL); } constexpr bool is_code_label() const { return m_type == PTYPE_CODE_LABEL; }
bool is_c_function() const { return (m_type == PTYPE_C_FUNCTION); } constexpr bool is_c_function() const { return m_type == PTYPE_C_FUNCTION; }
bool is_rounding() const { return (m_type == PTYPE_ROUNDING); } constexpr bool is_rounding() const { return m_type == PTYPE_ROUNDING; }
bool is_string() const { return (m_type == PTYPE_STRING); } constexpr bool is_string() const { return m_type == PTYPE_STRING; }
// other queries // 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:
// private constructor // private constructor
@ -377,18 +376,18 @@ namespace uml
{ {
struct parameter_info struct parameter_info
{ {
uint8_t output; // input or output? u8 output; // input or output?
uint8_t size; // size of the parameter u8 size; // size of the parameter
uint16_t typemask; // types allowed u16 typemask; // types allowed
}; };
opcode_t opcode; // the opcode itself opcode_t opcode; // the opcode itself
const char * mnemonic; // mnemonic string char const * mnemonic; // mnemonic string
uint8_t sizes; // allowed sizes u8 sizes; // allowed sizes
bool condition; // conditions allowed? bool condition; // conditions allowed?
uint8_t inflags; // input flags u8 inflags; // input flags
uint8_t outflags; // output flags u8 outflags; // output flags
uint8_t modflags; // modified flags u8 modflags; // modified flags
parameter_info param[4]; // information about parameters parameter_info param[4]; // information about parameters
}; };
@ -397,37 +396,37 @@ namespace uml
{ {
public: public:
// construction/destruction // construction/destruction
instruction(); constexpr instruction() { }
// getters // getters
opcode_t opcode() const { return m_opcode; } constexpr opcode_t opcode() const { return m_opcode; }
condition_t condition() const { return m_condition; } constexpr condition_t condition() const { return m_condition; }
uint8_t flags() const { return m_flags; } constexpr u8 flags() const { return m_flags; }
uint8_t size() const { return m_size; } constexpr u8 size() const { return m_size; }
uint8_t numparams() const { return m_numparams; } constexpr u8 numparams() const { return m_numparams; }
const parameter &param(int index) const { assert(index < m_numparams); return m_param[index]; } const parameter &param(int index) const { assert(index < m_numparams); return m_param[index]; }
// setters // setters
void set_flags(uint8_t flags) { m_flags = flags; } void set_flags(u8 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_mapvar(int paramnum, u32 value) { assert(paramnum < m_numparams); assert(m_param[paramnum].is_mapvar()); m_param[paramnum] = value; }
// misc // misc
std::string disasm(drcuml_state *drcuml = nullptr) const; std::string disasm(drcuml_state *drcuml = nullptr) const;
uint8_t input_flags() const; u8 input_flags() const;
uint8_t output_flags() const; u8 output_flags() const;
uint8_t modified_flags() const; u8 modified_flags() const;
void simplify(); void simplify();
// compile-time opcodes // compile-time opcodes
void handle(code_handle &hand) { configure(OP_HANDLE, 4, hand); } 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 label(code_label lab) { configure(OP_LABEL, 4, lab); }
void comment(const char *string) { configure(OP_COMMENT, 4, parameter::make_string(string)); } void comment(char const *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 mapvar(parameter mapvar, u32 value) { assert(mapvar.is_mapvar()); configure(OP_MAPVAR, 4, mapvar, value); }
// control flow operations // control flow operations
void nop() { configure(OP_NOP, 4); } 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(parameter param) { configure(OP_EXIT, 4, param); }
void exit(condition_t cond, parameter param) { configure(OP_EXIT, 4, param, cond); } 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); } 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 setfmod(parameter mode) { configure(OP_SETFMOD, 4, mode); }
void getfmod(parameter dst) { configure(OP_GETFMOD, 4, dst); } void getfmod(parameter dst) { configure(OP_GETFMOD, 4, dst); }
void getexp(parameter dst) { configure(OP_GETEXP, 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 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)); } void restore(drcuml_machine_state *src) { configure(OP_RESTORE, 4, parameter::make_memory(src)); }
// 32-bit integer operations // 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 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, 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 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 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 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)); } 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); } void rorc(parameter dst, parameter src, parameter count) { configure(OP_RORC, 4, dst, src, count); }
// 64-bit integer operations // 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 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, 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 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 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 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)); } 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); } void drorc(parameter dst, parameter src, parameter count) { configure(OP_RORC, 8, dst, src, count); }
// 32-bit floating point operations // 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 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 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)); } 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); } void icopyfs(parameter dst, parameter src) { configure(OP_ICOPYF, 4, dst, src); }
// 64-bit floating point operations // 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 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 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)); } 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); } void icopyfd(parameter dst, parameter src) { configure(OP_ICOPYF, 8, dst, src); }
// constants // constants
static const int MAX_PARAMS = 4; static constexpr int MAX_PARAMS = 4;
private: private:
// internal configuration // internal configuration
void configure(opcode_t op, uint8_t size, condition_t cond = COND_ALWAYS); void configure(opcode_t op, u8 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, u8 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, u8 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, u8 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, parameter p0, parameter p1, parameter p2, parameter p3, condition_t cond = COND_ALWAYS);
// opcode validation and simplification // opcode validation and simplification
void validate(); 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]; } void convert_to_mov_param(int pnum) { m_opcode = OP_MOV; m_numparams = 2; m_param[1] = m_param[pnum]; }
// internal state // internal state
opcode_t m_opcode; // opcode opcode_t m_opcode = OP_INVALID; // opcode
condition_t m_condition; // condition condition_t m_condition = COND_ALWAYS; // condition
uint8_t m_flags; // flags u8 m_flags = 0; // flags
uint8_t m_size; // operation size u8 m_size = 4; // operation size
uint8_t m_numparams; // number of parameters u8 m_numparams = 0; // number of parameters
parameter m_param[MAX_PARAMS]; // up to 4 parameters parameter m_param[MAX_PARAMS]; // up to 4 parameters
static const opcode_info s_opcode_info_table[OP_MAX]; static opcode_info const s_opcode_info_table[OP_MAX];
}; };
// structure describing rules for parameter encoding // structure describing rules for parameter encoding
struct parameter_info struct parameter_info
{ {
uint8_t output; // input or output? u8 output; // input or output?
uint8_t size; // size of the parameter u8 size; // size of the parameter
uint16_t typemask; // types allowed u16 typemask; // types allowed
}; };
// global inline functions to specify a register parameter by index // 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)); const parameter M9(parameter::make_mapvar(MAPVAR_M0 + 9));
} }
#endif // MAME_CPU_UML_H
#endif /* __UML_H__ */

View File

@ -313,7 +313,7 @@ static const dasm_table_entry dasm_table[] =
{ "cquestrot", be, -3, []() -> util::disasm_interface * { return new cquestrot_disassembler; } }, { "cquestrot", be, -3, []() -> util::disasm_interface * { return new cquestrot_disassembler; } },
{ "cquestsnd", be, -3, []() -> util::disasm_interface * { return new cquestsnd_disassembler; } }, { "cquestsnd", be, -3, []() -> util::disasm_interface * { return new cquestsnd_disassembler; } },
{ "ds5002fp", le, 0, []() -> util::disasm_interface * { return new ds5002fp_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; } }, { "dsp32c", le, 0, []() -> util::disasm_interface * { return new dsp32c_disassembler; } },
{ "dsp56k", le, -1, []() -> util::disasm_interface * { return new dsp56k_disassembler; } }, { "dsp56k", le, -1, []() -> util::disasm_interface * { return new dsp56k_disassembler; } },
{ "e0c6200", be, -1, []() -> util::disasm_interface * { return new e0c6200_disassembler; } }, { "e0c6200", be, -1, []() -> util::disasm_interface * { return new e0c6200_disassembler; } },