Running clang-format on alloy.
All except x64_sequences, which needs work.
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user