mirror of
https://github.com/xenia-project/xenia.git
synced 2025-12-06 07:12:03 +01:00
[a64] Fix indirect and external calls
This commit is contained in:
parent
8aa4b9372a
commit
6a0e6a9ca9
|
|
@ -510,7 +510,14 @@ void A64Emitter::CallIndirect(const hir::Instr* instr,
|
||||||
MOV(W1, reg.toW());
|
MOV(W1, reg.toW());
|
||||||
|
|
||||||
ADRP(X16, ResolveFunction);
|
ADRP(X16, ResolveFunction);
|
||||||
|
|
||||||
|
// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actually jump/call to rax.
|
// Actually jump/call to rax.
|
||||||
|
|
@ -532,7 +539,14 @@ void A64Emitter::CallIndirect(const hir::Instr* instr,
|
||||||
// mov(rcx, qword[rsp + StackLayout::GUEST_CALL_RET_ADDR]);
|
// mov(rcx, qword[rsp + StackLayout::GUEST_CALL_RET_ADDR]);
|
||||||
// call(rax);
|
// call(rax);
|
||||||
LDR(X0, XSP, StackLayout::GUEST_CALL_RET_ADDR);
|
LDR(X0, XSP, StackLayout::GUEST_CALL_RET_ADDR);
|
||||||
|
|
||||||
|
// 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -568,7 +582,15 @@ void A64Emitter::CallExtern(const hir::Instr* instr, const Function* function) {
|
||||||
MOV(X2, reinterpret_cast<uint64_t>(builtin_function->arg1()));
|
MOV(X2, reinterpret_cast<uint64_t>(builtin_function->arg1()));
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
} else if (function->behavior() == Function::Behavior::kExtern) {
|
} else if (function->behavior() == Function::Behavior::kExtern) {
|
||||||
|
|
@ -591,7 +613,15 @@ void A64Emitter::CallExtern(const hir::Instr* instr, const Function* function) {
|
||||||
LDR(X2, GetContextReg(), offsetof(ppc::PPCContext, kernel_state));
|
LDR(X2, GetContextReg(), offsetof(ppc::PPCContext, kernel_state));
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue