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