Moving source map to Function.
This commit is contained in:
@@ -75,17 +75,21 @@ bool X64Assembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder,
|
||||
// Reset when we leave.
|
||||
xe::make_reset_scope(this);
|
||||
|
||||
// Create now, and populate as we go.
|
||||
// We may throw it away if we fail.
|
||||
auto fn = std::make_unique<X64Function>(symbol_info);
|
||||
|
||||
// Lower HIR -> x64.
|
||||
void* machine_code = nullptr;
|
||||
size_t code_size = 0;
|
||||
if (!emitter_->Emit(symbol_info, builder, debug_info_flags, debug_info.get(),
|
||||
machine_code, code_size)) {
|
||||
machine_code, code_size, fn->source_map())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Stash generated machine code.
|
||||
if (debug_info_flags & DebugInfoFlags::kDebugInfoDisasmMachineCode) {
|
||||
DumpMachineCode(debug_info.get(), machine_code, code_size, &string_buffer_);
|
||||
DumpMachineCode(machine_code, code_size, fn->source_map(), &string_buffer_);
|
||||
debug_info->set_machine_code_disasm(string_buffer_.ToString());
|
||||
string_buffer_.Reset();
|
||||
}
|
||||
@@ -98,21 +102,19 @@ bool X64Assembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder,
|
||||
}
|
||||
}
|
||||
|
||||
X64Function* fn = new X64Function(symbol_info);
|
||||
fn->set_debug_info(std::move(debug_info));
|
||||
fn->Setup(reinterpret_cast<uint8_t*>(machine_code), code_size);
|
||||
|
||||
*out_function = fn;
|
||||
|
||||
// Pass back ownership.
|
||||
*out_function = fn.release();
|
||||
return true;
|
||||
}
|
||||
|
||||
void X64Assembler::DumpMachineCode(DebugInfo* debug_info, void* machine_code,
|
||||
size_t code_size, StringBuffer* str) {
|
||||
auto source_map_entries = debug_info->source_map_entries();
|
||||
auto source_map_count = debug_info->source_map_count();
|
||||
void X64Assembler::DumpMachineCode(
|
||||
void* machine_code, size_t code_size,
|
||||
const std::vector<SourceMapEntry>& source_map, StringBuffer* str) {
|
||||
auto source_map_index = 0;
|
||||
uint32_t next_code_offset = source_map_entries[0].code_offset;
|
||||
uint32_t next_code_offset = source_map[0].code_offset;
|
||||
|
||||
const uint8_t* code_ptr = reinterpret_cast<uint8_t*>(machine_code);
|
||||
size_t remaining_code_size = code_size;
|
||||
@@ -125,11 +127,11 @@ void X64Assembler::DumpMachineCode(DebugInfo* debug_info, void* machine_code,
|
||||
auto code_offset =
|
||||
uint32_t(code_ptr - reinterpret_cast<uint8_t*>(machine_code));
|
||||
if (code_offset >= next_code_offset &&
|
||||
source_map_index < source_map_count) {
|
||||
auto& source_map_entry = source_map_entries[source_map_index];
|
||||
source_map_index < source_map.size()) {
|
||||
auto& source_map_entry = source_map[source_map_index];
|
||||
str->AppendFormat("%.8X ", source_map_entry.source_offset);
|
||||
++source_map_index;
|
||||
next_code_offset = source_map_entries[source_map_index].code_offset;
|
||||
next_code_offset = source_map[source_map_index].code_offset;
|
||||
} else {
|
||||
str->Append(" ");
|
||||
}
|
||||
|
||||
@@ -11,9 +11,11 @@
|
||||
#define XENIA_BACKEND_X64_X64_ASSEMBLER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "xenia/base/string_buffer.h"
|
||||
#include "xenia/cpu/backend/assembler.h"
|
||||
#include "xenia/cpu/function.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
@@ -39,8 +41,9 @@ class X64Assembler : public Assembler {
|
||||
Function** out_function) override;
|
||||
|
||||
private:
|
||||
void DumpMachineCode(DebugInfo* debug_info, void* machine_code,
|
||||
size_t code_size, StringBuffer* str);
|
||||
void DumpMachineCode(void* machine_code, size_t code_size,
|
||||
const std::vector<SourceMapEntry>& source_map,
|
||||
StringBuffer* str);
|
||||
|
||||
private:
|
||||
X64Backend* x64_backend_;
|
||||
|
||||
@@ -67,13 +67,7 @@ X64Emitter::X64Emitter(X64Backend* backend, XbyakAllocator* allocator)
|
||||
processor_(backend->processor()),
|
||||
backend_(backend),
|
||||
code_cache_(backend->code_cache()),
|
||||
allocator_(allocator),
|
||||
feature_flags_(0),
|
||||
current_instr_(0),
|
||||
debug_info_(nullptr),
|
||||
debug_info_flags_(0),
|
||||
source_map_count_(0),
|
||||
stack_size_(0) {
|
||||
allocator_(allocator) {
|
||||
if (FLAGS_enable_haswell_instructions) {
|
||||
feature_flags_ |= cpu_.has(Xbyak::util::Cpu::tAVX2) ? kX64EmitAVX2 : 0;
|
||||
feature_flags_ |= cpu_.has(Xbyak::util::Cpu::tFMA) ? kX64EmitFMA : 0;
|
||||
@@ -95,16 +89,14 @@ X64Emitter::~X64Emitter() = default;
|
||||
|
||||
bool X64Emitter::Emit(FunctionInfo* function_info, HIRBuilder* builder,
|
||||
uint32_t debug_info_flags, DebugInfo* debug_info,
|
||||
void*& out_code_address, size_t& out_code_size) {
|
||||
void*& out_code_address, size_t& out_code_size,
|
||||
std::vector<SourceMapEntry>& out_source_map) {
|
||||
SCOPE_profile_cpu_f("cpu");
|
||||
|
||||
// Reset.
|
||||
debug_info_ = debug_info;
|
||||
debug_info_flags_ = debug_info_flags;
|
||||
if (debug_info_flags_ & DebugInfoFlags::kDebugInfoSourceMap) {
|
||||
source_map_count_ = 0;
|
||||
source_map_arena_.Reset();
|
||||
}
|
||||
source_map_arena_.Reset();
|
||||
|
||||
// Fill the generator with code.
|
||||
size_t stack_size = 0;
|
||||
@@ -117,10 +109,7 @@ bool X64Emitter::Emit(FunctionInfo* function_info, HIRBuilder* builder,
|
||||
out_code_address = Emplace(stack_size, function_info);
|
||||
|
||||
// Stash source map.
|
||||
if (debug_info_flags_ & DebugInfoFlags::kDebugInfoSourceMap) {
|
||||
debug_info->InitializeSourceMap(
|
||||
source_map_count_, (SourceMapEntry*)source_map_arena_.CloneContents());
|
||||
}
|
||||
source_map_arena_.CloneContents(out_source_map);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -266,7 +255,6 @@ void X64Emitter::MarkSourceOffset(const Instr* i) {
|
||||
entry->source_offset = static_cast<uint32_t>(i->src1.offset);
|
||||
entry->hir_offset = uint32_t(i->block->ordinal << 16) | i->ordinal;
|
||||
entry->code_offset = static_cast<uint32_t>(getSize() + 1);
|
||||
source_map_count_++;
|
||||
|
||||
if (FLAGS_debug) {
|
||||
nop();
|
||||
|
||||
@@ -10,7 +10,10 @@
|
||||
#ifndef XENIA_BACKEND_X64_X64_EMITTER_H_
|
||||
#define XENIA_BACKEND_X64_X64_EMITTER_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "xenia/base/arena.h"
|
||||
#include "xenia/cpu/function.h"
|
||||
#include "xenia/cpu/hir/hir_builder.h"
|
||||
#include "xenia/cpu/hir/instr.h"
|
||||
#include "xenia/cpu/hir/value.h"
|
||||
@@ -117,7 +120,8 @@ class X64Emitter : public Xbyak::CodeGenerator {
|
||||
|
||||
bool Emit(FunctionInfo* function_info, hir::HIRBuilder* builder,
|
||||
uint32_t debug_info_flags, DebugInfo* debug_info,
|
||||
void*& out_code_address, size_t& out_code_size);
|
||||
void*& out_code_address, size_t& out_code_size,
|
||||
std::vector<SourceMapEntry>& out_source_map);
|
||||
|
||||
static uint32_t PlaceData(Memory* memory);
|
||||
|
||||
@@ -201,23 +205,22 @@ class X64Emitter : public Xbyak::CodeGenerator {
|
||||
void EmitTraceUserCallReturn();
|
||||
|
||||
protected:
|
||||
Processor* processor_;
|
||||
X64Backend* backend_;
|
||||
X64CodeCache* code_cache_;
|
||||
XbyakAllocator* allocator_;
|
||||
Processor* processor_ = nullptr;
|
||||
X64Backend* backend_ = nullptr;
|
||||
X64CodeCache* code_cache_ = nullptr;
|
||||
XbyakAllocator* allocator_ = nullptr;
|
||||
Xbyak::util::Cpu cpu_;
|
||||
uint32_t feature_flags_;
|
||||
uint32_t feature_flags_ = 0;
|
||||
|
||||
Xbyak::Label* epilog_label_ = nullptr;
|
||||
|
||||
hir::Instr* current_instr_;
|
||||
hir::Instr* current_instr_ = nullptr;
|
||||
|
||||
DebugInfo* debug_info_;
|
||||
uint32_t debug_info_flags_;
|
||||
size_t source_map_count_;
|
||||
DebugInfo* debug_info_ = nullptr;
|
||||
uint32_t debug_info_flags_ = 0;
|
||||
Arena source_map_arena_;
|
||||
|
||||
size_t stack_size_;
|
||||
size_t stack_size_ = 0;
|
||||
|
||||
static const uint32_t gpr_reg_map_[GPR_COUNT];
|
||||
static const uint32_t xmm_reg_map_[XMM_COUNT];
|
||||
|
||||
Reference in New Issue
Block a user