@@ -1080,6 +1080,10 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
10801080 // Try to create BICs for vector ANDs.
10811081 setTargetDAGCombine(ISD::AND);
10821082
1083+ // llvm.init.trampoline and llvm.adjust.trampoline
1084+ setOperationAction(ISD::INIT_TRAMPOLINE, MVT::Other, Custom);
1085+ setOperationAction(ISD::ADJUST_TRAMPOLINE, MVT::Other, Custom);
1086+
10831087 // Vector add and sub nodes may conceal a high-half opportunity.
10841088 // Also, try to fold ADD into CSINC/CSINV..
10851089 setTargetDAGCombine({ISD::ADD, ISD::ABS, ISD::SUB, ISD::XOR, ISD::SINT_TO_FP,
@@ -6688,6 +6692,56 @@ static SDValue LowerFLDEXP(SDValue Op, SelectionDAG &DAG) {
66886692 return Final;
66896693}
66906694
6695+ SDValue AArch64TargetLowering::LowerADJUST_TRAMPOLINE(SDValue Op,
6696+ SelectionDAG &DAG) const {
6697+ // Note: x18 cannot be used for the Nest parameter on Windows and macOS.
6698+ if (Subtarget->isTargetDarwin() || Subtarget->isTargetWindows())
6699+ report_fatal_error(
6700+ "ADJUST_TRAMPOLINE operation is only supported on Linux.");
6701+
6702+ return Op.getOperand(0);
6703+ }
6704+
6705+ SDValue AArch64TargetLowering::LowerINIT_TRAMPOLINE(SDValue Op,
6706+ SelectionDAG &DAG) const {
6707+
6708+ // Note: x18 cannot be used for the Nest parameter on Windows and macOS.
6709+ if (Subtarget->isTargetDarwin() || Subtarget->isTargetWindows())
6710+ report_fatal_error("INIT_TRAMPOLINE operation is only supported on Linux.");
6711+
6712+ SDValue Chain = Op.getOperand(0);
6713+ SDValue Trmp = Op.getOperand(1); // trampoline
6714+ SDValue FPtr = Op.getOperand(2); // nested function
6715+ SDValue Nest = Op.getOperand(3); // 'nest' parameter value
6716+ SDLoc dl(Op);
6717+
6718+ EVT PtrVT = getPointerTy(DAG.getDataLayout());
6719+ Type *IntPtrTy = DAG.getDataLayout().getIntPtrType(*DAG.getContext());
6720+
6721+ TargetLowering::ArgListTy Args;
6722+ TargetLowering::ArgListEntry Entry;
6723+
6724+ Entry.Ty = IntPtrTy;
6725+ Entry.Node = Trmp;
6726+ Args.push_back(Entry);
6727+ Entry.Node = DAG.getConstant(20, dl, MVT::i64);
6728+ Args.push_back(Entry);
6729+
6730+ Entry.Node = FPtr;
6731+ Args.push_back(Entry);
6732+ Entry.Node = Nest;
6733+ Args.push_back(Entry);
6734+
6735+ // Lower to a call to __trampoline_setup(Trmp, TrampSize, FPtr, ctx_reg)
6736+ TargetLowering::CallLoweringInfo CLI(DAG);
6737+ CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
6738+ CallingConv::C, Type::getVoidTy(*DAG.getContext()),
6739+ DAG.getExternalSymbol("__trampoline_setup", PtrVT), std::move(Args));
6740+
6741+ std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);
6742+ return CallResult.second;
6743+ }
6744+
66916745SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
66926746 SelectionDAG &DAG) const {
66936747 LLVM_DEBUG(dbgs() << "Custom lowering: ");
@@ -6705,6 +6759,10 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
67056759 return LowerGlobalTLSAddress(Op, DAG);
67066760 case ISD::PtrAuthGlobalAddress:
67076761 return LowerPtrAuthGlobalAddress(Op, DAG);
6762+ case ISD::ADJUST_TRAMPOLINE:
6763+ return LowerADJUST_TRAMPOLINE(Op, DAG);
6764+ case ISD::INIT_TRAMPOLINE:
6765+ return LowerINIT_TRAMPOLINE(Op, DAG);
67086766 case ISD::SETCC:
67096767 case ISD::STRICT_FSETCC:
67106768 case ISD::STRICT_FSETCCS:
0 commit comments