mirror of
https://github.com/xenia-project/xenia.git
synced 2025-12-06 07:12:03 +01:00
[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:
parent
defb68eae2
commit
124f684987
|
|
@ -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]));
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue