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