xref: /llvm-project/clang/lib/CodeGen/Targets/MSP430.cpp (revision 6d973b4548e281d0b8e75e85833804bb45b6a0e8)
1992cb984SSergei Barannikov //===- MSP430.cpp ---------------------------------------------------------===//
2992cb984SSergei Barannikov //
3992cb984SSergei Barannikov // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4992cb984SSergei Barannikov // See https://llvm.org/LICENSE.txt for license information.
5992cb984SSergei Barannikov // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6992cb984SSergei Barannikov //
7992cb984SSergei Barannikov //===----------------------------------------------------------------------===//
8992cb984SSergei Barannikov 
9992cb984SSergei Barannikov #include "ABIInfoImpl.h"
10992cb984SSergei Barannikov #include "TargetInfo.h"
11992cb984SSergei Barannikov 
12992cb984SSergei Barannikov using namespace clang;
13992cb984SSergei Barannikov using namespace clang::CodeGen;
14992cb984SSergei Barannikov 
15992cb984SSergei Barannikov //===----------------------------------------------------------------------===//
16992cb984SSergei Barannikov // MSP430 ABI Implementation
17992cb984SSergei Barannikov //===----------------------------------------------------------------------===//
18992cb984SSergei Barannikov 
19992cb984SSergei Barannikov namespace {
20992cb984SSergei Barannikov 
21992cb984SSergei Barannikov class MSP430ABIInfo : public DefaultABIInfo {
complexArgInfo()22992cb984SSergei Barannikov   static ABIArgInfo complexArgInfo() {
23992cb984SSergei Barannikov     ABIArgInfo Info = ABIArgInfo::getDirect();
24992cb984SSergei Barannikov     Info.setCanBeFlattened(false);
25992cb984SSergei Barannikov     return Info;
26992cb984SSergei Barannikov   }
27992cb984SSergei Barannikov 
28992cb984SSergei Barannikov public:
MSP430ABIInfo(CodeGenTypes & CGT)29992cb984SSergei Barannikov   MSP430ABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}
30992cb984SSergei Barannikov 
classifyReturnType(QualType RetTy) const31992cb984SSergei Barannikov   ABIArgInfo classifyReturnType(QualType RetTy) const {
32992cb984SSergei Barannikov     if (RetTy->isAnyComplexType())
33992cb984SSergei Barannikov       return complexArgInfo();
34992cb984SSergei Barannikov 
35992cb984SSergei Barannikov     return DefaultABIInfo::classifyReturnType(RetTy);
36992cb984SSergei Barannikov   }
37992cb984SSergei Barannikov 
classifyArgumentType(QualType RetTy) const38992cb984SSergei Barannikov   ABIArgInfo classifyArgumentType(QualType RetTy) const {
39992cb984SSergei Barannikov     if (RetTy->isAnyComplexType())
40992cb984SSergei Barannikov       return complexArgInfo();
41992cb984SSergei Barannikov 
42992cb984SSergei Barannikov     return DefaultABIInfo::classifyArgumentType(RetTy);
43992cb984SSergei Barannikov   }
44992cb984SSergei Barannikov 
45992cb984SSergei Barannikov   // Just copy the original implementations because
46992cb984SSergei Barannikov   // DefaultABIInfo::classify{Return,Argument}Type() are not virtual
computeInfo(CGFunctionInfo & FI) const47992cb984SSergei Barannikov   void computeInfo(CGFunctionInfo &FI) const override {
48992cb984SSergei Barannikov     if (!getCXXABI().classifyReturnType(FI))
49992cb984SSergei Barannikov       FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
50992cb984SSergei Barannikov     for (auto &I : FI.arguments())
51992cb984SSergei Barannikov       I.info = classifyArgumentType(I.type);
52992cb984SSergei Barannikov   }
53992cb984SSergei Barannikov 
EmitVAArg(CodeGenFunction & CGF,Address VAListAddr,QualType Ty,AggValueSlot Slot) const54*6d973b45SMariya Podchishchaeva   RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
55*6d973b45SMariya Podchishchaeva                    AggValueSlot Slot) const override {
56*6d973b45SMariya Podchishchaeva     return CGF.EmitLoadOfAnyValue(
57*6d973b45SMariya Podchishchaeva         CGF.MakeAddrLValue(
58*6d973b45SMariya Podchishchaeva             EmitVAArgInstr(CGF, VAListAddr, Ty, classifyArgumentType(Ty)), Ty),
59*6d973b45SMariya Podchishchaeva         Slot);
60992cb984SSergei Barannikov   }
61992cb984SSergei Barannikov };
62992cb984SSergei Barannikov 
63992cb984SSergei Barannikov class MSP430TargetCodeGenInfo : public TargetCodeGenInfo {
64992cb984SSergei Barannikov public:
MSP430TargetCodeGenInfo(CodeGenTypes & CGT)65992cb984SSergei Barannikov   MSP430TargetCodeGenInfo(CodeGenTypes &CGT)
66992cb984SSergei Barannikov       : TargetCodeGenInfo(std::make_unique<MSP430ABIInfo>(CGT)) {}
67992cb984SSergei Barannikov   void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
68992cb984SSergei Barannikov                            CodeGen::CodeGenModule &M) const override;
69992cb984SSergei Barannikov };
70992cb984SSergei Barannikov 
71992cb984SSergei Barannikov }
72992cb984SSergei Barannikov 
setTargetAttributes(const Decl * D,llvm::GlobalValue * GV,CodeGen::CodeGenModule & M) const73992cb984SSergei Barannikov void MSP430TargetCodeGenInfo::setTargetAttributes(
74992cb984SSergei Barannikov     const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const {
75992cb984SSergei Barannikov   if (GV->isDeclaration())
76992cb984SSergei Barannikov     return;
77992cb984SSergei Barannikov   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
78992cb984SSergei Barannikov     const auto *InterruptAttr = FD->getAttr<MSP430InterruptAttr>();
79992cb984SSergei Barannikov     if (!InterruptAttr)
80992cb984SSergei Barannikov       return;
81992cb984SSergei Barannikov 
82992cb984SSergei Barannikov     // Handle 'interrupt' attribute:
83992cb984SSergei Barannikov     llvm::Function *F = cast<llvm::Function>(GV);
84992cb984SSergei Barannikov 
85992cb984SSergei Barannikov     // Step 1: Set ISR calling convention.
86992cb984SSergei Barannikov     F->setCallingConv(llvm::CallingConv::MSP430_INTR);
87992cb984SSergei Barannikov 
88992cb984SSergei Barannikov     // Step 2: Add attributes goodness.
89992cb984SSergei Barannikov     F->addFnAttr(llvm::Attribute::NoInline);
90992cb984SSergei Barannikov     F->addFnAttr("interrupt", llvm::utostr(InterruptAttr->getNumber()));
91992cb984SSergei Barannikov   }
92992cb984SSergei Barannikov }
93992cb984SSergei Barannikov 
94992cb984SSergei Barannikov std::unique_ptr<TargetCodeGenInfo>
createMSP430TargetCodeGenInfo(CodeGenModule & CGM)95992cb984SSergei Barannikov CodeGen::createMSP430TargetCodeGenInfo(CodeGenModule &CGM) {
96992cb984SSergei Barannikov   return std::make_unique<MSP430TargetCodeGenInfo>(CGM.getTypes());
97992cb984SSergei Barannikov }
98