Files
UnrealEngine/Engine/Source/Runtime/AutoRTFM/Private/LongJump.cpp
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

104 lines
2.5 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#if (defined(__AUTORTFM) && __AUTORTFM)
#include "LongJump.h"
#if AUTORTFM_USE_SAVE_RESTORE_CONTEXT
namespace AutoRTFM
{
// https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170#callercallee-saved-registers
// Registers that must be saved:
// RBX, RBP, RDI, RSI, RSP, R12, R13, R14, R15, and XMM6-XMM15
UE_AUTORTFM_NOAUTORTFM __attribute__((noinline)) __attribute((naked))
bool FLongJump::SaveContext(void* Buffer)
{
__asm
{
// rcx: Buffer, rax: Return value
// Save non-volatile registers
mov [rcx + 0], rsp
mov [rcx + 8], rbx
mov [rcx + 16], rbp
mov [rcx + 24], rdi
mov [rcx + 32], rsi
mov [rcx + 40], r12
mov [rcx + 48], r13
mov [rcx + 56], r14
mov [rcx + 64], r15
movupd [rcx + 80], xmm6
movupd [rcx + 96], xmm7
movupd [rcx + 112], xmm8
movupd [rcx + 128], xmm9
movupd [rcx + 144], xmm10
movupd [rcx + 160], xmm11
movupd [rcx + 176], xmm12
movupd [rcx + 192], xmm13
movupd [rcx + 208], xmm14
movupd [rcx + 224], xmm15
// Save register control & status state
stmxcsr [rcx + 240]
fnstcw [rcx + 244]
// Use return address on stack as restore instruction pointer
mov r8, [rsp]
mov [rcx + 248], r8
// Return 0 to indicate that this is a context-save
mov rax, 0
ret
}
}
UE_AUTORTFM_NOAUTORTFM __attribute__((noinline)) __attribute((naked))
void FLongJump::RestoreContext(void* Buffer)
{
__asm
{
// rcx: Buffer, rax: Return value
// Restore non-volatile registers
mov rsp, [rcx + 0]
mov rbx, [rcx + 8]
mov rbp, [rcx + 16]
mov rdi, [rcx + 24]
mov rsi, [rcx + 32]
mov r12, [rcx + 40]
mov r13, [rcx + 48]
mov r14, [rcx + 56]
mov r15, [rcx + 64]
movupd xmm6, [rcx + 80]
movupd xmm7, [rcx + 96]
movupd xmm8, [rcx + 112]
movupd xmm9, [rcx + 128]
movupd xmm10, [rcx + 144]
movupd xmm11, [rcx + 160]
movupd xmm12, [rcx + 176]
movupd xmm13, [rcx + 192]
movupd xmm14, [rcx + 208]
movupd xmm15, [rcx + 224]
// Restore register control & status state
ldmxcsr [rcx + 240]
fldcw [rcx + 244]
fnclex
// Replace caller's return address with saved return address and return.
mov r8, [rcx + 248]
mov [rsp], r8
// Return 1 to indicate that this is a context-restore
mov rax, 1
ret
}
}
}
#endif // AUTORTFM_USE_SAVE_RESTORE_CONTEXT
#endif // (defined(__AUTORTFM) && __AUTORTFM)