================ @@ -337,12 +347,58 @@ CharUnits PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const { return CharUnits::fromQuantity(4); } +ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t &TypeSize) const { + llvm::Type *ElemTy; + unsigned RegsNeeded; // Registers Needed for Complex. + + if (TypeSize == 64) { + ElemTy = llvm::Type::getInt64Ty(getVMContext()); + RegsNeeded = 1; + } else { + ElemTy = llvm::Type::getInt32Ty(getVMContext()); + RegsNeeded = (TypeSize + 31) / 32; + } + return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded)); +} + +ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty, + int &ArgGPRsLeft) const { + assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow"); + Ty = useFirstFieldIfTransparentUnion(Ty); + + ASTContext &Context = getContext(); + + uint64_t TypeSize = Context.getTypeSize(Ty); + + if (IsComplexInRegABI && Ty->isAnyComplexType() && + TypeSize <= RegLen * ArgGPRsLeft) { + assert(Ty->isAnyComplexType() && "Ty must be Complex type."); + ArgGPRsLeft -= TypeSize / RegLen; + return handleComplex(TypeSize); + } + + if (ArgGPRsLeft) { + // Records with non-trivial destructors/copy-constructors should not be + // passed by value. + if (isAggregateTypeForABI(Ty)) + ArgGPRsLeft -= 1; + else if (!Ty->isFloatingType()) { + // For other premitive types. + if (TypeSize > RegLen && TypeSize <= 2 * RegLen) + ArgGPRsLeft -= TypeSize / RegLen; ---------------- diggerlin wrote:
for a test case `foo6(_Complex long double foo4(int x1, long long y1, int x2, _Complex double z,)` `int x1` will have r3, `long long y1` will have r5,r6 (skip r4 since it is even, for 64bit integer need to start start odd register.) `int x2` will have r7, ` _Complex double z` need to occupy 4 registers, there is no enough register , it can not pass `_Complex double z` in r8,r9,r10 , you have to pass ` _Complex double z` in by pointer (you can not call `handleComplex()`). but in your code, ArgGPRsLeft is 7 after int x1, ArgGPRsLeft is 5 after long long y1 ArgGPRsLeft is 4 after int x2 there is still have 4 registers left for ` _Complex double z`, you can call `handleComplex()`, you will pass ` _Complex double z` by value can you check how gcc deal with this case `foo6(_Complex long double foo4(int x1, long long y1, int x2, _Complex double z,)` ? https://github.com/llvm/llvm-project/pull/77732 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits