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:
Vas Crabb 2025-02-03 08:02:40 +11:00
parent bf7061a27e
commit 32736e4c43
10 changed files with 395 additions and 434 deletions

View File

@ -1680,7 +1680,6 @@ CPPCHECK_PARAMS += -I3rdparty/bx/include
CPPCHECK_PARAMS += -I$(BUILDDIR)/generated/emu CPPCHECK_PARAMS += -I$(BUILDDIR)/generated/emu
CPPCHECK_PARAMS += -I$(BUILDDIR)/generated/emu/layout CPPCHECK_PARAMS += -I$(BUILDDIR)/generated/emu/layout
CPPCHECK_PARAMS += -I$(BUILDDIR)/generated/mame/layout CPPCHECK_PARAMS += -I$(BUILDDIR)/generated/mame/layout
CPPCHECK_PARAMS += -DX64_WINDOWS_ABI
CPPCHECK_PARAMS += -DPTR64=1 CPPCHECK_PARAMS += -DPTR64=1
CPPCHECK_PARAMS += -DMAME_DEBUG CPPCHECK_PARAMS += -DMAME_DEBUG
CPPCHECK_PARAMS += -DMAME_PROFILER CPPCHECK_PARAMS += -DMAME_PROFILER

View File

@ -2054,67 +2054,30 @@ void drcbe_arm64::op_read(a64::Assembler &a, const uml::instruction &inst)
const parameter &spacesizep = inst.param(2); const parameter &spacesizep = inst.param(2);
assert(spacesizep.is_size_space()); assert(spacesizep.is_size_space());
const auto &trampolines = m_accessors[spacesizep.space()];
const auto &resolved = m_resolved_accessors[spacesizep.space()]; const auto &resolved = m_resolved_accessors[spacesizep.space()];
mov_reg_param(a, 4, REG_PARAM2, addrp); mov_reg_param(a, 4, REG_PARAM2, addrp);
if (spacesizep.size() == SIZE_BYTE) if (spacesizep.size() == SIZE_BYTE)
{
if (resolved.read_byte)
{ {
get_imm_relative(a, REG_PARAM1, resolved.read_byte.obj); get_imm_relative(a, REG_PARAM1, resolved.read_byte.obj);
call_arm_addr(a, resolved.read_byte.func); 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);
}
}
else if (spacesizep.size() == SIZE_WORD) else if (spacesizep.size() == SIZE_WORD)
{
if (resolved.read_word)
{ {
get_imm_relative(a, REG_PARAM1, resolved.read_word.obj); get_imm_relative(a, REG_PARAM1, resolved.read_word.obj);
call_arm_addr(a, resolved.read_word.func); 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);
}
}
else if (spacesizep.size() == SIZE_DWORD) else if (spacesizep.size() == SIZE_DWORD)
{
if (resolved.read_dword)
{ {
get_imm_relative(a, REG_PARAM1, resolved.read_dword.obj); get_imm_relative(a, REG_PARAM1, resolved.read_dword.obj);
call_arm_addr(a, resolved.read_dword.func); 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);
}
}
else if (spacesizep.size() == SIZE_QWORD) else if (spacesizep.size() == SIZE_QWORD)
{
if (resolved.read_qword)
{ {
get_imm_relative(a, REG_PARAM1, resolved.read_qword.obj); get_imm_relative(a, REG_PARAM1, resolved.read_qword.obj);
call_arm_addr(a, resolved.read_qword.func); 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);
}
}
mov_param_reg(a, inst.size(), dstp, REG_PARAM1); mov_param_reg(a, inst.size(), dstp, REG_PARAM1);
} }
@ -2131,68 +2094,31 @@ void drcbe_arm64::op_readm(a64::Assembler &a, const uml::instruction &inst)
const parameter &spacesizep = inst.param(3); const parameter &spacesizep = inst.param(3);
assert(spacesizep.is_size_space()); assert(spacesizep.is_size_space());
const auto &trampolines = m_accessors[spacesizep.space()];
const auto &resolved = m_resolved_accessors[spacesizep.space()]; const auto &resolved = m_resolved_accessors[spacesizep.space()];
mov_reg_param(a, 4, REG_PARAM2, addrp); mov_reg_param(a, 4, REG_PARAM2, addrp);
mov_reg_param(a, inst.size(), REG_PARAM3, maskp); mov_reg_param(a, inst.size(), REG_PARAM3, maskp);
if (spacesizep.size() == SIZE_BYTE) if (spacesizep.size() == SIZE_BYTE)
{
if (resolved.read_byte_masked)
{ {
get_imm_relative(a, REG_PARAM1, resolved.read_byte_masked.obj); get_imm_relative(a, REG_PARAM1, resolved.read_byte_masked.obj);
call_arm_addr(a, resolved.read_byte_masked.func); 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);
}
}
else if (spacesizep.size() == SIZE_WORD) else if (spacesizep.size() == SIZE_WORD)
{
if (resolved.read_word_masked)
{ {
get_imm_relative(a, REG_PARAM1, resolved.read_word_masked.obj); get_imm_relative(a, REG_PARAM1, resolved.read_word_masked.obj);
call_arm_addr(a, resolved.read_word_masked.func); 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);
}
}
else if (spacesizep.size() == SIZE_DWORD) else if (spacesizep.size() == SIZE_DWORD)
{
if (resolved.read_dword_masked)
{ {
get_imm_relative(a, REG_PARAM1, resolved.read_dword_masked.obj); get_imm_relative(a, REG_PARAM1, resolved.read_dword_masked.obj);
call_arm_addr(a, resolved.read_dword_masked.func); 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);
}
}
else if (spacesizep.size() == SIZE_QWORD) else if (spacesizep.size() == SIZE_QWORD)
{
if (resolved.read_qword_masked)
{ {
get_imm_relative(a, REG_PARAM1, resolved.read_qword_masked.obj); get_imm_relative(a, REG_PARAM1, resolved.read_qword_masked.obj);
call_arm_addr(a, resolved.read_qword_masked.func); 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);
}
}
mov_param_reg(a, inst.size(), dstp, REG_PARAM1); mov_param_reg(a, inst.size(), dstp, REG_PARAM1);
} }
@ -2208,68 +2134,31 @@ void drcbe_arm64::op_write(a64::Assembler &a, const uml::instruction &inst)
const parameter &spacesizep = inst.param(2); const parameter &spacesizep = inst.param(2);
assert(spacesizep.is_size_space()); assert(spacesizep.is_size_space());
const auto &trampolines = m_accessors[spacesizep.space()];
const auto &resolved = m_resolved_accessors[spacesizep.space()]; const auto &resolved = m_resolved_accessors[spacesizep.space()];
mov_reg_param(a, 4, REG_PARAM2, addrp); mov_reg_param(a, 4, REG_PARAM2, addrp);
mov_reg_param(a, inst.size(), REG_PARAM3, srcp); mov_reg_param(a, inst.size(), REG_PARAM3, srcp);
if (spacesizep.size() == SIZE_BYTE) if (spacesizep.size() == SIZE_BYTE)
{
if (resolved.write_byte)
{ {
get_imm_relative(a, REG_PARAM1, resolved.write_byte.obj); get_imm_relative(a, REG_PARAM1, resolved.write_byte.obj);
call_arm_addr(a, resolved.write_byte.func); 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);
}
}
else if (spacesizep.size() == SIZE_WORD) else if (spacesizep.size() == SIZE_WORD)
{
if (resolved.write_word)
{ {
get_imm_relative(a, REG_PARAM1, resolved.write_word.obj); get_imm_relative(a, REG_PARAM1, resolved.write_word.obj);
call_arm_addr(a, resolved.write_word.func); 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);
}
}
else if (spacesizep.size() == SIZE_DWORD) else if (spacesizep.size() == SIZE_DWORD)
{
if (resolved.write_dword)
{ {
get_imm_relative(a, REG_PARAM1, resolved.write_dword.obj); get_imm_relative(a, REG_PARAM1, resolved.write_dword.obj);
call_arm_addr(a, resolved.write_dword.func); 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);
}
}
else if (spacesizep.size() == SIZE_QWORD) else if (spacesizep.size() == SIZE_QWORD)
{
if (resolved.write_qword)
{ {
get_imm_relative(a, REG_PARAM1, resolved.write_qword.obj); get_imm_relative(a, REG_PARAM1, resolved.write_qword.obj);
call_arm_addr(a, resolved.write_qword.func); 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);
}
}
} }
void drcbe_arm64::op_writem(a64::Assembler &a, const uml::instruction &inst) void drcbe_arm64::op_writem(a64::Assembler &a, const uml::instruction &inst)
@ -2285,7 +2174,6 @@ void drcbe_arm64::op_writem(a64::Assembler &a, const uml::instruction &inst)
assert(spacesizep.is_size_space()); assert(spacesizep.is_size_space());
// set up a call to the write handler // set up a call to the write handler
const auto &trampolines = m_accessors[spacesizep.space()];
const auto &resolved = m_resolved_accessors[spacesizep.space()]; const auto &resolved = m_resolved_accessors[spacesizep.space()];
mov_reg_param(a, 4, REG_PARAM2, addrp); mov_reg_param(a, 4, REG_PARAM2, addrp);
@ -2293,61 +2181,25 @@ void drcbe_arm64::op_writem(a64::Assembler &a, const uml::instruction &inst)
mov_reg_param(a, inst.size(), REG_PARAM4, maskp); mov_reg_param(a, inst.size(), REG_PARAM4, maskp);
if (spacesizep.size() == SIZE_BYTE) if (spacesizep.size() == SIZE_BYTE)
{
if (resolved.write_byte_masked)
{ {
get_imm_relative(a, REG_PARAM1, resolved.write_byte_masked.obj); get_imm_relative(a, REG_PARAM1, resolved.write_byte_masked.obj);
call_arm_addr(a, resolved.write_byte_masked.func); 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);
}
}
else if (spacesizep.size() == SIZE_WORD) else if (spacesizep.size() == SIZE_WORD)
{
if (resolved.write_word_masked)
{ {
get_imm_relative(a, REG_PARAM1, resolved.write_word_masked.obj); get_imm_relative(a, REG_PARAM1, resolved.write_word_masked.obj);
call_arm_addr(a, resolved.write_word_masked.func); 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);
}
}
else if (spacesizep.size() == SIZE_DWORD) else if (spacesizep.size() == SIZE_DWORD)
{
if (resolved.write_dword_masked)
{ {
get_imm_relative(a, REG_PARAM1, resolved.write_dword_masked.obj); get_imm_relative(a, REG_PARAM1, resolved.write_dword_masked.obj);
call_arm_addr(a, resolved.write_dword_masked.func); 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);
}
}
else if (spacesizep.size() == SIZE_QWORD) else if (spacesizep.size() == SIZE_QWORD)
{
if (resolved.write_qword_masked)
{ {
get_imm_relative(a, REG_PARAM1, resolved.write_qword_masked.obj); get_imm_relative(a, REG_PARAM1, resolved.write_qword_masked.obj);
call_arm_addr(a, resolved.write_qword_masked.func); 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);
}
}
} }
void drcbe_arm64::op_carry(a64::Assembler &a, const uml::instruction &inst) void drcbe_arm64::op_carry(a64::Assembler &a, const uml::instruction &inst)
@ -3924,40 +3776,21 @@ void drcbe_arm64::op_fread(a64::Assembler &a, const uml::instruction &inst)
assert(spacesizep.is_size_space()); assert(spacesizep.is_size_space());
assert((1 << spacesizep.size()) == inst.size()); assert((1 << spacesizep.size()) == inst.size());
const auto &trampolines = m_accessors[spacesizep.space()];
const auto &resolved = m_resolved_accessors[spacesizep.space()]; const auto &resolved = m_resolved_accessors[spacesizep.space()];
mov_reg_param(a, 4, REG_PARAM2, addrp); mov_reg_param(a, 4, REG_PARAM2, addrp);
if (inst.size() == 4) if (inst.size() == 4)
{
if (resolved.read_dword)
{ {
get_imm_relative(a, REG_PARAM1, resolved.read_dword.obj); get_imm_relative(a, REG_PARAM1, resolved.read_dword.obj);
call_arm_addr(a, resolved.read_dword.func); 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);
}
mov_float_param_int_reg(a, inst.size(), dstp, REG_PARAM1.w()); mov_float_param_int_reg(a, inst.size(), dstp, REG_PARAM1.w());
} }
else if (inst.size() == 8) else if (inst.size() == 8)
{
if (resolved.read_qword)
{ {
get_imm_relative(a, REG_PARAM1, resolved.read_qword.obj); get_imm_relative(a, REG_PARAM1, resolved.read_qword.obj);
call_arm_addr(a, resolved.read_qword.func); 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);
}
mov_float_param_int_reg(a, inst.size(), dstp, REG_PARAM1); 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(spacesizep.is_size_space());
assert((1 << spacesizep.size()) == inst.size()); assert((1 << spacesizep.size()) == inst.size());
const auto &trampolines = m_accessors[spacesizep.space()];
const auto &resolved = m_resolved_accessors[spacesizep.space()]; const auto &resolved = m_resolved_accessors[spacesizep.space()];
mov_reg_param(a, 4, REG_PARAM2, addrp); mov_reg_param(a, 4, REG_PARAM2, addrp);
@ -3984,33 +3816,15 @@ void drcbe_arm64::op_fwrite(a64::Assembler &a, const uml::instruction &inst)
a.fmov(select_register(REG_PARAM3, inst.size()), select_register(TEMPF_REG1, inst.size())); a.fmov(select_register(REG_PARAM3, inst.size()), select_register(TEMPF_REG1, inst.size()));
if (inst.size() == 4) if (inst.size() == 4)
{
if (resolved.write_dword)
{ {
get_imm_relative(a, REG_PARAM1, resolved.write_dword.obj); get_imm_relative(a, REG_PARAM1, resolved.write_dword.obj);
call_arm_addr(a, resolved.write_dword.func); 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);
}
}
else if (inst.size() == 8) else if (inst.size() == 8)
{
if (resolved.write_qword)
{ {
get_imm_relative(a, REG_PARAM1, resolved.write_qword.obj); get_imm_relative(a, REG_PARAM1, resolved.write_qword.obj);
call_arm_addr(a, resolved.write_qword.func); 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);
}
}
} }
void drcbe_arm64::op_fmov(a64::Assembler &a, const uml::instruction &inst) void drcbe_arm64::op_fmov(a64::Assembler &a, const uml::instruction &inst)

