//===- MSP430.cpp ---------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "ABIInfoImpl.h" #include "TargetInfo.h" using namespace clang; using namespace clang::CodeGen; //===----------------------------------------------------------------------===// // MSP430 ABI Implementation //===----------------------------------------------------------------------===// namespace { class MSP430ABIInfo : public DefaultABIInfo { static ABIArgInfo complexArgInfo() { ABIArgInfo Info = ABIArgInfo::getDirect(); Info.setCanBeFlattened(false); return Info; } public: MSP430ABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} ABIArgInfo classifyReturnType(QualType RetTy) const { if (RetTy->isAnyComplexType()) return complexArgInfo(); return DefaultABIInfo::classifyReturnType(RetTy); } ABIArgInfo classifyArgumentType(QualType RetTy) const { if (RetTy->isAnyComplexType()) return complexArgInfo(); return DefaultABIInfo::classifyArgumentType(RetTy); } // Just copy the original implementations because // DefaultABIInfo::classify{Return,Argument}Type() are not virtual void computeInfo(CGFunctionInfo &FI) const override { if (!getCXXABI().classifyReturnType(FI)) FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); for (auto &I : FI.arguments()) I.info = classifyArgumentType(I.type); } Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty) const override { return EmitVAArgInstr(CGF, VAListAddr, Ty, classifyArgumentType(Ty)); } }; class MSP430TargetCodeGenInfo : public TargetCodeGenInfo { public: MSP430TargetCodeGenInfo(CodeGenTypes &CGT) : TargetCodeGenInfo(std::make_unique(CGT)) {} void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const override; }; } void MSP430TargetCodeGenInfo::setTargetAttributes( const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const { if (GV->isDeclaration()) return; if (const FunctionDecl *FD = dyn_cast_or_null(D)) { const auto *InterruptAttr = FD->getAttr(); if (!InterruptAttr) return; // Handle 'interrupt' attribute: llvm::Function *F = cast(GV); // Step 1: Set ISR calling convention. F->setCallingConv(llvm::CallingConv::MSP430_INTR); // Step 2: Add attributes goodness. F->addFnAttr(llvm::Attribute::NoInline); F->addFnAttr("interrupt", llvm::utostr(InterruptAttr->getNumber())); } } std::unique_ptr CodeGen::createMSP430TargetCodeGenInfo(CodeGenModule &CGM) { return std::make_unique(CGM.getTypes()); }