@@ -43,6 +43,8 @@ static cl::opt<bool> GenerateThunks("arm64ec-generate-thunks", cl::Hidden,
4343
4444namespace {
4545
46+ enum class ThunkType { GuestExit, Entry, Exit };
47+
4648class AArch64Arm64ECCallLowering : public ModulePass {
4749public:
4850 static char ID;
@@ -69,14 +71,14 @@ class AArch64Arm64ECCallLowering : public ModulePass {
6971 Type *I64Ty;
7072 Type *VoidTy;
7173
72- void getThunkType (FunctionType *FT, AttributeList AttrList, bool EntryThunk ,
74+ void getThunkType (FunctionType *FT, AttributeList AttrList, ThunkType TT ,
7375 raw_ostream &Out, FunctionType *&Arm64Ty,
7476 FunctionType *&X64Ty);
7577 void getThunkRetType (FunctionType *FT, AttributeList AttrList,
7678 raw_ostream &Out, Type *&Arm64RetTy, Type *&X64RetTy,
7779 SmallVectorImpl<Type *> &Arm64ArgTypes,
7880 SmallVectorImpl<Type *> &X64ArgTypes, bool &HasSretPtr);
79- void getThunkArgTypes (FunctionType *FT, AttributeList AttrList,
81+ void getThunkArgTypes (FunctionType *FT, AttributeList AttrList, ThunkType TT,
8082 raw_ostream &Out,
8183 SmallVectorImpl<Type *> &Arm64ArgTypes,
8284 SmallVectorImpl<Type *> &X64ArgTypes, bool HasSretPtr);
@@ -89,10 +91,11 @@ class AArch64Arm64ECCallLowering : public ModulePass {
8991
9092void AArch64Arm64ECCallLowering::getThunkType (FunctionType *FT,
9193 AttributeList AttrList,
92- bool EntryThunk , raw_ostream &Out,
94+ ThunkType TT , raw_ostream &Out,
9395 FunctionType *&Arm64Ty,
9496 FunctionType *&X64Ty) {
95- Out << (EntryThunk ? " $ientry_thunk$cdecl$" : " $iexit_thunk$cdecl$" );
97+ Out << (TT == ThunkType::Entry ? " $ientry_thunk$cdecl$"
98+ : " $iexit_thunk$cdecl$" );
9699
97100 Type *Arm64RetTy;
98101 Type *X64RetTy;
@@ -102,23 +105,25 @@ void AArch64Arm64ECCallLowering::getThunkType(FunctionType *FT,
102105
103106 // The first argument to a thunk is the called function, stored in x9.
104107 // For exit thunks, we pass the called function down to the emulator;
105- // for entry thunks, we just call the Arm64 function directly.
106- if (!EntryThunk )
108+ // for entry/guest exit thunks, we just call the Arm64 function directly.
109+ if (TT == ThunkType::Exit )
107110 Arm64ArgTypes.push_back (PtrTy);
108111 X64ArgTypes.push_back (PtrTy);
109112
110113 bool HasSretPtr = false ;
111114 getThunkRetType (FT, AttrList, Out, Arm64RetTy, X64RetTy, Arm64ArgTypes,
112115 X64ArgTypes, HasSretPtr);
113116
114- getThunkArgTypes (FT, AttrList, Out, Arm64ArgTypes, X64ArgTypes, HasSretPtr);
117+ getThunkArgTypes (FT, AttrList, TT, Out, Arm64ArgTypes, X64ArgTypes,
118+ HasSretPtr);
115119
116- Arm64Ty = FunctionType::get (Arm64RetTy, Arm64ArgTypes, false );
120+ Arm64Ty = FunctionType::get (Arm64RetTy, Arm64ArgTypes,
121+ TT == ThunkType::Entry && FT->isVarArg ());
117122 X64Ty = FunctionType::get (X64RetTy, X64ArgTypes, false );
118123}
119124
120125void AArch64Arm64ECCallLowering::getThunkArgTypes (
121- FunctionType *FT, AttributeList AttrList, raw_ostream &Out,
126+ FunctionType *FT, AttributeList AttrList, ThunkType TT, raw_ostream &Out,
122127 SmallVectorImpl<Type *> &Arm64ArgTypes,
123128 SmallVectorImpl<Type *> &X64ArgTypes, bool HasSretPtr) {
124129
@@ -151,14 +156,16 @@ void AArch64Arm64ECCallLowering::getThunkArgTypes(
151156 X64ArgTypes.push_back (I64Ty);
152157 }
153158
154- // x4
155- Arm64ArgTypes.push_back (PtrTy);
156- X64ArgTypes.push_back (PtrTy);
157- // x5
158- Arm64ArgTypes.push_back (I64Ty);
159- // FIXME: x5 isn't actually passed/used by the x64 side; revisit once we
160- // have proper isel for varargs
161- X64ArgTypes.push_back (I64Ty);
159+ if (TT != ThunkType::Entry) {
160+ // x4
161+ Arm64ArgTypes.push_back (PtrTy);
162+ X64ArgTypes.push_back (PtrTy);
163+ // x5
164+ Arm64ArgTypes.push_back (I64Ty);
165+ // FIXME: x5 isn't actually passed/used by the x64 side; revisit once we
166+ // have proper isel for varargs
167+ X64ArgTypes.push_back (I64Ty);
168+ }
162169 return ;
163170 }
164171
@@ -339,8 +346,7 @@ Function *AArch64Arm64ECCallLowering::buildExitThunk(FunctionType *FT,
339346 SmallString<256 > ExitThunkName;
340347 llvm::raw_svector_ostream ExitThunkStream (ExitThunkName);
341348 FunctionType *Arm64Ty, *X64Ty;
342- getThunkType (FT, Attrs, /* EntryThunk*/ false , ExitThunkStream, Arm64Ty,
343- X64Ty);
349+ getThunkType (FT, Attrs, ThunkType::Exit, ExitThunkStream, Arm64Ty, X64Ty);
344350 if (Function *F = M->getFunction (ExitThunkName))
345351 return F;
346352
@@ -443,7 +449,7 @@ Function *AArch64Arm64ECCallLowering::buildEntryThunk(Function *F) {
443449 SmallString<256 > EntryThunkName;
444450 llvm::raw_svector_ostream EntryThunkStream (EntryThunkName);
445451 FunctionType *Arm64Ty, *X64Ty;
446- getThunkType (F->getFunctionType (), F->getAttributes (), /* EntryThunk */ true ,
452+ getThunkType (F->getFunctionType (), F->getAttributes (), ThunkType::Entry ,
447453 EntryThunkStream, Arm64Ty, X64Ty);
448454 if (Function *F = M->getFunction (EntryThunkName))
449455 return F;
@@ -518,7 +524,7 @@ Function *AArch64Arm64ECCallLowering::buildEntryThunk(Function *F) {
518524Function *AArch64Arm64ECCallLowering::buildGuestExitThunk (Function *F) {
519525 llvm::raw_null_ostream NullThunkName;
520526 FunctionType *Arm64Ty, *X64Ty;
521- getThunkType (F->getFunctionType (), F->getAttributes (), /* EntryThunk */ true ,
527+ getThunkType (F->getFunctionType (), F->getAttributes (), ThunkType::GuestExit ,
522528 NullThunkName, Arm64Ty, X64Ty);
523529 auto MangledName = getArm64ECMangledFunctionName (F->getName ().str ());
524530 assert (MangledName && " Can't guest exit to function that's already native" );
0 commit comments