Skip to content

Commit be02455

Browse files
committed
cpu/drcbearm64.cpp: Added scaffolding for directly dispatching memory accesses.
1 parent b7a80b1 commit be02455

File tree

3 files changed

+72
-62
lines changed

3 files changed

+72
-62
lines changed

src/devices/cpu/drcbearm64.cpp

Lines changed: 51 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -974,11 +974,14 @@ drcbe_arm64::drcbe_arm64(drcuml_state &drcuml, device_t &device, drc_cache &cach
974974
m_drcmap_get_value.set(m_map, &drc_map_variables::get_value);
975975
if (!m_drcmap_get_value)
976976
throw emu_fatalerror("Error resolving map variable get value function!\n");
977-
m_resolved_accessors.resize(m_space.size());
977+
m_memory_accessors.resize(m_space.size());
978978
for (int space = 0; m_space.size() > space; ++space)
979979
{
980980
if (m_space[space])
981-
m_resolved_accessors[space].set(*m_space[space]);
981+
{
982+
m_memory_accessors[space].resolved.set(*m_space[space]);
983+
m_memory_accessors[space].specific = m_space[space]->specific_accessors();
984+
}
982985
}
983986
}
984987

@@ -2046,29 +2049,29 @@ void drcbe_arm64::op_read(a64::Assembler &a, const uml::instruction &inst)
20462049
const parameter &spacesizep = inst.param(2);
20472050
assert(spacesizep.is_size_space());
20482051

2049-
const auto &resolved = m_resolved_accessors[spacesizep.space()];
2052+
auto const &accessors = m_memory_accessors[spacesizep.space()];
20502053

20512054
mov_reg_param(a, 4, REG_PARAM2, addrp);
20522055

20532056
if (spacesizep.size() == SIZE_BYTE)
20542057
{
2055-
get_imm_relative(a, REG_PARAM1, resolved.read_byte.obj);
2056-
call_arm_addr(a, resolved.read_byte.func);
2058+
get_imm_relative(a, REG_PARAM1, accessors.resolved.read_byte.obj);
2059+
call_arm_addr(a, accessors.resolved.read_byte.func);
20572060
}
20582061
else if (spacesizep.size() == SIZE_WORD)
20592062
{
2060-
get_imm_relative(a, REG_PARAM1, resolved.read_word.obj);
2061-
call_arm_addr(a, resolved.read_word.func);
2063+
get_imm_relative(a, REG_PARAM1, accessors.resolved.read_word.obj);
2064+
call_arm_addr(a, accessors.resolved.read_word.func);
20622065
}
20632066
else if (spacesizep.size() == SIZE_DWORD)
20642067
{
2065-
get_imm_relative(a, REG_PARAM1, resolved.read_dword.obj);
2066-
call_arm_addr(a, resolved.read_dword.func);
2068+
get_imm_relative(a, REG_PARAM1, accessors.resolved.read_dword.obj);
2069+
call_arm_addr(a, accessors.resolved.read_dword.func);
20672070
}
20682071
else if (spacesizep.size() == SIZE_QWORD)
20692072
{
2070-
get_imm_relative(a, REG_PARAM1, resolved.read_qword.obj);
2071-
call_arm_addr(a, resolved.read_qword.func);
2073+
get_imm_relative(a, REG_PARAM1, accessors.resolved.read_qword.obj);
2074+
call_arm_addr(a, accessors.resolved.read_qword.func);
20722075
}
20732076

20742077
mov_param_reg(a, inst.size(), dstp, REG_PARAM1);
@@ -2086,30 +2089,30 @@ void drcbe_arm64::op_readm(a64::Assembler &a, const uml::instruction &inst)
20862089
const parameter &spacesizep = inst.param(3);
20872090
assert(spacesizep.is_size_space());
20882091

2089-
const auto &resolved = m_resolved_accessors[spacesizep.space()];
2092+
auto const &accessors = m_memory_accessors[spacesizep.space()];
20902093

20912094
mov_reg_param(a, 4, REG_PARAM2, addrp);
20922095
mov_reg_param(a, inst.size(), REG_PARAM3, maskp);
20932096

