From ee339b596015363dbf55414d1fa198a9acb4df70 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Sun, 11 Aug 2024 09:37:32 -0400 Subject: [PATCH] OpcodeDispatcher: optimize POPA Signed-off-by: Alyssa Rosenzweig --- .../Interface/Core/OpcodeDispatcher.cpp | 52 ++++--------------- 1 file changed, 11 insertions(+), 41 deletions(-) diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index de9138b6c..56235a924 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -514,52 +514,22 @@ void OpDispatchBuilder::POPAOp(OpcodeArgs) { // 32bit only const uint8_t Size = GetSrcSize(Op); - auto Constant = _Constant(Size); - auto OldSP = LoadGPRRegister(X86State::REG_RSP); + Ref SP = _RMWHandle(LoadGPRRegister(X86State::REG_RSP)); - // POPA order: - // pop EDI - // pop ESI - // pop EBP - // ESP += 4; // Skip RSP because it'll be correct at the end - // pop EBX - // pop EDX - // pop ECX - // pop EAX + StoreGPRRegister(X86State::REG_RDI, Pop(Size, SP), Size); + StoreGPRRegister(X86State::REG_RSI, Pop(Size, SP), Size); + StoreGPRRegister(X86State::REG_RBP, Pop(Size, SP), Size); - Ref Src {}; - Ref NewSP = OldSP; - Src = _LoadMem(GPRClass, Size, NewSP, Size); - StoreGPRRegister(X86State::REG_RDI, Src, Size); - NewSP = _Add(OpSize::i64Bit, NewSP, Constant); + // Skip loading RSP because it'll be correct at the end + SP = _RMWHandle(_Add(OpSize::i64Bit, SP, _Constant(Size))); - Src = _LoadMem(GPRClass, Size, NewSP, Size); - StoreGPRRegister(X86State::REG_RSI, Src, Size); - NewSP = _Add(OpSize::i64Bit, NewSP, Constant); - - Src = _LoadMem(GPRClass, Size, NewSP, Size); - StoreGPRRegister(X86State::REG_RBP, Src, Size); - NewSP = _Add(OpSize::i64Bit, NewSP, _Constant(Size * 2)); - - // Skip SP loading - Src = _LoadMem(GPRClass, Size, NewSP, Size); - StoreGPRRegister(X86State::REG_RBX, Src, Size); - NewSP = _Add(OpSize::i64Bit, NewSP, Constant); - - Src = _LoadMem(GPRClass, Size, NewSP, Size); - StoreGPRRegister(X86State::REG_RDX, Src, Size); - NewSP = _Add(OpSize::i64Bit, NewSP, Constant); - - Src = _LoadMem(GPRClass, Size, NewSP, Size); - StoreGPRRegister(X86State::REG_RCX, Src, Size); - NewSP = _Add(OpSize::i64Bit, NewSP, Constant); - - Src = _LoadMem(GPRClass, Size, NewSP, Size); - StoreGPRRegister(X86State::REG_RAX, Src, Size); - NewSP = _Add(OpSize::i64Bit, NewSP, Constant); + StoreGPRRegister(X86State::REG_RBX, Pop(Size, SP), Size); + StoreGPRRegister(X86State::REG_RDX, Pop(Size, SP), Size); + StoreGPRRegister(X86State::REG_RCX, Pop(Size, SP), Size); + StoreGPRRegister(X86State::REG_RAX, Pop(Size, SP), Size); // Store the new stack pointer - StoreGPRRegister(X86State::REG_RSP, NewSP); + StoreGPRRegister(X86State::REG_RSP, SP); } template