1*06c3fb27SDimitry Andric //===- MSP430.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 // MSP430 ABI Implementation 17*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 18*06c3fb27SDimitry Andric 19*06c3fb27SDimitry Andric namespace { 20*06c3fb27SDimitry Andric 21*06c3fb27SDimitry Andric class MSP430ABIInfo : public DefaultABIInfo { 22*06c3fb27SDimitry Andric static ABIArgInfo complexArgInfo() { 23*06c3fb27SDimitry Andric ABIArgInfo Info = ABIArgInfo::getDirect(); 24*06c3fb27SDimitry Andric Info.setCanBeFlattened(false); 25*06c3fb27SDimitry Andric return Info; 26*06c3fb27SDimitry Andric } 27*06c3fb27SDimitry Andric 28*06c3fb27SDimitry Andric public: 29*06c3fb27SDimitry Andric MSP430ABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} 30*06c3fb27SDimitry Andric 31*06c3fb27SDimitry Andric ABIArgInfo classifyReturnType(QualType RetTy) const { 32*06c3fb27SDimitry Andric if (RetTy->isAnyComplexType()) 33*06c3fb27SDimitry Andric return complexArgInfo(); 34*06c3fb27SDimitry Andric 35*06c3fb27SDimitry Andric return DefaultABIInfo::classifyReturnType(RetTy); 36*06c3fb27SDimitry Andric } 37*06c3fb27SDimitry Andric 38*06c3fb27SDimitry Andric ABIArgInfo classifyArgumentType(QualType RetTy) const { 39*06c3fb27SDimitry Andric if (RetTy->isAnyComplexType()) 40*06c3fb27SDimitry Andric return complexArgInfo(); 41*06c3fb27SDimitry Andric 42*06c3fb27SDimitry Andric return DefaultABIInfo::classifyArgumentType(RetTy); 43*06c3fb27SDimitry Andric } 44*06c3fb27SDimitry Andric 45*06c3fb27SDimitry Andric // Just copy the original implementations because 46*06c3fb27SDimitry Andric // DefaultABIInfo::classify{Return,Argument}Type() are not virtual 47*06c3fb27SDimitry Andric void computeInfo(CGFunctionInfo &FI) const override { 48*06c3fb27SDimitry Andric if (!getCXXABI().classifyReturnType(FI)) 49*06c3fb27SDimitry Andric FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); 50*06c3fb27SDimitry Andric for (auto &I : FI.arguments()) 51*06c3fb27SDimitry Andric I.info = classifyArgumentType(I.type); 52*06c3fb27SDimitry Andric } 53*06c3fb27SDimitry Andric 54*06c3fb27SDimitry Andric Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, 55*06c3fb27SDimitry Andric QualType Ty) const override { 56*06c3fb27SDimitry Andric return EmitVAArgInstr(CGF, VAListAddr, Ty, classifyArgumentType(Ty)); 57*06c3fb27SDimitry Andric } 58*06c3fb27SDimitry Andric }; 59*06c3fb27SDimitry Andric 60*06c3fb27SDimitry Andric class MSP430TargetCodeGenInfo : public TargetCodeGenInfo { 61*06c3fb27SDimitry Andric public: 62*06c3fb27SDimitry Andric MSP430TargetCodeGenInfo(CodeGenTypes &CGT) 63*06c3fb27SDimitry Andric : TargetCodeGenInfo(std::make_unique<MSP430ABIInfo>(CGT)) {} 64*06c3fb27SDimitry Andric void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, 65*06c3fb27SDimitry Andric CodeGen::CodeGenModule &M) const override; 66*06c3fb27SDimitry Andric }; 67*06c3fb27SDimitry Andric 68*06c3fb27SDimitry Andric } 69*06c3fb27SDimitry Andric 70*06c3fb27SDimitry Andric void MSP430TargetCodeGenInfo::setTargetAttributes( 71*06c3fb27SDimitry Andric const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const { 72*06c3fb27SDimitry Andric if (GV->isDeclaration()) 73*06c3fb27SDimitry Andric return; 74*06c3fb27SDimitry Andric if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) { 75*06c3fb27SDimitry Andric const auto *InterruptAttr = FD->getAttr<MSP430InterruptAttr>(); 76*06c3fb27SDimitry Andric if (!InterruptAttr) 77*06c3fb27SDimitry Andric return; 78*06c3fb27SDimitry Andric 79*06c3fb27SDimitry Andric // Handle 'interrupt' attribute: 80*06c3fb27SDimitry Andric llvm::Function *F = cast<llvm::Function>(GV); 81*06c3fb27SDimitry Andric 82*06c3fb27SDimitry Andric // Step 1: Set ISR calling convention. 83*06c3fb27SDimitry Andric F->setCallingConv(llvm::CallingConv::MSP430_INTR); 84*06c3fb27SDimitry Andric 85*06c3fb27SDimitry Andric // Step 2: Add attributes goodness. 86*06c3fb27SDimitry Andric F->addFnAttr(llvm::Attribute::NoInline); 87*06c3fb27SDimitry Andric F->addFnAttr("interrupt", llvm::utostr(InterruptAttr->getNumber())); 88*06c3fb27SDimitry Andric } 89*06c3fb27SDimitry Andric } 90*06c3fb27SDimitry Andric 91*06c3fb27SDimitry Andric std::unique_ptr<TargetCodeGenInfo> 92*06c3fb27SDimitry Andric CodeGen::createMSP430TargetCodeGenInfo(CodeGenModule &CGM) { 93*06c3fb27SDimitry Andric return std::make_unique<MSP430TargetCodeGenInfo>(CGM.getTypes()); 94*06c3fb27SDimitry Andric } 95