dylanmckay updated this revision to Diff 83913.
dylanmckay marked 2 inline comments as done.
dylanmckay added a comment.
[AVR] Document the 'interrupt' and 'naked' attributes
https://reviews.llvm.org/D28451
Files:
include/clang/Basic/Attr.td
include/clang/Basic/AttrDocs.td
lib/CodeGen/TargetInfo.cpp
lib/Sema/SemaDeclAttr.cpp
test/CodeGen/avr/attributes/interrupt.c
test/CodeGen/avr/attributes/naked.c
test/CodeGen/avr/attributes/signal.c
Index: test/CodeGen/avr/attributes/signal.c
===================================================================
--- /dev/null
+++ test/CodeGen/avr/attributes/signal.c
@@ -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.*}}}
Index: test/CodeGen/avr/attributes/naked.c
===================================================================
--- /dev/null
+++ test/CodeGen/avr/attributes/naked.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: define void @foo() #0
+__attribute__((naked)) void foo(void) { }
+
+// CHECK: attributes #0 = {{{.*naked.*}}}
Index: test/CodeGen/avr/attributes/interrupt.c
===================================================================
--- /dev/null
+++ test/CodeGen/avr/attributes/interrupt.c
@@ -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.*}}}
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -5126,6 +5126,20 @@
D->addAttr(UsedAttr::CreateImplicit(S.Context));
}
+static void handleAVRInterruptAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
+ D->addAttr(::new (S.Context)
+ AVRInterruptAttr(Attr.getLoc(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
+}
+
+static void handleAVRSignalAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
+ D->addAttr(::new (S.Context)
+ AVRSignalAttr(Attr.getLoc(), S.Context,
+ Attr.getAttributeSpellingListIndex()));
+}
+
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 +5154,9 @@
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 +5717,9 @@
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;
Index: lib/CodeGen/TargetInfo.cpp
===================================================================
--- lib/CodeGen/TargetInfo.cpp
+++ lib/CodeGen/TargetInfo.cpp
@@ -6884,6 +6884,31 @@
}
//===----------------------------------------------------------------------===//
+// 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 FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
+ if (!FD) return;
+ llvm::Function *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.
@@ -8386,6 +8411,9 @@
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;
Index: include/clang/Basic/AttrDocs.td
===================================================================
--- include/clang/Basic/AttrDocs.td
+++ include/clang/Basic/AttrDocs.td
@@ -1181,6 +1181,33 @@
}];
}
+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 = [{
Index: include/clang/Basic/Attr.td
===================================================================
--- include/clang/Basic/Attr.td
+++ include/clang/Basic/Attr.td
@@ -258,6 +258,7 @@
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,18 @@
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 Documentation = [AVRSignalDocs];
+}
+
def AsmLabel : InheritableAttr {
let Spellings = [Keyword<"asm">, Keyword<"__asm__">];
let Args = [StringArgument<"Label">];
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits