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 void computeInfo(CGFunctionInfo &FI)
const override;
47 uint64_t ElementTypeSize = getContext().getTypeSize(ElementTy);
48 if (ElementTypeSize <= 32) {
51 llvm::IntegerType::get(getVMContext(), 2 * ElementTypeSize));
57 return getNaturalAlignIndirect(QualType(CT, 0),
58 getDataLayout().getAllocaAddrSpace());
61 const auto *BT = ElementTy->
getAs<BuiltinType>();
62 if (BT && BT->getKind() == BuiltinType::LongDouble)
68ABIArgInfo SparcV8ABIInfo::classifyReturnType(QualType Ty)
const {
69 if (
const auto *CT = Ty->
getAs<ComplexType>())
70 return classifyComplexType(CT,
true);
72 if (
const auto *BT = Ty->
getAs<BuiltinType>();
73 BT && BT->getKind() == BuiltinType::LongDouble)
74 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
80ABIArgInfo SparcV8ABIInfo::classifyArgumentType(QualType Ty)
const {
81 if (
const auto *CT = Ty->
getAs<ComplexType>())
82 return classifyComplexType(CT,
false);
84 const auto *BT = Ty->
getAs<BuiltinType>();
85 if (BT && BT->getKind() == BuiltinType::LongDouble)
86 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
91void SparcV8ABIInfo::computeInfo(CGFunctionInfo &FI)
const {
98class SparcV8TargetCodeGenInfo :
public TargetCodeGenInfo {
100 SparcV8TargetCodeGenInfo(CodeGenTypes &CGT)
101 : TargetCodeGenInfo(std::make_unique<SparcV8ABIInfo>(CGT)) {}
103 llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
104 llvm::Value *Address)
const override {
111 llvm::ConstantInt::get(CGF.
Int32Ty, Offset));
114 llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
115 llvm::Value *Address)
const override {
122 llvm::ConstantInt::get(CGF.
Int32Ty, Offset));
154class SparcV9ABIInfo :
public ABIInfo {
156 SparcV9ABIInfo(CodeGenTypes &CGT)
158 IsComplexGnuABI(!CGT.getContext().getLangOpts().isCompatibleWith(
159 LangOptions::ClangABI::Ver23)) {}
163 bool IsComplexGnuABI;
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;
182 struct CoerceBuilder {
183 llvm::LLVMContext &Context;
184 const llvm::DataLayout &DL;
185 SmallVector<llvm::Type*, 8> Elems;
189 CoerceBuilder(llvm::LLVMContext &c,
const llvm::DataLayout &dl)
190 : Context(c), DL(dl),
Size(0), InReg(
false) {}
193 void pad(uint64_t ToSize) {
194 assert(ToSize >= Size &&
"Cannot remove elements");
199 uint64_t Aligned = llvm::alignTo(Size, 64);
200 if (Aligned > Size && Aligned <= ToSize) {
201 Elems.push_back(llvm::IntegerType::get(Context, Aligned - Size));
206 while (Size + 64 <= ToSize) {
207 Elems.push_back(llvm::Type::getInt64Ty(Context));
213 Elems.push_back(llvm::IntegerType::get(Context, ToSize - Size));
219 void addFloat(uint64_t Offset, llvm::Type *Ty,
unsigned Bits) {
228 Size = Offset + Bits;
232 void addStruct(uint64_t Offset, llvm::StructType *StrTy) {
233 const llvm::StructLayout *Layout = DL.getStructLayout(StrTy);
234 for (
unsigned i = 0, e = StrTy->getNumElements(); i != e; ++i) {
235 llvm::Type *ElemTy = StrTy->getElementType(i);
236 uint64_t ElemOffset = Offset + Layout->getElementOffsetInBits(i);
237 switch (ElemTy->getTypeID()) {
238 case llvm::Type::StructTyID:
241 case llvm::Type::FloatTyID:
242 addFloat(ElemOffset, ElemTy, 32);
244 case llvm::Type::DoubleTyID:
245 addFloat(ElemOffset, ElemTy, 64);
247 case llvm::Type::FP128TyID:
248 addFloat(ElemOffset, ElemTy, 128);
250 case llvm::Type::PointerTyID:
251 if (ElemOffset % 64 == 0) {
253 Elems.push_back(ElemTy);
264 bool isUsableType(llvm::StructType *Ty)
const {
265 return llvm::ArrayRef(Elems) == Ty->elements();
270 if (Elems.size() == 1)
271 return Elems.front();
273 return llvm::StructType::get(Context, Elems);
279ABIArgInfo SparcV9ABIInfo::classifyType(QualType Ty,
unsigned SizeLimit,
280 unsigned &RegOffset)
const {
284 auto &Context = getContext();
285 auto &VMContext = getVMContext();
299 if (Size > SizeLimit) {
301 return getNaturalAlignIndirect(
302 Ty, getDataLayout().getAllocaAddrSpace(),
311 llvm::Type *Padding = (Alignment > 64 && RegOffset % 2 != 0)
312 ? llvm::Type::getInt64Ty(VMContext)
314 unsigned PaddingSlots = Padding ? 1 : 0;
315 unsigned SizeSlots = llvm::divideCeil(Size, 64);
319 Ty = ED->getIntegerType();
323 RegOffset += PaddingSlots + SizeSlots;
327 if (
const auto *EIT = Ty->
getAs<BitIntType>())
328 if (EIT->getNumBits() < 64) {
329 RegOffset += PaddingSlots + SizeSlots;
337 if (IsComplexGnuABI) {
338 const auto *CT = Ty->
getAs<ComplexType>();
341 if (ElementTypeSize <= 32) {
344 llvm::IntegerType::get(VMContext, 2 * ElementTypeSize),
352 RegOffset += PaddingSlots + SizeSlots;
360 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
366 llvm::StructType *StrTy = dyn_cast<llvm::StructType>(CGT.ConvertType(Ty));
368 RegOffset += PaddingSlots + SizeSlots;
372 CoerceBuilder CB(VMContext, getDataLayout());
373 CB.addStruct(0, StrTy);
376 CB.pad(llvm::alignTo(
377 std::max(CB.DL.getTypeSizeInBits(StrTy).getKnownMinValue(),
uint64_t(1)),
379 RegOffset += PaddingSlots + CB.Size / 64;
382 llvm::Type *CoerceTy = CB.isUsableType(StrTy) ? StrTy : CB.getType();
389RValue SparcV9ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
390 QualType Ty, AggValueSlot Slot)
const {
392 auto TInfo = getContext().getTypeInfoInChars(Ty);
402 TInfo.Width > 2 * SlotSize, TInfo,
404 true, Slot, ForceRightAdjust);
407void SparcV9ABIInfo::computeInfo(CGFunctionInfo &FI)
const {
408 unsigned RetOffset = 0;
413 unsigned ArgOffset = RetType.
isIndirect() ? RetOffset : 0;
419class SparcV9TargetCodeGenInfo :
public TargetCodeGenInfo {
421 SparcV9TargetCodeGenInfo(CodeGenTypes &CGT)
422 : TargetCodeGenInfo(std::make_unique<SparcV9ABIInfo>(CGT)) {}
424 int getDwarfEHStackPointer(CodeGen::CodeGenModule &M)
const override {
428 bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
429 llvm::Value *Address)
const override;
431 llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
432 llvm::Value *Address)
const override {
434 llvm::ConstantInt::get(CGF.
Int32Ty, 8));
437 llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
438 llvm::Value *Address)
const override {
440 llvm::ConstantInt::get(CGF.
Int32Ty, -8));
446SparcV9TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
447 llvm::Value *Address)
const {
451 CodeGen::CGBuilderTy &Builder = CGF.
Builder;
453 llvm::IntegerType *i8 = CGF.
Int8Ty;
454 llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
455 llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
479std::unique_ptr<TargetCodeGenInfo>
481 return std::make_unique<SparcV8TargetCodeGenInfo>(CGM.
getTypes());
484std::unique_ptr<TargetCodeGenInfo>
486 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()
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