A64/translate/branch: bug: Read-after-write error in BLR
This commit is contained in:
parent
9f57283a30
commit
19da68568e
3 changed files with 18 additions and 7 deletions
|
@ -347,10 +347,18 @@ void A64EmitX64::EmitTerminalImpl(IR::Term::PopRSBHint, IR::LocationDescriptor i
|
|||
}
|
||||
|
||||
void A64EmitX64::EmitTerminalImpl(IR::Term::If terminal, IR::LocationDescriptor initial_location) {
|
||||
switch (terminal.if_) {
|
||||
case IR::Cond::AL:
|
||||
case IR::Cond::NV:
|
||||
EmitTerminal(terminal.then_, initial_location);
|
||||
break;
|
||||
default:
|
||||
Xbyak::Label pass = EmitCond(terminal.if_);
|
||||
EmitTerminal(terminal.else_, initial_location);
|
||||
code->L(pass);
|
||||
EmitTerminal(terminal.then_, initial_location);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void A64EmitX64::EmitTerminalImpl(IR::Term::CheckBit terminal, IR::LocationDescriptor initial_location) {
|
||||
|
|
|
@ -39,10 +39,11 @@ bool TranslatorVisitor::BL(Imm<26> imm26) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::BLR(Reg Rn) {
|
||||
auto target = X(64, Rn);
|
||||
|
||||
X(64, Reg::R30, ir.Imm64(ir.PC() + 4));
|
||||
ir.PushRSB(ir.current_location.AdvancePC(4));
|
||||
|
||||
auto target = X(64, Rn);
|
||||
ir.SetPC(target);
|
||||
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
||||
return false;
|
||||
|
@ -50,6 +51,7 @@ bool TranslatorVisitor::BLR(Reg Rn) {
|
|||
|
||||
bool TranslatorVisitor::BR(Reg Rn) {
|
||||
auto target = X(64, Rn);
|
||||
|
||||
ir.SetPC(target);
|
||||
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
||||
return false;
|
||||
|
@ -57,6 +59,7 @@ bool TranslatorVisitor::BR(Reg Rn) {
|
|||
|
||||
bool TranslatorVisitor::RET(Reg Rn) {
|
||||
auto target = X(64, Rn);
|
||||
|
||||
ir.SetPC(target);
|
||||
ir.SetTerm(IR::Term::PopRSBHint{});
|
||||
return false;
|
||||
|
|
|
@ -129,7 +129,7 @@ static std::string TerminalToString(const Terminal& terminal_variant) {
|
|||
}
|
||||
case 6: {
|
||||
auto terminal = boost::get<IR::Term::If>(terminal_variant);
|
||||
return fmt::format("If{{{}, {}, {}}}", A32::CondToString(terminal.if_), TerminalToString(terminal.then_), TerminalToString(terminal.else_));
|
||||
return fmt::format("If{{{}, {}, {}}}", A64::CondToString(terminal.if_), TerminalToString(terminal.then_), TerminalToString(terminal.else_));
|
||||
}
|
||||
case 7: {
|
||||
auto terminal = boost::get<IR::Term::CheckBit>(terminal_variant);
|
||||
|
@ -149,7 +149,7 @@ std::string DumpBlock(const IR::Block& block) {
|
|||
|
||||
ret += fmt::format("Block: location={}\n", block.Location());
|
||||
ret += fmt::format("cycles={}", block.CycleCount());
|
||||
ret += fmt::format(", entry_cond={}", A32::CondToString(block.GetCondition(), true));
|
||||
ret += fmt::format(", entry_cond={}", A64::CondToString(block.GetCondition()));
|
||||
if (block.GetCondition() != Cond::AL) {
|
||||
ret += fmt::format(", cond_fail={}", block.ConditionFailedLocation());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue