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 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, 38 AggValueSlot Slot) 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 class WindowsMIPSTargetCodeGenInfo : public MIPSTargetCodeGenInfo { 110 public: 111 WindowsMIPSTargetCodeGenInfo(CodeGenTypes &CGT, bool IsO32) 112 : MIPSTargetCodeGenInfo(CGT, IsO32) {} 113 114 void getDependentLibraryOption(llvm::StringRef Lib, 115 llvm::SmallString<24> &Opt) const override { 116 Opt = "/DEFAULTLIB:"; 117 Opt += qualifyWindowsLibrary(Lib); 118 } 119 120 void getDetectMismatchOption(llvm::StringRef Name, llvm::StringRef Value, 121 llvm::SmallString<32> &Opt) const override { 122 Opt = "/FAILIFMISMATCH:\"" + Name.str() + "=" + Value.str() + "\""; 123 } 124 }; 125 } 126 127 void MipsABIInfo::CoerceToIntArgs( 128 uint64_t TySize, SmallVectorImpl<llvm::Type *> &ArgList) const { 129 llvm::IntegerType *IntTy = 130 llvm::IntegerType::get(getVMContext(), MinABIStackAlignInBytes * 8); 131 132 // Add (TySize / MinABIStackAlignInBytes) args of IntTy. 133 for (unsigned N = TySize / (MinABIStackAlignInBytes * 8); N; --N) 134 ArgList.push_back(IntTy); 135 136 // If necessary, add one more integer type to ArgList. 137 unsigned R = TySize % (MinABIStackAlignInBytes * 8); 138 139 if (R) 140 ArgList.push_back(llvm::IntegerType::get(getVMContext(), R)); 141 } 142 143 // In N32/64, an aligned double precision floating point field is passed in 144 // a register. 145 llvm::Type* MipsABIInfo::HandleAggregates(QualType Ty, uint64_t TySize) const { 146 SmallVector<llvm::Type*, 8> ArgList, IntArgList; 147 148 if (IsO32) { 149 CoerceToIntArgs(TySize, ArgList); 150 return llvm::StructType::get(getVMContext(), ArgList); 151 } 152 153 if (Ty->isComplexType()) 154 return CGT.ConvertType(Ty); 155 156 const RecordType *RT = Ty->getAs<RecordType>(); 157 158 // Unions/vectors are passed in integer registers. 159 if (!RT || !RT->isStructureOrClassType()) { 160 CoerceToIntArgs(TySize, ArgList); 161 return llvm::StructType::get(getVMContext(), ArgList); 162 } 163 164 const RecordDecl *RD = RT->getDecl(); 165 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 166 assert(!(TySize % 8) && "Size of structure must be multiple of 8."); 167 168 uint64_t LastOffset = 0; 169 unsigned idx = 0; 170 llvm::IntegerType *I64 = llvm::IntegerType::get(getVMContext(), 64); 171 172 // Iterate over fields in the struct/class and check if there are any aligned 173 // double fields. 174 for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); 175 i != e; ++i, ++idx) { 176 const QualType Ty = i->getType(); 177 const BuiltinType *BT = Ty->getAs<BuiltinType>(); 178 179 if (!BT || BT->getKind() != BuiltinType::Double) 180 continue; 181 182 uint64_t Offset = Layout.getFieldOffset(idx); 183 if (Offset % 64) // Ignore doubles that are not aligned. 184 continue; 185 186 // Add ((Offset - LastOffset) / 64) args of type i64. 187 for (unsigned j = (Offset - LastOffset) / 64; j > 0; --j) 188 ArgList.push_back(I64); 189 190 // Add double type. 191 ArgList.push_back(llvm::Type::getDoubleTy(getVMContext())); 192 LastOffset = Offset + 64; 193 } 194 195 CoerceToIntArgs(TySize - LastOffset, IntArgList); 196 ArgList.append(IntArgList.begin(), IntArgList.end()); 197 198 return llvm::StructType::get(getVMContext(), ArgList); 199 } 200 201 llvm::Type *MipsABIInfo::getPaddingType(uint64_t OrigOffset, 202 uint64_t Offset) const { 203 if (OrigOffset + MinABIStackAlignInBytes > Offset) 204 return nullptr; 205 206 return llvm::IntegerType::get(getVMContext(), (Offset - OrigOffset) * 8); 207 } 208 209 ABIArgInfo 210 MipsABIInfo::classifyArgumentType(QualType Ty, uint64_t &Offset) const { 211 Ty = useFirstFieldIfTransparentUnion(Ty); 212 213 uint64_t OrigOffset = Offset; 214 uint64_t TySize = getContext().getTypeSize(Ty); 215 uint64_t Align = getContext().getTypeAlign(Ty) / 8; 216 217 Align = std::clamp(Align, (uint64_t)MinABIStackAlignInBytes, 218 (uint64_t)StackAlignInBytes); 219 unsigned CurrOffset = llvm::alignTo(Offset, Align); 220 Offset = CurrOffset + llvm::alignTo(TySize, Align * 8) / 8; 221 222 if (isAggregateTypeForABI(Ty) || Ty->isVectorType()) { 223 // Ignore empty aggregates. 224 if (TySize == 0) 225 return ABIArgInfo::getIgnore(); 226 227 if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) { 228 Offset = OrigOffset + MinABIStackAlignInBytes; 229 return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory); 230 } 231 232 // If we have reached here, aggregates are passed directly by coercing to 233 // another structure type. Padding is inserted if the offset of the 234 // aggregate is unaligned. 235 ABIArgInfo ArgInfo = 236 ABIArgInfo::getDirect(HandleAggregates(Ty, TySize), 0, 237 getPaddingType(OrigOffset, CurrOffset)); 238 ArgInfo.setInReg(true); 239 return ArgInfo; 240 } 241 242 // Treat an enum type as its underlying type. 243 if (const EnumType *EnumTy = Ty->getAs<EnumType>()) 244 Ty = EnumTy->getDecl()->getIntegerType(); 245 246 // Make sure we pass indirectly things that are too large. 247 if (const auto *EIT = Ty->getAs<BitIntType>()) 248 if (EIT->getNumBits() > 128 || 249 (EIT->getNumBits() > 64 && 250 !getContext().getTargetInfo().hasInt128Type())) 251 return getNaturalAlignIndirect(Ty); 252 253 // All integral types are promoted to the GPR width. 254 if (Ty->isIntegralOrEnumerationType()) 255 return extendType(Ty); 256 257 return ABIArgInfo::getDirect( 258 nullptr, 0, IsO32 ? nullptr : getPaddingType(OrigOffset, CurrOffset)); 259 } 260 261 llvm::Type* 262 MipsABIInfo::returnAggregateInRegs(QualType RetTy, uint64_t Size) const { 263 const RecordType *RT = RetTy->getAs<RecordType>(); 264 SmallVector<llvm::Type*, 8> RTList; 265 266 if (RT && RT->isStructureOrClassType()) { 267 const RecordDecl *RD = RT->getDecl(); 268 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 269 unsigned FieldCnt = Layout.getFieldCount(); 270 271 // N32/64 returns struct/classes in floating point registers if the 272 // following conditions are met: 273 // 1. The size of the struct/class is no larger than 128-bit. 274 // 2. The struct/class has one or two fields all of which are floating 275 // point types. 276 // 3. The offset of the first field is zero (this follows what gcc does). 277 // 278 // Any other composite results are returned in integer registers. 279 // 280 if (FieldCnt && (FieldCnt <= 2) && !Layout.getFieldOffset(0)) { 281 RecordDecl::field_iterator b = RD->field_begin(), e = RD->field_end(); 282 for (; b != e; ++b) { 283 const BuiltinType *BT = b->getType()->getAs<BuiltinType>(); 284 285 if (!BT || !BT->isFloatingPoint()) 286 break; 287 288 RTList.push_back(CGT.ConvertType(b->getType())); 289 } 290 291 if (b == e) 292 return llvm::StructType::get(getVMContext(), RTList, 293 RD->hasAttr<PackedAttr>()); 294 295 RTList.clear(); 296 } 297 } 298 299 CoerceToIntArgs(Size, RTList); 300 return llvm::StructType::get(getVMContext(), RTList); 301 } 302 303 ABIArgInfo MipsABIInfo::classifyReturnType(QualType RetTy) const { 304 uint64_t Size = getContext().getTypeSize(RetTy); 305 306 if (RetTy->isVoidType()) 307 return ABIArgInfo::getIgnore(); 308 309 // O32 doesn't treat zero-sized structs differently from other structs. 310 // However, N32/N64 ignores zero sized return values. 311 if (!IsO32 && Size == 0) 312 return ABIArgInfo::getIgnore(); 313 314 if (isAggregateTypeForABI(RetTy) || RetTy->isVectorType()) { 315 if (Size <= 128) { 316 if (RetTy->isAnyComplexType()) 317 return ABIArgInfo::getDirect(); 318 319 // O32 returns integer vectors in registers and N32/N64 returns all small 320 // aggregates in registers. 321 if (!IsO32 || 322 (RetTy->isVectorType() && !RetTy->hasFloatingRepresentation())) { 323 ABIArgInfo ArgInfo = 324 ABIArgInfo::getDirect(returnAggregateInRegs(RetTy, Size)); 325 ArgInfo.setInReg(true); 326 return ArgInfo; 327 } 328 } 329 330 return getNaturalAlignIndirect(RetTy); 331 } 332 333 // Treat an enum type as its underlying type. 334 if (const EnumType *EnumTy = RetTy->getAs<EnumType>()) 335 RetTy = EnumTy->getDecl()->getIntegerType(); 336 337 // Make sure we pass indirectly things that are too large. 338 if (const auto *EIT = RetTy->getAs<BitIntType>()) 339 if (EIT->getNumBits() > 128 || 340 (EIT->getNumBits() > 64 && 341 !getContext().getTargetInfo().hasInt128Type())) 342 return getNaturalAlignIndirect(RetTy); 343 344 if (isPromotableIntegerTypeForABI(RetTy)) 345 return ABIArgInfo::getExtend(RetTy); 346 347 if ((RetTy->isUnsignedIntegerOrEnumerationType() || 348 RetTy->isSignedIntegerOrEnumerationType()) && Size == 32 && !IsO32) 349 return ABIArgInfo::getSignExtend(RetTy); 350 351 return ABIArgInfo::getDirect(); 352 } 353 354 void MipsABIInfo::computeInfo(CGFunctionInfo &FI) const { 355 ABIArgInfo &RetInfo = FI.getReturnInfo(); 356 if (!getCXXABI().classifyReturnType(FI)) 357 RetInfo = classifyReturnType(FI.getReturnType()); 358 359 // Check if a pointer to an aggregate is passed as a hidden argument. 360 uint64_t Offset = RetInfo.isIndirect() ? MinABIStackAlignInBytes : 0; 361 362 for (auto &I : FI.arguments()) 363 I.info = classifyArgumentType(I.type, Offset); 364 } 365 366 RValue MipsABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, 367 QualType OrigTy, AggValueSlot Slot) const { 368 QualType Ty = OrigTy; 369 370 // Integer arguments are promoted to 32-bit on O32 and 64-bit on N32/N64. 371 // Pointers are also promoted in the same way but this only matters for N32. 372 unsigned SlotSizeInBits = IsO32 ? 32 : 64; 373 unsigned PtrWidth = getTarget().getPointerWidth(LangAS::Default); 374 bool DidPromote = false; 375 if ((Ty->isIntegerType() && 376 getContext().getIntWidth(Ty) < SlotSizeInBits) || 377 (Ty->isPointerType() && PtrWidth < SlotSizeInBits)) { 378 DidPromote = true; 379 Ty = getContext().getIntTypeForBitwidth(SlotSizeInBits, 380 Ty->isSignedIntegerType()); 381 } 382 383 auto TyInfo = getContext().getTypeInfoInChars(Ty); 384 385 // The alignment of things in the argument area is never larger than 386 // StackAlignInBytes. 387 TyInfo.Align = 388 std::min(TyInfo.Align, CharUnits::fromQuantity(StackAlignInBytes)); 389 390 // MinABIStackAlignInBytes is the size of argument slots on the stack. 391 CharUnits ArgSlotSize = CharUnits::fromQuantity(MinABIStackAlignInBytes); 392 393 RValue Res = emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*indirect*/ false, TyInfo, 394 ArgSlotSize, /*AllowHigherAlign*/ true, Slot); 395 396 // If there was a promotion, "unpromote". 397 // TODO: can we just use a pointer into a subset of the original slot? 398 if (DidPromote) { 399 llvm::Type *ValTy = CGF.ConvertType(OrigTy); 400 llvm::Value *Promoted = Res.getScalarVal(); 401 402 // Truncate down to the right width. 403 llvm::Type *IntTy = (OrigTy->isIntegerType() ? ValTy : CGF.IntPtrTy); 404 llvm::Value *V = CGF.Builder.CreateTrunc(Promoted, IntTy); 405 if (OrigTy->isPointerType()) 406 V = CGF.Builder.CreateIntToPtr(V, ValTy); 407 408 return RValue::get(V); 409 } 410 411 return Res; 412 } 413 414 ABIArgInfo MipsABIInfo::extendType(QualType Ty) const { 415 int TySize = getContext().getTypeSize(Ty); 416 417 // MIPS64 ABI requires unsigned 32 bit integers to be sign extended. 418 if (Ty->isUnsignedIntegerOrEnumerationType() && TySize == 32) 419 return ABIArgInfo::getSignExtend(Ty); 420 421 return ABIArgInfo::getExtend(Ty); 422 } 423 424 bool 425 MIPSTargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 426 llvm::Value *Address) const { 427 // This information comes from gcc's implementation, which seems to 428 // as canonical as it gets. 429 430 // Everything on MIPS is 4 bytes. Double-precision FP registers 431 // are aliased to pairs of single-precision FP registers. 432 llvm::Value *Four8 = llvm::ConstantInt::get(CGF.Int8Ty, 4); 433 434 // 0-31 are the general purpose registers, $0 - $31. 435 // 32-63 are the floating-point registers, $f0 - $f31. 436 // 64 and 65 are the multiply/divide registers, $hi and $lo. 437 // 66 is the (notional, I think) register for signal-handler return. 438 AssignToArrayRange(CGF.Builder, Address, Four8, 0, 65); 439 440 // 67-74 are the floating-point status registers, $fcc0 - $fcc7. 441 // They are one bit wide and ignored here. 442 443 // 80-111 are the coprocessor 0 registers, $c0r0 - $c0r31. 444 // (coprocessor 1 is the FP unit) 445 // 112-143 are the coprocessor 2 registers, $c2r0 - $c2r31. 446 // 144-175 are the coprocessor 3 registers, $c3r0 - $c3r31. 447 // 176-181 are the DSP accumulator registers. 448 AssignToArrayRange(CGF.Builder, Address, Four8, 80, 181); 449 return false; 450 } 451 452 std::unique_ptr<TargetCodeGenInfo> 453 CodeGen::createMIPSTargetCodeGenInfo(CodeGenModule &CGM, bool IsOS32) { 454 return std::make_unique<MIPSTargetCodeGenInfo>(CGM.getTypes(), IsOS32); 455 } 456 457 std::unique_ptr<TargetCodeGenInfo> 458 CodeGen::createWindowsMIPSTargetCodeGenInfo(CodeGenModule &CGM, bool IsOS32) { 459 return std::make_unique<WindowsMIPSTargetCodeGenInfo>(CGM.getTypes(), IsOS32); 460 } 461