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.
Definition: