10#include "TargetInfo.h"
53 if (GV->isDeclaration())
64 unsigned RegsLeft = 6;
72 assert(Size <= 64 &&
"Not expecting to pass arguments larger than 64 bits"
73 " through registers");
83 if (2 <= (*RegsLeft & (~1U))) {
84 *RegsLeft = (*RegsLeft & (~1U)) - 2;
97 unsigned *RegsLeft)
const {
101 Ty = EnumTy->getDecl()->getIntegerType();
108 return getNaturalAlignIndirect(Ty,
true);
122 unsigned Align = getContext().getTypeAlign(Ty);
125 return getNaturalAlignIndirect(Ty,
true);
128 Align =
Size <= 32 ? 32 : 64;
131 Size = llvm::bit_ceil(Size);
146 if (
T.hasFeature(
"hvx")) {
147 assert(
T.hasFeature(
"hvx-length64b") ||
T.hasFeature(
"hvx-length128b"));
148 uint64_t VecSize =
T.hasFeature(
"hvx-length64b") ? 64*8 : 128*8;
149 if (Size == VecSize || Size == 2*VecSize)
154 return getNaturalAlignIndirect(RetTy);
160 RetTy = EnumTy->getDecl()->getIntegerType();
163 return getNaturalAlignIndirect(RetTy,
false);
176 Size = llvm::bit_ceil(Size);
179 return getNaturalAlignIndirect(RetTy,
true);
186 Address __overflow_area_pointer_p =
189 __overflow_area_pointer_p,
"__overflow_area_pointer");
194 assert((Align & (Align - 1)) == 0 &&
"Alignment is not power of 2!");
197 llvm::Value *Offset = llvm::ConstantInt::get(CGF.
Int64Ty, Align - 1);
200 __overflow_area_pointer =
207 llvm::Value *Mask = llvm::ConstantInt::get(CGF.
Int32Ty, -(
int)Align);
208 __overflow_area_pointer = CGF.
Builder.CreateIntToPtr(
209 CGF.
Builder.CreateAnd(AsInt, Mask), __overflow_area_pointer->getType(),
210 "__overflow_area_pointer.align");
223 CGF.
Int8Ty, __overflow_area_pointer,
224 llvm::ConstantInt::get(CGF.
Int32Ty, Offset),
225 "__overflow_area_pointer.next");
238 llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP,
"ap.cur");
242 assert((TyAlign & (TyAlign - 1)) == 0 &&
"Alignment is not power of 2!");
243 llvm::Value *AddrAsInt = Builder.CreatePtrToInt(Addr, CGF.
Int32Ty);
244 AddrAsInt = Builder.CreateAdd(AddrAsInt, Builder.getInt32(TyAlign - 1));
245 AddrAsInt = Builder.CreateAnd(AddrAsInt, Builder.getInt32(~(TyAlign - 1)));
246 Addr = Builder.CreateIntToPtr(AddrAsInt, BP);
252 llvm::Value *NextAddr = Builder.CreateGEP(
253 CGF.
Int8Ty, Addr, llvm::ConstantInt::get(CGF.
Int32Ty, Offset),
"ap.next");
254 Builder.CreateStore(NextAddr, VAListAddrAsBPP);
265 return EmitVAArgFromMemory(CGF, VAListAddr, Ty);
271 unsigned RegsLeft = 6;
290 VAListAddr, 0,
"__current_saved_reg_area_pointer_p");
292 __current_saved_reg_area_pointer_p,
"__current_saved_reg_area_pointer");
296 VAListAddr, 1,
"__saved_reg_area_end_pointer_p");
298 __saved_reg_area_end_pointer_p,
"__saved_reg_area_end_pointer");
304 llvm::Value *__current_saved_reg_area_pointer_int =
305 CGF.
Builder.CreatePtrToInt(__current_saved_reg_area_pointer,
308 __current_saved_reg_area_pointer_int = CGF.
Builder.CreateAdd(
309 __current_saved_reg_area_pointer_int,
310 llvm::ConstantInt::get(CGF.
Int32Ty, (ArgAlign - 1)),
311 "align_current_saved_reg_area_pointer");
313 __current_saved_reg_area_pointer_int =
314 CGF.
Builder.CreateAnd(__current_saved_reg_area_pointer_int,
315 llvm::ConstantInt::get(CGF.
Int32Ty, -ArgAlign),
316 "align_current_saved_reg_area_pointer");
318 __current_saved_reg_area_pointer =
319 CGF.
Builder.CreateIntToPtr(__current_saved_reg_area_pointer_int,
320 __current_saved_reg_area_pointer->getType(),
321 "align_current_saved_reg_area_pointer");
324 llvm::Value *__new_saved_reg_area_pointer =
326 llvm::ConstantInt::get(CGF.
Int32Ty, ArgSize),
327 "__new_saved_reg_area_pointer");
329 llvm::Value *UsingStack =
nullptr;
330 UsingStack = CGF.
Builder.CreateICmpSGT(__new_saved_reg_area_pointer,
331 __saved_reg_area_end_pointer);
333 CGF.
Builder.CreateCondBr(UsingStack, OnStackBlock, InRegBlock);
340 llvm::Value *__saved_reg_area_p = CGF.
Builder.CreateBitCast(
341 __current_saved_reg_area_pointer, llvm::PointerType::getUnqual(PTy));
344 __current_saved_reg_area_pointer_p);
353 Address __overflow_area_pointer_p =
356 __overflow_area_pointer_p,
"__overflow_area_pointer");
360 llvm::Value *__overflow_area_pointer_int =
363 __overflow_area_pointer_int =
364 CGF.
Builder.CreateAdd(__overflow_area_pointer_int,
365 llvm::ConstantInt::get(CGF.
Int32Ty, ArgAlign - 1),
366 "align_overflow_area_pointer");
368 __overflow_area_pointer_int =
369 CGF.
Builder.CreateAnd(__overflow_area_pointer_int,
370 llvm::ConstantInt::get(CGF.
Int32Ty, -ArgAlign),
371 "align_overflow_area_pointer");
373 __overflow_area_pointer = CGF.
Builder.CreateIntToPtr(
374 __overflow_area_pointer_int, __overflow_area_pointer->getType(),
375 "align_overflow_area_pointer");
381 CGF.
Int8Ty, __overflow_area_pointer,
382 llvm::ConstantInt::get(CGF.
Int32Ty, ArgSize),
383 "__overflow_area_pointer.next");
386 __overflow_area_pointer_p);
389 __current_saved_reg_area_pointer_p);
393 llvm::Value *__overflow_area_p = CGF.
Builder.CreateBitCast(
394 __overflow_area_pointer, llvm::PointerType::getUnqual(OverflowPTy));
403 llvm::Type *MemPTy = llvm::PointerType::getUnqual(MemTy);
404 llvm::PHINode *ArgAddr = CGF.
Builder.CreatePHI(MemPTy, 2,
"vaarg.addr");
405 ArgAddr->addIncoming(__saved_reg_area_p, InRegBlock);
406 ArgAddr->addIncoming(__overflow_area_p, OnStackBlock);
414 if (getTarget().getTriple().isMusl())
416 CGF.
MakeAddrLValue(EmitVAArgForHexagonLinux(CGF, VAListAddr, Ty), Ty),
420 CGF.
MakeAddrLValue(EmitVAArgForHexagon(CGF, VAListAddr, Ty), Ty), Slot);
423std::unique_ptr<TargetCodeGenInfo>
425 return std::make_unique<HexagonTargetCodeGenInfo>(CGM.
getTypes());
static bool HexagonAdjustRegsLeft(uint64_t Size, unsigned *RegsLeft)
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
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.
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
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)
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, 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...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
llvm::Type * ConvertTypeForMem(QualType T)
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
ASTContext & getContext() const
llvm::Type * ConvertType(QualType T)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
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 classifyArgumentType(QualType RetTy) const
RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, AggValueSlot Slot) const override
EmitVAArg - Emit the target dependent code to load a value of.
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 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.
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.
Exposes information about the current target.
bool isBitIntType() const
const T * getAs() const
Member-template getAs<specific type>'.
Represents a GCC generic vector 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 > createHexagonTargetCodeGenInfo(CodeGenModule &CGM)
bool isAggregateTypeForABI(QualType T)
bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, bool AsIfNoUniqueAddr=false)
isEmptyRecord - Return true iff a structure contains only empty fields.
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * Int32Ty
llvm::PointerType * Int8PtrTy