Running clang-format on alloy.

All except x64_sequences, which needs work.
This commit is contained in:
Ben Vanik
2014-07-10 20:20:00 -07:00
parent 0158380cfc
commit 7daa85179c
139 changed files with 6925 additions and 6998 deletions

View File

@@ -12,24 +12,20 @@
#include <alloy/backend/tracing.h>
namespace alloy {
namespace backend {
namespace x64 {
const uint32_t ALLOY_BACKEND_X64 =
alloy::backend::EventType::ALLOY_BACKEND_X64;
const uint32_t ALLOY_BACKEND_X64 = alloy::backend::EventType::ALLOY_BACKEND_X64;
class EventType {
public:
public:
enum {
ALLOY_BACKEND_X64_INIT = ALLOY_BACKEND_X64 | (1),
ALLOY_BACKEND_X64_DEINIT = ALLOY_BACKEND_X64 | (2),
ALLOY_BACKEND_X64_ASSEMBLER = ALLOY_BACKEND_X64 | (1 << 20),
ALLOY_BACKEND_X64_ASSEMBLER_INIT = ALLOY_BACKEND_X64_ASSEMBLER | (1),
ALLOY_BACKEND_X64_ASSEMBLER_DEINIT = ALLOY_BACKEND_X64_ASSEMBLER | (2),
ALLOY_BACKEND_X64_INIT = ALLOY_BACKEND_X64 | (1),
ALLOY_BACKEND_X64_DEINIT = ALLOY_BACKEND_X64 | (2),
ALLOY_BACKEND_X64_ASSEMBLER = ALLOY_BACKEND_X64 | (1 << 20),
ALLOY_BACKEND_X64_ASSEMBLER_INIT = ALLOY_BACKEND_X64_ASSEMBLER | (1),
ALLOY_BACKEND_X64_ASSEMBLER_DEINIT = ALLOY_BACKEND_X64_ASSEMBLER | (2),
};
typedef struct Init_s {
@@ -47,10 +43,8 @@ public:
} AssemblerDeinit;
};
} // namespace x64
} // namespace backend
} // namespace alloy
#endif // ALLOY_BACKEND_X64_TRACING_H_

View File

