summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorSean Fertile <sd.fertile@gmail.com>2019-11-29 12:44:56 -0500
committerSean Fertile <sd.fertile@gmail.com>2019-11-29 12:46:53 -0500
commit26ab827c24c8dcebebad136c0580cae5fdc84c9f (patch)
treefffd5cd91ceba938bd4cfba55e31919eb1ae8659 /llvm/lib
parent76fd58d0fe69667304569cb1c4cffe041c3cb9c5 (diff)
downloadbcm5719-llvm-26ab827c24c8dcebebad136c0580cae5fdc84c9f.tar.gz
bcm5719-llvm-26ab827c24c8dcebebad136c0580cae5fdc84c9f.zip
[PowerPC][AIX] Add support for lowering int/float/double formal arguments.
This patch adds LowerFormalArguments_AIX, support is added for lowering int, float, and double formal arguments into general purpose and floating point registers only. The aix calling convention testcase have been redone to test for caller and callee functionality in the same lit test. Patch by Zarko Todorovski! Differential Revision: https://reviews.llvm.org/D69578
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelLowering.cpp118
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelLowering.h4
2 files changed, 119 insertions, 3 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 8730c88f435..a4f662dfddd 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -3418,15 +3418,16 @@ SDValue PPCTargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ if (Subtarget.isAIXABI())
+ return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
+ InVals);
if (Subtarget.is64BitELFABI())
return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
InVals);
- else if (Subtarget.is32BitELFABI())
+ if (Subtarget.is32BitELFABI())
return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
InVals);
- // FIXME: We are using this for both AIX and Darwin. We should add appropriate
- // AIX testing, and rename it appropriately.
return LowerFormalArguments_Darwin(Chain, CallConv, isVarArg, Ins, dl, DAG,
InVals);
}
@@ -6808,6 +6809,117 @@ static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT,
}
}
+static const TargetRegisterClass *getRegClassForSVT(MVT::SimpleValueType SVT,
+ bool IsPPC64) {
+ assert((IsPPC64 || SVT != MVT::i64) &&
+ "i64 should have been split for 32-bit codegen.");
+
+ switch (SVT) {
+ default:
+ report_fatal_error("Unexpected value type for formal argument");
+ case MVT::i1:
+ case MVT::i32:
+ case MVT::i64:
+ return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
+ case MVT::f32:
+ return &PPC::F4RCRegClass;
+ case MVT::f64:
+ return &PPC::F8RCRegClass;
+ }
+}
+
+static SDValue truncateScalarIntegerArg(ISD::ArgFlagsTy Flags, EVT ValVT,
+ SelectionDAG &DAG, SDValue ArgValue,
+ MVT LocVT, const SDLoc &dl) {
+ assert(ValVT.isScalarInteger() && LocVT.isScalarInteger());
+ assert(ValVT.getSizeInBits() < LocVT.getSizeInBits());
+
+ if (Flags.isSExt())
+ ArgValue = DAG.getNode(ISD::AssertSext, dl, LocVT, ArgValue,
+ DAG.getValueType(ValVT));
+ else if (Flags.isZExt())
+ ArgValue = DAG.getNode(ISD::AssertZext, dl, LocVT, ArgValue,
+ DAG.getValueType(ValVT));
+
+ return DAG.getNode(ISD::TRUNCATE, dl, ValVT, ArgValue);
+}
+
+SDValue PPCTargetLowering::LowerFormalArguments_AIX(
+ SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
+ const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
+ SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+
+ assert((CallConv == CallingConv::C || CallConv == CallingConv::Cold ||
+ CallConv == CallingConv::Fast) &&
+ "Unexpected calling convention!");
+
+ if (isVarArg)
+ report_fatal_error("This call type is unimplemented on AIX.");
+
+ if (getTargetMachine().Options.GuaranteedTailCallOpt)
+ report_fatal_error("Tail call support is unimplemented on AIX.");
+
+ if (useSoftFloat())
+ report_fatal_error("Soft float support is unimplemented on AIX.");
+
+ const PPCSubtarget &Subtarget =
+ static_cast<const PPCSubtarget &>(DAG.getSubtarget());
+ if (Subtarget.hasQPX())
+ report_fatal_error("QPX support is not supported on AIX.");
+
+ const bool IsPPC64 = Subtarget.isPPC64();
+ const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
+
+ // Assign locations to all of the incoming arguments.
+ SmallVector<CCValAssign, 16> ArgLocs;
+ MachineFunction &MF = DAG.getMachineFunction();
+ CCState CCInfo(CallConv, isVarArg, MF, ArgLocs, *DAG.getContext());
+
+ // Reserve space for the linkage area on the stack.
+ const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
+ // On AIX a minimum of 8 words is saved to the parameter save area.
+ const unsigned MinParameterSaveArea = 8 * PtrByteSize;
+ CCInfo.AllocateStack(LinkageSize + MinParameterSaveArea, PtrByteSize);
+ CCInfo.AnalyzeFormalArguments(Ins, CC_AIX);
+
+ for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
+ CCValAssign &VA = ArgLocs[i];
+ SDValue ArgValue;
+ ISD::ArgFlagsTy Flags = Ins[i].Flags;
+ if (VA.isRegLoc()) {
+ EVT ValVT = VA.getValVT();
+ MVT LocVT = VA.getLocVT();
+ MVT::SimpleValueType SVT = ValVT.getSimpleVT().SimpleTy;
+ unsigned VReg =
+ MF.addLiveIn(VA.getLocReg(), getRegClassForSVT(SVT, IsPPC64));
+ ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, LocVT);
+ if (ValVT.isScalarInteger() &&
+ (ValVT.getSizeInBits() < LocVT.getSizeInBits())) {
+ ArgValue =
+ truncateScalarIntegerArg(Flags, ValVT, DAG, ArgValue, LocVT, dl);
+ }
+ InVals.push_back(ArgValue);
+ } else {
+ report_fatal_error("Handling of formal arguments on the stack is "
+ "unimplemented!");
+ }
+ }
+
+ // Area that is at least reserved in the caller of this function.
+ unsigned MinReservedArea = CCInfo.getNextStackOffset();
+
+ // Set the size that is at least reserved in caller of this function. Tail
+ // call optimized function's reserved stack space needs to be aligned so
+ // that taking the difference between two stack areas will result in an
+ // aligned stack.
+ MinReservedArea =
+ EnsureStackAlignment(Subtarget.getFrameLowering(), MinReservedArea);
+ PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
+ FuncInfo->setMinReservedArea(MinReservedArea);
+
+ return Chain;
+}
+
SDValue PPCTargetLowering::LowerCall_AIX(
SDValue Chain, SDValue Callee, CallingConv::ID CallConv, bool isVarArg,
bool isTailCall, bool isPatchPoint,
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h
index 77b19b26346..612d1c6b3f2 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.h
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h
@@ -1121,6 +1121,10 @@ namespace llvm {
SelectionDAG &DAG, SDValue ArgVal,
const SDLoc &dl) const;
+ SDValue LowerFormalArguments_AIX(
+ SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
+ const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
+ SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const;
SDValue LowerFormalArguments_Darwin(
SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
OpenPOWER on IntegriCloud