diff --git a/src/backend/A64/constant_pool.cpp b/src/backend/A64/constant_pool.cpp new file mode 100644 index 00000000..c2303b4f --- /dev/null +++ b/src/backend/A64/constant_pool.cpp @@ -0,0 +1,38 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2016 MerryMage + * This software may be used and distributed according to the terms of the GNU + * General Public License version 2 or any later version. + */ + +#include + +#include "backend/A64/block_of_code.h" +#include "backend/A64/constant_pool.h" +#include "common/assert.h" + +namespace Dynarmic::BackendA64 { + +ConstantPool::ConstantPool(BlockOfCode& code, size_t size) : code(code), pool_size(size) {} + +void ConstantPool::AllocatePool() { + code.BRK(0); + pool_begin = const_cast(code.AlignCode16()); + code.AllocateFromCodeSpace(pool_size); + current_pool_ptr = pool_begin; + ASSERT(code.GetCodePtr() - pool_begin == static_cast(pool_size)); +} + +void* ConstantPool::GetConstant(u64 lower, u64 upper) { + const auto constant = std::make_tuple(lower, upper); + auto iter = constant_info.find(constant); + if (iter == constant_info.end()) { + ASSERT(static_cast(current_pool_ptr - pool_begin) < pool_size); + std::memcpy(current_pool_ptr, &lower, sizeof(u64)); + std::memcpy(current_pool_ptr + sizeof(u64), &upper, sizeof(u64)); + iter = constant_info.emplace(constant, current_pool_ptr).first; + current_pool_ptr += align_size; + } + return iter->second; +} + +} // namespace Dynarmic::BackendX64 diff --git a/src/backend/A64/constant_pool.h b/src/backend/A64/constant_pool.h new file mode 100644 index 00000000..f6f65459 --- /dev/null +++ b/src/backend/A64/constant_pool.h @@ -0,0 +1,40 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2016 MerryMage + * This software may be used and distributed according to the terms of the GNU + * General Public License version 2 or any later version. + */ + +#pragma once + +#include + +#include "common/common_types.h" + +namespace Dynarmic::BackendA64 { + +class BlockOfCode; + +/// ConstantPool allocates a block of memory from BlockOfCode. +/// It places constants into this block of memory, returning the address +/// of the memory location where the constant is placed. If the constant +/// already exists, its memory location is reused. +class ConstantPool final { +public: + ConstantPool(BlockOfCode& code, size_t size); + + void AllocatePool(); + + void* GetConstant(u64 lower, u64 upper = 0); + +private: + static constexpr size_t align_size = 16; // bytes + + std::map, void*> constant_info; + + BlockOfCode& code; + size_t pool_size; + u8* pool_begin; + u8* current_pool_ptr; +}; + +} // namespace Dynarmic::BackendA64