20942097
if (spacesizep.size() == SIZE_BYTE)
20952098
{
2096-
get_imm_relative(a, REG_PARAM1, resolved.read_byte_masked.obj);
2097-
call_arm_addr(a, resolved.read_byte_masked.func);
2099+
get_imm_relative(a, REG_PARAM1, accessors.resolved.read_byte_masked.obj);
2100+
call_arm_addr(a, accessors.resolved.read_byte_masked.func);
20982101
}
20992102
else if (spacesizep.size() == SIZE_WORD)
21002103
{
2101-
get_imm_relative(a, REG_PARAM1, resolved.read_word_masked.obj);
2102-
call_arm_addr(a, resolved.read_word_masked.func);
2104+
get_imm_relative(a, REG_PARAM1, accessors.resolved.read_word_masked.obj);
2105+
call_arm_addr(a, accessors.resolved.read_word_masked.func);
21032106
}
21042107
else if (spacesizep.size() == SIZE_DWORD)
21052108
{
2106-
get_imm_relative(a, REG_PARAM1, resolved.read_dword_masked.obj);
2107-
call_arm_addr(a, resolved.read_dword_masked.func);
2109+
get_imm_relative(a, REG_PARAM1, accessors.resolved.read_dword_masked.obj);
2110+
call_arm_addr(a, accessors.resolved.read_dword_masked.func);
21082111
}
21092112
else if (spacesizep.size() == SIZE_QWORD)
21102113
{
2111-
get_imm_relative(a, REG_PARAM1, resolved.read_qword_masked.obj);
2112-
call_arm_addr(a, resolved.read_qword_masked.func);
2114+
get_imm_relative(a, REG_PARAM1, accessors.resolved.read_qword_masked.obj);
2115+
call_arm_addr(a, accessors.resolved.read_qword_masked.func);
21132116
}
21142117

21152118
mov_param_reg(a, inst.size(), dstp, REG_PARAM1);
@@ -2126,30 +2129,30 @@ void drcbe_arm64::op_write(a64::Assembler &a, const uml::instruction &inst)
21262129
const parameter &spacesizep = inst.param(2);
21272130
assert(spacesizep.is_size_space());
21282131

2129-
const auto &resolved = m_resolved_accessors[spacesizep.space()];
2132+
auto const &accessors = m_memory_accessors[spacesizep.space()];
21302133

21312134
mov_reg_param(a, 4, REG_PARAM2, addrp);
21322135
mov_reg_param(a, inst.size(), REG_PARAM3, srcp);
21332136

21342137
if (spacesizep.size() == SIZE_BYTE)
21352138
{
2136-
get_imm_relative(a, REG_PARAM1, resolved.write_byte.obj);
2137-
call_arm_addr(a, resolved.write_byte.func);
2139+
get_imm_relative(a, REG_PARAM1, accessors.resolved.write_byte.obj);
2140+
call_arm_addr(a, accessors.resolved.write_byte.func);
21382141
}
21392142
else if (spacesizep.size() == SIZE_WORD)
21402143
{
2141-
get_imm_relative(a, REG_PARAM1, resolved.write_word.obj);
2142-
call_arm_addr(a, resolved.write_word.func);
2144+
get_imm_relative(a, REG_PARAM1, accessors.resolved.write_word.obj);
2145+
call_arm_addr(a, accessors.resolved.write_word.func);
21432146
}
21442147
else if (spacesizep.size() == SIZE_DWORD)
21452148
{
2146-
get_imm_relative(a, REG_PARAM1, resolved.write_dword.obj);
2147-
call_arm_addr(a, resolved.write_dword.func);
2149+
get_imm_relative(a, REG_PARAM1, accessors.resolved.write_dword.obj);
2150+
call_arm_addr(a, accessors.resolved.write_dword.func);
21482151
}
21492152
else if (spacesizep.size() == SIZE_QWORD)
21502153
{
2151-
get_imm_relative(a, REG_PARAM1, resolved.write_qword.obj);
2152-
call_arm_addr(a, resolved.write_qword.func);
2154+
get_imm_relative(a, REG_PARAM1, accessors.resolved.write_qword.obj);
2155+
call_arm_addr(a, accessors.resolved.write_qword.func);
21532156
}
21542157
}
21552158

