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 Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, 48 QualType Ty) 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. Half precision isn't 114 // currently supported on LoongArch and the ABI hasn't been confirmed, so 115 // default to the integer ABI in that case. 116 if (IsFloat && (Size > FRLen || Size < 32)) 117 return false; 118 // Can't be eligible if an integer type was already found (int+int pairs 119 // are not eligible). 120 if (IsInt && Field1Ty && Field1Ty->isIntegerTy()) 121 return false; 122 if (!Field1Ty) { 123 Field1Ty = CGT.ConvertType(Ty); 124 Field1Off = CurOff; 125 return true; 126 } 127 if (!Field2Ty) { 128 Field2Ty = CGT.ConvertType(Ty); 129 Field2Off = CurOff; 130 return true; 131 } 132 return false; 133 } 134 135 if (auto CTy = Ty->getAs<ComplexType>()) { 136 if (Field1Ty) 137 return false; 138 QualType EltTy = CTy->getElementType(); 139 if (getContext().getTypeSize(EltTy) > FRLen) 140 return false; 141 Field1Ty = CGT.ConvertType(EltTy); 142 Field1Off = CurOff; 143 Field2Ty = Field1Ty; 144 Field2Off = Field1Off + getContext().getTypeSizeInChars(EltTy); 145 return true; 146 } 147 148 if (const ConstantArrayType *ATy = getContext().getAsConstantArrayType(Ty)) { 149 uint64_t ArraySize = ATy->getSize().getZExtValue(); 150 QualType EltTy = ATy->getElementType(); 151 // Non-zero-length arrays of empty records make the struct ineligible to be 152 // passed via FARs in C++. 153 if (const auto *RTy = EltTy->getAs<RecordType>()) { 154 if (ArraySize != 0 && isa<CXXRecordDecl>(RTy->getDecl()) && 155 isEmptyRecord(getContext(), EltTy, true, true)) 156 return false; 157 } 158 CharUnits EltSize = getContext().getTypeSizeInChars(EltTy); 159 for (uint64_t i = 0; i < ArraySize; ++i) { 160 if (!detectFARsEligibleStructHelper(EltTy, CurOff, Field1Ty, Field1Off, 161 Field2Ty, Field2Off)) 162 return false; 163 CurOff += EltSize; 164 } 165 return true; 166 } 167 168 if (const auto *RTy = Ty->getAs<RecordType>()) { 169 // Structures with either a non-trivial destructor or a non-trivial 170 // copy constructor are not eligible for the FP calling convention. 171 if (getRecordArgABI(Ty, CGT.getCXXABI())) 172 return false; 173 const RecordDecl *RD = RTy->getDecl(); 174 if (isEmptyRecord(getContext(), Ty, true, true) && 175 (!RD->isUnion() || !isa<CXXRecordDecl>(RD))) 176 return true; 177 // Unions aren't eligible unless they're empty in C (which is caught above). 178 if (RD->isUnion()) 179 return false; 180 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 181 // If this is a C++ record, check the bases first. 182 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { 183 for (const CXXBaseSpecifier &B : CXXRD->bases()) { 184 const auto *BDecl = 185 cast<CXXRecordDecl>(B.getType()->castAs<RecordType>()->getDecl()); 186 if (!detectFARsEligibleStructHelper( 187 B.getType(), CurOff + Layout.getBaseClassOffset(BDecl), 188 Field1Ty, Field1Off, Field2Ty, Field2Off)) 189 return false; 190 } 191 } 192 for (const FieldDecl *FD : RD->fields()) { 193 QualType QTy = FD->getType(); 194 if (FD->isBitField()) { 195 unsigned BitWidth = FD->getBitWidthValue(getContext()); 196 // Zero-width bitfields are ignored. 197 if (BitWidth == 0) 198 continue; 199 // Allow a bitfield with a type greater than GRLen as long as the 200 // bitwidth is GRLen or less. 201 if (getContext().getTypeSize(QTy) > GRLen && BitWidth <= GRLen) { 202 QTy = getContext().getIntTypeForBitwidth(GRLen, false); 203 } 204 } 205 206 if (!detectFARsEligibleStructHelper( 207 QTy, 208 CurOff + getContext().toCharUnitsFromBits( 209 Layout.getFieldOffset(FD->getFieldIndex())), 210 Field1Ty, Field1Off, Field2Ty, Field2Off)) 211 return false; 212 } 213 return Field1Ty != nullptr; 214 } 215 216 return false; 217 } 218 219 // Determine if a struct is eligible to be passed in FARs (and GARs) (i.e., when 220 // flattened it contains a single fp value, fp+fp, or int+fp of appropriate 221 // size). If so, NeededFARs and NeededGARs are incremented appropriately. 222 bool LoongArchABIInfo::detectFARsEligibleStruct( 223 QualType Ty, llvm::Type *&Field1Ty, CharUnits &Field1Off, 224 llvm::Type *&Field2Ty, CharUnits &Field2Off, int &NeededGARs, 225 int &NeededFARs) const { 226 Field1Ty = nullptr; 227 Field2Ty = nullptr; 228 NeededGARs = 0; 229 NeededFARs = 0; 230 if (!detectFARsEligibleStructHelper(Ty, CharUnits::Zero(), Field1Ty, 231 Field1Off, Field2Ty, Field2Off)) 232 return false; 233 if (!Field1Ty) 234 return false; 235 // Not really a candidate if we have a single int but no float. 236 if (Field1Ty && !Field2Ty && !Field1Ty->isFloatingPointTy()) 237 return false; 238 if (Field1Ty && Field1Ty->isFloatingPointTy()) 239 NeededFARs++; 240 else if (Field1Ty) 241 NeededGARs++; 242 if (Field2Ty && Field2Ty->isFloatingPointTy()) 243 NeededFARs++; 244 else if (Field2Ty) 245 NeededGARs++; 246 return true; 247 } 248 249 // Call getCoerceAndExpand for the two-element flattened struct described by 250 // Field1Ty, Field1Off, Field2Ty, Field2Off. This method will create an 251 // appropriate coerceToType and unpaddedCoerceToType. 252 ABIArgInfo LoongArchABIInfo::coerceAndExpandFARsEligibleStruct( 253 llvm::Type *Field1Ty, CharUnits Field1Off, llvm::Type *Field2Ty, 254 CharUnits Field2Off) const { 255 SmallVector<llvm::Type *, 3> CoerceElts; 256 SmallVector<llvm::Type *, 2> UnpaddedCoerceElts; 257 if (!Field1Off.isZero()) 258 CoerceElts.push_back(llvm::ArrayType::get( 259 llvm::Type::getInt8Ty(getVMContext()), Field1Off.getQuantity())); 260 261 CoerceElts.push_back(Field1Ty); 262 UnpaddedCoerceElts.push_back(Field1Ty); 263 264 if (!Field2Ty) { 265 return ABIArgInfo::getCoerceAndExpand( 266 llvm::StructType::get(getVMContext(), CoerceElts, !Field1Off.isZero()), 267 UnpaddedCoerceElts[0]); 268 } 269 270 CharUnits Field2Align = 271 CharUnits::fromQuantity(getDataLayout().getABITypeAlign(Field2Ty)); 272 CharUnits Field1End = 273 Field1Off + 274 CharUnits::fromQuantity(getDataLayout().getTypeStoreSize(Field1Ty)); 275 CharUnits Field2OffNoPadNoPack = Field1End.alignTo(Field2Align); 276 277 CharUnits Padding = CharUnits::Zero(); 278 if (Field2Off > Field2OffNoPadNoPack) 279 Padding = Field2Off - Field2OffNoPadNoPack; 280 else if (Field2Off != Field2Align && Field2Off > Field1End) 281 Padding = Field2Off - Field1End; 282 283 bool IsPacked = !Field2Off.isMultipleOf(Field2Align); 284 285 if (!Padding.isZero()) 286 CoerceElts.push_back(llvm::ArrayType::get( 287 llvm::Type::getInt8Ty(getVMContext()), Padding.getQuantity())); 288 289 CoerceElts.push_back(Field2Ty); 290 UnpaddedCoerceElts.push_back(Field2Ty); 291 292 return ABIArgInfo::getCoerceAndExpand( 293 llvm::StructType::get(getVMContext(), CoerceElts, IsPacked), 294 llvm::StructType::get(getVMContext(), UnpaddedCoerceElts, IsPacked)); 295 } 296 297 ABIArgInfo LoongArchABIInfo::classifyArgumentType(QualType Ty, bool IsFixed, 298 int &GARsLeft, 299 int &FARsLeft) const { 300 assert(GARsLeft <= NumGARs && "GAR tracking underflow"); 301 Ty = useFirstFieldIfTransparentUnion(Ty); 302 303 // Structures with either a non-trivial destructor or a non-trivial 304 // copy constructor are always passed indirectly. 305 if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) { 306 if (GARsLeft) 307 GARsLeft -= 1; 308 return getNaturalAlignIndirect(Ty, /*ByVal=*/RAA == 309 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(Ty, /*ByVal=*/false); 385 } 386 387 return ABIArgInfo::getDirect(); 388 } 389 390 // Aggregates which are <= 2*GRLen will be passed in registers if possible, 391 // so coerce to integers. 392 if (Size <= 2 * GRLen) { 393 // Use a single GRLen int if possible, 2*GRLen if 2*GRLen alignment is 394 // required, and a 2-element GRLen array if only GRLen alignment is 395 // required. 396 if (Size <= GRLen) { 397 return ABIArgInfo::getDirect( 398 llvm::IntegerType::get(getVMContext(), GRLen)); 399 } 400 if (getContext().getTypeAlign(Ty) == 2 * GRLen) { 401 return ABIArgInfo::getDirect( 402 llvm::IntegerType::get(getVMContext(), 2 * GRLen)); 403 } 404 return ABIArgInfo::getDirect( 405 llvm::ArrayType::get(llvm::IntegerType::get(getVMContext(), GRLen), 2)); 406 } 407 return getNaturalAlignIndirect(Ty, /*ByVal=*/false); 408 } 409 410 ABIArgInfo LoongArchABIInfo::classifyReturnType(QualType RetTy) const { 411 if (RetTy->isVoidType()) 412 return ABIArgInfo::getIgnore(); 413 // The rules for return and argument types are the same, so defer to 414 // classifyArgumentType. 415 int GARsLeft = 2; 416 int FARsLeft = FRLen ? 2 : 0; 417 return classifyArgumentType(RetTy, /*IsFixed=*/true, GARsLeft, FARsLeft); 418 } 419 420 Address LoongArchABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, 421 QualType Ty) const { 422 CharUnits SlotSize = CharUnits::fromQuantity(GRLen / 8); 423 424 // Empty records are ignored for parameter passing purposes. 425 if (isEmptyRecord(getContext(), Ty, true)) 426 return Address(CGF.Builder.CreateLoad(VAListAddr), 427 CGF.ConvertTypeForMem(Ty), SlotSize); 428 429 auto TInfo = getContext().getTypeInfoInChars(Ty); 430 431 // Arguments bigger than 2*GRLen bytes are passed indirectly. 432 return emitVoidPtrVAArg(CGF, VAListAddr, Ty, 433 /*IsIndirect=*/TInfo.Width > 2 * SlotSize, TInfo, 434 SlotSize, 435 /*AllowHigherAlign=*/true); 436 } 437 438 ABIArgInfo LoongArchABIInfo::extendType(QualType Ty) const { 439 int TySize = getContext().getTypeSize(Ty); 440 // LA64 ABI requires unsigned 32 bit integers to be sign extended. 441 if (GRLen == 64 && Ty->isUnsignedIntegerOrEnumerationType() && TySize == 32) 442 return ABIArgInfo::getSignExtend(Ty); 443 return ABIArgInfo::getExtend(Ty); 444 } 445 446 namespace { 447 class LoongArchTargetCodeGenInfo : public TargetCodeGenInfo { 448 public: 449 LoongArchTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, unsigned GRLen, 450 unsigned FRLen) 451 : TargetCodeGenInfo( 452 std::make_unique<LoongArchABIInfo>(CGT, GRLen, FRLen)) {} 453 }; 454 } // namespace 455 456 std::unique_ptr<TargetCodeGenInfo> 457 CodeGen::createLoongArchTargetCodeGenInfo(CodeGenModule &CGM, unsigned GRLen, 458 unsigned FLen) { 459 return std::make_unique<LoongArchTargetCodeGenInfo>(CGM.getTypes(), GRLen, 460 FLen); 461 } 462