xref: /freebsd/contrib/llvm-project/clang/lib/CodeGen/Targets/LoongArch.cpp (revision e64bea71c21eb42e97aa615188ba91f6cce0d36d)
1 //===- LoongArch.cpp ------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "ABIInfoImpl.h"
10 #include "TargetInfo.h"
11 
12 using namespace clang;
13 using namespace clang::CodeGen;
14 
15 // LoongArch ABI Implementation. Documented at
16 // https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html
17 //
18 //===----------------------------------------------------------------------===//
19 
20 namespace {
21 class LoongArchABIInfo : public DefaultABIInfo {
22 private:
23   // Size of the integer ('r') registers in bits.
24   unsigned GRLen;
25   // Size of the floating point ('f') registers in bits.
26   unsigned FRLen;
27   // Number of general-purpose argument registers.
28   static const int NumGARs = 8;
29   // Number of floating-point argument registers.
30   static const int NumFARs = 8;
31   bool detectFARsEligibleStructHelper(QualType Ty, CharUnits CurOff,
32                                       llvm::Type *&Field1Ty,
33                                       CharUnits &Field1Off,
34                                       llvm::Type *&Field2Ty,
35                                       CharUnits &Field2Off) const;
36 
37 public:
38   LoongArchABIInfo(CodeGen::CodeGenTypes &CGT, unsigned GRLen, unsigned FRLen)
39       : DefaultABIInfo(CGT), GRLen(GRLen), FRLen(FRLen) {}
40 
41   void computeInfo(CGFunctionInfo &FI) const override;
42 
43   ABIArgInfo classifyArgumentType(QualType Ty, bool IsFixed, int &GARsLeft,
44                                   int &FARsLeft) const;
45   ABIArgInfo classifyReturnType(QualType RetTy) const;
46 
47   RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
48                    AggValueSlot Slot) const override;
49 
50   ABIArgInfo extendType(QualType Ty) const;
51 
52   bool detectFARsEligibleStruct(QualType Ty, llvm::Type *&Field1Ty,
53                                 CharUnits &Field1Off, llvm::Type *&Field2Ty,
54                                 CharUnits &Field2Off, int &NeededArgGPRs,
55                                 int &NeededArgFPRs) const;
56   ABIArgInfo coerceAndExpandFARsEligibleStruct(llvm::Type *Field1Ty,
57                                                CharUnits Field1Off,
58                                                llvm::Type *Field2Ty,
59                                                CharUnits Field2Off) const;
60 };
61 } // end anonymous namespace
62 
63 void LoongArchABIInfo::computeInfo(CGFunctionInfo &FI) const {
64   QualType RetTy = FI.getReturnType();
65   if (!getCXXABI().classifyReturnType(FI))
66     FI.getReturnInfo() = classifyReturnType(RetTy);
67 
68   // IsRetIndirect is true if classifyArgumentType indicated the value should
69   // be passed indirect, or if the type size is a scalar greater than 2*GRLen
70   // and not a complex type with elements <= FRLen. e.g. fp128 is passed direct
71   // in LLVM IR, relying on the backend lowering code to rewrite the argument
72   // list and pass indirectly on LA32.
73   bool IsRetIndirect = FI.getReturnInfo().getKind() == ABIArgInfo::Indirect;
74   if (!IsRetIndirect && RetTy->isScalarType() &&
75       getContext().getTypeSize(RetTy) > (2 * GRLen)) {
76     if (RetTy->isComplexType() && FRLen) {
77       QualType EltTy = RetTy->castAs<ComplexType>()->getElementType();
78       IsRetIndirect = getContext().getTypeSize(EltTy) > FRLen;
79     } else {
80       // This is a normal scalar > 2*GRLen, such as fp128 on LA32.
81       IsRetIndirect = true;
82     }
83   }
84 
85   // We must track the number of GARs and FARs used in order to conform to the
86   // LoongArch ABI. As GAR usage is different for variadic arguments, we must
87   // also track whether we are examining a vararg or not.
88   int GARsLeft = IsRetIndirect ? NumGARs - 1 : NumGARs;
89   int FARsLeft = FRLen ? NumFARs : 0;
90   int NumFixedArgs = FI.getNumRequiredArgs();
91 
92   int ArgNum = 0;
93   for (auto &ArgInfo : FI.arguments()) {
94     ArgInfo.info = classifyArgumentType(
95         ArgInfo.type, /*IsFixed=*/ArgNum < NumFixedArgs, GARsLeft, FARsLeft);
96     ArgNum++;
97   }
98 }
99 
100 // Returns true if the struct is a potential candidate to be passed in FARs (and
101 // GARs). If this function returns true, the caller is responsible for checking
102 // that if there is only a single field then that field is a float.
103 bool LoongArchABIInfo::detectFARsEligibleStructHelper(
104     QualType Ty, CharUnits CurOff, llvm::Type *&Field1Ty, CharUnits &Field1Off,
105     llvm::Type *&Field2Ty, CharUnits &Field2Off) const {
106   bool IsInt = Ty->isIntegralOrEnumerationType();
107   bool IsFloat = Ty->isRealFloatingType();
108 
109   if (IsInt || IsFloat) {
110     uint64_t Size = getContext().getTypeSize(Ty);
111     if (IsInt && Size > GRLen)
112       return false;
113     // Can't be eligible if larger than the FP registers. Handling of half
114     // precision values has been specified in the ABI, so don't block those.
115     if (IsFloat && Size > FRLen)
116       return false;
117     // Can't be eligible if an integer type was already found (int+int pairs
118     // are not eligible).
119     if (IsInt && Field1Ty && Field1Ty->isIntegerTy())
120       return false;
121     if (!Field1Ty) {
122       Field1Ty = CGT.ConvertType(Ty);
123       Field1Off = CurOff;
124       return true;
125     }
126     if (!Field2Ty) {
127       Field2Ty = CGT.ConvertType(Ty);
128       Field2Off = CurOff;
129       return true;
130     }
131     return false;
132   }
133 
134   if (auto CTy = Ty->getAs<ComplexType>()) {
135     if (Field1Ty)
136       return false;
137     QualType EltTy = CTy->getElementType();
138     if (getContext().getTypeSize(EltTy) > FRLen)
139       return false;
140     Field1Ty = CGT.ConvertType(EltTy);
141     Field1Off = CurOff;
142     Field2Ty = Field1Ty;
143     Field2Off = Field1Off + getContext().getTypeSizeInChars(EltTy);
144     return true;
145   }
146 
147   if (const ConstantArrayType *ATy = getContext().getAsConstantArrayType(Ty)) {
148     uint64_t ArraySize = ATy->getZExtSize();
149     QualType EltTy = ATy->getElementType();
150     // Non-zero-length arrays of empty records make the struct ineligible to be
151     // passed via FARs in C++.
152     if (const auto *RTy = EltTy->getAs<RecordType>()) {
153       if (ArraySize != 0 && isa<CXXRecordDecl>(RTy->getDecl()) &&
154           isEmptyRecord(getContext(), EltTy, true, true))
155         return false;
156     }
157     CharUnits EltSize = getContext().getTypeSizeInChars(EltTy);
158     for (uint64_t i = 0; i < ArraySize; ++i) {
159       if (!detectFARsEligibleStructHelper(EltTy, CurOff, Field1Ty, Field1Off,
160                                           Field2Ty, Field2Off))
161         return false;
162       CurOff += EltSize;
163     }
164     return true;
165   }
166 
167   if (const auto *RTy = Ty->getAs<RecordType>()) {
168     // Structures with either a non-trivial destructor or a non-trivial
169     // copy constructor are not eligible for the FP calling convention.
170     if (getRecordArgABI(Ty, CGT.getCXXABI()))
171       return false;
172     const RecordDecl *RD = RTy->getDecl();
173     if (isEmptyRecord(getContext(), Ty, true, true) &&
174         (!RD->isUnion() || !isa<CXXRecordDecl>(RD)))
175       return true;
176     // Unions aren't eligible unless they're empty in C (which is caught above).
177     if (RD->isUnion())
178       return false;
179     const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
180     // If this is a C++ record, check the bases first.
181     if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
182       for (const CXXBaseSpecifier &B : CXXRD->bases()) {
183         const auto *BDecl =
184             cast<CXXRecordDecl>(B.getType()->castAs<RecordType>()->getDecl());
185         if (!detectFARsEligibleStructHelper(
186                 B.getType(), CurOff + Layout.getBaseClassOffset(BDecl),
187                 Field1Ty, Field1Off, Field2Ty, Field2Off))
188           return false;
189       }
190     }
191     for (const FieldDecl *FD : RD->fields()) {
192       QualType QTy = FD->getType();
193       if (FD->isBitField()) {
194         unsigned BitWidth = FD->getBitWidthValue();
195         // Zero-width bitfields are ignored.
196         if (BitWidth == 0)
197           continue;
198         // Allow a bitfield with a type greater than GRLen as long as the
199         // bitwidth is GRLen or less.
200         if (getContext().getTypeSize(QTy) > GRLen && BitWidth <= GRLen) {
201           QTy = getContext().getIntTypeForBitwidth(GRLen, false);
202         }
203       }
204 
205       if (!detectFARsEligibleStructHelper(
206               QTy,
207               CurOff + getContext().toCharUnitsFromBits(
208                            Layout.getFieldOffset(FD->getFieldIndex())),
209               Field1Ty, Field1Off, Field2Ty, Field2Off))
210         return false;
211     }
212     return Field1Ty != nullptr;
213   }
214 
215   return false;
216 }
217 
218 // Determine if a struct is eligible to be passed in FARs (and GARs) (i.e., when
219 // flattened it contains a single fp value, fp+fp, or int+fp of appropriate
220 // size). If so, NeededFARs and NeededGARs are incremented appropriately.
221 bool LoongArchABIInfo::detectFARsEligibleStruct(
222     QualType Ty, llvm::Type *&Field1Ty, CharUnits &Field1Off,
223     llvm::Type *&Field2Ty, CharUnits &Field2Off, int &NeededGARs,
224     int &NeededFARs) const {
225   Field1Ty = nullptr;
226   Field2Ty = nullptr;
227   NeededGARs = 0;
228   NeededFARs = 0;
229   if (!detectFARsEligibleStructHelper(Ty, CharUnits::Zero(), Field1Ty,
230                                       Field1Off, Field2Ty, Field2Off))
231     return false;
232   if (!Field1Ty)
233     return false;
234   // Not really a candidate if we have a single int but no float.
235   if (Field1Ty && !Field2Ty && !Field1Ty->isFloatingPointTy())
236     return false;
237   if (Field1Ty && Field1Ty->isFloatingPointTy())
238     NeededFARs++;
239   else if (Field1Ty)
240     NeededGARs++;
241   if (Field2Ty && Field2Ty->isFloatingPointTy())
242     NeededFARs++;
243   else if (Field2Ty)
244     NeededGARs++;
245   return true;
246 }
247 
248 // Call getCoerceAndExpand for the two-element flattened struct described by
249 // Field1Ty, Field1Off, Field2Ty, Field2Off. This method will create an
250 // appropriate coerceToType and unpaddedCoerceToType.
251 ABIArgInfo LoongArchABIInfo::coerceAndExpandFARsEligibleStruct(
252     llvm::Type *Field1Ty, CharUnits Field1Off, llvm::Type *Field2Ty,
253     CharUnits Field2Off) const {
254   SmallVector<llvm::Type *, 3> CoerceElts;
255   SmallVector<llvm::Type *, 2> UnpaddedCoerceElts;
256   if (!Field1Off.isZero())
257     CoerceElts.push_back(llvm::ArrayType::get(
258         llvm::Type::getInt8Ty(getVMContext()), Field1Off.getQuantity()));
259 
260   CoerceElts.push_back(Field1Ty);
261   UnpaddedCoerceElts.push_back(Field1Ty);
262 
263   if (!Field2Ty) {
264     return ABIArgInfo::getCoerceAndExpand(
265         llvm::StructType::get(getVMContext(), CoerceElts, !Field1Off.isZero()),
266         UnpaddedCoerceElts[0]);
267   }
268 
269   CharUnits Field2Align =
270       CharUnits::fromQuantity(getDataLayout().getABITypeAlign(Field2Ty));
271   CharUnits Field1End =
272       Field1Off +
273       CharUnits::fromQuantity(getDataLayout().getTypeStoreSize(Field1Ty));
274   CharUnits Field2OffNoPadNoPack = Field1End.alignTo(Field2Align);
275 
276   CharUnits Padding = CharUnits::Zero();
277   if (Field2Off > Field2OffNoPadNoPack)
278     Padding = Field2Off - Field2OffNoPadNoPack;
279   else if (Field2Off != Field2Align && Field2Off > Field1End)
280     Padding = Field2Off - Field1End;
281 
282   bool IsPacked = !Field2Off.isMultipleOf(Field2Align);
283 
284   if (!Padding.isZero())
285     CoerceElts.push_back(llvm::ArrayType::get(
286         llvm::Type::getInt8Ty(getVMContext()), Padding.getQuantity()));
287 
288   CoerceElts.push_back(Field2Ty);
289   UnpaddedCoerceElts.push_back(Field2Ty);
290 
291   return ABIArgInfo::getCoerceAndExpand(
292       llvm::StructType::get(getVMContext(), CoerceElts, IsPacked),
293       llvm::StructType::get(getVMContext(), UnpaddedCoerceElts, IsPacked));
294 }
295 
296 ABIArgInfo LoongArchABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
297                                                   int &GARsLeft,
298                                                   int &FARsLeft) const {
299   assert(GARsLeft <= NumGARs && "GAR tracking underflow");
300   Ty = useFirstFieldIfTransparentUnion(Ty);
301 
302   // Structures with either a non-trivial destructor or a non-trivial
303   // copy constructor are always passed indirectly.
304   if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) {
305     if (GARsLeft)
306       GARsLeft -= 1;
307     return getNaturalAlignIndirect(
308         Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),
309         /*ByVal=*/RAA == CGCXXABI::RAA_DirectInMemory);
310   }
311 
312   uint64_t Size = getContext().getTypeSize(Ty);
313 
314   // Ignore empty struct or union whose size is zero, e.g. `struct { }` in C or
315   // `struct { int a[0]; }` in C++. In C++, `struct { }` is empty but it's size
316   // is 1 byte and g++ doesn't ignore it; clang++ matches this behaviour.
317   if (isEmptyRecord(getContext(), Ty, true) && Size == 0)
318     return ABIArgInfo::getIgnore();
319 
320   // Pass floating point values via FARs if possible.
321   if (IsFixed && Ty->isFloatingType() && !Ty->isComplexType() &&
322       FRLen >= Size && FARsLeft) {
323     FARsLeft--;
324     return ABIArgInfo::getDirect();
325   }
326 
327   // Complex types for the *f or *d ABI must be passed directly rather than
328   // using CoerceAndExpand.
329   if (IsFixed && Ty->isComplexType() && FRLen && FARsLeft >= 2) {
330     QualType EltTy = Ty->castAs<ComplexType>()->getElementType();
331     if (getContext().getTypeSize(EltTy) <= FRLen) {
332       FARsLeft -= 2;
333       return ABIArgInfo::getDirect();
334     }
335   }
336 
337   if (IsFixed && FRLen && Ty->isStructureOrClassType()) {
338     llvm::Type *Field1Ty = nullptr;
339     llvm::Type *Field2Ty = nullptr;
340     CharUnits Field1Off = CharUnits::Zero();
341     CharUnits Field2Off = CharUnits::Zero();
342     int NeededGARs = 0;
343     int NeededFARs = 0;
344     bool IsCandidate = detectFARsEligibleStruct(
345         Ty, Field1Ty, Field1Off, Field2Ty, Field2Off, NeededGARs, NeededFARs);
346     if (IsCandidate && NeededGARs <= GARsLeft && NeededFARs <= FARsLeft) {
347       GARsLeft -= NeededGARs;
348       FARsLeft -= NeededFARs;
349       return coerceAndExpandFARsEligibleStruct(Field1Ty, Field1Off, Field2Ty,
350                                                Field2Off);
351     }
352   }
353 
354   uint64_t NeededAlign = getContext().getTypeAlign(Ty);
355   // Determine the number of GARs needed to pass the current argument
356   // according to the ABI. 2*GRLen-aligned varargs are passed in "aligned"
357   // register pairs, so may consume 3 registers.
358   int NeededGARs = 1;
359   if (!IsFixed && NeededAlign == 2 * GRLen)
360     NeededGARs = 2 + (GARsLeft % 2);
361   else if (Size > GRLen && Size <= 2 * GRLen)
362     NeededGARs = 2;
363 
364   if (NeededGARs > GARsLeft)
365     NeededGARs = GARsLeft;
366 
367   GARsLeft -= NeededGARs;
368 
369   if (!isAggregateTypeForABI(Ty) && !Ty->isVectorType()) {
370     // Treat an enum type as its underlying type.
371     if (const EnumType *EnumTy = Ty->getAs<EnumType>())
372       Ty = EnumTy->getDecl()->getIntegerType();
373 
374     // All integral types are promoted to GRLen width.
375     if (Size < GRLen && Ty->isIntegralOrEnumerationType())
376       return extendType(Ty);
377 
378     if (const auto *EIT = Ty->getAs<BitIntType>()) {
379       if (EIT->getNumBits() < GRLen)
380         return extendType(Ty);
381       if (EIT->getNumBits() > 128 ||
382           (!getContext().getTargetInfo().hasInt128Type() &&
383            EIT->getNumBits() > 64))
384         return getNaturalAlignIndirect(
385             Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),
386             /*ByVal=*/false);
387     }
388 
389     return ABIArgInfo::getDirect();
390   }
391 
392   // Aggregates which are <= 2*GRLen will be passed in registers if possible,
393   // so coerce to integers.
394   if (Size <= 2 * GRLen) {
395     // Use a single GRLen int if possible, 2*GRLen if 2*GRLen alignment is
396     // required, and a 2-element GRLen array if only GRLen alignment is
397     // required.
398     if (Size <= GRLen) {
399       return ABIArgInfo::getDirect(
400           llvm::IntegerType::get(getVMContext(), GRLen));
401     }
402     if (getContext().getTypeAlign(Ty) == 2 * GRLen) {
403       return ABIArgInfo::getDirect(
404           llvm::IntegerType::get(getVMContext(), 2 * GRLen));
405     }
406     return ABIArgInfo::getDirect(
407         llvm::ArrayType::get(llvm::IntegerType::get(getVMContext(), GRLen), 2));
408   }
409   return getNaturalAlignIndirect(
410       Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),
411       /*ByVal=*/false);
412 }
413 
414 ABIArgInfo LoongArchABIInfo::classifyReturnType(QualType RetTy) const {
415   if (RetTy->isVoidType())
416     return ABIArgInfo::getIgnore();
417   // The rules for return and argument types are the same, so defer to
418   // classifyArgumentType.
419   int GARsLeft = 2;
420   int FARsLeft = FRLen ? 2 : 0;
421   return classifyArgumentType(RetTy, /*IsFixed=*/true, GARsLeft, FARsLeft);
422 }
423 
424 RValue LoongArchABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
425                                    QualType Ty, AggValueSlot Slot) const {
426   CharUnits SlotSize = CharUnits::fromQuantity(GRLen / 8);
427 
428   // Empty records are ignored for parameter passing purposes.
429   if (isEmptyRecord(getContext(), Ty, true))
430     return Slot.asRValue();
431 
432   auto TInfo = getContext().getTypeInfoInChars(Ty);
433 
434   // Arguments bigger than 2*GRLen bytes are passed indirectly.
435   return emitVoidPtrVAArg(CGF, VAListAddr, Ty,
436                           /*IsIndirect=*/TInfo.Width > 2 * SlotSize, TInfo,
437                           SlotSize,
438                           /*AllowHigherAlign=*/true, Slot);
439 }
440 
441 ABIArgInfo LoongArchABIInfo::extendType(QualType Ty) const {
442   int TySize = getContext().getTypeSize(Ty);
443   // LA64 ABI requires unsigned 32 bit integers to be sign extended.
444   if (GRLen == 64 && Ty->isUnsignedIntegerOrEnumerationType() && TySize == 32)
445     return ABIArgInfo::getSignExtend(Ty);
446   return ABIArgInfo::getExtend(Ty);
447 }
448 
449 namespace {
450 class LoongArchTargetCodeGenInfo : public TargetCodeGenInfo {
451 public:
452   LoongArchTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, unsigned GRLen,
453                              unsigned FRLen)
454       : TargetCodeGenInfo(
455             std::make_unique<LoongArchABIInfo>(CGT, GRLen, FRLen)) {}
456 };
457 } // namespace
458 
459 std::unique_ptr<TargetCodeGenInfo>
460 CodeGen::createLoongArchTargetCodeGenInfo(CodeGenModule &CGM, unsigned GRLen,
461                                           unsigned FLen) {
462   return std::make_unique<LoongArchTargetCodeGenInfo>(CGM.getTypes(), GRLen,
463                                                       FLen);
464 }
465