summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/ABIInfo.h7
-rw-r--r--clang/lib/CodeGen/CGCall.cpp46
-rw-r--r--clang/lib/CodeGen/TargetABIInfo.cpp28
3 files changed, 52 insertions, 29 deletions
diff --git a/clang/lib/CodeGen/ABIInfo.h b/clang/lib/CodeGen/ABIInfo.h
index 44af0c476aa..58e5a778cf3 100644
--- a/clang/lib/CodeGen/ABIInfo.h
+++ b/clang/lib/CodeGen/ABIInfo.h
@@ -44,6 +44,9 @@ namespace clang {
/// converted LLVM type. Complex and structure types
/// are passed using first class aggregates.
+ Extend, /// Valid only for integer argument types. Same as 'direct'
+ /// but also emit a zero/sign extension attribute.
+
Indirect, /// Pass the argument indirectly via a hidden pointer
/// with the specified alignment (0 indicates default
/// alignment).
@@ -79,6 +82,9 @@ namespace clang {
static ABIArgInfo getDirect() {
return ABIArgInfo(Direct);
}
+ static ABIArgInfo getExtend() {
+ return ABIArgInfo(Extend);
+ }
static ABIArgInfo getIgnore() {
return ABIArgInfo(Ignore);
}
@@ -94,6 +100,7 @@ namespace clang {
Kind getKind() const { return TheKind; }
bool isDirect() const { return TheKind == Direct; }
+ bool isExtend() const { return TheKind == Extend; }
bool isIgnore() const { return TheKind == Ignore; }
bool isCoerce() const { return TheKind == Coerce; }
bool isIndirect() const { return TheKind == Indirect; }
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index b46e860b2ef..b10b9c2d9de 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -314,6 +314,7 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool IsVariadic) {
case ABIArgInfo::Expand:
assert(0 && "Invalid ABI kind for return argument");
+ case ABIArgInfo::Extend:
case ABIArgInfo::Direct:
ResultType = ConvertType(RetTy);
break;
@@ -353,7 +354,8 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool IsVariadic) {
ArgTys.push_back(llvm::PointerType::getUnqual(LTy));
break;
}
-
+
+ case ABIArgInfo::Extend:
case ABIArgInfo::Direct:
ArgTys.push_back(ConvertType(it->type));
break;
@@ -394,14 +396,14 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
unsigned Index = 1;
const ABIArgInfo &RetAI = FI.getReturnInfo();
switch (RetAI.getKind()) {
+ case ABIArgInfo::Extend:
+ if (RetTy->isSignedIntegerType()) {
+ RetAttrs |= llvm::Attribute::SExt;
+ } else if (RetTy->isUnsignedIntegerType()) {
+ RetAttrs |= llvm::Attribute::ZExt;
+ }
+ // FALLTHROUGH
case ABIArgInfo::Direct:
- if (RetTy->isPromotableIntegerType()) {
- if (RetTy->isSignedIntegerType()) {
- RetAttrs |= llvm::Attribute::SExt;
- } else if (RetTy->isUnsignedIntegerType()) {
- RetAttrs |= llvm::Attribute::ZExt;
- }
- }
break;
case ABIArgInfo::Indirect:
@@ -452,15 +454,15 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
FuncAttrs &= ~(llvm::Attribute::ReadOnly |
llvm::Attribute::ReadNone);
break;
-
+
+ case ABIArgInfo::Extend:
+ if (ParamType->isSignedIntegerType()) {
+ Attributes |= llvm::Attribute::SExt;
+ } else if (ParamType->isUnsignedIntegerType()) {
+ Attributes |= llvm::Attribute::ZExt;
+ }
+ // FALLS THROUGH
case ABIArgInfo::Direct:
- if (ParamType->isPromotableIntegerType()) {
- if (ParamType->isSignedIntegerType()) {
- Attributes |= llvm::Attribute::SExt;
- } else if (ParamType->isUnsignedIntegerType()) {
- Attributes |= llvm::Attribute::ZExt;
- }
- }
if (RegParm > 0 &&
(ParamType->isIntegerType() || ParamType->isPointerType())) {
RegParm -=
@@ -536,7 +538,8 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
EmitParmDecl(*Arg, V);
break;
}
-
+
+ case ABIArgInfo::Extend:
case ABIArgInfo::Direct: {
assert(AI != Fn->arg_end() && "Argument mismatch!");
llvm::Value* V = AI;
@@ -618,10 +621,10 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
llvm::Value *RV = 0;
// Functions with no result always return void.
- if (ReturnValue) {
+ if (ReturnValue) {
QualType RetTy = FI.getReturnType();
const ABIArgInfo &RetAI = FI.getReturnInfo();
-
+
switch (RetAI.getKind()) {
case ABIArgInfo::Indirect:
if (RetTy->isAnyComplexType()) {
@@ -630,11 +633,12 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
} else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
EmitAggregateCopy(CurFn->arg_begin(), ReturnValue, RetTy);
} else {
- EmitStoreOfScalar(Builder.CreateLoad(ReturnValue), CurFn->arg_begin(),
+ EmitStoreOfScalar(Builder.CreateLoad(ReturnValue), CurFn->arg_begin(),
false, RetTy);
}
break;
+ case ABIArgInfo::Extend:
case ABIArgInfo::Direct:
// The internal return value temp always will have
// pointer-to-return-type type.
@@ -705,6 +709,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
}
break;
+ case ABIArgInfo::Extend:
case ABIArgInfo::Direct:
if (RV.isScalar()) {
Args.push_back(RV.getScalarVal());
@@ -791,6 +796,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
return RValue::getAggregate(Args[0]);
return RValue::get(EmitLoadOfScalar(Args[0], false, RetTy));
+ case ABIArgInfo::Extend:
case ABIArgInfo::Direct:
if (RetTy->isAnyComplexType()) {
llvm::Value *Real = Builder.CreateExtractValue(CI, 0);
diff --git a/clang/lib/CodeGen/TargetABIInfo.cpp b/clang/lib/CodeGen/TargetABIInfo.cpp
index 573ffed10a0..6f7bea2340a 100644
--- a/clang/lib/CodeGen/TargetABIInfo.cpp
+++ b/clang/lib/CodeGen/TargetABIInfo.cpp
@@ -28,6 +28,9 @@ void ABIArgInfo::dump() const {
case Direct:
fprintf(stderr, "Direct");
break;
+ case Extend:
+ fprintf(stderr, "Extend");
+ break;
case Ignore:
fprintf(stderr, "Ignore");
break;
@@ -342,7 +345,8 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
return ABIArgInfo::getIndirect(0);
} else {
- return ABIArgInfo::getDirect();
+ return (RetTy->isPromotableIntegerType() ?
+ ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
}
}
@@ -371,7 +375,8 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
return ABIArgInfo::getIndirect(0);
} else {
- return ABIArgInfo::getDirect();
+ return (Ty->isPromotableIntegerType() ?
+ ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
}
}
@@ -750,8 +755,8 @@ ABIArgInfo X86_64ABIInfo::getCoerceResult(QualType Ty,
// Integer and pointer types will end up in a general purpose
// register.
if (Ty->isIntegralType() || Ty->isPointerType())
- return ABIArgInfo::getDirect();
-
+ return (Ty->isPromotableIntegerType() ?
+ ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
} else if (CoerceTo == llvm::Type::DoubleTy) {
// FIXME: It would probably be better to make CGFunctionInfo only map using
// canonical types than to canonize here.
@@ -771,7 +776,8 @@ ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty,
// If this is a scalar LLVM value then assume LLVM will pass it in the right
// place naturally.
if (!CodeGenFunction::hasAggregateLLVMType(Ty))
- return ABIArgInfo::getDirect();
+ return (Ty->isPromotableIntegerType() ?
+ ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
// FIXME: Set alignment correctly.
return ABIArgInfo::getIndirect(0);
@@ -1267,7 +1273,8 @@ void ARMABIInfo::computeInfo(CGFunctionInfo &FI, ASTContext &Context) const {
ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty,
ASTContext &Context) const {
if (!CodeGenFunction::hasAggregateLLVMType(Ty)) {
- return ABIArgInfo::getDirect();
+ return (Ty->isPromotableIntegerType() ?
+ ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
}
// FIXME: This is kind of nasty... but there isn't much choice because the ARM
// backend doesn't support byval.
@@ -1299,7 +1306,8 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy,
return ABIArgInfo::getCoerce(llvm::Type::Int32Ty);
return ABIArgInfo::getIndirect(0);
} else {
- return ABIArgInfo::getDirect();
+ return (RetTy->isPromotableIntegerType() ?
+ ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
}
}
@@ -1335,7 +1343,8 @@ ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy,
} else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
return ABIArgInfo::getIndirect(0);
} else {
- return ABIArgInfo::getDirect();
+ return (RetTy->isPromotableIntegerType() ?
+ ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
}
}
@@ -1344,7 +1353,8 @@ ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty,
if (CodeGenFunction::hasAggregateLLVMType(Ty)) {
return ABIArgInfo::getIndirect(0);
} else {
- return ABIArgInfo::getDirect();
+ return (Ty->isPromotableIntegerType() ?
+ ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
}
}
OpenPOWER on IntegriCloud