@@ -2166,31 +2169,31 @@ void drcbe_arm64::op_writem(a64::Assembler &a, const uml::instruction &inst)
21662169
assert(spacesizep.is_size_space());
21672170

21682171
// set up a call to the write handler
2169-
const auto &resolved = m_resolved_accessors[spacesizep.space()];
2172+
auto const &accessors = m_memory_accessors[spacesizep.space()];
21702173

21712174
mov_reg_param(a, 4, REG_PARAM2, addrp);
21722175
mov_reg_param(a, inst.size(), REG_PARAM3, srcp);
21732176
mov_reg_param(a, inst.size(), REG_PARAM4, maskp);
21742177

21752178
if (spacesizep.size() == SIZE_BYTE)
21762179
{
2177-
get_imm_relative(a, REG_PARAM1, resolved.write_byte_masked.obj);
2178-
call_arm_addr(a, resolved.write_byte_masked.func);
2180+
get_imm_relative(a, REG_PARAM1, accessors.resolved.write_byte_masked.obj);
2181+
call_arm_addr(a, accessors.resolved.write_byte_masked.func);
21792182
}
21802183
else if (spacesizep.size() == SIZE_WORD)
21812184
{
2182-
get_imm_relative(a, REG_PARAM1, resolved.write_word_masked.obj);
2183-
call_arm_addr(a, resolved.write_word_masked.func);
2185+
get_imm_relative(a, REG_PARAM1, accessors.resolved.write_word_masked.obj);
2186+
call_arm_addr(a, accessors.resolved.write_word_masked.func);
21842187
}
21852188
else if (spacesizep.size() == SIZE_DWORD)
21862189
{
2187-
get_imm_relative(a, REG_PARAM1, resolved.write_dword_masked.obj);
2188-
call_arm_addr(a, resolved.write_dword_masked.func);
2190+
get_imm_relative(a, REG_PARAM1, accessors.resolved.write_dword_masked.obj);
2191+
call_arm_addr(a, accessors.resolved.write_dword_masked.func);
21892192
}
21902193
else if (spacesizep.size() == SIZE_QWORD)
21912194
{
2192-
get_imm_relative(a, REG_PARAM1, resolved.write_qword_masked.obj);
2193-
call_arm_addr(a, resolved.write_qword_masked.func);
2195+
get_imm_relative(a, REG_PARAM1, accessors.resolved.write_qword_masked.obj);
2196+
call_arm_addr(a, accessors.resolved.write_qword_masked.func);
21942197
}
21952198
}
21962199

@@ -3768,21 +3771,21 @@ void drcbe_arm64::op_fread(a64::Assembler &a, const uml::instruction &inst)
37683771
assert(spacesizep.is_size_space());
37693772
assert((1 << spacesizep.size()) == inst.size());
37703773

3771-
const auto &resolved = m_resolved_accessors[spacesizep.space()];
3774+
auto const &accessors = m_memory_accessors[spacesizep.space()];
37723775

37733776
mov_reg_param(a, 4, REG_PARAM2, addrp);
37743777

37753778
if (inst.size() == 4)
37763779
{
3777-
get_imm_relative(a, REG_PARAM1, resolved.read_dword.obj);
3778-
call_arm_addr(a, resolved.read_dword.func);
3780+
get_imm_relative(a, REG_PARAM1, accessors.resolved.read_dword.obj);
3781+
call_arm_addr(a, accessors.resolved.read_dword.func);
37793782

37803783
mov_float_param_int_reg(a, inst.size(), dstp, REG_PARAM1.w());
37813784
}
37823785
else if (inst.size() == 8)
37833786
{
3784-
get_imm_relative(a, REG_PARAM1, resolved.read_qword.obj);
3785-
call_arm_addr(a, resolved.read_qword.func);
3787+
get_imm_relative(a, REG_PARAM1, accessors.resolved.read_qword.obj);
3788+
call_arm_addr(a, accessors.resolved.read_qword.func);
37863789

37873790
mov_float_param_int_reg(a, inst.size(), dstp, REG_PARAM1);
37883791
}
@@ -3800,7 +3803,7 @@ void drcbe_arm64::op_fwrite(a64::Assembler &a, const uml::instruction &inst)
38003803
assert(spacesizep.is_size_space());
38013804
assert((1 << spacesizep.size()) == inst.size());
38023805

