1 //===- Mips.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 //===----------------------------------------------------------------------===// 16 // MIPS ABI Implementation. This works for both little-endian and 17 // big-endian variants. 18 //===----------------------------------------------------------------------===// 19 20 namespace { 21 class MipsABIInfo : public ABIInfo { 22 bool IsO32; 23 const unsigned MinABIStackAlignInBytes, StackAlignInBytes; 24 void CoerceToIntArgs(uint64_t TySize, 25 SmallVectorImpl<llvm::Type *> &ArgList) const; 26 llvm::Type* HandleAggregates(QualType Ty, uint64_t TySize) const; 27 llvm::Type* returnAggregateInRegs(QualType RetTy, uint64_t Size) const; 28 llvm::Type* getPaddingType(uint64_t Align, uint64_t Offset) const; 29 public: 30 MipsABIInfo(CodeGenTypes &CGT, bool _IsO32) : 31 ABIInfo(CGT), IsO32(_IsO32), MinABIStackAlignInBytes(IsO32 ? 4 : 8), 32 StackAlignInBytes(IsO32 ? 8 : 16) {} 33 34 ABIArgInfo classifyReturnType(QualType RetTy) const; 35 ABIArgInfo classifyArgumentType(QualType RetTy, uint64_t &Offset) const; 36 void computeInfo(CGFunctionInfo &FI) const override; 37 Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, 38 QualType Ty) const override; 39 ABIArgInfo extendType(QualType Ty) const; 40 }; 41 42 class MIPSTargetCodeGenInfo : public TargetCodeGenInfo { 43 unsigned SizeOfUnwindException; 44 public: 45 MIPSTargetCodeGenInfo(CodeGenTypes &CGT, bool IsO32) 46 : TargetCodeGenInfo(std::make_unique<MipsABIInfo>(CGT, IsO32)), 47 SizeOfUnwindException(IsO32 ? 24 : 32) {} 48 49 int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override { 50 return 29; 51 } 52 53 void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, 54 CodeGen::CodeGenModule &CGM) const override { 55 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D); 56 if (!FD) return; 57 llvm::Function *Fn = cast<llvm::Function>(GV); 58 59 if (FD->hasAttr<MipsLongCallAttr>()) 60 Fn->addFnAttr("long-call"); 61 else if (FD->hasAttr<MipsShortCallAttr>()) 62 Fn->addFnAttr("short-call"); 63 64 // Other attributes do not have a meaning for declarations. 65 if (GV->isDeclaration()) 66 return; 67 68 if (FD->hasAttr<Mips16Attr>()) { 69 Fn->addFnAttr("mips16"); 70 } 71 else if (FD->hasAttr<NoMips16Attr>()) { 72 Fn->addFnAttr("nomips16"); 73 } 74 75 if (FD->hasAttr<MicroMipsAttr>()) 76 Fn->addFnAttr("micromips"); 77 else if (FD->hasAttr<NoMicroMipsAttr>()) 78 Fn->addFnAttr("nomicromips"); 79 80 const MipsInterruptAttr *Attr = FD->getAttr<MipsInterruptAttr>(); 81 if (!Attr) 82 return; 83 84 const char *Kind; 85 switch (Attr->getInterrupt()) { 86 case MipsInterruptAttr::eic: Kind = "eic"; break; 87 case MipsInterruptAttr::sw0: Kind = "sw0"; break; 88 case MipsInterruptAttr::sw1: Kind = "sw1"; break; 89 case MipsInterruptAttr::hw0: Kind = "hw0"; break; 90 case MipsInterruptAttr::hw1: Kind = "hw1"; break; 91 case MipsInterruptAttr::hw2: Kind = "hw2"; break; 92 case MipsInterruptAttr::hw3: Kind = "hw3"; break; 93 case MipsInterruptAttr::hw4: Kind = "hw4"; break; 94 case MipsInterruptAttr::hw5: Kind = "hw5"; break; 95 } 96 97 Fn->addFnAttr("interrupt", Kind); 98 99 } 100 101 bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 102 llvm::Value *Address) const override; 103 104 unsigned getSizeOfUnwindException() const override { 105 return SizeOfUnwindException; 106 } 107 }; 108 } 109 110 void MipsABIInfo::CoerceToIntArgs( 111 uint64_t TySize, SmallVectorImpl<llvm::Type *> &ArgList) const { 112 llvm::IntegerType *IntTy = 113 llvm::IntegerType::get(getVMContext(), MinABIStackAlignInBytes * 8); 114 115 // Add (TySize / MinABIStackAlignInBytes) args of IntTy. 116 for (unsigned N = TySize / (MinABIStackAlignInBytes * 8); N; --N) 117 ArgList.push_back(IntTy); 118 119 // If necessary, add one more integer type to ArgList. 120 unsigned R = TySize % (MinABIStackAlignInBytes * 8); 121 122 if (R) 123 ArgList.push_back(llvm::IntegerType::get(getVMContext(), R)); 124 } 125 126 // In N32/64, an aligned double precision floating point field is passed in 127 // a register. 128 llvm::Type* MipsABIInfo::HandleAggregates(QualType Ty, uint64_t TySize) const { 129 SmallVector<llvm::Type*, 8> ArgList, IntArgList; 130 131 if (IsO32) { 132 CoerceToIntArgs(TySize, ArgList); 133 return llvm::StructType::get(getVMContext(), ArgList); 134 } 135 136 if (Ty->isComplexType()) 137 return CGT.ConvertType(Ty); 138 139 const RecordType *RT = Ty->getAs<RecordType>(); 140 141 // Unions/vectors are passed in integer registers. 142 if (!RT || !RT->isStructureOrClassType()) { 143 CoerceToIntArgs(TySize, ArgList); 144 return llvm::StructType::get(getVMContext(), ArgList); 145 } 146 147 const RecordDecl *RD = RT->getDecl(); 148 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 149 assert(!(TySize % 8) && "Size of structure must be multiple of 8."); 150 151 uint64_t LastOffset = 0; 152 unsigned idx = 0; 153 llvm::IntegerType *I64 = llvm::IntegerType::get(getVMContext(), 64); 154 155 // Iterate over fields in the struct/class and check if there are any aligned 156 // double fields. 157 for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); 158 i != e; ++i, ++idx) { 159 const QualType Ty = i->getType(); 160 const BuiltinType *BT = Ty->getAs<BuiltinType>(); 161 162 if (!BT || BT->getKind() != BuiltinType::Double) 163 continue; 164 165 uint64_t Offset = Layout.getFieldOffset(idx); 166 if (Offset % 64) // Ignore doubles that are not aligned. 167 continue; 168 169 // Add ((Offset - LastOffset) / 64) args of type i64. 170 for (unsigned j = (Offset - LastOffset) / 64; j > 0; --j) 171 ArgList.push_back(I64); 172 173 // Add double type. 174 ArgList.push_back(llvm::Type::getDoubleTy(getVMContext())); 175 LastOffset = Offset + 64; 176 } 177 178 CoerceToIntArgs(TySize - LastOffset, IntArgList); 179 ArgList.append(IntArgList.begin(), IntArgList.end()); 180 181 return llvm::StructType::get(getVMContext(), ArgList); 182 } 183 184 llvm::Type *MipsABIInfo::getPaddingType(uint64_t OrigOffset, 185 uint64_t Offset) const { 186 if (OrigOffset + MinABIStackAlignInBytes > Offset) 187 return nullptr; 188 189 return llvm::IntegerType::get(getVMContext(), (Offset - OrigOffset) * 8); 190 } 191 192 ABIArgInfo 193 MipsABIInfo::classifyArgumentType(QualType Ty, uint64_t &Offset) const { 194 Ty = useFirstFieldIfTransparentUnion(Ty); 195 196 uint64_t OrigOffset = Offset; 197 uint64_t TySize = getContext().getTypeSize(Ty); 198 uint64_t Align = getContext().getTypeAlign(Ty) / 8; 199 200 Align = std::clamp(Align, (uint64_t)MinABIStackAlignInBytes, 201 (uint64_t)StackAlignInBytes); 202 unsigned CurrOffset = llvm::alignTo(Offset, Align); 203 Offset = CurrOffset + llvm::alignTo(TySize, Align * 8) / 8; 204 205 if (isAggregateTypeForABI(Ty) || Ty->isVectorType()) { 206 // Ignore empty aggregates. 207 if (TySize == 0) 208 return ABIArgInfo::getIgnore(); 209 210 if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) { 211 Offset = OrigOffset + MinABIStackAlignInBytes; 212 return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory); 213 } 214 215 // If we have reached here, aggregates are passed directly by coercing to 216 // another structure type. Padding is inserted if the offset of the 217 // aggregate is unaligned. 218 ABIArgInfo ArgInfo = 219 ABIArgInfo::getDirect(HandleAggregates(Ty, TySize), 0, 220 getPaddingType(OrigOffset, CurrOffset)); 221 ArgInfo.setInReg(true); 222 return ArgInfo; 223 } 224 225 // 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 244 llvm::Type* 245 MipsABIInfo::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 286 ABIArgInfo 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 337 void 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 349 Address 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 400 ABIArgInfo 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 410 bool 411 MIPSTargetCodeGenInfo::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 438 std::unique_ptr<TargetCodeGenInfo> 439 CodeGen::createMIPSTargetCodeGenInfo(CodeGenModule &CGM, bool IsOS32) { 440 return std::make_unique<MIPSTargetCodeGenInfo>(CGM.getTypes(), IsOS32); 441 } 442