Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions src/backend/llvm/branch_targets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,15 @@ BasicBlock *FunctionEmitter::externalDestination(const DolIRTerminator &term,
builder_.CreateRetVoid();
} else {
reloadCallCounters();
for (u32 state = 0; state < DOLIR_STATE_COUNT; state++) {
if (!used_[state])
continue;
auto stateSlot = static_cast<DolIRStateSlot>(state);
builder_.CreateStore(loadContext(stateSlot), state_[state]);
}
// The callee can invalidate anything the emitter had concluded about
// guest state: whether MSR[FP] was already checked, which slots hold
// known constants, whether paired-single addressing was proven.
// Reloading the values without dropping those conclusions leaves
// stateValue() returning a constant the callee has since overwritten.
// The fallback resume path already uses reloadUsedState() for exactly
// this reason; this path reloaded values by hand and skipped the
// invalidation.
reloadUsedState();
builder_.CreateBr(blocks_[continuationBlock]);
}
builder_.restoreIP(saved);
Expand Down
9 changes: 9 additions & 0 deletions src/backend/llvm/register_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ void FunctionEmitter::noteStateWrite(DolIRStateSlot slot, Value *value) {
} else if (slot == DOLIR_STATE_HID2) {
psq_direct_proven_ = false;
psq_indexed_proven_ = false;
} else if (slot == DOLIR_STATE_MSR) {
// MSR[FP] decides whether a floating-point instruction traps, and
// emitFPAvailable caches that answer for the rest of the region. A
// write to MSR can clear FP, so the cached answer has to go. Without
// this an mtmsr that disables FP mid-region leaves the FP
// instructions after it running unchecked, and the guest never takes
// the FP-unavailable exception its lazy FPU context switching is
// built on.
fp_available_checked_ = false;
}
}

Expand Down
Loading