10#include "TargetInfo.h"
24 SparcV8ABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}
28 void computeInfo(CGFunctionInfo &FI)
const override;
34SparcV8ABIInfo::classifyReturnType(
QualType Ty)
const {
43void SparcV8ABIInfo::computeInfo(CGFunctionInfo &FI)
const {
51class SparcV8TargetCodeGenInfo :
public TargetCodeGenInfo {
53 SparcV8TargetCodeGenInfo(CodeGenTypes &CGT)
54 : TargetCodeGenInfo(std::make_unique<SparcV8ABIInfo>(CGT)) {}
56 llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
57 llvm::Value *Address)
const override {
64 llvm::ConstantInt::get(CGF.
Int32Ty, Offset));
67 llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
68 llvm::Value *Address)
const override {
75 llvm::ConstantInt::get(CGF.
Int32Ty, Offset));
107class SparcV9ABIInfo :
public ABIInfo {
109 SparcV9ABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {}
112 ABIArgInfo
classifyType(QualType RetTy,
unsigned SizeLimit)
const;
113 void computeInfo(CGFunctionInfo &FI)
const override;
114 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
115 AggValueSlot Slot)
const override;
128 struct CoerceBuilder {
129 llvm::LLVMContext &Context;
130 const llvm::DataLayout &DL;
131 SmallVector<llvm::Type*, 8> Elems;
135 CoerceBuilder(llvm::LLVMContext &
c,
const llvm::DataLayout &dl)
136 : Context(
c), DL(dl),
Size(0), InReg(
false) {}
139 void pad(uint64_t ToSize) {
140 assert(ToSize >= Size &&
"Cannot remove elements");
145 uint64_t Aligned = llvm::alignTo(Size, 64);
146 if (Aligned > Size && Aligned <= ToSize) {
147 Elems.push_back(llvm::IntegerType::get(Context, Aligned - Size));
152 while (Size + 64 <= ToSize) {
153 Elems.push_back(llvm::Type::getInt64Ty(Context));
159 Elems.push_back(llvm::IntegerType::get(Context, ToSize - Size));
165 void addFloat(uint64_t Offset, llvm::Type *Ty,
unsigned Bits) {
174 Size = Offset + Bits;
178 void addStruct(uint64_t Offset, llvm::StructType *StrTy) {
179 const llvm::StructLayout *Layout = DL.getStructLayout(StrTy);
180 for (
unsigned i = 0, e = StrTy->getNumElements(); i != e; ++i) {
181 llvm::Type *ElemTy = StrTy->getElementType(i);
182 uint64_t ElemOffset = Offset + Layout->getElementOffsetInBits(i);
183 switch (ElemTy->getTypeID()) {
184 case llvm::Type::StructTyID:
187 case llvm::Type::FloatTyID:
188 addFloat(ElemOffset, ElemTy, 32);
190 case llvm::Type::DoubleTyID:
191 addFloat(ElemOffset, ElemTy, 64);
193 case llvm::Type::FP128TyID:
194 addFloat(ElemOffset, ElemTy, 128);
196 case llvm::Type::PointerTyID:
197 if (ElemOffset % 64 == 0) {
199 Elems.push_back(ElemTy);
210 bool isUsableType(llvm::StructType *Ty)
const {
211 return llvm::ArrayRef(Elems) == Ty->elements();
216 if (Elems.size() == 1)
217 return Elems.front();
219 return llvm::StructType::get(Context, Elems);
226SparcV9ABIInfo::classifyType(QualType Ty,
unsigned SizeLimit)
const {
234 if (Size > SizeLimit)
235 return getNaturalAlignIndirect(
236 Ty, getDataLayout().getAllocaAddrSpace(),
241 Ty = ED->getIntegerType();
244 if (Size < 64 && Ty->isIntegerType())
247 if (
const auto *EIT = Ty->
getAs<BitIntType>())
248 if (EIT->getNumBits() < 64)
258 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
263 llvm::StructType *StrTy = dyn_cast<llvm::StructType>(CGT.ConvertType(Ty));
267 CoerceBuilder CB(getVMContext(), getDataLayout());
268 CB.addStruct(0, StrTy);
271 CB.pad(llvm::alignTo(
272 std::max(CB.DL.getTypeSizeInBits(StrTy).getKnownMinValue(),
uint64_t(1)),
276 llvm::Type *CoerceTy = CB.isUsableType(StrTy) ? StrTy : CB.getType();
284RValue SparcV9ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
285 QualType Ty, AggValueSlot Slot)
const {
287 llvm::Type *ArgTy = CGT.ConvertType(Ty);
293 CGBuilderTy &Builder = CGF.
Builder;
294 Address
Addr = Address(Builder.CreateLoad(VAListAddr,
"ap.cur"),
298 auto TypeInfo = getContext().getTypeInfoInChars(Ty);
307 llvm_unreachable(
"Unsupported ABI kind for va_arg");
311 CharUnits Offset = SlotSize - TypeInfo.Width;
312 ArgAddr = Builder.CreateConstInBoundsByteGEP(
Addr, Offset,
"extend");
317 auto AllocSize = getDataLayout().getTypeAllocSize(AI.
getCoerceToType());
327 ArgAddr = Address(Builder.CreateLoad(ArgAddr,
"indirect.arg"), ArgTy,
336 Address NextPtr = Builder.CreateConstInBoundsByteGEP(
Addr, Stride,
"ap.next");
343void SparcV9ABIInfo::computeInfo(CGFunctionInfo &FI)
const {
350class SparcV9TargetCodeGenInfo :
public TargetCodeGenInfo {
352 SparcV9TargetCodeGenInfo(CodeGenTypes &CGT)
353 : TargetCodeGenInfo(std::make_unique<SparcV9ABIInfo>(CGT)) {}
355 int getDwarfEHStackPointer(CodeGen::CodeGenModule &M)
const override {
359 bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
360 llvm::Value *Address)
const override;
362 llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
363 llvm::Value *Address)
const override {
365 llvm::ConstantInt::get(CGF.
Int32Ty, 8));
368 llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
369 llvm::Value *Address)
const override {
371 llvm::ConstantInt::get(CGF.
Int32Ty, -8));
377SparcV9TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
378 llvm::Value *Address)
const {
382 CodeGen::CGBuilderTy &Builder = CGF.
Builder;
384 llvm::IntegerType *i8 = CGF.
Int8Ty;
385 llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
386 llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
410std::unique_ptr<TargetCodeGenInfo>
412 return std::make_unique<SparcV8TargetCodeGenInfo>(CGM.
getTypes());
415std::unique_ptr<TargetCodeGenInfo>
417 return std::make_unique<SparcV9TargetCodeGenInfo>(CGM.
getTypes());
static ABIArgInfo classifyType(CodeGenModule &CGM, CanQualType type, bool forReturn)
__device__ __2f16 float c
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
static ABIArgInfo getIgnore()
void setCoerceToType(llvm::Type *T)
static ABIArgInfo getDirect(llvm::Type *T=nullptr, unsigned Offset=0, llvm::Type *Padding=nullptr, bool CanBeFlattened=true, unsigned Align=0)
@ Extend
Extend - Valid only for integer argument types.
@ Ignore
Ignore - Ignore the argument (treat as void).
@ IndirectAliased
IndirectAliased - Similar to Indirect, but the pointer may be to an object that is otherwise referenc...
@ Expand
Expand - Only valid for aggregate argument types.
@ TargetSpecific
TargetSpecific - Some argument types are passed as target specific types such as RISC-V's tuple type,...
@ InAlloca
InAlloca - Pass the argument directly using the LLVM inalloca attribute.
@ Indirect
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
@ CoerceAndExpand
CoerceAndExpand - Only valid for aggregate argument types.
@ Direct
Direct - Pass the argument directly using the normal converted LLVM type, or by coercing to another s...
static ABIArgInfo getExtend(QualType Ty, llvm::Type *T=nullptr)
llvm::Type * getCoerceToType() const
bool canHaveCoerceToType() const
static ABIArgInfo getDirectInReg(llvm::Type *T=nullptr)
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
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()
RValue EmitLoadOfAnyValue(LValue V, AggValueSlot Slot=AggValueSlot::ignored(), SourceLocation Loc={})
Like EmitLoadOfLValue but also handles complex and aggregate types.
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
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)
bool isAggregateTypeForABI(QualType T)
llvm::Type * getVAListElementType(CodeGenFunction &CGF)
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.
U cast(CodeGen::Address addr)
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * Int32Ty
llvm::PointerType * UnqualPtrTy