a32_unicorn: Halt when PC leaves code_mem
This commit is contained in:
parent
331a02e02e
commit
b252636dc3
3 changed files with 13 additions and 18 deletions
|
@ -215,6 +215,8 @@ static void RunTestInstance(Dynarmic::A32::Jit& jit,
|
||||||
|
|
||||||
jit_env.code_mem.resize(code_mem_size);
|
jit_env.code_mem.resize(code_mem_size);
|
||||||
uni_env.code_mem.resize(code_mem_size);
|
uni_env.code_mem.resize(code_mem_size);
|
||||||
|
std::fill(jit_env.code_mem.begin(), jit_env.code_mem.end(), TestEnv::infinite_loop);
|
||||||
|
std::fill(uni_env.code_mem.begin(), uni_env.code_mem.end(), TestEnv::infinite_loop);
|
||||||
|
|
||||||
std::copy(instructions.begin(), instructions.end(), jit_env.code_mem.begin() + num_words);
|
std::copy(instructions.begin(), instructions.end(), jit_env.code_mem.begin() + num_words);
|
||||||
std::copy(instructions.begin(), instructions.end(), uni_env.code_mem.begin() + num_words);
|
std::copy(instructions.begin(), instructions.end(), uni_env.code_mem.begin() + num_words);
|
||||||
|
@ -240,20 +242,7 @@ static void RunTestInstance(Dynarmic::A32::Jit& jit,
|
||||||
jit_env.ticks_left = ticks_left;
|
jit_env.ticks_left = ticks_left;
|
||||||
jit.Run();
|
jit.Run();
|
||||||
|
|
||||||
uni_env.ticks_left = [&]{
|
uni_env.ticks_left = instructions.size(); // Unicorn counts thumb instructions weirdly.
|
||||||
if constexpr (std::is_same_v<TestEnv, ThumbTestEnv>) {
|
|
||||||
// Unicorn counts thumb instructions weirdly:
|
|
||||||
// A 32-bit thumb instruction counts as two.
|
|
||||||
// Except for branch instructions which count as one???
|
|
||||||
if (instructions.size() <= 1)
|
|
||||||
return ticks_left;
|
|
||||||
if ((instructions[instructions.size() - 2] & 0xF800) <= 0xE800)
|
|
||||||
return instructions.size();
|
|
||||||
return instructions.size() - 1;
|
|
||||||
} else {
|
|
||||||
return ticks_left;
|
|
||||||
}
|
|
||||||
}();
|
|
||||||
uni.Run();
|
uni.Run();
|
||||||
|
|
||||||
SCOPE_FAIL {
|
SCOPE_FAIL {
|
||||||
|
|
|
@ -37,18 +37,21 @@ public:
|
||||||
} while (code_mem.size() % 2 != 0);
|
} while (code_mem.size() % 2 != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsInCodeMem(u32 vaddr) const {
|
||||||
|
return vaddr < sizeof(InstructionType) * code_mem.size();
|
||||||
|
}
|
||||||
|
|
||||||
std::uint32_t MemoryReadCode(u32 vaddr) override {
|
std::uint32_t MemoryReadCode(u32 vaddr) override {
|
||||||
const size_t index = vaddr / sizeof(InstructionType);
|
if (IsInCodeMem(vaddr)) {
|
||||||
if (index < code_mem.size()) {
|
|
||||||
u32 value;
|
u32 value;
|
||||||
std::memcpy(&value, &code_mem[index], sizeof(u32));
|
std::memcpy(&value, &code_mem[vaddr / sizeof(InstructionType)], sizeof(u32));
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
return infinite_loop_u32; // B .
|
return infinite_loop_u32; // B .
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint8_t MemoryRead8(u32 vaddr) override {
|
std::uint8_t MemoryRead8(u32 vaddr) override {
|
||||||
if (vaddr < sizeof(InstructionType) * code_mem.size()) {
|
if (IsInCodeMem(vaddr)) {
|
||||||
return reinterpret_cast<u8*>(code_mem.data())[vaddr];
|
return reinterpret_cast<u8*>(code_mem.data())[vaddr];
|
||||||
}
|
}
|
||||||
if (auto iter = modified_memory.find(vaddr); iter != modified_memory.end()) {
|
if (auto iter = modified_memory.find(vaddr); iter != modified_memory.end()) {
|
||||||
|
|
|
@ -44,6 +44,9 @@ void A32Unicorn<TestEnvironment>::Run() {
|
||||||
constexpr u64 pc_mask = std::is_same_v<TestEnvironment, ArmTestEnv> ? 0 : 1;
|
constexpr u64 pc_mask = std::is_same_v<TestEnvironment, ArmTestEnv> ? 0 : 1;
|
||||||
while (testenv.ticks_left > 0) {
|
while (testenv.ticks_left > 0) {
|
||||||
const u32 pc = GetPC() | pc_mask;
|
const u32 pc = GetPC() | pc_mask;
|
||||||
|
if (!testenv.IsInCodeMem(pc)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (auto cerr_ = uc_emu_start(uc, pc, END_ADDRESS, 0, 1)) {
|
if (auto cerr_ = uc_emu_start(uc, pc, END_ADDRESS, 0, 1)) {
|
||||||
ASSERT_MSG(false, "uc_emu_start failed @ {:08x} (code = {:08x}) with error {} ({})", pc, testenv.MemoryReadCode(pc), cerr_, uc_strerror(cerr_));
|
ASSERT_MSG(false, "uc_emu_start failed @ {:08x} (code = {:08x}) with error {} ({})", pc, testenv.MemoryReadCode(pc), cerr_, uc_strerror(cerr_));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue