mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 19:17:44 +00:00
UserspaceEmulator: Add a fast path for forward REP STOSD
Same as REP STOSB, except for 32-bit fills instead.
This commit is contained in:
parent
102e1d330c
commit
6dab0af9af
3 changed files with 43 additions and 1 deletions
|
@ -3072,6 +3072,22 @@ void SoftCPU::STOSB(const X86::Instruction& insn)
|
||||||
|
|
||||||
void SoftCPU::STOSD(const X86::Instruction& insn)
|
void SoftCPU::STOSD(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
|
if (insn.has_rep_prefix() && !df()) {
|
||||||
|
// Fast path for 32-bit forward memory fill.
|
||||||
|
if (m_emulator.mmu().fast_fill_memory32({ es(), destination_index(insn.a32()).value() }, ecx().value(), eax())) {
|
||||||
|
if (insn.a32()) {
|
||||||
|
// FIXME: Should an uninitialized ECX taint EDI here?
|
||||||
|
set_edi({ (u32)(edi().value() + (ecx().value() * sizeof(u32))), edi().shadow() });
|
||||||
|
set_ecx(shadow_wrap_as_initialized<u32>(0));
|
||||||
|
} else {
|
||||||
|
// FIXME: Should an uninitialized CX taint DI here?
|
||||||
|
set_di({ (u16)(di().value() + (cx().value() * sizeof(u32))), di().shadow() });
|
||||||
|
set_cx(shadow_wrap_as_initialized<u16>(0));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
do_once_or_repeat<false>(insn, [&] {
|
do_once_or_repeat<false>(insn, [&] {
|
||||||
write_memory32({ es(), destination_index(insn.a32()).value() }, eax());
|
write_memory32({ es(), destination_index(insn.a32()).value() }, eax());
|
||||||
step_destination_index(insn.a32(), 4);
|
step_destination_index(insn.a32(), 4);
|
||||||
|
|
|
@ -259,7 +259,7 @@ bool SoftMMU::fast_fill_memory8(X86::LogicalAddress address, size_t size, ValueW
|
||||||
if (region->is_mmap() && static_cast<const MmapRegion&>(*region).is_malloc_block()) {
|
if (region->is_mmap() && static_cast<const MmapRegion&>(*region).is_malloc_block()) {
|
||||||
if (auto* tracer = Emulator::the().malloc_tracer()) {
|
if (auto* tracer = Emulator::the().malloc_tracer()) {
|
||||||
// FIXME: Add a way to audit an entire range of memory instead of looping here!
|
// FIXME: Add a way to audit an entire range of memory instead of looping here!
|
||||||
for (size_t i = 0; i < size; i += sizeof(u8)) {
|
for (size_t i = 0; i < size; ++i) {
|
||||||
tracer->audit_write(address.offset() + (i * sizeof(u8)), sizeof(u8));
|
tracer->audit_write(address.offset() + (i * sizeof(u8)), sizeof(u8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,4 +271,29 @@ bool SoftMMU::fast_fill_memory8(X86::LogicalAddress address, size_t size, ValueW
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SoftMMU::fast_fill_memory32(X86::LogicalAddress address, size_t count, ValueWithShadow<u32> value)
|
||||||
|
{
|
||||||
|
if (!count)
|
||||||
|
return true;
|
||||||
|
auto* region = find_region(address);
|
||||||
|
if (!region)
|
||||||
|
return false;
|
||||||
|
if (!region->contains(address.offset() + (count * sizeof(u32)) - 1))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (region->is_mmap() && static_cast<const MmapRegion&>(*region).is_malloc_block()) {
|
||||||
|
if (auto* tracer = Emulator::the().malloc_tracer()) {
|
||||||
|
// FIXME: Add a way to audit an entire range of memory instead of looping here!
|
||||||
|
for (size_t i = 0; i < count; ++i) {
|
||||||
|
tracer->audit_write(address.offset() + (i * sizeof(u32)), sizeof(u32));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t offset_in_region = address.offset() - region->base();
|
||||||
|
fast_u32_fill((u32*)(region->data() + offset_in_region), value.value(), count);
|
||||||
|
fast_u32_fill((u32*)(region->shadow_data() + offset_in_region), value.shadow(), count);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,6 +109,7 @@ public:
|
||||||
void set_tls_region(NonnullOwnPtr<Region>);
|
void set_tls_region(NonnullOwnPtr<Region>);
|
||||||
|
|
||||||
bool fast_fill_memory8(X86::LogicalAddress, size_t size, ValueWithShadow<u8>);
|
bool fast_fill_memory8(X86::LogicalAddress, size_t size, ValueWithShadow<u8>);
|
||||||
|
bool fast_fill_memory32(X86::LogicalAddress, size_t size, ValueWithShadow<u32>);
|
||||||
|
|
||||||
void copy_to_vm(FlatPtr destination, const void* source, size_t);
|
void copy_to_vm(FlatPtr destination, const void* source, size_t);
|
||||||
void copy_from_vm(void* destination, const FlatPtr source, size_t);
|
void copy_from_vm(void* destination, const FlatPtr source, size_t);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue