Implement perfmap

This commit is contained in:
MerryMage
2018-07-27 12:42:10 +01:00
parent f73104633b
commit de4494ffa5
10 changed files with 184 additions and 12 deletions

View File

@@ -7,6 +7,7 @@
#include <initializer_list>
#include <dynarmic/A64/exclusive_monitor.h>
#include <fmt/format.h>
#include <fmt/ostream.h>
#include "backend/x64/a64_emit_x64.h"
@@ -15,6 +16,7 @@
#include "backend/x64/block_of_code.h"
#include "backend/x64/devirtualize.h"
#include "backend/x64/emit_x64.h"
#include "backend/x64/perf_map.h"
#include "common/address_range.h"
#include "common/assert.h"
#include "common/bit_util.h"
@@ -118,17 +120,15 @@ A64EmitX64::BlockDescriptor A64EmitX64::Emit(IR::Block& block) {
EmitX64::EmitTerminal(block.GetTerminal(), block.Location());
code.int3();
const A64::LocationDescriptor descriptor{block.Location()};
Patch(descriptor, entrypoint);
const size_t size = static_cast<size_t>(code.getCurr() - entrypoint);
const A64::LocationDescriptor descriptor{block.Location()};
const A64::LocationDescriptor end_location{block.EndLocation()};
const auto range = boost::icl::discrete_interval<u64>::closed(descriptor.PC(), end_location.PC() - 1);
A64EmitX64::BlockDescriptor block_desc{entrypoint, size};
block_descriptors.emplace(descriptor.UniqueHash(), block_desc);
block_ranges.AddRange(range, descriptor);
return block_desc;
return RegisterBlock(descriptor, entrypoint, size);
}
void A64EmitX64::ClearCache() {
@@ -166,6 +166,7 @@ void A64EmitX64::GenMemory128Accessors() {
code.add(rsp, 8);
#endif
code.ret();
PerfMapRegister(memory_read_128, code.getCurr(), "a64_memory_read_128");
code.align();
memory_write_128 = code.getCurr<void(*)()>();
@@ -189,6 +190,7 @@ void A64EmitX64::GenMemory128Accessors() {
code.add(rsp, 8);
#endif
code.ret();
PerfMapRegister(memory_read_128, code.getCurr(), "a64_memory_write_128");
}
void A64EmitX64::GenFastmemFallbacks() {
@@ -224,6 +226,7 @@ void A64EmitX64::GenFastmemFallbacks() {
}
ABI_PopCallerSaveRegistersAndAdjustStackExcept(code, HostLocXmmIdx(value_idx));
code.ret();
PerfMapRegister(read_fallbacks[std::make_tuple(128, vaddr_idx, value_idx)], code.getCurr(), "a64_read_fallback_128");
code.align();
write_fallbacks[std::make_tuple(128, vaddr_idx, value_idx)] = code.getCurr<void(*)()>();
@@ -237,6 +240,7 @@ void A64EmitX64::GenFastmemFallbacks() {
code.call(memory_write_128);
ABI_PopCallerSaveRegistersAndAdjustStack(code);
code.ret();
PerfMapRegister(write_fallbacks[std::make_tuple(128, vaddr_idx, value_idx)], code.getCurr(), "a64_write_fallback_128");
if (value_idx == 4 || value_idx == 15) {
continue;
@@ -255,6 +259,7 @@ void A64EmitX64::GenFastmemFallbacks() {
}
ABI_PopCallerSaveRegistersAndAdjustStackExcept(code, HostLocRegIdx(value_idx));
code.ret();
PerfMapRegister(read_fallbacks[std::make_tuple(bitsize, vaddr_idx, value_idx)], code.getCurr(), fmt::format("a64_read_fallback_{}", bitsize));
}
for (auto& [bitsize, callback] : write_callbacks) {
@@ -279,6 +284,7 @@ void A64EmitX64::GenFastmemFallbacks() {
callback.EmitCall(code);
ABI_PopCallerSaveRegistersAndAdjustStack(code);
code.ret();
PerfMapRegister(write_fallbacks[std::make_tuple(bitsize, vaddr_idx, value_idx)], code.getCurr(), fmt::format("a64_write_fallback_{}", bitsize));
}
}
}
@@ -999,6 +1005,13 @@ void A64EmitX64::EmitA64ExclusiveWriteMemory128(A64EmitContext& ctx, IR::Inst* i
EmitExclusiveWrite(ctx, inst, 128);
}
std::string A64EmitX64::LocationDescriptorToFriendlyName(const IR::LocationDescriptor& ir_descriptor) const {
const A64::LocationDescriptor descriptor{ir_descriptor};
return fmt::format("a64_{:016X}_fpcr{:08X}",
descriptor.PC(),
descriptor.FPCR().Value());
}
void A64EmitX64::EmitTerminalImpl(IR::Term::Interpret terminal, IR::LocationDescriptor) {
code.SwitchMxcsrOnExit();
Devirtualize<&A64::UserCallbacks::InterpreterFallback>(conf.callbacks).EmitCall(code,