mirror of
https://github.com/holub/mame
synced 2025-04-26 02:07:14 +03:00
use more constexpr and literal classes in UML to give compiler more optimisation opportunities (nw)
This commit is contained in:
parent
e34faf61ff
commit
245f822e7d
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
@ -162,5 +161,4 @@ private:
|
||||
std::vector<opcode_desc *> m_desc_array; // array of descriptions in PC order
|
||||
};
|
||||
|
||||
|
||||
#endif /* __DRCFE_H__ */
|
||||
#endif // MAME_CPU_DRCFE_H
|
||||
|
@ -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)
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "emu.h"
|
||||
#include "dsp16dis.h"
|
||||
|
||||
std::string dsp16a_disassembler::disasmF1Field(u8 F1, u8 D, u8 S)
|
||||
std::string dsp16_disassembler::disasmF1Field(u8 F1, u8 D, u8 S)
|
||||
{
|
||||
switch (F1)
|
||||
{
|
||||
@ -27,7 +27,7 @@ std::string dsp16a_disassembler::disasmF1Field(u8 F1, u8 D, u8 S)
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
std::string dsp16a_disassembler::disasmYField(u8 Y)
|
||||
std::string dsp16_disassembler::disasmYField(u8 Y)
|
||||
{
|
||||
switch (Y & 0x03U)
|
||||
{
|
||||
@ -39,7 +39,7 @@ std::string dsp16a_disassembler::disasmYField(u8 Y)
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
std::string dsp16a_disassembler::disasmZField(u8 Z)
|
||||
std::string dsp16_disassembler::disasmZField(u8 Z)
|
||||
{
|
||||
switch (Z & 0x03U)
|
||||
{
|
||||
@ -51,7 +51,7 @@ std::string dsp16a_disassembler::disasmZField(u8 Z)
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
std::string dsp16a_disassembler::disasmF2Field(u8 F2, u8 D, u8 S)
|
||||
std::string dsp16_disassembler::disasmF2Field(u8 F2, u8 D, u8 S)
|
||||
{
|
||||
switch (F2)
|
||||
{
|
||||
@ -75,7 +75,7 @@ std::string dsp16a_disassembler::disasmF2Field(u8 F2, u8 D, u8 S)
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
std::string dsp16a_disassembler::disasmCONField(u8 CON)
|
||||
std::string dsp16_disassembler::disasmCONField(u8 CON)
|
||||
{
|
||||
switch (CON)
|
||||
{
|
||||
@ -102,7 +102,7 @@ std::string dsp16a_disassembler::disasmCONField(u8 CON)
|
||||
}
|
||||
}
|
||||
|
||||
std::string dsp16a_disassembler::disasmBField(u8 B, uint32_t &dasmflags)
|
||||
std::string dsp16_disassembler::disasmBField(u8 B, u32 &dasmflags)
|
||||
{
|
||||
switch (B)
|
||||
{
|
||||
@ -118,7 +118,7 @@ std::string dsp16a_disassembler::disasmBField(u8 B, uint32_t &dasmflags)
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
std::string dsp16a_disassembler::disasmRImmediateField(u8 R)
|
||||
std::string dsp16_disassembler::disasmRImmediateField(u8 R)
|
||||
{
|
||||
switch (R)
|
||||
{
|
||||
@ -134,7 +134,7 @@ std::string dsp16a_disassembler::disasmRImmediateField(u8 R)
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
std::string dsp16a_disassembler::disasmRField(u8 R)
|
||||
std::string dsp16_disassembler::disasmRField(u8 R)
|
||||
{
|
||||
switch (R)
|
||||
{
|
||||
@ -170,7 +170,7 @@ std::string dsp16a_disassembler::disasmRField(u8 R)
|
||||
}
|
||||
}
|
||||
|
||||
std::string dsp16a_disassembler::disasmIField(u8 I)
|
||||
std::string dsp16_disassembler::disasmIField(u8 I)
|
||||
{
|
||||
switch (I)
|
||||
{
|
||||
@ -183,7 +183,7 @@ std::string dsp16a_disassembler::disasmIField(u8 I)
|
||||
}
|
||||
}
|
||||
|
||||
bool dsp16a_disassembler::disasmSIField(u8 SI)
|
||||
bool dsp16_disassembler::disasmSIField(u8 SI)
|
||||
{
|
||||
switch (SI)
|
||||
{
|
||||
@ -194,27 +194,27 @@ bool dsp16a_disassembler::disasmSIField(u8 SI)
|
||||
}
|
||||
|
||||
|
||||
u32 dsp16a_disassembler::interface_flags() const
|
||||
u32 dsp16_disassembler::interface_flags() const
|
||||
{
|
||||
return PAGED;
|
||||
}
|
||||
|
||||
u32 dsp16a_disassembler::page_address_bits() const
|
||||
u32 dsp16_disassembler::page_address_bits() const
|
||||
{
|
||||
return 12U;
|
||||
}
|
||||
|
||||
u32 dsp16a_disassembler::opcode_alignment() const
|
||||
u32 dsp16_disassembler::opcode_alignment() const
|
||||
{
|
||||
return 1U;
|
||||
}
|
||||
|
||||
offs_t dsp16a_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms)
|
||||
offs_t dsp16_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms)
|
||||
{
|
||||
u8 opSize = 1;
|
||||
uint32_t dasmflags = 0;
|
||||
uint16_t op = opcodes.r16(pc);
|
||||
uint16_t op2 = opcodes.r16(pc+1);
|
||||
u32 dasmflags = 0;
|
||||
u16 op = opcodes.r16(pc);
|
||||
u16 op2 = opcodes.r16(pc+1);
|
||||
|
||||
// TODO: Test for previous "if CON" instruction and tab the next instruction in?
|
||||
|
||||
@ -394,13 +394,13 @@ offs_t dsp16a_disassembler::disassemble(std::ostream &stream, offs_t pc, const d
|
||||
// Format 4: Branch Direct Group
|
||||
case 0x00: case 0x01: // goto JA
|
||||
{
|
||||
const uint16_t JA = (op & 0x0fff) | (pc & 0xf000);
|
||||
const u16 JA = (op & 0x0fff) | (pc & 0xf000);
|
||||
util::stream_format(stream, "goto 0x%04x", JA);
|
||||
}
|
||||
break;
|
||||
case 0x10: case 0x11: // call JA
|
||||
{
|
||||
const uint16_t JA = (op & 0x0fff) | (pc & 0xf000);
|
||||
const u16 JA = (op & 0x0fff) | (pc & 0xf000);
|
||||
util::stream_format(stream, "call 0x%04x", JA);
|
||||
dasmflags |= STEP_OVER;
|
||||
}
|
||||
@ -492,7 +492,7 @@ offs_t dsp16a_disassembler::disassemble(std::ostream &stream, offs_t pc, const d
|
||||
// Format 9: Short Immediate Group
|
||||
case 0x02: case 0x03: // R = M
|
||||
{
|
||||
const uint16_t M = (op & 0x01ff);
|
||||
const u16 M = (op & 0x01ff);
|
||||
const u8 R = (op & 0x0e00) >> 9;
|
||||
std::string rString = disasmRImmediateField(R);
|
||||
util::stream_format(stream, "set %s = 0x%04x", rString, M);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
@ -283,29 +283,15 @@ void uml::code_handle::set_codeptr(drccodeptr code)
|
||||
// UML INSTRUCTION
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// instruction - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
uml::instruction::instruction()
|
||||
: m_opcode(OP_INVALID),
|
||||
m_condition(COND_ALWAYS),
|
||||
m_flags(0),
|
||||
m_size(4),
|
||||
m_numparams(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// configure - configure an opcode with no
|
||||
// parameters
|
||||
//-------------------------------------------------
|
||||
|
||||
void uml::instruction::configure(opcode_t op, uint8_t size, condition_t condition)
|
||||
void uml::instruction::configure(opcode_t op, u8 size, condition_t condition)
|
||||
{
|
||||
// fill in the instruction
|
||||
m_opcode = (opcode_t)(uint8_t)op;
|
||||
m_opcode = opcode_t(u8(op));
|
||||
m_size = size;
|
||||
m_condition = condition;
|
||||
m_flags = 0;
|
||||
@ -321,10 +307,10 @@ void uml::instruction::configure(opcode_t op, uint8_t size, condition_t conditio
|
||||
// parameter
|
||||
//-------------------------------------------------
|
||||
|
||||
void uml::instruction::configure(opcode_t op, uint8_t size, parameter p0, condition_t condition)
|
||||
void uml::instruction::configure(opcode_t op, u8 size, parameter p0, condition_t condition)
|
||||
{
|
||||
// fill in the instruction
|
||||
m_opcode = (opcode_t)(uint8_t)op;
|
||||
m_opcode = opcode_t(u8(op));
|
||||
m_size = size;
|
||||
m_condition = condition;
|
||||
m_flags = 0;
|
||||
@ -341,10 +327,10 @@ void uml::instruction::configure(opcode_t op, uint8_t size, parameter p0, condit
|
||||
// parameters
|
||||
//-------------------------------------------------
|
||||
|
||||
void uml::instruction::configure(opcode_t op, uint8_t size, parameter p0, parameter p1, condition_t condition)
|
||||
void uml::instruction::configure(opcode_t op, u8 size, parameter p0, parameter p1, condition_t condition)
|
||||
{
|
||||
// fill in the instruction
|
||||
m_opcode = (opcode_t)(uint8_t)op;
|
||||
m_opcode = opcode_t(u8(op));
|
||||
m_size = size;
|
||||
m_condition = condition;
|
||||
m_flags = 0;
|
||||
@ -362,10 +348,10 @@ void uml::instruction::configure(opcode_t op, uint8_t size, parameter p0, parame
|
||||
// parameters
|
||||
//-------------------------------------------------
|
||||
|
||||
void uml::instruction::configure(opcode_t op, uint8_t size, parameter p0, parameter p1, parameter p2, condition_t condition)
|
||||
void uml::instruction::configure(opcode_t op, u8 size, parameter p0, parameter p1, parameter p2, condition_t condition)
|
||||
{
|
||||
// fill in the instruction
|
||||
m_opcode = (opcode_t)(uint8_t)op;
|
||||
m_opcode = opcode_t(u8(op));
|
||||
m_size = size;
|
||||
m_condition = condition;
|
||||
m_flags = 0;
|
||||
@ -384,10 +370,10 @@ void uml::instruction::configure(opcode_t op, uint8_t size, parameter p0, parame
|
||||
// parameters
|
||||
//-------------------------------------------------
|
||||
|
||||
void uml::instruction::configure(opcode_t op, uint8_t size, parameter p0, parameter p1, parameter p2, parameter p3, condition_t condition)
|
||||
void uml::instruction::configure(opcode_t op, u8 size, parameter p0, parameter p1, parameter p2, parameter p3, condition_t condition)
|
||||
{
|
||||
// fill in the instruction
|
||||
m_opcode = (opcode_t)(uint8_t)op;
|
||||
m_opcode = opcode_t(u8(op));
|
||||
m_size = size;
|
||||
m_condition = condition;
|
||||
m_flags = 0;
|
||||
@ -414,8 +400,8 @@ void uml::instruction::simplify()
|
||||
if (m_flags != 0)
|
||||
return;
|
||||
|
||||
static const uint64_t instsizemask[] = { 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0xffffffffffffffffU };
|
||||
static const uint64_t paramsizemask[] = { 0xff, 0xffff, 0xffffffff, 0xffffffffffffffffU };
|
||||
static constexpr u64 instsizemask[] = { 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0xffffffffffffffffU };
|
||||
static constexpr u64 paramsizemask[] = { 0xff, 0xffff, 0xffffffff, 0xffffffffffffffffU };
|
||||
|
||||
// loop until we've simplified all we can
|
||||
opcode_t origop;
|
||||
@ -462,10 +448,10 @@ void uml::instruction::simplify()
|
||||
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_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;
|
||||
@ -545,9 +531,9 @@ void uml::instruction::simplify()
|
||||
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()));
|
||||
convert_to_mov_immediate(u32(u32(m_param[1].immediate()) * u32(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()));
|
||||
convert_to_mov_immediate(u64(u64(m_param[1].immediate()) * u64(m_param[2].immediate())));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -561,9 +547,9 @@ void uml::instruction::simplify()
|
||||
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()));
|
||||
convert_to_mov_immediate(s32(s32(m_param[1].immediate()) * s32(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()));
|
||||
convert_to_mov_immediate(s64(s64(m_param[1].immediate()) * s64(m_param[2].immediate())));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -577,9 +563,9 @@ void uml::instruction::simplify()
|
||||
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()));
|
||||
convert_to_mov_immediate(u32(u32(m_param[1].immediate()) / u32(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()));
|
||||
convert_to_mov_immediate(u64(u64(m_param[1].immediate()) / u64(m_param[2].immediate())));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -593,9 +579,9 @@ void uml::instruction::simplify()
|
||||
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()));
|
||||
convert_to_mov_immediate(s32(s32(m_param[1].immediate()) / s32(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()));
|
||||
convert_to_mov_immediate(s64(s64(m_param[1].immediate()) / s64(m_param[2].immediate())));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -680,9 +666,9 @@ void uml::instruction::simplify()
|
||||
if (m_param[1].is_immediate() && m_param[2].is_immediate())
|
||||
{
|
||||
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)
|
||||
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))
|
||||
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_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)
|
||||
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))
|
||||
convert_to_mov_param(1);
|
||||
@ -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++)
|
||||
@ -916,14 +898,11 @@ std::string uml::instruction::disasm(drcuml_state *drcuml) const
|
||||
}
|
||||
|
||||
// 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);
|
||||
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;
|
||||
|
||||
@ -940,8 +919,8 @@ std::string uml::instruction::disasm(drcuml_state *drcuml) const
|
||||
// size + scale immediate
|
||||
case parameter::PTYPE_SIZE_SCALE:
|
||||
{
|
||||
int scale = param.scale();
|
||||
int size = param.size();
|
||||
int const scale = param.scale();
|
||||
int const size = param.size();
|
||||
if (scale == size)
|
||||
util::stream_format(buffer, "%s", sizes[size]);
|
||||
else
|
||||
@ -973,7 +952,7 @@ std::string uml::instruction::disasm(drcuml_state *drcuml) const
|
||||
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,17 +965,17 @@ 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;
|
||||
}
|
||||
break;
|
||||
|
||||
// string pointer
|
||||
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;
|
||||
|
||||
// handle pointer
|
||||
|
@ -7,12 +7,11 @@
|
||||
Universal machine language definitions and classes.
|
||||
|
||||
***************************************************************************/
|
||||
#ifndef MAME_CPU_UML_H
|
||||
#define MAME_CPU_UML_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __UML_H__
|
||||
#define __UML_H__
|
||||
|
||||
#include "drccache.h"
|
||||
|
||||
|
||||
@ -31,31 +30,31 @@ struct drcuml_machine_state;
|
||||
namespace uml
|
||||
{
|
||||
// integer registers
|
||||
const int REG_I0 = 0x400;
|
||||
const int REG_I_COUNT = 10;
|
||||
const int REG_I_END = REG_I0 + REG_I_COUNT;
|
||||
constexpr int REG_I0 = 0x400;
|
||||
constexpr int REG_I_COUNT = 10;
|
||||
constexpr int REG_I_END = REG_I0 + REG_I_COUNT;
|
||||
|
||||
// floating point registers
|
||||
const int REG_F0 = 0x800;
|
||||
const int REG_F_COUNT = 10;
|
||||
const int REG_F_END = REG_F0 + REG_F_COUNT;
|
||||
constexpr int REG_F0 = 0x800;
|
||||
constexpr int REG_F_COUNT = 10;
|
||||
constexpr int REG_F_END = REG_F0 + REG_F_COUNT;
|
||||
|
||||
// vector registers
|
||||
const int REG_V0 = 0xc00;
|
||||
const int REG_V_COUNT = 10;
|
||||
const int REG_V_END = REG_V0 + REG_V_COUNT;
|
||||
constexpr int REG_V0 = 0xc00;
|
||||
constexpr int REG_V_COUNT = 10;
|
||||
constexpr int REG_V_END = REG_V0 + REG_V_COUNT;
|
||||
|
||||
// map variables
|
||||
const int MAPVAR_M0 = 0x1000;
|
||||
const int MAPVAR_COUNT = 10;
|
||||
const int MAPVAR_END = MAPVAR_M0 + MAPVAR_COUNT;
|
||||
constexpr int MAPVAR_M0 = 0x1000;
|
||||
constexpr int MAPVAR_COUNT = 10;
|
||||
constexpr int MAPVAR_END = MAPVAR_M0 + MAPVAR_COUNT;
|
||||
|
||||
// flag definitions
|
||||
const uint8_t FLAG_C = 0x01; // carry flag
|
||||
const uint8_t FLAG_V = 0x02; // overflow flag (defined for integer only)
|
||||
const uint8_t FLAG_Z = 0x04; // zero flag
|
||||
const uint8_t FLAG_S = 0x08; // sign flag (defined for integer only)
|
||||
const uint8_t FLAG_U = 0x10; // unordered flag (defined for FP only)
|
||||
constexpr u8 FLAG_C = 0x01; // carry flag
|
||||
constexpr u8 FLAG_V = 0x02; // overflow flag (defined for integer only)
|
||||
constexpr u8 FLAG_Z = 0x04; // zero flag
|
||||
constexpr u8 FLAG_S = 0x08; // sign flag (defined for integer only)
|
||||
constexpr u8 FLAG_U = 0x10; // unordered flag (defined for FP only)
|
||||
|
||||
// testable conditions; note that these are defined such that (condition ^ 1) is
|
||||
// always the opposite
|
||||
@ -242,7 +241,7 @@ namespace uml
|
||||
code_handle *next() const { return m_next; }
|
||||
drccodeptr codeptr() const { return *m_code; }
|
||||
drccodeptr *codeptr_addr() { return m_code; }
|
||||
const char *string() const { return m_string.c_str(); }
|
||||
char const *string() const { return m_string.c_str(); }
|
||||
|
||||
// setters
|
||||
void set_codeptr(drccodeptr code);
|
||||
@ -260,18 +259,18 @@ namespace uml
|
||||
{
|
||||
public:
|
||||
// construction
|
||||
code_label(uint32_t label = 0) : m_label(label) { }
|
||||
constexpr code_label(u32 label = 0) : m_label(label) { }
|
||||
|
||||
// operators
|
||||
operator uint32_t &() { return m_label; }
|
||||
bool operator==(const code_label &rhs) const { return (m_label == rhs.m_label); }
|
||||
bool operator!=(const code_label &rhs) const { return (m_label != rhs.m_label); }
|
||||
operator u32 &() { return m_label; }
|
||||
constexpr bool operator==(code_label const &rhs) const { return (m_label == rhs.m_label); }
|
||||
constexpr bool operator!=(code_label const &rhs) const { return (m_label != rhs.m_label); }
|
||||
|
||||
// getters
|
||||
uint32_t label() const { return m_label; }
|
||||
constexpr u32 label() const { return m_label; }
|
||||
|
||||
private:
|
||||
uint32_t m_label;
|
||||
u32 m_label;
|
||||
};
|
||||
|
||||
// a parameter for a UML instruction is encoded like this
|
||||
@ -300,36 +299,36 @@ namespace uml
|
||||
};
|
||||
|
||||
// represents the value of an opcode parameter
|
||||
typedef uint64_t parameter_value;
|
||||
typedef u64 parameter_value;
|
||||
|
||||
// construction
|
||||
parameter() : m_type(PTYPE_NONE), m_value(0) { }
|
||||
parameter(const parameter ¶m) : m_type(param.m_type), m_value(param.m_value) { }
|
||||
parameter(uint64_t val) : m_type(PTYPE_IMMEDIATE), m_value(val) { }
|
||||
constexpr parameter() : m_type(PTYPE_NONE), m_value(0) { }
|
||||
constexpr parameter(parameter const ¶m) : m_type(param.m_type), m_value(param.m_value) { }
|
||||
constexpr parameter(u64 val) : m_type(PTYPE_IMMEDIATE), m_value(val) { }
|
||||
parameter(operand_size size, memory_scale scale) : m_type(PTYPE_SIZE_SCALE), m_value((scale << 4) | size) { assert(size >= SIZE_BYTE && size <= SIZE_DQWORD); assert(scale >= SCALE_x1 && scale <= SCALE_x8); }
|
||||
parameter(operand_size size, memory_space space) : m_type(PTYPE_SIZE_SPACE), m_value((space << 4) | size) { assert(size >= SIZE_BYTE && size <= SIZE_DQWORD); assert(space >= SPACE_PROGRAM && space <= SPACE_IO); }
|
||||
parameter(code_handle &handle) : m_type(PTYPE_CODE_HANDLE), m_value(reinterpret_cast<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 ¶m(int index) const { assert(index < m_numparams); return m_param[index]; }
|
||||
|
||||
// setters
|
||||
void set_flags(uint8_t flags) { m_flags = flags; }
|
||||
void set_mapvar(int paramnum, uint32_t value) { assert(paramnum < m_numparams); assert(m_param[paramnum].is_mapvar()); m_param[paramnum] = value; }
|
||||
void set_flags(u8 flags) { m_flags = flags; }
|
||||
void set_mapvar(int paramnum, u32 value) { assert(paramnum < m_numparams); assert(m_param[paramnum].is_mapvar()); m_param[paramnum] = value; }
|
||||
|
||||
// misc
|
||||
std::string disasm(drcuml_state *drcuml = nullptr) const;
|
||||
uint8_t input_flags() const;
|
||||
uint8_t output_flags() const;
|
||||
uint8_t modified_flags() const;
|
||||
u8 input_flags() const;
|
||||
u8 output_flags() const;
|
||||
u8 modified_flags() const;
|
||||
void simplify();
|
||||
|
||||
// compile-time opcodes
|
||||
void handle(code_handle &hand) { configure(OP_HANDLE, 4, hand); }
|
||||
void hash(uint32_t mode, uint32_t pc) { configure(OP_HASH, 4, mode, pc); }
|
||||
void hash(u32 mode, u32 pc) { configure(OP_HASH, 4, mode, pc); }
|
||||
void label(code_label lab) { configure(OP_LABEL, 4, lab); }
|
||||
void comment(const char *string) { configure(OP_COMMENT, 4, parameter::make_string(string)); }
|
||||
void mapvar(parameter mapvar, uint32_t value) { assert(mapvar.is_mapvar()); configure(OP_MAPVAR, 4, mapvar, value); }
|
||||
void comment(char const *string) { configure(OP_COMMENT, 4, parameter::make_string(string)); }
|
||||
void mapvar(parameter mapvar, u32 value) { assert(mapvar.is_mapvar()); configure(OP_MAPVAR, 4, mapvar, value); }
|
||||
|
||||
// control flow operations
|
||||
void nop() { configure(OP_NOP, 4); }
|
||||
void debug(uint32_t pc) { configure(OP_DEBUG, 4, pc); }
|
||||
void debug(u32 pc) { configure(OP_DEBUG, 4, pc); }
|
||||
void exit(parameter param) { configure(OP_EXIT, 4, param); }
|
||||
void exit(condition_t cond, parameter param) { configure(OP_EXIT, 4, param, cond); }
|
||||
void hashjmp(parameter mode, parameter pc, code_handle &handle) { configure(OP_HASHJMP, 4, mode, pc, handle); }
|
||||
@ -447,13 +446,13 @@ namespace uml
|
||||
void setfmod(parameter mode) { configure(OP_SETFMOD, 4, mode); }
|
||||
void getfmod(parameter dst) { configure(OP_GETFMOD, 4, dst); }
|
||||
void getexp(parameter dst) { configure(OP_GETEXP, 4, dst); }
|
||||
void getflgs(parameter dst, uint32_t flags) { configure(OP_GETFLGS, 4, dst, flags); }
|
||||
void getflgs(parameter dst, u32 flags) { configure(OP_GETFLGS, 4, dst, flags); }
|
||||
void save(drcuml_machine_state *dst) { configure(OP_SAVE, 4, parameter::make_memory(dst)); }
|
||||
void restore(drcuml_machine_state *src) { configure(OP_RESTORE, 4, parameter::make_memory(src)); }
|
||||
|
||||
// 32-bit integer operations
|
||||
void load(parameter dst, const void *base, parameter index, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_LOAD, 4, dst, parameter::make_memory(base), index, parameter(size, scale)); }
|
||||
void loads(parameter dst, const void *base, parameter index, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_LOADS, 4, dst, parameter::make_memory(base), index, parameter(size, scale)); }
|
||||
void load(parameter dst, void const *base, parameter index, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_LOAD, 4, dst, parameter::make_memory(base), index, parameter(size, scale)); }
|
||||
void loads(parameter dst, void const *base, parameter index, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_LOADS, 4, dst, parameter::make_memory(base), index, parameter(size, scale)); }
|
||||
void store(void *base, parameter index, parameter src1, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_STORE, 4, parameter::make_memory(base), index, src1, parameter(size, scale)); }
|
||||
void read(parameter dst, parameter src1, operand_size size, memory_space space = SPACE_PROGRAM) { configure(OP_READ, 4, dst, src1, parameter(size, space)); }
|
||||
void readm(parameter dst, parameter src1, parameter mask, operand_size size, memory_space space = SPACE_PROGRAM) { configure(OP_READM, 4, dst, src1, mask, parameter(size, space)); }
|
||||
@ -491,8 +490,8 @@ namespace uml
|
||||
void rorc(parameter dst, parameter src, parameter count) { configure(OP_RORC, 4, dst, src, count); }
|
||||
|
||||
// 64-bit integer operations
|
||||
void dload(parameter dst, const void *base, parameter index, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_LOAD, 8, dst, parameter::make_memory(base), index, parameter(size, scale)); }
|
||||
void dloads(parameter dst, const void *base, parameter index, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_LOADS, 8, dst, parameter::make_memory(base), index, parameter(size, scale)); }
|
||||
void dload(parameter dst, void const *base, parameter index, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_LOAD, 8, dst, parameter::make_memory(base), index, parameter(size, scale)); }
|
||||
void dloads(parameter dst, void const *base, parameter index, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_LOADS, 8, dst, parameter::make_memory(base), index, parameter(size, scale)); }
|
||||
void dstore(void *base, parameter index, parameter src1, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_STORE, 8, parameter::make_memory(base), index, src1, parameter(size, scale)); }
|
||||
void dread(parameter dst, parameter src1, operand_size size, memory_space space = SPACE_PROGRAM) { configure(OP_READ, 8, dst, src1, parameter(size, space)); }
|
||||
void dreadm(parameter dst, parameter src1, parameter mask, operand_size size, memory_space space = SPACE_PROGRAM) { configure(OP_READM, 8, dst, src1, mask, parameter(size, space)); }
|
||||
@ -530,7 +529,7 @@ namespace uml
|
||||
void drorc(parameter dst, parameter src, parameter count) { configure(OP_RORC, 8, dst, src, count); }
|
||||
|
||||
// 32-bit floating point operations
|
||||
void fsload(parameter dst, const void *base, parameter index) { configure(OP_FLOAD, 4, dst, parameter::make_memory(base), index); }
|
||||
void fsload(parameter dst, void const *base, parameter index) { configure(OP_FLOAD, 4, dst, parameter::make_memory(base), index); }
|
||||
void fsstore(void *base, parameter index, parameter src1) { configure(OP_FSTORE, 4, parameter::make_memory(base), index, src1); }
|
||||
void fsread(parameter dst, parameter src1, memory_space space) { configure(OP_FREAD, 4, dst, src1, parameter(SIZE_SHORT, space)); }
|
||||
void fswrite(parameter dst, parameter src1, memory_space space) { configure(OP_FWRITE, 4, dst, src1, parameter(SIZE_SHORT, space)); }
|
||||
@ -553,7 +552,7 @@ namespace uml
|
||||
void icopyfs(parameter dst, parameter src) { configure(OP_ICOPYF, 4, dst, src); }
|
||||
|
||||
// 64-bit floating point operations
|
||||
void fdload(parameter dst, const void *base, parameter index) { configure(OP_FLOAD, 8, dst, parameter::make_memory(base), index); }
|
||||
void fdload(parameter dst, void const *base, parameter index) { configure(OP_FLOAD, 8, dst, parameter::make_memory(base), index); }
|
||||
void fdstore(void *base, parameter index, parameter src1) { configure(OP_FSTORE, 8, parameter::make_memory(base), index, src1); }
|
||||
void fdread(parameter dst, parameter src1, memory_space space) { configure(OP_FREAD, 8, dst, src1, parameter(SIZE_DOUBLE, space)); }
|
||||
void fdwrite(parameter dst, parameter src1, memory_space space) { configure(OP_FWRITE, 8, dst, src1, parameter(SIZE_DOUBLE, space)); }
|
||||
@ -577,38 +576,38 @@ namespace uml
|
||||
void icopyfd(parameter dst, parameter src) { configure(OP_ICOPYF, 8, dst, src); }
|
||||
|
||||
// constants
|
||||
static const int MAX_PARAMS = 4;
|
||||
static constexpr int MAX_PARAMS = 4;
|
||||
|
||||
private:
|
||||
// internal configuration
|
||||
void configure(opcode_t op, uint8_t size, condition_t cond = COND_ALWAYS);
|
||||
void configure(opcode_t op, uint8_t size, parameter p0, condition_t cond = COND_ALWAYS);
|
||||
void configure(opcode_t op, uint8_t size, parameter p0, parameter p1, condition_t cond = COND_ALWAYS);
|
||||
void configure(opcode_t op, uint8_t size, parameter p0, parameter p1, parameter p2, condition_t cond = COND_ALWAYS);
|
||||
void configure(opcode_t op, uint8_t size, parameter p0, parameter p1, parameter p2, parameter p3, condition_t cond = COND_ALWAYS);
|
||||
void configure(opcode_t op, u8 size, condition_t cond = COND_ALWAYS);
|
||||
void configure(opcode_t op, u8 size, parameter p0, condition_t cond = COND_ALWAYS);
|
||||
void configure(opcode_t op, u8 size, parameter p0, parameter p1, condition_t cond = COND_ALWAYS);
|
||||
void configure(opcode_t op, u8 size, parameter p0, parameter p1, parameter p2, condition_t cond = COND_ALWAYS);
|
||||
void configure(opcode_t op, u8 size, parameter p0, parameter p1, parameter p2, parameter p3, condition_t cond = COND_ALWAYS);
|
||||
|
||||
// opcode validation and simplification
|
||||
void validate();
|
||||
void convert_to_mov_immediate(uint64_t immediate) { m_opcode = OP_MOV; m_numparams = 2; m_param[1] = immediate; }
|
||||
void convert_to_mov_immediate(u64 immediate) { m_opcode = OP_MOV; m_numparams = 2; m_param[1] = immediate; }
|
||||
void convert_to_mov_param(int pnum) { m_opcode = OP_MOV; m_numparams = 2; m_param[1] = m_param[pnum]; }
|
||||
|
||||
// internal state
|
||||
opcode_t m_opcode; // opcode
|
||||
condition_t m_condition; // condition
|
||||
uint8_t m_flags; // flags
|
||||
uint8_t m_size; // operation size
|
||||
uint8_t m_numparams; // number of parameters
|
||||
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 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
|
||||
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
|
||||
|
@ -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; } },
|
||||
|
Loading…
Reference in New Issue
Block a user