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