diff options
author | Ben Shi <powerman1st@163.com> | 2021-06-29 11:15:00 +0800 |
---|---|---|
committer | Ben Shi <ben.shi@streamcomputing.com> | 2021-06-29 11:32:39 +0800 |
commit | c94c8d8b5d999c97ea424b35a1cb540d2a1d3bc6 (patch) | |
tree | 584b91ec3b91de98950bf6561381280d14623555 /clang/lib/CodeGen/TargetInfo.cpp | |
parent | ae79854e1c597962b74cb13293fcd5d31a2ca9bc (diff) | |
download | llvm-c94c8d8b5d999c97ea424b35a1cb540d2a1d3bc6.zip llvm-c94c8d8b5d999c97ea424b35a1cb540d2a1d3bc6.tar.gz llvm-c94c8d8b5d999c97ea424b35a1cb540d2a1d3bc6.tar.bz2 |
[AVR][clang] Fix wrong calling convention in functions return struct type
According to AVR ABI (https://gcc.gnu.org/wiki/avr-gcc), returned struct value
within size 1-8 bytes should be returned directly (via register r18-r25), while
larger ones should be returned via an implicit struct pointer argument.
Reviewed By: dylanmckay
Differential Revision: https://reviews.llvm.org/D99237
Diffstat (limited to 'clang/lib/CodeGen/TargetInfo.cpp')
-rw-r--r-- | clang/lib/CodeGen/TargetInfo.cpp | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index e9565a5..035c131 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -8154,14 +8154,39 @@ void M68kTargetCodeGenInfo::setTargetAttributes( } //===----------------------------------------------------------------------===// -// AVR ABI Implementation. +// AVR ABI Implementation. Documented at +// https://gcc.gnu.org/wiki/avr-gcc#Calling_Convention +// https://gcc.gnu.org/wiki/avr-gcc#Reduced_Tiny //===----------------------------------------------------------------------===// namespace { +class AVRABIInfo : public DefaultABIInfo { +public: + AVRABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} + + ABIArgInfo classifyReturnType(QualType Ty) const { + // A return struct with size less than or equal to 8 bytes is returned + // directly via registers R18-R25. + if (isAggregateTypeForABI(Ty) && getContext().getTypeSize(Ty) <= 64) + return ABIArgInfo::getDirect(); + else + return DefaultABIInfo::classifyReturnType(Ty); + } + + // Just copy the original implementation of DefaultABIInfo::computeInfo(), + // since DefaultABIInfo::classify{Return,Argument}Type() are not virtual. + void computeInfo(CGFunctionInfo &FI) const override { + if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + for (auto &I : FI.arguments()) + I.info = classifyArgumentType(I.type); + } +}; + class AVRTargetCodeGenInfo : public TargetCodeGenInfo { public: AVRTargetCodeGenInfo(CodeGenTypes &CGT) - : TargetCodeGenInfo(std::make_unique<DefaultABIInfo>(CGT)) {} + : TargetCodeGenInfo(std::make_unique<AVRABIInfo>(CGT)) {} LangAS getGlobalVarAddressSpace(CodeGenModule &CGM, const VarDecl *D) const override { |