View File

@ -590,7 +590,7 @@ void drc_label_list::oob_callback(drccodeptr *codeptr, void *param1, void *param
// set - bind to address space // 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 .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)); 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_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 .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)); 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 } // namespace drc

View File

@ -214,7 +214,7 @@ struct resolved_memory_accessors
resolved_member_function write_qword; resolved_member_function write_qword;
resolved_member_function write_qword_masked; 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>; using resolved_memory_accessors_vector = std::vector<resolved_memory_accessors>;

View File

@ -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_MRI = PTYPE_M | PTYPE_R | PTYPE_I;
const uint32_t PTYPE_MF = PTYPE_M | PTYPE_F; 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_PARAM1 = Gp::kIdCx;
const Gp::Id REG_PARAM2 = Gp::kIdDx; const Gp::Id REG_PARAM2 = Gp::kIdDx;
@ -233,7 +233,7 @@ const Gp::Id REG_PARAM4 = Gp::kIdCx;
// register mapping tables // register mapping tables
const Gp::Id int_register_map[REG_I_COUNT] = 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, Gp::kIdBx, Gp::kIdSi, Gp::kIdDi, Gp::kIdR12, Gp::kIdR13, Gp::kIdR14, Gp::kIdR15,
#else #else
Gp::kIdBx, Gp::kIdR12, Gp::kIdR13, Gp::kIdR14, Gp::kIdR15 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] = uint32_t float_register_map[REG_F_COUNT] =
{ {
#ifdef X64_WINDOWS_ABI #ifdef _WIN32
6, 7, 8, 9, 10, 11, 12, 13, 14, 15 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
#else #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. // save/restore them around CALLC, they should be safe for our use.
0, 1, 2, 3, 4, 5, 6, 7 0, 1, 2, 3, 4, 5, 6, 7
#endif #endif

View File

@ -257,7 +257,7 @@ private:
uint32_t ssemode; // saved SSE mode uint32_t ssemode; // saved SSE mode
uint32_t ssemodesave; // temporary location for saving uint32_t ssemodesave; // temporary location for saving
uint32_t ssecontrol[4]; // copy of the sse_control array 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 double double1; // 1.0 in double-precision
void * stacksave; // saved stack pointer void * stacksave; // saved stack pointer

View File

@ -114,6 +114,12 @@ namespace {
// CONSTANTS // 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_M = 1 << parameter::PTYPE_MEMORY;
const uint32_t PTYPE_I = 1 << parameter::PTYPE_IMMEDIATE; const uint32_t PTYPE_I = 1 << parameter::PTYPE_IMMEDIATE;
const uint32_t PTYPE_R = 1 << parameter::PTYPE_INT_REGISTER; 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 - constructor
//------------------------------------------------- //-------------------------------------------------
drcbe_x86::drcbe_x86(drcuml_state &drcuml, device_t &device, drc_cache &cache, uint32_t flags, int modes, int addrbits, int ignorebits) 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), drcbe_interface(drcuml, cache, device)
m_hash(cache, modes, addrbits, ignorebits), , m_hash(cache, modes, addrbits, ignorebits)
m_map(cache, 0), , m_map(cache, 0)
m_log(nullptr), , m_log(nullptr)
m_log_asmjit(nullptr), , m_log_asmjit(nullptr)
m_logged_common(false), , m_logged_common(false)
m_sse3(CpuInfo::host().features().x86().hasSSE3()), , m_sse3(CpuInfo::host().features().x86().hasSSE3())
m_entry(nullptr), , m_entry(nullptr)
m_exit(nullptr), , m_exit(nullptr)
m_nocode(nullptr), , m_nocode(nullptr)
m_save(nullptr), , m_save(nullptr)
m_restore(nullptr), , m_restore(nullptr)
m_last_lower_reg(Gp()), , m_last_lower_reg(Gp())
m_last_lower_pc(nullptr), , m_last_lower_pc(nullptr)
m_last_lower_addr(nullptr), , m_last_lower_addr(nullptr)
m_last_upper_reg(Gp()), , m_last_upper_reg(Gp())
m_last_upper_pc(nullptr), , m_last_upper_pc(nullptr)
m_last_upper_addr(nullptr), , m_last_upper_addr(nullptr)
m_fptemp(0), , m_fptemp(0)
m_fpumode(0), , m_fpumode(0)
m_fmodesave(0), , m_fmodesave(0)
m_stacksave(nullptr), , m_stacksave(nullptr)
m_hashstacksave(nullptr), , m_hashstacksave(nullptr)
m_reslo(0), , m_reslo(0)
m_reshi(0) , m_reshi(0)
{ {
// compute hi pointers for each register // compute hi pointers for each register
for (int regnum = 0; regnum < std::size(int_register_map); regnum++) 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; 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) // build the opcode table (static but it doesn't hurt to regenerate it)
for (auto & elem : s_opcode_table_source) for (auto & elem : s_opcode_table_source)
s_opcode_table[elem.opcode] = elem.func; 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 // pick a target register for the general case
Gp const dstreg = dstp.select_register(eax); Gp const dstreg = dstp.select_register(eax);
// set up a call to the read byte handler // set up a call to the read handler
emit_mov_m32_p32(a, dword_ptr(esp, 4), addrp); // mov [esp+4],addrp auto const &accessors = m_memory_accessors[spacesizep.space()];
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) if (spacesizep.size() == SIZE_BYTE)
{ {
a.call(imm(m_accessors[spacesizep.space()].read_byte)); // call read_byte if (USE_THISCALL)
a.movzx(dstreg, al); // movzx dstreg,al 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) else if (spacesizep.size() == SIZE_WORD)
{ {
a.call(imm(m_accessors[spacesizep.space()].read_word)); // call read_word if (USE_THISCALL)
a.movzx(dstreg, ax); // movzx dstreg,ax 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) else if (spacesizep.size() == SIZE_DWORD)
{ {
a.call(imm(m_accessors[spacesizep.space()].read_dword)); // call read_dword if (USE_THISCALL)
a.mov(dstreg, eax); // mov dstreg,eax 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) else if (spacesizep.size() == SIZE_QWORD)
{ {
a.call(imm(m_accessors[spacesizep.space()].read_qword)); // call read_qword if (USE_THISCALL)
a.mov(dstreg, eax); // mov dstreg,eax 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 // 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 // 64-bit form stores upper 32 bits
if (inst.size() == 8) if (inst.size() == 8)
{ {
// 1, 2, or 4-byte case
if (spacesizep.size() != SIZE_QWORD) if (spacesizep.size() != SIZE_QWORD)
{ {
// 1, 2, or 4-byte case
if (dstp.is_memory()) 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()) 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 else
{ {
// 8-byte case
if (dstp.is_memory()) 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()) 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); Gp const dstreg = dstp.select_register(eax);
// set up a call to the read byte handler // set up a call to the read byte handler
auto const &accessors = m_memory_accessors[spacesizep.space()];
if (spacesizep.size() != SIZE_QWORD) 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 else
emit_mov_m64_p64(a, qword_ptr(esp, 8), maskp); // mov [esp+8],maskp emit_mov_m64_p64(a, qword_ptr(esp, USE_THISCALL ? 4 : 8), maskp);
emit_mov_m32_p32(a, dword_ptr(esp, 4), addrp); // mov [esp+4],addrp emit_mov_m32_p32(a, dword_ptr(esp, USE_THISCALL ? 0 : 4), addrp);
a.mov(dword_ptr(esp, 0), imm(m_space[spacesizep.space()])); // mov [esp],space
if (spacesizep.size() == SIZE_BYTE) if (spacesizep.size() == SIZE_BYTE)
{ {
a.call(imm(m_accessors[spacesizep.space()].read_byte_masked)); // call read_byte_masked if (USE_THISCALL)
a.movzx(dstreg, al); // movzx dstreg,al 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) else if (spacesizep.size() == SIZE_WORD)
{ {
a.call(imm(m_accessors[spacesizep.space()].read_word_masked)); // call read_word_masked if (USE_THISCALL)
a.movzx(dstreg, ax); // movzx dstreg,ax 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) else if (spacesizep.size() == SIZE_DWORD)
{ {
a.call(imm(m_accessors[spacesizep.space()].read_dword_masked)); // call read_dword_masked if (USE_THISCALL)
a.mov(dstreg, eax); // mov dstreg,eax 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) else if (spacesizep.size() == SIZE_QWORD)
{ {
a.call(imm(m_accessors[spacesizep.space()].read_qword_masked)); // call read_qword_masked if (USE_THISCALL)
a.mov(dstreg, eax); // mov dstreg,eax 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 // 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 // 64-bit form stores upper 32 bits
if (inst.size() == 8) if (inst.size() == 8)
{ {
// 1, 2, or 4-byte case
if (spacesizep.size() != SIZE_QWORD) if (spacesizep.size() != SIZE_QWORD)
{ {
// 1, 2, or 4-byte case
if (dstp.is_memory()) 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()) 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 else
{ {
// 8-byte case
if (dstp.is_memory()) 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()) 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()); assert(spacesizep.is_size_space());
// set up a call to the write byte handler // set up a call to the write byte handler
auto const &accessors = m_memory_accessors[spacesizep.space()];
if (spacesizep.size() != SIZE_QWORD) 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 else
emit_mov_m64_p64(a, qword_ptr(esp, 8), srcp); // mov [esp+8],srcp 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 emit_mov_m32_p32(a, dword_ptr(esp, USE_THISCALL ? 0 : 4), addrp);
a.mov(dword_ptr(esp, 0), imm(m_space[spacesizep.space()])); // mov [esp],space
if (spacesizep.size() == SIZE_BYTE) 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) 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) 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) 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()); assert(spacesizep.is_size_space());
// set up a call to the write byte handler // set up a call to the write byte handler
auto const &accessors = m_memory_accessors[spacesizep.space()];
if (spacesizep.size() != SIZE_QWORD) 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, USE_THISCALL ? 8 : 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 ? 4 : 8), srcp);
} }
else else
{ {
emit_mov_m64_p64(a, qword_ptr(esp, 16), maskp); // mov [esp+16],maskp emit_mov_m64_p64(a, qword_ptr(esp, USE_THISCALL ? 12 : 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 ? 4 : 8), srcp);
} }
emit_mov_m32_p32(a, dword_ptr(esp, 4), addrp); // mov [esp+4],addrp emit_mov_m32_p32(a, dword_ptr(esp, USE_THISCALL ? 0 : 4), addrp);
a.mov(dword_ptr(esp, 0), imm(m_space[spacesizep.space()])); // mov [esp],space
if (spacesizep.size() == SIZE_BYTE) 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) 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) 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) 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()); assert((1 << spacep.size()) == inst.size());
// set up a call to the read dword/qword handler // set up a call to the read dword/qword handler
emit_mov_m32_p32(a, dword_ptr(esp, 4), addrp); // mov [esp+4],addrp auto const &accessors = m_memory_accessors[spacep.space()];
a.mov(dword_ptr(esp, 0), imm(m_space[spacep.space()])); // mov [esp],space auto const &accessor = (inst.size() == 4) ? accessors.read_dword : accessors.read_qword;
if (inst.size() == 4) emit_mov_m32_p32(a, dword_ptr(esp, USE_THISCALL ? 0 : 4), addrp);
a.call(imm(m_accessors[spacep.space()].read_dword)); // call read_dword if (USE_THISCALL)
else if (inst.size() == 8) a.mov(ecx, imm(accessor.obj));
a.call(imm(m_accessors[spacep.space()].read_qword)); // call read_qword else
a.mov(dword_ptr(esp, 0), imm(accessor.obj));
a.call(imm(accessor.func));
if (USE_THISCALL)
a.sub(esp, 4);
// store result // store result
if (inst.size() == 4) 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) 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()); assert((1 << spacep.size()) == inst.size());
// set up a call to the write dword/qword handler // 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) 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) else if (inst.size() == 8)
emit_mov_m64_p64(a, qword_ptr(esp, 8), srcp); // mov [esp+8],srcp 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 if (USE_THISCALL)
a.mov(dword_ptr(esp, 0), imm(m_space[spacep.space()])); // mov [esp],space a.mov(ecx, imm(accessor.obj));
if (inst.size() == 4) else
a.call(imm(m_accessors[spacep.space()].write_dword)); // call write_dword a.mov(dword_ptr(esp, 0), imm(accessor.obj));
else if (inst.size() == 8) a.call(imm(accessor.func));
a.call(imm(m_accessors[spacep.space()].write_qword)); // call write_qword if (USE_THISCALL)
a.sub(esp, (inst.size() == 4) ? 8 : 12);
} }

View File

@ -291,6 +291,9 @@ private:
uint64_t m_reslo; // extended low result uint64_t m_reslo; // extended low result
uint64_t m_reshi; // extended high result uint64_t m_reshi; // extended high result
// resolved memory handler functions
resolved_memory_accessors_vector m_memory_accessors;
// globals // globals
typedef void (drcbe_x86::*opcode_generate_func)(asmjit::x86::Assembler &a, const uml::instruction &inst); typedef void (drcbe_x86::*opcode_generate_func)(asmjit::x86::Assembler &a, const uml::instruction &inst);
struct opcode_table_entry struct opcode_table_entry

View File

@ -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 */ /* allocate a timer for the compare interrupt */
m_compare_int_timer = timer_alloc(FUNC(mips3_device::compare_int_callback), this); m_compare_int_timer = timer_alloc(FUNC(mips3_device::compare_int_callback), this);
@ -1204,7 +1201,7 @@ inline bool mips3_device::RBYTE(offs_t address, uint32_t *result)
*result = m_fastram[ramnum].offset_base8[tlbaddress ^ m_byte_xor]; *result = m_fastram[ramnum].offset_base8[tlbaddress ^ m_byte_xor];
return true; return true;
} }
*result = (*m_memory.read_byte)(*m_program, tlbaddress); *result = m_program->read_byte(tlbaddress);
} }
else else
{ {
@ -1237,7 +1234,7 @@ inline bool mips3_device::RHALF(offs_t address, uint32_t *result)
*result = m_fastram[ramnum].offset_base16[(tlbaddress ^ m_word_xor) >> 1]; *result = m_fastram[ramnum].offset_base16[(tlbaddress ^ m_word_xor) >> 1];
return true; return true;
} }
*result = (*m_memory.read_word)(*m_program, tlbaddress); *result = m_program->read_word(tlbaddress);
} }
else else
{ {
@ -1270,7 +1267,7 @@ inline bool mips3_device::RWORD(offs_t address, uint32_t *result, bool insn)
*result = m_fastram[ramnum].offset_base32[(tlbaddress ^ m_dword_xor) >> 2]; *result = m_fastram[ramnum].offset_base32[(tlbaddress ^ m_dword_xor) >> 2];
return true; return true;
} }
*result = (*m_memory.read_dword)(*m_program, tlbaddress); *result = m_program->read_dword(tlbaddress);
} }
else else
{ {
@ -1293,7 +1290,7 @@ inline bool mips3_device::RWORD_MASKED(offs_t address, uint32_t *result, uint32_
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & READ_ALLOWED) 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 else
{ {
@ -1316,7 +1313,7 @@ inline bool mips3_device::RDOUBLE(offs_t address, uint64_t *result)
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & READ_ALLOWED) 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 else
{ {
@ -1339,7 +1336,7 @@ inline bool mips3_device::RDOUBLE_MASKED(offs_t address, uint64_t *result, uint6
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & READ_ALLOWED) 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 else
{ {
@ -1372,7 +1369,7 @@ inline void mips3_device::WBYTE(offs_t address, uint8_t data)
m_fastram[ramnum].offset_base8[tlbaddress ^ m_byte_xor] = data; m_fastram[ramnum].offset_base8[tlbaddress ^ m_byte_xor] = data;
return; return;
} }
(*m_memory.write_byte)(*m_program, tlbaddress, data); m_program->write_byte(tlbaddress, data);
} }
else else
{ {
@ -1406,7 +1403,7 @@ inline void mips3_device::WHALF(offs_t address, uint16_t data)
m_fastram[ramnum].offset_base16[(tlbaddress ^ m_word_xor) >> 1] = data; m_fastram[ramnum].offset_base16[(tlbaddress ^ m_word_xor) >> 1] = data;
return; return;
} }
(*m_memory.write_word)(*m_program, tlbaddress, data); m_program->write_word(tlbaddress, data);
} }
else else
{ {
@ -1440,7 +1437,7 @@ inline void mips3_device::WWORD(offs_t address, uint32_t data)
m_fastram[ramnum].offset_base32[(tlbaddress ^ m_dword_xor) >> 2] = data; m_fastram[ramnum].offset_base32[(tlbaddress ^ m_dword_xor) >> 2] = data;
return; return;
} }
(*m_memory.write_dword)(*m_program, tlbaddress, data); m_program->write_dword(tlbaddress, data);
} }
else else
{ {
@ -1464,7 +1461,7 @@ inline void mips3_device::WWORD_MASKED(offs_t address, uint32_t data, uint32_t m
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & WRITE_ALLOWED) 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 else
{ {
@ -1488,7 +1485,7 @@ inline void mips3_device::WDOUBLE(offs_t address, uint64_t data)
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & WRITE_ALLOWED) 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 else
{ {
@ -1512,7 +1509,7 @@ inline void mips3_device::WDOUBLE_MASKED(offs_t address, uint64_t data, uint64_t
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & WRITE_ALLOWED) 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 else
{ {
@ -1535,7 +1532,7 @@ inline bool r4650_device::RBYTE(offs_t address, uint32_t *result)
{ {
if ((SR & SR_KSU_USER) == SR_KSU_KERNEL) if ((SR & SR_KSU_USER) == SR_KSU_KERNEL)
{ {
*result = (*m_memory.read_byte)(*m_program, address); *result = m_program->read_byte(address);
return true; return true;
} }
@ -1545,7 +1542,7 @@ inline bool r4650_device::RBYTE(offs_t address, uint32_t *result)
*result = 0; *result = 0;
return false; 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; 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) if ((SR & SR_KSU_USER) == SR_KSU_KERNEL)
{ {
*result = (*m_memory.read_word)(*m_program, address); *result = m_program->read_word(address);
return true; return true;
} }
@ -1563,7 +1560,7 @@ inline bool r4650_device::RHALF(offs_t address, uint32_t *result)
*result = 0; *result = 0;
return false; 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; 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) if ((SR & SR_KSU_USER) == SR_KSU_KERNEL)
{ {
*result = (*m_memory.read_dword)(*m_program, address); *result = m_program->read_dword(address);
return true; return true;
} }
@ -1585,7 +1582,7 @@ inline bool r4650_device::RWORD(offs_t address, uint32_t *result, bool insn)
*result = 0; *result = 0;
return false; return false;
} }
*result = (*m_memory.read_dword)(*m_program, address + base); *result = m_program->read_dword(address + base);
return true; 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) 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; return true;
} }
@ -1603,7 +1600,7 @@ inline bool r4650_device::RWORD_MASKED(offs_t address, uint32_t *result, uint32_
*result = 0; *result = 0;
return false; 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; 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) if ((SR & SR_KSU_USER) == SR_KSU_KERNEL)
{ {
*result = (*m_memory.read_qword)(*m_program, address); *result = m_program->read_qword(address);
return true; return true;
} }
@ -1621,7 +1618,7 @@ inline bool r4650_device::RDOUBLE(offs_t address, uint64_t *result)
*result = 0; *result = 0;
return false; 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; 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) 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; return true;
} }
@ -1639,102 +1636,103 @@ inline bool r4650_device::RDOUBLE_MASKED(offs_t address, uint64_t *result, uint6
*result = 0; *result = 0;
return false; 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; return true;
} }
inline void r4650_device::WBYTE(offs_t address, uint8_t data) inline void r4650_device::WBYTE(offs_t address, uint8_t data)
{ {
if ((SR & SR_KSU_USER) == SR_KSU_KERNEL) 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]) else if ((address & 0xfffff000) > m_core->cpr[0][COP0_R4650_DBound])
generate_tlb_exception(EXCEPTION_ADDRSTORE, address); generate_tlb_exception(EXCEPTION_ADDRSTORE, address);
else 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) inline void r4650_device::WHALF(offs_t address, uint16_t data)
{ {
if ((SR & SR_KSU_USER) == SR_KSU_KERNEL) 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]) else if ((address & 0xfffff000) > m_core->cpr[0][COP0_R4650_DBound])
generate_tlb_exception(EXCEPTION_ADDRSTORE, address); generate_tlb_exception(EXCEPTION_ADDRSTORE, address);
else 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) inline void r4650_device::WWORD(offs_t address, uint32_t data)
{ {
if ((SR & SR_KSU_USER) == SR_KSU_KERNEL) 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]) else if ((address & 0xfffff000) > m_core->cpr[0][COP0_R4650_DBound])
generate_tlb_exception(EXCEPTION_ADDRSTORE, address); generate_tlb_exception(EXCEPTION_ADDRSTORE, address);
else 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) inline void r4650_device::WWORD_MASKED(offs_t address, uint32_t data, uint32_t mem_mask)
{ {
if ((SR & SR_KSU_USER) == SR_KSU_KERNEL) 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]) else if ((address & 0xfffff000) > m_core->cpr[0][COP0_R4650_DBound])
generate_tlb_exception(EXCEPTION_ADDRSTORE, address); generate_tlb_exception(EXCEPTION_ADDRSTORE, address);
else 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) inline void r4650_device::WDOUBLE(offs_t address, uint64_t data)
{ {
if ((SR & SR_KSU_USER) == SR_KSU_KERNEL) 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]) else if ((address & 0xfffff000) > m_core->cpr[0][COP0_R4650_DBound])
generate_tlb_exception(EXCEPTION_ADDRSTORE, address); generate_tlb_exception(EXCEPTION_ADDRSTORE, address);
else 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) inline void r4650_device::WDOUBLE_MASKED(offs_t address, uint64_t data, uint64_t mem_mask)
{ {
if ((SR & SR_KSU_USER) == SR_KSU_KERNEL) 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]) else if ((address & 0xfffff000) > m_core->cpr[0][COP0_R4650_DBound])
generate_tlb_exception(EXCEPTION_ADDRSTORE, address); generate_tlb_exception(EXCEPTION_ADDRSTORE, address);
else 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) 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); else mips3_device::WBYTE(address, data);
} }
inline void r5900_device::WHALF(offs_t address, uint16_t 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); else mips3_device::WHALF(address, data);
} }
inline void r5900_device::WWORD(offs_t address, uint32_t 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); else mips3_device::WWORD(address, data);
} }
inline void r5900_device::WWORD_MASKED(offs_t address, uint32_t data, uint32_t mem_mask) 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); else mips3_device::WWORD_MASKED(address, data, mem_mask);
} }
inline void r5900_device::WDOUBLE(offs_t address, uint64_t data) { inline void r5900_device::WDOUBLE(offs_t address, uint64_t data)
if (address >= 0x70000000 && address < 0x70004000) (*m_memory.write_qword)(*m_program, address, data); {
if (address >= 0x70000000 && address < 0x70004000) m_program->write_qword(address, data);
else mips3_device::WDOUBLE(address, data); else mips3_device::WDOUBLE(address, data);
} }
inline void r5900_device::WDOUBLE_MASKED(offs_t address, uint64_t data, uint64_t mem_mask) 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); else mips3_device::WDOUBLE_MASKED(address, data, mem_mask);
} }
@ -1742,16 +1740,16 @@ inline void r5900le_device::WQUAD(offs_t address, uint64_t data_hi, uint64_t dat
{ {
if (address >= 0x70000000 && address < 0x70004000) if (address >= 0x70000000 && address < 0x70004000)
{ {
(*m_memory.write_qword)(*m_program, address, data_lo); m_program->write_qword(address, data_lo);
(*m_memory.write_qword)(*m_program, address + 8, data_hi); m_program->write_qword(address + 8, data_hi);
return; return;
} }
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & WRITE_ALLOWED) if (tlbval & WRITE_ALLOWED)
{ {
(*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data_lo); m_program->write_qword((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 + 8) & 0xfff), data_hi);
} }
else else
{ {
@ -1774,16 +1772,16 @@ inline void r5900be_device::WQUAD(offs_t address, uint64_t data_hi, uint64_t dat
{ {
if (address >= 0x70000000 && address < 0x70004000) if (address >= 0x70000000 && address < 0x70004000)
{ {
(*m_memory.write_qword)(*m_program, address, data_hi); m_program->write_qword(address, data_hi);
(*m_memory.write_qword)(*m_program, address + 8, data_lo); m_program->write_qword(address + 8, data_lo);
return; return;
} }
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & WRITE_ALLOWED) if (tlbval & WRITE_ALLOWED)
{ {
(*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data_hi); m_program->write_qword((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 + 8) & 0xfff), data_lo);
} }
else else
{ {
@ -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) { inline bool r5900_device::RBYTE(offs_t address, uint32_t *result)
if (address >= 0x70000000 && address < 0x70004000) { {
*result = (*m_memory.read_byte)(*m_program, address); if (address >= 0x70000000 && address < 0x70004000)
{
*result = m_program->read_byte(address);
return true; return true;
} }
return mips3_device::RBYTE(address, result); 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) if (address >= 0x70000000 && address < 0x70004000)
{ {
*result = (*m_memory.read_word)(*m_program, address); *result = m_program->read_word(address);
return true; return true;
} }
return mips3_device::RHALF(address, result); 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) if (address >= 0x70000000 && address < 0x70004000)
{ {
*result = (*m_memory.read_dword)(*m_program, address); *result = m_program->read_dword(address);
return true; return true;
} }
return mips3_device::RWORD(address, result, insn); 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) 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 true;
} }
return mips3_device::RWORD_MASKED(address, result, mem_mask); 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) if (address >= 0x70000000 && address < 0x70004000)
{ {
*result = (*m_memory.read_qword)(*m_program, address); *result = m_program->read_qword(address);
return true; return true;
} }
return mips3_device::RDOUBLE(address, result); 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) 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 true;
} }
return mips3_device::RDOUBLE_MASKED(address, result, mem_mask); return mips3_device::RDOUBLE_MASKED(address, result, mem_mask);
@ -1864,16 +1864,16 @@ inline bool r5900le_device::RQUAD(offs_t address, uint64_t *result_hi, uint64_t
{ {
if (address >= 0x70000000 && address < 0x70004000) if (address >= 0x70000000 && address < 0x70004000)
{ {
*result_lo = (*m_memory.read_qword)(*m_program, address); *result_lo = m_program->read_qword(address);
*result_hi = (*m_memory.read_qword)(*m_program, address + 8); *result_hi = m_program->read_qword(address + 8);
return true; return true;
} }
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & READ_ALLOWED) if (tlbval & READ_ALLOWED)
{ {
*result_lo = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff)); *result_lo = m_program->read_qword((tlbval & ~0xfff) | (address & 0xfff));
*result_hi = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | ((address + 8) & 0xfff)); *result_hi = m_program->read_qword((tlbval & ~0xfff) | ((address + 8) & 0xfff));
} }
else else
{ {
@ -1896,16 +1896,16 @@ inline bool r5900be_device::RQUAD(offs_t address, uint64_t *result_hi, uint64_t
{ {
if (address >= 0x70000000 && address < 0x70004000) if (address >= 0x70000000 && address < 0x70004000)
{ {
*result_hi = (*m_memory.read_qword)(*m_program, address); *result_hi = m_program->read_qword(address);
*result_lo = (*m_memory.read_qword)(*m_program, address + 8); *result_lo = m_program->read_qword(address + 8);
return true; return true;
} }
const uint32_t tlbval = vtlb_table()[address >> 12]; const uint32_t tlbval = vtlb_table()[address >> 12];
if (tlbval & READ_ALLOWED) if (tlbval & READ_ALLOWED)
{ {
*result_hi = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff)); *result_hi = m_program->read_qword((tlbval & ~0xfff) | (address & 0xfff));
*result_lo = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | ((address + 8) & 0xfff)); *result_lo = m_program->read_qword((tlbval & ~0xfff) | ((address + 8) & 0xfff));
} }
else else
{ {
@ -2255,25 +2255,31 @@ void mips3_device::handle_cop1_fr0(uint32_t op)
break; break;
case 0x03: case 0x03:
if (IS_SINGLE(op)) { /* DIV.S */ if (IS_SINGLE(op)) /* DIV.S */
if (FTVALW_FR0 == 0 && (COP1_FCR31 & (1 << (FCR31_ENABLE + FPE_DIV0)))) { {
if (FTVALW_FR0 == 0 && (COP1_FCR31 & (1 << (FCR31_ENABLE + FPE_DIV0))))
{
COP1_FCR31 |= (1 << (FCR31_FLAGS + FPE_DIV0)); // Set flag COP1_FCR31 |= (1 << (FCR31_FLAGS + FPE_DIV0)); // Set flag
COP1_FCR31 |= (1 << (FCR31_CAUSE + FPE_DIV0)); // Set cause COP1_FCR31 |= (1 << (FCR31_CAUSE + FPE_DIV0)); // Set cause
generate_exception(EXCEPTION_FPE, 1); generate_exception(EXCEPTION_FPE, 1);
//machine().debug_break(); //machine().debug_break();
} }
else { else
{
FDVALS_FR0 = FSVALS_FR0 / FTVALS_FR0; FDVALS_FR0 = FSVALS_FR0 / FTVALS_FR0;
} }
} }
else { /* DIV.D */ else /* DIV.D */
if (FTVALL_FR0 == 0ull && (COP1_FCR31 & (1 << (FCR31_ENABLE + FPE_DIV0)))) { {
if (FTVALL_FR0 == 0ull && (COP1_FCR31 & (1 << (FCR31_ENABLE + FPE_DIV0))))
{
COP1_FCR31 |= (1 << (FCR31_FLAGS + FPE_DIV0)); // Set flag COP1_FCR31 |= (1 << (FCR31_FLAGS + FPE_DIV0)); // Set flag
COP1_FCR31 |= (1 << (FCR31_CAUSE + FPE_DIV0)); // Set cause COP1_FCR31 |= (1 << (FCR31_CAUSE + FPE_DIV0)); // Set cause
generate_exception(EXCEPTION_FPE, 1); generate_exception(EXCEPTION_FPE, 1);
//machine().debug_break(); //machine().debug_break();
} }
else { else
{
FDVALD_FR0 = FSVALD_FR0 / FTVALD_FR0; FDVALD_FR0 = FSVALD_FR0 / FTVALD_FR0;
} }
} }

View File

@ -448,7 +448,6 @@ protected:
uint32_t m_byte_xor; uint32_t m_byte_xor;
uint32_t m_word_xor; uint32_t m_word_xor;
uint32_t m_dword_xor; uint32_t m_dword_xor;
data_accessors m_memory;
/* cache memory */ /* cache memory */
size_t c_icache_size; size_t c_icache_size;