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 Andricvoid 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 AndricCodeGen::createM68kTargetCodeGenInfo(CodeGenModule &CGM) { 54*06c3fb27SDimitry Andric return std::make_unique<M68kTargetCodeGenInfo>(CGM.getTypes()); 55*06c3fb27SDimitry Andric } 56