10#include "TargetInfo.h"
23 HexagonABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}
29 void computeInfo(CGFunctionInfo &FI)
const override;
31 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
32 AggValueSlot Slot)
const override;
33 Address EmitVAArgFromMemory(CodeGenFunction &CFG, Address VAListAddr,
35 Address EmitVAArgForHexagon(CodeGenFunction &CFG, Address VAListAddr,
37 Address EmitVAArgForHexagonLinux(CodeGenFunction &CFG, Address VAListAddr,
43 HexagonTargetCodeGenInfo(CodeGenTypes &CGT)
44 : TargetCodeGenInfo(std::make_unique<HexagonABIInfo>(CGT)) {}
46 int getDwarfEHStackPointer(CodeGen::CodeGenModule &M)
const override {
50 void setTargetAttributes(
const Decl *D, llvm::GlobalValue *GV,
51 CodeGen::CodeGenModule &GCM)
const override {
52 if (GV->isDeclaration())
54 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
63 unsigned RegsLeft = 6;
71 assert(Size <= 64 &&
"Not expecting to pass arguments larger than 64 bits"
72 " through registers");
82 if (2 <= (*RegsLeft & (~1U))) {
83 *RegsLeft = (*RegsLeft & (~1U)) - 2;
95ABIArgInfo HexagonABIInfo::classifyArgumentType(QualType Ty,
96 unsigned *RegsLeft)
const {
100 Ty = ED->getIntegerType();
107 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
111 : ABIArgInfo::getDirect();
115 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
123 unsigned Align = getContext().getTypeAlign(Ty);
126 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
130 Align =
Size <= 32 ? 32 : 64;
133 Size = llvm::bit_ceil(Size);
139ABIArgInfo HexagonABIInfo::classifyReturnType(QualType RetTy)
const {
143 const TargetInfo &
T = CGT.getTarget();
146 if (RetTy->
getAs<VectorType>()) {
148 if (
T.hasFeature(
"hvx")) {
149 assert(
T.hasFeature(
"hvx-length64b") ||
T.hasFeature(
"hvx-length128b"));
150 uint64_t VecSize =
T.hasFeature(
"hvx-length64b") ? 64*8 : 128*8;
151 if (Size == VecSize || Size == 2*VecSize)
156 return getNaturalAlignIndirect(RetTy,
157 getDataLayout().getAllocaAddrSpace());
163 RetTy = ED->getIntegerType();
166 return getNaturalAlignIndirect(
167 RetTy, getDataLayout().getAllocaAddrSpace(),
false);
170 : ABIArgInfo::getDirect();
180 Size = llvm::bit_ceil(Size);
183 return getNaturalAlignIndirect(RetTy, getDataLayout().getAllocaAddrSpace(),
187Address HexagonABIInfo::EmitVAArgFromMemory(CodeGenFunction &CGF,
191 Address __overflow_area_pointer_p =
194 __overflow_area_pointer_p,
"__overflow_area_pointer");
199 assert((Align & (Align - 1)) == 0 &&
"Alignment is not power of 2!");
202 llvm::Value *Offset = llvm::ConstantInt::get(CGF.
Int64Ty, Align - 1);
205 __overflow_area_pointer =
212 llvm::Value *Mask = llvm::ConstantInt::getSigned(CGF.
Int32Ty, -(
int)Align);
213 __overflow_area_pointer = CGF.
Builder.CreateIntToPtr(
214 CGF.
Builder.CreateAnd(AsInt, Mask), __overflow_area_pointer->getType(),
215 "__overflow_area_pointer.align");
228 CGF.
Int8Ty, __overflow_area_pointer,
229 llvm::ConstantInt::get(CGF.
Int32Ty, Offset),
230 "__overflow_area_pointer.next");
236Address HexagonABIInfo::EmitVAArgForHexagon(CodeGenFunction &CGF,
241 CGBuilderTy &Builder = CGF.
Builder;
243 llvm::Value *
Addr = Builder.CreateLoad(VAListAddrAsBPP,
"ap.cur");
247 assert((TyAlign & (TyAlign - 1)) == 0 &&
"Alignment is not power of 2!");
248 llvm::Value *AddrAsInt = Builder.CreatePtrToInt(
Addr, CGF.
Int32Ty);
249 AddrAsInt = Builder.CreateAdd(AddrAsInt, Builder.getInt32(TyAlign - 1));
250 AddrAsInt = Builder.CreateAnd(AddrAsInt, Builder.getInt32(~(TyAlign - 1)));
251 Addr = Builder.CreateIntToPtr(AddrAsInt, BP);
257 llvm::Value *NextAddr = Builder.CreateGEP(
259 Builder.CreateStore(NextAddr, VAListAddrAsBPP);
264Address HexagonABIInfo::EmitVAArgForHexagonLinux(CodeGenFunction &CGF,
270 return EmitVAArgFromMemory(CGF, VAListAddr, Ty);
276 unsigned RegsLeft = 6;
287 ArgSize = (CGF.
getContext().getTypeSize(Ty) <= 32) ? 4 : 8;
288 int ArgAlign = (CGF.
getContext().getTypeSize(Ty) <= 32) ? 4 : 8;
295 VAListAddr, 0,
"__current_saved_reg_area_pointer_p");
297 __current_saved_reg_area_pointer_p,
"__current_saved_reg_area_pointer");
301 VAListAddr, 1,
"__saved_reg_area_end_pointer_p");
303 __saved_reg_area_end_pointer_p,
"__saved_reg_area_end_pointer");
309 llvm::Value *__current_saved_reg_area_pointer_int =
310 CGF.
Builder.CreatePtrToInt(__current_saved_reg_area_pointer,
313 __current_saved_reg_area_pointer_int = CGF.
Builder.CreateAdd(
314 __current_saved_reg_area_pointer_int,
315 llvm::ConstantInt::get(CGF.
Int32Ty, (ArgAlign - 1)),
316 "align_current_saved_reg_area_pointer");
318 __current_saved_reg_area_pointer_int = CGF.
Builder.CreateAnd(
319 __current_saved_reg_area_pointer_int,
320 llvm::ConstantInt::getSigned(CGF.
Int32Ty, -ArgAlign),
321 "align_current_saved_reg_area_pointer");
323 __current_saved_reg_area_pointer =
324 CGF.
Builder.CreateIntToPtr(__current_saved_reg_area_pointer_int,
325 __current_saved_reg_area_pointer->getType(),
326 "align_current_saved_reg_area_pointer");
329 llvm::Value *__new_saved_reg_area_pointer =
331 llvm::ConstantInt::get(CGF.
Int32Ty, ArgSize),
332 "__new_saved_reg_area_pointer");
334 llvm::Value *UsingStack =
nullptr;
335 UsingStack = CGF.
Builder.CreateICmpSGT(__new_saved_reg_area_pointer,
336 __saved_reg_area_end_pointer);
338 CGF.
Builder.CreateCondBr(UsingStack, OnStackBlock, InRegBlock);
345 __current_saved_reg_area_pointer_p);
354 Address __overflow_area_pointer_p =
357 __overflow_area_pointer_p,
"__overflow_area_pointer");
361 llvm::Value *__overflow_area_pointer_int =
364 __overflow_area_pointer_int =
365 CGF.
Builder.CreateAdd(__overflow_area_pointer_int,
366 llvm::ConstantInt::get(CGF.
Int32Ty, ArgAlign - 1),
367 "align_overflow_area_pointer");
369 __overflow_area_pointer_int = CGF.
Builder.CreateAnd(
370 __overflow_area_pointer_int,
371 llvm::ConstantInt::getSigned(CGF.
Int32Ty, -ArgAlign),
372 "align_overflow_area_pointer");
374 __overflow_area_pointer = CGF.
Builder.CreateIntToPtr(
375 __overflow_area_pointer_int, __overflow_area_pointer->getType(),
376 "align_overflow_area_pointer");
382 CGF.
Int8Ty, __overflow_area_pointer,
383 llvm::ConstantInt::get(CGF.
Int32Ty, ArgSize),
384 "__overflow_area_pointer.next");
387 __overflow_area_pointer_p);
390 __current_saved_reg_area_pointer_p);
398 llvm::PHINode *ArgAddr = CGF.
Builder.CreatePHI(
399 llvm::PointerType::getUnqual(MemTy->getContext()), 2,
"vaarg.addr");
400 ArgAddr->addIncoming(__current_saved_reg_area_pointer, InRegBlock);
401 ArgAddr->addIncoming(__overflow_area_pointer, OnStackBlock);
406RValue HexagonABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
407 QualType Ty, AggValueSlot Slot)
const {
411 CGF.
MakeAddrLValue(EmitVAArgForHexagonLinux(CGF, VAListAddr, Ty), Ty),
415 CGF.
MakeAddrLValue(EmitVAArgForHexagon(CGF, VAListAddr, Ty), Ty), Slot);
418std::unique_ptr<TargetCodeGenInfo>
420 return std::make_unique<HexagonTargetCodeGenInfo>(CGM.
getTypes());
static bool HexagonAdjustRegsLeft(uint64_t Size, unsigned *RegsLeft)
static StringRef getTriple(const Command &Job)
static CanQualType getCanonicalType(QualType T)
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.
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
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, llvm::Type *Padding=nullptr)
static ABIArgInfo getDirectInReg(llvm::Type *T=nullptr)
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()
llvm::Type * ConvertType(QualType T)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
RValue EmitLoadOfAnyValue(LValue V, AggValueSlot Slot=AggValueSlot::ignored(), SourceLocation Loc={})
Like EmitLoadOfLValue but also handles complex and aggregate types.
ASTContext & getContext() const
llvm::Type * ConvertTypeForMem(QualType T)
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
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 classifyArgumentType(QualType RetTy) const
TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...
bool isBitIntType() 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.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
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.
@ Address
A pointer to a ValueDecl.
Top level wrappers for InstallAPI frontend operations.
const FunctionProtoType * T
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * Int32Ty
llvm::PointerType * Int8PtrTy