jasonliu created this revision.
jasonliu added reviewers: sfertile, nemanjai, hubert.reinterpretcast,
cebowleratibm.
Herald added subscribers: steven.zhang, shchenz.
jasonliu added a reviewer: PowerPC.
jasonliu added a comment.
To reviewers:
Although the patch is showing changes on various ABIInfo classes. But those
classes are actually untouched.
This patch only touches PowerPC TargetCodeGenInfo related classes.
There is little differences across all power pc related target for
TargetCodeGenInfo implementation.
The biggest difference is the different ABIInfo classes it takes.
But we don't necessarily need so many TargetCodeGenInfo for different PowerPC
architect.
So it might be beneficial to common them up as one PPCTargetCodeGenInfo.
https://reviews.llvm.org/D78506
Files:
clang/lib/CodeGen/TargetInfo.cpp
Index: clang/lib/CodeGen/TargetInfo.cpp
===
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -4172,8 +4172,9 @@
/*allowHigherAlign*/ false);
}
-// PowerPC-32
+// PowerPC
namespace {
+// PowerPC-32
/// PPC32_SVR4_ABIInfo - The 32-bit PowerPC ELF (SVR4) ABI information.
class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
bool IsSoftFloatABI;
@@ -4188,10 +4189,136 @@
QualType Ty) const override;
};
-class PPC32TargetCodeGenInfo : public TargetCodeGenInfo {
+// PowerPC-64
+/// PPC64_SVR4_ABIInfo - The 64-bit PowerPC ELF (SVR4) ABI information.
+class PPC64_SVR4_ABIInfo : public SwiftABIInfo {
+public:
+ enum ABIKind {
+ELFv1 = 0,
+ELFv2
+ };
+
+private:
+ static const unsigned GPRBits = 64;
+ ABIKind Kind;
+ bool HasQPX;
+ bool IsSoftFloatABI;
+
+ // A vector of float or double will be promoted to <4 x f32> or <4 x f64> and
+ // will be passed in a QPX register.
+ bool IsQPXVectorTy(const Type *Ty) const {
+if (!HasQPX)
+ return false;
+
+if (const VectorType *VT = Ty->getAs()) {
+ unsigned NumElements = VT->getNumElements();
+ if (NumElements == 1)
+return false;
+
+ if (VT->getElementType()->isSpecificBuiltinType(BuiltinType::Double)) {
+if (getContext().getTypeSize(Ty) <= 256)
+ return true;
+ } else if (VT->getElementType()->
+ isSpecificBuiltinType(BuiltinType::Float)) {
+if (getContext().getTypeSize(Ty) <= 128)
+ return true;
+ }
+}
+
+return false;
+ }
+
+ bool IsQPXVectorTy(QualType Ty) const {
+return IsQPXVectorTy(Ty.getTypePtr());
+ }
+
+public:
+ PPC64_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, ABIKind Kind, bool HasQPX,
+ bool SoftFloatABI)
+ : SwiftABIInfo(CGT), Kind(Kind), HasQPX(HasQPX),
+IsSoftFloatABI(SoftFloatABI) {}
+
+ bool isPromotableTypeForABI(QualType Ty) const;
+ CharUnits getParamTypeAlignment(QualType Ty) const;
+
+ ABIArgInfo classifyReturnType(QualType RetTy) const;
+ ABIArgInfo classifyArgumentType(QualType Ty) const;
+
+ bool isHomogeneousAggregateBaseType(QualType Ty) const override;
+ bool isHomogeneousAggregateSmallEnough(const Type *Ty,
+ uint64_t Members) const override;
+
+ // TODO: We can add more logic to computeInfo to improve performance.
+ // Example: For aggregate arguments that fit in a register, we could
+ // use getDirectInReg (as is done below for structs containing a single
+ // floating-point value) to avoid pushing them to memory on function
+ // entry. This would require changing the logic in PPCISelLowering
+ // when lowering the parameters in the caller and args in the callee.
+ void computeInfo(CGFunctionInfo &FI) const override {
+if (!getCXXABI().classifyReturnType(FI))
+ FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+for (auto &I : FI.arguments()) {
+ // We rely on the default argument classification for the most part.
+ // One exception: An aggregate containing a single floating-point
+ // or vector item must be passed in a register if one is available.
+ const Type *T = isSingleElementStruct(I.type, getContext());
+ if (T) {
+const BuiltinType *BT = T->getAs();
+if (IsQPXVectorTy(T) ||
+(T->isVectorType() && getContext().getTypeSize(T) == 128) ||
+(BT && BT->isFloatingPoint())) {
+ QualType QT(T, 0);
+ I.info = ABIArgInfo::getDirectInReg(CGT.ConvertType(QT));
+ continue;
+}
+ }
+ I.info = classifyArgumentType(I.type);
+}
+ }
+
+ Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+QualType Ty) const override;
+
+ bool shouldPassIndirectlyForSwift(ArrayRef scalars,
+bool asReturnValue) const override {
+return occupiesMoreThan(CGT, scalars, /*total*/ 4);
+ }
+
+ bool isSwiftErrorInRegister() const override {
+return false;
+ }
+};
+
+class PPCTargetCodeGenInf