@@ -21,22 +21,23 @@ namespace BE {
#include <beaengine/BeaEngine.h>
}
using namespace alloy;
using namespace alloy::backend;
using namespace alloy::backend::x64;
using namespace alloy::hir;
namespace alloy {
namespace backend {
namespace x64 {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::runtime;
using alloy::hir::HIRBuilder;
using alloy::runtime::DebugInfo;
using alloy::runtime::Function;
using alloy::runtime::FunctionInfo;
X64Assembler::X64Assembler(X64Backend* backend) :
x64_backend_(backend),
emitter_(0), allocator_(0),
Assembler(backend) {
}
X64Assembler::X64Assembler(X64Backend* backend)
: x64_backend_(backend), emitter_(0), allocator_(0), Assembler(backend) {}
X64Assembler::~X64Assembler() {
alloy::tracing::WriteEvent(EventType::AssemblerDeinit({
}));
alloy::tracing::WriteEvent(EventType::AssemblerDeinit({}));
delete emitter_;
delete allocator_;
@@ -51,8 +52,7 @@ int X64Assembler::Initialize() {
allocator_ = new XbyakAllocator();
emitter_ = new X64Emitter(x64_backend_, allocator_);
alloy::tracing::WriteEvent(EventType::AssemblerInit({
}));
alloy::tracing::WriteEvent(EventType::AssemblerInit({}));
return result;
}
@@ -62,10 +62,9 @@ void X64Assembler::Reset() {
Assembler::Reset();
}
int X64Assembler::Assemble(
FunctionInfo* symbol_info, HIRBuilder* builder,
uint32_t debug_info_flags, DebugInfo* debug_info,
Function** out_function) {
int X64Assembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder,
uint32_t debug_info_flags, DebugInfo* debug_info,
Function** out_function) {
SCOPE_profile_cpu_f("alloy");
int result = 0;
@@ -73,13 +72,12 @@ int X64Assembler::Assemble(
// Lower HIR -> x64.
void* machine_code = 0;
size_t code_size = 0;
result = emitter_->Emit(builder,
debug_info_flags, debug_info,
machine_code, code_size);
result = emitter_->Emit(builder, debug_info_flags, debug_info, machine_code,
code_size);
XEEXPECTZERO(result);
// Stash generated machine code.
if (debug_info_flags & DEBUG_INFO_MACHINE_CODE_DISASM) {
if (debug_info_flags & DebugInfoFlags::DEBUG_INFO_MACHINE_CODE_DISASM) {
DumpMachineCode(debug_info, machine_code, code_size, &string_buffer_);
debug_info->set_machine_code_disasm(string_buffer_.ToString());
string_buffer_.Reset();
@@ -100,10 +98,8 @@ XECLEANUP:
return result;
}
void X64Assembler::DumpMachineCode(
DebugInfo* debug_info,
void* machine_code, size_t code_size,
StringBuffer* str) {
void X64Assembler::DumpMachineCode(DebugInfo* debug_info, void* machine_code,
size_t code_size, StringBuffer* str) {
BE::DISASM disasm;
xe_zero_struct(&disasm, sizeof(disasm));
disasm.Archi = 64;
@@ -113,8 +109,8 @@ void X64Assembler::DumpMachineCode(
uint64_t prev_source_offset = 0;
while (disasm.EIP < eip_end) {
// Look up source offset.
auto map_entry = debug_info->LookupCodeOffset(
disasm.EIP - (BE::UIntPtr)machine_code);
auto map_entry =
debug_info->LookupCodeOffset(disasm.EIP - (BE::UIntPtr)machine_code);
if (map_entry) {
if (map_entry->source_offset == prev_source_offset) {
str->Append(" ");
@@ -134,3 +130,7 @@ void X64Assembler::DumpMachineCode(
disasm.EIP += len;
}
}
} // namespace x64
} // namespace backend
} // namespace alloy

View File

@@ -14,7 +14,6 @@
#include <alloy/backend/assembler.h>
namespace alloy {
namespace backend {
namespace x64 {
@@ -23,9 +22,8 @@ class X64Backend;
class X64Emitter;
class XbyakAllocator;
class X64Assembler : public Assembler {
public:
public:
X64Assembler(X64Backend* backend);
virtual ~X64Assembler();
@@ -33,28 +31,25 @@ public:
virtual void Reset();
virtual int Assemble(
runtime::FunctionInfo* symbol_info, hir::HIRBuilder* builder,
uint32_t debug_info_flags, runtime::DebugInfo* debug_info,
runtime::Function** out_function);
virtual int Assemble(runtime::FunctionInfo* symbol_info,
hir::HIRBuilder* builder, uint32_t debug_info_flags,
runtime::DebugInfo* debug_info,
runtime::Function** out_function);
private:
void DumpMachineCode(runtime::DebugInfo* debug_info,
void* machine_code, size_t code_size,
StringBuffer* str);
private:
void DumpMachineCode(runtime::DebugInfo* debug_info, void* machine_code,
size_t code_size, StringBuffer* str);
private:
X64Backend* x64_backend_;
X64Emitter* emitter_;
XbyakAllocator* allocator_;
private:
X64Backend* x64_backend_;
X64Emitter* emitter_;
XbyakAllocator* allocator_;
StringBuffer string_buffer_;
StringBuffer string_buffer_;
};
} // namespace x64
} // namespace backend
} // namespace alloy
#endif // ALLOY_BACKEND_X64_X64_ASSEMBLER_H_

View File

@@ -15,20 +15,16 @@
#include <alloy/backend/x64/x64_sequences.h>
#include <alloy/backend/x64/x64_thunk_emitter.h>
using namespace alloy;
using namespace alloy::backend;
using namespace alloy::backend::x64;
using namespace alloy::runtime;
namespace alloy {
namespace backend {
namespace x64 {
using alloy::runtime::Runtime;
X64Backend::X64Backend(Runtime* runtime) :
code_cache_(0),
Backend(runtime) {
}
X64Backend::X64Backend(Runtime* runtime) : code_cache_(0), Backend(runtime) {}
X64Backend::~X64Backend() {
alloy::tracing::WriteEvent(EventType::Deinit({
}));
alloy::tracing::WriteEvent(EventType::Deinit({}));
delete code_cache_;
}
@@ -41,17 +37,12 @@ int X64Backend::Initialize() {
RegisterSequences();
machine_info_.register_sets[0] = {
0,
"gpr",
MachineInfo::RegisterSet::INT_TYPES,
X64Emitter::GPR_COUNT,
0, "gpr", MachineInfo::RegisterSet::INT_TYPES, X64Emitter::GPR_COUNT,
};
machine_info_.register_sets[1] = {
1,
"xmm",
MachineInfo::RegisterSet::FLOAT_TYPES |
MachineInfo::RegisterSet::VEC_TYPES,
X64Emitter::XMM_COUNT,
1, "xmm", MachineInfo::RegisterSet::FLOAT_TYPES |
MachineInfo::RegisterSet::VEC_TYPES,
X64Emitter::XMM_COUNT,
};
code_cache_ = new X64CodeCache();
@@ -67,12 +58,13 @@ int X64Backend::Initialize() {
delete thunk_emitter;
delete allocator;
alloy::tracing::WriteEvent(EventType::Init({
}));
alloy::tracing::WriteEvent(EventType::Init({}));
return result;
}
Assembler* X64Backend::CreateAssembler() {
return new X64Assembler(this);
}
Assembler* X64Backend::CreateAssembler() { return new X64Assembler(this); }
} // namespace x64
} // namespace backend
} // namespace alloy

View File

@@ -14,22 +14,19 @@
#include <alloy/backend/backend.h>
namespace alloy {
namespace backend {
namespace x64 {
class X64CodeCache;
#define ALLOY_HAS_X64_BACKEND 1
typedef void* (*HostToGuestThunk)(void* target, void* arg0, void* arg1);
typedef void* (*GuestToHostThunk)(void* target, void* arg0, void* arg1);
class X64Backend : public Backend {
public:
public:
X64Backend(runtime::Runtime* runtime);
virtual ~X64Backend();
@@ -41,16 +38,14 @@ public:
virtual Assembler* CreateAssembler();
private:
private:
X64CodeCache* code_cache_;
HostToGuestThunk host_to_guest_thunk_;
GuestToHostThunk guest_to_host_thunk_;
};
} // namespace x64
} // namespace backend
} // namespace alloy
#endif // ALLOY_BACKEND_X64_X64_BACKEND_H_

View File

@@ -11,24 +11,20 @@
#include <alloy/backend/x64/tracing.h>
using namespace alloy;
using namespace alloy::backend;
using namespace alloy::backend::x64;
namespace alloy {
namespace backend {
namespace x64 {
class X64CodeChunk {
public:
public:
X64CodeChunk(size_t chunk_size);
~X64CodeChunk();
public:
public:
X64CodeChunk* next;
size_t capacity;
uint8_t* buffer;
size_t offset;
size_t capacity;
uint8_t* buffer;
size_t offset;
// Estimate of function sized use to determine initial table capacity.
const static uint32_t ESTIMATED_FN_SIZE = 512;
@@ -36,24 +32,16 @@ public:
// TODO(benvanik): move this to emitter.
const static uint32_t UNWIND_INFO_SIZE = 4 + (2 * 1 + 2 + 2);
void* fn_table_handle;
void* fn_table_handle;
RUNTIME_FUNCTION* fn_table;
uint32_t fn_table_count;
uint32_t fn_table_capacity;
uint32_t fn_table_count;
uint32_t fn_table_capacity;
void AddTableEntry(uint8_t* code, size_t code_size, size_t stack_size);
};
} // namespace x64
} // namespace backend
} // namespace alloy
X64CodeCache::X64CodeCache(size_t chunk_size) :
chunk_size_(chunk_size),
head_chunk_(NULL), active_chunk_(NULL) {
}
X64CodeCache::X64CodeCache(size_t chunk_size)
: chunk_size_(chunk_size), head_chunk_(NULL), active_chunk_(NULL) {}
X64CodeCache::~X64CodeCache() {
std::lock_guard<std::mutex> guard(lock_);
@@ -66,9 +54,7 @@ X64CodeCache::~X64CodeCache() {
head_chunk_ = NULL;
}
int X64CodeCache::Initialize() {
return 0;
}
int X64CodeCache::Initialize() { return 0; }
void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size,
size_t stack_size) {
@@ -87,7 +73,7 @@ void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size,
if (active_chunk_->capacity - active_chunk_->offset < code_size) {
auto next = active_chunk_->next;
if (!next) {
XEASSERT(code_size < chunk_size_); // need to support larger chunks
XEASSERT(code_size < chunk_size_); // need to support larger chunks
next = new X64CodeChunk(chunk_size_);
active_chunk_->next = next;
}
@@ -113,25 +99,19 @@ void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size,
return final_address;
}
X64CodeChunk::X64CodeChunk(size_t chunk_size) :
next(NULL),
capacity(chunk_size), buffer(0), offset(0) {
buffer = (uint8_t*)VirtualAlloc(
NULL, capacity,
MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
X64CodeChunk::X64CodeChunk(size_t chunk_size)
: next(NULL), capacity(chunk_size), buffer(0), offset(0) {
buffer = (uint8_t*)VirtualAlloc(NULL, capacity, MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
fn_table_capacity = (uint32_t)XEROUNDUP(capacity / ESTIMATED_FN_SIZE, 16);
size_t table_size = fn_table_capacity * sizeof(RUNTIME_FUNCTION);
fn_table = (RUNTIME_FUNCTION*)xe_malloc(table_size);
fn_table_count = 0;
fn_table_handle = 0;
RtlAddGrowableFunctionTable(
&fn_table_handle,
fn_table,
fn_table_count,
fn_table_capacity,
(ULONG_PTR)buffer, (ULONG_PTR)buffer + capacity);
RtlAddGrowableFunctionTable(&fn_table_handle, fn_table, fn_table_count,
fn_table_capacity, (ULONG_PTR)buffer,
(ULONG_PTR)buffer + capacity);
}
X64CodeChunk::~X64CodeChunk() {
@@ -157,7 +137,7 @@ typedef enum _UNWIND_OP_CODES {
UWOP_PUSH_MACHFRAME /* info == 0: no error-code, 1: error-code */
} UNWIND_CODE_OPS;
class UNWIND_REGISTER {
public:
public:
enum _ {
RAX = 0,
RCX = 1,
@@ -182,25 +162,25 @@ typedef union _UNWIND_CODE {
struct {
uint8_t CodeOffset;
uint8_t UnwindOp : 4;
uint8_t OpInfo : 4;
uint8_t OpInfo : 4;
};
USHORT FrameOffset;
} UNWIND_CODE, *PUNWIND_CODE;
typedef struct _UNWIND_INFO {
uint8_t Version : 3;
uint8_t Flags : 5;
uint8_t Version : 3;
uint8_t Flags : 5;
uint8_t SizeOfProlog;
uint8_t CountOfCodes;
uint8_t FrameRegister : 4;
uint8_t FrameOffset : 4;
uint8_t FrameOffset : 4;
UNWIND_CODE UnwindCode[1];
/* UNWIND_CODE MoreUnwindCode[((CountOfCodes + 1) & ~1) - 1];
* union {
* OPTIONAL ULONG ExceptionHandler;
* OPTIONAL ULONG FunctionEntry;
* };
* OPTIONAL ULONG ExceptionData[]; */
/* UNWIND_CODE MoreUnwindCode[((CountOfCodes + 1) & ~1) - 1];
* union {
* OPTIONAL ULONG ExceptionHandler;
* OPTIONAL ULONG FunctionEntry;
* };
* OPTIONAL ULONG ExceptionData[]; */
} UNWIND_INFO, *PUNWIND_INFO;
} // namespace
@@ -215,19 +195,17 @@ void X64CodeChunk::AddTableEntry(uint8_t* code, size_t code_size,
RtlDeleteGrowableFunctionTable(fn_table_handle);
size_t old_size = fn_table_capacity * sizeof(RUNTIME_FUNCTION);
size_t new_size = old_size * 2;
auto new_table = (RUNTIME_FUNCTION*)xe_realloc(fn_table, old_size, new_size);
auto new_table =
(RUNTIME_FUNCTION*)xe_realloc(fn_table, old_size, new_size);
XEASSERTNOTNULL(new_table);
if (!new_table) {
return;
}
fn_table = new_table;
fn_table_capacity *= 2;
RtlAddGrowableFunctionTable(
&fn_table_handle,
fn_table,
fn_table_count,
fn_table_capacity,
(ULONG_PTR)buffer, (ULONG_PTR)buffer + capacity);
RtlAddGrowableFunctionTable(&fn_table_handle, fn_table, fn_table_count,
fn_table_capacity, (ULONG_PTR)buffer,
(ULONG_PTR)buffer + capacity);
}
// Allocate unwind data. We know we have space because we overallocated.
@@ -261,7 +239,8 @@ void X64CodeChunk::AddTableEntry(uint8_t* code, size_t code_size,
// http://msdn.microsoft.com/en-us/library/ck9asaa9.aspx
size_t co = 0;
auto& unwind_code = unwind_info->UnwindCode[co++];
unwind_code.CodeOffset = 14; // end of instruction + 1 == offset of next instruction
unwind_code.CodeOffset =
14; // end of instruction + 1 == offset of next instruction
unwind_code.UnwindOp = UWOP_ALLOC_SMALL;
unwind_code.OpInfo = stack_size / 8 - 1;
} else {
@@ -280,7 +259,8 @@ void X64CodeChunk::AddTableEntry(uint8_t* code, size_t code_size,
// http://msdn.microsoft.com/en-us/library/ck9asaa9.aspx
size_t co = 0;
auto& unwind_code = unwind_info->UnwindCode[co++];
unwind_code.CodeOffset = 7; // end of instruction + 1 == offset of next instruction
unwind_code.CodeOffset =
7; // end of instruction + 1 == offset of next instruction
unwind_code.UnwindOp = UWOP_ALLOC_LARGE;
unwind_code.OpInfo = 0;
unwind_code = unwind_info->UnwindCode[co++];
@@ -296,3 +276,7 @@ void X64CodeChunk::AddTableEntry(uint8_t* code, size_t code_size,
// Notify the function table that it has new entries.
RtlGrowFunctionTable(fn_table_handle, fn_table_count);
}
} // namespace x64
} // namespace backend
} // namespace alloy

View File

@@ -14,7 +14,6 @@
#include <alloy/core.h>
namespace alloy {
namespace backend {
namespace x64 {
@@ -22,7 +21,7 @@ namespace x64 {
class X64CodeChunk;
class X64CodeCache {
public:
public:
X64CodeCache(size_t chunk_size = DEFAULT_CHUNK_SIZE);
virtual ~X64CodeCache();
@@ -34,18 +33,16 @@ public:
void* PlaceCode(void* machine_code, size_t code_size, size_t stack_size);
private:
private:
const static size_t DEFAULT_CHUNK_SIZE = 4 * 1024 * 1024;
std::mutex lock_;
size_t chunk_size_;
std::mutex lock_;
size_t chunk_size_;
X64CodeChunk* head_chunk_;
X64CodeChunk* active_chunk_;
};
} // namespace x64
} // namespace backend
} // namespace alloy
#endif // ALLOY_BACKEND_X64_X64_CODE_CACHE_H_

View File

@@ -20,18 +20,21 @@
#include <alloy/runtime/symbol_info.h>
#include <alloy/runtime/thread_state.h>
using namespace alloy;
using namespace alloy::backend;
using namespace alloy::backend::x64;
namespace alloy {
namespace backend {
namespace x64 {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace Xbyak;
namespace alloy {
namespace backend {
namespace x64 {
using alloy::hir::HIRBuilder;
using alloy::hir::Instr;
using alloy::runtime::Function;
using alloy::runtime::FunctionInfo;
using alloy::runtime::SourceMapEntry;
using alloy::runtime::ThreadState;
static const size_t MAX_CODE_SIZE = 1 * 1024 * 1024;
@@ -42,41 +45,29 @@ static const size_t STASH_OFFSET = 32;
// can get the value.
#define STORE_EFLAGS 1
} // namespace x64
} // namespace backend
} // namespace alloy
const uint32_t X64Emitter::gpr_reg_map_[X64Emitter::GPR_COUNT] = {
Operand::RBX,
Operand::R12, Operand::R13, Operand::R14, Operand::R15,
Operand::RBX, Operand::R12, Operand::R13, Operand::R14, Operand::R15,
};
const uint32_t X64Emitter::xmm_reg_map_[X64Emitter::XMM_COUNT] = {
6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
};
X64Emitter::X64Emitter(X64Backend* backend, XbyakAllocator* allocator)
: runtime_(backend->runtime()),
backend_(backend),
code_cache_(backend->code_cache()),
allocator_(allocator),
current_instr_(0),
CodeGenerator(MAX_CODE_SIZE, AutoGrow, allocator) {}
X64Emitter::X64Emitter(X64Backend* backend, XbyakAllocator* allocator) :
runtime_(backend->runtime()),
backend_(backend),
code_cache_(backend->code_cache()),
allocator_(allocator),
current_instr_(0),
CodeGenerator(MAX_CODE_SIZE, AutoGrow, allocator) {
}
X64Emitter::~X64Emitter() {}
X64Emitter::~X64Emitter() {
}
int X64Emitter::Initialize() { return 0; }
int X64Emitter::Initialize() {
return 0;
}
int X64Emitter::Emit(
HIRBuilder* builder,
uint32_t debug_info_flags, runtime::DebugInfo* debug_info,
void*& out_code_address, size_t& out_code_size) {
int X64Emitter::Emit(HIRBuilder* builder, uint32_t debug_info_flags,
runtime::DebugInfo* debug_info, void*& out_code_address,
size_t& out_code_size) {
SCOPE_profile_cpu_f("alloy");
// Reset.
@@ -99,8 +90,7 @@ int X64Emitter::Emit(
// Stash source map.
if (debug_info_flags & DEBUG_INFO_SOURCE_MAP) {
debug_info->InitializeSourceMap(
source_map_count_,
(SourceMapEntry*)source_map_arena_.CloneContents());
source_map_count_, (SourceMapEntry*)source_map_arena_.CloneContents());
}
return 0;
@@ -158,7 +148,7 @@ int X64Emitter::Emit(HIRBuilder* builder, size_t& out_stack_size) {
mov(qword[rsp + StackLayout::GUEST_RCX_HOME], rcx);
mov(qword[rsp + StackLayout::GUEST_RET_ADDR], rdx);
mov(qword[rsp + StackLayout::GUEST_CALL_RET_ADDR], 0);
mov(rdx, qword[rcx + 8]); // membase
mov(rdx, qword[rcx + 8]); // membase
}
// Body.
@@ -208,9 +198,9 @@ int X64Emitter::Emit(HIRBuilder* builder, size_t& out_stack_size) {
void X64Emitter::MarkSourceOffset(const Instr* i) {
auto entry = source_map_arena_.Alloc<SourceMapEntry>();
entry->source_offset = i->src1.offset;
entry->hir_offset = uint32_t(i->block->ordinal << 16) | i->ordinal;
entry->code_offset = getSize();
entry->source_offset = i->src1.offset;
entry->hir_offset = uint32_t(i->block->ordinal << 16) | i->ordinal;
entry->code_offset = getSize();
source_map_count_++;
}
@@ -221,20 +211,20 @@ void X64Emitter::DebugBreak() {
void X64Emitter::Trap(uint16_t trap_type) {
switch (trap_type) {
case 20:
// 0x0FE00014 is a 'debug print' where r3 = buffer r4 = length
// TODO(benvanik): debug print at runtime.
break;
case 0:
case 22:
// Always trap?
// TODO(benvanik): post software interrupt to debugger.
db(0xCC);
break;
default:
XELOGW("Unknown trap type %d", trap_type);
db(0xCC);
break;
case 20:
// 0x0FE00014 is a 'debug print' where r3 = buffer r4 = length
// TODO(benvanik): debug print at runtime.
break;
case 0:
case 22:
// Always trap?
// TODO(benvanik): post software interrupt to debugger.
db(0xCC);
break;
default:
XELOGW("Unknown trap type %d", trap_type);
db(0xCC);
break;
}
}
@@ -258,7 +248,8 @@ const size_t ASM_OFFSET = 2 + 2 + 8 + 2 + 8;
// 6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H
// 7 bytes NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H
// 8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H
// 9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00000000H] 66 0F 1F 84 00 00 00 00 00H
// 9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00000000H] 66 0F 1F 84 00 00 00 00
// 00H
uint64_t ResolveFunctionSymbol(void* raw_context, uint64_t symbol_info_ptr) {
// TODO(benvanik): generate this thunk at runtime? or a shim?
@@ -275,7 +266,7 @@ uint64_t ResolveFunctionSymbol(void* raw_context, uint64_t symbol_info_ptr) {
// Overwrite the call site.
// The return address points to ReloadRCX work after the call.
uint64_t return_address = reinterpret_cast<uint64_t>(_ReturnAddress());
#pragma pack(push, 1)
#pragma pack(push, 1)
struct Asm {
uint16_t mov_rax;
uint64_t rax_constant;
@@ -284,7 +275,7 @@ uint64_t ResolveFunctionSymbol(void* raw_context, uint64_t symbol_info_ptr) {
uint16_t call_rax;
uint8_t mov_rcx[5];
};
#pragma pack(pop)
#pragma pack(pop)
Asm* code = reinterpret_cast<Asm*>(return_address - ASM_OFFSET);
code->rax_constant = addr;
code->call_rax = 0x9066;
@@ -293,7 +284,8 @@ uint64_t ResolveFunctionSymbol(void* raw_context, uint64_t symbol_info_ptr) {
return addr;
}
void X64Emitter::Call(const hir::Instr* instr, runtime::FunctionInfo* symbol_info) {
void X64Emitter::Call(const hir::Instr* instr,
runtime::FunctionInfo* symbol_info) {
auto fn = reinterpret_cast<X64Function*>(symbol_info->function());
// Resolve address to the function to call and store in rax.
// TODO(benvanik): caching/etc. For now this makes debugging easier.
@@ -372,12 +364,12 @@ void X64Emitter::CallIndirect(const hir::Instr* instr, const Reg64& reg) {
uint64_t UndefinedCallExtern(void* raw_context, uint64_t symbol_info_ptr) {
auto symbol_info = reinterpret_cast<FunctionInfo*>(symbol_info_ptr);
XELOGW("undefined extern call to %.8X %s",
symbol_info->address(),
XELOGW("undefined extern call to %.8X %s", symbol_info->address(),
symbol_info->name());
return 0;
}
void X64Emitter::CallExtern(const hir::Instr* instr, const FunctionInfo* symbol_info) {
void X64Emitter::CallExtern(const hir::Instr* instr,
const FunctionInfo* symbol_info) {
XEASSERT(symbol_info->behavior() == FunctionInfo::BEHAVIOR_EXTERN);
if (!symbol_info->extern_handler()) {
CallNative(UndefinedCallExtern, reinterpret_cast<uint64_t>(symbol_info));
@@ -405,21 +397,22 @@ void X64Emitter::CallNative(void* fn) {
ReloadEDX();
}
void X64Emitter::CallNative(uint64_t(*fn)(void* raw_context)) {
void X64Emitter::CallNative(uint64_t (*fn)(void* raw_context)) {
mov(rax, reinterpret_cast<uint64_t>(fn));
call(rax);
ReloadECX();
ReloadEDX();
}
void X64Emitter::CallNative(uint64_t(*fn)(void* raw_context, uint64_t arg0)) {
void X64Emitter::CallNative(uint64_t (*fn)(void* raw_context, uint64_t arg0)) {
mov(rax, reinterpret_cast<uint64_t>(fn));
call(rax);
ReloadECX();
ReloadEDX();
}
void X64Emitter::CallNative(uint64_t(*fn)(void* raw_context, uint64_t arg0), uint64_t arg0) {
void X64Emitter::CallNative(uint64_t (*fn)(void* raw_context, uint64_t arg0),
uint64_t arg0) {
mov(rdx, arg0);
mov(rax, reinterpret_cast<uint64_t>(fn));
call(rax);
@@ -428,17 +421,17 @@ void X64Emitter::CallNative(uint64_t(*fn)(void* raw_context, uint64_t arg0), uin
}
void X64Emitter::CallNativeSafe(void* fn) {
// rcx = context
// rdx = target host function
// r8 = arg0
// r9 = arg1
mov(rdx, reinterpret_cast<uint64_t>(fn));
auto thunk = backend()->guest_to_host_thunk();
mov(rax, reinterpret_cast<uint64_t>(thunk));
call(rax);
ReloadECX();
ReloadEDX();
// rax = host return
// rcx = context
// rdx = target host function
// r8 = arg0
// r9 = arg1
mov(rdx, reinterpret_cast<uint64_t>(fn));
auto thunk = backend()->guest_to_host_thunk();
mov(rax, reinterpret_cast<uint64_t>(thunk));
call(rax);
ReloadECX();
ReloadEDX();
// rax = host return
}
void X64Emitter::SetReturnAddress(uint64_t value) {
@@ -450,7 +443,7 @@ void X64Emitter::ReloadECX() {
}
void X64Emitter::ReloadEDX() {
mov(rdx, qword[rcx + 8]); // membase
mov(rdx, qword[rcx + 8]); // membase
}
void X64Emitter::LoadEflags() {
@@ -459,7 +452,7 @@ void X64Emitter::LoadEflags() {
push(rax);
popf();
#else
// EFLAGS already present.
// EFLAGS already present.
#endif // STORE_EFLAGS
}
@@ -468,8 +461,8 @@ void X64Emitter::StoreEflags() {
pushf();
pop(qword[rsp + STASH_OFFSET]);
#else
// EFLAGS should have CA set?
// (so long as we don't fuck with it)
// EFLAGS should have CA set?
// (so long as we don't fuck with it)
#endif // STORE_EFLAGS
}
@@ -511,32 +504,51 @@ void X64Emitter::MovMem64(const RegExp& addr, uint64_t v) {
Address X64Emitter::GetXmmConstPtr(XmmConst id) {
static const vec128_t xmm_consts[] = {
/* XMMZero */ vec128f(0.0f, 0.0f, 0.0f, 0.0f),
/* XMMOne */ vec128f(1.0f, 1.0f, 1.0f, 1.0f),
/* XMMNegativeOne */ vec128f(-1.0f, -1.0f, -1.0f, -1.0f),
/* XMMMaskX16Y16 */ vec128i(0x0000FFFFu, 0xFFFF0000u, 0x00000000u, 0x00000000u),
/* XMMFlipX16Y16 */ vec128i(0x00008000u, 0x00000000u, 0x00000000u, 0x00000000u),
/* XMMFixX16Y16 */ vec128f(-32768.0f, 0.0f, 0.0f, 0.0f),
/* XMMNormalizeX16Y16 */ vec128f(1.0f / 32767.0f, 1.0f / (32767.0f * 65536.0f), 0.0f, 0.0f),
/* XMM0001 */ vec128f(0.0f, 0.0f, 0.0f, 1.0f),
/* XMM3301 */ vec128f(3.0f, 3.0f, 0.0f, 1.0f),
/* XMMSignMaskPS */ vec128i(0x80000000u, 0x80000000u, 0x80000000u, 0x80000000u),
/* XMMSignMaskPD */ vec128i(0x00000000u, 0x80000000u, 0x00000000u, 0x80000000u),
/* XMMAbsMaskPS */ vec128i(0x7FFFFFFFu, 0x7FFFFFFFu, 0x7FFFFFFFu, 0x7FFFFFFFu),
/* XMMAbsMaskPD */ vec128i(0xFFFFFFFFu, 0x7FFFFFFFu, 0xFFFFFFFFu, 0x7FFFFFFFu),
/* XMMByteSwapMask */ vec128i(0x00010203u, 0x04050607u, 0x08090A0Bu, 0x0C0D0E0Fu),
/* XMMPermuteControl15 */ vec128b(15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15),
/* XMMPackD3DCOLOR */ vec128i(0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x0C000408u),
/* XMMUnpackD3DCOLOR */ vec128i(0xFFFFFF0Eu, 0xFFFFFF0Du, 0xFFFFFF0Cu, 0xFFFFFF0Fu),
/* XMMOneOver255 */ vec128f(1.0f / 255.0f, 1.0f / 255.0f, 1.0f / 255.0f, 1.0f / 255.0f),
/* XMMShiftMaskPS */ vec128i(0x0000001Fu, 0x0000001Fu, 0x0000001Fu, 0x0000001Fu),
/* XMMShiftByteMask */ vec128i(0x000000FFu, 0x000000FFu, 0x000000FFu, 0x000000FFu),
/* XMMUnsignedDwordMax */ vec128i(0xFFFFFFFFu, 0x00000000u, 0xFFFFFFFFu, 0x00000000u),
/* XMM255 */ vec128f(255.0f, 255.0f, 255.0f, 255.0f),
/* XMMSignMaskI8 */ vec128i(0x80808080u, 0x80808080u, 0x80808080u, 0x80808080u),
/* XMMSignMaskI16 */ vec128i(0x80008000u, 0x80008000u, 0x80008000u, 0x80008000u),
/* XMMSignMaskI32 */ vec128i(0x80000000u, 0x80000000u, 0x80000000u, 0x80000000u),
/* XMMSignMaskF32 */ vec128i(0x80000000u, 0x80000000u, 0x80000000u, 0x80000000u),
/* XMMZero */ vec128f(0.0f, 0.0f, 0.0f, 0.0f),
/* XMMOne */ vec128f(1.0f, 1.0f, 1.0f, 1.0f),
/* XMMNegativeOne */ vec128f(-1.0f, -1.0f, -1.0f, -1.0f),
/* XMMMaskX16Y16 */ vec128i(0x0000FFFFu, 0xFFFF0000u,
0x00000000u, 0x00000000u),
/* XMMFlipX16Y16 */ vec128i(0x00008000u, 0x00000000u,
0x00000000u, 0x00000000u),
/* XMMFixX16Y16 */ vec128f(-32768.0f, 0.0f, 0.0f, 0.0f),
/* XMMNormalizeX16Y16 */ vec128f(
1.0f / 32767.0f, 1.0f / (32767.0f * 65536.0f), 0.0f, 0.0f),
/* XMM0001 */ vec128f(0.0f, 0.0f, 0.0f, 1.0f),
/* XMM3301 */ vec128f(3.0f, 3.0f, 0.0f, 1.0f),
/* XMMSignMaskPS */ vec128i(0x80000000u, 0x80000000u,
0x80000000u, 0x80000000u),
/* XMMSignMaskPD */ vec128i(0x00000000u, 0x80000000u,
0x00000000u, 0x80000000u),
/* XMMAbsMaskPS */ vec128i(0x7FFFFFFFu, 0x7FFFFFFFu,
0x7FFFFFFFu, 0x7FFFFFFFu),
/* XMMAbsMaskPD */ vec128i(0xFFFFFFFFu, 0x7FFFFFFFu,
0xFFFFFFFFu, 0x7FFFFFFFu),
/* XMMByteSwapMask */ vec128i(0x00010203u, 0x04050607u,
0x08090A0Bu, 0x0C0D0E0Fu),
/* XMMPermuteControl15 */ vec128b(15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15),
/* XMMPackD3DCOLOR */ vec128i(0xFFFFFFFFu, 0xFFFFFFFFu,
0xFFFFFFFFu, 0x0C000408u),
/* XMMUnpackD3DCOLOR */ vec128i(0xFFFFFF0Eu, 0xFFFFFF0Du,
0xFFFFFF0Cu, 0xFFFFFF0Fu),
/* XMMOneOver255 */ vec128f(1.0f / 255.0f, 1.0f / 255.0f,
1.0f / 255.0f, 1.0f / 255.0f),
/* XMMShiftMaskPS */ vec128i(0x0000001Fu, 0x0000001Fu,
0x0000001Fu, 0x0000001Fu),
/* XMMShiftByteMask */ vec128i(0x000000FFu, 0x000000FFu,
0x000000FFu, 0x000000FFu),
/* XMMUnsignedDwordMax */ vec128i(0xFFFFFFFFu, 0x00000000u,
0xFFFFFFFFu, 0x00000000u),
/* XMM255 */ vec128f(255.0f, 255.0f, 255.0f, 255.0f),
/* XMMSignMaskI8 */ vec128i(0x80808080u, 0x80808080u,
0x80808080u, 0x80808080u),
/* XMMSignMaskI16 */ vec128i(0x80008000u, 0x80008000u,
0x80008000u, 0x80008000u),
/* XMMSignMaskI32 */ vec128i(0x80000000u, 0x80000000u,
0x80000000u, 0x80000000u),
/* XMMSignMaskF32 */ vec128i(0x80000000u, 0x80000000u,
0x80000000u, 0x80000000u),
};
// TODO(benvanik): cache base pointer somewhere? stack? It'd be nice to
// prevent this move.
@@ -568,7 +580,7 @@ void X64Emitter::LoadConstantXmm(Xbyak::Xmm dest, float v) {
union {
float f;
uint32_t i;
} x = { v };
} x = {v};
if (!v) {
// 0
vpxor(dest, dest);
@@ -587,7 +599,7 @@ void X64Emitter::LoadConstantXmm(Xbyak::Xmm dest, double v) {
union {
double d;
uint64_t i;
} x = { v };
} x = {v};
if (!v) {
// 0
vpxor(dest, dest);
@@ -614,3 +626,7 @@ Address X64Emitter::StashXmm(const vec128_t& v) {
vmovups(addr, xmm0);
return addr;
}
} // namespace x64
} // namespace backend
} // namespace alloy

View File

@@ -31,12 +31,12 @@ class X64Backend;
class X64CodeCache;
enum RegisterFlags {
REG_DEST = (1 << 0),
REG_ABCD = (1 << 1),
REG_DEST = (1 << 0),
REG_ABCD = (1 << 1),
};
enum XmmConst {
XMMZero = 0,
XMMZero = 0,
XMMOne,
XMMNegativeOne,
XMMMaskX16Y16,
@@ -66,12 +66,12 @@ enum XmmConst {
// Unfortunately due to the design of xbyak we have to pass this to the ctor.
class XbyakAllocator : public Xbyak::Allocator {
public:
virtual bool useProtect() const { return false; }
public:
virtual bool useProtect() const { return false; }
};
class X64Emitter : public Xbyak::CodeGenerator {
public:
public:
X64Emitter(X64Backend* backend, XbyakAllocator* allocator);
virtual ~X64Emitter();
@@ -80,11 +80,11 @@ public:
int Initialize();
int Emit(hir::HIRBuilder* builder,
uint32_t debug_info_flags, runtime::DebugInfo* debug_info,
void*& out_code_address, size_t& out_code_size);
int Emit(hir::HIRBuilder* builder, uint32_t debug_info_flags,
runtime::DebugInfo* debug_info, void*& out_code_address,
size_t& out_code_size);
public:
public:
// Reserved: rsp
// Scratch: rax/rcx/rdx
// xmm0-2 (could be only xmm0 with some trickery)
@@ -123,11 +123,13 @@ public:
void Call(const hir::Instr* instr, runtime::FunctionInfo* symbol_info);
void CallIndirect(const hir::Instr* instr, const Xbyak::Reg64& reg);
void CallExtern(const hir::Instr* instr, const runtime::FunctionInfo* symbol_info);
void CallExtern(const hir::Instr* instr,
const runtime::FunctionInfo* symbol_info);
void CallNative(void* fn);
void CallNative(uint64_t(*fn)(void* raw_context));
void CallNative(uint64_t(*fn)(void* raw_context, uint64_t arg0));
void CallNative(uint64_t(*fn)(void* raw_context, uint64_t arg0), uint64_t arg0);
void CallNative(uint64_t (*fn)(void* raw_context));
void CallNative(uint64_t (*fn)(void* raw_context, uint64_t arg0));
void CallNative(uint64_t (*fn)(void* raw_context, uint64_t arg0),
uint64_t arg0);
void CallNativeSafe(void* fn);
void SetReturnAddress(uint64_t value);
void ReloadECX();
@@ -153,31 +155,29 @@ public:
size_t stack_size() const { return stack_size_; }
protected:
protected:
void* Emplace(size_t stack_size);
int Emit(hir::HIRBuilder* builder, size_t& out_stack_size);
protected:
protected:
runtime::Runtime* runtime_;
X64Backend* backend_;
X64CodeCache* code_cache_;
XbyakAllocator* allocator_;
X64Backend* backend_;
X64CodeCache* code_cache_;
XbyakAllocator* allocator_;
hir::Instr* current_instr_;
size_t source_map_count_;
Arena source_map_arena_;
size_t source_map_count_;
Arena source_map_arena_;
size_t stack_size_;
size_t stack_size_;
static const uint32_t gpr_reg_map_[GPR_COUNT];
static const uint32_t xmm_reg_map_[XMM_COUNT];
};
} // namespace x64
} // namespace backend
} // namespace alloy
#endif // ALLOY_BACKEND_X64_X64_EMITTER_H_

View File

@@ -14,16 +14,17 @@
#include <alloy/runtime/runtime.h>
#include <alloy/runtime/thread_state.h>
using namespace alloy;
using namespace alloy::backend;
using namespace alloy::backend::x64;
using namespace alloy::runtime;
namespace alloy {
namespace backend {
namespace x64 {
using alloy::runtime::Breakpoint;
using alloy::runtime::Function;
using alloy::runtime::FunctionInfo;
using alloy::runtime::ThreadState;
X64Function::X64Function(FunctionInfo* symbol_info) :
machine_code_(NULL), code_size_(0),
Function(symbol_info) {
}
X64Function::X64Function(FunctionInfo* symbol_info)
: machine_code_(NULL), code_size_(0), Function(symbol_info) {}
X64Function::~X64Function() {
// machine_code_ is freed by code cache.
@@ -34,20 +35,17 @@ void X64Function::Setup(void* machine_code, size_t code_size) {
code_size_ = code_size;
}
int X64Function::AddBreakpointImpl(Breakpoint* breakpoint) {
return 0;
}
int X64Function::AddBreakpointImpl(Breakpoint* breakpoint) { return 0; }
int X64Function::RemoveBreakpointImpl(Breakpoint* breakpoint) {
return 0;
}
int X64Function::RemoveBreakpointImpl(Breakpoint* breakpoint) { return 0; }
int X64Function::CallImpl(ThreadState* thread_state, uint64_t return_address) {
auto backend = (X64Backend*)thread_state->runtime()->backend();
auto thunk = backend->host_to_guest_thunk();
thunk(
machine_code_,
thread_state->raw_context(),
(void*)return_address);
thunk(machine_code_, thread_state->raw_context(), (void*)return_address);
return 0;
}
} // namespace x64
} // namespace backend
} // namespace alloy

View File

@@ -14,14 +14,12 @@
#include <alloy/runtime/function.h>
#include <alloy/runtime/symbol_info.h>
namespace alloy {
namespace backend {
namespace x64 {
class X64Function : public runtime::Function {
public:
public:
X64Function(runtime::FunctionInfo* symbol_info);
virtual ~X64Function();
@@ -30,21 +28,19 @@ public:
void Setup(void* machine_code, size_t code_size);
protected:
protected:
virtual int AddBreakpointImpl(runtime::Breakpoint* breakpoint);
virtual int RemoveBreakpointImpl(runtime::Breakpoint* breakpoint);
virtual int CallImpl(runtime::ThreadState* thread_state,
uint64_t return_address);
private:
void* machine_code_;
size_t code_size_;
private:
void* machine_code_;
size_t code_size_;
};
} // namespace x64
} // namespace backend
} // namespace alloy
#endif // ALLOY_BACKEND_X64_X64_FUNCTION_H_

View File

@@ -20,14 +20,12 @@ namespace x64 {
class X64Emitter;
void RegisterSequences();
bool SelectSequence(X64Emitter& e, const hir::Instr* i, const hir::Instr** new_tail);
bool SelectSequence(X64Emitter& e, const hir::Instr* i,
const hir::Instr** new_tail);
} // namespace x64
} // namespace backend
} // namespace alloy
#endif // ALLOY_BACKEND_X64_X64_SEQUENCES_H_

View File

@@ -11,21 +11,16 @@
#include <third_party/xbyak/xbyak/xbyak.h>
using namespace alloy;
using namespace alloy::backend;
using namespace alloy::backend::x64;
namespace alloy {
namespace backend {
namespace x64 {
using namespace Xbyak;
X64ThunkEmitter::X64ThunkEmitter(X64Backend* backend, XbyakAllocator* allocator)
: X64Emitter(backend, allocator) {}
X64ThunkEmitter::X64ThunkEmitter(
X64Backend* backend, XbyakAllocator* allocator) :
X64Emitter(backend, allocator) {
}
X64ThunkEmitter::~X64ThunkEmitter() {
}
X64ThunkEmitter::~X64ThunkEmitter() {}
HostToGuestThunk X64ThunkEmitter::EmitHostToGuestThunk() {
// rcx = target
@@ -101,7 +96,7 @@ GuestToHostThunk X64ThunkEmitter::EmitGuestToHostThunk() {
// rdx = target function
// r8 = arg0
// r9 = arg1
const size_t stack_size = StackLayout::THUNK_STACK_SIZE;
// rsp + 0 = return address
mov(qword[rsp + 8 * 2], rdx);
@@ -143,3 +138,7 @@ GuestToHostThunk X64ThunkEmitter::EmitGuestToHostThunk() {
void* fn = Emplace(stack_size);
return (HostToGuestThunk)fn;
}
} // namespace x64
} // namespace backend
} // namespace alloy

View File

@@ -14,12 +14,10 @@
#include <alloy/backend/x64/x64_backend.h>
#include <alloy/backend/x64/x64_emitter.h>
namespace alloy {
namespace backend {
namespace x64 {
/**
* Stack Layout
* ----------------------------
@@ -116,7 +114,7 @@ namespace x64 {
*/
class StackLayout {
public:
public:
const static size_t THUNK_STACK_SIZE = 120;
const static size_t GUEST_STACK_SIZE = 88;
@@ -125,9 +123,8 @@ public:
const static size_t GUEST_CALL_RET_ADDR = 80;
};
class X64ThunkEmitter : public X64Emitter {
public:
public:
X64ThunkEmitter(X64Backend* backend, XbyakAllocator* allocator);
virtual ~X64ThunkEmitter();
@@ -138,10 +135,8 @@ public:
GuestToHostThunk EmitGuestToHostThunk();
};
} // namespace x64
} // namespace backend
} // namespace alloy
#endif // ALLOY_BACKEND_X64_X64_THUNK_EMITTER_H_

View File

@@ -27,9 +27,12 @@ namespace x64 {
#define TARGET_THREAD 1
#define IFLUSH() fflush(stdout)
#define IPRINT if (thread_state->thread_id() == TARGET_THREAD) printf
#define IPRINT \
if (thread_state->thread_id() == TARGET_THREAD) printf
#define DFLUSH() fflush(stdout)
#define DPRINT DFLUSH(); if (thread_state->thread_id() == TARGET_THREAD) printf
#define DPRINT \
DFLUSH(); \
if (thread_state->thread_id() == TARGET_THREAD) printf
uint32_t GetTracingMode() {
uint32_t mode = 0;
@@ -66,7 +69,8 @@ void TraceContextLoadI64(void* raw_context, uint64_t offset, uint64_t value) {
}
void TraceContextLoadF32(void* raw_context, uint64_t offset, __m128 value) {
auto thread_state = *((ThreadState**)raw_context);
DPRINT("%e (%X) = ctx f32 +%d\n", value.m128_f32[0], value.m128_i32[0], offset);
DPRINT("%e (%X) = ctx f32 +%d\n", value.m128_f32[0], value.m128_i32[0],
offset);
}
void TraceContextLoadF64(void* raw_context, uint64_t offset, __m128 value) {
auto thread_state = *((ThreadState**)raw_context);
@@ -80,9 +84,9 @@ void TraceContextLoadF64(void* raw_context, uint64_t offset, __m128 value) {
void TraceContextLoadV128(void* raw_context, uint64_t offset, __m128 value) {
auto thread_state = *((ThreadState**)raw_context);
DPRINT("[%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X] = ctx v128 +%d\n",
value.m128_f32[0], value.m128_f32[1], value.m128_f32[2], value.m128_f32[3],
value.m128_i32[0], value.m128_i32[1], value.m128_i32[2], value.m128_i32[3],
offset);
value.m128_f32[0], value.m128_f32[1], value.m128_f32[2],
value.m128_f32[3], value.m128_i32[0], value.m128_i32[1],
value.m128_i32[2], value.m128_i32[3], offset);
}
void TraceContextStoreI8(void* raw_context, uint64_t offset, uint8_t value) {
@@ -103,7 +107,8 @@ void TraceContextStoreI64(void* raw_context, uint64_t offset, uint64_t value) {
}
void TraceContextStoreF32(void* raw_context, uint64_t offset, __m128 value) {
auto thread_state = *((ThreadState**)raw_context);
DPRINT("ctx f32 +%d = %e (%X)\n", offset, value.m128_i32[0], value.m128_f32[0]);
DPRINT("ctx f32 +%d = %e (%X)\n", offset, value.m128_i32[0],
value.m128_f32[0]);
}
void TraceContextStoreF64(void* raw_context, uint64_t offset, __m128 value) {
auto thread_state = *((ThreadState**)raw_context);
@@ -117,8 +122,9 @@ void TraceContextStoreF64(void* raw_context, uint64_t offset, __m128 value) {
void TraceContextStoreV128(void* raw_context, uint64_t offset, __m128 value) {
auto thread_state = *((ThreadState**)raw_context);
DPRINT("ctx v128 +%d = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n", offset,
value.m128_f32[0], value.m128_f32[1], value.m128_f32[2], value.m128_f32[3],
value.m128_i32[0], value.m128_i32[1], value.m128_i32[2], value.m128_i32[3]);
value.m128_f32[0], value.m128_f32[1], value.m128_f32[2],
value.m128_f32[3], value.m128_i32[0], value.m128_i32[1],
value.m128_i32[2], value.m128_i32[3]);
}
void TraceMemoryLoadI8(void* raw_context, uint64_t address, uint8_t value) {
@@ -139,7 +145,8 @@ void TraceMemoryLoadI64(void* raw_context, uint64_t address, uint64_t value) {
}
void TraceMemoryLoadF32(void* raw_context, uint64_t address, __m128 value) {
auto thread_state = *((ThreadState**)raw_context);
DPRINT("%e (%X) = load.f32 %.8X\n", value.m128_f32[0], value.m128_i32[0], address);
DPRINT("%e (%X) = load.f32 %.8X\n", value.m128_f32[0], value.m128_i32[0],
address);
}
void TraceMemoryLoadF64(void* raw_context, uint64_t address, __m128 value) {
auto thread_state = *((ThreadState**)raw_context);
@@ -153,9 +160,9 @@ void TraceMemoryLoadF64(void* raw_context, uint64_t address, __m128 value) {
void TraceMemoryLoadV128(void* raw_context, uint64_t address, __m128 value) {
auto thread_state = *((ThreadState**)raw_context);
DPRINT("[%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X] = load.v128 %.8X\n",
value.m128_f32[0], value.m128_f32[1], value.m128_f32[2], value.m128_f32[3],
value.m128_i32[0], value.m128_i32[1], value.m128_i32[2], value.m128_i32[3],
address);
value.m128_f32[0], value.m128_f32[1], value.m128_f32[2],
value.m128_f32[3], value.m128_i32[0], value.m128_i32[1],
value.m128_i32[2], value.m128_i32[3], address);
}
void TraceMemoryStoreI8(void* raw_context, uint64_t address, uint8_t value) {
@@ -176,7 +183,8 @@ void TraceMemoryStoreI64(void* raw_context, uint64_t address, uint64_t value) {
}
void TraceMemoryStoreF32(void* raw_context, uint64_t address, __m128 value) {
auto thread_state = *((ThreadState**)raw_context);
DPRINT("store.f32 %.8X = %e (%X)\n", address, value.m128_f32[0], value.m128_i32[0]);
DPRINT("store.f32 %.8X = %e (%X)\n", address, value.m128_f32[0],
value.m128_i32[0]);
}
void TraceMemoryStoreF64(void* raw_context, uint64_t address, __m128 value) {
auto thread_state = *((ThreadState**)raw_context);
@@ -189,12 +197,12 @@ void TraceMemoryStoreF64(void* raw_context, uint64_t address, __m128 value) {
}
void TraceMemoryStoreV128(void* raw_context, uint64_t address, __m128 value) {
auto thread_state = *((ThreadState**)raw_context);
DPRINT("store.v128 %.8X = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n", address,
value.m128_f32[0], value.m128_f32[1], value.m128_f32[2], value.m128_f32[3],
value.m128_i32[0], value.m128_i32[1], value.m128_i32[2], value.m128_i32[3]);
DPRINT("store.v128 %.8X = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n",
address, value.m128_f32[0], value.m128_f32[1], value.m128_f32[2],
value.m128_f32[3], value.m128_i32[0], value.m128_i32[1],
value.m128_i32[2], value.m128_i32[3]);
}
} // namespace x64
} // namespace backend
} // namespace alloy

View File

@@ -16,19 +16,18 @@
#include <xmmintrin.h>
#else
typedef union __declspec(align(16)) __m128 {
float m128_f32[4];
uint64_t m128_u64[2];
int8_t m128_i8[16];
int16_t m128_i16[8];
int32_t m128_i32[4];
int64_t m128_i64[2];
uint8_t m128_u8[16];
uint16_t m128_u16[8];
uint32_t m128_u32[4];
float m128_f32[4];
uint64_t m128_u64[2];
int8_t m128_i8[16];
int16_t m128_i16[8];
int32_t m128_i32[4];
int64_t m128_i64[2];
uint8_t m128_u8[16];
uint16_t m128_u16[8];
uint32_t m128_u32[4];
} __m128;
#endif
namespace alloy {
namespace backend {
namespace x64 {
@@ -81,5 +80,4 @@ void TraceMemoryStoreV128(void* raw_context, uint64_t address, __m128 value);
} // namespace backend
} // namespace alloy
#endif // ALLOY_BACKEND_X64_X64_TRACERS_H_