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
13using namespace clang;
14using 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//
22namespace {
23class SparcV8ABIInfo : public DefaultABIInfo {
24public:
25 SparcV8ABIInfo(CodeGenTypes &CGT)
26 : DefaultABIInfo(CGT),
27 IsComplexGnuABI(!CGT.getContext().getLangOpts().isCompatibleWith(
28 Version: LangOptions::ClangABI::Ver23)) {}
29
30private:
31 /// Whether how `_Complex` values are passed and returned is GCC-compatible.
32 bool IsComplexGnuABI;
33
34 ABIArgInfo classifyComplexType(const ComplexType *Ty, bool IsRet) const;
35 ABIArgInfo classifyReturnType(QualType RetTy) const;
36 ABIArgInfo classifyArgumentType(QualType Ty) const;
37 void computeInfo(CGFunctionInfo &FI) const override;
38};
39} // end anonymous namespace
40
41ABIArgInfo SparcV8ABIInfo::classifyComplexType(const ComplexType *CT,
42 bool IsRet) const {
43 QualType ElementTy = CT->getElementType();
44
45 if (IsComplexGnuABI && ElementTy->isIntegerType()) {
46 // The default path already does the right thing for `long long _Complex`.
47 uint64_t ElementTypeSize = getContext().getTypeSize(T: ElementTy);
48 if (ElementTypeSize <= 32) {
49 // Coerce to an integer to get the correct scalar-like behavior.
50 return ABIArgInfo::getDirect(
51 T: llvm::IntegerType::get(C&: getVMContext(), NumBits: 2 * ElementTypeSize));
52 }
53 }
54
55 // Any other complex value is passed indirectly, but returned in registers.
56 if (!IsRet)
57 return getNaturalAlignIndirect(Ty: QualType(CT, 0),
58 AddrSpace: getDataLayout().getAllocaAddrSpace());
59
60 // long double _Complex is special, it is marked as inreg.
61 const auto *BT = ElementTy->getAs<BuiltinType>();
62 if (BT && BT->getKind() == BuiltinType::LongDouble)
63 return ABIArgInfo::getDirectInReg();
64
65 return ABIArgInfo::getDirect();
66}
67
68ABIArgInfo SparcV8ABIInfo::classifyReturnType(QualType Ty) const {
69 if (const auto *CT = Ty->getAs<ComplexType>())
70 return classifyComplexType(CT, /*IsRet=*/true);
71
72 if (const auto *BT = Ty->getAs<BuiltinType>();
73 BT && BT->getKind() == BuiltinType::LongDouble)
74 return getNaturalAlignIndirect(Ty, AddrSpace: getDataLayout().getAllocaAddrSpace(),
75 /*ByVal=*/false);
76
77 return DefaultABIInfo::classifyReturnType(RetTy: Ty);
78}
79
80ABIArgInfo SparcV8ABIInfo::classifyArgumentType(QualType Ty) const {
81 if (const auto *CT = Ty->getAs<ComplexType>())
82 return classifyComplexType(CT, /*IsRet=*/false);
83
84 const auto *BT = Ty->getAs<BuiltinType>();
85 if (BT && BT->getKind() == BuiltinType::LongDouble)
86 return getNaturalAlignIndirect(Ty, AddrSpace: getDataLayout().getAllocaAddrSpace());
87
88 return DefaultABIInfo::classifyArgumentType(RetTy: Ty);
89}
90
91void SparcV8ABIInfo::computeInfo(CGFunctionInfo &FI) const {
92 FI.getReturnInfo() = classifyReturnType(Ty: FI.getReturnType());
93 for (auto &Arg : FI.arguments())
94 Arg.info = classifyArgumentType(Ty: Arg.type);
95}
96
97namespace {
98class SparcV8TargetCodeGenInfo : public TargetCodeGenInfo {
99public:
100 SparcV8TargetCodeGenInfo(CodeGenTypes &CGT)
101 : TargetCodeGenInfo(std::make_unique<SparcV8ABIInfo>(args&: CGT)) {}
102
103 llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
104 llvm::Value *Address) const override {
105 int Offset;
106 if (isAggregateTypeForABI(T: CGF.CurFnInfo->getReturnType()))
107 Offset = 12;
108 else
109 Offset = 8;
110 return CGF.Builder.CreateGEP(Ty: CGF.Int8Ty, Ptr: Address,
111 IdxList: llvm::ConstantInt::get(Ty: CGF.Int32Ty, V: Offset));
112 }
113
114 llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
115 llvm::Value *Address) const override {
116 int Offset;
117 if (isAggregateTypeForABI(T: CGF.CurFnInfo->getReturnType()))
118 Offset = -12;
119 else
120 Offset = -8;
121 return CGF.Builder.CreateGEP(Ty: CGF.Int8Ty, Ptr: Address,
122 IdxList: llvm::ConstantInt::get(Ty: CGF.Int32Ty, V: Offset));
123 }
124};
125} // end anonymous namespace
126
127//===----------------------------------------------------------------------===//
128// SPARC v9 ABI Implementation.
129// Based on the SPARC Compliance Definition version 2.4.1.
130//
131// Function arguments a mapped to a nominal "parameter array" and promoted to
132// registers depending on their type. Each argument occupies 8 or 16 bytes in
133// the array, structs larger than 16 bytes are passed indirectly.
134//
135// One case requires special care:
136//
137// struct mixed {
138// int i;
139// float f;
140// };
141//
142// When a struct mixed is passed by value, it only occupies 8 bytes in the
143// parameter array, but the int is passed in an integer register, and the float
144// is passed in a floating point register. This is represented as two arguments
145// with the LLVM IR inreg attribute:
146//
147// declare void f(i32 inreg %i, float inreg %f)
148//
149// The code generator will only allocate 4 bytes from the parameter array for
150// the inreg arguments. All other arguments are allocated a multiple of 8
151// bytes.
152//
153namespace {
154class SparcV9ABIInfo : public ABIInfo {
155public:
156 SparcV9ABIInfo(CodeGenTypes &CGT)
157 : ABIInfo(CGT),
158 IsComplexGnuABI(!CGT.getContext().getLangOpts().isCompatibleWith(
159 Version: LangOptions::ClangABI::Ver23)) {}
160
161private:
162 /// Whether how `_Complex` values are passed and returned is GCC-compatible.
163 bool IsComplexGnuABI;
164
165 ABIArgInfo classifyType(QualType RetTy, unsigned SizeLimit,
166 unsigned &RegOffset) const;
167 void computeInfo(CGFunctionInfo &FI) const override;
168 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
169 AggValueSlot Slot) const override;
170
171 // Coercion type builder for structs passed in registers. The coercion type
172 // serves two purposes:
173 //
174 // 1. Pad structs to a multiple of 64 bits, so they are passed 'left-aligned'
175 // in registers.
176 // 2. Expose aligned floating point elements as first-level elements, so the
177 // code generator knows to pass them in floating point registers.
178 //
179 // We also compute the InReg flag which indicates that the struct contains
180 // aligned 32-bit floats.
181 //
182 struct CoerceBuilder {
183 llvm::LLVMContext &Context;
184 const llvm::DataLayout &DL;
185 SmallVector<llvm::Type*, 8> Elems;
186 uint64_t Size;
187 bool InReg;
188
189 CoerceBuilder(llvm::LLVMContext &c, const llvm::DataLayout &dl)
190 : Context(c), DL(dl), Size(0), InReg(false) {}
191
192 // Pad Elems with integers until Size is ToSize.
193 void pad(uint64_t ToSize) {
194 assert(ToSize >= Size && "Cannot remove elements");
195 if (ToSize == Size)
196 return;
197
198 // Finish the current 64-bit word.
199 uint64_t Aligned = llvm::alignTo(Value: Size, Align: 64);
200 if (Aligned > Size && Aligned <= ToSize) {
201 Elems.push_back(Elt: llvm::IntegerType::get(C&: Context, NumBits: Aligned - Size));
202 Size = Aligned;
203 }
204
205 // Add whole 64-bit words.
206 while (Size + 64 <= ToSize) {
207 Elems.push_back(Elt: llvm::Type::getInt64Ty(C&: Context));
208 Size += 64;
209 }
210
211 // Final in-word padding.
212 if (Size < ToSize) {
213 Elems.push_back(Elt: llvm::IntegerType::get(C&: Context, NumBits: ToSize - Size));
214 Size = ToSize;
215 }
216 }
217
218 // Add a floating point element at Offset.
219 void addFloat(uint64_t Offset, llvm::Type *Ty, unsigned Bits) {
220 // Unaligned floats are treated as integers.
221 if (Offset % Bits)
222 return;
223 // The InReg flag is only required if there are any floats < 64 bits.
224 if (Bits < 64)
225 InReg = true;
226 pad(ToSize: Offset);
227 Elems.push_back(Elt: Ty);
228 Size = Offset + Bits;
229 }
230
231 // Add a struct type to the coercion type, starting at Offset (in bits).
232 void addStruct(uint64_t Offset, llvm::StructType *StrTy) {
233 const llvm::StructLayout *Layout = DL.getStructLayout(Ty: StrTy);
234 for (unsigned i = 0, e = StrTy->getNumElements(); i != e; ++i) {
235 llvm::Type *ElemTy = StrTy->getElementType(N: i);
236 uint64_t ElemOffset = Offset + Layout->getElementOffsetInBits(Idx: i);
237 switch (ElemTy->getTypeID()) {
238 case llvm::Type::StructTyID:
239 addStruct(Offset: ElemOffset, StrTy: cast<llvm::StructType>(Val: ElemTy));
240 break;
241 case llvm::Type::FloatTyID:
242 addFloat(Offset: ElemOffset, Ty: ElemTy, Bits: 32);
243 break;
244 case llvm::Type::DoubleTyID:
245 addFloat(Offset: ElemOffset, Ty: ElemTy, Bits: 64);
246 break;
247 case llvm::Type::FP128TyID:
248 addFloat(Offset: ElemOffset, Ty: ElemTy, Bits: 128);
249 break;
250 case llvm::Type::PointerTyID:
251 if (ElemOffset % 64 == 0) {
252 pad(ToSize: ElemOffset);
253 Elems.push_back(Elt: ElemTy);
254 Size += 64;
255 }
256 break;
257 default:
258 break;
259 }
260 }
261 }
262
263 // Check if Ty is a usable substitute for the coercion type.
264 bool isUsableType(llvm::StructType *Ty) const {
265 return llvm::ArrayRef(Elems) == Ty->elements();
266 }
267
268 // Get the coercion type as a literal struct type.
269 llvm::Type *getType() const {
270 if (Elems.size() == 1)
271 return Elems.front();
272 else
273 return llvm::StructType::get(Context, Elements: Elems);
274 }
275 };
276};
277} // end anonymous namespace
278
279ABIArgInfo SparcV9ABIInfo::classifyType(QualType Ty, unsigned SizeLimit,
280 unsigned &RegOffset) const {
281 if (Ty->isVoidType())
282 return ABIArgInfo::getIgnore();
283
284 auto &Context = getContext();
285 auto &VMContext = getVMContext();
286
287 // FIXME: the GCC-style `aligned` attribute on typedefs is not taken into
288 // account here, because the canonicalized type no longer has that
289 // information. Hence such over-aligned typedefs are not ABI-compatible with
290 // GCC.
291 //
292 // This is different from the `aligned` attribute on structs or fields, which
293 // is taken into account.
294 unsigned Alignment = Context.getTypeAlign(T: Ty);
295 uint64_t Size = Context.getTypeSize(T: Ty);
296
297 // Anything too big to fit in registers is passed with an explicit indirect
298 // pointer / sret pointer.
299 if (Size > SizeLimit) {
300 RegOffset += 1;
301 return getNaturalAlignIndirect(
302 Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),
303 /*ByVal=*/false);
304 }
305
306 // An argument that is passed in registers but has an alignment higher than 8
307 // bytes must be register-aligned. Insert a dummy i64 argument to fill the
308 // odd-numbered register.
309 //
310 // See SCD 2.4.1, pages 3P-11 and 3P-12.
311 llvm::Type *Padding = (Alignment > 64 && RegOffset % 2 != 0)
312 ? llvm::Type::getInt64Ty(C&: VMContext)
313 : nullptr;
314 unsigned PaddingSlots = Padding ? 1 : 0;
315 unsigned SizeSlots = llvm::divideCeil(Numerator: Size, Denominator: 64);
316
317 // Treat an enum type as its underlying type.
318 if (const auto *ED = Ty->getAsEnumDecl())
319 Ty = ED->getIntegerType();
320
321 // Integer types smaller than a register are extended.
322 if (Size < 64 && Ty->isIntegerType()) {
323 RegOffset += PaddingSlots + SizeSlots;
324 return ABIArgInfo::getExtend(Ty, /*T=*/nullptr, Padding);
325 }
326
327 if (const auto *EIT = Ty->getAs<BitIntType>())
328 if (EIT->getNumBits() < 64) {
329 RegOffset += PaddingSlots + SizeSlots;
330 return ABIArgInfo::getExtend(Ty, /*T=*/nullptr, Padding);
331 }
332
333 // When being GCC-compatible, cast a complex char, short and int to an integer
334 // type of the right size to get the correct scalar-like behavior. Other
335 // complex types fall through and are treated like a struct containing the
336 // real and imaginary parts, e.g. `{ i64, i64 }` or `{ double, double }`.
337 if (IsComplexGnuABI) {
338 const auto *CT = Ty->getAs<ComplexType>();
339 if (CT && CT->getElementType()->isIntegerType()) {
340 uint64_t ElementTypeSize = Context.getTypeSize(T: CT->getElementType());
341 if (ElementTypeSize <= 32) {
342 RegOffset += 1;
343 return ABIArgInfo::getDirect(
344 T: llvm::IntegerType::get(C&: VMContext, NumBits: 2 * ElementTypeSize),
345 /*Offset=*/0, Padding);
346 }
347 }
348 }
349
350 // Other non-aggregates go in registers.
351 if (!isAggregateTypeForABI(T: Ty)) {
352 RegOffset += PaddingSlots + SizeSlots;
353 return ABIArgInfo::getDirect(/*T=*/nullptr, /*Offset=*/0, Padding);
354 }
355
356 // If a C++ object has either a non-trivial copy constructor or a non-trivial
357 // destructor, it is passed with an explicit indirect pointer / sret pointer.
358 if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(T: Ty, CXXABI&: getCXXABI())) {
359 RegOffset += 1;
360 return getNaturalAlignIndirect(Ty, AddrSpace: getDataLayout().getAllocaAddrSpace(),
361 ByVal: RAA == CGCXXABI::RAA_DirectInMemory);
362 }
363
364 // This is a small aggregate type that should be passed in registers.
365 // Build a coercion type from the LLVM struct type.
366 llvm::StructType *StrTy = dyn_cast<llvm::StructType>(Val: CGT.ConvertType(T: Ty));
367 if (!StrTy) {
368 RegOffset += PaddingSlots + SizeSlots;
369 return ABIArgInfo::getDirect(/*T=*/nullptr, /*Offset=*/0, Padding);
370 }
371
372 CoerceBuilder CB(VMContext, getDataLayout());
373 CB.addStruct(Offset: 0, StrTy);
374 // All structs, even empty ones, should take up a register argument slot,
375 // so pin the minimum struct size to one bit.
376 CB.pad(ToSize: llvm::alignTo(
377 Value: std::max(a: CB.DL.getTypeSizeInBits(Ty: StrTy).getKnownMinValue(), b: uint64_t(1)),
378 Align: 64));
379 RegOffset += PaddingSlots + CB.Size / 64;
380
381 // Try to use the original type for coercion.
382 llvm::Type *CoerceTy = CB.isUsableType(Ty: StrTy) ? StrTy : CB.getType();
383
384 ABIArgInfo AAI = ABIArgInfo::getDirect(T: CoerceTy, Offset: 0, Padding);
385 AAI.setInReg(CB.InReg);
386 return AAI;
387}
388
389RValue SparcV9ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
390 QualType Ty, AggValueSlot Slot) const {
391 CharUnits SlotSize = CharUnits::fromQuantity(Quantity: 8);
392 auto TInfo = getContext().getTypeInfoInChars(T: Ty);
393
394 // Zero-sized types have a width of one byte for parameter passing purposes.
395 TInfo.Width = std::max(a: TInfo.Width, b: CharUnits::fromQuantity(Quantity: 1));
396
397 // Small _Complex types are right-adjusted, but small aggregates are not.
398 bool ForceRightAdjust = Ty->isAnyComplexType();
399
400 // Arguments bigger than 2*SlotSize bytes are passed indirectly.
401 return emitVoidPtrVAArg(CGF, VAListAddr, ValueTy: Ty,
402 /*IsIndirect=*/TInfo.Width > 2 * SlotSize, ValueInfo: TInfo,
403 SlotSizeAndAlign: SlotSize,
404 /*AllowHigherAlign=*/true, Slot, ForceRightAdjust);
405}
406
407void SparcV9ABIInfo::computeInfo(CGFunctionInfo &FI) const {
408 unsigned RetOffset = 0;
409 ABIArgInfo RetType = classifyType(Ty: FI.getReturnType(), SizeLimit: 32 * 8, RegOffset&: RetOffset);
410 FI.getReturnInfo() = RetType;
411
412 // Indirect returns will have its pointer passed as an argument.
413 unsigned ArgOffset = RetType.isIndirect() ? RetOffset : 0;
414 for (auto &I : FI.arguments())
415 I.info = classifyType(Ty: I.type, SizeLimit: 16 * 8, RegOffset&: ArgOffset);
416}
417
418namespace {
419class SparcV9TargetCodeGenInfo : public TargetCodeGenInfo {
420public:
421 SparcV9TargetCodeGenInfo(CodeGenTypes &CGT)
422 : TargetCodeGenInfo(std::make_unique<SparcV9ABIInfo>(args&: CGT)) {}
423
424 int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
425 return 14;
426 }
427
428 bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
429 llvm::Value *Address) const override;
430
431 llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
432 llvm::Value *Address) const override {
433 return CGF.Builder.CreateGEP(Ty: CGF.Int8Ty, Ptr: Address,
434 IdxList: llvm::ConstantInt::get(Ty: CGF.Int32Ty, V: 8));
435 }
436
437 llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
438 llvm::Value *Address) const override {
439 return CGF.Builder.CreateGEP(Ty: CGF.Int8Ty, Ptr: Address,
440 IdxList: llvm::ConstantInt::get(Ty: CGF.Int32Ty, V: -8));
441 }
442};
443} // end anonymous namespace
444
445bool
446SparcV9TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
447 llvm::Value *Address) const {
448 // This is calculated from the LLVM and GCC tables and verified
449 // against gcc output. AFAIK all ABIs use the same encoding.
450
451 CodeGen::CGBuilderTy &Builder = CGF.Builder;
452
453 llvm::IntegerType *i8 = CGF.Int8Ty;
454 llvm::Value *Four8 = llvm::ConstantInt::get(Ty: i8, V: 4);
455 llvm::Value *Eight8 = llvm::ConstantInt::get(Ty: i8, V: 8);
456
457 // 0-31: the 8-byte general-purpose registers
458 AssignToArrayRange(Builder, Array: Address, Value: Eight8, FirstIndex: 0, LastIndex: 31);
459
460 // 32-63: f0-31, the 4-byte floating-point registers
461 AssignToArrayRange(Builder, Array: Address, Value: Four8, FirstIndex: 32, LastIndex: 63);
462
463 // Y = 64
464 // PSR = 65
465 // WIM = 66
466 // TBR = 67
467 // PC = 68
468 // NPC = 69
469 // FSR = 70
470 // CSR = 71
471 AssignToArrayRange(Builder, Array: Address, Value: Eight8, FirstIndex: 64, LastIndex: 71);
472
473 // 72-87: d0-15, the 8-byte floating-point registers
474 AssignToArrayRange(Builder, Array: Address, Value: Eight8, FirstIndex: 72, LastIndex: 87);
475
476 return false;
477}
478
479std::unique_ptr<TargetCodeGenInfo>
480CodeGen::createSparcV8TargetCodeGenInfo(CodeGenModule &CGM) {
481 return std::make_unique<SparcV8TargetCodeGenInfo>(args&: CGM.getTypes());
482}
483
484std::unique_ptr<TargetCodeGenInfo>
485CodeGen::createSparcV9TargetCodeGenInfo(CodeGenModule &CGM) {
486 return std::make_unique<SparcV9TargetCodeGenInfo>(args&: CGM.getTypes());
487}
488