mirror of
https://github.com/holub/mame
synced 2025-04-18 22:49:58 +03:00
Cleanup:
cpu/drcbex86.cpp: Don't use static address space accessors. This gives a big performance improvement. cpu/drcbeut.cpp: Made failure to resolve address space accessors fatal. cpu/drcbearm64.cpp: Removed fallback to static address space accessors. cpu/mips3/mibs3.cpp: Removed static address space accessors. All they were doing was hurting performance. cpu/drcbex64.cpp: Don't use goofy X64_WINDOWS_ABI macro, just check _WIN32. The only other environment that uses the Windows calling convention is (U)EFI, and we can move feature detection to util/abi.h if we ever need to care about it.
This commit is contained in:
parent
bf7061a27e
commit
32736e4c43
1
makefile
1
makefile
@ -1680,7 +1680,6 @@ CPPCHECK_PARAMS += -I3rdparty/bx/include
|
||||
CPPCHECK_PARAMS += -I$(BUILDDIR)/generated/emu
|
||||
CPPCHECK_PARAMS += -I$(BUILDDIR)/generated/emu/layout
|
||||
CPPCHECK_PARAMS += -I$(BUILDDIR)/generated/mame/layout
|
||||
CPPCHECK_PARAMS += -DX64_WINDOWS_ABI
|
||||
CPPCHECK_PARAMS += -DPTR64=1
|
||||
CPPCHECK_PARAMS += -DMAME_DEBUG
|
||||
CPPCHECK_PARAMS += -DMAME_PROFILER
|
||||
|
@ -2054,66 +2054,29 @@ void drcbe_arm64::op_read(a64::Assembler &a, const uml::instruction &inst)
|
||||
const parameter &spacesizep = inst.param(2);
|
||||
assert(spacesizep.is_size_space());
|
||||
|
||||
const auto &trampolines = m_accessors[spacesizep.space()];
|
||||
const auto &resolved = m_resolved_accessors[spacesizep.space()];
|
||||
|
||||
mov_reg_param(a, 4, REG_PARAM2, addrp);
|
||||
|
||||
if (spacesizep.size() == SIZE_BYTE)
|
||||
{
|
||||
if (resolved.read_byte)
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, resolved.read_byte.obj);
|
||||
call_arm_addr(a, resolved.read_byte.func);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, (uintptr_t)m_space[spacesizep.space()]);
|
||||
emit_ldr_mem(a, TEMP_REG1, &trampolines.read_byte);
|
||||
a.blr(TEMP_REG1);
|
||||
}
|
||||
get_imm_relative(a, REG_PARAM1, resolved.read_byte.obj);
|
||||
call_arm_addr(a, resolved.read_byte.func);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_WORD)
|
||||
{
|
||||
if (resolved.read_word)
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, resolved.read_word.obj);
|
||||
call_arm_addr(a, resolved.read_word.func);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, (uintptr_t)m_space[spacesizep.space()]);
|
||||
emit_ldr_mem(a, TEMP_REG1, &trampolines.read_word);
|
||||
a.blr(TEMP_REG1);
|
||||
}
|
||||
get_imm_relative(a, REG_PARAM1, resolved.read_word.obj);
|
||||
call_arm_addr(a, resolved.read_word.func);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_DWORD)
|
||||
{
|
||||
if (resolved.read_dword)
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, resolved.read_dword.obj);
|
||||
call_arm_addr(a, resolved.read_dword.func);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, (uintptr_t)m_space[spacesizep.space()]);
|
||||
emit_ldr_mem(a, TEMP_REG1, &trampolines.read_dword);
|
||||
a.blr(TEMP_REG1);
|
||||
}
|
||||
get_imm_relative(a, REG_PARAM1, resolved.read_dword.obj);
|
||||
call_arm_addr(a, resolved.read_dword.func);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_QWORD)
|
||||
{
|
||||
if (resolved.read_qword)
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, resolved.read_qword.obj);
|
||||
call_arm_addr(a, resolved.read_qword.func);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, (uintptr_t)m_space[spacesizep.space()]);
|
||||
emit_ldr_mem(a, TEMP_REG1, &trampolines.read_qword);
|
||||
a.blr(TEMP_REG1);
|
||||
}
|
||||
get_imm_relative(a, REG_PARAM1, resolved.read_qword.obj);
|
||||
call_arm_addr(a, resolved.read_qword.func);
|
||||
}
|
||||
|
||||
mov_param_reg(a, inst.size(), dstp, REG_PARAM1);
|
||||
@ -2131,7 +2094,6 @@ void drcbe_arm64::op_readm(a64::Assembler &a, const uml::instruction &inst)
|
||||
const parameter &spacesizep = inst.param(3);
|
||||
assert(spacesizep.is_size_space());
|
||||
|
||||
const auto &trampolines = m_accessors[spacesizep.space()];
|
||||
const auto &resolved = m_resolved_accessors[spacesizep.space()];
|
||||
|
||||
mov_reg_param(a, 4, REG_PARAM2, addrp);
|
||||
@ -2139,59 +2101,23 @@ void drcbe_arm64::op_readm(a64::Assembler &a, const uml::instruction &inst)
|
||||
|
||||
if (spacesizep.size() == SIZE_BYTE)
|
||||
{
|
||||
if (resolved.read_byte_masked)
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, resolved.read_byte_masked.obj);
|
||||
call_arm_addr(a, resolved.read_byte_masked.func);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, (uintptr_t)m_space[spacesizep.space()]);
|
||||
emit_ldr_mem(a, TEMP_REG1, &trampolines.read_byte_masked);
|
||||
a.blr(TEMP_REG1);
|
||||
}
|
||||
get_imm_relative(a, REG_PARAM1, resolved.read_byte_masked.obj);
|
||||
call_arm_addr(a, resolved.read_byte_masked.func);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_WORD)
|
||||
{
|
||||
if (resolved.read_word_masked)
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, resolved.read_word_masked.obj);
|
||||
call_arm_addr(a, resolved.read_word_masked.func);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, (uintptr_t)m_space[spacesizep.space()]);
|
||||
emit_ldr_mem(a, TEMP_REG1, &trampolines.read_word_masked);
|
||||
a.blr(TEMP_REG1);
|
||||
}
|
||||
get_imm_relative(a, REG_PARAM1, resolved.read_word_masked.obj);
|
||||
call_arm_addr(a, resolved.read_word_masked.func);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_DWORD)
|
||||
{
|
||||
if (resolved.read_dword_masked)
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, resolved.read_dword_masked.obj);
|
||||
call_arm_addr(a, resolved.read_dword_masked.func);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, (uintptr_t)m_space[spacesizep.space()]);
|
||||
emit_ldr_mem(a, TEMP_REG1, &trampolines.read_dword_masked);
|
||||
a.blr(TEMP_REG1);
|
||||
}
|
||||
get_imm_relative(a, REG_PARAM1, resolved.read_dword_masked.obj);
|
||||
call_arm_addr(a, resolved.read_dword_masked.func);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_QWORD)
|
||||
{
|
||||
if (resolved.read_qword_masked)
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, resolved.read_qword_masked.obj);
|
||||
call_arm_addr(a, resolved.read_qword_masked.func);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, (uintptr_t)m_space[spacesizep.space()]);
|
||||
emit_ldr_mem(a, TEMP_REG1, &trampolines.read_qword_masked);
|
||||
a.blr(TEMP_REG1);
|
||||
}
|
||||
get_imm_relative(a, REG_PARAM1, resolved.read_qword_masked.obj);
|
||||
call_arm_addr(a, resolved.read_qword_masked.func);
|
||||
}
|
||||
|
||||
mov_param_reg(a, inst.size(), dstp, REG_PARAM1);
|
||||
@ -2208,7 +2134,6 @@ void drcbe_arm64::op_write(a64::Assembler &a, const uml::instruction &inst)
|
||||
const parameter &spacesizep = inst.param(2);
|
||||
assert(spacesizep.is_size_space());
|
||||
|
||||
const auto &trampolines = m_accessors[spacesizep.space()];
|
||||
const auto &resolved = m_resolved_accessors[spacesizep.space()];
|
||||
|
||||
mov_reg_param(a, 4, REG_PARAM2, addrp);
|
||||
@ -2216,59 +2141,23 @@ void drcbe_arm64::op_write(a64::Assembler &a, const uml::instruction &inst)
|
||||
|
||||
if (spacesizep.size() == SIZE_BYTE)
|
||||
{
|
||||
if (resolved.write_byte)
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, resolved.write_byte.obj);
|
||||
call_arm_addr(a, resolved.write_byte.func);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, (uintptr_t)m_space[spacesizep.space()]);
|
||||
emit_ldr_mem(a, TEMP_REG1, &trampolines.write_byte);
|
||||
a.blr(TEMP_REG1);
|
||||
}
|
||||
get_imm_relative(a, REG_PARAM1, resolved.write_byte.obj);
|
||||
call_arm_addr(a, resolved.write_byte.func);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_WORD)
|
||||
{
|
||||
if (resolved.write_word)
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, resolved.write_word.obj);
|
||||
call_arm_addr(a, resolved.write_word.func);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, (uintptr_t)m_space[spacesizep.space()]);
|
||||
emit_ldr_mem(a, TEMP_REG1, &trampolines.write_word);
|
||||
a.blr(TEMP_REG1);
|
||||
}
|
||||
get_imm_relative(a, REG_PARAM1, resolved.write_word.obj);
|
||||
call_arm_addr(a, resolved.write_word.func);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_DWORD)
|
||||
{
|
||||
if (resolved.write_dword)
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, resolved.write_dword.obj);
|
||||
call_arm_addr(a, resolved.write_dword.func);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, (uintptr_t)m_space[spacesizep.space()]);
|
||||
emit_ldr_mem(a, TEMP_REG1, &trampolines.write_dword);
|
||||
a.blr(TEMP_REG1);
|
||||
}
|
||||
get_imm_relative(a, REG_PARAM1, resolved.write_dword.obj);
|
||||
call_arm_addr(a, resolved.write_dword.func);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_QWORD)
|
||||
{
|
||||
if (resolved.write_qword)
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, resolved.write_qword.obj);
|
||||
call_arm_addr(a, resolved.write_qword.func);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, (uintptr_t)m_space[spacesizep.space()]);
|
||||
emit_ldr_mem(a, TEMP_REG1, &trampolines.write_qword);
|
||||
a.blr(TEMP_REG1);
|
||||
}
|
||||
get_imm_relative(a, REG_PARAM1, resolved.write_qword.obj);
|
||||
call_arm_addr(a, resolved.write_qword.func);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2285,7 +2174,6 @@ void drcbe_arm64::op_writem(a64::Assembler &a, const uml::instruction &inst)
|
||||
assert(spacesizep.is_size_space());
|
||||
|
||||
// set up a call to the write handler
|
||||
const auto &trampolines = m_accessors[spacesizep.space()];
|
||||
const auto &resolved = m_resolved_accessors[spacesizep.space()];
|
||||
|
||||
mov_reg_param(a, 4, REG_PARAM2, addrp);
|
||||
@ -2294,59 +2182,23 @@ void drcbe_arm64::op_writem(a64::Assembler &a, const uml::instruction &inst)
|
||||
|
||||
if (spacesizep.size() == SIZE_BYTE)
|
||||
{
|
||||
if (resolved.write_byte_masked)
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, resolved.write_byte_masked.obj);
|
||||
call_arm_addr(a, resolved.write_byte_masked.func);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, (uintptr_t)m_space[spacesizep.space()]);
|
||||
emit_ldr_mem(a, TEMP_REG1, &trampolines.write_byte_masked);
|
||||
a.blr(TEMP_REG1);
|
||||
}
|
||||
get_imm_relative(a, REG_PARAM1, resolved.write_byte_masked.obj);
|
||||
call_arm_addr(a, resolved.write_byte_masked.func);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_WORD)
|
||||
{
|
||||
if (resolved.write_word_masked)
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, resolved.write_word_masked.obj);
|
||||
call_arm_addr(a, resolved.write_word_masked.func);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, (uintptr_t)m_space[spacesizep.space()]);
|
||||
emit_ldr_mem(a, TEMP_REG1, &trampolines.write_word_masked);
|
||||
a.blr(TEMP_REG1);
|
||||
}
|
||||
get_imm_relative(a, REG_PARAM1, resolved.write_word_masked.obj);
|
||||
call_arm_addr(a, resolved.write_word_masked.func);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_DWORD)
|
||||
{
|
||||
if (resolved.write_dword_masked)
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, resolved.write_dword_masked.obj);
|
||||
call_arm_addr(a, resolved.write_dword_masked.func);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, (uintptr_t)m_space[spacesizep.space()]);
|
||||
emit_ldr_mem(a, TEMP_REG1, &trampolines.write_dword_masked);
|
||||
a.blr(TEMP_REG1);
|
||||
}
|
||||
get_imm_relative(a, REG_PARAM1, resolved.write_dword_masked.obj);
|
||||
call_arm_addr(a, resolved.write_dword_masked.func);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_QWORD)
|
||||
{
|
||||
if (resolved.write_qword_masked)
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, resolved.write_qword_masked.obj);
|
||||
call_arm_addr(a, resolved.write_qword_masked.func);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, (uintptr_t)m_space[spacesizep.space()]);
|
||||
emit_ldr_mem(a, TEMP_REG1, &trampolines.write_qword_masked);
|
||||
a.blr(TEMP_REG1);
|
||||
}
|
||||
get_imm_relative(a, REG_PARAM1, resolved.write_qword_masked.obj);
|
||||
call_arm_addr(a, resolved.write_qword_masked.func);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3924,40 +3776,21 @@ void drcbe_arm64::op_fread(a64::Assembler &a, const uml::instruction &inst)
|
||||
assert(spacesizep.is_size_space());
|
||||
assert((1 << spacesizep.size()) == inst.size());
|
||||
|
||||
const auto &trampolines = m_accessors[spacesizep.space()];
|
||||
const auto &resolved = m_resolved_accessors[spacesizep.space()];
|
||||
|
||||
mov_reg_param(a, 4, REG_PARAM2, addrp);
|
||||
|
||||
if (inst.size() == 4)
|
||||
{
|
||||
if (resolved.read_dword)
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, resolved.read_dword.obj);
|
||||
call_arm_addr(a, resolved.read_dword.func);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, (uintptr_t)m_space[spacesizep.space()]);
|
||||
emit_ldr_mem(a, TEMP_REG1, &trampolines.read_dword);
|
||||
a.blr(TEMP_REG1);
|
||||
}
|
||||
get_imm_relative(a, REG_PARAM1, resolved.read_dword.obj);
|
||||
call_arm_addr(a, resolved.read_dword.func);
|
||||
|
||||
mov_float_param_int_reg(a, inst.size(), dstp, REG_PARAM1.w());
|
||||
}
|
||||
else if (inst.size() == 8)
|
||||
{
|
||||
if (resolved.read_qword)
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, resolved.read_qword.obj);
|
||||
call_arm_addr(a, resolved.read_qword.func);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, (uintptr_t)m_space[spacesizep.space()]);
|
||||
emit_ldr_mem(a, TEMP_REG1, &trampolines.read_qword);
|
||||
a.blr(TEMP_REG1);
|
||||
}
|
||||
get_imm_relative(a, REG_PARAM1, resolved.read_qword.obj);
|
||||
call_arm_addr(a, resolved.read_qword.func);
|
||||
|
||||
mov_float_param_int_reg(a, inst.size(), dstp, REG_PARAM1);
|
||||
}
|
||||
@ -3975,7 +3808,6 @@ void drcbe_arm64::op_fwrite(a64::Assembler &a, const uml::instruction &inst)
|
||||
assert(spacesizep.is_size_space());
|
||||
assert((1 << spacesizep.size()) == inst.size());
|
||||
|
||||
const auto &trampolines = m_accessors[spacesizep.space()];
|
||||
const auto &resolved = m_resolved_accessors[spacesizep.space()];
|
||||
|
||||
mov_reg_param(a, 4, REG_PARAM2, addrp);
|
||||
@ -3985,31 +3817,13 @@ void drcbe_arm64::op_fwrite(a64::Assembler &a, const uml::instruction &inst)
|
||||
|
||||
if (inst.size() == 4)
|
||||
{
|
||||
if (resolved.write_dword)
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, resolved.write_dword.obj);
|
||||
call_arm_addr(a, resolved.write_dword.func);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, (uintptr_t)m_space[spacesizep.space()]);
|
||||
emit_ldr_mem(a, TEMP_REG1, &trampolines.write_dword);
|
||||
a.blr(TEMP_REG1);
|
||||
}
|
||||
get_imm_relative(a, REG_PARAM1, resolved.write_dword.obj);
|
||||
call_arm_addr(a, resolved.write_dword.func);
|
||||
}
|
||||
else if (inst.size() == 8)
|
||||
{
|
||||
if (resolved.write_qword)
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, resolved.write_qword.obj);
|
||||
call_arm_addr(a, resolved.write_qword.func);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_imm_relative(a, REG_PARAM1, (uintptr_t)m_space[spacesizep.space()]);
|
||||
emit_ldr_mem(a, TEMP_REG1, &trampolines.write_qword);
|
||||
a.blr(TEMP_REG1);
|
||||
}
|
||||
get_imm_relative(a, REG_PARAM1, resolved.write_qword.obj);
|
||||
call_arm_addr(a, resolved.write_qword.func);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -590,7 +590,7 @@ void drc_label_list::oob_callback(drccodeptr *codeptr, void *param1, void *param
|
||||
// set - bind to address space
|
||||
//-------------------------------------------------
|
||||
|
||||
void resolved_memory_accessors::set(address_space &space) noexcept
|
||||
void resolved_memory_accessors::set(address_space &space)
|
||||
{
|
||||
read_byte .set(space, static_cast<u8 (address_space::*)(offs_t) >(&address_space::read_byte));
|
||||
read_byte_masked .set(space, static_cast<u8 (address_space::*)(offs_t, u8) >(&address_space::read_byte));
|
||||
@ -609,6 +609,15 @@ void resolved_memory_accessors::set(address_space &space) noexcept
|
||||
write_dword_masked .set(space, static_cast<void (address_space::*)(offs_t, u32, u32)>(&address_space::write_dword));
|
||||
write_qword .set(space, static_cast<void (address_space::*)(offs_t, u64) >(&address_space::write_qword));
|
||||
write_qword_masked .set(space, static_cast<void (address_space::*)(offs_t, u64, u64)>(&address_space::write_qword));
|
||||
|
||||
if (
|
||||
!read_byte || !read_byte_masked || !write_byte || !write_byte_masked ||
|
||||
!read_word || !read_word_masked || !write_word || !write_word_masked ||
|
||||
!read_dword || !read_dword_masked || !write_dword || !write_dword_masked ||
|
||||
!read_qword || !read_qword_masked || !write_qword || !write_qword_masked)
|
||||
{
|
||||
throw emu_fatalerror("Error resolving address space accessor member functions!\n");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace drc
|
||||
|
@ -214,7 +214,7 @@ struct resolved_memory_accessors
|
||||
resolved_member_function write_qword;
|
||||
resolved_member_function write_qword_masked;
|
||||
|
||||
void set(address_space &space) noexcept;
|
||||
void set(address_space &space);
|
||||
};
|
||||
|
||||
using resolved_memory_accessors_vector = std::vector<resolved_memory_accessors>;
|
||||
|
@ -214,7 +214,7 @@ const uint32_t PTYPE_MR = PTYPE_M | PTYPE_R;
|
||||
const uint32_t PTYPE_MRI = PTYPE_M | PTYPE_R | PTYPE_I;
|
||||
const uint32_t PTYPE_MF = PTYPE_M | PTYPE_F;
|
||||
|
||||
#ifdef X64_WINDOWS_ABI
|
||||
#ifdef _WIN32
|
||||
|
||||
const Gp::Id REG_PARAM1 = Gp::kIdCx;
|
||||
const Gp::Id REG_PARAM2 = Gp::kIdDx;
|
||||
@ -233,7 +233,7 @@ const Gp::Id REG_PARAM4 = Gp::kIdCx;
|
||||
// register mapping tables
|
||||
const Gp::Id int_register_map[REG_I_COUNT] =
|
||||
{
|
||||
#ifdef X64_WINDOWS_ABI
|
||||
#ifdef _WIN32
|
||||
Gp::kIdBx, Gp::kIdSi, Gp::kIdDi, Gp::kIdR12, Gp::kIdR13, Gp::kIdR14, Gp::kIdR15,
|
||||
#else
|
||||
Gp::kIdBx, Gp::kIdR12, Gp::kIdR13, Gp::kIdR14, Gp::kIdR15
|
||||
@ -242,10 +242,10 @@ const Gp::Id int_register_map[REG_I_COUNT] =
|
||||
|
||||
uint32_t float_register_map[REG_F_COUNT] =
|
||||
{
|
||||
#ifdef X64_WINDOWS_ABI
|
||||
#ifdef _WIN32
|
||||
6, 7, 8, 9, 10, 11, 12, 13, 14, 15
|
||||
#else
|
||||
// on AMD x64 ABI, XMM0-7 are FP function args. since this code has no args, and we
|
||||
// on SysV x64 ABI, XMM0-7 are FP function args. since this code has no args, and we
|
||||
// save/restore them around CALLC, they should be safe for our use.
|
||||
0, 1, 2, 3, 4, 5, 6, 7
|
||||
#endif
|
||||
|
@ -257,7 +257,7 @@ private:
|
||||
uint32_t ssemode; // saved SSE mode
|
||||
uint32_t ssemodesave; // temporary location for saving
|
||||
uint32_t ssecontrol[4]; // copy of the sse_control array
|
||||
float single1; // 1.0 is single-precision
|
||||
float single1; // 1.0 in single-precision
|
||||
double double1; // 1.0 in double-precision
|
||||
|
||||
void * stacksave; // saved stack pointer
|
||||
|
@ -114,6 +114,12 @@ namespace {
|
||||
// CONSTANTS
|
||||
//**************************************************************************
|
||||
|
||||
#ifdef _WIN32
|
||||
constexpr bool USE_THISCALL = true;
|
||||
#else
|
||||
constexpr bool USE_THISCALL = false;
|
||||
#endif
|
||||
|
||||
const uint32_t PTYPE_M = 1 << parameter::PTYPE_MEMORY;
|
||||
const uint32_t PTYPE_I = 1 << parameter::PTYPE_IMMEDIATE;
|
||||
const uint32_t PTYPE_R = 1 << parameter::PTYPE_INT_REGISTER;
|
||||
@ -538,32 +544,32 @@ inline bool drcbe_x86::can_skip_upper_load(Assembler &a, uint32_t *memref, Gp co
|
||||
// drcbe_x86 - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
drcbe_x86::drcbe_x86(drcuml_state &drcuml, device_t &device, drc_cache &cache, uint32_t flags, int modes, int addrbits, int ignorebits)
|
||||
: drcbe_interface(drcuml, cache, device),
|
||||
m_hash(cache, modes, addrbits, ignorebits),
|
||||
m_map(cache, 0),
|
||||
m_log(nullptr),
|
||||
m_log_asmjit(nullptr),
|
||||
m_logged_common(false),
|
||||
m_sse3(CpuInfo::host().features().x86().hasSSE3()),
|
||||
m_entry(nullptr),
|
||||
m_exit(nullptr),
|
||||
m_nocode(nullptr),
|
||||
m_save(nullptr),
|
||||
m_restore(nullptr),
|
||||
m_last_lower_reg(Gp()),
|
||||
m_last_lower_pc(nullptr),
|
||||
m_last_lower_addr(nullptr),
|
||||
m_last_upper_reg(Gp()),
|
||||
m_last_upper_pc(nullptr),
|
||||
m_last_upper_addr(nullptr),
|
||||
m_fptemp(0),
|
||||
m_fpumode(0),
|
||||
m_fmodesave(0),
|
||||
m_stacksave(nullptr),
|
||||
m_hashstacksave(nullptr),
|
||||
m_reslo(0),
|
||||
m_reshi(0)
|
||||
drcbe_x86::drcbe_x86(drcuml_state &drcuml, device_t &device, drc_cache &cache, uint32_t flags, int modes, int addrbits, int ignorebits) :
|
||||
drcbe_interface(drcuml, cache, device)
|
||||
, m_hash(cache, modes, addrbits, ignorebits)
|
||||
, m_map(cache, 0)
|
||||
, m_log(nullptr)
|
||||
, m_log_asmjit(nullptr)
|
||||
, m_logged_common(false)
|
||||
, m_sse3(CpuInfo::host().features().x86().hasSSE3())
|
||||
, m_entry(nullptr)
|
||||
, m_exit(nullptr)
|
||||
, m_nocode(nullptr)
|
||||
, m_save(nullptr)
|
||||
, m_restore(nullptr)
|
||||
, m_last_lower_reg(Gp())
|
||||
, m_last_lower_pc(nullptr)
|
||||
, m_last_lower_addr(nullptr)
|
||||
, m_last_upper_reg(Gp())
|
||||
, m_last_upper_pc(nullptr)
|
||||
, m_last_upper_addr(nullptr)
|
||||
, m_fptemp(0)
|
||||
, m_fpumode(0)
|
||||
, m_fmodesave(0)
|
||||
, m_stacksave(nullptr)
|
||||
, m_hashstacksave(nullptr)
|
||||
, m_reslo(0)
|
||||
, m_reshi(0)
|
||||
{
|
||||
// compute hi pointers for each register
|
||||
for (int regnum = 0; regnum < std::size(int_register_map); regnum++)
|
||||
@ -595,6 +601,14 @@ drcbe_x86::drcbe_x86(drcuml_state &drcuml, device_t &device, drc_cache &cache, u
|
||||
flags_unmap[entry] = flags;
|
||||
}
|
||||
|
||||
// resolve the actual addresses of member functions we need to call
|
||||
m_memory_accessors.resize(m_space.size());
|
||||
for (int space = 0; m_space.size() > space; ++space)
|
||||
{
|
||||
if (m_space[space])
|
||||
m_memory_accessors[space].set(*m_space[space]);
|
||||
}
|
||||
|
||||
// build the opcode table (static but it doesn't hurt to regenerate it)
|
||||
for (auto & elem : s_opcode_table_source)
|
||||
s_opcode_table[elem.opcode] = elem.func;
|
||||
@ -3448,52 +3462,75 @@ void drcbe_x86::op_read(Assembler &a, const instruction &inst)
|
||||
// pick a target register for the general case
|
||||
Gp const dstreg = dstp.select_register(eax);
|
||||
|
||||
// set up a call to the read byte handler
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, 4), addrp); // mov [esp+4],addrp
|
||||
a.mov(dword_ptr(esp, 0), imm(m_space[spacesizep.space()])); // mov [esp],space
|
||||
// set up a call to the read handler
|
||||
auto const &accessors = m_memory_accessors[spacesizep.space()];
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, USE_THISCALL ? 0 : 4), addrp);
|
||||
if (spacesizep.size() == SIZE_BYTE)
|
||||
{
|
||||
a.call(imm(m_accessors[spacesizep.space()].read_byte)); // call read_byte
|
||||
a.movzx(dstreg, al); // movzx dstreg,al
|
||||
if (USE_THISCALL)
|
||||
a.mov(ecx, imm(accessors.read_byte.obj));
|
||||
else
|
||||
a.mov(dword_ptr(esp, 0), imm(accessors.read_byte.obj));
|
||||
a.call(imm(accessors.read_byte.func));
|
||||
if (USE_THISCALL)
|
||||
a.sub(esp, 4);
|
||||
a.movzx(dstreg, al);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_WORD)
|
||||
{
|
||||
a.call(imm(m_accessors[spacesizep.space()].read_word)); // call read_word
|
||||
a.movzx(dstreg, ax); // movzx dstreg,ax
|
||||
if (USE_THISCALL)
|
||||
a.mov(ecx, imm(accessors.read_word.obj));
|
||||
else
|
||||
a.mov(dword_ptr(esp, 0), imm(accessors.read_word.obj));
|
||||
a.call(imm(accessors.read_word.func));
|
||||
if (USE_THISCALL)
|
||||
a.sub(esp, 4);
|
||||
a.movzx(dstreg, ax);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_DWORD)
|
||||
{
|
||||
a.call(imm(m_accessors[spacesizep.space()].read_dword)); // call read_dword
|
||||
a.mov(dstreg, eax); // mov dstreg,eax
|
||||
if (USE_THISCALL)
|
||||
a.mov(ecx, imm(accessors.read_dword.obj));
|
||||
else
|
||||
a.mov(dword_ptr(esp, 0), imm(accessors.read_dword.obj));
|
||||
a.call(imm(accessors.read_dword.func));
|
||||
if (USE_THISCALL)
|
||||
a.sub(esp, 4);
|
||||
a.mov(dstreg, eax);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_QWORD)
|
||||
{
|
||||
a.call(imm(m_accessors[spacesizep.space()].read_qword)); // call read_qword
|
||||
a.mov(dstreg, eax); // mov dstreg,eax
|
||||
if (USE_THISCALL)
|
||||
a.mov(ecx, imm(accessors.read_qword.obj));
|
||||
else
|
||||
a.mov(dword_ptr(esp, 0), imm(accessors.read_qword.obj));
|
||||
a.call(imm(accessors.read_qword.func));
|
||||
if (USE_THISCALL)
|
||||
a.sub(esp, 4);
|
||||
a.mov(dstreg, eax);
|
||||
}
|
||||
|
||||
// store low 32 bits
|
||||
emit_mov_p32_r32(a, dstp, dstreg); // mov dstp,dstreg
|
||||
emit_mov_p32_r32(a, dstp, dstreg);
|
||||
|
||||
// 64-bit form stores upper 32 bits
|
||||
if (inst.size() == 8)
|
||||
{
|
||||
// 1, 2, or 4-byte case
|
||||
if (spacesizep.size() != SIZE_QWORD)
|
||||
{
|
||||
// 1, 2, or 4-byte case
|
||||
if (dstp.is_memory())
|
||||
a.mov(MABS(dstp.memory(4), 4), 0); // mov [dstp+4],0
|
||||
a.mov(MABS(dstp.memory(4), 4), 0);
|
||||
else if (dstp.is_int_register())
|
||||
a.mov(MABS(m_reghi[dstp.ireg()], 4), 0); // mov [reghi],0
|
||||
a.mov(MABS(m_reghi[dstp.ireg()], 4), 0);
|
||||
}
|
||||
|
||||
// 8-byte case
|
||||
else
|
||||
{
|
||||
// 8-byte case
|
||||
if (dstp.is_memory())
|
||||
a.mov(MABS(dstp.memory(4)), edx); // mov [dstp+4],edx
|
||||
a.mov(MABS(dstp.memory(4)), edx);
|
||||
else if (dstp.is_int_register())
|
||||
a.mov(MABS(m_reghi[dstp.ireg()]), edx); // mov [reghi],edx
|
||||
a.mov(MABS(m_reghi[dstp.ireg()]), edx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3521,55 +3558,78 @@ void drcbe_x86::op_readm(Assembler &a, const instruction &inst)
|
||||
Gp const dstreg = dstp.select_register(eax);
|
||||
|
||||
// set up a call to the read byte handler
|
||||
auto const &accessors = m_memory_accessors[spacesizep.space()];
|
||||
if (spacesizep.size() != SIZE_QWORD)
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, 8), maskp); // mov [esp+8],maskp
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, USE_THISCALL ? 4 : 8), maskp);
|
||||
else
|
||||
emit_mov_m64_p64(a, qword_ptr(esp, 8), maskp); // mov [esp+8],maskp
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, 4), addrp); // mov [esp+4],addrp
|
||||
a.mov(dword_ptr(esp, 0), imm(m_space[spacesizep.space()])); // mov [esp],space
|
||||
emit_mov_m64_p64(a, qword_ptr(esp, USE_THISCALL ? 4 : 8), maskp);
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, USE_THISCALL ? 0 : 4), addrp);
|
||||
if (spacesizep.size() == SIZE_BYTE)
|
||||
{
|
||||
a.call(imm(m_accessors[spacesizep.space()].read_byte_masked)); // call read_byte_masked
|
||||
a.movzx(dstreg, al); // movzx dstreg,al
|
||||
if (USE_THISCALL)
|
||||
a.mov(ecx, imm(accessors.read_byte_masked.obj));
|
||||
else
|
||||
a.mov(dword_ptr(esp, 0), imm(accessors.read_byte_masked.obj));
|
||||
a.call(imm(accessors.read_byte_masked.func));
|
||||
if (USE_THISCALL)
|
||||
a.sub(esp, 8);
|
||||
a.movzx(dstreg, al);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_WORD)
|
||||
{
|
||||
a.call(imm(m_accessors[spacesizep.space()].read_word_masked)); // call read_word_masked
|
||||
a.movzx(dstreg, ax); // movzx dstreg,ax
|
||||
if (USE_THISCALL)
|
||||
a.mov(ecx, imm(accessors.read_word_masked.obj));
|
||||
else
|
||||
a.mov(dword_ptr(esp, 0), imm(accessors.read_word_masked.obj));
|
||||
a.call(imm(accessors.read_word_masked.func));
|
||||
if (USE_THISCALL)
|
||||
a.sub(esp, 8);
|
||||
a.movzx(dstreg, ax);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_DWORD)
|
||||
{
|
||||
a.call(imm(m_accessors[spacesizep.space()].read_dword_masked)); // call read_dword_masked
|
||||
a.mov(dstreg, eax); // mov dstreg,eax
|
||||
if (USE_THISCALL)
|
||||
a.mov(ecx, imm(accessors.read_dword_masked.obj));
|
||||
else
|
||||
a.mov(dword_ptr(esp, 0), imm(accessors.read_dword_masked.obj));
|
||||
a.call(imm(accessors.read_dword_masked.func));
|
||||
if (USE_THISCALL)
|
||||
a.sub(esp, 8);
|
||||
a.mov(dstreg, eax);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_QWORD)
|
||||
{
|
||||
a.call(imm(m_accessors[spacesizep.space()].read_qword_masked)); // call read_qword_masked
|
||||
a.mov(dstreg, eax); // mov dstreg,eax
|
||||
if (USE_THISCALL)
|
||||
a.mov(ecx, imm(accessors.read_qword_masked.obj));
|
||||
else
|
||||
a.mov(dword_ptr(esp, 0), imm(accessors.read_qword_masked.obj));
|
||||
a.call(imm(accessors.read_qword_masked.func));
|
||||
if (USE_THISCALL)
|
||||
a.sub(esp, 12);
|
||||
a.mov(dstreg, eax);
|
||||
}
|
||||
|
||||
// store low 32 bits
|
||||
emit_mov_p32_r32(a, dstp, dstreg); // mov dstp,dstreg
|
||||
emit_mov_p32_r32(a, dstp, dstreg);
|
||||
|
||||
// 64-bit form stores upper 32 bits
|
||||
if (inst.size() == 8)
|
||||
{
|
||||
// 1, 2, or 4-byte case
|
||||
if (spacesizep.size() != SIZE_QWORD)
|
||||
{
|
||||
// 1, 2, or 4-byte case
|
||||
if (dstp.is_memory())
|
||||
a.mov(MABS(dstp.memory(4), 4), 0); // mov [dstp+4],0
|
||||
a.mov(MABS(dstp.memory(4), 4), 0);
|
||||
else if (dstp.is_int_register())
|
||||
a.mov(MABS(m_reghi[dstp.ireg()], 4), 0); // mov [reghi],0
|
||||
a.mov(MABS(m_reghi[dstp.ireg()], 4), 0);
|
||||
}
|
||||
|
||||
// 8-byte case
|
||||
else
|
||||
{
|
||||
// 8-byte case
|
||||
if (dstp.is_memory())
|
||||
a.mov(MABS(dstp.memory(4)), edx); // mov [dstp+4],edx
|
||||
a.mov(MABS(dstp.memory(4)), edx);
|
||||
else if (dstp.is_int_register())
|
||||
a.mov(MABS(m_reghi[dstp.ireg()]), edx); // mov [reghi],edx
|
||||
a.mov(MABS(m_reghi[dstp.ireg()]), edx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3593,20 +3653,52 @@ void drcbe_x86::op_write(Assembler &a, const instruction &inst)
|
||||
assert(spacesizep.is_size_space());
|
||||
|
||||
// set up a call to the write byte handler
|
||||
auto const &accessors = m_memory_accessors[spacesizep.space()];
|
||||
if (spacesizep.size() != SIZE_QWORD)
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, 8), srcp); // mov [esp+8],srcp
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, USE_THISCALL ? 4 : 8), srcp);
|
||||
else
|
||||
emit_mov_m64_p64(a, qword_ptr(esp, 8), srcp); // mov [esp+8],srcp
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, 4), addrp); // mov [esp+4],addrp
|
||||
a.mov(dword_ptr(esp, 0), imm(m_space[spacesizep.space()])); // mov [esp],space
|
||||
emit_mov_m64_p64(a, qword_ptr(esp, USE_THISCALL ? 4 : 8), srcp);
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, USE_THISCALL ? 0 : 4), addrp);
|
||||
if (spacesizep.size() == SIZE_BYTE)
|
||||
a.call(imm(m_accessors[spacesizep.space()].write_byte)); // call write_byte
|
||||
{
|
||||
if (USE_THISCALL)
|
||||
a.mov(ecx, imm(accessors.write_byte.obj));
|
||||
else
|
||||
a.mov(dword_ptr(esp, 0), imm(accessors.write_byte.obj));
|
||||
a.call(imm(accessors.write_byte.func));
|
||||
if (USE_THISCALL)
|
||||
a.sub(esp, 8);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_WORD)
|
||||
a.call(imm(m_accessors[spacesizep.space()].write_word)); // call write_word
|
||||
{
|
||||
if (USE_THISCALL)
|
||||
a.mov(ecx, imm(accessors.write_word.obj));
|
||||
else
|
||||
a.mov(dword_ptr(esp, 0), imm(accessors.write_word.obj));
|
||||
a.call(imm(accessors.write_word.func));
|
||||
if (USE_THISCALL)
|
||||
a.sub(esp, 8);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_DWORD)
|
||||
a.call(imm(m_accessors[spacesizep.space()].write_dword)); // call write_dword
|
||||
{
|
||||
if (USE_THISCALL)
|
||||
a.mov(ecx, imm(accessors.write_dword.obj));
|
||||
else
|
||||
a.mov(dword_ptr(esp, 0), imm(accessors.write_dword.obj));
|
||||
a.call(imm(accessors.write_dword.func));
|
||||
if (USE_THISCALL)
|
||||
a.sub(esp, 8);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_QWORD)
|
||||
a.call(imm(m_accessors[spacesizep.space()].write_qword)); // call write_qword
|
||||
{
|
||||
if (USE_THISCALL)
|
||||
a.mov(ecx, imm(accessors.write_qword.obj));
|
||||
else
|
||||
a.mov(dword_ptr(esp, 0), imm(accessors.write_qword.obj));
|
||||
a.call(imm(accessors.write_qword.func));
|
||||
if (USE_THISCALL)
|
||||
a.sub(esp, 12);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3629,26 +3721,58 @@ void drcbe_x86::op_writem(Assembler &a, const instruction &inst)
|
||||
assert(spacesizep.is_size_space());
|
||||
|
||||
// set up a call to the write byte handler
|
||||
auto const &accessors = m_memory_accessors[spacesizep.space()];
|
||||
if (spacesizep.size() != SIZE_QWORD)
|
||||
{
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, 12), maskp); // mov [esp+12],maskp
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, 8), srcp); // mov [esp+8],srcp
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, USE_THISCALL ? 8 : 12), maskp);
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, USE_THISCALL ? 4 : 8), srcp);
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_mov_m64_p64(a, qword_ptr(esp, 16), maskp); // mov [esp+16],maskp
|
||||
emit_mov_m64_p64(a, qword_ptr(esp, 8), srcp); // mov [esp+8],srcp
|
||||
emit_mov_m64_p64(a, qword_ptr(esp, USE_THISCALL ? 12 : 16), maskp);
|
||||
emit_mov_m64_p64(a, qword_ptr(esp, USE_THISCALL ? 4 : 8), srcp);
|
||||
}
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, 4), addrp); // mov [esp+4],addrp
|
||||
a.mov(dword_ptr(esp, 0), imm(m_space[spacesizep.space()])); // mov [esp],space
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, USE_THISCALL ? 0 : 4), addrp);
|
||||
if (spacesizep.size() == SIZE_BYTE)
|
||||
a.call(imm(m_accessors[spacesizep.space()].write_byte_masked)); // call write_byte_masked
|
||||
{
|
||||
if (USE_THISCALL)
|
||||
a.mov(ecx, imm(accessors.write_byte_masked.obj));
|
||||
else
|
||||
a.mov(dword_ptr(esp, 0), imm(accessors.write_byte_masked.obj));
|
||||
a.call(imm(accessors.write_byte_masked.func));
|
||||
if (USE_THISCALL)
|
||||
a.sub(esp, 12);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_WORD)
|
||||
a.call(imm(m_accessors[spacesizep.space()].write_word_masked)); // call write_word_masked
|
||||
{
|
||||
if (USE_THISCALL)
|
||||
a.mov(ecx, imm(accessors.write_word_masked.obj));
|
||||
else
|
||||
a.mov(dword_ptr(esp, 0), imm(accessors.write_word_masked.obj));
|
||||
a.call(imm(accessors.write_word_masked.func));
|
||||
if (USE_THISCALL)
|
||||
a.sub(esp, 12);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_DWORD)
|
||||
a.call(imm(m_accessors[spacesizep.space()].write_dword_masked)); // call write_dword_masked
|
||||
{
|
||||
if (USE_THISCALL)
|
||||
a.mov(ecx, imm(accessors.write_dword_masked.obj));
|
||||
else
|
||||
a.mov(dword_ptr(esp, 0), imm(accessors.write_dword_masked.obj));
|
||||
a.call(imm(accessors.write_dword_masked.func));
|
||||
if (USE_THISCALL)
|
||||
a.sub(esp, 12);
|
||||
}
|
||||
else if (spacesizep.size() == SIZE_QWORD)
|
||||
a.call(imm(m_accessors[spacesizep.space()].write_qword_masked)); // call write_qword_masked
|
||||
{
|
||||
if (USE_THISCALL)
|
||||
a.mov(ecx, imm(accessors.write_qword_masked.obj));
|
||||
else
|
||||
a.mov(dword_ptr(esp, 0), imm(accessors.write_qword_masked.obj));
|
||||
a.call(imm(accessors.write_qword_masked.func));
|
||||
if (USE_THISCALL)
|
||||
a.sub(esp, 20);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -6066,18 +6190,22 @@ void drcbe_x86::op_fread(Assembler &a, const instruction &inst)
|
||||
assert((1 << spacep.size()) == inst.size());
|
||||
|
||||
// set up a call to the read dword/qword handler
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, 4), addrp); // mov [esp+4],addrp
|
||||
a.mov(dword_ptr(esp, 0), imm(m_space[spacep.space()])); // mov [esp],space
|
||||
if (inst.size() == 4)
|
||||
a.call(imm(m_accessors[spacep.space()].read_dword)); // call read_dword
|
||||
else if (inst.size() == 8)
|
||||
a.call(imm(m_accessors[spacep.space()].read_qword)); // call read_qword
|
||||
auto const &accessors = m_memory_accessors[spacep.space()];
|
||||
auto const &accessor = (inst.size() == 4) ? accessors.read_dword : accessors.read_qword;
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, USE_THISCALL ? 0 : 4), addrp);
|
||||
if (USE_THISCALL)
|
||||
a.mov(ecx, imm(accessor.obj));
|
||||
else
|
||||
a.mov(dword_ptr(esp, 0), imm(accessor.obj));
|
||||
a.call(imm(accessor.func));
|
||||
if (USE_THISCALL)
|
||||
a.sub(esp, 4);
|
||||
|
||||
// store result
|
||||
if (inst.size() == 4)
|
||||
emit_mov_p32_r32(a, dstp, eax); // mov dstp,eax
|
||||
emit_mov_p32_r32(a, dstp, eax);
|
||||
else if (inst.size() == 8)
|
||||
emit_mov_p64_r64(a, dstp, eax, edx); // mov dstp,edx:eax
|
||||
emit_mov_p64_r64(a, dstp, eax, edx);
|
||||
}
|
||||
|
||||
|
||||
@ -6100,16 +6228,19 @@ void drcbe_x86::op_fwrite(Assembler &a, const instruction &inst)
|
||||
assert((1 << spacep.size()) == inst.size());
|
||||
|
||||
// set up a call to the write dword/qword handler
|
||||
auto const &accessors = m_memory_accessors[spacep.space()];
|
||||
auto const &accessor = (inst.size() == 4) ? accessors.write_dword : accessors.write_qword;
|
||||
if (inst.size() == 4)
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, 8), srcp); // mov [esp+8],srcp
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, USE_THISCALL ? 4 : 8), srcp);
|
||||
else if (inst.size() == 8)
|
||||
emit_mov_m64_p64(a, qword_ptr(esp, 8), srcp); // mov [esp+8],srcp
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, 4), addrp); // mov [esp+4],addrp
|
||||
a.mov(dword_ptr(esp, 0), imm(m_space[spacep.space()])); // mov [esp],space
|
||||
if (inst.size() == 4)
|
||||
a.call(imm(m_accessors[spacep.space()].write_dword)); // call write_dword
|
||||
else if (inst.size() == 8)
|
||||
a.call(imm(m_accessors[spacep.space()].write_qword)); // call write_qword
|
||||
emit_mov_m64_p64(a, qword_ptr(esp, USE_THISCALL ? 4 : 8), srcp);
|
||||
if (USE_THISCALL)
|
||||
a.mov(ecx, imm(accessor.obj));
|
||||
else
|
||||
a.mov(dword_ptr(esp, 0), imm(accessor.obj));
|
||||
a.call(imm(accessor.func));
|
||||
if (USE_THISCALL)
|
||||
a.sub(esp, (inst.size() == 4) ? 8 : 12);
|
||||
}
|
||||
|
||||
|
||||
|
@ -291,6 +291,9 @@ private:
|
||||
uint64_t m_reslo; // extended low result
|
||||
uint64_t m_reshi; // extended high result
|
||||
|
||||
// resolved memory handler functions
|
||||
resolved_memory_accessors_vector m_memory_accessors;
|
||||
|
||||
// globals
|
||||
typedef void (drcbe_x86::*opcode_generate_func)(asmjit::x86::Assembler &a, const uml::instruction &inst);
|
||||
struct opcode_table_entry
|
||||
|
@ -429,9 +429,6 @@ void mips3_device::device_start()
|
||||
}
|
||||
}
|
||||
|
||||
/* set up the endianness */
|
||||
m_program->accessors(m_memory);
|
||||
|
||||
/* allocate a timer for the compare interrupt */
|
||||
m_compare_int_timer = timer_alloc(FUNC(mips3_device::compare_int_callback), this);
|
||||
|
||||
@ -1204,11 +1201,11 @@ inline bool mips3_device::RBYTE(offs_t address, uint32_t *result)
|
||||
*result = m_fastram[ramnum].offset_base8[tlbaddress ^ m_byte_xor];
|
||||
return true;
|
||||
}
|
||||
*result = (*m_memory.read_byte)(*m_program, tlbaddress);
|
||||
*result = m_program->read_byte(tlbaddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tlbval & FLAG_FIXED)
|
||||
if (tlbval & FLAG_FIXED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBLOAD, address);
|
||||
}
|
||||
@ -1237,11 +1234,11 @@ inline bool mips3_device::RHALF(offs_t address, uint32_t *result)
|
||||
*result = m_fastram[ramnum].offset_base16[(tlbaddress ^ m_word_xor) >> 1];
|
||||
return true;
|
||||
}
|
||||
*result = (*m_memory.read_word)(*m_program, tlbaddress);
|
||||
*result = m_program->read_word(tlbaddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tlbval & FLAG_FIXED)
|
||||
if (tlbval & FLAG_FIXED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBLOAD, address);
|
||||
}
|
||||
@ -1270,11 +1267,11 @@ inline bool mips3_device::RWORD(offs_t address, uint32_t *result, bool insn)
|
||||
*result = m_fastram[ramnum].offset_base32[(tlbaddress ^ m_dword_xor) >> 2];
|
||||
return true;
|
||||
}
|
||||
*result = (*m_memory.read_dword)(*m_program, tlbaddress);
|
||||
*result = m_program->read_dword(tlbaddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tlbval & FLAG_FIXED)
|
||||
if (tlbval & FLAG_FIXED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBLOAD, address);
|
||||
}
|
||||
@ -1293,11 +1290,11 @@ inline bool mips3_device::RWORD_MASKED(offs_t address, uint32_t *result, uint32_
|
||||
const uint32_t tlbval = vtlb_table()[address >> 12];
|
||||
if (tlbval & READ_ALLOWED)
|
||||
{
|
||||
*result = (*m_memory.read_dword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), mem_mask);
|
||||
*result = m_program->read_dword((tlbval & ~0xfff) | (address & 0xfff), mem_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tlbval & FLAG_FIXED)
|
||||
if (tlbval & FLAG_FIXED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBLOAD, address);
|
||||
}
|
||||
@ -1316,11 +1313,11 @@ inline bool mips3_device::RDOUBLE(offs_t address, uint64_t *result)
|
||||
const uint32_t tlbval = vtlb_table()[address >> 12];
|
||||
if (tlbval & READ_ALLOWED)
|
||||
{
|
||||
*result = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff));
|
||||
*result = m_program->read_qword((tlbval & ~0xfff) | (address & 0xfff));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tlbval & FLAG_FIXED)
|
||||
if (tlbval & FLAG_FIXED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBLOAD, address);
|
||||
}
|
||||
@ -1339,11 +1336,11 @@ inline bool mips3_device::RDOUBLE_MASKED(offs_t address, uint64_t *result, uint6
|
||||
const uint32_t tlbval = vtlb_table()[address >> 12];
|
||||
if (tlbval & READ_ALLOWED)
|
||||
{
|
||||
*result = (*m_memory.read_qword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), mem_mask);
|
||||
*result = m_program->read_qword((tlbval & ~0xfff) | (address & 0xfff), mem_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tlbval & FLAG_FIXED)
|
||||
if (tlbval & FLAG_FIXED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBLOAD, address);
|
||||
}
|
||||
@ -1372,15 +1369,15 @@ inline void mips3_device::WBYTE(offs_t address, uint8_t data)
|
||||
m_fastram[ramnum].offset_base8[tlbaddress ^ m_byte_xor] = data;
|
||||
return;
|
||||
}
|
||||
(*m_memory.write_byte)(*m_program, tlbaddress, data);
|
||||
m_program->write_byte(tlbaddress, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tlbval & READ_ALLOWED)
|
||||
if (tlbval & READ_ALLOWED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBMOD, address);
|
||||
}
|
||||
else if(tlbval & FLAG_FIXED)
|
||||
else if (tlbval & FLAG_FIXED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBSTORE, address);
|
||||
}
|
||||
@ -1406,15 +1403,15 @@ inline void mips3_device::WHALF(offs_t address, uint16_t data)
|
||||
m_fastram[ramnum].offset_base16[(tlbaddress ^ m_word_xor) >> 1] = data;
|
||||
return;
|
||||
}
|
||||
(*m_memory.write_word)(*m_program, tlbaddress, data);
|
||||
m_program->write_word(tlbaddress, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tlbval & READ_ALLOWED)
|
||||
if (tlbval & READ_ALLOWED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBMOD, address);
|
||||
}
|
||||
else if(tlbval & FLAG_FIXED)
|
||||
else if (tlbval & FLAG_FIXED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBSTORE, address);
|
||||
}
|
||||
@ -1440,15 +1437,15 @@ inline void mips3_device::WWORD(offs_t address, uint32_t data)
|
||||
m_fastram[ramnum].offset_base32[(tlbaddress ^ m_dword_xor) >> 2] = data;
|
||||
return;
|
||||
}
|
||||
(*m_memory.write_dword)(*m_program, tlbaddress, data);
|
||||
m_program->write_dword(tlbaddress, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tlbval & READ_ALLOWED)
|
||||
if (tlbval & READ_ALLOWED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBMOD, address);
|
||||
}
|
||||
else if(tlbval & FLAG_FIXED)
|
||||
else if (tlbval & FLAG_FIXED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBSTORE, address);
|
||||
}
|
||||
@ -1464,15 +1461,15 @@ inline void mips3_device::WWORD_MASKED(offs_t address, uint32_t data, uint32_t m
|
||||
const uint32_t tlbval = vtlb_table()[address >> 12];
|
||||
if (tlbval & WRITE_ALLOWED)
|
||||
{
|
||||
(*m_memory.write_dword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data, mem_mask);
|
||||
m_program->write_dword((tlbval & ~0xfff) | (address & 0xfff), data, mem_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tlbval & READ_ALLOWED)
|
||||
if (tlbval & READ_ALLOWED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBMOD, address);
|
||||
}
|
||||
else if(tlbval & FLAG_FIXED)
|
||||
else if (tlbval & FLAG_FIXED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBSTORE, address);
|
||||
}
|
||||
@ -1488,15 +1485,15 @@ inline void mips3_device::WDOUBLE(offs_t address, uint64_t data)
|
||||
const uint32_t tlbval = vtlb_table()[address >> 12];
|
||||
if (tlbval & WRITE_ALLOWED)
|
||||
{
|
||||
(*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data);
|
||||
m_program->write_qword((tlbval & ~0xfff) | (address & 0xfff), data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tlbval & READ_ALLOWED)
|
||||
if (tlbval & READ_ALLOWED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBMOD, address);
|
||||
}
|
||||
else if(tlbval & FLAG_FIXED)
|
||||
else if (tlbval & FLAG_FIXED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBSTORE, address);
|
||||
}
|
||||
@ -1512,15 +1509,15 @@ inline void mips3_device::WDOUBLE_MASKED(offs_t address, uint64_t data, uint64_t
|
||||
const uint32_t tlbval = vtlb_table()[address >> 12];
|
||||
if (tlbval & WRITE_ALLOWED)
|
||||
{
|
||||
(*m_memory.write_qword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data, mem_mask);
|
||||
m_program->write_qword((tlbval & ~0xfff) | (address & 0xfff), data, mem_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tlbval & READ_ALLOWED)
|
||||
if (tlbval & READ_ALLOWED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBMOD, address);
|
||||
}
|
||||
else if(tlbval & FLAG_FIXED)
|
||||
else if (tlbval & FLAG_FIXED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBSTORE, address);
|
||||
}
|
||||
@ -1535,7 +1532,7 @@ inline bool r4650_device::RBYTE(offs_t address, uint32_t *result)
|
||||
{
|
||||
if ((SR & SR_KSU_USER) == SR_KSU_KERNEL)
|
||||
{
|
||||
*result = (*m_memory.read_byte)(*m_program, address);
|
||||
*result = m_program->read_byte(address);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1545,7 +1542,7 @@ inline bool r4650_device::RBYTE(offs_t address, uint32_t *result)
|
||||
*result = 0;
|
||||
return false;
|
||||
}
|
||||
*result = (*m_memory.read_byte)(*m_program, address + m_core->cpr[0][COP0_R4650_DBase]);
|
||||
*result = m_program->read_byte(address + m_core->cpr[0][COP0_R4650_DBase]);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1553,7 +1550,7 @@ inline bool r4650_device::RHALF(offs_t address, uint32_t *result)
|
||||
{
|
||||
if ((SR & SR_KSU_USER) == SR_KSU_KERNEL)
|
||||
{
|
||||
*result = (*m_memory.read_word)(*m_program, address);
|
||||
*result = m_program->read_word(address);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1563,7 +1560,7 @@ inline bool r4650_device::RHALF(offs_t address, uint32_t *result)
|
||||
*result = 0;
|
||||
return false;
|
||||
}
|
||||
*result = (*m_memory.read_word)(*m_program, address + m_core->cpr[0][COP0_R4650_DBase]);
|
||||
*result = m_program->read_word(address + m_core->cpr[0][COP0_R4650_DBase]);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1571,7 +1568,7 @@ inline bool r4650_device::RWORD(offs_t address, uint32_t *result, bool insn)
|
||||
{
|
||||
if ((SR & SR_KSU_USER) == SR_KSU_KERNEL)
|
||||
{
|
||||
*result = (*m_memory.read_dword)(*m_program, address);
|
||||
*result = m_program->read_dword(address);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1585,7 +1582,7 @@ inline bool r4650_device::RWORD(offs_t address, uint32_t *result, bool insn)
|
||||
*result = 0;
|
||||
return false;
|
||||
}
|
||||
*result = (*m_memory.read_dword)(*m_program, address + base);
|
||||
*result = m_program->read_dword(address + base);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1593,7 +1590,7 @@ inline bool r4650_device::RWORD_MASKED(offs_t address, uint32_t *result, uint32_
|
||||
{
|
||||
if ((SR & SR_KSU_USER) == SR_KSU_KERNEL)
|
||||
{
|
||||
*result = (*m_memory.read_dword_masked)(*m_program, address, mem_mask);
|
||||
*result = m_program->read_dword(address, mem_mask);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1603,7 +1600,7 @@ inline bool r4650_device::RWORD_MASKED(offs_t address, uint32_t *result, uint32_
|
||||
*result = 0;
|
||||
return false;
|
||||
}
|
||||
*result = (*m_memory.read_dword_masked)(*m_program, address + m_core->cpr[0][COP0_R4650_DBase], mem_mask);
|
||||
*result = m_program->read_dword(address + m_core->cpr[0][COP0_R4650_DBase], mem_mask);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1611,7 +1608,7 @@ inline bool r4650_device::RDOUBLE(offs_t address, uint64_t *result)
|
||||
{
|
||||
if ((SR & SR_KSU_USER) == SR_KSU_KERNEL)
|
||||
{
|
||||
*result = (*m_memory.read_qword)(*m_program, address);
|
||||
*result = m_program->read_qword(address);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1621,7 +1618,7 @@ inline bool r4650_device::RDOUBLE(offs_t address, uint64_t *result)
|
||||
*result = 0;
|
||||
return false;
|
||||
}
|
||||
*result = (*m_memory.read_qword)(*m_program, address + m_core->cpr[0][COP0_R4650_DBase]);
|
||||
*result = m_program->read_qword(address + m_core->cpr[0][COP0_R4650_DBase]);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1629,7 +1626,7 @@ inline bool r4650_device::RDOUBLE_MASKED(offs_t address, uint64_t *result, uint6
|
||||
{
|
||||
if ((SR & SR_KSU_USER) == SR_KSU_KERNEL)
|
||||
{
|
||||
*result = (*m_memory.read_qword_masked)(*m_program, address, mem_mask);
|
||||
*result = m_program->read_qword(address, mem_mask);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1639,102 +1636,103 @@ inline bool r4650_device::RDOUBLE_MASKED(offs_t address, uint64_t *result, uint6
|
||||
*result = 0;
|
||||
return false;
|
||||
}
|
||||
*result = (*m_memory.read_qword_masked)(*m_program, address + m_core->cpr[0][COP0_R4650_DBase], mem_mask);
|
||||
*result = m_program->read_qword(address + m_core->cpr[0][COP0_R4650_DBase], mem_mask);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void r4650_device::WBYTE(offs_t address, uint8_t data)
|
||||
{
|
||||
if ((SR & SR_KSU_USER) == SR_KSU_KERNEL)
|
||||
(*m_memory.write_byte)(*m_program, address, data);
|
||||
m_program->write_byte(address, data);
|
||||
else if ((address & 0xfffff000) > m_core->cpr[0][COP0_R4650_DBound])
|
||||
generate_tlb_exception(EXCEPTION_ADDRSTORE, address);
|
||||
else
|
||||
(*m_memory.write_byte)(*m_program, address + m_core->cpr[0][COP0_R4650_DBound], data);
|
||||
m_program->write_byte(address + m_core->cpr[0][COP0_R4650_DBound], data);
|
||||
}
|
||||
|
||||
inline void r4650_device::WHALF(offs_t address, uint16_t data)
|
||||
{
|
||||
if ((SR & SR_KSU_USER) == SR_KSU_KERNEL)
|
||||
(*m_memory.write_word)(*m_program, address, data);
|
||||
m_program->write_word(address, data);
|
||||
else if ((address & 0xfffff000) > m_core->cpr[0][COP0_R4650_DBound])
|
||||
generate_tlb_exception(EXCEPTION_ADDRSTORE, address);
|
||||
else
|
||||
(*m_memory.write_word)(*m_program, address + m_core->cpr[0][COP0_R4650_DBound], data);
|
||||
m_program->write_word(address + m_core->cpr[0][COP0_R4650_DBound], data);
|
||||
}
|
||||
|
||||
inline void r4650_device::WWORD(offs_t address, uint32_t data)
|
||||
{
|
||||
if ((SR & SR_KSU_USER) == SR_KSU_KERNEL)
|
||||
(*m_memory.write_dword)(*m_program, address, data);
|
||||
m_program->write_dword(address, data);
|
||||
else if ((address & 0xfffff000) > m_core->cpr[0][COP0_R4650_DBound])
|
||||
generate_tlb_exception(EXCEPTION_ADDRSTORE, address);
|
||||
else
|
||||
(*m_memory.write_dword)(*m_program, address + m_core->cpr[0][COP0_R4650_DBound], data);
|
||||
m_program->write_dword(address + m_core->cpr[0][COP0_R4650_DBound], data);
|
||||
}
|
||||
|
||||
inline void r4650_device::WWORD_MASKED(offs_t address, uint32_t data, uint32_t mem_mask)
|
||||
{
|
||||
if ((SR & SR_KSU_USER) == SR_KSU_KERNEL)
|
||||
(*m_memory.write_dword_masked)(*m_program, address, data, mem_mask);
|
||||
m_program->write_dword(address, data, mem_mask);
|
||||
else if ((address & 0xfffff000) > m_core->cpr[0][COP0_R4650_DBound])
|
||||
generate_tlb_exception(EXCEPTION_ADDRSTORE, address);
|
||||
else
|
||||
(*m_memory.write_dword_masked)(*m_program, address + m_core->cpr[0][COP0_R4650_DBound], data, mem_mask);
|
||||
m_program->write_dword(address + m_core->cpr[0][COP0_R4650_DBound], data, mem_mask);
|
||||
}
|
||||
|
||||
inline void r4650_device::WDOUBLE(offs_t address, uint64_t data)
|
||||
{
|
||||
if ((SR & SR_KSU_USER) == SR_KSU_KERNEL)
|
||||
(*m_memory.write_qword)(*m_program, address, data);
|
||||
m_program->write_qword(address, data);
|
||||
else if ((address & 0xfffff000) > m_core->cpr[0][COP0_R4650_DBound])
|
||||
generate_tlb_exception(EXCEPTION_ADDRSTORE, address);
|
||||
else
|
||||
(*m_memory.write_qword)(*m_program, address + m_core->cpr[0][COP0_R4650_DBound], data);
|
||||
m_program->write_qword(address + m_core->cpr[0][COP0_R4650_DBound], data);
|
||||
}
|
||||
|
||||
inline void r4650_device::WDOUBLE_MASKED(offs_t address, uint64_t data, uint64_t mem_mask)
|
||||
{
|
||||
if ((SR & SR_KSU_USER) == SR_KSU_KERNEL)
|
||||
(*m_memory.write_qword_masked)(*m_program, address, data, mem_mask);
|
||||
m_program->write_qword(address, data, mem_mask);
|
||||
else if ((address & 0xfffff000) > m_core->cpr[0][COP0_R4650_DBound])
|
||||
generate_tlb_exception(EXCEPTION_ADDRSTORE, address);
|
||||
else
|
||||
(*m_memory.write_qword_masked)(*m_program, address + m_core->cpr[0][COP0_R4650_DBound], data, mem_mask);
|
||||
m_program->write_qword(address + m_core->cpr[0][COP0_R4650_DBound], data, mem_mask);
|
||||
}
|
||||
|
||||
inline void r5900_device::WBYTE(offs_t address, uint8_t data)
|
||||
{
|
||||
if (address >= 0x70000000 && address < 0x70004000) (*m_memory.write_byte)(*m_program, address, data);
|
||||
if (address >= 0x70000000 && address < 0x70004000) m_program->write_byte(address, data);
|
||||
else mips3_device::WBYTE(address, data);
|
||||
}
|
||||
|
||||
inline void r5900_device::WHALF(offs_t address, uint16_t data)
|
||||
{
|
||||
if (address >= 0x70000000 && address < 0x70004000) (*m_memory.write_word)(*m_program, address, data);
|
||||
if (address >= 0x70000000 && address < 0x70004000) m_program->write_word(address, data);
|
||||
else mips3_device::WHALF(address, data);
|
||||
}
|
||||
|
||||
inline void r5900_device::WWORD(offs_t address, uint32_t data)
|
||||
{
|
||||
if (address >= 0x70000000 && address < 0x70004000) (*m_memory.write_dword)(*m_program, address, data);
|
||||
if (address >= 0x70000000 && address < 0x70004000) m_program->write_dword(address, data);
|
||||
else mips3_device::WWORD(address, data);
|
||||
}
|
||||
|
||||
inline void r5900_device::WWORD_MASKED(offs_t address, uint32_t data, uint32_t mem_mask)
|
||||
{
|
||||
if (address >= 0x70000000 && address < 0x70004000) (*m_memory.write_dword_masked)(*m_program, address, data, mem_mask);
|
||||
if (address >= 0x70000000 && address < 0x70004000) m_program->write_dword(address, data, mem_mask);
|
||||
else mips3_device::WWORD_MASKED(address, data, mem_mask);
|
||||
}
|
||||
|
||||
inline void r5900_device::WDOUBLE(offs_t address, uint64_t data) {
|
||||
if (address >= 0x70000000 && address < 0x70004000) (*m_memory.write_qword)(*m_program, address, data);
|
||||
inline void r5900_device::WDOUBLE(offs_t address, uint64_t data)
|
||||
{
|
||||
if (address >= 0x70000000 && address < 0x70004000) m_program->write_qword(address, data);
|
||||
else mips3_device::WDOUBLE(address, data);
|
||||
}
|
||||
|
||||
inline void r5900_device::WDOUBLE_MASKED(offs_t address, uint64_t data, uint64_t mem_mask)
|
||||
{
|
||||
if (address >= 0x70000000 && address < 0x70004000) (*m_memory.write_qword_masked)(*m_program, address, data, mem_mask);
|
||||
if (address >= 0x70000000 && address < 0x70004000) m_program->write_qword(address, data, mem_mask);
|
||||
else mips3_device::WDOUBLE_MASKED(address, data, mem_mask);
|
||||
}
|
||||
|
||||
@ -1742,24 +1740,24 @@ inline void r5900le_device::WQUAD(offs_t address, uint64_t data_hi, uint64_t dat
|
||||
{
|
||||
if (address >= 0x70000000 && address < 0x70004000)
|
||||
{
|
||||
(*m_memory.write_qword)(*m_program, address, data_lo);
|
||||
(*m_memory.write_qword)(*m_program, address + 8, data_hi);
|
||||
m_program->write_qword(address, data_lo);
|
||||
m_program->write_qword(address + 8, data_hi);
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t tlbval = vtlb_table()[address >> 12];
|
||||
if (tlbval & WRITE_ALLOWED)
|
||||
{
|
||||
(*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data_lo);
|
||||
(*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | ((address + 8) & 0xfff), data_hi);
|
||||
m_program->write_qword((tlbval & ~0xfff) | (address & 0xfff), data_lo);
|
||||
m_program->write_qword((tlbval & ~0xfff) | ((address + 8) & 0xfff), data_hi);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tlbval & READ_ALLOWED)
|
||||
if (tlbval & READ_ALLOWED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBMOD, address);
|
||||
}
|
||||
else if(tlbval & FLAG_FIXED)
|
||||
else if (tlbval & FLAG_FIXED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBSTORE, address);
|
||||
}
|
||||
@ -1774,24 +1772,24 @@ inline void r5900be_device::WQUAD(offs_t address, uint64_t data_hi, uint64_t dat
|
||||
{
|
||||
if (address >= 0x70000000 && address < 0x70004000)
|
||||
{
|
||||
(*m_memory.write_qword)(*m_program, address, data_hi);
|
||||
(*m_memory.write_qword)(*m_program, address + 8, data_lo);
|
||||
m_program->write_qword(address, data_hi);
|
||||
m_program->write_qword(address + 8, data_lo);
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t tlbval = vtlb_table()[address >> 12];
|
||||
if (tlbval & WRITE_ALLOWED)
|
||||
{
|
||||
(*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data_hi);
|
||||
(*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | ((address + 8) & 0xfff), data_lo);
|
||||
m_program->write_qword((tlbval & ~0xfff) | (address & 0xfff), data_hi);
|
||||
m_program->write_qword((tlbval & ~0xfff) | ((address + 8) & 0xfff), data_lo);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tlbval & READ_ALLOWED)
|
||||
if (tlbval & READ_ALLOWED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBMOD, address);
|
||||
}
|
||||
else if(tlbval & FLAG_FIXED)
|
||||
else if (tlbval & FLAG_FIXED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBSTORE, address);
|
||||
}
|
||||
@ -1802,9 +1800,11 @@ inline void r5900be_device::WQUAD(offs_t address, uint64_t data_hi, uint64_t dat
|
||||
}
|
||||
}
|
||||
|
||||
inline bool r5900_device::RBYTE(offs_t address, uint32_t *result) {
|
||||
if (address >= 0x70000000 && address < 0x70004000) {
|
||||
*result = (*m_memory.read_byte)(*m_program, address);
|
||||
inline bool r5900_device::RBYTE(offs_t address, uint32_t *result)
|
||||
{
|
||||
if (address >= 0x70000000 && address < 0x70004000)
|
||||
{
|
||||
*result = m_program->read_byte(address);
|
||||
return true;
|
||||
}
|
||||
return mips3_device::RBYTE(address, result);
|
||||
@ -1814,7 +1814,7 @@ inline bool r5900_device::RHALF(offs_t address, uint32_t *result)
|
||||
{
|
||||
if (address >= 0x70000000 && address < 0x70004000)
|
||||
{
|
||||
*result = (*m_memory.read_word)(*m_program, address);
|
||||
*result = m_program->read_word(address);
|
||||
return true;
|
||||
}
|
||||
return mips3_device::RHALF(address, result);
|
||||
@ -1824,7 +1824,7 @@ inline bool r5900_device::RWORD(offs_t address, uint32_t *result, bool insn)
|
||||
{
|
||||
if (address >= 0x70000000 && address < 0x70004000)
|
||||
{
|
||||
*result = (*m_memory.read_dword)(*m_program, address);
|
||||
*result = m_program->read_dword(address);
|
||||
return true;
|
||||
}
|
||||
return mips3_device::RWORD(address, result, insn);
|
||||
@ -1834,7 +1834,7 @@ inline bool r5900_device::RWORD_MASKED(offs_t address, uint32_t *result, uint32_
|
||||
{
|
||||
if (address >= 0x70000000 && address < 0x70004000)
|
||||
{
|
||||
*result = (*m_memory.read_dword_masked)(*m_program, address, mem_mask);
|
||||
*result = m_program->read_dword(address, mem_mask);
|
||||
return true;
|
||||
}
|
||||
return mips3_device::RWORD_MASKED(address, result, mem_mask);
|
||||
@ -1844,7 +1844,7 @@ inline bool r5900_device::RDOUBLE(offs_t address, uint64_t *result)
|
||||
{
|
||||
if (address >= 0x70000000 && address < 0x70004000)
|
||||
{
|
||||
*result = (*m_memory.read_qword)(*m_program, address);
|
||||
*result = m_program->read_qword(address);
|
||||
return true;
|
||||
}
|
||||
return mips3_device::RDOUBLE(address, result);
|
||||
@ -1854,7 +1854,7 @@ inline bool r5900_device::RDOUBLE_MASKED(offs_t address, uint64_t *result, uint6
|
||||
{
|
||||
if (address >= 0x70000000 && address < 0x70004000)
|
||||
{
|
||||
*result = (*m_memory.read_qword_masked)(*m_program, address, mem_mask);
|
||||
*result = m_program->read_qword(address, mem_mask);
|
||||
return true;
|
||||
}
|
||||
return mips3_device::RDOUBLE_MASKED(address, result, mem_mask);
|
||||
@ -1864,20 +1864,20 @@ inline bool r5900le_device::RQUAD(offs_t address, uint64_t *result_hi, uint64_t
|
||||
{
|
||||
if (address >= 0x70000000 && address < 0x70004000)
|
||||
{
|
||||
*result_lo = (*m_memory.read_qword)(*m_program, address);
|
||||
*result_hi = (*m_memory.read_qword)(*m_program, address + 8);
|
||||
*result_lo = m_program->read_qword(address);
|
||||
*result_hi = m_program->read_qword(address + 8);
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint32_t tlbval = vtlb_table()[address >> 12];
|
||||
if (tlbval & READ_ALLOWED)
|
||||
{
|
||||
*result_lo = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff));
|
||||
*result_hi = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | ((address + 8) & 0xfff));
|
||||
*result_lo = m_program->read_qword((tlbval & ~0xfff) | (address & 0xfff));
|
||||
*result_hi = m_program->read_qword((tlbval & ~0xfff) | ((address + 8) & 0xfff));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tlbval & FLAG_FIXED)
|
||||
if (tlbval & FLAG_FIXED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBLOAD, address);
|
||||
}
|
||||
@ -1896,20 +1896,20 @@ inline bool r5900be_device::RQUAD(offs_t address, uint64_t *result_hi, uint64_t
|
||||
{
|
||||
if (address >= 0x70000000 && address < 0x70004000)
|
||||
{
|
||||
*result_hi = (*m_memory.read_qword)(*m_program, address);
|
||||
*result_lo = (*m_memory.read_qword)(*m_program, address + 8);
|
||||
*result_hi = m_program->read_qword(address);
|
||||
*result_lo = m_program->read_qword(address + 8);
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint32_t tlbval = vtlb_table()[address >> 12];
|
||||
if (tlbval & READ_ALLOWED)
|
||||
{
|
||||
*result_hi = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff));
|
||||
*result_lo = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | ((address + 8) & 0xfff));
|
||||
*result_hi = m_program->read_qword((tlbval & ~0xfff) | (address & 0xfff));
|
||||
*result_lo = m_program->read_qword((tlbval & ~0xfff) | ((address + 8) & 0xfff));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tlbval & FLAG_FIXED)
|
||||
if (tlbval & FLAG_FIXED)
|
||||
{
|
||||
generate_tlb_exception(EXCEPTION_TLBLOAD, address);
|
||||
}
|
||||
@ -2255,25 +2255,31 @@ void mips3_device::handle_cop1_fr0(uint32_t op)
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
if (IS_SINGLE(op)) { /* DIV.S */
|
||||
if (FTVALW_FR0 == 0 && (COP1_FCR31 & (1 << (FCR31_ENABLE + FPE_DIV0)))) {
|
||||
if (IS_SINGLE(op)) /* DIV.S */
|
||||
{
|
||||
if (FTVALW_FR0 == 0 && (COP1_FCR31 & (1 << (FCR31_ENABLE + FPE_DIV0))))
|
||||
{
|
||||
COP1_FCR31 |= (1 << (FCR31_FLAGS + FPE_DIV0)); // Set flag
|
||||
COP1_FCR31 |= (1 << (FCR31_CAUSE + FPE_DIV0)); // Set cause
|
||||
generate_exception(EXCEPTION_FPE, 1);
|
||||
//machine().debug_break();
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
FDVALS_FR0 = FSVALS_FR0 / FTVALS_FR0;
|
||||
}
|
||||
}
|
||||
else { /* DIV.D */
|
||||
if (FTVALL_FR0 == 0ull && (COP1_FCR31 & (1 << (FCR31_ENABLE + FPE_DIV0)))) {
|
||||
else /* DIV.D */
|
||||
{
|
||||
if (FTVALL_FR0 == 0ull && (COP1_FCR31 & (1 << (FCR31_ENABLE + FPE_DIV0))))
|
||||
{
|
||||
COP1_FCR31 |= (1 << (FCR31_FLAGS + FPE_DIV0)); // Set flag
|
||||
COP1_FCR31 |= (1 << (FCR31_CAUSE + FPE_DIV0)); // Set cause
|
||||
generate_exception(EXCEPTION_FPE, 1);
|
||||
//machine().debug_break();
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
FDVALD_FR0 = FSVALD_FR0 / FTVALD_FR0;
|
||||
}
|
||||
}
|
||||
|
@ -448,7 +448,6 @@ protected:
|
||||
uint32_t m_byte_xor;
|
||||
uint32_t m_word_xor;
|
||||
uint32_t m_dword_xor;
|
||||
data_accessors m_memory;
|
||||
|
||||
/* cache memory */
|
||||
size_t c_icache_size;
|
||||
|
Loading…
Reference in New Issue
Block a user