1209139Srpaulo//===- Mips.cpp -----------------------------------------------------------===// 2209139Srpaulo// 3209139Srpaulo// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4209139Srpaulo// See https://llvm.org/LICENSE.txt for license information. 5252726Srpaulo// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6252726Srpaulo// 7209139Srpaulo//===----------------------------------------------------------------------===// 8209139Srpaulo 9209139Srpaulo#include "ABIInfoImpl.h" 10209139Srpaulo#include "TargetInfo.h" 11209139Srpaulo 12209139Srpaulousing namespace clang; 13209139Srpaulousing namespace clang::CodeGen; 14209139Srpaulo 15209139Srpaulo//===----------------------------------------------------------------------===// 16209139Srpaulo// MIPS ABI Implementation. This works for both little-endian and 17209139Srpaulo// big-endian variants. 18209139Srpaulo//===----------------------------------------------------------------------===// 19209139Srpaulo 20209139Srpaulonamespace { 21209139Srpauloclass MipsABIInfo : public ABIInfo { 22209139Srpaulo bool IsO32; 23209139Srpaulo const unsigned MinABIStackAlignInBytes, StackAlignInBytes; 24209139Srpaulo void CoerceToIntArgs(uint64_t TySize, 25209139Srpaulo SmallVectorImpl<llvm::Type *> &ArgList) const; 26209139Srpaulo llvm::Type* HandleAggregates(QualType Ty, uint64_t TySize) const; 27209139Srpaulo llvm::Type* returnAggregateInRegs(QualType RetTy, uint64_t Size) const; 28209139Srpaulo llvm::Type* getPaddingType(uint64_t Align, uint64_t Offset) const; 29209139Srpaulopublic: 30209139Srpaulo MipsABIInfo(CodeGenTypes &CGT, bool _IsO32) : 31209139Srpaulo ABIInfo(CGT), IsO32(_IsO32), MinABIStackAlignInBytes(IsO32 ? 4 : 8), 32209139Srpaulo StackAlignInBytes(IsO32 ? 8 : 16) {} 33209139Srpaulo 34209139Srpaulo ABIArgInfo classifyReturnType(QualType RetTy) const; 35252726Srpaulo ABIArgInfo classifyArgumentType(QualType RetTy, uint64_t &Offset) const; 36252726Srpaulo void computeInfo(CGFunctionInfo &FI) const override; 37252726Srpaulo Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, 38252726Srpaulo QualType Ty) const override; 39209139Srpaulo ABIArgInfo extendType(QualType Ty) const; 40252726Srpaulo}; 41209139Srpaulo 42209139Srpauloclass MIPSTargetCodeGenInfo : public TargetCodeGenInfo { 43209139Srpaulo unsigned SizeOfUnwindException; 44209139Srpaulopublic: 45209139Srpaulo MIPSTargetCodeGenInfo(CodeGenTypes &CGT, bool IsO32) 46209139Srpaulo : TargetCodeGenInfo(std::make_unique<MipsABIInfo>(CGT, IsO32)), 47209139Srpaulo SizeOfUnwindException(IsO32 ? 24 : 32) {} 48209139Srpaulo 49209139Srpaulo int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override { 50209139Srpaulo return 29; 51209139Srpaulo } 52209139Srpaulo 53209139Srpaulo void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, 54209139Srpaulo CodeGen::CodeGenModule &CGM) const override { 55209139Srpaulo const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D); 56209139Srpaulo if (!FD) return; 57209139Srpaulo llvm::Function *Fn = cast<llvm::Function>(GV); 58209139Srpaulo 59209139Srpaulo if (FD->hasAttr<MipsLongCallAttr>()) 60209139Srpaulo Fn->addFnAttr("long-call"); 61209139Srpaulo else if (FD->hasAttr<MipsShortCallAttr>()) 62209139Srpaulo Fn->addFnAttr("short-call"); 63209139Srpaulo 64209139Srpaulo // Other attributes do not have a meaning for declarations. 65209139Srpaulo if (GV->isDeclaration()) 66209139Srpaulo return; 67209139Srpaulo 68209139Srpaulo if (FD->hasAttr<Mips16Attr>()) { 69209139Srpaulo Fn->addFnAttr("mips16"); 70209139Srpaulo } 71209139Srpaulo else if (FD->hasAttr<NoMips16Attr>()) { 72209139Srpaulo Fn->addFnAttr("nomips16"); 73209139Srpaulo } 74209139Srpaulo 75209139Srpaulo if (FD->hasAttr<MicroMipsAttr>()) 76209139Srpaulo Fn->addFnAttr("micromips"); 77209139Srpaulo else if (FD->hasAttr<NoMicroMipsAttr>()) 78209139Srpaulo Fn->addFnAttr("nomicromips"); 79209139Srpaulo 80209139Srpaulo const MipsInterruptAttr *Attr = FD->getAttr<MipsInterruptAttr>(); 81209139Srpaulo if (!Attr) 82209139Srpaulo return; 83209139Srpaulo 84209139Srpaulo const char *Kind; 85209139Srpaulo switch (Attr->getInterrupt()) { 86209139Srpaulo case MipsInterruptAttr::eic: Kind = "eic"; break; 87209139Srpaulo case MipsInterruptAttr::sw0: Kind = "sw0"; break; 88209139Srpaulo case MipsInterruptAttr::sw1: Kind = "sw1"; break; 89209139Srpaulo case MipsInterruptAttr::hw0: Kind = "hw0"; break; 90209139Srpaulo case MipsInterruptAttr::hw1: Kind = "hw1"; break; 91209139Srpaulo case MipsInterruptAttr::hw2: Kind = "hw2"; break; 92209139Srpaulo case MipsInterruptAttr::hw3: Kind = "hw3"; break; 93209139Srpaulo case MipsInterruptAttr::hw4: Kind = "hw4"; break; 94209139Srpaulo case MipsInterruptAttr::hw5: Kind = "hw5"; break; 95209139Srpaulo } 96209139Srpaulo 97209139Srpaulo Fn->addFnAttr("interrupt", Kind); 98209139Srpaulo 99209139Srpaulo } 100209139Srpaulo 101209139Srpaulo bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 102209139Srpaulo llvm::Value *Address) const override; 103209139Srpaulo 104209139Srpaulo unsigned getSizeOfUnwindException() const override { 105209139Srpaulo return SizeOfUnwindException; 106209139Srpaulo } 107209139Srpaulo}; 108209139Srpaulo} 109209139Srpaulo 110209139Srpaulovoid MipsABIInfo::CoerceToIntArgs( 111209139Srpaulo uint64_t TySize, SmallVectorImpl<llvm::Type *> &ArgList) const { 112209139Srpaulo llvm::IntegerType *IntTy = 113209139Srpaulo llvm::IntegerType::get(getVMContext(), MinABIStackAlignInBytes * 8); 114209139Srpaulo 115209139Srpaulo // Add (TySize / MinABIStackAlignInBytes) args of IntTy. 116209139Srpaulo for (unsigned N = TySize / (MinABIStackAlignInBytes * 8); N; --N) 117209139Srpaulo ArgList.push_back(IntTy); 118209139Srpaulo 119209139Srpaulo // If necessary, add one more integer type to ArgList. 120209139Srpaulo unsigned R = TySize % (MinABIStackAlignInBytes * 8); 121209139Srpaulo 122209139Srpaulo if (R) 123209139Srpaulo ArgList.push_back(llvm::IntegerType::get(getVMContext(), R)); 124209139Srpaulo} 125209139Srpaulo 126209139Srpaulo// In N32/64, an aligned double precision floating point field is passed in 127209139Srpaulo// a register. 128209139Srpaulollvm::Type* MipsABIInfo::HandleAggregates(QualType Ty, uint64_t TySize) const { 129209139Srpaulo SmallVector<llvm::Type*, 8> ArgList, IntArgList; 130209139Srpaulo 131209139Srpaulo if (IsO32) { 132209139Srpaulo CoerceToIntArgs(TySize, ArgList); 133209139Srpaulo return llvm::StructType::get(getVMContext(), ArgList); 134209139Srpaulo } 135209139Srpaulo 136209139Srpaulo if (Ty->isComplexType()) 137209139Srpaulo return CGT.ConvertType(Ty); 138209139Srpaulo 139209139Srpaulo const RecordType *RT = Ty->getAs<RecordType>(); 140209139Srpaulo 141209139Srpaulo // Unions/vectors are passed in integer registers. 142209139Srpaulo if (!RT || !RT->isStructureOrClassType()) { 143209139Srpaulo CoerceToIntArgs(TySize, ArgList); 144209139Srpaulo return llvm::StructType::get(getVMContext(), ArgList); 145209139Srpaulo } 146209139Srpaulo 147209139Srpaulo const RecordDecl *RD = RT->getDecl(); 148209139Srpaulo const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 149209139Srpaulo assert(!(TySize % 8) && "Size of structure must be multiple of 8."); 150209139Srpaulo 151209139Srpaulo uint64_t LastOffset = 0; 152209139Srpaulo unsigned idx = 0; 153209139Srpaulo llvm::IntegerType *I64 = llvm::IntegerType::get(getVMContext(), 64); 154209139Srpaulo 155209139Srpaulo // Iterate over fields in the struct/class and check if there are any aligned 156209139Srpaulo // double fields. 157209139Srpaulo for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); 158209139Srpaulo i != e; ++i, ++idx) { 159209139Srpaulo const QualType Ty = i->getType(); 160209139Srpaulo const BuiltinType *BT = Ty->getAs<BuiltinType>(); 161209139Srpaulo 162209139Srpaulo if (!BT || BT->getKind() != BuiltinType::Double) 163209139Srpaulo continue; 164209139Srpaulo 165209139Srpaulo uint64_t Offset = Layout.getFieldOffset(idx); 166209139Srpaulo if (Offset % 64) // Ignore doubles that are not aligned. 167209139Srpaulo continue; 168209139Srpaulo 169209139Srpaulo // Add ((Offset - LastOffset) / 64) args of type i64. 170209139Srpaulo for (unsigned j = (Offset - LastOffset) / 64; j > 0; --j) 171209139Srpaulo ArgList.push_back(I64); 172209139Srpaulo 173209139Srpaulo // Add double type. 174209139Srpaulo ArgList.push_back(llvm::Type::getDoubleTy(getVMContext())); 175209139Srpaulo LastOffset = Offset + 64; 176209139Srpaulo } 177209139Srpaulo 178209139Srpaulo CoerceToIntArgs(TySize - LastOffset, IntArgList); 179209139Srpaulo ArgList.append(IntArgList.begin(), IntArgList.end()); 180209139Srpaulo 181209139Srpaulo return llvm::StructType::get(getVMContext(), ArgList); 182209139Srpaulo} 183209139Srpaulo 184209139Srpaulollvm::Type *MipsABIInfo::getPaddingType(uint64_t OrigOffset, 185209139Srpaulo uint64_t Offset) const { 186209139Srpaulo if (OrigOffset + MinABIStackAlignInBytes > Offset) 187209139Srpaulo return nullptr; 188209139Srpaulo 189209139Srpaulo return llvm::IntegerType::get(getVMContext(), (Offset - OrigOffset) * 8); 190209139Srpaulo} 191209139Srpaulo 192209139SrpauloABIArgInfo 193209139SrpauloMipsABIInfo::classifyArgumentType(QualType Ty, uint64_t &Offset) const { 194209139Srpaulo Ty = useFirstFieldIfTransparentUnion(Ty); 195209139Srpaulo 196209139Srpaulo uint64_t OrigOffset = Offset; 197209139Srpaulo uint64_t TySize = getContext().getTypeSize(Ty); 198209139Srpaulo uint64_t Align = getContext().getTypeAlign(Ty) / 8; 199209139Srpaulo 200209139Srpaulo Align = std::clamp(Align, (uint64_t)MinABIStackAlignInBytes, 201209139Srpaulo (uint64_t)StackAlignInBytes); 202209139Srpaulo unsigned CurrOffset = llvm::alignTo(Offset, Align); 203209139Srpaulo Offset = CurrOffset + llvm::alignTo(TySize, Align * 8) / 8; 204209139Srpaulo 205209139Srpaulo if (isAggregateTypeForABI(Ty) || Ty->isVectorType()) { 206209139Srpaulo // Ignore empty aggregates. 207209139Srpaulo if (TySize == 0) 208209139Srpaulo return ABIArgInfo::getIgnore(); 209209139Srpaulo 210209139Srpaulo if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) { 211209139Srpaulo Offset = OrigOffset + MinABIStackAlignInBytes; 212209139Srpaulo return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory); 213209139Srpaulo } 214209139Srpaulo 215209139Srpaulo // If we have reached here, aggregates are passed directly by coercing to 216209139Srpaulo // another structure type. Padding is inserted if the offset of the 217209139Srpaulo // aggregate is unaligned. 218209139Srpaulo ABIArgInfo ArgInfo = 219209139Srpaulo ABIArgInfo::getDirect(HandleAggregates(Ty, TySize), 0, 220209139Srpaulo getPaddingType(OrigOffset, CurrOffset)); 221209139Srpaulo ArgInfo.setInReg(true); 222209139Srpaulo return ArgInfo; 223209139Srpaulo } 224209139Srpaulo 225209139Srpaulo // Treat an enum type as its underlying type. 226 if (const EnumType *EnumTy = Ty->getAs<EnumType>()) 227 Ty = EnumTy->getDecl()->getIntegerType(); 228 229 // Make sure we pass indirectly things that are too large. 230 if (const auto *EIT = Ty->getAs<BitIntType>()) 231 if (EIT->getNumBits() > 128 || 232 (EIT->getNumBits() > 64 && 233 !getContext().getTargetInfo().hasInt128Type())) 234 return getNaturalAlignIndirect(Ty); 235 236 // All integral types are promoted to the GPR width. 237 if (Ty->isIntegralOrEnumerationType()) 238 return extendType(Ty); 239 240 return ABIArgInfo::getDirect( 241 nullptr, 0, IsO32 ? nullptr : getPaddingType(OrigOffset, CurrOffset)); 242} 243 244llvm::Type* 245MipsABIInfo::returnAggregateInRegs(QualType RetTy, uint64_t Size) const { 246 const RecordType *RT = RetTy->getAs<RecordType>(); 247 SmallVector<llvm::Type*, 8> RTList; 248 249 if (RT && RT->isStructureOrClassType()) { 250 const RecordDecl *RD = RT->getDecl(); 251 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 252 unsigned FieldCnt = Layout.getFieldCount(); 253 254 // N32/64 returns struct/classes in floating point registers if the 255 // following conditions are met: 256 // 1. The size of the struct/class is no larger than 128-bit. 257 // 2. The struct/class has one or two fields all of which are floating 258 // point types. 259 // 3. The offset of the first field is zero (this follows what gcc does). 260 // 261 // Any other composite results are returned in integer registers. 262 // 263 if (FieldCnt && (FieldCnt <= 2) && !Layout.getFieldOffset(0)) { 264 RecordDecl::field_iterator b = RD->field_begin(), e = RD->field_end(); 265 for (; b != e; ++b) { 266 const BuiltinType *BT = b->getType()->getAs<BuiltinType>(); 267 268 if (!BT || !BT->isFloatingPoint()) 269 break; 270 271 RTList.push_back(CGT.ConvertType(b->getType())); 272 } 273 274 if (b == e) 275 return llvm::StructType::get(getVMContext(), RTList, 276 RD->hasAttr<PackedAttr>()); 277 278 RTList.clear(); 279 } 280 } 281 282 CoerceToIntArgs(Size, RTList); 283 return llvm::StructType::get(getVMContext(), RTList); 284} 285 286ABIArgInfo MipsABIInfo::classifyReturnType(QualType RetTy) const { 287 uint64_t Size = getContext().getTypeSize(RetTy); 288 289 if (RetTy->isVoidType()) 290 return ABIArgInfo::getIgnore(); 291 292 // O32 doesn't treat zero-sized structs differently from other structs. 293 // However, N32/N64 ignores zero sized return values. 294 if (!IsO32 && Size == 0) 295 return ABIArgInfo::getIgnore(); 296 297 if (isAggregateTypeForABI(RetTy) || RetTy->isVectorType()) { 298 if (Size <= 128) { 299 if (RetTy->isAnyComplexType()) 300 return ABIArgInfo::getDirect(); 301 302 // O32 returns integer vectors in registers and N32/N64 returns all small 303 // aggregates in registers. 304 if (!IsO32 || 305 (RetTy->isVectorType() && !RetTy->hasFloatingRepresentation())) { 306 ABIArgInfo ArgInfo = 307 ABIArgInfo::getDirect(returnAggregateInRegs(RetTy, Size)); 308 ArgInfo.setInReg(true); 309 return ArgInfo; 310 } 311 } 312 313 return getNaturalAlignIndirect(RetTy); 314 } 315 316 // Treat an enum type as its underlying type. 317 if (const EnumType *EnumTy = RetTy->getAs<EnumType>()) 318 RetTy = EnumTy->getDecl()->getIntegerType(); 319 320 // Make sure we pass indirectly things that are too large. 321 if (const auto *EIT = RetTy->getAs<BitIntType>()) 322 if (EIT->getNumBits() > 128 || 323 (EIT->getNumBits() > 64 && 324 !getContext().getTargetInfo().hasInt128Type())) 325 return getNaturalAlignIndirect(RetTy); 326 327 if (isPromotableIntegerTypeForABI(RetTy)) 328 return ABIArgInfo::getExtend(RetTy); 329 330 if ((RetTy->isUnsignedIntegerOrEnumerationType() || 331 RetTy->isSignedIntegerOrEnumerationType()) && Size == 32 && !IsO32) 332 return ABIArgInfo::getSignExtend(RetTy); 333 334 return ABIArgInfo::getDirect(); 335} 336 337void MipsABIInfo::computeInfo(CGFunctionInfo &FI) const { 338 ABIArgInfo &RetInfo = FI.getReturnInfo(); 339 if (!getCXXABI().classifyReturnType(FI)) 340 RetInfo = classifyReturnType(FI.getReturnType()); 341 342 // Check if a pointer to an aggregate is passed as a hidden argument. 343 uint64_t Offset = RetInfo.isIndirect() ? MinABIStackAlignInBytes : 0; 344 345 for (auto &I : FI.arguments()) 346 I.info = classifyArgumentType(I.type, Offset); 347} 348 349Address MipsABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, 350 QualType OrigTy) const { 351 QualType Ty = OrigTy; 352 353 // Integer arguments are promoted to 32-bit on O32 and 64-bit on N32/N64. 354 // Pointers are also promoted in the same way but this only matters for N32. 355 unsigned SlotSizeInBits = IsO32 ? 32 : 64; 356 unsigned PtrWidth = getTarget().getPointerWidth(LangAS::Default); 357 bool DidPromote = false; 358 if ((Ty->isIntegerType() && 359 getContext().getIntWidth(Ty) < SlotSizeInBits) || 360 (Ty->isPointerType() && PtrWidth < SlotSizeInBits)) { 361 DidPromote = true; 362 Ty = getContext().getIntTypeForBitwidth(SlotSizeInBits, 363 Ty->isSignedIntegerType()); 364 } 365 366 auto TyInfo = getContext().getTypeInfoInChars(Ty); 367 368 // The alignment of things in the argument area is never larger than 369 // StackAlignInBytes. 370 TyInfo.Align = 371 std::min(TyInfo.Align, CharUnits::fromQuantity(StackAlignInBytes)); 372 373 // MinABIStackAlignInBytes is the size of argument slots on the stack. 374 CharUnits ArgSlotSize = CharUnits::fromQuantity(MinABIStackAlignInBytes); 375 376 Address Addr = emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*indirect*/ false, 377 TyInfo, ArgSlotSize, /*AllowHigherAlign*/ true); 378 379 380 // If there was a promotion, "unpromote" into a temporary. 381 // TODO: can we just use a pointer into a subset of the original slot? 382 if (DidPromote) { 383 Address Temp = CGF.CreateMemTemp(OrigTy, "vaarg.promotion-temp"); 384 llvm::Value *Promoted = CGF.Builder.CreateLoad(Addr); 385 386 // Truncate down to the right width. 387 llvm::Type *IntTy = (OrigTy->isIntegerType() ? Temp.getElementType() 388 : CGF.IntPtrTy); 389 llvm::Value *V = CGF.Builder.CreateTrunc(Promoted, IntTy); 390 if (OrigTy->isPointerType()) 391 V = CGF.Builder.CreateIntToPtr(V, Temp.getElementType()); 392 393 CGF.Builder.CreateStore(V, Temp); 394 Addr = Temp; 395 } 396 397 return Addr; 398} 399 400ABIArgInfo MipsABIInfo::extendType(QualType Ty) const { 401 int TySize = getContext().getTypeSize(Ty); 402 403 // MIPS64 ABI requires unsigned 32 bit integers to be sign extended. 404 if (Ty->isUnsignedIntegerOrEnumerationType() && TySize == 32) 405 return ABIArgInfo::getSignExtend(Ty); 406 407 return ABIArgInfo::getExtend(Ty); 408} 409 410bool 411MIPSTargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 412 llvm::Value *Address) const { 413 // This information comes from gcc's implementation, which seems to 414 // as canonical as it gets. 415 416 // Everything on MIPS is 4 bytes. Double-precision FP registers 417 // are aliased to pairs of single-precision FP registers. 418 llvm::Value *Four8 = llvm::ConstantInt::get(CGF.Int8Ty, 4); 419 420 // 0-31 are the general purpose registers, $0 - $31. 421 // 32-63 are the floating-point registers, $f0 - $f31. 422 // 64 and 65 are the multiply/divide registers, $hi and $lo. 423 // 66 is the (notional, I think) register for signal-handler return. 424 AssignToArrayRange(CGF.Builder, Address, Four8, 0, 65); 425 426 // 67-74 are the floating-point status registers, $fcc0 - $fcc7. 427 // They are one bit wide and ignored here. 428 429 // 80-111 are the coprocessor 0 registers, $c0r0 - $c0r31. 430 // (coprocessor 1 is the FP unit) 431 // 112-143 are the coprocessor 2 registers, $c2r0 - $c2r31. 432 // 144-175 are the coprocessor 3 registers, $c3r0 - $c3r31. 433 // 176-181 are the DSP accumulator registers. 434 AssignToArrayRange(CGF.Builder, Address, Four8, 80, 181); 435 return false; 436} 437 438std::unique_ptr<TargetCodeGenInfo> 439CodeGen::createMIPSTargetCodeGenInfo(CodeGenModule &CGM, bool IsOS32) { 440 return std::make_unique<MIPSTargetCodeGenInfo>(CGM.getTypes(), IsOS32); 441} 442