[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
zhijian lin via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 5 12:18:32 PDT 2024
================
@@ -396,12 +405,80 @@ 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.
+
+ // Choice of using llvm::Type::getInt64Ty(getVMContext()) for complex
+ // single-precision floats is based on the ABI ATR-PASS-COMPLEX-IN-GPRS
+ // specification. According to the specification:
+ // - For complex single-precision floats: If the register (gr) is even, it's
+ // incremented by one, and the lower-addressed word of the argument is loaded
+ // into gr, while the higher-addressed word is loaded into gr + 1. Then, gr is
+ // incremented by 2.
+ // - For complex double-precision floats: The words of the argument are loaded
+ // in memory-address order into gr, gr + 1, gr + 2, and gr + 3, with gr being
+ // incremented by 4. Thus, to maintain even alignment and adhere to the ABI
+ // specification, llvm::Type::getInt64Ty(getVMContext()) is used when TypeSize
+ // is 64. Powerpc backend handles this alignment requirement. Specifically,
+ // you can refer to the CC_PPC32_SVR4_Custom_AlignArgRegs method from
+ // PPCCallingconvention.cpp. For more context, refer to the previous
+ // discussion: https://reviews.llvm.org/D146942 and the related LLVM pull
+ // request: #77732
+
+ if (TypeSize == 64) {
+ ElemTy = llvm::Type::getInt64Ty(getVMContext());
+ RegsNeeded = 1;
+ } else {
+ ElemTy = llvm::Type::getInt32Ty(getVMContext());
+ RegsNeeded = TypeSize >> 5;
+ }
+ return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+ int &ArgGPRsLeft) const {
+ Ty = useFirstFieldIfTransparentUnion(Ty);
+
+ if (!(getCodeGenOpts().getComplexInRegABI() == CodeGenOptions::CMPLX_InGPR) ||
+ !ArgGPRsLeft)
+ return DefaultABIInfo::classifyArgumentType(Ty);
+
+ assert(ArgGPRsLeft >= 0 && "Arg GPR must be large or equal than zero");
+ ASTContext &Context = getContext();
+ uint64_t TypeSize = Context.getTypeSize(Ty);
+
+ if (Ty->isAnyComplexType()) {
+ // If gr is even set gr = gr + 1 for TypeSize=64.
+ if (TypeSize == 64 && ArgGPRsLeft % 2 == 1)
+ --ArgGPRsLeft;
+
+ if (TypeSize <= RegLen * ArgGPRsLeft) {
+ ArgGPRsLeft -= TypeSize / RegLen;
+ return handleComplex(TypeSize);
+ }
+ }
+
+ // Records with non-trivial destructors/copy-constructors should not be
+ // passed by value.
+ if (isAggregateTypeForABI(Ty))
+ --ArgGPRsLeft;
+ else if (!Ty->isFloatingType() || (Ty->isFloatingType() && IsSoftFloatABI)) {
+ // For other primitive types.
+ if (TypeSize == 64 && ArgGPRsLeft % 2 == 1)
+ --ArgGPRsLeft; // If gr is even set gr = gr + 1 for TypeSize=64.
+ if (TypeSize <= ArgGPRsLeft * RegLen)
+ ArgGPRsLeft -= TypeSize / RegLen;
+ }
----------------
diggerlin wrote:
the code line 467-472 is duplicated with the code 452-458 ,you rewrite the function as
```
ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
int &ArgGPRsLeft) const {
Ty = useFirstFieldIfTransparentUnion(Ty);
if ( getCodeGenOpts().getComplexInRegABI() != CodeGenOptions::CMPLX_InGPR ||
!ArgGPRsLeft || (Ty->isFloatingType() && !IsSoftFloatABI)
return DefaultABIInfo::classifyArgumentType(Ty);
assert(ArgGPRsLeft >= 0 && "Arg GPR must be large or equal than zero");
// Records with non-trivial destructors/copy-constructors should not be
// passed by value.
if (isAggregateTypeForABI(Ty))
--ArgGPRsLeft;
ASTContext &Context = getContext();
uint64_t TypeSize = Context.getTypeSize(Ty);
// If gr is even set gr = gr + 1 for TypeSize=64.
if (TypeSize == 64 && ArgGPRsLeft % 2 == 1)
--ArgGPRsLeft;
if (TypeSize <= RegLen * ArgGPRsLeft) {
ArgGPRsLeft -= TypeSize / RegLen;
return handleComplex(TypeSize);
}
return DefaultABIInfo::classifyArgumentType(Ty);
}
```
https://github.com/llvm/llvm-project/pull/77732
More information about the cfe-commits
mailing list