xref: /llvm-project/clang/lib/CodeGen/Targets/M68k.cpp (revision 992cb98462abb7630e87003516b75b241628f64c)
1*992cb984SSergei Barannikov //===- M68k.cpp -----------------------------------------------------------===//
2*992cb984SSergei Barannikov //
3*992cb984SSergei Barannikov // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*992cb984SSergei Barannikov // See https://llvm.org/LICENSE.txt for license information.
5*992cb984SSergei Barannikov // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*992cb984SSergei Barannikov //
7*992cb984SSergei Barannikov //===----------------------------------------------------------------------===//
8*992cb984SSergei Barannikov 
9*992cb984SSergei Barannikov #include "ABIInfoImpl.h"
10*992cb984SSergei Barannikov #include "TargetInfo.h"
11*992cb984SSergei Barannikov 
12*992cb984SSergei Barannikov using namespace clang;
13*992cb984SSergei Barannikov using namespace clang::CodeGen;
14*992cb984SSergei Barannikov 
15*992cb984SSergei Barannikov //===----------------------------------------------------------------------===//
16*992cb984SSergei Barannikov // M68k ABI Implementation
17*992cb984SSergei Barannikov //===----------------------------------------------------------------------===//
18*992cb984SSergei Barannikov 
19*992cb984SSergei Barannikov namespace {
20*992cb984SSergei Barannikov 
21*992cb984SSergei Barannikov class M68kTargetCodeGenInfo : public TargetCodeGenInfo {
22*992cb984SSergei Barannikov public:
M68kTargetCodeGenInfo(CodeGenTypes & CGT)23*992cb984SSergei Barannikov   M68kTargetCodeGenInfo(CodeGenTypes &CGT)
24*992cb984SSergei Barannikov       : TargetCodeGenInfo(std::make_unique<DefaultABIInfo>(CGT)) {}
25*992cb984SSergei Barannikov   void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
26*992cb984SSergei Barannikov                            CodeGen::CodeGenModule &M) const override;
27*992cb984SSergei Barannikov };
28*992cb984SSergei Barannikov 
29*992cb984SSergei Barannikov } // namespace
30*992cb984SSergei Barannikov 
setTargetAttributes(const Decl * D,llvm::GlobalValue * GV,CodeGen::CodeGenModule & M) const31*992cb984SSergei Barannikov void M68kTargetCodeGenInfo::setTargetAttributes(
32*992cb984SSergei Barannikov     const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const {
33*992cb984SSergei Barannikov   if (const auto *FD = dyn_cast_or_null<FunctionDecl>(D)) {
34*992cb984SSergei Barannikov     if (const auto *attr = FD->getAttr<M68kInterruptAttr>()) {
35*992cb984SSergei Barannikov       // Handle 'interrupt' attribute:
36*992cb984SSergei Barannikov       llvm::Function *F = cast<llvm::Function>(GV);
37*992cb984SSergei Barannikov 
38*992cb984SSergei Barannikov       // Step 1: Set ISR calling convention.
39*992cb984SSergei Barannikov       F->setCallingConv(llvm::CallingConv::M68k_INTR);
40*992cb984SSergei Barannikov 
41*992cb984SSergei Barannikov       // Step 2: Add attributes goodness.
42*992cb984SSergei Barannikov       F->addFnAttr(llvm::Attribute::NoInline);
43*992cb984SSergei Barannikov 
44*992cb984SSergei Barannikov       // Step 3: Emit ISR vector alias.
45*992cb984SSergei Barannikov       unsigned Num = attr->getNumber() / 2;
46*992cb984SSergei Barannikov       llvm::GlobalAlias::create(llvm::Function::ExternalLinkage,
47*992cb984SSergei Barannikov                                 "__isr_" + Twine(Num), F);
48*992cb984SSergei Barannikov     }
49*992cb984SSergei Barannikov   }
50*992cb984SSergei Barannikov }
51*992cb984SSergei Barannikov 
52*992cb984SSergei Barannikov std::unique_ptr<TargetCodeGenInfo>
createM68kTargetCodeGenInfo(CodeGenModule & CGM)53*992cb984SSergei Barannikov CodeGen::createM68kTargetCodeGenInfo(CodeGenModule &CGM) {
54*992cb984SSergei Barannikov   return std::make_unique<M68kTargetCodeGenInfo>(CGM.getTypes());
55*992cb984SSergei Barannikov }
56