3803-
const auto &resolved = m_resolved_accessors[spacesizep.space()];
3806+
auto const &accessors = m_memory_accessors[spacesizep.space()];
38043807

38053808
mov_reg_param(a, 4, REG_PARAM2, addrp);
38063809
mov_float_reg_param(a, inst.size(), TEMPF_REG1, srcp);
@@ -3809,13 +3812,13 @@ void drcbe_arm64::op_fwrite(a64::Assembler &a, const uml::instruction &inst)
38093812

38103813
if (inst.size() == 4)
38113814
{
3812-
get_imm_relative(a, REG_PARAM1, resolved.write_dword.obj);
3813-
call_arm_addr(a, resolved.write_dword.func);
3815+
get_imm_relative(a, REG_PARAM1, accessors.resolved.write_dword.obj);
3816+
call_arm_addr(a, accessors.resolved.write_dword.func);
38143817
}
38153818
else if (inst.size() == 8)
38163819
{
3817-
get_imm_relative(a, REG_PARAM1, resolved.write_qword.obj);
3818-
call_arm_addr(a, resolved.write_qword.func);
3820+
get_imm_relative(a, REG_PARAM1, accessors.resolved.write_qword.obj);
3821+
call_arm_addr(a, accessors.resolved.write_qword.func);
38193822
}
38203823
}
38213824

src/devices/cpu/drcbearm64.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,14 @@ class drcbe_arm64 : public drcbe_interface
238238
static const opcode_table_entry s_opcode_table_source[];
239239
static opcode_generate_func s_opcode_table[uml::OP_MAX];
240240

241+
struct memory_accessors
242+
{
243+
resolved_memory_accessors resolved;
244+
address_space::specific_access_info specific;
245+
};
241246
resolved_member_function m_debug_cpu_instruction_hook;
242247
resolved_member_function m_drcmap_get_value;
243-
resolved_memory_accessors_vector m_resolved_accessors;
248+
std::vector<memory_accessors> m_memory_accessors;
244249
};
245250

246251
} // namespace drc

src/devices/cpu/drcbex64.cpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2587,14 +2587,18 @@ void drcbe_x64::op_read(Assembler &a, const instruction &inst)
25872587
a.mov(r10d, Gpd(REG_PARAM2)); // copy masked address
25882588
a.shr(Gpd(REG_PARAM2), accessors.specific.low_bits); // shift off low bits
25892589
}
2590-
a.and_(ecx, imm((accessors.specific.native_bytes - (1 << spacesizep.size())) << 3)); // mask bit address
25912590
a.mov(rax, ptr(rax, Gpq(REG_PARAM2), 3)); // load dispatch table entry
2591+
a.and_(ecx, imm((accessors.specific.native_bytes - (1 << spacesizep.size())) << 3)); // mask bit address
25922592
if (accessors.specific.low_bits)
25932593
a.mov(Gpd(REG_PARAM2), r10d); // restore masked address
25942594
if (need_save)
25952595
a.mov(Gpd(int_register_map[0]), ecx); // save masked bit address
25962596
else
25972597
a.mov(dstreg.r32(), ecx); // save masked bit address
2598+
if (accessors.specific.read.is_virtual)
2599+
a.mov(r10, ptr(rax, accessors.specific.read.displacement)); // load vtable pointer
2600+
if (accessors.specific.read.displacement)
2601+
a.add(rax, accessors.specific.read.displacement); // apply this pointer offset
25982602
if (accessors.specific.native_bytes <= 4)
25992603
a.shl(Gpd(REG_PARAM3), cl); // shift mem_mask by masked bit address
26002604
else
@@ -2603,11 +2607,7 @@ void drcbe_x64::op_read(Assembler &a, const instruction &inst)
26032607
// need to do this after finished with CL as REG_PARAM1 is C on Windows
26042608
a.mov(Gpq(REG_PARAM1), rax);
26052609
if (accessors.specific.read.is_virtual)
2606-
a.mov(rax, ptr(rax, accessors.specific.read.displacement)); // load vtable pointer
2607-
if (accessors.specific.read.displacement)
2608-
a.add(Gpq(REG_PARAM1), accessors.specific.read.displacement); // apply this pointer offset
2609-
if (accessors.specific.read.is_virtual)
2610-
a.call(ptr(rax, accessors.specific.read.function)); // call virtual member function
2610+
a.call(ptr(r10, accessors.specific.read.function)); // call virtual member function
26112611
else
26122612
smart_call_r64(a, (x86code *)accessors.specific.read.function, rax); // call non-virtual member function
26132613

