mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-26 23:21:11 +00:00
[AArch64] Skip over shadow space for ARM64EC entry thunk variadic calls (#80994)
When in an entry thunk the x64 SP is passed in x4 but this cannot be directly passed through since x64 varargs calls have a 32 byte shadow store at SP followed by the in-stack parameters. ARM64EC varargs calls on the other hand expect x4 to point to the first in-stack parameter.
This commit is contained in:
parent
42c599ab36
commit
89d543227a
@ -117,8 +117,8 @@ void AArch64Arm64ECCallLowering::getThunkType(FunctionType *FT,
|
||||
getThunkArgTypes(FT, AttrList, TT, Out, Arm64ArgTypes, X64ArgTypes,
|
||||
HasSretPtr);
|
||||
|
||||
Arm64Ty = FunctionType::get(Arm64RetTy, Arm64ArgTypes,
|
||||
TT == ThunkType::Entry && FT->isVarArg());
|
||||
Arm64Ty = FunctionType::get(Arm64RetTy, Arm64ArgTypes, false);
|
||||
|
||||
X64Ty = FunctionType::get(X64RetTy, X64ArgTypes, false);
|
||||
}
|
||||
|
||||
@ -156,13 +156,13 @@ void AArch64Arm64ECCallLowering::getThunkArgTypes(
|
||||
X64ArgTypes.push_back(I64Ty);
|
||||
}
|
||||
|
||||
// x4
|
||||
Arm64ArgTypes.push_back(PtrTy);
|
||||
X64ArgTypes.push_back(PtrTy);
|
||||
// x5
|
||||
Arm64ArgTypes.push_back(I64Ty);
|
||||
if (TT != ThunkType::Entry) {
|
||||
// x4
|
||||
Arm64ArgTypes.push_back(PtrTy);
|
||||
X64ArgTypes.push_back(PtrTy);
|
||||
// x5
|
||||
Arm64ArgTypes.push_back(I64Ty);
|
||||
// FIXME: x5 isn't actually passed/used by the x64 side; revisit once we
|
||||
// FIXME: x5 isn't actually used by the x64 side; revisit once we
|
||||
// have proper isel for varargs
|
||||
X64ArgTypes.push_back(I64Ty);
|
||||
}
|
||||
@ -471,10 +471,11 @@ Function *AArch64Arm64ECCallLowering::buildEntryThunk(Function *F) {
|
||||
|
||||
bool TransformDirectToSRet = X64RetType->isVoidTy() && !RetTy->isVoidTy();
|
||||
unsigned ThunkArgOffset = TransformDirectToSRet ? 2 : 1;
|
||||
unsigned PassthroughArgSize = F->isVarArg() ? 5 : Thunk->arg_size();
|
||||
|
||||
// Translate arguments to call.
|
||||
SmallVector<Value *> Args;
|
||||
for (unsigned i = ThunkArgOffset, e = Thunk->arg_size(); i != e; ++i) {
|
||||
for (unsigned i = ThunkArgOffset, e = PassthroughArgSize; i != e; ++i) {
|
||||
Value *Arg = Thunk->getArg(i);
|
||||
Type *ArgTy = Arm64Ty->getParamType(i - ThunkArgOffset);
|
||||
if (ArgTy->isArrayTy() || ArgTy->isStructTy() ||
|
||||
@ -491,6 +492,22 @@ Function *AArch64Arm64ECCallLowering::buildEntryThunk(Function *F) {
|
||||
Args.push_back(Arg);
|
||||
}
|
||||
|
||||
if (F->isVarArg()) {
|
||||
// The 5th argument to variadic entry thunks is used to model the x64 sp
|
||||
// which is passed to the thunk in x4, this can be passed to the callee as
|
||||
// the variadic argument start address after skipping over the 32 byte
|
||||
// shadow store.
|
||||
|
||||
// The EC thunk CC will assign any argument marked as InReg to x4.
|
||||
Thunk->addParamAttr(5, Attribute::InReg);
|
||||
Value *Arg = Thunk->getArg(5);
|
||||
Arg = IRB.CreatePtrAdd(Arg, IRB.getInt64(0x20));
|
||||
Args.push_back(Arg);
|
||||
|
||||
// Pass in a zero variadic argument size (in x5).
|
||||
Args.push_back(IRB.getInt64(0));
|
||||
}
|
||||
|
||||
// Call the function passed to the thunk.
|
||||
Value *Callee = Thunk->getArg(0);
|
||||
Callee = IRB.CreateBitCast(Callee, PtrTy);
|
||||
|
@ -213,6 +213,9 @@ def CC_AArch64_Arm64EC_VarArg : CallingConv<[
|
||||
// address is passed in X9.
|
||||
let Entry = 1 in
|
||||
def CC_AArch64_Arm64EC_Thunk : CallingConv<[
|
||||
// ARM64EC-specific: the InReg attribute can be used to access the x64 sp passed into entry thunks in x4 from the IR.
|
||||
CCIfInReg<CCIfType<[i64], CCAssignToReg<[X4]>>>,
|
||||
|
||||
// Byval aggregates are passed by pointer
|
||||
CCIfByVal<CCPassIndirect<i64>>,
|
||||
|
||||
|
@ -147,7 +147,7 @@ define void @has_varargs(...) nounwind {
|
||||
; CHECK-NEXT: add x29, sp, #160
|
||||
; CHECK-NEXT: .seh_add_fp 160
|
||||
; CHECK-NEXT: .seh_endprologue
|
||||
; CHECK-NEXT: mov x4, sp
|
||||
; CHECK-NEXT: add x4, x4, #32
|
||||
; CHECK-NEXT: mov x5, xzr
|
||||
; CHECK-NEXT: blr x9
|
||||
; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_ret
|
||||
|
Loading…
Reference in New Issue
Block a user