1 //===- Sparc.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 #include <algorithm> 12 13 using namespace clang; 14 using namespace clang::CodeGen; 15 16 //===----------------------------------------------------------------------===// 17 // SPARC v8 ABI Implementation. 18 // Based on the SPARC Compliance Definition version 2.4.1. 19 // 20 // Ensures that complex values are passed in registers. 21 // 22 namespace { 23 class SparcV8ABIInfo : public DefaultABIInfo { 24 public: 25 SparcV8ABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} 26 27 private: 28 ABIArgInfo classifyReturnType(QualType RetTy) const; 29 void computeInfo(CGFunctionInfo &FI) const override; 30 }; 31 } // end anonymous namespace 32 33 34 ABIArgInfo 35 SparcV8ABIInfo::classifyReturnType(QualType Ty) const { 36 if (Ty->isAnyComplexType()) { 37 return ABIArgInfo::getDirect(); 38 } 39 else { 40 return DefaultABIInfo::classifyReturnType(Ty); 41 } 42 } 43 44 void SparcV8ABIInfo::computeInfo(CGFunctionInfo &FI) const { 45 46 FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); 47 for (auto &Arg : FI.arguments()) 48 Arg.info = classifyArgumentType(Arg.type); 49 } 50 51 namespace { 52 class SparcV8TargetCodeGenInfo : public TargetCodeGenInfo { 53 public: 54 SparcV8TargetCodeGenInfo(CodeGenTypes &CGT) 55 : TargetCodeGenInfo(std::make_unique<SparcV8ABIInfo>(CGT)) {} 56 57 llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF, 58 llvm::Value *Address) const override { 59 int Offset; 60 if (isAggregateTypeForABI(CGF.CurFnInfo->getReturnType())) 61 Offset = 12; 62 else 63 Offset = 8; 64 return CGF.Builder.CreateGEP(CGF.Int8Ty, Address, 65 llvm::ConstantInt::get(CGF.Int32Ty, Offset)); 66 } 67 68 llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF, 69 llvm::Value *Address) const override { 70 int Offset; 71 if (isAggregateTypeForABI(CGF.CurFnInfo->getReturnType())) 72 Offset = -12; 73 else 74 Offset = -8; 75 return CGF.Builder.CreateGEP(CGF.Int8Ty, Address, 76 llvm::ConstantInt::get(CGF.Int32Ty, Offset)); 77 } 78 }; 79 } // end anonymous namespace 80 81 //===----------------------------------------------------------------------===// 82 // SPARC v9 ABI Implementation. 83 // Based on the SPARC Compliance Definition version 2.4.1. 84 // 85 // Function arguments a mapped to a nominal "parameter array" and promoted to 86 // registers depending on their type. Each argument occupies 8 or 16 bytes in 87 // the array, structs larger than 16 bytes are passed indirectly. 88 // 89 // One case requires special care: 90 // 91 // struct mixed { 92 // int i; 93 // float f; 94 // }; 95 // 96 // When a struct mixed is passed by value, it only occupies 8 bytes in the 97 // parameter array, but the int is passed in an integer register, and the float 98 // is passed in a floating point register. This is represented as two arguments 99 // with the LLVM IR inreg attribute: 100 // 101 // declare void f(i32 inreg %i, float inreg %f) 102 // 103 // The code generator will only allocate 4 bytes from the parameter array for 104 // the inreg arguments. All other arguments are allocated a multiple of 8 105 // bytes. 106 // 107 namespace { 108 class SparcV9ABIInfo : public ABIInfo { 109 public: 110 SparcV9ABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {} 111 112 private: 113 ABIArgInfo classifyType(QualType RetTy, unsigned SizeLimit, 114 unsigned &RegOffset) const; 115 void computeInfo(CGFunctionInfo &FI) const override; 116 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, 117 AggValueSlot Slot) const override; 118 119 // Coercion type builder for structs passed in registers. The coercion type 120 // serves two purposes: 121 // 122 // 1. Pad structs to a multiple of 64 bits, so they are passed 'left-aligned' 123 // in registers. 124 // 2. Expose aligned floating point elements as first-level elements, so the 125 // code generator knows to pass them in floating point registers. 126 // 127 // We also compute the InReg flag which indicates that the struct contains 128 // aligned 32-bit floats. 129 // 130 struct CoerceBuilder { 131 llvm::LLVMContext &Context; 132 const llvm::DataLayout &DL; 133 SmallVector<llvm::Type*, 8> Elems; 134 uint64_t Size; 135 bool InReg; 136 137 CoerceBuilder(llvm::LLVMContext &c, const llvm::DataLayout &dl) 138 : Context(c), DL(dl), Size(0), InReg(false) {} 139 140 // Pad Elems with integers until Size is ToSize. 141 void pad(uint64_t ToSize) { 142 assert(ToSize >= Size && "Cannot remove elements"); 143 if (ToSize == Size) 144 return; 145 146 // Finish the current 64-bit word. 147 uint64_t Aligned = llvm::alignTo(Size, 64); 148 if (Aligned > Size && Aligned <= ToSize) { 149 Elems.push_back(llvm::IntegerType::get(Context, Aligned - Size)); 150 Size = Aligned; 151 } 152 153 // Add whole 64-bit words. 154 while (Size + 64 <= ToSize) { 155 Elems.push_back(llvm::Type::getInt64Ty(Context)); 156 Size += 64; 157 } 158 159 // Final in-word padding. 160 if (Size < ToSize) { 161 Elems.push_back(llvm::IntegerType::get(Context, ToSize - Size)); 162 Size = ToSize; 163 } 164 } 165 166 // Add a floating point element at Offset. 167 void addFloat(uint64_t Offset, llvm::Type *Ty, unsigned Bits) { 168 // Unaligned floats are treated as integers. 169 if (Offset % Bits) 170 return; 171 // The InReg flag is only required if there are any floats < 64 bits. 172 if (Bits < 64) 173 InReg = true; 174 pad(Offset); 175 Elems.push_back(Ty); 176 Size = Offset + Bits; 177 } 178 179 // Add a struct type to the coercion type, starting at Offset (in bits). 180 void addStruct(uint64_t Offset, llvm::StructType *StrTy) { 181 const llvm::StructLayout *Layout = DL.getStructLayout(StrTy); 182 for (unsigned i = 0, e = StrTy->getNumElements(); i != e; ++i) { 183 llvm::Type *ElemTy = StrTy->getElementType(i); 184 uint64_t ElemOffset = Offset + Layout->getElementOffsetInBits(i); 185 switch (ElemTy->getTypeID()) { 186 case llvm::Type::StructTyID: 187 addStruct(ElemOffset, cast<llvm::StructType>(ElemTy)); 188 break; 189 case llvm::Type::FloatTyID: 190 addFloat(ElemOffset, ElemTy, 32); 191 break; 192 case llvm::Type::DoubleTyID: 193 addFloat(ElemOffset, ElemTy, 64); 194 break; 195 case llvm::Type::FP128TyID: 196 addFloat(ElemOffset, ElemTy, 128); 197 break; 198 case llvm::Type::PointerTyID: 199 if (ElemOffset % 64 == 0) { 200 pad(ElemOffset); 201 Elems.push_back(ElemTy); 202 Size += 64; 203 } 204 break; 205 default: 206 break; 207 } 208 } 209 } 210 211 // Check if Ty is a usable substitute for the coercion type. 212 bool isUsableType(llvm::StructType *Ty) const { 213 return llvm::ArrayRef(Elems) == Ty->elements(); 214 } 215 216 // Get the coercion type as a literal struct type. 217 llvm::Type *getType() const { 218 if (Elems.size() == 1) 219 return Elems.front(); 220 else 221 return llvm::StructType::get(Context, Elems); 222 } 223 }; 224 }; 225 } // end anonymous namespace 226 227 ABIArgInfo SparcV9ABIInfo::classifyType(QualType Ty, unsigned SizeLimit, 228 unsigned &RegOffset) const { 229 if (Ty->isVoidType()) 230 return ABIArgInfo::getIgnore(); 231 232 auto &Context = getContext(); 233 auto &VMContext = getVMContext(); 234 235 uint64_t Size = Context.getTypeSize(Ty); 236 unsigned Alignment = Context.getTypeAlign(Ty); 237 bool NeedPadding = (Alignment > 64) && (RegOffset % 2 != 0); 238 239 // Anything too big to fit in registers is passed with an explicit indirect 240 // pointer / sret pointer. 241 if (Size > SizeLimit) { 242 RegOffset += 1; 243 return getNaturalAlignIndirect( 244 Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(), 245 /*ByVal=*/false); 246 } 247 248 // Treat an enum type as its underlying type. 249 if (const EnumType *EnumTy = Ty->getAs<EnumType>()) 250 Ty = EnumTy->getDecl()->getIntegerType(); 251 252 // Integer types smaller than a register are extended. 253 if (Size < 64 && Ty->isIntegerType()) { 254 RegOffset += 1; 255 return ABIArgInfo::getExtend(Ty); 256 } 257 258 if (const auto *EIT = Ty->getAs<BitIntType>()) 259 if (EIT->getNumBits() < 64) { 260 RegOffset += 1; 261 return ABIArgInfo::getExtend(Ty); 262 } 263 264 // Other non-aggregates go in registers. 265 if (!isAggregateTypeForABI(Ty)) { 266 RegOffset += Size / 64; 267 return ABIArgInfo::getDirect(); 268 } 269 270 // If a C++ object has either a non-trivial copy constructor or a non-trivial 271 // destructor, it is passed with an explicit indirect pointer / sret pointer. 272 if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) { 273 RegOffset += 1; 274 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(), 275 RAA == CGCXXABI::RAA_DirectInMemory); 276 } 277 278 // This is a small aggregate type that should be passed in registers. 279 // Build a coercion type from the LLVM struct type. 280 llvm::StructType *StrTy = dyn_cast<llvm::StructType>(CGT.ConvertType(Ty)); 281 if (!StrTy) { 282 RegOffset += Size / 64; 283 return ABIArgInfo::getDirect(); 284 } 285 286 CoerceBuilder CB(VMContext, getDataLayout()); 287 CB.addStruct(0, StrTy); 288 // All structs, even empty ones, should take up a register argument slot, 289 // so pin the minimum struct size to one bit. 290 CB.pad(llvm::alignTo( 291 std::max(CB.DL.getTypeSizeInBits(StrTy).getKnownMinValue(), uint64_t(1)), 292 64)); 293 RegOffset += CB.Size / 64; 294 295 // If we're dealing with overaligned structs we may need to add a padding in 296 // the front, to preserve the correct register-memory mapping. 297 // 298 // See SCD 2.4.1, pages 3P-11 and 3P-12. 299 llvm::Type *Padding = 300 NeedPadding ? llvm::Type::getInt64Ty(VMContext) : nullptr; 301 RegOffset += NeedPadding ? 1 : 0; 302 303 // Try to use the original type for coercion. 304 llvm::Type *CoerceTy = CB.isUsableType(StrTy) ? StrTy : CB.getType(); 305 306 ABIArgInfo AAI = ABIArgInfo::getDirect(CoerceTy, 0, Padding); 307 AAI.setInReg(CB.InReg); 308 return AAI; 309 } 310 311 RValue SparcV9ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, 312 QualType Ty, AggValueSlot Slot) const { 313 CharUnits SlotSize = CharUnits::fromQuantity(8); 314 auto TInfo = getContext().getTypeInfoInChars(Ty); 315 316 // Zero-sized types have a width of one byte for parameter passing purposes. 317 TInfo.Width = std::max(TInfo.Width, CharUnits::fromQuantity(1)); 318 319 // Arguments bigger than 2*SlotSize bytes are passed indirectly. 320 return emitVoidPtrVAArg(CGF, VAListAddr, Ty, 321 /*IsIndirect=*/TInfo.Width > 2 * SlotSize, TInfo, 322 SlotSize, 323 /*AllowHigherAlign=*/true, Slot); 324 } 325 326 void SparcV9ABIInfo::computeInfo(CGFunctionInfo &FI) const { 327 unsigned RetOffset = 0; 328 ABIArgInfo RetType = classifyType(FI.getReturnType(), 32 * 8, RetOffset); 329 FI.getReturnInfo() = RetType; 330 331 // Indirect returns will have its pointer passed as an argument. 332 unsigned ArgOffset = RetType.isIndirect() ? RetOffset : 0; 333 for (auto &I : FI.arguments()) 334 I.info = classifyType(I.type, 16 * 8, ArgOffset); 335 } 336 337 namespace { 338 class SparcV9TargetCodeGenInfo : public TargetCodeGenInfo { 339 public: 340 SparcV9TargetCodeGenInfo(CodeGenTypes &CGT) 341 : TargetCodeGenInfo(std::make_unique<SparcV9ABIInfo>(CGT)) {} 342 343 int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override { 344 return 14; 345 } 346 347 bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 348 llvm::Value *Address) const override; 349 350 llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF, 351 llvm::Value *Address) const override { 352 return CGF.Builder.CreateGEP(CGF.Int8Ty, Address, 353 llvm::ConstantInt::get(CGF.Int32Ty, 8)); 354 } 355 356 llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF, 357 llvm::Value *Address) const override { 358 return CGF.Builder.CreateGEP(CGF.Int8Ty, Address, 359 llvm::ConstantInt::get(CGF.Int32Ty, -8)); 360 } 361 }; 362 } // end anonymous namespace 363 364 bool 365 SparcV9TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 366 llvm::Value *Address) const { 367 // This is calculated from the LLVM and GCC tables and verified 368 // against gcc output. AFAIK all ABIs use the same encoding. 369 370 CodeGen::CGBuilderTy &Builder = CGF.Builder; 371 372 llvm::IntegerType *i8 = CGF.Int8Ty; 373 llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4); 374 llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8); 375 376 // 0-31: the 8-byte general-purpose registers 377 AssignToArrayRange(Builder, Address, Eight8, 0, 31); 378 379 // 32-63: f0-31, the 4-byte floating-point registers 380 AssignToArrayRange(Builder, Address, Four8, 32, 63); 381 382 // Y = 64 383 // PSR = 65 384 // WIM = 66 385 // TBR = 67 386 // PC = 68 387 // NPC = 69 388 // FSR = 70 389 // CSR = 71 390 AssignToArrayRange(Builder, Address, Eight8, 64, 71); 391 392 // 72-87: d0-15, the 8-byte floating-point registers 393 AssignToArrayRange(Builder, Address, Eight8, 72, 87); 394 395 return false; 396 } 397 398 std::unique_ptr<TargetCodeGenInfo> 399 CodeGen::createSparcV8TargetCodeGenInfo(CodeGenModule &CGM) { 400 return std::make_unique<SparcV8TargetCodeGenInfo>(CGM.getTypes()); 401 } 402 403 std::unique_ptr<TargetCodeGenInfo> 404 CodeGen::createSparcV9TargetCodeGenInfo(CodeGenModule &CGM) { 405 return std::make_unique<SparcV9TargetCodeGenInfo>(CGM.getTypes()); 406 } 407