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);
|
||||
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(), 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.Run();
|
||||
|
||||
uni_env.ticks_left = [&]{
|
||||
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_env.ticks_left = instructions.size(); // Unicorn counts thumb instructions weirdly.
|
||||
uni.Run();
|
||||
|
||||
SCOPE_FAIL {
|
||||
|
|
|
@ -37,18 +37,21 @@ public:
|
|||
} 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 {
|
||||
const size_t index = vaddr / sizeof(InstructionType);
|
||||
if (index < code_mem.size()) {
|
||||
if (IsInCodeMem(vaddr)) {
|
||||
u32 value;
|
||||
std::memcpy(&value, &code_mem[index], sizeof(u32));
|
||||
std::memcpy(&value, &code_mem[vaddr / sizeof(InstructionType)], sizeof(u32));
|
||||
return value;
|
||||
}
|
||||
return infinite_loop_u32; // B .
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
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;
|
||||
while (testenv.ticks_left > 0) {
|
||||
const u32 pc = GetPC() | pc_mask;
|
||||
if (!testenv.IsInCodeMem(pc)) {
|
||||
return;
|
||||
}
|
||||
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_));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue