@@ -1074,6 +1074,10 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
10741074 // Try to create BICs for vector ANDs.
10751075 setTargetDAGCombine(ISD::AND);
10761076
1077+ // llvm.init.trampoline and llvm.adjust.trampoline
1078+ setOperationAction(ISD::INIT_TRAMPOLINE, MVT::Other, Custom);
1079+ setOperationAction(ISD::ADJUST_TRAMPOLINE, MVT::Other, Custom);
1080+
10771081 // Vector add and sub nodes may conceal a high-half opportunity.
10781082 // Also, try to fold ADD into CSINC/CSINV..
10791083 setTargetDAGCombine({ISD::ADD, ISD::ABS, ISD::SUB, ISD::XOR, ISD::SINT_TO_FP,
@@ -6653,6 +6657,56 @@ static SDValue LowerFLDEXP(SDValue Op, SelectionDAG &DAG) {
66536657 return Final;
66546658}
66556659
6660+ SDValue AArch64TargetLowering::LowerADJUST_TRAMPOLINE(SDValue Op,
6661+ SelectionDAG &DAG) const {
6662+ // Note: x18 cannot be used for the Nest parameter on Windows and macOS.
6663+ if (Subtarget->isTargetDarwin() || Subtarget->isTargetWindows())
6664+ report_fatal_error(
6665+ "ADJUST_TRAMPOLINE operation is only supported on Linux.");
6666+
6667+ return Op.getOperand(0);
6668+ }
6669+
6670+ SDValue AArch64TargetLowering::LowerINIT_TRAMPOLINE(SDValue Op,
6671+ SelectionDAG &DAG) const {
6672+
6673+ // Note: x18 cannot be used for the Nest parameter on Windows and macOS.
6674+ if (Subtarget->isTargetDarwin() || Subtarget->isTargetWindows())
6675+ report_fatal_error("INIT_TRAMPOLINE operation is only supported on Linux.");
6676+
6677+ SDValue Chain = Op.getOperand(0);
6678+ SDValue Trmp = Op.getOperand(1); // trampoline
6679+ SDValue FPtr = Op.getOperand(2); // nested function
6680+ SDValue Nest = Op.getOperand(3); // 'nest' parameter value
6681+ SDLoc dl(Op);
6682+
6683+ EVT PtrVT = getPointerTy(DAG.getDataLayout());
6684+ Type *IntPtrTy = DAG.getDataLayout().getIntPtrType(*DAG.getContext());
6685+
6686+ TargetLowering::ArgListTy Args;
6687+ TargetLowering::ArgListEntry Entry;
6688+
6689+ Entry.Ty = IntPtrTy;
6690+ Entry.Node = Trmp;
6691+ Args.push_back(Entry);
6692+ Entry.Node = DAG.getConstant(20, dl, MVT::i64);
6693+ Args.push_back(Entry);
6694+
6695+ Entry.Node = FPtr;
6696+ Args.push_back(Entry);
6697+ Entry.Node = Nest;
6698+ Args.push_back(Entry);
6699+
6700+ // Lower to a call to __trampoline_setup(Trmp, TrampSize, FPtr, ctx_reg)
6701+ TargetLowering::CallLoweringInfo CLI(DAG);
6702+ CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
6703+ CallingConv::C, Type::getVoidTy(*DAG.getContext()),
6704+ DAG.getExternalSymbol("__trampoline_setup", PtrVT), std::move(Args));
6705+
6706+ std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);
6707+ return CallResult.second;
6708+ }
6709+
66566710SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
66576711 SelectionDAG &DAG) const {
66586712 LLVM_DEBUG(dbgs() << "Custom lowering: ");
@@ -6670,6 +6724,10 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
66706724 return LowerGlobalTLSAddress(Op, DAG);
66716725 case ISD::PtrAuthGlobalAddress:
66726726 return LowerPtrAuthGlobalAddress(Op, DAG);
6727+ case ISD::ADJUST_TRAMPOLINE:
6728+ return LowerADJUST_TRAMPOLINE(Op, DAG);
6729+ case ISD::INIT_TRAMPOLINE:
6730+ return LowerINIT_TRAMPOLINE(Op, DAG);
66736731 case ISD::SETCC:
66746732 case ISD::STRICT_FSETCC:
66756733 case ISD::STRICT_FSETCCS:
0 commit comments