10#include "TargetInfo.h"
21class MipsABIInfo :
public ABIInfo {
23 const unsigned MinABIStackAlignInBytes, StackAlignInBytes;
24 void CoerceToIntArgs(uint64_t TySize,
26 llvm::Type* HandleAggregates(
QualType Ty, uint64_t TySize)
const;
27 llvm::Type* returnAggregateInRegs(
QualType RetTy, uint64_t Size)
const;
28 llvm::Type* getPaddingType(uint64_t Align, uint64_t Offset)
const;
31 ABIInfo(CGT), IsO32(_IsO32), MinABIStackAlignInBytes(IsO32 ? 4 : 8),
32 StackAlignInBytes(IsO32 ? 8 : 16) {}
43 unsigned SizeOfUnwindException;
47 SizeOfUnwindException(IsO32 ? 24 : 32) {}
57 llvm::Function *
Fn = cast<llvm::Function>(GV);
59 if (FD->
hasAttr<MipsLongCallAttr>())
60 Fn->addFnAttr(
"long-call");
61 else if (FD->
hasAttr<MipsShortCallAttr>())
62 Fn->addFnAttr(
"short-call");
65 if (GV->isDeclaration())
68 if (FD->
hasAttr<Mips16Attr>()) {
69 Fn->addFnAttr(
"mips16");
71 else if (FD->
hasAttr<NoMips16Attr>()) {
72 Fn->addFnAttr(
"nomips16");
75 if (FD->
hasAttr<MicroMipsAttr>())
76 Fn->addFnAttr(
"micromips");
77 else if (FD->
hasAttr<NoMicroMipsAttr>())
78 Fn->addFnAttr(
"nomicromips");
80 const MipsInterruptAttr *
Attr = FD->
getAttr<MipsInterruptAttr>();
85 switch (
Attr->getInterrupt()) {
86 case MipsInterruptAttr::eic:
Kind =
"eic";
break;
87 case MipsInterruptAttr::sw0:
Kind =
"sw0";
break;
88 case MipsInterruptAttr::sw1:
Kind =
"sw1";
break;
89 case MipsInterruptAttr::hw0:
Kind =
"hw0";
break;
90 case MipsInterruptAttr::hw1:
Kind =
"hw1";
break;
91 case MipsInterruptAttr::hw2:
Kind =
"hw2";
break;
92 case MipsInterruptAttr::hw3:
Kind =
"hw3";
break;
93 case MipsInterruptAttr::hw4:
Kind =
"hw4";
break;
94 case MipsInterruptAttr::hw5:
Kind =
"hw5";
break;
97 Fn->addFnAttr(
"interrupt", Kind);
102 llvm::Value *
Address)
const override;
105 return SizeOfUnwindException;
110void MipsABIInfo::CoerceToIntArgs(
112 llvm::IntegerType *IntTy =
113 llvm::IntegerType::get(getVMContext(), MinABIStackAlignInBytes * 8);
116 for (
unsigned N = TySize / (MinABIStackAlignInBytes * 8); N; --N)
117 ArgList.push_back(IntTy);
120 unsigned R = TySize % (MinABIStackAlignInBytes * 8);
123 ArgList.push_back(llvm::IntegerType::get(getVMContext(), R));
128llvm::Type* MipsABIInfo::HandleAggregates(
QualType Ty, uint64_t TySize)
const {
132 CoerceToIntArgs(TySize, ArgList);
133 return llvm::StructType::get(getVMContext(), ArgList);
137 return CGT.ConvertType(Ty);
143 CoerceToIntArgs(TySize, ArgList);
144 return llvm::StructType::get(getVMContext(), ArgList);
149 assert(!(TySize % 8) &&
"Size of structure must be multiple of 8.");
153 llvm::IntegerType *I64 = llvm::IntegerType::get(getVMContext(), 64);
158 i != e; ++i, ++idx) {
162 if (!BT || BT->
getKind() != BuiltinType::Double)
170 for (
unsigned j = (Offset - LastOffset) / 64; j > 0; --j)
171 ArgList.push_back(I64);
174 ArgList.push_back(llvm::Type::getDoubleTy(getVMContext()));
175 LastOffset = Offset + 64;
178 CoerceToIntArgs(TySize - LastOffset, IntArgList);
179 ArgList.append(IntArgList.begin(), IntArgList.end());
181 return llvm::StructType::get(getVMContext(), ArgList);
184llvm::Type *MipsABIInfo::getPaddingType(uint64_t OrigOffset,
185 uint64_t Offset)
const {
186 if (OrigOffset + MinABIStackAlignInBytes > Offset)
189 return llvm::IntegerType::get(getVMContext(), (Offset - OrigOffset) * 8);
193MipsABIInfo::classifyArgumentType(
QualType Ty, uint64_t &Offset)
const {
197 uint64_t TySize = getContext().getTypeSize(Ty);
198 uint64_t Align = getContext().getTypeAlign(Ty) / 8;
200 Align = std::clamp(Align, (uint64_t)MinABIStackAlignInBytes,
201 (uint64_t)StackAlignInBytes);
202 unsigned CurrOffset = llvm::alignTo(Offset, Align);
203 Offset = CurrOffset + llvm::alignTo(TySize, Align * 8) / 8;
211 Offset = OrigOffset + MinABIStackAlignInBytes;
220 getPaddingType(OrigOffset, CurrOffset));
227 Ty = EnumTy->getDecl()->getIntegerType();
231 if (EIT->getNumBits() > 128 ||
232 (EIT->getNumBits() > 64 &&
233 !getContext().getTargetInfo().hasInt128Type()))
234 return getNaturalAlignIndirect(Ty);
238 return extendType(Ty);
241 nullptr, 0, IsO32 ?
nullptr : getPaddingType(OrigOffset, CurrOffset));
245MipsABIInfo::returnAggregateInRegs(
QualType RetTy, uint64_t Size)
const {
265 for (;
b != e; ++
b) {
271 RTList.push_back(CGT.ConvertType(
b->getType()));
275 return llvm::StructType::get(getVMContext(), RTList,
282 CoerceToIntArgs(Size, RTList);
283 return llvm::StructType::get(getVMContext(), RTList);
294 if (!IsO32 && Size == 0)
313 return getNaturalAlignIndirect(RetTy);
318 RetTy = EnumTy->getDecl()->getIntegerType();
322 if (EIT->getNumBits() > 128 ||
323 (EIT->getNumBits() > 64 &&
324 !getContext().getTargetInfo().hasInt128Type()))
325 return getNaturalAlignIndirect(RetTy);
327 if (isPromotableIntegerTypeForABI(RetTy))
355 unsigned SlotSizeInBits = IsO32 ? 32 : 64;
356 unsigned PtrWidth = getTarget().getPointerWidth(LangAS::Default);
357 bool DidPromote =
false;
359 getContext().getIntWidth(Ty) < SlotSizeInBits) ||
362 Ty = getContext().getIntTypeForBitwidth(SlotSizeInBits,
366 auto TyInfo = getContext().getTypeInfoInChars(Ty);
377 ArgSlotSize,
true, Slot);
387 llvm::Value *
V = CGF.
Builder.CreateTrunc(Promoted, IntTy);
389 V = CGF.
Builder.CreateIntToPtr(
V, ValTy);
398 int TySize = getContext().getTypeSize(Ty);
415 llvm::Value *Four8 = llvm::ConstantInt::get(CGF.
Int8Ty, 4);
435std::unique_ptr<TargetCodeGenInfo>
437 return std::make_unique<MIPSTargetCodeGenInfo>(CGM.
getTypes(), IsOS32);
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
Attr - This represents one attribute.
A fixed int type of a specified bitwidth.
This class is used for builtin types like 'int'.
bool isFloatingPoint() const
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.
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 getSignExtend(QualType Ty, 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 ...
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...
llvm::Type * ConvertType(QualType T)
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.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...
virtual unsigned getSizeOfUnwindException() const
Determines the size of struct _Unwind_Exception on this platform, in 8-bit units.
virtual bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const
Initializes the given DWARF EH register-size table, a char*.
virtual void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const
setTargetAttributes - Provides a convenient hook to handle extra target-specific attributes for the g...
virtual int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const
Determines the DWARF register number for the stack pointer, for exception-handling purposes.
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
Decl - This represents one declaration (or definition), e.g.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Represents a function declaration or definition.
A (possibly-)qualified type.
Represents a struct/union/class.
field_iterator field_end() const
field_iterator field_begin() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isAnyComplexType() const
bool hasFloatingRepresentation() const
Determine whether this type has a floating-point representation of some sort, e.g....
bool isStructureOrClassType() const
bool isVectorType() 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)
std::unique_ptr< TargetCodeGenInfo > createMIPSTargetCodeGenInfo(CodeGenModule &CGM, bool IsOS32)
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)
QualType useFirstFieldIfTransparentUnion(QualType Ty)
Pass transparent unions as if they were the type of the first element.
The JSON file list parser is used to communicate input to InstallAPI.
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * IntPtrTy