10#include "TargetInfo.h"
21 static const int MaxNumArgGPRs = 6;
22 static const int MaxNumRetGPRs = 4;
25 XtensaABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}
27 void computeInfo(CGFunctionInfo &FI)
const override;
33 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
34 AggValueSlot Slot)
const override;
36 ABIArgInfo extendType(QualType Ty)
const;
45 int ArgGPRsLeft = MaxNumArgGPRs;
51ABIArgInfo XtensaABIInfo::classifyArgumentType(QualType Ty,
52 int &ArgGPRsLeft)
const {
53 assert(ArgGPRsLeft <= MaxNumArgGPRs &&
"Arg GPR tracking underflow");
60 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
70 uint64_t NeededAlign = getContext().getTypeAlign(Ty);
71 int NeededArgGPRs = (
Size + 31) / 32;
73 if (NeededAlign == (2 * 32))
74 NeededArgGPRs += (ArgGPRsLeft % 2);
79 if ((NeededArgGPRs > ArgGPRsLeft) || (NeededAlign > (4 * 32)) ||
80 ((ArgGPRsLeft < 6) && (NeededAlign == (4 * 32)))) {
82 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
85 ArgGPRsLeft -= NeededArgGPRs;
90 Ty = ED->getIntegerType();
92 if (Size < 32 && Ty->isIntegralOrEnumerationType()) {
93 return extendType(Ty);
101 if (Size <= (MaxNumArgGPRs * 32)) {
104 }
else if (NeededAlign == (2 * 32)) {
106 llvm::IntegerType::get(getVMContext(), 64), NeededArgGPRs / 2));
107 }
else if (NeededAlign == (4 * 32)) {
112 llvm::IntegerType::get(getVMContext(), 32), NeededArgGPRs));
115 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
119ABIArgInfo XtensaABIInfo::classifyReturnType(QualType RetTy)
const {
123 int ArgGPRsLeft = MaxNumRetGPRs;
124 auto RetSize = llvm::alignTo(getContext().getTypeSize(RetTy), 32) / 32;
134RValue XtensaABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
135 QualType Ty, AggValueSlot Slot)
const {
142 CGBuilderTy &Builder = CGF.
Builder;
144 Address OverflowAreaPtr = Builder.CreateStructGEP(VAListAddr, 0,
"__va_stk");
145 Address OverflowArea =
Address(Builder.CreateLoad(OverflowAreaPtr,
""),
147 Address RegSaveAreaPtr = Builder.CreateStructGEP(VAListAddr, 1,
"__va_reg");
148 Address RegSaveArea =
Address(Builder.CreateLoad(RegSaveAreaPtr,
""),
150 Address ARAreaPtr = Builder.CreateStructGEP(VAListAddr, 2,
"__va_ndx");
151 llvm::Value *ARIndex = Builder.CreateLoad(ARAreaPtr,
"");
153 ARIndex = Builder.CreateLShr(ARIndex, Builder.getInt32(2));
155 unsigned Align = getContext().getTypeAlign(Ty) / 32;
156 unsigned Size = (getContext().getTypeSize(Ty) + 31) / 32;
159 ARIndex = Builder.CreateAdd(ARIndex, Builder.getInt32(Align - 1));
161 Builder.CreateAnd(ARIndex, Builder.getInt32((
uint32_t)~(Align - 1)));
164 llvm::Value *ARIndexNext = Builder.CreateAdd(ARIndex, Builder.getInt32(Size));
165 Builder.CreateStore(Builder.CreateShl(ARIndexNext, Builder.getInt32(2)),
168 const unsigned OverflowLimit = 6;
169 llvm::Value *CC = Builder.CreateICmpULE(
170 ARIndexNext, Builder.getInt32(OverflowLimit),
"cond");
172 llvm::BasicBlock *UsingRegSaveArea =
177 Builder.CreateCondBr(CC, UsingRegSaveArea, UsingOverflow);
188 Address(Builder.CreateInBoundsGEP(
200 llvm::Value *CC1 = Builder.CreateICmpULE(
201 ARIndex, Builder.getInt32(OverflowLimit),
"cond_overflow");
203 llvm::Value *ARIndexOff = Builder.CreateSelect(
204 CC1, Builder.CreateSub(Builder.getInt32(8), ARIndex),
205 Builder.getInt32(0));
207 llvm::Value *ARIndexCorr = Builder.CreateAdd(ARIndex, ARIndexOff);
208 llvm::Value *ARIndexNextCorr = Builder.CreateAdd(ARIndexNext, ARIndexOff);
209 Builder.CreateStore(Builder.CreateShl(ARIndexNextCorr, Builder.getInt32(2)),
214 Address(Builder.CreateInBoundsGEP(
226 emitMergePHI(CGF, RegAddr, UsingRegSaveArea, MemAddr, UsingOverflow,
"");
231ABIArgInfo XtensaABIInfo::extendType(QualType Ty)
const {
236class XtensaTargetCodeGenInfo :
public TargetCodeGenInfo {
238 XtensaTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT)
239 : TargetCodeGenInfo(std::make_unique<XtensaABIInfo>(CGT)) {}
243std::unique_ptr<TargetCodeGenInfo>
245 return std::make_unique<XtensaTargetCodeGenInfo>(CGM.
getTypes());
Result
Implement __builtin_bit_cast and related operations.
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
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)
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CharUnits getAlignment() const
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
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.
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 classifyReturnType(QualType RetTy) const
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isVectorType() const
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 > createXtensaTargetCodeGenInfo(CodeGenModule &CGM)
Address emitMergePHI(CodeGenFunction &CGF, Address Addr1, llvm::BasicBlock *Block1, Address Addr2, llvm::BasicBlock *Block2, const llvm::Twine &Name="")
bool isAggregateTypeForABI(QualType T)
QualType useFirstFieldIfTransparentUnion(QualType Ty)
Pass transparent unions as if they were the type of the first element.
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.
llvm::IntegerType * Int32Ty