10#include "TargetInfo.h"
25 SparcV8ABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}
29 void computeInfo(CGFunctionInfo &FI)
const override;
35SparcV8ABIInfo::classifyReturnType(
QualType Ty)
const {
44void SparcV8ABIInfo::computeInfo(CGFunctionInfo &FI)
const {
52class SparcV8TargetCodeGenInfo :
public TargetCodeGenInfo {
54 SparcV8TargetCodeGenInfo(CodeGenTypes &CGT)
55 : TargetCodeGenInfo(std::make_unique<SparcV8ABIInfo>(CGT)) {}
57 llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
58 llvm::Value *Address)
const override {
65 llvm::ConstantInt::get(CGF.
Int32Ty, Offset));
68 llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
69 llvm::Value *Address)
const override {
76 llvm::ConstantInt::get(CGF.
Int32Ty, Offset));
108class SparcV9ABIInfo :
public ABIInfo {
110 SparcV9ABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {}
113 ABIArgInfo
classifyType(QualType RetTy,
unsigned SizeLimit,
114 unsigned &RegOffset)
const;
115 void computeInfo(CGFunctionInfo &FI)
const override;
116 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
117 AggValueSlot Slot)
const override;
130 struct CoerceBuilder {
131 llvm::LLVMContext &Context;
132 const llvm::DataLayout &DL;
133 SmallVector<llvm::Type*, 8> Elems;
137 CoerceBuilder(llvm::LLVMContext &
c,
const llvm::DataLayout &dl)
138 : Context(
c), DL(dl),
Size(0), InReg(
false) {}
141 void pad(uint64_t ToSize) {
142 assert(ToSize >= Size &&
"Cannot remove elements");
147 uint64_t Aligned = llvm::alignTo(Size, 64);
148 if (Aligned > Size && Aligned <= ToSize) {
149 Elems.push_back(llvm::IntegerType::get(Context, Aligned - Size));
154 while (Size + 64 <= ToSize) {
155 Elems.push_back(llvm::Type::getInt64Ty(Context));
161 Elems.push_back(llvm::IntegerType::get(Context, ToSize - Size));
167 void addFloat(uint64_t Offset, llvm::Type *Ty,
unsigned Bits) {
176 Size = Offset + Bits;
180 void addStruct(uint64_t Offset, llvm::StructType *StrTy) {
181 const llvm::StructLayout *Layout = DL.getStructLayout(StrTy);
182 for (
unsigned i = 0, e = StrTy->getNumElements(); i != e; ++i) {
183 llvm::Type *ElemTy = StrTy->getElementType(i);
184 uint64_t ElemOffset = Offset + Layout->getElementOffsetInBits(i);
185 switch (ElemTy->getTypeID()) {
186 case llvm::Type::StructTyID:
189 case llvm::Type::FloatTyID:
190 addFloat(ElemOffset, ElemTy, 32);
192 case llvm::Type::DoubleTyID:
193 addFloat(ElemOffset, ElemTy, 64);
195 case llvm::Type::FP128TyID:
196 addFloat(ElemOffset, ElemTy, 128);
198 case llvm::Type::PointerTyID:
199 if (ElemOffset % 64 == 0) {
201 Elems.push_back(ElemTy);
212 bool isUsableType(llvm::StructType *Ty)
const {
213 return llvm::ArrayRef(Elems) == Ty->elements();
218 if (Elems.size() == 1)
219 return Elems.front();
221 return llvm::StructType::get(Context, Elems);
227ABIArgInfo SparcV9ABIInfo::classifyType(QualType Ty,
unsigned SizeLimit,
228 unsigned &RegOffset)
const {
232 auto &Context = getContext();
233 auto &VMContext = getVMContext();
237 bool NeedPadding = (Alignment > 64) && (RegOffset % 2 != 0);
241 if (Size > SizeLimit) {
243 return getNaturalAlignIndirect(
244 Ty, getDataLayout().getAllocaAddrSpace(),
250 Ty = ED->getIntegerType();
253 if (Size < 64 && Ty->isIntegerType()) {
258 if (
const auto *EIT = Ty->
getAs<BitIntType>())
259 if (EIT->getNumBits() < 64) {
266 RegOffset +=
Size / 64;
274 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
280 llvm::StructType *StrTy = dyn_cast<llvm::StructType>(CGT.ConvertType(Ty));
282 RegOffset +=
Size / 64;
286 CoerceBuilder CB(VMContext, getDataLayout());
287 CB.addStruct(0, StrTy);
290 CB.pad(llvm::alignTo(
291 std::max(CB.DL.getTypeSizeInBits(StrTy).getKnownMinValue(),
uint64_t(1)),
293 RegOffset += CB.Size / 64;
299 llvm::Type *Padding =
300 NeedPadding ? llvm::Type::getInt64Ty(VMContext) :
nullptr;
301 RegOffset += NeedPadding ? 1 : 0;
304 llvm::Type *CoerceTy = CB.isUsableType(StrTy) ? StrTy : CB.getType();
311RValue SparcV9ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
312 QualType Ty, AggValueSlot Slot)
const {
314 auto TInfo = getContext().getTypeInfoInChars(Ty);
321 TInfo.Width > 2 * SlotSize, TInfo,
326void SparcV9ABIInfo::computeInfo(CGFunctionInfo &FI)
const {
327 unsigned RetOffset = 0;
332 unsigned ArgOffset = RetType.
isIndirect() ? RetOffset : 0;
338class SparcV9TargetCodeGenInfo :
public TargetCodeGenInfo {
340 SparcV9TargetCodeGenInfo(CodeGenTypes &CGT)
341 : TargetCodeGenInfo(std::make_unique<SparcV9ABIInfo>(CGT)) {}
343 int getDwarfEHStackPointer(CodeGen::CodeGenModule &M)
const override {
347 bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
348 llvm::Value *Address)
const override;
350 llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
351 llvm::Value *Address)
const override {
353 llvm::ConstantInt::get(CGF.
Int32Ty, 8));
356 llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
357 llvm::Value *Address)
const override {
359 llvm::ConstantInt::get(CGF.
Int32Ty, -8));
365SparcV9TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
366 llvm::Value *Address)
const {
370 CodeGen::CGBuilderTy &Builder = CGF.
Builder;
372 llvm::IntegerType *i8 = CGF.
Int8Ty;
373 llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
374 llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
398std::unique_ptr<TargetCodeGenInfo>
400 return std::make_unique<SparcV8TargetCodeGenInfo>(CGM.
getTypes());
403std::unique_ptr<TargetCodeGenInfo>
405 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)
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 classifyReturnType(QualType RetTy) const
A (possibly-)qualified type.
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)
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