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 *BT = Ty->
getAs<BuiltinType>();
75 BT && BT->getKind() == BuiltinType::LongDouble)
76 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
82ABIArgInfo SparcV8ABIInfo::classifyArgumentType(QualType Ty)
const {
83 if (
const auto *CT = Ty->
getAs<ComplexType>())
84 return classifyComplexType(CT,
false);
86 const auto *BT = Ty->
getAs<BuiltinType>();
87 if (BT && BT->getKind() == BuiltinType::LongDouble)
88 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
93void SparcV8ABIInfo::computeInfo(CGFunctionInfo &FI)
const {
99RValue SparcV8ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
100 QualType Ty, AggValueSlot Slot)
const {
102 auto TInfo = getContext().getTypeInfoInChars(Ty);
108 bool AllowHigherAlign =
false;
112 bool ForceRightAdjust =
true;
115 AllowHigherAlign, Slot, ForceRightAdjust);
119class SparcV8TargetCodeGenInfo :
public TargetCodeGenInfo {
121 SparcV8TargetCodeGenInfo(CodeGenTypes &CGT)
122 : TargetCodeGenInfo(std::make_unique<SparcV8ABIInfo>(CGT)) {}
124 llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
125 llvm::Value *Address)
const override {
132 llvm::ConstantInt::get(CGF.
Int32Ty, Offset));
135 llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
136 llvm::Value *Address)
const override {
143 llvm::ConstantInt::get(CGF.
Int32Ty, Offset));
175class SparcV9ABIInfo :
public ABIInfo {
177 SparcV9ABIInfo(CodeGenTypes &CGT)
179 IsComplexGnuABI(!CGT.getContext().getLangOpts().isCompatibleWith(
180 LangOptions::ClangABI::Ver23)) {}
184 bool IsComplexGnuABI;
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;
203 struct CoerceBuilder {
204 llvm::LLVMContext &Context;
205 const llvm::DataLayout &DL;
206 SmallVector<llvm::Type*, 8> Elems;
211 CoerceBuilder(llvm::LLVMContext &c,
const llvm::DataLayout &dl,
213 : Context(c), DL(dl),
Size(0), InReg(
false), IsVarArg(IsVarArg) {}
216 void pad(uint64_t ToSize) {
217 assert(ToSize >= Size &&
"Cannot remove elements");
222 uint64_t Aligned = llvm::alignTo(Size, 64);
223 if (Aligned > Size && Aligned <= ToSize) {
224 Elems.push_back(llvm::IntegerType::get(Context, Aligned - Size));
229 while (Size + 64 <= ToSize) {
230 Elems.push_back(llvm::Type::getInt64Ty(Context));
236 Elems.push_back(llvm::IntegerType::get(Context, ToSize - Size));
242 void addFloat(uint64_t Offset, llvm::Type *Ty,
unsigned Bits) {
254 Size = Offset + Bits;
258 void addStruct(uint64_t Offset, llvm::StructType *StrTy) {
259 const llvm::StructLayout *Layout = DL.getStructLayout(StrTy);
260 for (
unsigned i = 0, e = StrTy->getNumElements(); i != e; ++i) {
261 llvm::Type *ElemTy = StrTy->getElementType(i);
262 uint64_t ElemOffset = Offset + Layout->getElementOffsetInBits(i);
263 switch (ElemTy->getTypeID()) {
264 case llvm::Type::StructTyID:
267 case llvm::Type::FloatTyID:
268 addFloat(ElemOffset, ElemTy, 32);
270 case llvm::Type::DoubleTyID:
271 addFloat(ElemOffset, ElemTy, 64);
273 case llvm::Type::FP128TyID:
274 addFloat(ElemOffset, ElemTy, 128);
276 case llvm::Type::PointerTyID:
277 if (ElemOffset % 64 == 0) {
279 Elems.push_back(ElemTy);
290 bool isUsableType(llvm::StructType *Ty)
const {
291 return llvm::ArrayRef(Elems) == Ty->elements();
296 if (Elems.size() == 1)
297 return Elems.front();
299 return llvm::StructType::get(Context, Elems);
305ABIArgInfo SparcV9ABIInfo::classifyType(QualType Ty,
unsigned SizeLimit,
307 bool IsVarArg)
const {
311 auto &Context = getContext();
312 auto &VMContext = getVMContext();
326 if (Size > SizeLimit) {
328 return getNaturalAlignIndirect(
329 Ty, getDataLayout().getAllocaAddrSpace(),
338 llvm::Type *Padding = (Alignment > 64 && RegOffset % 2 != 0)
339 ? llvm::Type::getInt64Ty(VMContext)
341 unsigned PaddingSlots = Padding ? 1 : 0;
342 unsigned SizeSlots = llvm::divideCeil(Size, 64);
346 Ty = ED->getIntegerType();
350 RegOffset += PaddingSlots + SizeSlots;
354 if (
const auto *EIT = Ty->
getAs<BitIntType>())
355 if (EIT->getNumBits() < 64) {
356 RegOffset += PaddingSlots + SizeSlots;
364 if (IsComplexGnuABI) {
365 const auto *CT = Ty->
getAs<ComplexType>();
368 if (ElementTypeSize <= 32) {
371 llvm::IntegerType::get(VMContext, 2 * ElementTypeSize),
379 RegOffset += PaddingSlots + SizeSlots;
387 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
393 llvm::StructType *StrTy = dyn_cast<llvm::StructType>(CGT.ConvertType(Ty));
395 RegOffset += PaddingSlots + SizeSlots;
399 CoerceBuilder CB(VMContext, getDataLayout(), IsVarArg);
400 CB.addStruct(0, StrTy);
403 CB.pad(llvm::alignTo(
404 std::max(CB.DL.getTypeSizeInBits(StrTy).getKnownMinValue(),
uint64_t(1)),
406 RegOffset += PaddingSlots + CB.Size / 64;
409 llvm::Type *CoerceTy = CB.isUsableType(StrTy) ? StrTy : CB.getType();
416RValue SparcV9ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
417 QualType Ty, AggValueSlot Slot)
const {
419 auto TInfo = getContext().getTypeInfoInChars(Ty);
429 TInfo.Width > 2 * SlotSize, TInfo,
431 true, Slot, ForceRightAdjust);
434void SparcV9ABIInfo::computeInfo(CGFunctionInfo &FI)
const {
435 unsigned RetOffset = 0;
441 unsigned ArgOffset = RetType.
isIndirect() ? RetOffset : 0;
442 for (
auto [ArgNo, I] : llvm::enumerate(FI.
arguments())) {
444 I.info =
classifyType(I.type, 16 * 8, ArgOffset, IsVarArg);
449class SparcV9TargetCodeGenInfo :
public TargetCodeGenInfo {
451 SparcV9TargetCodeGenInfo(CodeGenTypes &CGT)
452 : TargetCodeGenInfo(std::make_unique<SparcV9ABIInfo>(CGT)) {}
454 int getDwarfEHStackPointer(CodeGen::CodeGenModule &M)
const override {
458 bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
459 llvm::Value *Address)
const override;
461 llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
462 llvm::Value *Address)
const override {
464 llvm::ConstantInt::get(CGF.
Int32Ty, 8));
467 llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
468 llvm::Value *Address)
const override {
470 llvm::ConstantInt::get(CGF.
Int32Ty, -8));
476SparcV9TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
477 llvm::Value *Address)
const {
481 CodeGen::CGBuilderTy &Builder = CGF.
Builder;
483 llvm::IntegerType *i8 = CGF.
Int8Ty;
484 llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
485 llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
509std::unique_ptr<TargetCodeGenInfo>
511 return std::make_unique<SparcV8TargetCodeGenInfo>(CGM.
getTypes());
514std::unique_ptr<TargetCodeGenInfo>
516 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)
fromQuantity - 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