@@ -3041,31 +3041,33 @@ void drcbe_x64::op_writem(Assembler &a, const instruction &inst)
30413041
a.mov(r10d, Gpd(REG_PARAM2)); // copy masked address
30423042
a.shr(Gpd(REG_PARAM2), accessors.specific.low_bits); // shift off low bits
30433043
}
3044-
a.and_(ecx, imm((accessors.specific.native_bytes - (1 << spacesizep.size())) << 3)); // mask bit address
30453044
a.mov(rax, ptr(rax, Gpq(REG_PARAM2), 3)); // load dispatch table entry
3045+
a.and_(ecx, imm((accessors.specific.native_bytes - (1 << spacesizep.size())) << 3)); // mask bit address
30463046
if (accessors.specific.low_bits)
30473047
a.mov(Gpd(REG_PARAM2), r10d); // restore masked address
30483048
if (accessors.specific.native_bytes <= 4)
30493049
{
30503050
a.shl(r11d, cl); // shift mem_mask by masked bit address
30513051
a.shl(Gpd(REG_PARAM3), cl); // shift data by masked bit address
3052-
a.mov(Gpd(REG_PARAM4), r11d); // copy mem_mask to parameter 4 (ECX on SysV)
30533052
}
30543053
else
30553054
{
30563055
a.shl(r11, cl); // shift mem_mask by masked bit address
30573056
a.shl(Gpq(REG_PARAM3), cl); // shift data by masked bit address
3058-
a.mov(Gpq(REG_PARAM4), r11); // copy mem_mask to parameter 4 (RCX on SysV)
30593057
}
3058+
if (accessors.specific.write.is_virtual)
3059+
a.mov(r10, ptr(rax, accessors.specific.write.displacement)); // load vtable pointer
30603060

3061-
// need to do this after finished with CL as REG_PARAM1 is C on Windows
3061+
// need to do this after finished with CL as REG_PARAM1 is C on Windows and REG_PARAM4 is C on SysV
30623062
a.mov(Gpq(REG_PARAM1), rax);
3063-
if (accessors.specific.write.is_virtual)
3064-
a.mov(rax, ptr(rax, accessors.specific.write.displacement)); // load vtable pointer
3063+
if (accessors.specific.native_bytes <= 4)
3064+
a.mov(Gpd(REG_PARAM4), r11d); // copy mem_mask to parameter 4 (ECX on SysV)
3065+
else
3066+
a.mov(Gpq(REG_PARAM4), r11); // copy mem_mask to parameter 4 (RCX on SysV)
30653067
if (accessors.specific.write.displacement)
30663068
a.add(Gpq(REG_PARAM1), accessors.specific.write.displacement); // apply this pointer offset
30673069
if (accessors.specific.write.is_virtual)
3068-
a.call(ptr(rax, accessors.specific.write.function)); // call virtual member function
3070+
a.call(ptr(r10, accessors.specific.write.function)); // call virtual member function
30693071
else
30703072
smart_call_r64(a, (x86code *)accessors.specific.write.function, rax); // call non-virtual member function
30713073
}

0 commit comments

Comments
 (0)