Code cleanup: moving poly/ into xenia/base/
This commit is contained in:
@@ -9,13 +9,13 @@
|
||||
|
||||
#include "xenia/cpu/backend/x64/x64_assembler.h"
|
||||
|
||||
#include "xenia/base/reset_scope.h"
|
||||
#include "xenia/cpu/backend/x64/x64_backend.h"
|
||||
#include "xenia/cpu/backend/x64/x64_emitter.h"
|
||||
#include "xenia/cpu/backend/x64/x64_function.h"
|
||||
#include "xenia/cpu/hir/hir_builder.h"
|
||||
#include "xenia/cpu/hir/label.h"
|
||||
#include "xenia/cpu/runtime.h"
|
||||
#include "poly/reset_scope.h"
|
||||
#include "xenia/profiling.h"
|
||||
|
||||
namespace BE {
|
||||
@@ -65,7 +65,7 @@ int X64Assembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder,
|
||||
SCOPE_profile_cpu_f("cpu");
|
||||
|
||||
// Reset when we leave.
|
||||
poly::make_reset_scope(this);
|
||||
xe::make_reset_scope(this);
|
||||
|
||||
// Lower HIR -> x64.
|
||||
void* machine_code = 0;
|
||||
@@ -95,7 +95,7 @@ int X64Assembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder,
|
||||
}
|
||||
|
||||
void X64Assembler::DumpMachineCode(DebugInfo* debug_info, void* machine_code,
|
||||
size_t code_size, poly::StringBuffer* str) {
|
||||
size_t code_size, StringBuffer* str) {
|
||||
BE::DISASM disasm = {0};
|
||||
disasm.Archi = 64;
|
||||
disasm.Options = BE::Tabulation + BE::MasmSyntax + BE::PrefixedNumeral;
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "xenia/base/string_buffer.h"
|
||||
#include "xenia/cpu/backend/assembler.h"
|
||||
#include "poly/string_buffer.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
@@ -39,14 +39,14 @@ class X64Assembler : public Assembler {
|
||||
|
||||
private:
|
||||
void DumpMachineCode(DebugInfo* debug_info, void* machine_code,
|
||||
size_t code_size, poly::StringBuffer* str);
|
||||
size_t code_size, StringBuffer* str);
|
||||
|
||||
private:
|
||||
X64Backend* x64_backend_;
|
||||
std::unique_ptr<X64Emitter> emitter_;
|
||||
std::unique_ptr<XbyakAllocator> allocator_;
|
||||
|
||||
poly::StringBuffer string_buffer_;
|
||||
StringBuffer string_buffer_;
|
||||
};
|
||||
|
||||
} // namespace x64
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "poly/assert.h"
|
||||
#include "poly/math.h"
|
||||
#include "xenia/base/assert.h"
|
||||
#include "xenia/base/math.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
@@ -51,7 +51,7 @@ void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size,
|
||||
size_t stack_size) {
|
||||
// Always move the code to land on 16b alignment. We do this by rounding up
|
||||
// to 16b so that all offsets are aligned.
|
||||
code_size = poly::round_up(code_size, 16);
|
||||
code_size = xe::round_up(code_size, 16);
|
||||
|
||||
lock_.lock();
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
#include "xenia/cpu/backend/x64/x64_code_cache.h"
|
||||
|
||||
#include "poly/assert.h"
|
||||
#include "poly/math.h"
|
||||
#include "xenia/logging.h"
|
||||
#include "xenia/base/assert.h"
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/base/math.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
@@ -64,11 +64,11 @@ void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size,
|
||||
size_t alloc_size = code_size;
|
||||
|
||||
// Add unwind info into the allocation size. Keep things 16b aligned.
|
||||
alloc_size += poly::round_up(X64CodeChunk::UNWIND_INFO_SIZE, 16);
|
||||
alloc_size += xe::round_up(X64CodeChunk::UNWIND_INFO_SIZE, 16);
|
||||
|
||||
// Always move the code to land on 16b alignment. We do this by rounding up
|
||||
// to 16b so that all offsets are aligned.
|
||||
alloc_size = poly::round_up(alloc_size, 16);
|
||||
alloc_size = xe::round_up(alloc_size, 16);
|
||||
|
||||
lock_.lock();
|
||||
|
||||
@@ -108,7 +108,7 @@ X64CodeChunk::X64CodeChunk(size_t chunk_size)
|
||||
PAGE_EXECUTE_READWRITE);
|
||||
|
||||
fn_table_capacity =
|
||||
static_cast<uint32_t>(poly::round_up(capacity / ESTIMATED_FN_SIZE, 16));
|
||||
static_cast<uint32_t>(xe::round_up(capacity / ESTIMATED_FN_SIZE, 16));
|
||||
size_t table_size = fn_table_capacity * sizeof(RUNTIME_FUNCTION);
|
||||
fn_table = (RUNTIME_FUNCTION*)malloc(table_size);
|
||||
fn_table_count = 0;
|
||||
|
||||
@@ -9,21 +9,21 @@
|
||||
|
||||
#include "xenia/cpu/backend/x64/x64_emitter.h"
|
||||
|
||||
#include "poly/assert.h"
|
||||
#include "poly/math.h"
|
||||
#include "poly/vec128.h"
|
||||
#include "xenia/base/assert.h"
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/base/math.h"
|
||||
#include "xenia/base/vec128.h"
|
||||
#include "xenia/cpu/backend/x64/x64_backend.h"
|
||||
#include "xenia/cpu/backend/x64/x64_code_cache.h"
|
||||
#include "xenia/cpu/backend/x64/x64_function.h"
|
||||
#include "xenia/cpu/backend/x64/x64_sequences.h"
|
||||
#include "xenia/cpu/backend/x64/x64_thunk_emitter.h"
|
||||
#include "xenia/cpu/cpu-private.h"
|
||||
#include "xenia/cpu/hir/hir_builder.h"
|
||||
#include "xenia/cpu/debug_info.h"
|
||||
#include "xenia/cpu/hir/hir_builder.h"
|
||||
#include "xenia/cpu/runtime.h"
|
||||
#include "xenia/cpu/symbol_info.h"
|
||||
#include "xenia/cpu/thread_state.h"
|
||||
#include "xenia/logging.h"
|
||||
#include "xenia/profiling.h"
|
||||
#include "xdb/protocol.h"
|
||||
|
||||
@@ -36,10 +36,6 @@ namespace x64 {
|
||||
using namespace xe::cpu::hir;
|
||||
using namespace xe::cpu;
|
||||
|
||||
using poly::vec128b;
|
||||
using poly::vec128f;
|
||||
using poly::vec128i;
|
||||
|
||||
using namespace Xbyak;
|
||||
using xe::cpu::hir::HIRBuilder;
|
||||
using xe::cpu::hir::Instr;
|
||||
@@ -132,13 +128,13 @@ int X64Emitter::Emit(HIRBuilder* builder, size_t& out_stack_size) {
|
||||
auto slot = *it;
|
||||
size_t type_size = GetTypeSize(slot->type);
|
||||
// Align to natural size.
|
||||
stack_offset = poly::align(stack_offset, type_size);
|
||||
stack_offset = xe::align(stack_offset, type_size);
|
||||
slot->set_constant((uint32_t)stack_offset);
|
||||
stack_offset += type_size;
|
||||
}
|
||||
// Ensure 16b alignment.
|
||||
stack_offset -= StackLayout::GUEST_STACK_SIZE;
|
||||
stack_offset = poly::align(stack_offset, static_cast<size_t>(16));
|
||||
stack_offset = xe::align(stack_offset, static_cast<size_t>(16));
|
||||
|
||||
// Function prolog.
|
||||
// Must be 16b aligned.
|
||||
@@ -536,8 +532,8 @@ uint64_t ResolveFunctionAddress(void* raw_context, uint32_t target_address) {
|
||||
Asm* table_slot = reinterpret_cast<Asm*>(table_start);
|
||||
bool wrote_ic = false;
|
||||
for (int i = 0; i < kICSlotCount; ++i) {
|
||||
if (poly::atomic_cas(kICSlotInvalidTargetAddress, addr,
|
||||
&table_slot->target_constant)) {
|
||||
if (xe::atomic_cas(kICSlotInvalidTargetAddress, addr,
|
||||
&table_slot->target_constant)) {
|
||||
// Got slot! Just write the compare and we're done.
|
||||
table_slot->address_constant = static_cast<uint32_t>(target_address);
|
||||
wrote_ic = true;
|
||||
|
||||
@@ -10,10 +10,11 @@
|
||||
#ifndef XENIA_BACKEND_X64_X64_EMITTER_H_
|
||||
#define XENIA_BACKEND_X64_X64_EMITTER_H_
|
||||
|
||||
#include "xenia/cpu/hir/value.h"
|
||||
#include "poly/arena.h"
|
||||
#include "third_party/xbyak/xbyak/xbyak.h"
|
||||
|
||||
#include "xenia/base/arena.h"
|
||||
#include "xenia/cpu/hir/value.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
class DebugInfo;
|
||||
@@ -32,8 +33,6 @@ namespace cpu {
|
||||
namespace backend {
|
||||
namespace x64 {
|
||||
|
||||
using vec128_t = poly::vec128_t;
|
||||
|
||||
class X64Backend;
|
||||
class X64CodeCache;
|
||||
|
||||
@@ -196,7 +195,7 @@ class X64Emitter : public Xbyak::CodeGenerator {
|
||||
hir::Instr* current_instr_;
|
||||
|
||||
size_t source_map_count_;
|
||||
poly::Arena source_map_arena_;
|
||||
Arena source_map_arena_;
|
||||
|
||||
size_t stack_size_;
|
||||
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
|
||||
#include "xenia/cpu/backend/x64/x64_sequences.h"
|
||||
|
||||
#include "poly/assert.h"
|
||||
#include "poly/threading.h"
|
||||
#include "xenia/base/assert.h"
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/base/threading.h"
|
||||
#include "xenia/cpu/backend/x64/x64_emitter.h"
|
||||
#include "xenia/cpu/backend/x64/x64_tracers.h"
|
||||
#include "xenia/cpu/hir/hir_builder.h"
|
||||
#include "xenia/cpu/runtime.h"
|
||||
#include "xenia/logging.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
@@ -43,8 +43,6 @@ using namespace Xbyak;
|
||||
using namespace xe::cpu::hir;
|
||||
using namespace xe::cpu;
|
||||
|
||||
using poly::vec128b;
|
||||
|
||||
typedef bool (*SequenceSelectFn)(X64Emitter&, const Instr*, const Instr**);
|
||||
std::unordered_multimap<uint32_t, SequenceSelectFn> sequence_table;
|
||||
|
||||
@@ -1022,7 +1020,7 @@ EMITTER(LOAD_VECTOR_SHL_I8, MATCH(I<OPCODE_LOAD_VECTOR_SHL, V128<>, I8<>>)) {
|
||||
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
||||
if (i.src1.is_constant) {
|
||||
auto sh = i.src1.constant();
|
||||
assert_true(sh < poly::countof(lvsl_table));
|
||||
assert_true(sh < xe::countof(lvsl_table));
|
||||
e.mov(e.rax, (uintptr_t)&lvsl_table[sh]);
|
||||
e.vmovaps(i.dest, e.ptr[e.rax]);
|
||||
} else {
|
||||
@@ -1066,7 +1064,7 @@ EMITTER(LOAD_VECTOR_SHR_I8, MATCH(I<OPCODE_LOAD_VECTOR_SHR, V128<>, I8<>>)) {
|
||||
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
||||
if (i.src1.is_constant) {
|
||||
auto sh = i.src1.constant();
|
||||
assert_true(sh < poly::countof(lvsr_table));
|
||||
assert_true(sh < xe::countof(lvsr_table));
|
||||
e.mov(e.rax, (uintptr_t)&lvsr_table[sh]);
|
||||
e.vmovaps(i.dest, e.ptr[e.rax]);
|
||||
} else {
|
||||
@@ -1095,7 +1093,7 @@ EMITTER(LOAD_CLOCK, MATCH(I<OPCODE_LOAD_CLOCK, I64<>>)) {
|
||||
e.mov(i.dest, e.rax);
|
||||
}
|
||||
static uint64_t LoadClock(void* raw_context) {
|
||||
return poly::threading::ticks();
|
||||
return xe::threading::ticks();
|
||||
}
|
||||
};
|
||||
EMITTER_OPCODE_TABLE(
|
||||
@@ -4697,7 +4695,7 @@ EMITTER(VECTOR_ROTATE_LEFT_V128, MATCH(I<OPCODE_VECTOR_ROTATE_LEFT, V128<>, V128
|
||||
_mm_store_si128(reinterpret_cast<__m128i*>(value), src1);
|
||||
_mm_store_si128(reinterpret_cast<__m128i*>(shamt), src2);
|
||||
for (size_t i = 0; i < 16; ++i) {
|
||||
value[i] = poly::rotate_left<uint8_t>(value[i], shamt[i] & 0x7);
|
||||
value[i] = xe::rotate_left<uint8_t>(value[i], shamt[i] & 0x7);
|
||||
}
|
||||
return _mm_load_si128(reinterpret_cast<__m128i*>(value));
|
||||
}
|
||||
@@ -4707,7 +4705,7 @@ EMITTER(VECTOR_ROTATE_LEFT_V128, MATCH(I<OPCODE_VECTOR_ROTATE_LEFT, V128<>, V128
|
||||
_mm_store_si128(reinterpret_cast<__m128i*>(value), src1);
|
||||
_mm_store_si128(reinterpret_cast<__m128i*>(shamt), src2);
|
||||
for (size_t i = 0; i < 8; ++i) {
|
||||
value[i] = poly::rotate_left<uint16_t>(value[i], shamt[i] & 0xF);
|
||||
value[i] = xe::rotate_left<uint16_t>(value[i], shamt[i] & 0xF);
|
||||
}
|
||||
return _mm_load_si128(reinterpret_cast<__m128i*>(value));
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#include "xenia/cpu/backend/x64/x64_tracers.h"
|
||||
|
||||
#include "poly/vec128.h"
|
||||
#include "xenia/base/vec128.h"
|
||||
#include "xenia/cpu/backend/x64/x64_emitter.h"
|
||||
#include "xenia/cpu/runtime.h"
|
||||
#include "xenia/cpu/thread_state.h"
|
||||
@@ -71,23 +71,22 @@ 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 +%llu\n", poly::m128_f32<0>(value),
|
||||
poly::m128_i32<0>(value), offset);
|
||||
DPRINT("%e (%X) = ctx f32 +%llu\n", xe::m128_f32<0>(value),
|
||||
xe::m128_i32<0>(value), offset);
|
||||
}
|
||||
void TraceContextLoadF64(void* raw_context, uint64_t offset,
|
||||
const double* value) {
|
||||
auto thread_state = *((ThreadState**)raw_context);
|
||||
auto v = _mm_loadu_pd(value);
|
||||
DPRINT("%le (%llX) = ctx f64 +%llu\n", poly::m128_f64<0>(v),
|
||||
poly::m128_i64<0>(v), offset);
|
||||
DPRINT("%le (%llX) = ctx f64 +%llu\n", xe::m128_f64<0>(v), xe::m128_i64<0>(v),
|
||||
offset);
|
||||
}
|
||||
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 +%llu\n",
|
||||
poly::m128_f32<0>(value), poly::m128_f32<1>(value),
|
||||
poly::m128_f32<2>(value), poly::m128_f32<3>(value),
|
||||
poly::m128_i32<0>(value), poly::m128_i32<1>(value),
|
||||
poly::m128_i32<2>(value), poly::m128_i32<3>(value), offset);
|
||||
xe::m128_f32<0>(value), xe::m128_f32<1>(value), xe::m128_f32<2>(value),
|
||||
xe::m128_f32<3>(value), xe::m128_i32<0>(value), xe::m128_i32<1>(value),
|
||||
xe::m128_i32<2>(value), xe::m128_i32<3>(value), offset);
|
||||
}
|
||||
|
||||
void TraceContextStoreI8(void* raw_context, uint64_t offset, uint8_t value) {
|
||||
@@ -108,23 +107,22 @@ 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 +%llu = %e (%X)\n", offset, poly::m128_f32<0>(value),
|
||||
poly::m128_i32<0>(value));
|
||||
DPRINT("ctx f32 +%llu = %e (%X)\n", offset, xe::m128_f32<0>(value),
|
||||
xe::m128_i32<0>(value));
|
||||
}
|
||||
void TraceContextStoreF64(void* raw_context, uint64_t offset,
|
||||
const double* value) {
|
||||
auto thread_state = *((ThreadState**)raw_context);
|
||||
auto v = _mm_loadu_pd(value);
|
||||
DPRINT("ctx f64 +%llu = %le (%llX)\n", offset, poly::m128_f64<0>(v),
|
||||
poly::m128_i64<0>(v));
|
||||
DPRINT("ctx f64 +%llu = %le (%llX)\n", offset, xe::m128_f64<0>(v),
|
||||
xe::m128_i64<0>(v));
|
||||
}
|
||||
void TraceContextStoreV128(void* raw_context, uint64_t offset, __m128 value) {
|
||||
auto thread_state = *((ThreadState**)raw_context);
|
||||
DPRINT("ctx v128 +%llu = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n", offset,
|
||||
poly::m128_f32<0>(value), poly::m128_f32<1>(value),
|
||||
poly::m128_f32<2>(value), poly::m128_f32<3>(value),
|
||||
poly::m128_i32<0>(value), poly::m128_i32<1>(value),
|
||||
poly::m128_i32<2>(value), poly::m128_i32<3>(value));
|
||||
xe::m128_f32<0>(value), xe::m128_f32<1>(value), xe::m128_f32<2>(value),
|
||||
xe::m128_f32<3>(value), xe::m128_i32<0>(value), xe::m128_i32<1>(value),
|
||||
xe::m128_i32<2>(value), xe::m128_i32<3>(value));
|
||||
}
|
||||
|
||||
void TraceMemoryLoadI8(void* raw_context, uint32_t address, uint8_t value) {
|
||||
@@ -145,21 +143,20 @@ void TraceMemoryLoadI64(void* raw_context, uint32_t address, uint64_t value) {
|
||||
}
|
||||
void TraceMemoryLoadF32(void* raw_context, uint32_t address, __m128 value) {
|
||||
auto thread_state = *((ThreadState**)raw_context);
|
||||
DPRINT("%e (%X) = load.f32 %.8X\n", poly::m128_f32<0>(value),
|
||||
poly::m128_i32<0>(value), address);
|
||||
DPRINT("%e (%X) = load.f32 %.8X\n", xe::m128_f32<0>(value),
|
||||
xe::m128_i32<0>(value), address);
|
||||
}
|
||||
void TraceMemoryLoadF64(void* raw_context, uint32_t address, __m128 value) {
|
||||
auto thread_state = *((ThreadState**)raw_context);
|
||||
DPRINT("%le (%llX) = load.f64 %.8X\n", poly::m128_f64<0>(value),
|
||||
poly::m128_i64<0>(value), address);
|
||||
DPRINT("%le (%llX) = load.f64 %.8X\n", xe::m128_f64<0>(value),
|
||||
xe::m128_i64<0>(value), address);
|
||||
}
|
||||
void TraceMemoryLoadV128(void* raw_context, uint32_t address, __m128 value) {
|
||||
auto thread_state = *((ThreadState**)raw_context);
|
||||
DPRINT("[%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X] = load.v128 %.8X\n",
|
||||
poly::m128_f32<0>(value), poly::m128_f32<1>(value),
|
||||
poly::m128_f32<2>(value), poly::m128_f32<3>(value),
|
||||
poly::m128_i32<0>(value), poly::m128_i32<1>(value),
|
||||
poly::m128_i32<2>(value), poly::m128_i32<3>(value), address);
|
||||
xe::m128_f32<0>(value), xe::m128_f32<1>(value), xe::m128_f32<2>(value),
|
||||
xe::m128_f32<3>(value), xe::m128_i32<0>(value), xe::m128_i32<1>(value),
|
||||
xe::m128_i32<2>(value), xe::m128_i32<3>(value), address);
|
||||
}
|
||||
|
||||
void TraceMemoryStoreI8(void* raw_context, uint32_t address, uint8_t value) {
|
||||
@@ -180,21 +177,21 @@ void TraceMemoryStoreI64(void* raw_context, uint32_t address, uint64_t value) {
|
||||
}
|
||||
void TraceMemoryStoreF32(void* raw_context, uint32_t address, __m128 value) {
|
||||
auto thread_state = *((ThreadState**)raw_context);
|
||||
DPRINT("store.f32 %.8X = %e (%X)\n", address, poly::m128_f32<0>(value),
|
||||
poly::m128_i32<0>(value));
|
||||
DPRINT("store.f32 %.8X = %e (%X)\n", address, xe::m128_f32<0>(value),
|
||||
xe::m128_i32<0>(value));
|
||||
}
|
||||
void TraceMemoryStoreF64(void* raw_context, uint32_t address, __m128 value) {
|
||||
auto thread_state = *((ThreadState**)raw_context);
|
||||
DPRINT("store.f64 %.8X = %le (%llX)\n", address, poly::m128_f64<0>(value),
|
||||
poly::m128_i64<0>(value));
|
||||
DPRINT("store.f64 %.8X = %le (%llX)\n", address, xe::m128_f64<0>(value),
|
||||
xe::m128_i64<0>(value));
|
||||
}
|
||||
void TraceMemoryStoreV128(void* raw_context, uint32_t address, __m128 value) {
|
||||
auto thread_state = *((ThreadState**)raw_context);
|
||||
DPRINT("store.v128 %.8X = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n",
|
||||
address, poly::m128_f32<0>(value), poly::m128_f32<1>(value),
|
||||
poly::m128_f32<2>(value), poly::m128_f32<3>(value),
|
||||
poly::m128_i32<0>(value), poly::m128_i32<1>(value),
|
||||
poly::m128_i32<2>(value), poly::m128_i32<3>(value));
|
||||
address, xe::m128_f32<0>(value), xe::m128_f32<1>(value),
|
||||
xe::m128_f32<2>(value), xe::m128_f32<3>(value), xe::m128_i32<0>(value),
|
||||
xe::m128_i32<1>(value), xe::m128_i32<2>(value),
|
||||
xe::m128_i32<3>(value));
|
||||
}
|
||||
|
||||
} // namespace x64
|
||||
|
||||
Reference in New Issue
Block a user