forked from OSchip/llvm-project
now that ABIInfo depends on CGT, it has trivial access to such
things as TargetData, ASTContext, LLVMContext etc. Stop passing them through so many APIs. llvm-svn: 109723
This commit is contained in:
parent
2b03797222
commit
458b2aaee0
|
@ -140,8 +140,6 @@ namespace clang {
|
||||||
const llvm::TargetData &getTargetData() const;
|
const llvm::TargetData &getTargetData() const;
|
||||||
|
|
||||||
virtual void computeInfo(CodeGen::CGFunctionInfo &FI,
|
virtual void computeInfo(CodeGen::CGFunctionInfo &FI,
|
||||||
ASTContext &Ctx,
|
|
||||||
llvm::LLVMContext &VMContext,
|
|
||||||
// This is the preferred type for argument lowering
|
// This is the preferred type for argument lowering
|
||||||
// which can be used to generate better IR.
|
// which can be used to generate better IR.
|
||||||
const llvm::Type *const *PrefTypes = 0,
|
const llvm::Type *const *PrefTypes = 0,
|
||||||
|
|
|
@ -255,8 +255,8 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(CanQualType ResTy,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute ABI information.
|
// Compute ABI information.
|
||||||
getABIInfo().computeInfo(*FI, getContext(), TheModule.getContext(),
|
getABIInfo().computeInfo(*FI, PreferredArgTypes.data(),
|
||||||
PreferredArgTypes.data(), PreferredArgTypes.size());
|
PreferredArgTypes.size());
|
||||||
|
|
||||||
// If this is a top-level call and ConvertTypeRecursive hit unresolved pointer
|
// If this is a top-level call and ConvertTypeRecursive hit unresolved pointer
|
||||||
// types, resolve them now. These pointers may point to this function, which
|
// types, resolve them now. These pointers may point to this function, which
|
||||||
|
|
|
@ -288,23 +288,16 @@ class DefaultABIInfo : public ABIInfo {
|
||||||
public:
|
public:
|
||||||
DefaultABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {}
|
DefaultABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {}
|
||||||
|
|
||||||
ABIArgInfo classifyReturnType(QualType RetTy,
|
ABIArgInfo classifyReturnType(QualType RetTy) const;
|
||||||
ASTContext &Context,
|
ABIArgInfo classifyArgumentType(QualType RetTy) const;
|
||||||
llvm::LLVMContext &VMContext) const;
|
|
||||||
|
|
||||||
ABIArgInfo classifyArgumentType(QualType RetTy,
|
virtual void computeInfo(CGFunctionInfo &FI,
|
||||||
ASTContext &Context,
|
|
||||||
llvm::LLVMContext &VMContext) const;
|
|
||||||
|
|
||||||
virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context,
|
|
||||||
llvm::LLVMContext &VMContext,
|
|
||||||
const llvm::Type *const *PrefTypes,
|
const llvm::Type *const *PrefTypes,
|
||||||
unsigned NumPrefTypes) const {
|
unsigned NumPrefTypes) const {
|
||||||
FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), Context,
|
FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
|
||||||
VMContext);
|
|
||||||
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
|
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
|
||||||
it != ie; ++it)
|
it != ie; ++it)
|
||||||
it->info = classifyArgumentType(it->type, Context, VMContext);
|
it->info = classifyArgumentType(it->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||||
|
@ -322,9 +315,7 @@ llvm::Value *DefaultABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty,
|
ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const {
|
||||||
ASTContext &Context,
|
|
||||||
llvm::LLVMContext &VMContext) const {
|
|
||||||
if (CodeGenFunction::hasAggregateLLVMType(Ty))
|
if (CodeGenFunction::hasAggregateLLVMType(Ty))
|
||||||
return ABIArgInfo::getIndirect(0);
|
return ABIArgInfo::getIndirect(0);
|
||||||
|
|
||||||
|
@ -353,29 +344,20 @@ class X86_32ABIInfo : public ABIInfo {
|
||||||
|
|
||||||
/// getIndirectResult - Give a source type \arg Ty, return a suitable result
|
/// getIndirectResult - Give a source type \arg Ty, return a suitable result
|
||||||
/// such that the argument will be passed in memory.
|
/// such that the argument will be passed in memory.
|
||||||
ABIArgInfo getIndirectResult(QualType Ty, ASTContext &Context,
|
ABIArgInfo getIndirectResult(QualType Ty, bool ByVal = true) const;
|
||||||
bool ByVal = true) const;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
X86_32ABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {}
|
|
||||||
|
|
||||||
ABIArgInfo classifyReturnType(QualType RetTy,
|
ABIArgInfo classifyReturnType(QualType RetTy) const;
|
||||||
ASTContext &Context,
|
ABIArgInfo classifyArgumentType(QualType RetTy) const;
|
||||||
llvm::LLVMContext &VMContext) const;
|
|
||||||
|
|
||||||
ABIArgInfo classifyArgumentType(QualType RetTy,
|
virtual void computeInfo(CGFunctionInfo &FI,
|
||||||
ASTContext &Context,
|
|
||||||
llvm::LLVMContext &VMContext) const;
|
|
||||||
|
|
||||||
virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context,
|
|
||||||
llvm::LLVMContext &VMContext,
|
|
||||||
const llvm::Type *const *PrefTypes,
|
const llvm::Type *const *PrefTypes,
|
||||||
unsigned NumPrefTypes) const {
|
unsigned NumPrefTypes) const {
|
||||||
FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), Context,
|
FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
|
||||||
VMContext);
|
|
||||||
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
|
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
|
||||||
it != ie; ++it)
|
it != ie; ++it)
|
||||||
it->info = classifyArgumentType(it->type, Context, VMContext);
|
it->info = classifyArgumentType(it->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||||
|
@ -460,34 +442,36 @@ bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
|
ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy) const {
|
||||||
ASTContext &Context,
|
if (RetTy->isVoidType())
|
||||||
llvm::LLVMContext &VMContext) const {
|
|
||||||
if (RetTy->isVoidType()) {
|
|
||||||
return ABIArgInfo::getIgnore();
|
return ABIArgInfo::getIgnore();
|
||||||
} else if (const VectorType *VT = RetTy->getAs<VectorType>()) {
|
|
||||||
|
if (const VectorType *VT = RetTy->getAs<VectorType>()) {
|
||||||
// On Darwin, some vectors are returned in registers.
|
// On Darwin, some vectors are returned in registers.
|
||||||
if (IsDarwinVectorABI) {
|
if (IsDarwinVectorABI) {
|
||||||
uint64_t Size = Context.getTypeSize(RetTy);
|
uint64_t Size = getContext().getTypeSize(RetTy);
|
||||||
|
|
||||||
// 128-bit vectors are a special case; they are returned in
|
// 128-bit vectors are a special case; they are returned in
|
||||||
// registers and we need to make sure to pick a type the LLVM
|
// registers and we need to make sure to pick a type the LLVM
|
||||||
// backend will like.
|
// backend will like.
|
||||||
if (Size == 128)
|
if (Size == 128)
|
||||||
return ABIArgInfo::getCoerce(llvm::VectorType::get(
|
return ABIArgInfo::getCoerce(llvm::VectorType::get(
|
||||||
llvm::Type::getInt64Ty(VMContext), 2));
|
llvm::Type::getInt64Ty(getVMContext()), 2));
|
||||||
|
|
||||||
// Always return in register if it fits in a general purpose
|
// Always return in register if it fits in a general purpose
|
||||||
// register, or if it is 64 bits and has a single element.
|
// register, or if it is 64 bits and has a single element.
|
||||||
if ((Size == 8 || Size == 16 || Size == 32) ||
|
if ((Size == 8 || Size == 16 || Size == 32) ||
|
||||||
(Size == 64 && VT->getNumElements() == 1))
|
(Size == 64 && VT->getNumElements() == 1))
|
||||||
return ABIArgInfo::getCoerce(llvm::IntegerType::get(VMContext, Size));
|
return ABIArgInfo::getCoerce(llvm::IntegerType::get(getVMContext(),
|
||||||
|
Size));
|
||||||
|
|
||||||
return ABIArgInfo::getIndirect(0);
|
return ABIArgInfo::getIndirect(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ABIArgInfo::getDirect();
|
return ABIArgInfo::getDirect();
|
||||||
} else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
|
}
|
||||||
|
|
||||||
|
if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
|
||||||
if (const RecordType *RT = RetTy->getAs<RecordType>()) {
|
if (const RecordType *RT = RetTy->getAs<RecordType>()) {
|
||||||
// Structures with either a non-trivial destructor or a non-trivial
|
// Structures with either a non-trivial destructor or a non-trivial
|
||||||
// copy constructor are always indirect.
|
// copy constructor are always indirect.
|
||||||
|
@ -504,76 +488,78 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
|
||||||
return ABIArgInfo::getIndirect(0);
|
return ABIArgInfo::getIndirect(0);
|
||||||
|
|
||||||
// Classify "single element" structs as their element type.
|
// Classify "single element" structs as their element type.
|
||||||
if (const Type *SeltTy = isSingleElementStruct(RetTy, Context)) {
|
if (const Type *SeltTy = isSingleElementStruct(RetTy, getContext())) {
|
||||||
if (const BuiltinType *BT = SeltTy->getAs<BuiltinType>()) {
|
if (const BuiltinType *BT = SeltTy->getAs<BuiltinType>()) {
|
||||||
if (BT->isIntegerType()) {
|
if (BT->isIntegerType()) {
|
||||||
// We need to use the size of the structure, padding
|
// We need to use the size of the structure, padding
|
||||||
// bit-fields can adjust that to be larger than the single
|
// bit-fields can adjust that to be larger than the single
|
||||||
// element type.
|
// element type.
|
||||||
uint64_t Size = Context.getTypeSize(RetTy);
|
uint64_t Size = getContext().getTypeSize(RetTy);
|
||||||
return ABIArgInfo::getCoerce(
|
return ABIArgInfo::getCoerce(
|
||||||
llvm::IntegerType::get(VMContext, (unsigned) Size));
|
llvm::IntegerType::get(getVMContext(), (unsigned)Size));
|
||||||
} else if (BT->getKind() == BuiltinType::Float) {
|
}
|
||||||
assert(Context.getTypeSize(RetTy) == Context.getTypeSize(SeltTy) &&
|
|
||||||
|
if (BT->getKind() == BuiltinType::Float) {
|
||||||
|
assert(getContext().getTypeSize(RetTy) ==
|
||||||
|
getContext().getTypeSize(SeltTy) &&
|
||||||
"Unexpect single element structure size!");
|
"Unexpect single element structure size!");
|
||||||
return ABIArgInfo::getCoerce(llvm::Type::getFloatTy(VMContext));
|
return ABIArgInfo::getCoerce(llvm::Type::getFloatTy(getVMContext()));
|
||||||
} else if (BT->getKind() == BuiltinType::Double) {
|
}
|
||||||
assert(Context.getTypeSize(RetTy) == Context.getTypeSize(SeltTy) &&
|
|
||||||
|
if (BT->getKind() == BuiltinType::Double) {
|
||||||
|
assert(getContext().getTypeSize(RetTy) ==
|
||||||
|
getContext().getTypeSize(SeltTy) &&
|
||||||
"Unexpect single element structure size!");
|
"Unexpect single element structure size!");
|
||||||
return ABIArgInfo::getCoerce(llvm::Type::getDoubleTy(VMContext));
|
return ABIArgInfo::getCoerce(llvm::Type::getDoubleTy(getVMContext()));
|
||||||
}
|
}
|
||||||
} else if (SeltTy->isPointerType()) {
|
} else if (SeltTy->isPointerType()) {
|
||||||
// FIXME: It would be really nice if this could come out as the proper
|
// FIXME: It would be really nice if this could come out as the proper
|
||||||
// pointer type.
|
// pointer type.
|
||||||
const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext);
|
const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(getVMContext());
|
||||||
return ABIArgInfo::getCoerce(PtrTy);
|
return ABIArgInfo::getCoerce(PtrTy);
|
||||||
} else if (SeltTy->isVectorType()) {
|
} else if (SeltTy->isVectorType()) {
|
||||||
// 64- and 128-bit vectors are never returned in a
|
// 64- and 128-bit vectors are never returned in a
|
||||||
// register when inside a structure.
|
// register when inside a structure.
|
||||||
uint64_t Size = Context.getTypeSize(RetTy);
|
uint64_t Size = getContext().getTypeSize(RetTy);
|
||||||
if (Size == 64 || Size == 128)
|
if (Size == 64 || Size == 128)
|
||||||
return ABIArgInfo::getIndirect(0);
|
return ABIArgInfo::getIndirect(0);
|
||||||
|
|
||||||
return classifyReturnType(QualType(SeltTy, 0), Context, VMContext);
|
return classifyReturnType(QualType(SeltTy, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Small structures which are register sized are generally returned
|
// Small structures which are register sized are generally returned
|
||||||
// in a register.
|
// in a register.
|
||||||
if (X86_32ABIInfo::shouldReturnTypeInRegister(RetTy, Context)) {
|
if (X86_32ABIInfo::shouldReturnTypeInRegister(RetTy, getContext())) {
|
||||||
uint64_t Size = Context.getTypeSize(RetTy);
|
uint64_t Size = getContext().getTypeSize(RetTy);
|
||||||
return ABIArgInfo::getCoerce(llvm::IntegerType::get(VMContext, Size));
|
return ABIArgInfo::getCoerce(llvm::IntegerType::get(getVMContext(),Size));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ABIArgInfo::getIndirect(0);
|
return ABIArgInfo::getIndirect(0);
|
||||||
} else {
|
|
||||||
// Treat an enum type as its underlying type.
|
|
||||||
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
|
|
||||||
RetTy = EnumTy->getDecl()->getIntegerType();
|
|
||||||
|
|
||||||
return (RetTy->isPromotableIntegerType() ?
|
|
||||||
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Treat an enum type as its underlying type.
|
||||||
|
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
|
||||||
|
RetTy = EnumTy->getDecl()->getIntegerType();
|
||||||
|
|
||||||
|
return (RetTy->isPromotableIntegerType() ?
|
||||||
|
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
|
||||||
}
|
}
|
||||||
|
|
||||||
ABIArgInfo X86_32ABIInfo::getIndirectResult(QualType Ty,
|
ABIArgInfo X86_32ABIInfo::getIndirectResult(QualType Ty, bool ByVal) const {
|
||||||
ASTContext &Context,
|
|
||||||
bool ByVal) const {
|
|
||||||
if (!ByVal)
|
if (!ByVal)
|
||||||
return ABIArgInfo::getIndirect(0, false);
|
return ABIArgInfo::getIndirect(0, false);
|
||||||
|
|
||||||
// Compute the byval alignment. We trust the back-end to honor the
|
// Compute the byval alignment. We trust the back-end to honor the
|
||||||
// minimum ABI alignment for byval, to make cleaner IR.
|
// minimum ABI alignment for byval, to make cleaner IR.
|
||||||
const unsigned MinABIAlign = 4;
|
const unsigned MinABIAlign = 4;
|
||||||
unsigned Align = Context.getTypeAlign(Ty) / 8;
|
unsigned Align = getContext().getTypeAlign(Ty) / 8;
|
||||||
if (Align > MinABIAlign)
|
if (Align > MinABIAlign)
|
||||||
return ABIArgInfo::getIndirect(Align);
|
return ABIArgInfo::getIndirect(Align);
|
||||||
return ABIArgInfo::getIndirect(0);
|
return ABIArgInfo::getIndirect(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
|
ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty) const {
|
||||||
ASTContext &Context,
|
|
||||||
llvm::LLVMContext &VMContext) const {
|
|
||||||
// FIXME: Set alignment on indirect arguments.
|
// FIXME: Set alignment on indirect arguments.
|
||||||
if (CodeGenFunction::hasAggregateLLVMType(Ty)) {
|
if (CodeGenFunction::hasAggregateLLVMType(Ty)) {
|
||||||
// Structures with flexible arrays are always indirect.
|
// Structures with flexible arrays are always indirect.
|
||||||
|
@ -581,32 +567,32 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
|
||||||
// Structures with either a non-trivial destructor or a non-trivial
|
// Structures with either a non-trivial destructor or a non-trivial
|
||||||
// copy constructor are always indirect.
|
// copy constructor are always indirect.
|
||||||
if (hasNonTrivialDestructorOrCopyConstructor(RT))
|
if (hasNonTrivialDestructorOrCopyConstructor(RT))
|
||||||
return getIndirectResult(Ty, Context, /*ByVal=*/false);
|
return getIndirectResult(Ty, /*ByVal=*/false);
|
||||||
|
|
||||||
if (RT->getDecl()->hasFlexibleArrayMember())
|
if (RT->getDecl()->hasFlexibleArrayMember())
|
||||||
return getIndirectResult(Ty, Context);
|
return getIndirectResult(Ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore empty structs.
|
// Ignore empty structs.
|
||||||
if (Ty->isStructureType() && Context.getTypeSize(Ty) == 0)
|
if (Ty->isStructureType() && getContext().getTypeSize(Ty) == 0)
|
||||||
return ABIArgInfo::getIgnore();
|
return ABIArgInfo::getIgnore();
|
||||||
|
|
||||||
// Expand small (<= 128-bit) record types when we know that the stack layout
|
// Expand small (<= 128-bit) record types when we know that the stack layout
|
||||||
// of those arguments will match the struct. This is important because the
|
// of those arguments will match the struct. This is important because the
|
||||||
// LLVM backend isn't smart enough to remove byval, which inhibits many
|
// LLVM backend isn't smart enough to remove byval, which inhibits many
|
||||||
// optimizations.
|
// optimizations.
|
||||||
if (Context.getTypeSize(Ty) <= 4*32 &&
|
if (getContext().getTypeSize(Ty) <= 4*32 &&
|
||||||
canExpandIndirectArgument(Ty, Context))
|
canExpandIndirectArgument(Ty, getContext()))
|
||||||
return ABIArgInfo::getExpand();
|
return ABIArgInfo::getExpand();
|
||||||
|
|
||||||
return getIndirectResult(Ty, Context);
|
return getIndirectResult(Ty);
|
||||||
} else {
|
}
|
||||||
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
|
|
||||||
Ty = EnumTy->getDecl()->getIntegerType();
|
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
|
||||||
|
Ty = EnumTy->getDecl()->getIntegerType();
|
||||||
|
|
||||||
return (Ty->isPromotableIntegerType() ?
|
return (Ty->isPromotableIntegerType() ?
|
||||||
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
|
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Value *X86_32ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
llvm::Value *X86_32ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||||
|
@ -755,11 +741,9 @@ class X86_64ABIInfo : public ABIInfo {
|
||||||
/// such that the argument will be passed in memory.
|
/// such that the argument will be passed in memory.
|
||||||
ABIArgInfo getIndirectResult(QualType Ty) const;
|
ABIArgInfo getIndirectResult(QualType Ty) const;
|
||||||
|
|
||||||
ABIArgInfo classifyReturnType(QualType RetTy,
|
ABIArgInfo classifyReturnType(QualType RetTy) const;
|
||||||
llvm::LLVMContext &VMContext) const;
|
|
||||||
|
|
||||||
ABIArgInfo classifyArgumentType(QualType Ty,
|
ABIArgInfo classifyArgumentType(QualType Ty,
|
||||||
llvm::LLVMContext &VMContext,
|
|
||||||
unsigned &neededInt,
|
unsigned &neededInt,
|
||||||
unsigned &neededSSE,
|
unsigned &neededSSE,
|
||||||
const llvm::Type *PrefType) const;
|
const llvm::Type *PrefType) const;
|
||||||
|
@ -767,8 +751,7 @@ class X86_64ABIInfo : public ABIInfo {
|
||||||
public:
|
public:
|
||||||
X86_64ABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {}
|
X86_64ABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {}
|
||||||
|
|
||||||
virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context,
|
virtual void computeInfo(CGFunctionInfo &FI,
|
||||||
llvm::LLVMContext &VMContext,
|
|
||||||
const llvm::Type *const *PrefTypes,
|
const llvm::Type *const *PrefTypes,
|
||||||
unsigned NumPrefTypes) const;
|
unsigned NumPrefTypes) const;
|
||||||
|
|
||||||
|
@ -1257,7 +1240,7 @@ static const llvm::Type *Get8ByteTypeAtOffset(const llvm::Type *PrefType,
|
||||||
}
|
}
|
||||||
|
|
||||||
ABIArgInfo X86_64ABIInfo::
|
ABIArgInfo X86_64ABIInfo::
|
||||||
classifyReturnType(QualType RetTy, llvm::LLVMContext &VMContext) const {
|
classifyReturnType(QualType RetTy) const {
|
||||||
// AMD64-ABI 3.2.3p4: Rule 1. Classify the return type with the
|
// AMD64-ABI 3.2.3p4: Rule 1. Classify the return type with the
|
||||||
// classification algorithm.
|
// classification algorithm.
|
||||||
X86_64ABIInfo::Class Lo, Hi;
|
X86_64ABIInfo::Class Lo, Hi;
|
||||||
|
@ -1286,7 +1269,7 @@ classifyReturnType(QualType RetTy, llvm::LLVMContext &VMContext) const {
|
||||||
// available register of the sequence %rax, %rdx is used.
|
// available register of the sequence %rax, %rdx is used.
|
||||||
case Integer:
|
case Integer:
|
||||||
ResType = Get8ByteTypeAtOffset(0, 0, RetTy, 0, getTargetData(),
|
ResType = Get8ByteTypeAtOffset(0, 0, RetTy, 0, getTargetData(),
|
||||||
VMContext, getContext());
|
getVMContext(), getContext());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// AMD64-ABI 3.2.3p4: Rule 4. If the class is SSE, the next
|
// AMD64-ABI 3.2.3p4: Rule 4. If the class is SSE, the next
|
||||||
|
@ -1306,7 +1289,7 @@ classifyReturnType(QualType RetTy, llvm::LLVMContext &VMContext) const {
|
||||||
// %st1.
|
// %st1.
|
||||||
case ComplexX87:
|
case ComplexX87:
|
||||||
assert(Hi == ComplexX87 && "Unexpected ComplexX87 classification.");
|
assert(Hi == ComplexX87 && "Unexpected ComplexX87 classification.");
|
||||||
ResType = llvm::StructType::get(VMContext,
|
ResType = llvm::StructType::get(getVMContext(),
|
||||||
llvm::Type::getX86_FP80Ty(getVMContext()),
|
llvm::Type::getX86_FP80Ty(getVMContext()),
|
||||||
llvm::Type::getX86_FP80Ty(getVMContext()),
|
llvm::Type::getX86_FP80Ty(getVMContext()),
|
||||||
NULL);
|
NULL);
|
||||||
|
@ -1326,14 +1309,15 @@ classifyReturnType(QualType RetTy, llvm::LLVMContext &VMContext) const {
|
||||||
|
|
||||||
case Integer: {
|
case Integer: {
|
||||||
const llvm::Type *HiType =
|
const llvm::Type *HiType =
|
||||||
Get8ByteTypeAtOffset(0, 8, RetTy, 8, getTargetData(), VMContext,
|
Get8ByteTypeAtOffset(0, 8, RetTy, 8, getTargetData(), getVMContext(),
|
||||||
getContext());
|
getContext());
|
||||||
ResType = llvm::StructType::get(VMContext, ResType, HiType, NULL);
|
ResType = llvm::StructType::get(getVMContext(), ResType, HiType, NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SSE:
|
case SSE:
|
||||||
ResType = llvm::StructType::get(VMContext, ResType,
|
ResType = llvm::StructType::get(getVMContext(), ResType,
|
||||||
llvm::Type::getDoubleTy(VMContext), NULL);
|
llvm::Type::getDoubleTy(getVMContext()),
|
||||||
|
NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// AMD64-ABI 3.2.3p4: Rule 5. If the class is SSEUP, the eightbyte
|
// AMD64-ABI 3.2.3p4: Rule 5. If the class is SSEUP, the eightbyte
|
||||||
|
@ -1342,7 +1326,7 @@ classifyReturnType(QualType RetTy, llvm::LLVMContext &VMContext) const {
|
||||||
// SSEUP should always be preceeded by SSE, just widen.
|
// SSEUP should always be preceeded by SSE, just widen.
|
||||||
case SSEUp:
|
case SSEUp:
|
||||||
assert(Lo == SSE && "Unexpected SSEUp classification.");
|
assert(Lo == SSE && "Unexpected SSEUp classification.");
|
||||||
ResType = llvm::VectorType::get(llvm::Type::getDoubleTy(VMContext), 2);
|
ResType = llvm::VectorType::get(llvm::Type::getDoubleTy(getVMContext()), 2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// AMD64-ABI 3.2.3p4: Rule 7. If the class is X87UP, the value is
|
// AMD64-ABI 3.2.3p4: Rule 7. If the class is X87UP, the value is
|
||||||
|
@ -1353,17 +1337,16 @@ classifyReturnType(QualType RetTy, llvm::LLVMContext &VMContext) const {
|
||||||
// preceeded by X87. In such situations we follow gcc and pass the
|
// preceeded by X87. In such situations we follow gcc and pass the
|
||||||
// extra bits in an SSE reg.
|
// extra bits in an SSE reg.
|
||||||
if (Lo != X87)
|
if (Lo != X87)
|
||||||
ResType = llvm::StructType::get(VMContext, ResType,
|
ResType = llvm::StructType::get(getVMContext(), ResType,
|
||||||
llvm::Type::getDoubleTy(VMContext), NULL);
|
llvm::Type::getDoubleTy(getVMContext()),
|
||||||
|
NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return getCoerceResult(RetTy, ResType);
|
return getCoerceResult(RetTy, ResType);
|
||||||
}
|
}
|
||||||
|
|
||||||
ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty,
|
ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned &neededInt,
|
||||||
llvm::LLVMContext &VMContext,
|
|
||||||
unsigned &neededInt,
|
|
||||||
unsigned &neededSSE,
|
unsigned &neededSSE,
|
||||||
const llvm::Type *PrefType)const{
|
const llvm::Type *PrefType)const{
|
||||||
X86_64ABIInfo::Class Lo, Hi;
|
X86_64ABIInfo::Class Lo, Hi;
|
||||||
|
@ -1404,7 +1387,7 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty,
|
||||||
|
|
||||||
// Pick an 8-byte type based on the preferred type.
|
// Pick an 8-byte type based on the preferred type.
|
||||||
ResType = Get8ByteTypeAtOffset(PrefType, 0, Ty, 0, getTargetData(),
|
ResType = Get8ByteTypeAtOffset(PrefType, 0, Ty, 0, getTargetData(),
|
||||||
VMContext, getContext());
|
getVMContext(), getContext());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// AMD64-ABI 3.2.3p3: Rule 3. If the class is SSE, the next
|
// AMD64-ABI 3.2.3p3: Rule 3. If the class is SSE, the next
|
||||||
|
@ -1412,7 +1395,7 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty,
|
||||||
// order from %xmm0 to %xmm7.
|
// order from %xmm0 to %xmm7.
|
||||||
case SSE:
|
case SSE:
|
||||||
++neededSSE;
|
++neededSSE;
|
||||||
ResType = llvm::Type::getDoubleTy(VMContext);
|
ResType = llvm::Type::getDoubleTy(getVMContext());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1434,8 +1417,8 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty,
|
||||||
// Pick an 8-byte type based on the preferred type.
|
// Pick an 8-byte type based on the preferred type.
|
||||||
const llvm::Type *HiType =
|
const llvm::Type *HiType =
|
||||||
Get8ByteTypeAtOffset(PrefType, 8, Ty, 8, getTargetData(),
|
Get8ByteTypeAtOffset(PrefType, 8, Ty, 8, getTargetData(),
|
||||||
VMContext, getContext());
|
getVMContext(), getContext());
|
||||||
ResType = llvm::StructType::get(VMContext, ResType, HiType, NULL);
|
ResType = llvm::StructType::get(getVMContext(), ResType, HiType, NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1443,8 +1426,9 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty,
|
||||||
// memory), except in situations involving unions.
|
// memory), except in situations involving unions.
|
||||||
case X87Up:
|
case X87Up:
|
||||||
case SSE:
|
case SSE:
|
||||||
ResType = llvm::StructType::get(VMContext, ResType,
|
ResType = llvm::StructType::get(getVMContext(), ResType,
|
||||||
llvm::Type::getDoubleTy(VMContext), NULL);
|
llvm::Type::getDoubleTy(getVMContext()),
|
||||||
|
NULL);
|
||||||
++neededSSE;
|
++neededSSE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1453,7 +1437,7 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty,
|
||||||
// register. This only happens when 128-bit vectors are passed.
|
// register. This only happens when 128-bit vectors are passed.
|
||||||
case SSEUp:
|
case SSEUp:
|
||||||
assert(Lo == SSE && "Unexpected SSEUp classification");
|
assert(Lo == SSE && "Unexpected SSEUp classification");
|
||||||
ResType = llvm::VectorType::get(llvm::Type::getDoubleTy(VMContext), 2);
|
ResType = llvm::VectorType::get(llvm::Type::getDoubleTy(getVMContext()), 2);
|
||||||
|
|
||||||
// If the preferred type is a 16-byte vector, prefer to pass it.
|
// If the preferred type is a 16-byte vector, prefer to pass it.
|
||||||
if (const llvm::VectorType *VT =
|
if (const llvm::VectorType *VT =
|
||||||
|
@ -1472,11 +1456,10 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty,
|
||||||
return getCoerceResult(Ty, ResType);
|
return getCoerceResult(Ty, ResType);
|
||||||
}
|
}
|
||||||
|
|
||||||
void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI, ASTContext &Context,
|
void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI,
|
||||||
llvm::LLVMContext &VMContext,
|
|
||||||
const llvm::Type *const *PrefTypes,
|
const llvm::Type *const *PrefTypes,
|
||||||
unsigned NumPrefTypes) const {
|
unsigned NumPrefTypes) const {
|
||||||
FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), VMContext);
|
FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
|
||||||
|
|
||||||
// Keep track of the number of assigned registers.
|
// Keep track of the number of assigned registers.
|
||||||
unsigned freeIntRegs = 6, freeSSERegs = 8;
|
unsigned freeIntRegs = 6, freeSSERegs = 8;
|
||||||
|
@ -1499,8 +1482,7 @@ void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI, ASTContext &Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned neededInt, neededSSE;
|
unsigned neededInt, neededSSE;
|
||||||
it->info = classifyArgumentType(it->type, VMContext,
|
it->info = classifyArgumentType(it->type, neededInt, neededSSE, PrefType);
|
||||||
neededInt, neededSSE, PrefType);
|
|
||||||
|
|
||||||
// AMD64-ABI 3.2.3p3: If there are no registers available for any
|
// AMD64-ABI 3.2.3p3: If there are no registers available for any
|
||||||
// eightbyte of an argument, the whole argument is passed on the
|
// eightbyte of an argument, the whole argument is passed on the
|
||||||
|
@ -1580,7 +1562,7 @@ llvm::Value *X86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||||
unsigned neededInt, neededSSE;
|
unsigned neededInt, neededSSE;
|
||||||
|
|
||||||
Ty = CGF.getContext().getCanonicalType(Ty);
|
Ty = CGF.getContext().getCanonicalType(Ty);
|
||||||
ABIArgInfo AI = classifyArgumentType(Ty, VMContext, neededInt, neededSSE, 0);
|
ABIArgInfo AI = classifyArgumentType(Ty, neededInt, neededSSE, 0);
|
||||||
|
|
||||||
// AMD64-ABI 3.5.7p5: Step 1. Determine whether type may be passed
|
// AMD64-ABI 3.5.7p5: Step 1. Determine whether type may be passed
|
||||||
// in the registers. If not go to step 7.
|
// in the registers. If not go to step 7.
|
||||||
|
@ -1737,23 +1719,17 @@ class PIC16ABIInfo : public ABIInfo {
|
||||||
public:
|
public:
|
||||||
PIC16ABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {}
|
PIC16ABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {}
|
||||||
|
|
||||||
ABIArgInfo classifyReturnType(QualType RetTy,
|
ABIArgInfo classifyReturnType(QualType RetTy) const;
|
||||||
ASTContext &Context,
|
|
||||||
llvm::LLVMContext &VMContext) const;
|
|
||||||
|
|
||||||
ABIArgInfo classifyArgumentType(QualType RetTy,
|
ABIArgInfo classifyArgumentType(QualType RetTy) const;
|
||||||
ASTContext &Context,
|
|
||||||
llvm::LLVMContext &VMContext) const;
|
|
||||||
|
|
||||||
virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context,
|
virtual void computeInfo(CGFunctionInfo &FI,
|
||||||
llvm::LLVMContext &VMContext,
|
|
||||||
const llvm::Type *const *PrefTypes,
|
const llvm::Type *const *PrefTypes,
|
||||||
unsigned NumPrefTypes) const {
|
unsigned NumPrefTypes) const {
|
||||||
FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), Context,
|
FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
|
||||||
VMContext);
|
|
||||||
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
|
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
|
||||||
it != ie; ++it)
|
it != ie; ++it)
|
||||||
it->info = classifyArgumentType(it->type, Context, VMContext);
|
it->info = classifyArgumentType(it->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||||
|
@ -1768,9 +1744,7 @@ public:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ABIArgInfo PIC16ABIInfo::classifyReturnType(QualType RetTy,
|
ABIArgInfo PIC16ABIInfo::classifyReturnType(QualType RetTy) const {
|
||||||
ASTContext &Context,
|
|
||||||
llvm::LLVMContext &VMContext) const {
|
|
||||||
if (RetTy->isVoidType()) {
|
if (RetTy->isVoidType()) {
|
||||||
return ABIArgInfo::getIgnore();
|
return ABIArgInfo::getIgnore();
|
||||||
} else {
|
} else {
|
||||||
|
@ -1778,9 +1752,7 @@ ABIArgInfo PIC16ABIInfo::classifyReturnType(QualType RetTy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ABIArgInfo PIC16ABIInfo::classifyArgumentType(QualType Ty,
|
ABIArgInfo PIC16ABIInfo::classifyArgumentType(QualType Ty) const {
|
||||||
ASTContext &Context,
|
|
||||||
llvm::LLVMContext &VMContext) const {
|
|
||||||
return ABIArgInfo::getDirect();
|
return ABIArgInfo::getDirect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1893,16 +1865,10 @@ public:
|
||||||
private:
|
private:
|
||||||
ABIKind getABIKind() const { return Kind; }
|
ABIKind getABIKind() const { return Kind; }
|
||||||
|
|
||||||
ABIArgInfo classifyReturnType(QualType RetTy,
|
ABIArgInfo classifyReturnType(QualType RetTy) const;
|
||||||
ASTContext &Context,
|
ABIArgInfo classifyArgumentType(QualType RetTy) const;
|
||||||
llvm::LLVMContext &VMCOntext) const;
|
|
||||||
|
|
||||||
ABIArgInfo classifyArgumentType(QualType RetTy,
|
virtual void computeInfo(CGFunctionInfo &FI,
|
||||||
ASTContext &Context,
|
|
||||||
llvm::LLVMContext &VMContext) const;
|
|
||||||
|
|
||||||
virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context,
|
|
||||||
llvm::LLVMContext &VMContext,
|
|
||||||
const llvm::Type *const *PrefTypes,
|
const llvm::Type *const *PrefTypes,
|
||||||
unsigned NumPrefTypes) const;
|
unsigned NumPrefTypes) const;
|
||||||
|
|
||||||
|
@ -1922,18 +1888,15 @@ public:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMABIInfo::computeInfo(CGFunctionInfo &FI, ASTContext &Context,
|
void ARMABIInfo::computeInfo(CGFunctionInfo &FI,
|
||||||
llvm::LLVMContext &VMContext,
|
|
||||||
const llvm::Type *const *PrefTypes,
|
const llvm::Type *const *PrefTypes,
|
||||||
unsigned NumPrefTypes) const {
|
unsigned NumPrefTypes) const {
|
||||||
FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), Context,
|
FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
|
||||||
VMContext);
|
|
||||||
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
|
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
|
||||||
it != ie; ++it) {
|
it != ie; ++it)
|
||||||
it->info = classifyArgumentType(it->type, Context, VMContext);
|
it->info = classifyArgumentType(it->type);
|
||||||
}
|
|
||||||
|
|
||||||
const llvm::Triple &Triple(Context.Target.getTriple());
|
const llvm::Triple &Triple(getContext().Target.getTriple());
|
||||||
llvm::CallingConv::ID DefaultCC;
|
llvm::CallingConv::ID DefaultCC;
|
||||||
if (Triple.getEnvironmentName() == "gnueabi" ||
|
if (Triple.getEnvironmentName() == "gnueabi" ||
|
||||||
Triple.getEnvironmentName() == "eabi")
|
Triple.getEnvironmentName() == "eabi")
|
||||||
|
@ -1958,9 +1921,7 @@ void ARMABIInfo::computeInfo(CGFunctionInfo &FI, ASTContext &Context,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty,
|
ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty) const {
|
||||||
ASTContext &Context,
|
|
||||||
llvm::LLVMContext &VMContext) const {
|
|
||||||
if (!CodeGenFunction::hasAggregateLLVMType(Ty)) {
|
if (!CodeGenFunction::hasAggregateLLVMType(Ty)) {
|
||||||
// Treat an enum type as its underlying type.
|
// Treat an enum type as its underlying type.
|
||||||
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
|
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
|
||||||
|
@ -1971,7 +1932,7 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore empty records.
|
// Ignore empty records.
|
||||||
if (isEmptyRecord(Context, Ty, true))
|
if (isEmptyRecord(getContext(), Ty, true))
|
||||||
return ABIArgInfo::getIgnore();
|
return ABIArgInfo::getIgnore();
|
||||||
|
|
||||||
// Structures with either a non-trivial destructor or a non-trivial
|
// Structures with either a non-trivial destructor or a non-trivial
|
||||||
|
@ -1984,21 +1945,21 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty,
|
||||||
// FIXME: This doesn't handle alignment > 64 bits.
|
// FIXME: This doesn't handle alignment > 64 bits.
|
||||||
const llvm::Type* ElemTy;
|
const llvm::Type* ElemTy;
|
||||||
unsigned SizeRegs;
|
unsigned SizeRegs;
|
||||||
if (Context.getTypeAlign(Ty) > 32) {
|
if (getContext().getTypeAlign(Ty) > 32) {
|
||||||
ElemTy = llvm::Type::getInt64Ty(VMContext);
|
ElemTy = llvm::Type::getInt64Ty(getVMContext());
|
||||||
SizeRegs = (Context.getTypeSize(Ty) + 63) / 64;
|
SizeRegs = (getContext().getTypeSize(Ty) + 63) / 64;
|
||||||
} else {
|
} else {
|
||||||
ElemTy = llvm::Type::getInt32Ty(VMContext);
|
ElemTy = llvm::Type::getInt32Ty(getVMContext());
|
||||||
SizeRegs = (Context.getTypeSize(Ty) + 31) / 32;
|
SizeRegs = (getContext().getTypeSize(Ty) + 31) / 32;
|
||||||
}
|
}
|
||||||
std::vector<const llvm::Type*> LLVMFields;
|
std::vector<const llvm::Type*> LLVMFields;
|
||||||
LLVMFields.push_back(llvm::ArrayType::get(ElemTy, SizeRegs));
|
LLVMFields.push_back(llvm::ArrayType::get(ElemTy, SizeRegs));
|
||||||
const llvm::Type* STy = llvm::StructType::get(VMContext, LLVMFields, true);
|
const llvm::Type* STy = llvm::StructType::get(getVMContext(), LLVMFields,
|
||||||
|
true);
|
||||||
return ABIArgInfo::getCoerce(STy);
|
return ABIArgInfo::getCoerce(STy);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isIntegerLikeType(QualType Ty,
|
static bool isIntegerLikeType(QualType Ty, ASTContext &Context,
|
||||||
ASTContext &Context,
|
|
||||||
llvm::LLVMContext &VMContext) {
|
llvm::LLVMContext &VMContext) {
|
||||||
// APCS, C Language Calling Conventions, Non-Simple Return Values: A structure
|
// APCS, C Language Calling Conventions, Non-Simple Return Values: A structure
|
||||||
// is called integer-like if its size is less than or equal to one word, and
|
// is called integer-like if its size is less than or equal to one word, and
|
||||||
|
@ -2083,9 +2044,7 @@ static bool isIntegerLikeType(QualType Ty,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy,
|
ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy) const {
|
||||||
ASTContext &Context,
|
|
||||||
llvm::LLVMContext &VMContext) const {
|
|
||||||
if (RetTy->isVoidType())
|
if (RetTy->isVoidType())
|
||||||
return ABIArgInfo::getIgnore();
|
return ABIArgInfo::getIgnore();
|
||||||
|
|
||||||
|
@ -2105,7 +2064,7 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy,
|
||||||
|
|
||||||
// Are we following APCS?
|
// Are we following APCS?
|
||||||
if (getABIKind() == APCS) {
|
if (getABIKind() == APCS) {
|
||||||
if (isEmptyRecord(Context, RetTy, false))
|
if (isEmptyRecord(getContext(), RetTy, false))
|
||||||
return ABIArgInfo::getIgnore();
|
return ABIArgInfo::getIgnore();
|
||||||
|
|
||||||
// Complex types are all returned as packed integers.
|
// Complex types are all returned as packed integers.
|
||||||
|
@ -2113,18 +2072,18 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy,
|
||||||
// FIXME: Consider using 2 x vector types if the back end handles them
|
// FIXME: Consider using 2 x vector types if the back end handles them
|
||||||
// correctly.
|
// correctly.
|
||||||
if (RetTy->isAnyComplexType())
|
if (RetTy->isAnyComplexType())
|
||||||
return ABIArgInfo::getCoerce(llvm::IntegerType::get(
|
return ABIArgInfo::getCoerce(llvm::IntegerType::get(getVMContext(),
|
||||||
VMContext, Context.getTypeSize(RetTy)));
|
getContext().getTypeSize(RetTy)));
|
||||||
|
|
||||||
// Integer like structures are returned in r0.
|
// Integer like structures are returned in r0.
|
||||||
if (isIntegerLikeType(RetTy, Context, VMContext)) {
|
if (isIntegerLikeType(RetTy, getContext(), getVMContext())) {
|
||||||
// Return in the smallest viable integer type.
|
// Return in the smallest viable integer type.
|
||||||
uint64_t Size = Context.getTypeSize(RetTy);
|
uint64_t Size = getContext().getTypeSize(RetTy);
|
||||||
if (Size <= 8)
|
if (Size <= 8)
|
||||||
return ABIArgInfo::getCoerce(llvm::Type::getInt8Ty(VMContext));
|
return ABIArgInfo::getCoerce(llvm::Type::getInt8Ty(getVMContext()));
|
||||||
if (Size <= 16)
|
if (Size <= 16)
|
||||||
return ABIArgInfo::getCoerce(llvm::Type::getInt16Ty(VMContext));
|
return ABIArgInfo::getCoerce(llvm::Type::getInt16Ty(getVMContext()));
|
||||||
return ABIArgInfo::getCoerce(llvm::Type::getInt32Ty(VMContext));
|
return ABIArgInfo::getCoerce(llvm::Type::getInt32Ty(getVMContext()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise return in memory.
|
// Otherwise return in memory.
|
||||||
|
@ -2133,19 +2092,19 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy,
|
||||||
|
|
||||||
// Otherwise this is an AAPCS variant.
|
// Otherwise this is an AAPCS variant.
|
||||||
|
|
||||||
if (isEmptyRecord(Context, RetTy, true))
|
if (isEmptyRecord(getContext(), RetTy, true))
|
||||||
return ABIArgInfo::getIgnore();
|
return ABIArgInfo::getIgnore();
|
||||||
|
|
||||||
// Aggregates <= 4 bytes are returned in r0; other aggregates
|
// Aggregates <= 4 bytes are returned in r0; other aggregates
|
||||||
// are returned indirectly.
|
// are returned indirectly.
|
||||||
uint64_t Size = Context.getTypeSize(RetTy);
|
uint64_t Size = getContext().getTypeSize(RetTy);
|
||||||
if (Size <= 32) {
|
if (Size <= 32) {
|
||||||
// Return in the smallest viable integer type.
|
// Return in the smallest viable integer type.
|
||||||
if (Size <= 8)
|
if (Size <= 8)
|
||||||
return ABIArgInfo::getCoerce(llvm::Type::getInt8Ty(VMContext));
|
return ABIArgInfo::getCoerce(llvm::Type::getInt8Ty(getVMContext()));
|
||||||
if (Size <= 16)
|
if (Size <= 16)
|
||||||
return ABIArgInfo::getCoerce(llvm::Type::getInt16Ty(VMContext));
|
return ABIArgInfo::getCoerce(llvm::Type::getInt16Ty(getVMContext()));
|
||||||
return ABIArgInfo::getCoerce(llvm::Type::getInt32Ty(VMContext));
|
return ABIArgInfo::getCoerce(llvm::Type::getInt32Ty(getVMContext()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ABIArgInfo::getIndirect(0);
|
return ABIArgInfo::getIndirect(0);
|
||||||
|
@ -2175,21 +2134,19 @@ llvm::Value *ARMABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||||
return AddrTyped;
|
return AddrTyped;
|
||||||
}
|
}
|
||||||
|
|
||||||
ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy,
|
ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) const {
|
||||||
ASTContext &Context,
|
if (RetTy->isVoidType())
|
||||||
llvm::LLVMContext &VMContext) const {
|
|
||||||
if (RetTy->isVoidType()) {
|
|
||||||
return ABIArgInfo::getIgnore();
|
return ABIArgInfo::getIgnore();
|
||||||
} else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
|
|
||||||
return ABIArgInfo::getIndirect(0);
|
|
||||||
} else {
|
|
||||||
// Treat an enum type as its underlying type.
|
|
||||||
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
|
|
||||||
RetTy = EnumTy->getDecl()->getIntegerType();
|
|
||||||
|
|
||||||
return (RetTy->isPromotableIntegerType() ?
|
if (CodeGenFunction::hasAggregateLLVMType(RetTy))
|
||||||
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
|
return ABIArgInfo::getIndirect(0);
|
||||||
}
|
|
||||||
|
// Treat an enum type as its underlying type.
|
||||||
|
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
|
||||||
|
RetTy = EnumTy->getDecl()->getIntegerType();
|
||||||
|
|
||||||
|
return (RetTy->isPromotableIntegerType() ?
|
||||||
|
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -2204,21 +2161,16 @@ public:
|
||||||
|
|
||||||
bool isPromotableIntegerType(QualType Ty) const;
|
bool isPromotableIntegerType(QualType Ty) const;
|
||||||
|
|
||||||
ABIArgInfo classifyReturnType(QualType RetTy, ASTContext &Context,
|
ABIArgInfo classifyReturnType(QualType RetTy) const;
|
||||||
llvm::LLVMContext &VMContext) const;
|
ABIArgInfo classifyArgumentType(QualType RetTy) const;
|
||||||
|
|
||||||
ABIArgInfo classifyArgumentType(QualType RetTy, ASTContext &Context,
|
virtual void computeInfo(CGFunctionInfo &FI,
|
||||||
llvm::LLVMContext &VMContext) const;
|
|
||||||
|
|
||||||
virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context,
|
|
||||||
llvm::LLVMContext &VMContext,
|
|
||||||
const llvm::Type *const *PrefTypes,
|
const llvm::Type *const *PrefTypes,
|
||||||
unsigned NumPrefTypes) const {
|
unsigned NumPrefTypes) const {
|
||||||
FI.getReturnInfo() = classifyReturnType(FI.getReturnType(),
|
FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
|
||||||
Context, VMContext);
|
|
||||||
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
|
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
|
||||||
it != ie; ++it)
|
it != ie; ++it)
|
||||||
it->info = classifyArgumentType(it->type, Context, VMContext);
|
it->info = classifyArgumentType(it->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||||
|
@ -2260,28 +2212,22 @@ llvm::Value *SystemZABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy,
|
ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy) const {
|
||||||
ASTContext &Context,
|
if (RetTy->isVoidType())
|
||||||
llvm::LLVMContext &VMContext) const {
|
|
||||||
if (RetTy->isVoidType()) {
|
|
||||||
return ABIArgInfo::getIgnore();
|
return ABIArgInfo::getIgnore();
|
||||||
} else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
|
if (CodeGenFunction::hasAggregateLLVMType(RetTy))
|
||||||
return ABIArgInfo::getIndirect(0);
|
return ABIArgInfo::getIndirect(0);
|
||||||
} else {
|
|
||||||
return (isPromotableIntegerType(RetTy) ?
|
return (isPromotableIntegerType(RetTy) ?
|
||||||
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
|
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty,
|
ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const {
|
||||||
ASTContext &Context,
|
if (CodeGenFunction::hasAggregateLLVMType(Ty))
|
||||||
llvm::LLVMContext &VMContext) const {
|
|
||||||
if (CodeGenFunction::hasAggregateLLVMType(Ty)) {
|
|
||||||
return ABIArgInfo::getIndirect(0);
|
return ABIArgInfo::getIndirect(0);
|
||||||
} else {
|
|
||||||
return (isPromotableIntegerType(Ty) ?
|
return (isPromotableIntegerType(Ty) ?
|
||||||
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
|
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
Loading…
Reference in New Issue