A64/translate/branch: bug: Read-after-write error in BLR

This commit is contained in:
MerryMage 2018-01-17 00:34:33 +00:00
parent 9f57283a30
commit 19da68568e
3 changed files with 18 additions and 7 deletions

View file

@ -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) {

View file

@ -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;

View file

@ -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());
} }