mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 14:00:16 +02:00
OpcodeDispatcher: Emit hints for call/ret instructions
This commit is contained in:
1 parent
261b7f1110
commit
a40d53497b
2 files changed
+29
-11
No files matched your search
@@ -173,7 +173,7 @@ void OpDispatchBuilder::RETOp(OpcodeArgs) {
|
||||
StoreGPRRegister(X86State::REG_RSP, SP);
|
||||
|
||||
// Store the new RIP
|
||||
ExitFunction(NewRIP);
|
||||
ExitFunction(NewRIP, BranchHint::Return);
|
||||
BlockSetRIP = true;
|
||||
}
|
||||
|
||||
@@ -520,22 +520,27 @@ void OpDispatchBuilder::CALLOp(OpcodeArgs) {
|
||||
InvalidatePF_AF();
|
||||
}
|
||||
|
||||
auto ConstantPC = GetRelocatedPC(Op);
|
||||
// Call instruction only uses up to 32-bit signed displacement
|
||||
int64_t TargetOffset = Op->Src[0].Literal();
|
||||
uint64_t InstRIP = Op->PC + Op->InstSize;
|
||||
uint64_t TargetRIP = InstRIP + TargetOffset;
|
||||
|
||||
Ref NewRIP = _Add(GPRSize, ConstantPC, _Constant(TargetOffset));
|
||||
auto NewRIP = GetRelocatedPC(Op, TargetOffset);
|
||||
auto ConstantPC = _Sub(GPRSize, NewRIP, _Constant(TargetOffset));
|
||||
|
||||
// Push the return address.
|
||||
Push(GPRSize, ConstantPC);
|
||||
|
||||
const uint64_t NextRIP = Op->PC + Op->InstSize;
|
||||
uint64_t TargetRIP = NextRIP + TargetOffset;
|
||||
|
||||
if (NextRIP != TargetRIP) {
|
||||
// Store the RIP
|
||||
ExitFunction(NewRIP); // If we get here then leave the function now
|
||||
ExitFunction(NewRIP, BranchHint::Call, ConstantPC, [&]() {
|
||||
auto CallReturnJumpTarget = JumpTargets.find(NextRIP);
|
||||
if (CallReturnJumpTarget != JumpTargets.end() && CallReturnJumpTarget->second.IsEntryPoint) {
|
||||
return CallReturnJumpTarget->second.BlockEntry;
|
||||
}
|
||||
return InvalidNode;
|
||||
}());
|
||||
} else {
|
||||
NeedsBlockEnd = true;
|
||||
}
|
||||
@@ -548,10 +553,18 @@ void OpDispatchBuilder::CALLAbsoluteOp(OpcodeArgs) {
|
||||
Ref JMPPCOffset = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags);
|
||||
|
||||
// Push the return address.
|
||||
Push(Size, GetRelocatedPC(Op));
|
||||
auto ConstantPC = GetRelocatedPC(Op);
|
||||
Push(Size, ConstantPC);
|
||||
|
||||
// Store the RIP
|
||||
ExitFunction(JMPPCOffset); // If we get here then leave the function now
|
||||
const uint64_t NextRIP = Op->PC + Op->InstSize;
|
||||
ExitFunction(JMPPCOffset, BranchHint::Call, ConstantPC, [&]() {
|
||||
auto CallReturnJumpTarget = JumpTargets.find(NextRIP);
|
||||
if (CallReturnJumpTarget != JumpTargets.end() && CallReturnJumpTarget->second.IsEntryPoint) {
|
||||
return CallReturnJumpTarget->second.BlockEntry;
|
||||
}
|
||||
return InvalidNode;
|
||||
}());
|
||||
}
|
||||
|
||||
Ref OpDispatchBuilder::SelectPF(bool Invert, IR::OpSize ResultSize, Ref TrueValue, Ref FalseValue) {
|
||||
@@ -3854,7 +3867,7 @@ void OpDispatchBuilder::CreateJumpBlocks(const fextl::vector<FEXCore::Frontend::
|
||||
for (auto& Target : *Blocks) {
|
||||
auto CodeNode = CreateCodeNode(Target.IsEntryPoint, Target.Entry - Entry);
|
||||
|
||||
JumpTargets.try_emplace(Target.Entry, JumpTargetInfo {CodeNode, false});
|
||||
JumpTargets.try_emplace(Target.Entry, JumpTargetInfo {CodeNode, false, Target.IsEntryPoint});
|
||||
|
||||
if (PrevCodeBlock) {
|
||||
LinkCodeBlocks(PrevCodeBlock, CodeNode);
|
||||
|
||||
@@ -166,9 +166,13 @@ public:
|
||||
auto InlineConst = _InlineConstant(Bit);
|
||||
return _CondJump(Src, InlineConst, InvalidNode, InvalidNode, {Set ? COND_TSTNZ : COND_TSTZ}, OpSize::iInvalid, false);
|
||||
}
|
||||
IRPair<IROp_ExitFunction> ExitFunction(Ref NewRIP) {
|
||||
IRPair<IROp_ExitFunction> ExitFunction(Ref NewRIP, BranchHint Hint = BranchHint::None) {
|
||||
FlushRegisterCache();
|
||||
return _ExitFunction(GetOpSize(NewRIP), NewRIP);
|
||||
return _ExitFunction(GetOpSize(NewRIP), NewRIP, Hint, InvalidNode, InvalidNode);
|
||||
}
|
||||
IRPair<IROp_ExitFunction> ExitFunction(Ref NewRIP, BranchHint Hint, Ref CallReturnAddress, Ref CallReturnBlock) {
|
||||
FlushRegisterCache();
|
||||
return _ExitFunction(GetOpSize(NewRIP), NewRIP, Hint, CallReturnAddress, CallReturnBlock);
|
||||
}
|
||||
IRPair<IROp_Break> Break(BreakDefinition Reason) {
|
||||
FlushRegisterCache();
|
||||
@@ -1319,6 +1323,7 @@ private:
|
||||
struct JumpTargetInfo {
|
||||
Ref BlockEntry;
|
||||
bool HaveEmitted;
|
||||
bool IsEntryPoint;
|
||||
};
|
||||
|
||||
FEXCore::Context::ContextImpl* CTX {};
|
||||
|
||||
Reference in new issue
Block a user