Author: dylanmckay Date: Tue Feb 7 23:09:26 2017 New Revision: 294402 URL: http://llvm.org/viewvc/llvm-project?rev=294402&view=rev Log: [AVR] Add support for the 'interrupt' and 'naked' attributes
Summary: This teaches clang how to parse and lower the 'interrupt' and 'naked' attributes. This allows interrupt signal handlers to be written. Reviewers: aaron.ballman Subscribers: malcolm.parsons, cfe-commits Differential Revision: https://reviews.llvm.org/D28451 Added: cfe/trunk/test/CodeGen/avr/attributes/ cfe/trunk/test/CodeGen/avr/attributes/interrupt.c cfe/trunk/test/CodeGen/avr/attributes/signal.c cfe/trunk/test/Sema/avr-interrupt-attr.c cfe/trunk/test/Sema/avr-signal-attr.c Modified: cfe/trunk/include/clang/Basic/Attr.td cfe/trunk/include/clang/Basic/AttrDocs.td cfe/trunk/lib/CodeGen/TargetInfo.cpp cfe/trunk/lib/Sema/SemaDeclAttr.cpp Modified: cfe/trunk/include/clang/Basic/Attr.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=294402&r1=294401&r2=294402&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/Attr.td (original) +++ cfe/trunk/include/clang/Basic/Attr.td Tue Feb 7 23:09:26 2017 @@ -258,6 +258,7 @@ class TargetArch<list<string> arches> { list<string> CXXABIs; } def TargetARM : TargetArch<["arm", "thumb", "armeb", "thumbeb"]>; +def TargetAVR : TargetArch<["avr"]>; def TargetMips : TargetArch<["mips", "mipsel"]>; def TargetMSP430 : TargetArch<["msp430"]>; def TargetX86 : TargetArch<["x86"]>; @@ -480,6 +481,19 @@ def ARMInterrupt : InheritableAttr, Targ let Documentation = [ARMInterruptDocs]; } +def AVRInterrupt : InheritableAttr, TargetSpecificAttr<TargetAVR> { + let Spellings = [GNU<"interrupt">]; + let Subjects = SubjectList<[Function]>; + let ParseKind = "Interrupt"; + let Documentation = [AVRInterruptDocs]; +} + +def AVRSignal : InheritableAttr, TargetSpecificAttr<TargetAVR> { + let Spellings = [GNU<"signal">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [AVRSignalDocs]; +} + def AsmLabel : InheritableAttr { let Spellings = [Keyword<"asm">, Keyword<"__asm__">]; let Args = [StringArgument<"Label">]; Modified: cfe/trunk/include/clang/Basic/AttrDocs.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=294402&r1=294401&r2=294402&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/AttrDocs.td (original) +++ cfe/trunk/include/clang/Basic/AttrDocs.td Tue Feb 7 23:09:26 2017 @@ -1182,6 +1182,33 @@ The semantics are as follows: }]; } +def AVRInterruptDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Clang supports the GNU style ``__attribute__((interrupt))`` attribute on +AVR targets. This attribute may be attached to a function definition and instructs +the backend to generate appropriate function entry/exit code so that it can be used +directly as an interrupt service routine. + +On the AVR, the hardware globally disables interrupts when an interrupt is executed. +The first instruction of an interrupt handler declared with this attribute is a SEI +instruction to re-enable interrupts. See also the signal attribute that +does not insert a SEI instruction. + }]; +} + +def AVRSignalDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Clang supports the GNU style ``__attribute__((signal))`` attribute on +AVR targets. This attribute may be attached to a function definition and instructs +the backend to generate appropriate function entry/exit code so that it can be used +directly as an interrupt service routine. + +Interrupt handler functions defined with the signal attribute do not re-enable interrupts. +}]; +} + def TargetDocs : Documentation { let Category = DocCatFunction; let Content = [{ Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=294402&r1=294401&r2=294402&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original) +++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Tue Feb 7 23:09:26 2017 @@ -6900,6 +6900,31 @@ MIPSTargetCodeGenInfo::initDwarfEHRegSiz } //===----------------------------------------------------------------------===// +// AVR ABI Implementation. +//===----------------------------------------------------------------------===// + +namespace { +class AVRTargetCodeGenInfo : public TargetCodeGenInfo { +public: + AVRTargetCodeGenInfo(CodeGenTypes &CGT) + : TargetCodeGenInfo(new DefaultABIInfo(CGT)) { } + + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &CGM) const override { + const auto *FD = dyn_cast_or_null<FunctionDecl>(D); + if (!FD) return; + auto *Fn = cast<llvm::Function>(GV); + + if (FD->getAttr<AVRInterruptAttr>()) + Fn->addFnAttr("interrupt"); + + if (FD->getAttr<AVRSignalAttr>()) + Fn->addFnAttr("signal"); + } +}; +} + +//===----------------------------------------------------------------------===// // TCE ABI Implementation (see http://tce.cs.tut.fi). Uses mostly the defaults. // Currently subclassed only to implement custom OpenCL C function attribute // handling. @@ -8402,6 +8427,9 @@ const TargetCodeGenInfo &CodeGenModule:: case llvm::Triple::mips64el: return SetCGInfo(new MIPSTargetCodeGenInfo(Types, false)); + case llvm::Triple::avr: + return SetCGInfo(new AVRTargetCodeGenInfo(Types)); + case llvm::Triple::aarch64: case llvm::Triple::aarch64_be: { AArch64ABIInfo::ABIKind Kind = AArch64ABIInfo::AAPCS; Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=294402&r1=294401&r2=294402&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue Feb 7 23:09:26 2017 @@ -5126,6 +5126,32 @@ static void handleAnyX86InterruptAttr(Se D->addAttr(UsedAttr::CreateImplicit(S.Context)); } +static void handleAVRInterruptAttr(Sema &S, Decl *D, const AttributeList &Attr) { + if (!isFunctionOrMethod(D)) { + S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) + << "'interrupt'" << ExpectedFunction; + return; + } + + if (!checkAttributeNumArgs(S, Attr, 0)) + return; + + handleSimpleAttribute<AVRInterruptAttr>(S, D, Attr); +} + +static void handleAVRSignalAttr(Sema &S, Decl *D, const AttributeList &Attr) { + if (!isFunctionOrMethod(D)) { + S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) + << "'signal'" << ExpectedFunction; + return; + } + + if (!checkAttributeNumArgs(S, Attr, 0)) + return; + + handleSimpleAttribute<AVRSignalAttr>(S, D, Attr); +} + static void handleInterruptAttr(Sema &S, Decl *D, const AttributeList &Attr) { // Dispatch the interrupt attribute based on the current target. switch (S.Context.getTargetInfo().getTriple().getArch()) { @@ -5140,6 +5166,9 @@ static void handleInterruptAttr(Sema &S, case llvm::Triple::x86_64: handleAnyX86InterruptAttr(S, D, Attr); break; + case llvm::Triple::avr: + handleAVRInterruptAttr(S, D, Attr); + break; default: handleARMInterruptAttr(S, D, Attr); break; @@ -5700,6 +5729,9 @@ static void ProcessDeclAttribute(Sema &S case AttributeList::AT_AMDGPUNumVGPR: handleAMDGPUNumVGPRAttr(S, D, Attr); break; + case AttributeList::AT_AVRSignal: + handleAVRSignalAttr(S, D, Attr); + break; case AttributeList::AT_IBAction: handleSimpleAttribute<IBActionAttr>(S, D, Attr); break; Added: cfe/trunk/test/CodeGen/avr/attributes/interrupt.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/avr/attributes/interrupt.c?rev=294402&view=auto ============================================================================== --- cfe/trunk/test/CodeGen/avr/attributes/interrupt.c (added) +++ cfe/trunk/test/CodeGen/avr/attributes/interrupt.c Tue Feb 7 23:09:26 2017 @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((interrupt)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*interrupt.*}}} Added: cfe/trunk/test/CodeGen/avr/attributes/signal.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/avr/attributes/signal.c?rev=294402&view=auto ============================================================================== --- cfe/trunk/test/CodeGen/avr/attributes/signal.c (added) +++ cfe/trunk/test/CodeGen/avr/attributes/signal.c Tue Feb 7 23:09:26 2017 @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((signal)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*signal.*}}} Added: cfe/trunk/test/Sema/avr-interrupt-attr.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/avr-interrupt-attr.c?rev=294402&view=auto ============================================================================== --- cfe/trunk/test/Sema/avr-interrupt-attr.c (added) +++ cfe/trunk/test/Sema/avr-interrupt-attr.c Tue Feb 7 23:09:26 2017 @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only +struct a { int b; }; + +struct a test __attribute__((interrupt)); // expected-warning {{'interrupt' attribute only applies to functions}} + +__attribute__((interrupt(12))) void foo(void) { } // expected-error {{'interrupt' attribute takes no arguments}} + +__attribute__((interrupt)) void food() {} Added: cfe/trunk/test/Sema/avr-signal-attr.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/avr-signal-attr.c?rev=294402&view=auto ============================================================================== --- cfe/trunk/test/Sema/avr-signal-attr.c (added) +++ cfe/trunk/test/Sema/avr-signal-attr.c Tue Feb 7 23:09:26 2017 @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only +struct a { int b; }; + +struct a test __attribute__((signal)); // expected-warning {{'signal' attribute only applies to functions}} + +__attribute__((signal(12))) void foo(void) { } // expected-error {{'signal' attribute takes no arguments}} + +__attribute__((signal)) void food() {} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits