diff options
| author | Anton Korobeynikov <anton@korobeynikov.info> | 2019-01-16 13:44:01 +0000 |
|---|---|---|
| committer | Anton Korobeynikov <anton@korobeynikov.info> | 2019-01-16 13:44:01 +0000 |
| commit | 383e8271212bfabb824161c9c30e22afa07d44e2 (patch) | |
| tree | 90d10cefb46f4c1bd5312529cfc2af526ffd2275 /clang/lib | |
| parent | b6cee6ceb61056bc26e9e96f6e9001c41aa644ea (diff) | |
| download | bcm5719-llvm-383e8271212bfabb824161c9c30e22afa07d44e2.tar.gz bcm5719-llvm-383e8271212bfabb824161c9c30e22afa07d44e2.zip | |
[MSP430] Improve support of 'interrupt' attribute
* Accept as an argument constants in range 0..63 (aligned with TI headers and linker scripts provided with TI GCC toolchain).
* Emit function attribute 'interrupt'='xx' instead of aliases (used in the backend to create a section for particular interrupt vector).
* Add more diagnostics.
Patch by Kristina Bessonova!
Differential Revision: https://reviews.llvm.org/D56663
llvm-svn: 351344
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/CodeGen/TargetInfo.cpp | 22 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 27 |
2 files changed, 33 insertions, 16 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 89ec73670a7..f5a770ed9d8 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -6774,21 +6774,19 @@ void MSP430TargetCodeGenInfo::setTargetAttributes( if (GV->isDeclaration()) return; if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) { - if (const MSP430InterruptAttr *attr = FD->getAttr<MSP430InterruptAttr>()) { - // Handle 'interrupt' attribute: - llvm::Function *F = cast<llvm::Function>(GV); + const auto *InterruptAttr = FD->getAttr<MSP430InterruptAttr>(); + if (!InterruptAttr) + return; - // Step 1: Set ISR calling convention. - F->setCallingConv(llvm::CallingConv::MSP430_INTR); + // Handle 'interrupt' attribute: + llvm::Function *F = cast<llvm::Function>(GV); - // Step 2: Add attributes goodness. - F->addFnAttr(llvm::Attribute::NoInline); + // Step 1: Set ISR calling convention. + F->setCallingConv(llvm::CallingConv::MSP430_INTR); - // Step 3: Emit ISR vector alias. - unsigned Num = attr->getNumber() / 2; - llvm::GlobalAlias::create(llvm::Function::ExternalLinkage, - "__isr_" + Twine(Num), F); - } + // Step 2: Add attributes goodness. + F->addFnAttr(llvm::Attribute::NoInline); + F->addFnAttr("interrupt", llvm::utostr(InterruptAttr->getNumber())); } } diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 0e10804a2ec..eb95cc748b1 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -5377,6 +5377,27 @@ static void handleARMInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } static void handleMSP430InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + // MSP430 'interrupt' attribute is applied to + // a function with no parameters and void return type. + if (!isFunctionOrMethod(D)) { + S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) + << "'interrupt'" << ExpectedFunctionOrMethod; + return; + } + + if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) { + S.Diag(D->getLocation(), diag::warn_msp430_interrupt_attribute) + << 0; + return; + } + + if (!getFunctionOrMethodResultType(D)->isVoidType()) { + S.Diag(D->getLocation(), diag::warn_msp430_interrupt_attribute) + << 1; + return; + } + + // The attribute takes one integer argument. if (!checkAttributeNumArgs(S, AL, 1)) return; @@ -5386,8 +5407,6 @@ static void handleMSP430InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { return; } - // FIXME: Check for decl - it should be void ()(void). - Expr *NumParamsExpr = static_cast<Expr *>(AL.getArgAsExpr(0)); llvm::APSInt NumParams(32); if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { @@ -5396,9 +5415,9 @@ static void handleMSP430InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { << NumParamsExpr->getSourceRange(); return; } - + // The argument should be in range 0..63. unsigned Num = NumParams.getLimitedValue(255); - if ((Num & 1) || Num > 30) { + if (Num > 63) { S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) << AL << (int)NumParams.getSExtValue() << NumParamsExpr->getSourceRange(); |

