99 lines · cpp
1//===- MSP430.cpp ---------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "ABIInfoImpl.h"10#include "TargetInfo.h"11#include "llvm/ADT/StringExtras.h"12 13using namespace clang;14using namespace clang::CodeGen;15 16//===----------------------------------------------------------------------===//17// MSP430 ABI Implementation18//===----------------------------------------------------------------------===//19 20namespace {21 22class MSP430ABIInfo : public DefaultABIInfo {23 static ABIArgInfo complexArgInfo() {24 ABIArgInfo Info = ABIArgInfo::getDirect();25 Info.setCanBeFlattened(false);26 return Info;27 }28 29public:30 MSP430ABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}31 32 ABIArgInfo classifyReturnType(QualType RetTy) const {33 if (RetTy->isAnyComplexType())34 return complexArgInfo();35 36 return DefaultABIInfo::classifyReturnType(RetTy);37 }38 39 ABIArgInfo classifyArgumentType(QualType RetTy) const {40 if (RetTy->isAnyComplexType())41 return complexArgInfo();42 43 return DefaultABIInfo::classifyArgumentType(RetTy);44 }45 46 // Just copy the original implementations because47 // DefaultABIInfo::classify{Return,Argument}Type() are not virtual48 void computeInfo(CGFunctionInfo &FI) const override {49 if (!getCXXABI().classifyReturnType(FI))50 FI.getReturnInfo() = classifyReturnType(FI.getReturnType());51 for (auto &I : FI.arguments())52 I.info = classifyArgumentType(I.type);53 }54 55 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,56 AggValueSlot Slot) const override {57 return CGF.EmitLoadOfAnyValue(58 CGF.MakeAddrLValue(59 EmitVAArgInstr(CGF, VAListAddr, Ty, classifyArgumentType(Ty)), Ty),60 Slot);61 }62};63 64class MSP430TargetCodeGenInfo : public TargetCodeGenInfo {65public:66 MSP430TargetCodeGenInfo(CodeGenTypes &CGT)67 : TargetCodeGenInfo(std::make_unique<MSP430ABIInfo>(CGT)) {}68 void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,69 CodeGen::CodeGenModule &M) const override;70};71 72}73 74void MSP430TargetCodeGenInfo::setTargetAttributes(75 const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const {76 if (GV->isDeclaration())77 return;78 if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {79 const auto *InterruptAttr = FD->getAttr<MSP430InterruptAttr>();80 if (!InterruptAttr)81 return;82 83 // Handle 'interrupt' attribute:84 llvm::Function *F = cast<llvm::Function>(GV);85 86 // Step 1: Set ISR calling convention.87 F->setCallingConv(llvm::CallingConv::MSP430_INTR);88 89 // Step 2: Add attributes goodness.90 F->addFnAttr(llvm::Attribute::NoInline);91 F->addFnAttr("interrupt", llvm::utostr(InterruptAttr->getNumber()));92 }93}94 95std::unique_ptr<TargetCodeGenInfo>96CodeGen::createMSP430TargetCodeGenInfo(CodeGenModule &CGM) {97 return std::make_unique<MSP430TargetCodeGenInfo>(CGM.getTypes());98}99