From 574fdcef32d0b8c49a62cab740fe6be737312929 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Mon, 8 Apr 2024 11:55:29 -0700 Subject: [PATCH] JIT: Adds support for spilling/Filling GPRPair Tony noticed this last week. I encountered it this week. Add support for spilling and filling GPR pairs. --- .../Interface/Core/JIT/Arm64/MemoryOps.cpp | 59 ++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/FEXCore/Source/Interface/Core/JIT/Arm64/MemoryOps.cpp b/FEXCore/Source/Interface/Core/JIT/Arm64/MemoryOps.cpp index d051d20f14..fe4bf03db5 100644 --- a/FEXCore/Source/Interface/Core/JIT/Arm64/MemoryOps.cpp +++ b/FEXCore/Source/Interface/Core/JIT/Arm64/MemoryOps.cpp @@ -771,7 +771,36 @@ DEF_OP(SpillRegister) { LOGMAN_MSG_A_FMT("Unhandled SpillRegister size: {}", OpSize); break; } - } else { + } else if (Op->Class == FEXCore::IR::GPRPairClass) { + const auto Src = GetRegPair(Op->Value.ID()); + switch (OpSize) { + case 8: { + if (SlotOffset <= 252 && (SlotOffset & 0b11) == 0) { + stp(Src.first.W(), Src.second.W(), ARMEmitter::Reg::rsp, SlotOffset); + } + else { + add(ARMEmitter::Size::i64Bit, TMP1, ARMEmitter::Reg::rsp, SlotOffset); + stp(Src.first.W(), Src.second.W(), TMP1, 0); + } + break; + } + + case 16: { + if (SlotOffset <= 504 && (SlotOffset & 0b111) == 0) { + stp(Src.first.X(), Src.second.X(), ARMEmitter::Reg::rsp, SlotOffset); + } + else { + add(ARMEmitter::Size::i64Bit, TMP1, ARMEmitter::Reg::rsp, SlotOffset); + stp(Src.first.X(), Src.second.X(), TMP1, 0); + } + break; + } + default: + LOGMAN_MSG_A_FMT("Unhandled SpillRegister(GPRPair) size: {}", OpSize); + break; + } + } + else { LOGMAN_MSG_A_FMT("Unhandled SpillRegister class: {}", Op->Class.Val); } } @@ -871,6 +900,34 @@ DEF_OP(FillRegister) { LOGMAN_MSG_A_FMT("Unhandled FillRegister size: {}", OpSize); break; } + } else if (Op->Class == FEXCore::IR::GPRPairClass) { + const auto Src = GetRegPair(Node); + switch (OpSize) { + case 8: { + if (SlotOffset <= 252 && (SlotOffset & 0b11) == 0) { + ldp(Src.first.W(), Src.second.W(), ARMEmitter::Reg::rsp, SlotOffset); + } + else { + add(ARMEmitter::Size::i64Bit, TMP1, ARMEmitter::Reg::rsp, SlotOffset); + ldp(Src.first.W(), Src.second.W(), TMP1, 0); + } + break; + } + + case 16: { + if (SlotOffset <= 504 && (SlotOffset & 0b111) == 0) { + ldp(Src.first.X(), Src.second.X(), ARMEmitter::Reg::rsp, SlotOffset); + } + else { + add(ARMEmitter::Size::i64Bit, TMP1, ARMEmitter::Reg::rsp, SlotOffset); + ldp(Src.first.X(), Src.second.X(), TMP1, 0); + } + break; + } + default: + LOGMAN_MSG_A_FMT("Unhandled FillRegister(GPRPair) size: {}", OpSize); + break; + } } else { LOGMAN_MSG_A_FMT("Unhandled FillRegister class: {}", Op->Class.Val); }