106c3fb27SDimitry Andric //===- MSP430.cpp ---------------------------------------------------------===// 206c3fb27SDimitry Andric // 306c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 506c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606c3fb27SDimitry Andric // 706c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 806c3fb27SDimitry Andric 906c3fb27SDimitry Andric #include "ABIInfoImpl.h" 1006c3fb27SDimitry Andric #include "TargetInfo.h" 1106c3fb27SDimitry Andric 1206c3fb27SDimitry Andric using namespace clang; 1306c3fb27SDimitry Andric using namespace clang::CodeGen; 1406c3fb27SDimitry Andric 1506c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 1606c3fb27SDimitry Andric // MSP430 ABI Implementation 1706c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 1806c3fb27SDimitry Andric 1906c3fb27SDimitry Andric namespace { 2006c3fb27SDimitry Andric 2106c3fb27SDimitry Andric class MSP430ABIInfo : public DefaultABIInfo { 2206c3fb27SDimitry Andric static ABIArgInfo complexArgInfo() { 2306c3fb27SDimitry Andric ABIArgInfo Info = ABIArgInfo::getDirect(); 2406c3fb27SDimitry Andric Info.setCanBeFlattened(false); 2506c3fb27SDimitry Andric return Info; 2606c3fb27SDimitry Andric } 2706c3fb27SDimitry Andric 2806c3fb27SDimitry Andric public: 2906c3fb27SDimitry Andric MSP430ABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} 3006c3fb27SDimitry Andric 3106c3fb27SDimitry Andric ABIArgInfo classifyReturnType(QualType RetTy) const { 3206c3fb27SDimitry Andric if (RetTy->isAnyComplexType()) 3306c3fb27SDimitry Andric return complexArgInfo(); 3406c3fb27SDimitry Andric 3506c3fb27SDimitry Andric return DefaultABIInfo::classifyReturnType(RetTy); 3606c3fb27SDimitry Andric } 3706c3fb27SDimitry Andric 3806c3fb27SDimitry Andric ABIArgInfo classifyArgumentType(QualType RetTy) const { 3906c3fb27SDimitry Andric if (RetTy->isAnyComplexType()) 4006c3fb27SDimitry Andric return complexArgInfo(); 4106c3fb27SDimitry Andric 4206c3fb27SDimitry Andric return DefaultABIInfo::classifyArgumentType(RetTy); 4306c3fb27SDimitry Andric } 4406c3fb27SDimitry Andric 4506c3fb27SDimitry Andric // Just copy the original implementations because 4606c3fb27SDimitry Andric // DefaultABIInfo::classify{Return,Argument}Type() are not virtual 4706c3fb27SDimitry Andric void computeInfo(CGFunctionInfo &FI) const override { 4806c3fb27SDimitry Andric if (!getCXXABI().classifyReturnType(FI)) 4906c3fb27SDimitry Andric FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); 5006c3fb27SDimitry Andric for (auto &I : FI.arguments()) 5106c3fb27SDimitry Andric I.info = classifyArgumentType(I.type); 5206c3fb27SDimitry Andric } 5306c3fb27SDimitry Andric 54*0fca6ea1SDimitry Andric RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, 55*0fca6ea1SDimitry Andric AggValueSlot Slot) const override { 56*0fca6ea1SDimitry Andric return CGF.EmitLoadOfAnyValue( 57*0fca6ea1SDimitry Andric CGF.MakeAddrLValue( 58*0fca6ea1SDimitry Andric EmitVAArgInstr(CGF, VAListAddr, Ty, classifyArgumentType(Ty)), Ty), 59*0fca6ea1SDimitry Andric Slot); 6006c3fb27SDimitry Andric } 6106c3fb27SDimitry Andric }; 6206c3fb27SDimitry Andric 6306c3fb27SDimitry Andric class MSP430TargetCodeGenInfo : public TargetCodeGenInfo { 6406c3fb27SDimitry Andric public: 6506c3fb27SDimitry Andric MSP430TargetCodeGenInfo(CodeGenTypes &CGT) 6606c3fb27SDimitry Andric : TargetCodeGenInfo(std::make_unique<MSP430ABIInfo>(CGT)) {} 6706c3fb27SDimitry Andric void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, 6806c3fb27SDimitry Andric CodeGen::CodeGenModule &M) const override; 6906c3fb27SDimitry Andric }; 7006c3fb27SDimitry Andric 7106c3fb27SDimitry Andric } 7206c3fb27SDimitry Andric 7306c3fb27SDimitry Andric void MSP430TargetCodeGenInfo::setTargetAttributes( 7406c3fb27SDimitry Andric const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const { 7506c3fb27SDimitry Andric if (GV->isDeclaration()) 7606c3fb27SDimitry Andric return; 7706c3fb27SDimitry Andric if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) { 7806c3fb27SDimitry Andric const auto *InterruptAttr = FD->getAttr<MSP430InterruptAttr>(); 7906c3fb27SDimitry Andric if (!InterruptAttr) 8006c3fb27SDimitry Andric return; 8106c3fb27SDimitry Andric 8206c3fb27SDimitry Andric // Handle 'interrupt' attribute: 8306c3fb27SDimitry Andric llvm::Function *F = cast<llvm::Function>(GV); 8406c3fb27SDimitry Andric 8506c3fb27SDimitry Andric // Step 1: Set ISR calling convention. 8606c3fb27SDimitry Andric F->setCallingConv(llvm::CallingConv::MSP430_INTR); 8706c3fb27SDimitry Andric 8806c3fb27SDimitry Andric // Step 2: Add attributes goodness. 8906c3fb27SDimitry Andric F->addFnAttr(llvm::Attribute::NoInline); 9006c3fb27SDimitry Andric F->addFnAttr("interrupt", llvm::utostr(InterruptAttr->getNumber())); 9106c3fb27SDimitry Andric } 9206c3fb27SDimitry Andric } 9306c3fb27SDimitry Andric 9406c3fb27SDimitry Andric std::unique_ptr<TargetCodeGenInfo> 9506c3fb27SDimitry Andric CodeGen::createMSP430TargetCodeGenInfo(CodeGenModule &CGM) { 9606c3fb27SDimitry Andric return std::make_unique<MSP430TargetCodeGenInfo>(CGM.getTypes()); 9706c3fb27SDimitry Andric } 98