10#include "TargetInfo.h"
25 SparcV8ABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}
30 void computeInfo(CGFunctionInfo &FI)
const override;
35 const auto *CT = Ty->
getAs<ComplexType>();
36 const auto *BT = Ty->
getAs<BuiltinType>();
39 bool IsLongDouble = BT && BT->getKind() == BuiltinType::LongDouble;
44 : ABIArgInfo::getDirect();
47 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
53ABIArgInfo SparcV8ABIInfo::classifyArgumentType(QualType Ty)
const {
54 if (
const auto *BT = Ty->
getAs<BuiltinType>();
55 BT && BT->getKind() == BuiltinType::LongDouble)
56 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
61void SparcV8ABIInfo::computeInfo(CGFunctionInfo &FI)
const {
68class SparcV8TargetCodeGenInfo :
public TargetCodeGenInfo {
70 SparcV8TargetCodeGenInfo(CodeGenTypes &CGT)
71 : TargetCodeGenInfo(std::make_unique<SparcV8ABIInfo>(CGT)) {}
73 llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
74 llvm::Value *Address)
const override {
81 llvm::ConstantInt::get(CGF.
Int32Ty, Offset));
84 llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
85 llvm::Value *Address)
const override {
92 llvm::ConstantInt::get(CGF.
Int32Ty, Offset));
124class SparcV9ABIInfo :
public ABIInfo {
126 SparcV9ABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {}
129 ABIArgInfo
classifyType(QualType RetTy,
unsigned SizeLimit,
130 unsigned &RegOffset)
const;
131 void computeInfo(CGFunctionInfo &FI)
const override;
132 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
133 AggValueSlot Slot)
const override;
146 struct CoerceBuilder {
147 llvm::LLVMContext &Context;
148 const llvm::DataLayout &DL;
149 SmallVector<llvm::Type*, 8> Elems;
153 CoerceBuilder(llvm::LLVMContext &
c,
const llvm::DataLayout &dl)
154 : Context(
c), DL(dl),
Size(0), InReg(
false) {}
157 void pad(uint64_t ToSize) {
158 assert(ToSize >= Size &&
"Cannot remove elements");
163 uint64_t Aligned = llvm::alignTo(Size, 64);
164 if (Aligned > Size && Aligned <= ToSize) {
165 Elems.push_back(llvm::IntegerType::get(Context, Aligned - Size));
170 while (Size + 64 <= ToSize) {
171 Elems.push_back(llvm::Type::getInt64Ty(Context));
177 Elems.push_back(llvm::IntegerType::get(Context, ToSize - Size));
183 void addFloat(uint64_t Offset, llvm::Type *Ty,
unsigned Bits) {
192 Size = Offset + Bits;
196 void addStruct(uint64_t Offset, llvm::StructType *StrTy) {
197 const llvm::StructLayout *Layout = DL.getStructLayout(StrTy);
198 for (
unsigned i = 0, e = StrTy->getNumElements(); i != e; ++i) {
199 llvm::Type *ElemTy = StrTy->getElementType(i);
200 uint64_t ElemOffset = Offset + Layout->getElementOffsetInBits(i);
201 switch (ElemTy->getTypeID()) {
202 case llvm::Type::StructTyID:
205 case llvm::Type::FloatTyID:
206 addFloat(ElemOffset, ElemTy, 32);
208 case llvm::Type::DoubleTyID:
209 addFloat(ElemOffset, ElemTy, 64);
211 case llvm::Type::FP128TyID:
212 addFloat(ElemOffset, ElemTy, 128);
214 case llvm::Type::PointerTyID:
215 if (ElemOffset % 64 == 0) {
217 Elems.push_back(ElemTy);
228 bool isUsableType(llvm::StructType *Ty)
const {
229 return llvm::ArrayRef(Elems) == Ty->elements();
234 if (Elems.size() == 1)
235 return Elems.front();
237 return llvm::StructType::get(Context, Elems);
243ABIArgInfo SparcV9ABIInfo::classifyType(QualType Ty,
unsigned SizeLimit,
244 unsigned &RegOffset)
const {
248 auto &Context = getContext();
249 auto &VMContext = getVMContext();
253 bool NeedPadding = (Alignment > 64) && (RegOffset % 2 != 0);
257 if (Size > SizeLimit) {
259 return getNaturalAlignIndirect(
260 Ty, getDataLayout().getAllocaAddrSpace(),
266 Ty = ED->getIntegerType();
269 if (Size < 64 && Ty->isIntegerType()) {
274 if (
const auto *EIT = Ty->
getAs<BitIntType>())
275 if (EIT->getNumBits() < 64) {
282 RegOffset +=
Size / 64;
290 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
296 llvm::StructType *StrTy = dyn_cast<llvm::StructType>(CGT.ConvertType(Ty));
298 RegOffset +=
Size / 64;
302 CoerceBuilder CB(VMContext, getDataLayout());
303 CB.addStruct(0, StrTy);
306 CB.pad(llvm::alignTo(
307 std::max(CB.DL.getTypeSizeInBits(StrTy).getKnownMinValue(),
uint64_t(1)),
309 RegOffset += CB.Size / 64;
315 llvm::Type *Padding =
316 NeedPadding ? llvm::Type::getInt64Ty(VMContext) :
nullptr;
317 RegOffset += NeedPadding ? 1 : 0;
320 llvm::Type *CoerceTy = CB.isUsableType(StrTy) ? StrTy : CB.getType();
327RValue SparcV9ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
328 QualType Ty, AggValueSlot Slot)
const {
330 auto TInfo = getContext().getTypeInfoInChars(Ty);
337 TInfo.Width > 2 * SlotSize, TInfo,
342void SparcV9ABIInfo::computeInfo(CGFunctionInfo &FI)
const {
343 unsigned RetOffset = 0;
348 unsigned ArgOffset = RetType.
isIndirect() ? RetOffset : 0;
354class SparcV9TargetCodeGenInfo :
public TargetCodeGenInfo {
356 SparcV9TargetCodeGenInfo(CodeGenTypes &CGT)
357 : TargetCodeGenInfo(std::make_unique<SparcV9ABIInfo>(CGT)) {}
359 int getDwarfEHStackPointer(CodeGen::CodeGenModule &M)
const override {
363 bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
364 llvm::Value *Address)
const override;
366 llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
367 llvm::Value *Address)
const override {
369 llvm::ConstantInt::get(CGF.
Int32Ty, 8));
372 llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
373 llvm::Value *Address)
const override {
375 llvm::ConstantInt::get(CGF.
Int32Ty, -8));
381SparcV9TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
382 llvm::Value *Address)
const {
386 CodeGen::CGBuilderTy &Builder = CGF.
Builder;
388 llvm::IntegerType *i8 = CGF.
Int8Ty;
389 llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
390 llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
414std::unique_ptr<TargetCodeGenInfo>
416 return std::make_unique<SparcV8TargetCodeGenInfo>(CGM.
getTypes());
419std::unique_ptr<TargetCodeGenInfo>
421 return std::make_unique<SparcV9TargetCodeGenInfo>(CGM.
getTypes());
static ABIArgInfo classifyType(CodeGenModule &CGM, CanQualType type, bool forReturn)
__device__ __2f16 float c
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)
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
QualType getElementType() const
A (possibly-)qualified type.
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)
The JSON file list parser is used to communicate input to InstallAPI.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
U cast(CodeGen::Address addr)
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * Int32Ty