From b4dacc31f3092e1d87c68c10c531c165896b6a99 Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Fri, 27 Nov 2015 18:00:36 +0000 Subject: [PATCH] Revert r254203: [mips] Interrupt attribute support. I forgot to credit the author. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@254204 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/Attr.td | 24 ++----- include/clang/Basic/AttrDocs.td | 40 ------------ include/clang/Basic/DiagnosticSemaKinds.td | 4 -- lib/CodeGen/TargetInfo.cpp | 21 ------ lib/Sema/SemaDeclAttr.cpp | 74 +--------------------- test/CodeGen/mips-interrupt-attr.c | 64 ------------------- test/Sema/mips-interrupt-attr.c | 29 --------- 7 files changed, 5 insertions(+), 251 deletions(-) delete mode 100644 test/CodeGen/mips-interrupt-attr.c delete mode 100644 test/Sema/mips-interrupt-attr.c diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 1281c3f477..e020227612 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -426,8 +426,8 @@ def Annotate : InheritableParamAttr { } def ARMInterrupt : InheritableAttr, TargetSpecificAttr { - // NOTE: If you add any additional spellings, MSP430Interrupt's and - // MipsInterrupt's spellings must match. + // NOTE: If you add any additional spellings, MSP430Interrupt's spellings + // must match. let Spellings = [GNU<"interrupt">]; let Args = [EnumArgument<"Interrupt", "InterruptType", ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""], @@ -845,8 +845,8 @@ def MSABI : InheritableAttr { } def MSP430Interrupt : InheritableAttr, TargetSpecificAttr { - // NOTE: If you add any additional spellings, ARMInterrupt's and - // MipsInterrupt's spellings must match. + // NOTE: If you add any additional spellings, ARMInterrupt's spellings must + // match. let Spellings = [GNU<"interrupt">]; let Args = [UnsignedArgument<"Number">]; let ParseKind = "Interrupt"; @@ -860,22 +860,6 @@ def Mips16 : InheritableAttr, TargetSpecificAttr { let Documentation = [Undocumented]; } -def MipsInterrupt : InheritableAttr, TargetSpecificAttr { - // NOTE: If you add any additional spellings, ARMInterrupt's and - // MSP430Interrupt's spellings must match. - let Spellings = [GNU<"interrupt">]; - let Subjects = SubjectList<[Function]>; - let Args = [EnumArgument<"Interrupt", "InterruptType", - ["vector=sw0", "vector=sw1", "vector=hw0", - "vector=hw1", "vector=hw2", "vector=hw3", - "vector=hw4", "vector=hw5", "eic", ""], - ["sw0", "sw1", "hw0", "hw1", "hw2", "hw3", - "hw4", "hw5", "eic", "eic"] - >]; - let ParseKind = "Interrupt"; - let Documentation = [MipsInterruptDocs]; -} - def Mode : Attr { let Spellings = [GCC<"mode">]; let Args = [IdentifierArgument<"Mode">]; diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td index 081db65153..9f933ba524 100644 --- a/include/clang/Basic/AttrDocs.td +++ b/include/clang/Basic/AttrDocs.td @@ -714,46 +714,6 @@ The semantics are as follows: }]; } -def MipsInterruptDocs : Documentation { - let Category = DocCatFunction; - let Content = [{ -Clang supports the GNU style ``__attribute__((interrupt("ARGUMENT")))`` attribute on -MIPS 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. - -By default, the compiler will produce a function prologue and epilogue suitable for -an interrupt service routine that handles an External Interrupt Controller (eic) -generated interrupt. This behaviour can be explicitly requested with the "eic" -argument. - -Otherwise, for use with vectored interrupt mode, the argument passed should be -of the form "vector=LEVEL" where LEVEL is one of the following values: -"sw0", "sw1", "hw0", "hw1", "hw2", "hw3", "hw4", "hw5". The compiler will -then set the interrupt mask to the corresponding level which will mask all -interrupts up to and including the argument. - -The semantics are as follows: - -- The prologue is modified so that the Exception Program Counter (EPC) and - Status coprocessor registers are saved to the stack. The interrupt mask is - set so that the function can only be interrupted by a higher priority - interrupt. The epilogue will restore the previous values of EPC and Status. - -- The prologue and epilogue are modified to save and restore all non-kernel - registers as necessary. - -- The FPU is disabled in the prologue, as the floating pointer registers are not - spilled to the stack. - -- The function return sequence is changed to use an exception return instruction. - -- The parameter sets the interrupt mask for the function corresponding to the - interrupt level specified. If no mask is specified the interrupt mask - defaults to "eic". - }]; -} - def TargetDocs : Documentation { let Category = DocCatFunction; let Content = [{ diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 9a98be1aee..ece71d3be2 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -255,10 +255,6 @@ def err_bad_variable_name : Error< def err_bad_parameter_name : Error< "%0 cannot be the name of a parameter">; def err_parameter_name_omitted : Error<"parameter name omitted">; -def warn_mips_interrupt_attribute : Warning< - "MIPS 'interrupt' attribute only applies to functions that have " - "%select{no parameters|a 'void' return type}0">, - InGroup; def warn_unused_parameter : Warning<"unused parameter %0">, InGroup, DefaultIgnore; def warn_unused_variable : Warning<"unused variable %0">, diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index df081b4fb9..06a2e71f5c 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -5893,27 +5893,6 @@ public: else if (FD->hasAttr()) { Fn->addFnAttr("nomips16"); } - - const MipsInterruptAttr *Attr = FD->getAttr(); - if (!Attr) - return; - - const char *Kind; - switch (Attr->getInterrupt()) { - default: llvm_unreachable("Unknown Mips interrupt attribute type!"); - case MipsInterruptAttr::eic: Kind = "eic"; break; - case MipsInterruptAttr::sw0: Kind = "sw0"; break; - case MipsInterruptAttr::sw1: Kind = "sw1"; break; - case MipsInterruptAttr::hw0: Kind = "hw0"; break; - case MipsInterruptAttr::hw1: Kind = "hw1"; break; - case MipsInterruptAttr::hw2: Kind = "hw2"; break; - case MipsInterruptAttr::hw3: Kind = "hw3"; break; - case MipsInterruptAttr::hw4: Kind = "hw4"; break; - case MipsInterruptAttr::hw5: Kind = "hw5"; break; - } - - Fn->addFnAttr("interrupt", Kind); - } bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index df1641af5f..13a11bcac9 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -4450,86 +4450,14 @@ static void handleMSP430InterruptAttr(Sema &S, Decl *D, D->addAttr(UsedAttr::CreateImplicit(S.Context)); } -static void handleMipsInterruptAttr(Sema &S, Decl *D, - const AttributeList &Attr) { - // Only one optional argument permitted. - if (Attr.getNumArgs() > 1) { - S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) - << Attr.getName() << 1; - return; - } - - StringRef Str; - SourceLocation ArgLoc; - - if (Attr.getNumArgs() == 0) - Str = ""; - else if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &ArgLoc)) - return; - - // Semantic checks for a function with the 'interrupt' attribute for MIPS: - // a) Must be a function. - // b) Must have no parameters. - // c) Must have the 'void' return type. - // d) Cannot have the 'mips16' attribute, as that instruction set - // lacks the 'eret' instruction. - // e) The attribute itself must either have no argument or one of the - // valid interrupt types, see [MipsInterruptDocs]. - - 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_mips_interrupt_attribute) - << 0; - return; - } - - if (!getFunctionOrMethodResultType(D)->isVoidType()) { - S.Diag(D->getLocation(), diag::warn_mips_interrupt_attribute) - << 1; - return; - } - - if (checkAttrMutualExclusion(S, D, Attr.getRange(), - Attr.getName())) - return; - - MipsInterruptAttr::InterruptType Kind; - if (!MipsInterruptAttr::ConvertStrToInterruptType(Str, Kind)) { - S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) - << Attr.getName() << "'" + std::string(Str) + "'"; - return; - } - - D->addAttr(::new (S.Context) MipsInterruptAttr( - Attr.getLoc(), S.Context, Kind, Attr.getAttributeSpellingListIndex())); -} - static void handleInterruptAttr(Sema &S, Decl *D, const AttributeList &Attr) { // Dispatch the interrupt attribute based on the current target. if (S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::msp430) handleMSP430InterruptAttr(S, D, Attr); - else if (S.Context.getTargetInfo().getTriple().getArch() == - llvm::Triple::mipsel || - S.Context.getTargetInfo().getTriple().getArch() == - llvm::Triple::mips) - handleMipsInterruptAttr(S, D, Attr); else handleARMInterruptAttr(S, D, Attr); } -static void handleMips16Attribute(Sema &S, Decl *D, const AttributeList &Attr) { - if (checkAttrMutualExclusion(S, D, Attr.getRange(), - Attr.getName())) - return; - - handleSimpleAttribute(S, D, Attr); -} - static void handleAMDGPUNumVGPRAttr(Sema &S, Decl *D, const AttributeList &Attr) { uint32_t NumRegs; @@ -4919,7 +4847,7 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, handleDLLAttr(S, D, Attr); break; case AttributeList::AT_Mips16: - handleMips16Attribute(S, D, Attr); + handleSimpleAttribute(S, D, Attr); break; case AttributeList::AT_NoMips16: handleSimpleAttribute(S, D, Attr); diff --git a/test/CodeGen/mips-interrupt-attr.c b/test/CodeGen/mips-interrupt-attr.c deleted file mode 100644 index df70b12b58..0000000000 --- a/test/CodeGen/mips-interrupt-attr.c +++ /dev/null @@ -1,64 +0,0 @@ -// RUN: %clang_cc1 -triple mipsel-unknown-linux -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK - -void __attribute__ ((interrupt("vector=sw0"))) -isr_sw0 (void) -{ - // CHECK: define void @isr_sw0() [[SW0:#[0-9]+]] -} - -void __attribute__ ((interrupt("vector=sw1"))) -isr_sw1 (void) -{ - // CHECK: define void @isr_sw1() [[SW1:#[0-9]+]] -} - -void __attribute__ ((interrupt("vector=hw0"))) -isr_hw0 (void) -{ - // CHECK: define void @isr_hw0() [[HW0:#[0-9]+]] -} - -void __attribute__ ((interrupt("vector=hw1"))) -isr_hw1 (void) -{ - // CHECK: define void @isr_hw1() [[HW1:#[0-9]+]] -} - -void __attribute__ ((interrupt("vector=hw2"))) -isr_hw2 (void) -{ - // CHECK: define void @isr_hw2() [[HW2:#[0-9]+]] -} - -void __attribute__ ((interrupt("vector=hw3"))) -isr_hw3 (void) -{ - // CHECK: define void @isr_hw3() [[HW3:#[0-9]+]] -} - -void __attribute__ ((interrupt("vector=hw4"))) -isr_hw4 (void) -{ - // CHECK: define void @isr_hw4() [[HW4:#[0-9]+]] -} - -void __attribute__ ((interrupt("vector=hw5"))) -isr_hw5 (void) -{ - // CHECK: define void @isr_hw5() [[HW5:#[0-9]+]] -} - -void __attribute__ ((interrupt)) -isr_eic (void) -{ - // CHECK: define void @isr_eic() [[EIC:#[0-9]+]] -} -// CHECK: attributes [[SW0]] = { {{.*}} "interrupt"="sw0" {{.*}} } -// CHECK: attributes [[SW1]] = { {{.*}} "interrupt"="sw1" {{.*}} } -// CHECK: attributes [[HW0]] = { {{.*}} "interrupt"="hw0" {{.*}} } -// CHECK: attributes [[HW1]] = { {{.*}} "interrupt"="hw1" {{.*}} } -// CHECK: attributes [[HW2]] = { {{.*}} "interrupt"="hw2" {{.*}} } -// CHECK: attributes [[HW3]] = { {{.*}} "interrupt"="hw3" {{.*}} } -// CHECK: attributes [[HW4]] = { {{.*}} "interrupt"="hw4" {{.*}} } -// CHECK: attributes [[HW5]] = { {{.*}} "interrupt"="hw5" {{.*}} } -// CHECK: attributes [[EIC]] = { {{.*}} "interrupt"="eic" {{.*}} } diff --git a/test/Sema/mips-interrupt-attr.c b/test/Sema/mips-interrupt-attr.c deleted file mode 100644 index 17344b6edc..0000000000 --- a/test/Sema/mips-interrupt-attr.c +++ /dev/null @@ -1,29 +0,0 @@ -// RUN: %clang_cc1 %s -triple mips-img-elf -verify -fsyntax-only -struct a { int b; }; - -struct a test __attribute__((interrupt)); // expected-warning {{'interrupt' attribute only applies to functions and methods}} - -__attribute__((interrupt("EIC"))) void foo1() {} // expected-warning {{'interrupt' attribute argument not supported: 'EIC'}} - -__attribute__((interrupt("eic", 1))) void foo2() {} // expected-error {{'interrupt' attribute takes no more than 1 argument}} - -__attribute__((interrupt("eic"))) void foo3() {} -__attribute__((interrupt("vector=sw0"))) void foo4() {} -__attribute__((interrupt("vector=hw0"))) void foo5() {} -__attribute__((interrupt("vector=hw1"))) void foo6() {} -__attribute__((interrupt("vector=hw2"))) void foo7() {} -__attribute__((interrupt("vector=hw3"))) void foo8() {} -__attribute__((interrupt("vector=hw4"))) void foo9() {} -__attribute__((interrupt("vector=hw5"))) void fooa() {} -__attribute__((interrupt(""))) void food() {} - -__attribute__((interrupt)) int foob() {return 0;} // expected-warning {{MIPS 'interrupt' attribute only applies to functions that have a 'void' return type}} -__attribute__((interrupt())) void fooc(int a) {} // expected-warning {{MIPS 'interrupt' attribute only applies to functions that have no parameters}} -__attribute__((interrupt,mips16)) void fooe() {} // expected-error {{'interrupt' and 'mips16' attributes are not compatible}} \ - // expected-note {{conflicting attribute is here}} -__attribute__((mips16,interrupt)) void foof() {} // expected-error {{'mips16' and 'interrupt' attributes are not compatible}} \ - // expected-note {{conflicting attribute is here}} -__attribute__((interrupt)) __attribute__ ((mips16)) void foo10() {} // expected-error {{'interrupt' and 'mips16' attributes are not compatible}} \ - // expected-note {{conflicting attribute is here}} -__attribute__((mips16)) __attribute ((interrupt)) void foo11() {} // expected-error {{'mips16' and 'interrupt' attributes are not compatible}} \ - // expected-note {{conflicting attribute is here}}