early-access version 1730
This commit is contained in:
147
externals/dynarmic/tests/unicorn_emu/a32_unicorn.cpp
vendored
147
externals/dynarmic/tests/unicorn_emu/a32_unicorn.cpp
vendored
@@ -3,25 +3,28 @@
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
*/
|
||||
|
||||
#include <type_traits>
|
||||
#include "A32/testenv.h"
|
||||
#include "a32_unicorn.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/bit_util.h"
|
||||
#include "./a32_unicorn.h"
|
||||
|
||||
#define CHECKED(expr) \
|
||||
do { \
|
||||
if (auto cerr_ = (expr)) { \
|
||||
ASSERT_MSG(false, "Call " #expr " failed with error: {} ({})\n", cerr_, \
|
||||
uc_strerror(cerr_)); \
|
||||
} \
|
||||
#include <type_traits>
|
||||
|
||||
#include "../A32/testenv.h"
|
||||
#include "dynarmic/common/assert.h"
|
||||
#include "dynarmic/common/bit_util.h"
|
||||
|
||||
#define CHECKED(expr) \
|
||||
do { \
|
||||
if (auto cerr_ = (expr)) { \
|
||||
ASSERT_MSG(false, "Call " #expr " failed with error: {} ({})\n", cerr_, \
|
||||
uc_strerror(cerr_)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
constexpr u32 BEGIN_ADDRESS = 0;
|
||||
constexpr u32 END_ADDRESS = ~u32(0);
|
||||
|
||||
template <class TestEnvironment>
|
||||
A32Unicorn<TestEnvironment>::A32Unicorn(TestEnvironment& testenv) : testenv{testenv} {
|
||||
template<class TestEnvironment>
|
||||
A32Unicorn<TestEnvironment>::A32Unicorn(TestEnvironment& testenv)
|
||||
: testenv{testenv} {
|
||||
constexpr uc_mode open_mode = std::is_same_v<TestEnvironment, ArmTestEnv> ? UC_MODE_ARM : UC_MODE_THUMB;
|
||||
|
||||
CHECKED(uc_open(UC_ARCH_ARM, open_mode, &uc));
|
||||
@@ -30,7 +33,7 @@ A32Unicorn<TestEnvironment>::A32Unicorn(TestEnvironment& testenv) : testenv{test
|
||||
CHECKED(uc_hook_add(uc, &mem_write_prot_hook, UC_HOOK_MEM_WRITE, (void*)MemoryWriteHook, this, BEGIN_ADDRESS, END_ADDRESS));
|
||||
}
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
A32Unicorn<TestEnvironment>::~A32Unicorn() {
|
||||
ClearPageCache();
|
||||
CHECKED(uc_hook_del(uc, intr_hook));
|
||||
@@ -38,7 +41,7 @@ A32Unicorn<TestEnvironment>::~A32Unicorn() {
|
||||
CHECKED(uc_close(uc));
|
||||
}
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
void A32Unicorn<TestEnvironment>::Run() {
|
||||
// Thumb execution mode requires the LSB to be set to 1.
|
||||
constexpr u64 pc_mask = std::is_same_v<TestEnvironment, ArmTestEnv> ? 0 : 1;
|
||||
@@ -61,36 +64,50 @@ void A32Unicorn<TestEnvironment>::Run() {
|
||||
SetPC(new_pc);
|
||||
}
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
u32 A32Unicorn<TestEnvironment>::GetPC() const {
|
||||
u32 pc;
|
||||
CHECKED(uc_reg_read(uc, UC_ARM_REG_PC, &pc));
|
||||
return pc;
|
||||
}
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
void A32Unicorn<TestEnvironment>::SetPC(u32 value) {
|
||||
CHECKED(uc_reg_write(uc, UC_ARM_REG_PC, &value));
|
||||
}
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
u32 A32Unicorn<TestEnvironment>::GetSP() const {
|
||||
u32 sp;
|
||||
CHECKED(uc_reg_read(uc, UC_ARM_REG_SP, &sp));
|
||||
return sp;
|
||||
}
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
void A32Unicorn<TestEnvironment>::SetSP(u32 value) {
|
||||
CHECKED(uc_reg_write(uc, UC_ARM_REG_SP, &value));
|
||||
}
|
||||
|
||||
constexpr std::array<int, Unicorn::A32::num_gprs> gpr_ids{
|
||||
UC_ARM_REG_R0, UC_ARM_REG_R1, UC_ARM_REG_R2, UC_ARM_REG_R3, UC_ARM_REG_R4, UC_ARM_REG_R5, UC_ARM_REG_R6, UC_ARM_REG_R7,
|
||||
UC_ARM_REG_R8, UC_ARM_REG_R9, UC_ARM_REG_R10, UC_ARM_REG_R11, UC_ARM_REG_R12, UC_ARM_REG_R13, UC_ARM_REG_R14, UC_ARM_REG_R15,
|
||||
UC_ARM_REG_R0,
|
||||
UC_ARM_REG_R1,
|
||||
UC_ARM_REG_R2,
|
||||
UC_ARM_REG_R3,
|
||||
UC_ARM_REG_R4,
|
||||
UC_ARM_REG_R5,
|
||||
UC_ARM_REG_R6,
|
||||
UC_ARM_REG_R7,
|
||||
UC_ARM_REG_R8,
|
||||
UC_ARM_REG_R9,
|
||||
UC_ARM_REG_R10,
|
||||
UC_ARM_REG_R11,
|
||||
UC_ARM_REG_R12,
|
||||
UC_ARM_REG_R13,
|
||||
UC_ARM_REG_R14,
|
||||
UC_ARM_REG_R15,
|
||||
};
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
Unicorn::A32::RegisterArray A32Unicorn<TestEnvironment>::GetRegisters() const {
|
||||
Unicorn::A32::RegisterArray regs{};
|
||||
Unicorn::A32::RegisterPtrArray ptrs;
|
||||
@@ -103,7 +120,7 @@ Unicorn::A32::RegisterArray A32Unicorn<TestEnvironment>::GetRegisters() const {
|
||||
return regs;
|
||||
}
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
void A32Unicorn<TestEnvironment>::SetRegisters(const RegisterArray& value) {
|
||||
Unicorn::A32::RegisterConstPtrArray ptrs;
|
||||
for (size_t i = 0; i < ptrs.size(); ++i) {
|
||||
@@ -114,22 +131,50 @@ void A32Unicorn<TestEnvironment>::SetRegisters(const RegisterArray& value) {
|
||||
reinterpret_cast<void**>(const_cast<u32**>(ptrs.data())), static_cast<int>(ptrs.size())));
|
||||
}
|
||||
|
||||
using DoubleExtRegPtrArray = std::array<Unicorn::A32::ExtRegArray::pointer, Unicorn::A32::num_ext_regs/2>;
|
||||
using DoubleExtRegConstPtrArray = std::array<Unicorn::A32::ExtRegArray::const_pointer, Unicorn::A32::num_ext_regs/2>;
|
||||
using DoubleExtRegPtrArray = std::array<Unicorn::A32::ExtRegArray::pointer, Unicorn::A32::num_ext_regs / 2>;
|
||||
using DoubleExtRegConstPtrArray = std::array<Unicorn::A32::ExtRegArray::const_pointer, Unicorn::A32::num_ext_regs / 2>;
|
||||
|
||||
constexpr std::array<int, Unicorn::A32::num_ext_regs/2> double_ext_reg_ids{
|
||||
UC_ARM_REG_D0, UC_ARM_REG_D1, UC_ARM_REG_D2, UC_ARM_REG_D3, UC_ARM_REG_D4, UC_ARM_REG_D5, UC_ARM_REG_D6, UC_ARM_REG_D7,
|
||||
UC_ARM_REG_D8, UC_ARM_REG_D9, UC_ARM_REG_D10, UC_ARM_REG_D11, UC_ARM_REG_D12, UC_ARM_REG_D13, UC_ARM_REG_D14, UC_ARM_REG_D15,
|
||||
UC_ARM_REG_D16, UC_ARM_REG_D17, UC_ARM_REG_D18, UC_ARM_REG_D19, UC_ARM_REG_D20, UC_ARM_REG_D21, UC_ARM_REG_D22, UC_ARM_REG_D23,
|
||||
UC_ARM_REG_D24, UC_ARM_REG_D25, UC_ARM_REG_D26, UC_ARM_REG_D27, UC_ARM_REG_D28, UC_ARM_REG_D29, UC_ARM_REG_D30, UC_ARM_REG_D31,
|
||||
constexpr std::array<int, Unicorn::A32::num_ext_regs / 2> double_ext_reg_ids{
|
||||
UC_ARM_REG_D0,
|
||||
UC_ARM_REG_D1,
|
||||
UC_ARM_REG_D2,
|
||||
UC_ARM_REG_D3,
|
||||
UC_ARM_REG_D4,
|
||||
UC_ARM_REG_D5,
|
||||
UC_ARM_REG_D6,
|
||||
UC_ARM_REG_D7,
|
||||
UC_ARM_REG_D8,
|
||||
UC_ARM_REG_D9,
|
||||
UC_ARM_REG_D10,
|
||||
UC_ARM_REG_D11,
|
||||
UC_ARM_REG_D12,
|
||||
UC_ARM_REG_D13,
|
||||
UC_ARM_REG_D14,
|
||||
UC_ARM_REG_D15,
|
||||
UC_ARM_REG_D16,
|
||||
UC_ARM_REG_D17,
|
||||
UC_ARM_REG_D18,
|
||||
UC_ARM_REG_D19,
|
||||
UC_ARM_REG_D20,
|
||||
UC_ARM_REG_D21,
|
||||
UC_ARM_REG_D22,
|
||||
UC_ARM_REG_D23,
|
||||
UC_ARM_REG_D24,
|
||||
UC_ARM_REG_D25,
|
||||
UC_ARM_REG_D26,
|
||||
UC_ARM_REG_D27,
|
||||
UC_ARM_REG_D28,
|
||||
UC_ARM_REG_D29,
|
||||
UC_ARM_REG_D30,
|
||||
UC_ARM_REG_D31,
|
||||
};
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
Unicorn::A32::ExtRegArray A32Unicorn<TestEnvironment>::GetExtRegs() const {
|
||||
Unicorn::A32::ExtRegArray ext_regs{};
|
||||
DoubleExtRegPtrArray ptrs;
|
||||
for (size_t i = 0; i < ptrs.size(); ++i)
|
||||
ptrs[i] = &ext_regs[i*2];
|
||||
ptrs[i] = &ext_regs[i * 2];
|
||||
|
||||
CHECKED(uc_reg_read_batch(uc, const_cast<int*>(double_ext_reg_ids.data()),
|
||||
reinterpret_cast<void**>(ptrs.data()), static_cast<int>(ptrs.size())));
|
||||
@@ -137,60 +182,60 @@ Unicorn::A32::ExtRegArray A32Unicorn<TestEnvironment>::GetExtRegs() const {
|
||||
return ext_regs;
|
||||
}
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
void A32Unicorn<TestEnvironment>::SetExtRegs(const ExtRegArray& value) {
|
||||
DoubleExtRegConstPtrArray ptrs;
|
||||
for (size_t i = 0; i < ptrs.size(); ++i) {
|
||||
ptrs[i] = &value[i*2];
|
||||
ptrs[i] = &value[i * 2];
|
||||
}
|
||||
|
||||
CHECKED(uc_reg_write_batch(uc, const_cast<int*>(double_ext_reg_ids.data()),
|
||||
reinterpret_cast<void* const *>(const_cast<u32**>(ptrs.data())), static_cast<int>(ptrs.size())));
|
||||
reinterpret_cast<void* const*>(const_cast<u32**>(ptrs.data())), static_cast<int>(ptrs.size())));
|
||||
}
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
u32 A32Unicorn<TestEnvironment>::GetFpscr() const {
|
||||
u32 fpsr;
|
||||
CHECKED(uc_reg_read(uc, UC_ARM_REG_FPSCR, &fpsr));
|
||||
return fpsr;
|
||||
}
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
void A32Unicorn<TestEnvironment>::SetFpscr(u32 value) {
|
||||
CHECKED(uc_reg_write(uc, UC_ARM_REG_FPSCR, &value));
|
||||
}
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
u32 A32Unicorn<TestEnvironment>::GetFpexc() const {
|
||||
u32 value = 0;
|
||||
CHECKED(uc_reg_read(uc, UC_ARM_REG_FPEXC, &value));
|
||||
return value;
|
||||
}
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
void A32Unicorn<TestEnvironment>::SetFpexc(u32 value) {
|
||||
CHECKED(uc_reg_write(uc, UC_ARM_REG_FPEXC, &value));
|
||||
}
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
u32 A32Unicorn<TestEnvironment>::GetCpsr() const {
|
||||
u32 pstate;
|
||||
CHECKED(uc_reg_read(uc, UC_ARM_REG_CPSR, &pstate));
|
||||
return pstate;
|
||||
}
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
void A32Unicorn<TestEnvironment>::SetCpsr(u32 value) {
|
||||
CHECKED(uc_reg_write(uc, UC_ARM_REG_CPSR, &value));
|
||||
}
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
void A32Unicorn<TestEnvironment>::EnableFloatingPointAccess() {
|
||||
const u32 new_fpexc = GetFpexc() | (1U << 30);
|
||||
SetFpexc(new_fpexc);
|
||||
}
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
void A32Unicorn<TestEnvironment>::ClearPageCache() {
|
||||
for (const auto& page : pages) {
|
||||
CHECKED(uc_mem_unmap(uc, page->address, 4096));
|
||||
@@ -198,7 +243,7 @@ void A32Unicorn<TestEnvironment>::ClearPageCache() {
|
||||
pages.clear();
|
||||
}
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
void A32Unicorn<TestEnvironment>::DumpMemoryInformation() {
|
||||
uc_mem_region* regions;
|
||||
u32 count;
|
||||
@@ -211,7 +256,7 @@ void A32Unicorn<TestEnvironment>::DumpMemoryInformation() {
|
||||
CHECKED(uc_free(regions));
|
||||
}
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
void A32Unicorn<TestEnvironment>::InterruptHook(uc_engine* /*uc*/, u32 int_number, void* user_data) {
|
||||
auto* this_ = static_cast<A32Unicorn*>(user_data);
|
||||
|
||||
@@ -222,7 +267,7 @@ void A32Unicorn<TestEnvironment>::InterruptHook(uc_engine* /*uc*/, u32 int_numbe
|
||||
auto iss = esr & 0xFFFFFF;
|
||||
|
||||
switch (ec) {
|
||||
case 0x15: // SVC
|
||||
case 0x15: // SVC
|
||||
this_->testenv.CallSVC(iss);
|
||||
break;
|
||||
default:
|
||||
@@ -231,7 +276,7 @@ void A32Unicorn<TestEnvironment>::InterruptHook(uc_engine* /*uc*/, u32 int_numbe
|
||||
}
|
||||
}
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
bool A32Unicorn<TestEnvironment>::UnmappedMemoryHook(uc_engine* uc, uc_mem_type /*type*/, u32 start_address, int size, u64 /*value*/, void* user_data) {
|
||||
auto* this_ = static_cast<A32Unicorn*>(user_data);
|
||||
|
||||
@@ -252,7 +297,7 @@ bool A32Unicorn<TestEnvironment>::UnmappedMemoryHook(uc_engine* uc, uc_mem_type
|
||||
|
||||
uc_err err = uc_mem_map_ptr(uc, base_address, page->data.size(), permissions, page->data.data());
|
||||
if (err == UC_ERR_MAP)
|
||||
return; // page already exists
|
||||
return; // page already exists
|
||||
CHECKED(err);
|
||||
|
||||
this_->pages.emplace_back(std::move(page));
|
||||
@@ -260,8 +305,8 @@ bool A32Unicorn<TestEnvironment>::UnmappedMemoryHook(uc_engine* uc, uc_mem_type
|
||||
|
||||
const auto is_in_range = [](u32 addr, u32 start, u32 end) {
|
||||
if (start <= end)
|
||||
return addr >= start && addr <= end; // fffff[tttttt]fffff
|
||||
return addr >= start || addr <= end; // ttttt]ffffff[ttttt
|
||||
return addr >= start && addr <= end; // fffff[tttttt]fffff
|
||||
return addr >= start || addr <= end; // ttttt]ffffff[ttttt
|
||||
};
|
||||
|
||||
const u32 start_address_page = start_address & ~u32(0xFFF);
|
||||
@@ -276,7 +321,7 @@ bool A32Unicorn<TestEnvironment>::UnmappedMemoryHook(uc_engine* uc, uc_mem_type
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
bool A32Unicorn<TestEnvironment>::MemoryWriteHook(uc_engine* /*uc*/, uc_mem_type /*type*/, u32 start_address, int size, u64 value, void* user_data) {
|
||||
auto* this_ = static_cast<A32Unicorn*>(user_data);
|
||||
|
||||
|
@@ -9,16 +9,15 @@
|
||||
#include <vector>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push, 0)
|
||||
#include <unicorn/unicorn.h>
|
||||
#pragma warning(pop)
|
||||
# pragma warning(push, 0)
|
||||
# include <unicorn/unicorn.h>
|
||||
# pragma warning(pop)
|
||||
#else
|
||||
#include <unicorn/unicorn.h>
|
||||
# include <unicorn/unicorn.h>
|
||||
#endif
|
||||
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "A32/testenv.h"
|
||||
#include "../A32/testenv.h"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
|
||||
namespace Unicorn::A32 {
|
||||
static constexpr size_t num_gprs = 16;
|
||||
@@ -28,9 +27,9 @@ using ExtRegArray = std::array<u32, num_ext_regs>;
|
||||
using RegisterArray = std::array<u32, num_gprs>;
|
||||
using RegisterPtrArray = std::array<RegisterArray::pointer, num_gprs>;
|
||||
using RegisterConstPtrArray = std::array<RegisterArray::const_pointer, num_gprs>;
|
||||
} // namespace Unicorn::A32
|
||||
} // namespace Unicorn::A32
|
||||
|
||||
template <class TestEnvironment>
|
||||
template<class TestEnvironment>
|
||||
class A32Unicorn final {
|
||||
public:
|
||||
using ExtRegArray = Unicorn::A32::ExtRegArray;
|
||||
|
@@ -3,21 +3,23 @@
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
*/
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "a64_unicorn.h"
|
||||
#include "./a64_unicorn.h"
|
||||
|
||||
#define CHECKED(expr) \
|
||||
do { \
|
||||
if (auto cerr_ = (expr)) { \
|
||||
ASSERT_MSG(false, "Call " #expr " failed with error: {} ({})\n", cerr_, \
|
||||
uc_strerror(cerr_)); \
|
||||
} \
|
||||
#include "dynarmic/common/assert.h"
|
||||
|
||||
#define CHECKED(expr) \
|
||||
do { \
|
||||
if (auto cerr_ = (expr)) { \
|
||||
ASSERT_MSG(false, "Call " #expr " failed with error: {} ({})\n", cerr_, \
|
||||
uc_strerror(cerr_)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
constexpr u64 BEGIN_ADDRESS = 0;
|
||||
constexpr u64 END_ADDRESS = ~u64(0);
|
||||
|
||||
A64Unicorn::A64Unicorn(A64TestEnv& testenv) : testenv(testenv) {
|
||||
A64Unicorn::A64Unicorn(A64TestEnv& testenv)
|
||||
: testenv(testenv) {
|
||||
CHECKED(uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc));
|
||||
u64 fpv = 3 << 20;
|
||||
CHECKED(uc_reg_write(uc, UC_ARM64_REG_CPACR_EL1, &fpv));
|
||||
@@ -66,8 +68,7 @@ constexpr std::array<int, A64Unicorn::num_gprs> gpr_ids{
|
||||
UC_ARM64_REG_X0, UC_ARM64_REG_X1, UC_ARM64_REG_X2, UC_ARM64_REG_X3, UC_ARM64_REG_X4, UC_ARM64_REG_X5, UC_ARM64_REG_X6, UC_ARM64_REG_X7,
|
||||
UC_ARM64_REG_X8, UC_ARM64_REG_X9, UC_ARM64_REG_X10, UC_ARM64_REG_X11, UC_ARM64_REG_X12, UC_ARM64_REG_X13, UC_ARM64_REG_X14, UC_ARM64_REG_X15,
|
||||
UC_ARM64_REG_X16, UC_ARM64_REG_X17, UC_ARM64_REG_X18, UC_ARM64_REG_X19, UC_ARM64_REG_X20, UC_ARM64_REG_X21, UC_ARM64_REG_X22, UC_ARM64_REG_X23,
|
||||
UC_ARM64_REG_X24, UC_ARM64_REG_X25, UC_ARM64_REG_X26, UC_ARM64_REG_X27, UC_ARM64_REG_X28, UC_ARM64_REG_X29, UC_ARM64_REG_X30
|
||||
};
|
||||
UC_ARM64_REG_X24, UC_ARM64_REG_X25, UC_ARM64_REG_X26, UC_ARM64_REG_X27, UC_ARM64_REG_X28, UC_ARM64_REG_X29, UC_ARM64_REG_X30};
|
||||
|
||||
A64Unicorn::RegisterArray A64Unicorn::GetRegisters() const {
|
||||
RegisterArray regs{};
|
||||
@@ -93,8 +94,7 @@ constexpr std::array<int, A64Unicorn::num_vecs> vec_ids{
|
||||
UC_ARM64_REG_Q0, UC_ARM64_REG_Q1, UC_ARM64_REG_Q2, UC_ARM64_REG_Q3, UC_ARM64_REG_Q4, UC_ARM64_REG_Q5, UC_ARM64_REG_Q6, UC_ARM64_REG_Q7,
|
||||
UC_ARM64_REG_Q8, UC_ARM64_REG_Q9, UC_ARM64_REG_Q10, UC_ARM64_REG_Q11, UC_ARM64_REG_Q12, UC_ARM64_REG_Q13, UC_ARM64_REG_Q14, UC_ARM64_REG_Q15,
|
||||
UC_ARM64_REG_Q16, UC_ARM64_REG_Q17, UC_ARM64_REG_Q18, UC_ARM64_REG_Q19, UC_ARM64_REG_Q20, UC_ARM64_REG_Q21, UC_ARM64_REG_Q22, UC_ARM64_REG_Q23,
|
||||
UC_ARM64_REG_Q24, UC_ARM64_REG_Q25, UC_ARM64_REG_Q26, UC_ARM64_REG_Q27, UC_ARM64_REG_Q28, UC_ARM64_REG_Q29, UC_ARM64_REG_Q30, UC_ARM64_REG_Q31
|
||||
};
|
||||
UC_ARM64_REG_Q24, UC_ARM64_REG_Q25, UC_ARM64_REG_Q26, UC_ARM64_REG_Q27, UC_ARM64_REG_Q28, UC_ARM64_REG_Q29, UC_ARM64_REG_Q30, UC_ARM64_REG_Q31};
|
||||
|
||||
A64Unicorn::VectorArray A64Unicorn::GetVectors() const {
|
||||
VectorArray vecs{};
|
||||
@@ -114,7 +114,7 @@ void A64Unicorn::SetVectors(const VectorArray& value) {
|
||||
ptrs[i] = &value[i];
|
||||
|
||||
CHECKED(uc_reg_write_batch(uc, const_cast<int*>(vec_ids.data()),
|
||||
reinterpret_cast<void* const *>(const_cast<Vector**>(ptrs.data())), static_cast<int>(num_vecs)));
|
||||
reinterpret_cast<void* const*>(const_cast<Vector**>(ptrs.data())), static_cast<int>(num_vecs)));
|
||||
}
|
||||
|
||||
u32 A64Unicorn::GetFpcr() const {
|
||||
@@ -176,7 +176,7 @@ void A64Unicorn::InterruptHook(uc_engine* uc, u32 int_number, void* user_data) {
|
||||
auto iss = esr & 0xFFFFFF;
|
||||
|
||||
switch (ec) {
|
||||
case 0x15: // SVC
|
||||
case 0x15: // SVC
|
||||
this_->testenv.CallSVC(iss);
|
||||
break;
|
||||
default:
|
||||
@@ -204,7 +204,7 @@ bool A64Unicorn::UnmappedMemoryHook(uc_engine* uc, uc_mem_type /*type*/, u64 sta
|
||||
|
||||
uc_err err = uc_mem_map_ptr(uc, base_address, page->data.size(), permissions, page->data.data());
|
||||
if (err == UC_ERR_MAP)
|
||||
return; // page already exists
|
||||
return; // page already exists
|
||||
CHECKED(err);
|
||||
|
||||
this_->pages.emplace_back(std::move(page));
|
||||
@@ -212,8 +212,8 @@ bool A64Unicorn::UnmappedMemoryHook(uc_engine* uc, uc_mem_type /*type*/, u64 sta
|
||||
|
||||
const auto is_in_range = [](u64 addr, u64 start, u64 end) {
|
||||
if (start <= end)
|
||||
return addr >= start && addr <= end; // fffff[tttttt]fffff
|
||||
return addr >= start || addr <= end; // ttttt]ffffff[ttttt
|
||||
return addr >= start && addr <= end; // fffff[tttttt]fffff
|
||||
return addr >= start || addr <= end; // ttttt]ffffff[ttttt
|
||||
};
|
||||
|
||||
const u64 start_address_page = start_address & ~u64(0xFFF);
|
||||
|
@@ -9,15 +9,15 @@
|
||||
#include <vector>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push, 0)
|
||||
#include <unicorn/unicorn.h>
|
||||
#pragma warning(pop)
|
||||
# pragma warning(push, 0)
|
||||
# include <unicorn/unicorn.h>
|
||||
# pragma warning(pop)
|
||||
#else
|
||||
#include <unicorn/unicorn.h>
|
||||
# include <unicorn/unicorn.h>
|
||||
#endif
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "A64/testenv.h"
|
||||
#include "../A64/testenv.h"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
|
||||
class A64Unicorn final {
|
||||
public:
|
||||
|
Reference in New Issue
Block a user