tests/unicorn: Add type aliases to the Unicorn class

Centralizes all register and vector array definitions to a single set of
aliases, so if these are ever changed, then the rest of the testing code
will follow suit without the need to manually change them.
This commit is contained in:
Lioncash 2018-07-13 13:41:19 -04:00 committed by MerryMage
parent a1d6a86e8c
commit a25bacc436
4 changed files with 41 additions and 36 deletions

View file

@ -148,7 +148,8 @@ static u32 GenFloatInst(u64 pc, bool is_last_inst) {
}
}
static void RunTestInstance(const std::array<u64, 31>& regs, const std::array<Vector, 32>& vecs, const size_t instructions_offset, const std::vector<u32>& instructions, const u32 pstate, const u32 fpcr) {
static void RunTestInstance(const Unicorn::RegisterArray& regs, const Unicorn::VectorArray& vecs, const size_t instructions_offset,
const std::vector<u32>& instructions, const u32 pstate, const u32 fpcr) {
static TestEnv jit_env;
static TestEnv uni_env;
@ -243,8 +244,8 @@ static void RunTestInstance(const std::array<u64, 31>& regs, const std::array<Ve
}
TEST_CASE("A64: Single random instruction", "[a64]") {
std::array<u64, 31> regs;
std::array<Vector, 32> vecs;
Unicorn::RegisterArray regs;
Unicorn::VectorArray vecs;
std::vector<u32> instructions(1);
for (size_t iteration = 0; iteration < 100000; ++iteration) {
@ -356,8 +357,8 @@ TEST_CASE("A64: Floating point instructions", "[a64]") {
return Vector{lower, upper};
};
std::array<u64, 31> regs;
std::array<Vector, 32> vecs;
Unicorn::RegisterArray regs;
Unicorn::VectorArray vecs;
std::vector<u32> instructions(1);
for (size_t iteration = 0; iteration < 100000; ++iteration) {
@ -374,8 +375,8 @@ TEST_CASE("A64: Floating point instructions", "[a64]") {
}
TEST_CASE("A64: Small random block", "[a64]") {
std::array<u64, 31> regs;
std::array<Vector, 32> vecs;
Unicorn::RegisterArray regs;
Unicorn::VectorArray vecs;
std::vector<u32> instructions(5);
for (size_t iteration = 0; iteration < 100000; ++iteration) {

View file

@ -60,18 +60,17 @@ void Unicorn::SetPC(u64 value) {
CHECKED(uc_reg_write(uc, UC_ARM64_REG_PC, &value));
}
constexpr size_t num_gprs = 31;
static const std::array<int, num_gprs> gpr_ids {
constexpr std::array<int, Unicorn::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
};
std::array<u64, 31> Unicorn::GetRegisters() const {
std::array<u64, num_gprs> regs;
std::array<u64*, num_gprs> ptrs;
for (size_t i = 0; i < num_gprs; ++i)
Unicorn::RegisterArray Unicorn::GetRegisters() const {
RegisterArray regs;
RegisterPtrArray ptrs;
for (size_t i = 0; i < ptrs.size(); ++i)
ptrs[i] = &regs[i];
CHECKED(uc_reg_read_batch(uc, const_cast<int*>(gpr_ids.data()),
@ -79,28 +78,26 @@ std::array<u64, 31> Unicorn::GetRegisters() const {
return regs;
}
void Unicorn::SetRegisters(const std::array<u64, 31>& value) {
std::array<const u64*, num_gprs> ptrs;
for (size_t i = 0; i < num_gprs; ++i)
void Unicorn::SetRegisters(const RegisterArray& value) {
RegisterConstPtrArray ptrs;
for (size_t i = 0; i < ptrs.size(); ++i)
ptrs[i] = &value[i];
CHECKED(uc_reg_write_batch(uc, const_cast<int*>(gpr_ids.data()),
reinterpret_cast<void**>(const_cast<u64**>(ptrs.data())), num_gprs));
}
using Vector = Unicorn::Vector;
constexpr size_t num_vecs = 32;
static const std::array<int, num_vecs> vec_ids {
constexpr std::array<int, Unicorn::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
};
std::array<Vector, 32> Unicorn::GetVectors() const {
std::array<Vector, num_vecs> vecs;
std::array<Vector*, num_vecs> ptrs;
for (size_t i = 0; i < num_vecs; ++i)
Unicorn::VectorArray Unicorn::GetVectors() const {
VectorArray vecs;
VectorPtrArray ptrs;
for (size_t i = 0; i < ptrs.size(); ++i)
ptrs[i] = &vecs[i];
CHECKED(uc_reg_read_batch(uc, const_cast<int*>(vec_ids.data()),
@ -109,9 +106,9 @@ std::array<Vector, 32> Unicorn::GetVectors() const {
return vecs;
}
void Unicorn::SetVectors(const std::array<Vector, 32>& value) {
std::array<const Vector*, num_vecs> ptrs;
for (size_t i = 0; i < num_vecs; ++i)
void Unicorn::SetVectors(const VectorArray& value) {
VectorConstPtrArray ptrs;
for (size_t i = 0; i < ptrs.size(); ++i)
ptrs[i] = &value[i];
CHECKED(uc_reg_write_batch(uc, const_cast<int*>(vec_ids.data()),

View file

@ -16,6 +16,16 @@
class Unicorn final {
public:
static constexpr size_t num_gprs = 31;
using RegisterArray = std::array<u64, num_gprs>;
using RegisterPtrArray = std::array<RegisterArray::pointer, num_gprs>;
using RegisterConstPtrArray = std::array<RegisterArray::const_pointer, num_gprs>;
static constexpr size_t num_vecs = 32;
using VectorArray = std::array<Vector, num_vecs>;
using VectorPtrArray = std::array<VectorArray::pointer, num_vecs>;
using VectorConstPtrArray = std::array<VectorArray::const_pointer, num_vecs>;
explicit Unicorn(TestEnv& testenv);
~Unicorn();
@ -27,14 +37,11 @@ public:
u64 GetPC() const;
void SetPC(u64 value);
std::array<u64, 31> GetRegisters() const;
void SetRegisters(const std::array<u64, 31>& value);
RegisterArray GetRegisters() const;
void SetRegisters(const RegisterArray& value);
using Vector = std::array<u64, 2>;
static_assert(sizeof(Vector) == sizeof(u64) * 2);
std::array<Vector, 32> GetVectors() const;
void SetVectors(const std::array<Vector, 32>& value);
VectorArray GetVectors() const;
void SetVectors(const VectorArray& value);
u32 GetFpcr() const;
void SetFpcr(u32 value);

View file

@ -19,7 +19,7 @@ TEST_CASE("Unicorn: Sanity test", "[a64]") {
env.code_mem[0] = 0x8b020020; // ADD X0, X1, X2
env.code_mem[1] = 0x14000000; // B .
std::array<u64, 31> regs {
constexpr Unicorn::RegisterArray regs{
0, 1, 2, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
@ -46,7 +46,7 @@ TEST_CASE("Unicorn: Ensure 0xFFFF'FFFF'FFFF'FFFF is readable", "[a64]") {
env.code_mem[0] = 0x385fed99; // LDRB W25, [X12, #0xfffffffffffffffe]!
env.code_mem[1] = 0x14000000; // B .
std::array<u64, 31> regs{};
Unicorn::RegisterArray regs{};
regs[12] = 1;
Unicorn unicorn{env};
@ -66,7 +66,7 @@ TEST_CASE("Unicorn: Ensure is able to read across page boundaries", "[a64]") {
env.code_mem[0] = 0xb85f93d9; // LDUR W25, [X30, #0xfffffffffffffff9]
env.code_mem[1] = 0x14000000; // B .
std::array<u64, 31> regs{};
Unicorn::RegisterArray regs{};
regs[30] = 4;
Unicorn unicorn{env};