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