3970 revert fixes crash caused by scheduler
4177 fix mario galaxy and metroid prime 4 not booting

Co-authored-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4187
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
This commit is contained in:
lizzie
2026-07-09 19:02:26 +02:00
committed by crueter
parent 372bdfccbc
commit 3fd6eeaf9f
13 changed files with 418 additions and 396 deletions
@@ -17,14 +17,10 @@ bool TranslatorVisitor::arm_B(Cond cond, Imm<24> imm24) {
if (!ArmConditionPassed(cond)) {
return true;
}
const u32 imm32 = mcl::bit::sign_extend<26, u32>(imm24.ZeroExtend() << 2) + 8;
const auto new_location = ir.current_location.AdvancePC(imm32);
// pattern match => b .
if (imm32 == 0) {
ir.SetTerm(IR::Term::LinkBlock{new_location});
} else {
ir.SetTerm(IR::Term::LinkBlockFast{new_location});
}
ir.SetTerm(IR::Term::LinkBlock{new_location});
return false;
}
@@ -39,7 +35,7 @@ bool TranslatorVisitor::arm_BL(Cond cond, Imm<24> imm24) {
const u32 imm32 = mcl::bit::sign_extend<26, u32>(imm24.ZeroExtend() << 2) + 8;
const auto new_location = ir.current_location.AdvancePC(imm32);
ir.SetTerm(IR::Term::LinkBlockFast{new_location});
ir.SetTerm(IR::Term::LinkBlock{new_location});
return false;
}
@@ -50,7 +46,7 @@ bool TranslatorVisitor::arm_BLX_imm(bool H, Imm<24> imm24) {
const u32 imm32 = mcl::bit::sign_extend<26, u32>((imm24.ZeroExtend() << 2)) + (H ? 2 : 0) + 8;
const auto new_location = ir.current_location.AdvancePC(imm32).SetTFlag(true);
ir.SetTerm(IR::Term::LinkBlockFast{new_location});
ir.SetTerm(IR::Term::LinkBlock{new_location});
return false;
}
@@ -56,10 +56,11 @@ bool TranslatorVisitor::arm_MSR_imm(Cond cond, unsigned mask, int rotate, Imm<8>
if (write_e) {
const bool E = (imm32 & 0x00000200) != 0;
if (E != ir.current_location.EFlag()) {
ir.SetTerm(IR::Term::LinkBlockFast{ir.current_location.AdvancePC(4).SetEFlag(E)});
ir.SetTerm(IR::Term::LinkBlock{ir.current_location.AdvancePC(4).SetEFlag(E)});
return false;
}
}
return true;
}
@@ -111,7 +112,7 @@ bool TranslatorVisitor::arm_RFE() {
// SETEND <endian_specifier>
bool TranslatorVisitor::arm_SETEND(bool E) {
ir.SetTerm(IR::Term::LinkBlockFast{ir.current_location.AdvancePC(4).SetEFlag(E)});
ir.SetTerm(IR::Term::LinkBlock{ir.current_location.AdvancePC(4).SetEFlag(E)});
return false;
}
@@ -803,7 +803,7 @@ bool TranslatorVisitor::thumb16_SETEND(bool E) {
return true;
}
ir.SetTerm(IR::Term::LinkBlockFast{ir.current_location.AdvancePC(2).SetEFlag(E).AdvanceIT()});
ir.SetTerm(IR::Term::LinkBlock{ir.current_location.AdvancePC(2).SetEFlag(E).AdvanceIT()});
return false;
}
@@ -906,8 +906,9 @@ bool TranslatorVisitor::thumb16_CBZ_CBNZ(bool nonzero, Imm<1> i, Imm<5> imm5, Re
ir.SetCheckBit(ir.IsZero(rn));
const auto [cond_pass, cond_fail] = [this, imm, nonzero] {
const auto skip = IR::Term::LinkBlockFast{ir.current_location.AdvancePC(2).AdvanceIT()};
const auto branch = IR::Term::LinkBlockFast{ir.current_location.AdvancePC(imm + 4).AdvanceIT()};
const auto skip = IR::Term::LinkBlock{ir.current_location.AdvancePC(2).AdvanceIT()};
const auto branch = IR::Term::LinkBlock{ir.current_location.AdvancePC(imm + 4).AdvanceIT()};
if (nonzero) {
return std::make_pair(skip, branch);
} else {
@@ -974,10 +975,10 @@ bool TranslatorVisitor::thumb16_B_t1(Cond cond, Imm<8> imm8) {
}
const s32 imm32 = static_cast<s32>((imm8.SignExtend<u32>() << 1) + 4);
const auto then_ = IR::Term::LinkBlockFast{ir.current_location.AdvancePC(imm32).AdvanceIT()};
const auto else_ = IR::Term::LinkBlockFast{ir.current_location.AdvancePC(2).AdvanceIT()};
const auto then_location = ir.current_location.AdvancePC(imm32).AdvanceIT();
const auto else_location = ir.current_location.AdvancePC(2).AdvanceIT();
ir.SetTerm(IR::Term::If{cond, then_, else_});
ir.SetTerm(IR::Term::If{cond, IR::Term::LinkBlock{then_location}, IR::Term::LinkBlock{else_location}});
return false;
}
@@ -989,12 +990,8 @@ bool TranslatorVisitor::thumb16_B_t2(Imm<11> imm11) {
const s32 imm32 = static_cast<s32>((imm11.SignExtend<u32>() << 1) + 4);
const auto next_location = ir.current_location.AdvancePC(imm32).AdvanceIT();
// pattern (b +#0)
if (imm32 == 0) {
ir.SetTerm(IR::Term::LinkBlock{next_location});
} else {
ir.SetTerm(IR::Term::LinkBlockFast{next_location});
}
ir.SetTerm(IR::Term::LinkBlock{next_location});
return false;
}
@@ -23,8 +23,10 @@ bool TranslatorVisitor::thumb32_BL_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j
ir.SetRegister(Reg::LR, ir.Imm32((ir.current_location.PC() + 4) | 1));
const s32 imm32 = static_cast<s32>((concatenate(S, i1, i2, hi, lo).SignExtend<u32>() << 1) + 4);
auto const new_location = ir.current_location.AdvancePC(imm32).AdvanceIT();
ir.SetTerm(IR::Term::LinkBlockFast{new_location});
const auto new_location = ir.current_location
.AdvancePC(imm32)
.AdvanceIT();
ir.SetTerm(IR::Term::LinkBlock{new_location});
return false;
}
@@ -45,8 +47,11 @@ bool TranslatorVisitor::thumb32_BLX_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1>
ir.SetRegister(Reg::LR, ir.Imm32((ir.current_location.PC() + 4) | 1));
const s32 imm32 = static_cast<s32>(concatenate(S, i1, i2, hi, lo).SignExtend<u32>() << 1);
const auto new_location = ir.current_location.SetPC(ir.AlignPC(4) + imm32).SetTFlag(false).AdvanceIT();
ir.SetTerm(IR::Term::LinkBlockFast{new_location});
const auto new_location = ir.current_location
.SetPC(ir.AlignPC(4) + imm32)
.SetTFlag(false)
.AdvanceIT();
ir.SetTerm(IR::Term::LinkBlock{new_location});
return false;
}
@@ -59,13 +64,10 @@ bool TranslatorVisitor::thumb32_B(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Im
}
const s32 imm32 = static_cast<s32>((concatenate(S, i1, i2, hi, lo).SignExtend<u32>() << 1) + 4);
auto const new_location = ir.current_location.AdvancePC(imm32).AdvanceIT();
// Pattern to halt execution (b +#0)
if (imm32 == 0) {
ir.SetTerm(IR::Term::LinkBlock{new_location});
} else {
ir.SetTerm(IR::Term::LinkBlockFast{new_location});
}
const auto new_location = ir.current_location
.AdvancePC(imm32)
.AdvanceIT();
ir.SetTerm(IR::Term::LinkBlock{new_location});
return false;
}
@@ -76,9 +78,13 @@ bool TranslatorVisitor::thumb32_B_cond(Imm<1> S, Cond cond, Imm<6> hi, Imm<1> i1
// Note: i1 and i2 were not inverted from encoding and are opposite compared to the other B instructions.
const s32 imm32 = static_cast<s32>((concatenate(S, i2, i1, hi, lo).SignExtend<u32>() << 1) + 4);
const auto then_ = IR::Term::LinkBlockFast{ir.current_location.AdvancePC(imm32).AdvanceIT()};
const auto else_ = IR::Term::LinkBlockFast{ir.current_location.AdvancePC(4).AdvanceIT()};
ir.SetTerm(IR::Term::If{cond, then_, else_});
const auto then_location = ir.current_location
.AdvancePC(imm32)
.AdvanceIT();
const auto else_location = ir.current_location
.AdvancePC(4)
.AdvanceIT();
ir.SetTerm(IR::Term::If{cond, IR::Term::LinkBlock{then_location}, IR::Term::LinkBlock{else_location}});
return false;
}
@@ -14,8 +14,8 @@ bool TranslatorVisitor::B_cond(Imm<19> imm19, Cond cond) {
const s64 offset = concatenate(imm19, Imm<2>{0}).SignExtend<s64>();
const u64 target = ir.PC() + offset;
const auto cond_pass = IR::Term::LinkBlockFast{ir.current_location->SetPC(target)};
const auto cond_fail = IR::Term::LinkBlockFast{ir.current_location->AdvancePC(4)};
const auto cond_pass = IR::Term::LinkBlock{ir.current_location->SetPC(target)};
const auto cond_fail = IR::Term::LinkBlock{ir.current_location->AdvancePC(4)};
ir.SetTerm(IR::Term::If{cond, cond_pass, cond_fail});
return false;
}
@@ -26,9 +26,9 @@ bool TranslatorVisitor::B_uncond(Imm<26> imm26) {
// Pattern to halt execution (B .)
if (target == ir.PC()) {
ir.SetTerm(IR::Term::LinkBlock{ir.current_location->SetPC(target)});
} else {
ir.SetTerm(IR::Term::LinkBlockFast{ir.current_location->SetPC(target)});
return false;
}
ir.SetTerm(IR::Term::LinkBlockFast{ir.current_location->SetPC(target)});
return false;
}
@@ -79,8 +79,8 @@ bool TranslatorVisitor::CBZ(bool sf, Imm<19> imm19, Reg Rt) {
ir.SetCheckBit(ir.IsZero(operand1));
const u64 target = ir.PC() + offset;
const auto cond_pass = IR::Term::LinkBlockFast{ir.current_location->SetPC(target)};
const auto cond_fail = IR::Term::LinkBlockFast{ir.current_location->AdvancePC(4)};
const auto cond_pass = IR::Term::LinkBlock{ir.current_location->SetPC(target)};
const auto cond_fail = IR::Term::LinkBlock{ir.current_location->AdvancePC(4)};
ir.SetTerm(IR::Term::CheckBit{cond_pass, cond_fail});
return false;
}
@@ -94,8 +94,8 @@ bool TranslatorVisitor::CBNZ(bool sf, Imm<19> imm19, Reg Rt) {
ir.SetCheckBit(ir.IsZero(operand1));
const u64 target = ir.PC() + offset;
const auto cond_pass = IR::Term::LinkBlockFast{ir.current_location->AdvancePC(4)};
const auto cond_fail = IR::Term::LinkBlockFast{ir.current_location->SetPC(target)};
const auto cond_pass = IR::Term::LinkBlock{ir.current_location->AdvancePC(4)};
const auto cond_fail = IR::Term::LinkBlock{ir.current_location->SetPC(target)};
ir.SetTerm(IR::Term::CheckBit{cond_pass, cond_fail});
return false;
}
@@ -110,8 +110,8 @@ bool TranslatorVisitor::TBZ(Imm<1> b5, Imm<5> b40, Imm<14> imm14, Reg Rt) {
ir.SetCheckBit(ir.TestBit(operand, ir.Imm8(bit_pos)));
const u64 target = ir.PC() + offset;
const auto cond_1 = IR::Term::LinkBlockFast{ir.current_location->AdvancePC(4)};
const auto cond_0 = IR::Term::LinkBlockFast{ir.current_location->SetPC(target)};
const auto cond_1 = IR::Term::LinkBlock{ir.current_location->AdvancePC(4)};
const auto cond_0 = IR::Term::LinkBlock{ir.current_location->SetPC(target)};
ir.SetTerm(IR::Term::CheckBit{cond_1, cond_0});
return false;
}
@@ -126,8 +126,8 @@ bool TranslatorVisitor::TBNZ(Imm<1> b5, Imm<5> b40, Imm<14> imm14, Reg Rt) {
ir.SetCheckBit(ir.TestBit(operand, ir.Imm8(bit_pos)));
const u64 target = ir.PC() + offset;
const auto cond_1 = IR::Term::LinkBlockFast{ir.current_location->SetPC(target)};
const auto cond_0 = IR::Term::LinkBlockFast{ir.current_location->AdvancePC(4)};
const auto cond_1 = IR::Term::LinkBlock{ir.current_location->SetPC(target)};
const auto cond_0 = IR::Term::LinkBlock{ir.current_location->AdvancePC(4)};
ir.SetTerm(IR::Term::CheckBit{cond_1, cond_0});
return false;
}