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) {
|
void A64EmitX64::EmitTerminalImpl(IR::Term::If terminal, IR::LocationDescriptor initial_location) {
|
||||||
Xbyak::Label pass = EmitCond(terminal.if_);
|
switch (terminal.if_) {
|
||||||
EmitTerminal(terminal.else_, initial_location);
|
case IR::Cond::AL:
|
||||||
code->L(pass);
|
case IR::Cond::NV:
|
||||||
EmitTerminal(terminal.then_, initial_location);
|
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) {
|
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) {
|
bool TranslatorVisitor::BLR(Reg Rn) {
|
||||||
|
auto target = X(64, Rn);
|
||||||
|
|
||||||
X(64, Reg::R30, ir.Imm64(ir.PC() + 4));
|
X(64, Reg::R30, ir.Imm64(ir.PC() + 4));
|
||||||
ir.PushRSB(ir.current_location.AdvancePC(4));
|
ir.PushRSB(ir.current_location.AdvancePC(4));
|
||||||
|
|
||||||
auto target = X(64, Rn);
|
|
||||||
ir.SetPC(target);
|
ir.SetPC(target);
|
||||||
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
||||||
return false;
|
return false;
|
||||||
|
@ -50,6 +51,7 @@ bool TranslatorVisitor::BLR(Reg Rn) {
|
||||||
|
|
||||||
bool TranslatorVisitor::BR(Reg Rn) {
|
bool TranslatorVisitor::BR(Reg Rn) {
|
||||||
auto target = X(64, Rn);
|
auto target = X(64, Rn);
|
||||||
|
|
||||||
ir.SetPC(target);
|
ir.SetPC(target);
|
||||||
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
||||||
return false;
|
return false;
|
||||||
|
@ -57,6 +59,7 @@ bool TranslatorVisitor::BR(Reg Rn) {
|
||||||
|
|
||||||
bool TranslatorVisitor::RET(Reg Rn) {
|
bool TranslatorVisitor::RET(Reg Rn) {
|
||||||
auto target = X(64, Rn);
|
auto target = X(64, Rn);
|
||||||
|
|
||||||
ir.SetPC(target);
|
ir.SetPC(target);
|
||||||
ir.SetTerm(IR::Term::PopRSBHint{});
|
ir.SetTerm(IR::Term::PopRSBHint{});
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -129,7 +129,7 @@ static std::string TerminalToString(const Terminal& terminal_variant) {
|
||||||
}
|
}
|
||||||
case 6: {
|
case 6: {
|
||||||
auto terminal = boost::get<IR::Term::If>(terminal_variant);
|
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: {
|
case 7: {
|
||||||
auto terminal = boost::get<IR::Term::CheckBit>(terminal_variant);
|
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("Block: location={}\n", block.Location());
|
||||||
ret += fmt::format("cycles={}", block.CycleCount());
|
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) {
|
if (block.GetCondition() != Cond::AL) {
|
||||||
ret += fmt::format(", cond_fail={}", block.ConditionFailedLocation());
|
ret += fmt::format(", cond_fail={}", block.ConditionFailedLocation());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue