aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/TargetInfo.cpp
diff options
context:
space:
mode:
authorBen Shi <powerman1st@163.com>2021-06-29 11:15:00 +0800
committerBen Shi <ben.shi@streamcomputing.com>2021-06-29 11:32:39 +0800
commitc94c8d8b5d999c97ea424b35a1cb540d2a1d3bc6 (patch)
tree584b91ec3b91de98950bf6561381280d14623555 /clang/lib/CodeGen/TargetInfo.cpp
parentae79854e1c597962b74cb13293fcd5d31a2ca9bc (diff)
downloadllvm-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.cpp29
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 {