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