10#include "TargetInfo.h"
25 SparcV8ABIInfo(CodeGenTypes &CGT)
26 : DefaultABIInfo(CGT),
27 IsComplexGnuABI(!CGT.getContext().getLangOpts().isCompatibleWith(
28 LangOptions::ClangABI::Ver23)) {}
34 ABIArgInfo classifyComplexType(
const ComplexType *Ty,
bool IsRet)
const;
37 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
38 AggValueSlot Slot)
const override;
39 void computeInfo(CGFunctionInfo &FI)
const override;
49 uint64_t ElementTypeSize = getContext().getTypeSize(ElementTy);
50 if (ElementTypeSize <= 32) {
53 llvm::IntegerType::get(getVMContext(), 2 * ElementTypeSize));
59 return getNaturalAlignIndirect(QualType(CT, 0),
60 getDataLayout().getAllocaAddrSpace());
63 const auto *BT = ElementTy->
getAs<BuiltinType>();
64 if (BT && BT->getKind() == BuiltinType::LongDouble)
70ABIArgInfo SparcV8ABIInfo::classifyReturnType(QualType Ty)
const {
71 if (
const auto *CT = Ty->
getAs<ComplexType>())
72 return classifyComplexType(CT,
true);
74 if (
const auto *VT = Ty->
getAs<VectorType>()) {
77 if (VT->getElementType()->isRealFloatingType() || Size > 64)
78 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
81 llvm::Type *FloatTy = llvm::Type::getFloatTy(getVMContext());
82 llvm::Type *DoubleTy = llvm::Type::getDoubleTy(getVMContext());
83 llvm::Type *CoerceTy =
Size <= 32 ? FloatTy : DoubleTy;
87 if (
const auto *BT = Ty->
getAs<BuiltinType>();
88 BT && BT->getKind() == BuiltinType::LongDouble &&
89 getContext().getTypeSize(Ty) > 64)
90 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
96ABIArgInfo SparcV8ABIInfo::classifyArgumentType(QualType Ty)
const {
97 if (
const auto *CT = Ty->
getAs<ComplexType>())
98 return classifyComplexType(CT,
false);
101 if (
const auto *VT = Ty->
getAs<VectorType>()) {
102 uint64_t SizeInBits = getContext().getTypeSize(Ty);
103 if (VT->getElementType()->isRealFloatingType() || SizeInBits > 64)
104 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
107 const auto *BT = Ty->
getAs<BuiltinType>();
108 if (BT && BT->getKind() == BuiltinType::LongDouble &&
109 getContext().getTypeSize(Ty) > 64)
110 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
115void SparcV8ABIInfo::computeInfo(CGFunctionInfo &FI)
const {
121RValue SparcV8ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
122 QualType Ty, AggValueSlot Slot)
const {
124 auto TInfo = getContext().getTypeInfoInChars(Ty);
130 bool AllowHigherAlign =
false;
134 bool ForceRightAdjust =
true;
137 AllowHigherAlign, Slot, ForceRightAdjust);
141class SparcV8TargetCodeGenInfo :
public TargetCodeGenInfo {
143 SparcV8TargetCodeGenInfo(CodeGenTypes &CGT)
144 : TargetCodeGenInfo(std::make_unique<SparcV8ABIInfo>(CGT)) {}
146 llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
147 llvm::Value *Address)
const override {
154 llvm::ConstantInt::get(CGF.
Int32Ty, Offset));
157 llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
158 llvm::Value *Address)
const override {
165 llvm::ConstantInt::get(CGF.
Int32Ty, Offset));
197class SparcV9ABIInfo :
public ABIInfo {
199 SparcV9ABIInfo(CodeGenTypes &CGT)
201 IsComplexGnuABI(!CGT.getContext().getLangOpts().isCompatibleWith(
202 LangOptions::ClangABI::Ver23)) {}
206 bool IsComplexGnuABI;
208 ABIArgInfo
classifyType(QualType RetTy,
unsigned SizeLimit,
209 unsigned &RegOffset,
bool IsVarArg)
const;
210 void computeInfo(CGFunctionInfo &FI)
const override;
211 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
212 AggValueSlot Slot)
const override;
225 struct CoerceBuilder {
226 llvm::LLVMContext &Context;
227 const llvm::DataLayout &DL;
228 SmallVector<llvm::Type*, 8> Elems;
233 CoerceBuilder(llvm::LLVMContext &c,
const llvm::DataLayout &dl,
235 : Context(c), DL(dl),
Size(0), InReg(
false), IsVarArg(IsVarArg) {}
238 void pad(uint64_t ToSize) {
239 assert(ToSize >= Size &&
"Cannot remove elements");
244 uint64_t Aligned = llvm::alignTo(Size, 64);
245 if (Aligned > Size && Aligned <= ToSize) {
246 Elems.push_back(llvm::IntegerType::get(Context, Aligned - Size));
251 while (Size + 64 <= ToSize) {
252 Elems.push_back(llvm::Type::getInt64Ty(Context));
258 Elems.push_back(llvm::IntegerType::get(Context, ToSize - Size));
264 void addFloat(uint64_t Offset, llvm::Type *Ty,
unsigned Bits) {
276 Size = Offset + Bits;
280 void addStruct(uint64_t Offset, llvm::StructType *StrTy) {
281 const llvm::StructLayout *Layout = DL.getStructLayout(StrTy);
282 for (
unsigned i = 0, e = StrTy->getNumElements(); i != e; ++i) {
283 llvm::Type *ElemTy = StrTy->getElementType(i);
284 uint64_t ElemOffset = Offset + Layout->getElementOffsetInBits(i);
285 switch (ElemTy->getTypeID()) {
286 case llvm::Type::StructTyID:
289 case llvm::Type::FloatTyID:
290 addFloat(ElemOffset, ElemTy, 32);
292 case llvm::Type::DoubleTyID:
293 addFloat(ElemOffset, ElemTy, 64);
295 case llvm::Type::FP128TyID:
296 addFloat(ElemOffset, ElemTy, 128);
298 case llvm::Type::PointerTyID:
299 if (ElemOffset % 64 == 0) {
301 Elems.push_back(ElemTy);
312 bool isUsableType(llvm::StructType *Ty)
const {
313 return llvm::ArrayRef(Elems) == Ty->elements();
318 if (Elems.size() == 1)
319 return Elems.front();
321 return llvm::StructType::get(Context, Elems);
327ABIArgInfo SparcV9ABIInfo::classifyType(QualType Ty,
unsigned SizeLimit,
329 bool IsVarArg)
const {
333 auto &Context = getContext();
334 auto &VMContext = getVMContext();
348 if (Size > SizeLimit) {
350 return getNaturalAlignIndirect(
351 Ty, getDataLayout().getAllocaAddrSpace(),
360 llvm::Type *Padding = (Alignment > 64 && RegOffset % 2 != 0)
361 ? llvm::Type::getInt64Ty(VMContext)
363 unsigned PaddingSlots = Padding ? 1 : 0;
364 unsigned SizeSlots = llvm::divideCeil(Size, 64);
368 Ty = ED->getIntegerType();
372 RegOffset += PaddingSlots + SizeSlots;
376 if (
const auto *EIT = Ty->
getAs<BitIntType>())
377 if (EIT->getNumBits() < 64) {
378 RegOffset += PaddingSlots + SizeSlots;
386 if (IsComplexGnuABI) {
387 const auto *CT = Ty->
getAs<ComplexType>();
390 if (ElementTypeSize <= 32) {
393 llvm::IntegerType::get(VMContext, 2 * ElementTypeSize),
401 RegOffset += PaddingSlots + SizeSlots;
409 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
415 llvm::StructType *StrTy = dyn_cast<llvm::StructType>(CGT.ConvertType(Ty));
417 RegOffset += PaddingSlots + SizeSlots;
421 CoerceBuilder CB(VMContext, getDataLayout(), IsVarArg);
422 CB.addStruct(0, StrTy);
425 CB.pad(llvm::alignTo(
426 std::max(CB.DL.getTypeSizeInBits(StrTy).getKnownMinValue(),
uint64_t(1)),
428 RegOffset += PaddingSlots + CB.Size / 64;
431 llvm::Type *CoerceTy = CB.isUsableType(StrTy) ? StrTy : CB.getType();
438RValue SparcV9ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
439 QualType Ty, AggValueSlot Slot)
const {
441 auto TInfo = getContext().getTypeInfoInChars(Ty);
451 TInfo.Width > 2 * SlotSize, TInfo,
453 true, Slot, ForceRightAdjust);
456void SparcV9ABIInfo::computeInfo(CGFunctionInfo &FI)
const {
457 unsigned RetOffset = 0;
463 unsigned ArgOffset = RetType.
isIndirect() ? RetOffset : 0;
464 for (
auto [ArgNo, I] : llvm::enumerate(FI.
arguments())) {
466 I.info =
classifyType(I.type, 16 * 8, ArgOffset, IsVarArg);
471class SparcV9TargetCodeGenInfo :
public TargetCodeGenInfo {
473 SparcV9TargetCodeGenInfo(CodeGenTypes &CGT)
474 : TargetCodeGenInfo(std::make_unique<SparcV9ABIInfo>(CGT)) {}
476 int getDwarfEHStackPointer(CodeGen::CodeGenModule &M)
const override {
480 bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
481 llvm::Value *Address)
const override;
483 llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
484 llvm::Value *Address)
const override {
486 llvm::ConstantInt::get(CGF.
Int32Ty, 8));
489 llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
490 llvm::Value *Address)
const override {
492 llvm::ConstantInt::get(CGF.
Int32Ty, -8));
498SparcV9TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
499 llvm::Value *Address)
const {
503 CodeGen::CGBuilderTy &Builder = CGF.
Builder;
505 llvm::IntegerType *i8 = CGF.
Int8Ty;
506 llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
507 llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
531std::unique_ptr<TargetCodeGenInfo>
533 return std::make_unique<SparcV8TargetCodeGenInfo>(CGM.
getTypes());
536std::unique_ptr<TargetCodeGenInfo>
538 return std::make_unique<SparcV9TargetCodeGenInfo>(CGM.
getTypes());
static ABIArgInfo classifyType(CodeGenModule &CGM, CanQualType type, bool forReturn)
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
unsigned getTypeAlign(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in bits.
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
static ABIArgInfo getIgnore()
static ABIArgInfo getDirect(llvm::Type *T=nullptr, unsigned Offset=0, llvm::Type *Padding=nullptr, bool CanBeFlattened=true, unsigned Align=0)
static ABIArgInfo getExtend(QualType Ty, llvm::Type *T=nullptr, llvm::Type *Padding=nullptr)
static ABIArgInfo getDirectInReg(llvm::Type *T=nullptr)
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
RecordArgABI
Specify how one should pass an argument of a record type.
@ RAA_DirectInMemory
Pass it on the stack using its defined layout.
ABIArgInfo & getReturnInfo()
CanQualType getReturnType() const
MutableArrayRef< ArgInfo > arguments()
unsigned getNumRequiredArgs() const
const CGFunctionInfo * CurFnInfo
This class organizes the cross-function state that is used while generating LLVM code.
CodeGenTypes & getTypes()
DefaultABIInfo - The default implementation for ABI specific details.
ABIArgInfo classifyArgumentType(QualType RetTy) const
ABIArgInfo classifyReturnType(QualType RetTy) const
Complex values, per C99 6.2.5p11.
QualType getElementType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
bool isAnyComplexType() const
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
const T * getAs() const
Member-template getAs<specific type>'.
ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to pass a particular type.
CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
RValue emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType ValueTy, bool IsIndirect, TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign, bool AllowHigherAlign, AggValueSlot Slot, bool ForceRightAdjust=false)
Emit va_arg for a platform using the common void* representation, where arguments are simply emitted ...
bool isAggregateTypeForABI(QualType T)
void AssignToArrayRange(CodeGen::CGBuilderTy &Builder, llvm::Value *Array, llvm::Value *Value, unsigned FirstIndex, unsigned LastIndex)
std::unique_ptr< TargetCodeGenInfo > createSparcV8TargetCodeGenInfo(CodeGenModule &CGM)
std::unique_ptr< TargetCodeGenInfo > createSparcV9TargetCodeGenInfo(CodeGenModule &CGM)
constexpr bool isIntegerType(PrimType T)
Top level wrappers for InstallAPI frontend operations.
U cast(CodeGen::Address addr)
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * Int32Ty