llvm.org GIT mirror llvm / d14325b
[PowerPC] Support the nest parameter attribute This adds support for the 'nest' attribute, which allows the static chain register to be set for functions calls under non-Darwin PPC/PPC64 targets. r11 is the chain register (which the PPC64 ELF ABI calls the "environment pointer"). For indirect calls under PPC64 ELFv1, this would normally be loaded from the function descriptor, but providing an explicit 'nest' parameter will override that process and use the value provided. This allows __builtin_call_with_static_chain to work as expected on PowerPC. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241984 91177308-0d34-0410-b5e6-96231b3b80d8 Hal Finkel 4 years ago
5 changed file(s) with 120 addition(s) and 17 deletion(s). Raw diff Collapse all Expand all
132132 // register having an odd register number.
133133 CCIfType<[i32], CCIfSplit>>,
134134
135 // The 'nest' parameter, if any, is passed in R11.
136 CCIfNest>,
137
135138 // The first 8 integer arguments are passed in integer registers.
136139 CCIfType<[i32], CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10]>>,
137140
30573057 unsigned NumBytes = LinkageSize;
30583058 unsigned AvailableFPRs = Num_FPR_Regs;
30593059 unsigned AvailableVRs = Num_VR_Regs;
3060 for (unsigned i = 0, e = Ins.size(); i != e; ++i)
3060 for (unsigned i = 0, e = Ins.size(); i != e; ++i) {
3061 if (Ins[i].Flags.isNest())
3062 continue;
3063
30613064 if (CalculateStackSlotUsed(Ins[i].VT, Ins[i].ArgVT, Ins[i].Flags,
30623065 PtrByteSize, LinkageSize, ParamAreaSize,
30633066 NumBytes, AvailableFPRs, AvailableVRs,
30643067 Subtarget.hasQPX()))
30653068 HasParameterArea = true;
3069 }
30663070
30673071 // Add DAG nodes to load the arguments or copy them out of registers. On
30683072 // entry to a function on PPC, the arguments start after the linkage area,
32143218 case MVT::i1:
32153219 case MVT::i32:
32163220 case MVT::i64:
3221 if (Flags.isNest()) {
3222 // The 'nest' parameter, if any, is passed in R11.
3223 unsigned VReg = MF.addLiveIn(PPC::X11, &PPC::G8RCRegClass);
3224 ArgVal = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i64);
3225
3226 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
3227 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
3228
3229 break;
3230 }
3231
32173232 // These can be scalar arguments or elements of an integer array type
32183233 // passed directly. Clang may use those instead of "byval" aggregate
32193234 // types to avoid forcing arguments to memory unnecessarily.
40524067 static
40534068 unsigned PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag,
40544069 SDValue &Chain, SDValue CallSeqStart, SDLoc dl, int SPDiff,
4055 bool isTailCall, bool IsPatchPoint,
4070 bool isTailCall, bool IsPatchPoint, bool hasNest,
40564071 SmallVectorImpl > &RegsToPass,
40574072 SmallVectorImpl &Ops, std::vector &NodeTys,
40584073 ImmutableCallSite *CS, const PPCSubtarget &Subtarget) {
41944209 Chain = TOCVal.getValue(0);
41954210 InFlag = TOCVal.getValue(1);
41964211
4197 SDValue EnvVal = DAG.getCopyToReg(Chain, dl, PPC::X11, LoadEnvPtr,
4198 InFlag);
4199
4200 Chain = EnvVal.getValue(0);
4201 InFlag = EnvVal.getValue(1);
4212 // If the function call has an explicit 'nest' parameter, it takes the
4213 // place of the environment pointer.
4214 if (!hasNest) {
4215 SDValue EnvVal = DAG.getCopyToReg(Chain, dl, PPC::X11, LoadEnvPtr,
4216 InFlag);
4217
4218 Chain = EnvVal.getValue(0);
4219 InFlag = EnvVal.getValue(1);
4220 }
42024221
42034222 MTCTROps[0] = Chain;
42044223 MTCTROps[1] = LoadFuncPtr;
42164235 CallOpc = PPCISD::BCTRL;
42174236 Callee.setNode(nullptr);
42184237 // Add use of X11 (holding environment pointer)
4219 if (isSVR4ABI && isPPC64 && !isELFv2ABI)
4238 if (isSVR4ABI && isPPC64 && !isELFv2ABI && !hasNest)
42204239 Ops.push_back(DAG.getRegister(PPC::X11, PtrVT));
42214240 // Add CTR register as callee so a bctr can be emitted later.
42224241 if (isTailCall)
43054324 SDValue
43064325 PPCTargetLowering::FinishCall(CallingConv::ID CallConv, SDLoc dl,
43074326 bool isTailCall, bool isVarArg, bool IsPatchPoint,
4308 SelectionDAG &DAG,
4327 bool hasNest, SelectionDAG &DAG,
43094328 SmallVector, 8>
43104329 &RegsToPass,
43114330 SDValue InFlag, SDValue Chain,
43184337 std::vector NodeTys;
43194338 SmallVector Ops;
43204339 unsigned CallOpc = PrepareCall(DAG, Callee, InFlag, Chain, CallSeqStart, dl,
4321 SPDiff, isTailCall, IsPatchPoint, RegsToPass,
4322 Ops, NodeTys, CS, Subtarget);
4340 SPDiff, isTailCall, IsPatchPoint, hasNest,
4341 RegsToPass, Ops, NodeTys, CS, Subtarget);
43234342
43244343 // Add implicit use of CR bit 6 for 32-bit SVR4 vararg calls
43254344 if (isVarArg && Subtarget.isSVR4ABI() && !Subtarget.isPPC64())
46634682 PrepareTailCall(DAG, InFlag, Chain, dl, false, SPDiff, NumBytes, LROp, FPOp,
46644683 false, TailCallArguments);
46654684
4666 return FinishCall(CallConv, dl, isTailCall, isVarArg, IsPatchPoint, DAG,
4685 return FinishCall(CallConv, dl, isTailCall, isVarArg, IsPatchPoint,
4686 /* unused except on PPC64 ELFv1 */ false, DAG,
46674687 RegsToPass, InFlag, Chain, CallSeqStart, Callee, SPDiff,
46684688 NumBytes, Ins, InVals, CS);
46694689 }
47024722 bool isELFv2ABI = Subtarget.isELFv2ABI();
47034723 bool isLittleEndian = Subtarget.isLittleEndian();
47044724 unsigned NumOps = Outs.size();
4725 bool hasNest = false;
47054726
47064727 EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout());
47074728 unsigned PtrByteSize = 8;
47564777 ISD::ArgFlagsTy Flags = Outs[i].Flags;
47574778 EVT ArgVT = Outs[i].VT;
47584779 EVT OrigVT = Outs[i].ArgVT;
4780
4781 if (Flags.isNest())
4782 continue;
47594783
47604784 if (CallConv == CallingConv::Fast) {
47614785 if (Flags.isByVal())
50205044 case MVT::i1:
50215045 case MVT::i32:
50225046 case MVT::i64:
5047 if (Flags.isNest()) {
5048 // The 'nest' parameter, if any, is passed in R11.
5049 RegsToPass.push_back(std::make_pair(PPC::X11, Arg));
5050 hasNest = true;
5051 break;
5052 }
5053
50235054 // These can be scalar arguments or elements of an integer array type
50245055 // passed directly. Clang may use those instead of "byval" aggregate
50255056 // types to avoid forcing arguments to memory unnecessarily.
53015332 PrepareTailCall(DAG, InFlag, Chain, dl, true, SPDiff, NumBytes, LROp,
53025333 FPOp, true, TailCallArguments);
53035334
5304 return FinishCall(CallConv, dl, isTailCall, isVarArg, IsPatchPoint, DAG,
5305 RegsToPass, InFlag, Chain, CallSeqStart, Callee, SPDiff,
5306 NumBytes, Ins, InVals, CS);
5335 return FinishCall(CallConv, dl, isTailCall, isVarArg, IsPatchPoint,
5336 hasNest, DAG, RegsToPass, InFlag, Chain, CallSeqStart,
5337 Callee, SPDiff, NumBytes, Ins, InVals, CS);
53075338 }
53085339
53095340 SDValue
56925723 PrepareTailCall(DAG, InFlag, Chain, dl, isPPC64, SPDiff, NumBytes, LROp,
56935724 FPOp, true, TailCallArguments);
56945725
5695 return FinishCall(CallConv, dl, isTailCall, isVarArg, IsPatchPoint, DAG,
5726 return FinishCall(CallConv, dl, isTailCall, isVarArg, IsPatchPoint,
5727 /* unused except on PPC64 ELFv1 */ false, DAG,
56965728 RegsToPass, InFlag, Chain, CallSeqStart, Callee, SPDiff,
56975729 NumBytes, Ins, InVals, CS);
56985730 }
747747 SDLoc dl, SelectionDAG &DAG,
748748 SmallVectorImpl &InVals) const;
749749 SDValue FinishCall(CallingConv::ID CallConv, SDLoc dl, bool isTailCall,
750 bool isVarArg, bool IsPatchPoint,
750 bool isVarArg, bool IsPatchPoint, bool hasNest,
751751 SelectionDAG &DAG,
752752 SmallVector, 8>
753753 &RegsToPass,
0 ; RUN: llc < %s | FileCheck %s
1 target datalayout = "E-m:e-p:32:32-i64:64-n32"
2 target triple = "powerpc-unknown-linux-gnu"
3
4 ; Tests that the 'nest' parameter attribute causes the relevant parameter to be
5 ; passed in the right register (r11 for PPC).
6
7 define i8* @nest_receiver(i8* nest %arg) nounwind {
8 ; CHECK-LABEL: nest_receiver:
9 ; CHECK: # BB#0:
10 ; CHECK-NEXT: mr 3, 11
11 ; CHECK-NEXT: blr
12
13 ret i8* %arg
14 }
15
16 define i8* @nest_caller(i8* %arg) nounwind {
17 ; CHECK-LABEL: nest_caller:
18 ; CHECK: mr 11, 3
19 ; CHECK-NEXT: bl nest_receiver
20 ; CHECK: blr
21
22 %result = call i8* @nest_receiver(i8* nest %arg)
23 ret i8* %result
24 }
25
0 ; RUN: llc < %s | FileCheck %s
1 target datalayout = "E-m:e-i64:64-n32:64"
2 target triple = "powerpc64-unknown-linux-gnu"
3
4 ; Tests that the 'nest' parameter attribute causes the relevant parameter to be
5 ; passed in the right register (r11 for PPC).
6
7 define i8* @nest_receiver(i8* nest %arg) nounwind {
8 ; CHECK-LABEL: nest_receiver:
9 ; CHECK: # BB#0:
10 ; CHECK-NEXT: mr 3, 11
11 ; CHECK-NEXT: blr
12
13 ret i8* %arg
14 }
15
16 define i8* @nest_caller(i8* %arg) nounwind {
17 ; CHECK-LABEL: nest_caller:
18 ; CHECK: mr 11, 3
19 ; CHECK-NEXT: bl nest_receiver
20 ; CHECK: blr
21
22 %result = call i8* @nest_receiver(i8* nest %arg)
23 ret i8* %result
24 }
25
26 define void @test_indirect(i32 ()* nocapture %f, i8* %p) {
27 entry:
28
29 ; CHECK-LABEL: test_indirect
30 ; CHECK-DAG: ld [[DEST:[0-9]+]], 0(3)
31 ; CHECK-DAG: ld 2, 8(3)
32 ; CHECK-DAG: mr 11, 4
33 ; CHECK: mtctr [[DEST]]
34 ; CHECK: bctrl
35 ; CHECK: blr
36
37 %callee.knr.cast = bitcast i32 ()* %f to i32 (i8*)*
38 %call = tail call signext i32 %callee.knr.cast(i8* nest %p)
39 ret void
40 }
41