diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/ABIInfo.h | 7 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 46 | ||||
-rw-r--r-- | clang/lib/CodeGen/TargetABIInfo.cpp | 28 |
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()); } } |