dylanmckay created this revision.
dylanmckay added a reviewer: aaron.ballman.
dylanmckay added a subscriber: cfe-commits.

This teaches clang how to parse and lower the 'interrupt' and 'naked'
attributes.

This allows interrupt signal handlers to be written.


https://reviews.llvm.org/D28451

Files:
  include/clang/Basic/Attr.td
  lib/CodeGen/TargetInfo.cpp
  lib/Sema/SemaDeclAttr.cpp
  test/CodeGen/avr/attributes/interrupt.c
  test/CodeGen/avr/attributes/naked.c

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
@@ -5042,6 +5042,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()) {
@@ -5056,6 +5070,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;
@@ -5616,6 +5633,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,29 @@
 }
 
 //===----------------------------------------------------------------------===//
+// 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");
+    }
+  }
+};
+}
+
+//===----------------------------------------------------------------------===//
 // 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 +8409,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/Attr.td
===================================================================
--- include/clang/Basic/Attr.td
+++ include/clang/Basic/Attr.td
@@ -255,6 +255,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"]>;
@@ -477,6 +478,18 @@
   let Documentation = [ARMInterruptDocs];
 }
 
+def AVRInterrupt : InheritableAttr, TargetSpecificAttr<TargetAVR> {
+  let Spellings = [GNU<"interrupt">];
+  let Subjects = SubjectList<[Function]>;
+  let ParseKind = "Interrupt";
+  let Documentation = [Undocumented];
+}
+
+def AVRSignal : InheritableAttr, TargetSpecificAttr<TargetAVR> {
+  let Spellings = [GNU<"signal">];
+  let Documentation = [Undocumented];
+}
+
 def AsmLabel : InheritableAttr {
   let Spellings = [Keyword<"asm">, Keyword<"__asm__">];
   let Args = [StringArgument<"Label">];
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to