brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.1 KiB · 523165c Raw
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