10#include "TargetInfo.h"
34SparcV8ABIInfo::classifyReturnType(
QualType Ty)
const {
57 llvm::Value *
Address)
const override {
64 llvm::ConstantInt::get(CGF.
Int32Ty, Offset));
68 llvm::Value *
Address)
const override {
75 llvm::ConstantInt::get(CGF.
Int32Ty, Offset));
107class SparcV9ABIInfo :
public ABIInfo {
128 struct CoerceBuilder {
129 llvm::LLVMContext &Context;
130 const llvm::DataLayout &DL;
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:
185 addStruct(ElemOffset, cast<llvm::StructType>(ElemTy));
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 {
215 llvm::Type *getType()
const {
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(Ty,
false);
239 Ty = EnumTy->getDecl()->getIntegerType();
242 if (Size < 64 && Ty->isIntegerType())
246 if (EIT->getNumBits() < 64)
260 llvm::StructType *StrTy = dyn_cast<llvm::StructType>(CGT.ConvertType(Ty));
264 CoerceBuilder CB(getVMContext(), getDataLayout());
265 CB.addStruct(0, StrTy);
268 CB.pad(llvm::alignTo(
269 std::max(CB.DL.getTypeSizeInBits(StrTy).getKnownMinValue(),
uint64_t(1)),
273 llvm::Type *CoerceTy = CB.isUsableType(StrTy) ? StrTy : CB.getType();
284 llvm::Type *ArgTy = CGT.ConvertType(Ty);
295 auto TypeInfo = getContext().getTypeInfoInChars(Ty);
303 llvm_unreachable(
"Unsupported ABI kind for va_arg");
308 ArgAddr = Builder.CreateConstInBoundsByteGEP(Addr, Offset,
"extend");
313 auto AllocSize = getDataLayout().getTypeAllocSize(AI.
getCoerceToType());
323 ArgAddr =
Address(Builder.CreateLoad(ArgAddr,
"indirect.arg"), ArgTy,
332 Address NextPtr = Builder.CreateConstInBoundsByteGEP(Addr, Stride,
"ap.next");
356 llvm::Value *
Address)
const override;
359 llvm::Value *
Address)
const override {
361 llvm::ConstantInt::get(CGF.
Int32Ty, 8));
365 llvm::Value *
Address)
const override {
367 llvm::ConstantInt::get(CGF.
Int32Ty, -8));
380 llvm::IntegerType *i8 = CGF.
Int8Ty;
381 llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
382 llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
406std::unique_ptr<TargetCodeGenInfo>
408 return std::make_unique<SparcV8TargetCodeGenInfo>(CGM.
getTypes());
411std::unique_ptr<TargetCodeGenInfo>
413 return std::make_unique<SparcV9TargetCodeGenInfo>(CGM.
getTypes());
static ABIArgInfo classifyType(CodeGenModule &CGM, CanQualType type, bool forReturn)
__device__ __2f16 float c
A fixed int type of a specified bitwidth.
CharUnits - This is an opaque type for sizes expressed in character units.
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.
@ 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)
ABIInfo - Target specific hooks for defining how a type should be passed or returned from functions.
virtual RValue EmitVAArg(CodeGen::CodeGenFunction &CGF, CodeGen::Address VAListAddr, QualType Ty, AggValueSlot Slot) const =0
EmitVAArg - Emit the target dependent code to load a value of.
virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const =0
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
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.
CGFunctionInfo - Class to encapsulate the information about a function definition.
ABIArgInfo & getReturnInfo()
CanQualType getReturnType() const
MutableArrayRef< ArgInfo > arguments()
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
const CGFunctionInfo * CurFnInfo
RValue EmitLoadOfAnyValue(LValue V, AggValueSlot Slot=AggValueSlot::ignored(), SourceLocation Loc={})
Like EmitLoadOfLValue but also handles complex and aggregate types.
This class organizes the cross-function state that is used while generating LLVM code.
CodeGenTypes & getTypes()
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
DefaultABIInfo - The default implementation for ABI specific details.
ABIArgInfo classifyReturnType(QualType RetTy) const
void computeInfo(CGFunctionInfo &FI) const override
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...
virtual llvm::Value * encodeReturnAddress(CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const
Performs the code-generation required to convert the address of an instruction into a return address ...
virtual llvm::Value * decodeReturnAddress(CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const
Performs the code-generation required to convert a return address as stored by the system into the ac...
virtual bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const
Initializes the given DWARF EH register-size table, a char*.
virtual int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const
Determines the DWARF register number for the stack pointer, for exception-handling purposes.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
A (possibly-)qualified type.
bool isAnyComplexType() const
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.
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * Int32Ty
llvm::PointerType * UnqualPtrTy