[a64] Fix Guest-To-Host native calls

These calls need to preserve and restore the `lr` register.

Unit tests all run now!
This commit is contained in:
Wunkolo 2024-05-03 19:00:05 -07:00
parent defb68eae2
commit 124f684987
3 changed files with 17 additions and 5 deletions

View file

@ -273,10 +273,10 @@ HostToGuestThunk A64ThunkEmitter::EmitHostToGuestThunk() {
} }
GuestToHostThunk A64ThunkEmitter::EmitGuestToHostThunk() { GuestToHostThunk A64ThunkEmitter::EmitGuestToHostThunk() {
// rcx = target function // X0 = target function
// rdx = arg0 // X1 = arg0
// r8 = arg1 // X2 = arg1
// r9 = arg2 // X3 = arg2
struct _code_offsets { struct _code_offsets {
size_t prolog; size_t prolog;
@ -420,6 +420,8 @@ void A64ThunkEmitter::EmitSaveVolatileRegs() {
STR(X17, XSP, offsetof(StackLayout::Thunk, r[17])); STR(X17, XSP, offsetof(StackLayout::Thunk, r[17]));
STR(X18, XSP, offsetof(StackLayout::Thunk, r[18])); STR(X18, XSP, offsetof(StackLayout::Thunk, r[18]));
STR(X30, XSP, offsetof(StackLayout::Thunk, r[19]));
STR(Q0, XSP, offsetof(StackLayout::Thunk, xmm[0])); STR(Q0, XSP, offsetof(StackLayout::Thunk, xmm[0]));
STR(Q1, XSP, offsetof(StackLayout::Thunk, xmm[1])); STR(Q1, XSP, offsetof(StackLayout::Thunk, xmm[1]));
STR(Q2, XSP, offsetof(StackLayout::Thunk, xmm[2])); STR(Q2, XSP, offsetof(StackLayout::Thunk, xmm[2]));
@ -477,6 +479,8 @@ void A64ThunkEmitter::EmitLoadVolatileRegs() {
LDR(X17, XSP, offsetof(StackLayout::Thunk, r[17])); LDR(X17, XSP, offsetof(StackLayout::Thunk, r[17]));
LDR(X18, XSP, offsetof(StackLayout::Thunk, r[18])); LDR(X18, XSP, offsetof(StackLayout::Thunk, r[18]));
LDR(X30, XSP, offsetof(StackLayout::Thunk, r[19]));
LDR(Q0, XSP, offsetof(StackLayout::Thunk, xmm[0])); LDR(Q0, XSP, offsetof(StackLayout::Thunk, xmm[0]));
LDR(Q1, XSP, offsetof(StackLayout::Thunk, xmm[1])); LDR(Q1, XSP, offsetof(StackLayout::Thunk, xmm[1]));
LDR(Q2, XSP, offsetof(StackLayout::Thunk, xmm[2])); LDR(Q2, XSP, offsetof(StackLayout::Thunk, xmm[2]));

View file

@ -628,7 +628,15 @@ void A64Emitter::CallNativeSafe(void* fn) {
// call(rax); // call(rax);
MOV(X0, reinterpret_cast<uint64_t>(fn)); MOV(X0, reinterpret_cast<uint64_t>(fn));
MOV(X16, reinterpret_cast<uint64_t>(thunk)); MOV(X16, reinterpret_cast<uint64_t>(thunk));
// Preserve frame and link register
STP(X29, X30, XSP, POST_INDEXED, -16);
BLR(X16); BLR(X16);
// Restore frame and link register
LDP(X29, X30, XSP, PRE_INDEXED, 16);
// X0 = host return // X0 = host return
} }

View file

@ -90,7 +90,7 @@ class StackLayout {
*/ */
XEPACKEDSTRUCT(Thunk, { XEPACKEDSTRUCT(Thunk, {
uint64_t arg_temp[3]; uint64_t arg_temp[3];
uint64_t r[19]; uint64_t r[20];
vec128_t xmm[32]; vec128_t xmm[32];
}); });
static_assert(sizeof(Thunk) % 16 == 0, static_assert(sizeof(Thunk) % 16 == 0,