r191769 - Implement ARM GNU-style interrupt attribute

Timur Iskhodzhanov timurrrr at google.com
Tue Oct 1 07:52:44 PDT 2013


The build is green again

2013/10/1 Timur Iskhodzhanov <timurrrr at google.com>:
> FYI this fails on Windows
>
> FAILED: cmd.exe /c cd . && "C:\Program Files (x86)\CMake
> 2.8\bin\cmake.exe" -E vs_link_exe C:\PROGRA~2\MICROS~2.0\VC\bin\cl.exe
>  /nologo  /DWIN32 /D_WINDOWS /W3 /Zm1000 /GR- /EHs-c-  /MD /O2 /Ob2
> /Febin\diagtool.exe /Fdbin\diagtool.pdb
> tools\clang\tools\diagtool\CMakeFiles\diagtool.dir\diagtool_main.cpp.obj
> tools\clang\tools\diagtool\CMakeFiles\diagtool.dir\DiagTool.cpp.obj
> tools\clang\tools\diagtool\CMakeFiles\diagtool.dir\DiagnosticNames.cpp.obj
> tools\clang\tools\diagtool\CMakeFiles\diagtool.dir\ListWarnings.cpp.obj
> tools\clang\tools\diagtool\CMakeFiles\diagtool.dir\ShowEnabledWarnings.cpp.obj
> tools\clang\tools\diagtool\CMakeFiles\diagtool.dir\TreeView.cpp.obj
> /link /implib:lib\diagtool.lib /version:0.0  /STACK:10000000
> /machine:X86  /INCREMENTAL:NO /subsystem:console
> lib\LLVMX86CodeGen.lib lib\LLVMX86AsmParser.lib
> lib\LLVMX86Disassembler.lib lib\LLVMAsmParser.lib
> lib\LLVMBitReader.lib lib\LLVMAsmPrinter.lib lib\LLVMSelectionDAG.lib
> lib\LLVMX86Desc.lib lib\LLVMMCParser.lib lib\LLVMCodeGen.lib
> lib\LLVMX86AsmPrinter.lib lib\LLVMX86Info.lib lib\LLVMObjCARCOpts.lib
> lib\LLVMScalarOpts.lib lib\LLVMX86Utils.lib lib\LLVMInstCombine.lib
> lib\LLVMTransformUtils.lib lib\LLVMipa.lib lib\LLVMAnalysis.lib
> lib\LLVMTarget.lib lib\LLVMCore.lib lib\LLVMMC.lib lib\LLVMObject.lib
> lib\LLVMSupport.lib lib\clangBasic.lib lib\clangLex.lib
> lib\clangSema.lib lib\clangFrontend.lib lib\clangDriver.lib
> lib\LLVMOption.lib lib\clangParse.lib lib\clangSerialization.lib
> lib\LLVMBitReader.lib lib\clangSema.lib lib\LLVMX86CodeGen.lib
> lib\LLVMX86AsmParser.lib lib\LLVMX86Disassembler.lib
> lib\LLVMAsmParser.lib lib\LLVMAsmPrinter.lib lib\LLVMSelectionDAG.lib
> lib\LLVMX86Desc.lib lib\LLVMMCParser.lib lib\LLVMCodeGen.lib
> lib\LLVMX86AsmPrinter.lib lib\LLVMX86Info.lib lib\LLVMObjCARCOpts.lib
> lib\LLVMScalarOpts.lib lib\LLVMX86Utils.lib lib\LLVMInstCombine.lib
> lib\LLVMTransformUtils.lib lib\LLVMipa.lib lib\LLVMAnalysis.lib
> lib\LLVMTarget.lib lib\LLVMCore.lib lib\clangAnalysis.lib
> lib\clangEdit.lib lib\clangAST.lib lib\clangLex.lib lib\clangBasic.lib
> lib\LLVMMC.lib lib\LLVMObject.lib lib\LLVMSupport.lib kernel32.lib
> user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib
> uuid.lib comdlg32.lib advapi32.lib && cd .
>    Creating library lib\diagtool.lib and object lib\diagtool.exp
>
>
> clangSerialization.lib(ASTReaderDecl.cpp.obj) : error LNK2001:
> unresolved external symbol "public: virtual class
> clang::ARMInterruptAttr * __thiscall
> clang::ARMInterruptAttr::clone(class clang::ASTContext &)const "
> (?clone at ARMInterruptAttr@clang@@UBEPAV12 at AAVASTContext@2@@Z)
>
>
> clangSema.lib(TargetAttributesSema.cpp.obj) : error LNK2001:
> unresolved external symbol "public: virtual class
> clang::ARMInterruptAttr * __thiscall
> clang::ARMInterruptAttr::clone(class clang::ASTContext &)const "
> (?clone at ARMInterruptAttr@clang@@UBEPAV12 at AAVASTContext@2@@Z)
>
>
> clangSerialization.lib(ASTReaderDecl.cpp.obj) : error LNK2001:
> unresolved external symbol "public: virtual void __thiscall
> clang::ARMInterruptAttr::printPretty(class llvm::raw_ostream &,struct
> clang::PrintingPolicy const &)const "
> (?printPretty at ARMInterruptAttr@clang@@UBEXAAVraw_ostream at llvm@@ABUPrintingPolicy at 2@@Z)
>
>
> clangSema.lib(TargetAttributesSema.cpp.obj) : error LNK2019:
> unresolved external symbol "public: virtual void __thiscall
> clang::ARMInterruptAttr::printPretty(class llvm::raw_ostream &,struct
> clang::PrintingPolicy const &)const "
> (?printPretty at ARMInterruptAttr@clang@@UBEXAAVraw_ostream at llvm@@ABUPrintingPolicy at 2@@Z)
> referenced in function "private: class clang::ExtQualsTypeCommonBase
> const * __thiscall clang::QualType::getCommonPtr(void)const "
> (?getCommonPtr at QualType@clang@@ABEPBVExtQualsTypeCommonBase at 2@XZ)
>
> 2013/10/1 Tim Northover <tnorthover at apple.com>:
>> Author: tnorthover
>> Date: Tue Oct  1 09:34:25 2013
>> New Revision: 191769
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=191769&view=rev
>> Log:
>> Implement ARM GNU-style interrupt attribute
>>
>> This attribute allows users to use a modified C or C++ function as an ARM
>> exception-handling function and, with care, to successfully return control to
>> user-space after the issue has been dealt with.
>>
>> rdar://problem/14207019
>>
>> Added:
>>     cfe/trunk/test/CodeGen/arm-interrupt-attr.c
>>     cfe/trunk/test/Sema/arm-interrupt-attr.c
>> Modified:
>>     cfe/trunk/docs/LanguageExtensions.rst
>>     cfe/trunk/include/clang/Basic/Attr.td
>>     cfe/trunk/lib/CodeGen/TargetInfo.cpp
>>     cfe/trunk/lib/Sema/SemaDeclAttr.cpp
>>     cfe/trunk/lib/Sema/TargetAttributesSema.cpp
>>
>> Modified: cfe/trunk/docs/LanguageExtensions.rst
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=191769&r1=191768&r2=191769&view=diff
>> ==============================================================================
>> --- cfe/trunk/docs/LanguageExtensions.rst (original)
>> +++ cfe/trunk/docs/LanguageExtensions.rst Tue Oct  1 09:34:25 2013
>> @@ -1843,6 +1843,48 @@ Which compiles to (on X86-32):
>>            movl    %gs:(%eax), %eax
>>            ret
>>
>> +ARM Language Extensions
>> +-----------------------
>> +
>> +Interrupt attribute
>> +^^^^^^^^^^^^^^^^^^^
>> +
>> +Clang supports the GNU style ``__attribite__((interrupt("TYPE")))`` attribute on
>> +ARM targets. This attribute may be attached to a function definiton and
>> +instructs the backend to generate appropriate function entry/exit code so that
>> +it can be used directly as an interrupt service routine.
>> +
>> + The parameter passed to the interrupt attribute is optional, but if
>> +provided it must be a string literal with one of the following values: "IRQ",
>> +"FIQ", "SWI", "ABORT", "UNDEF".
>> +
>> +The semantics are as follows:
>> +
>> +- If the function is AAPCS, Clang instructs the backend to realign the stack to
>> +  8 bytes on entry. This is a general requirement of the AAPCS at public
>> +  interfaces, but may not hold when an exception is taken. Doing this allows
>> +  other AAPCS functions to be called.
>> +- If the CPU is M-class this is all that needs to be done since the architecture
>> +  itself is designed in such a way that functions obeying the normal AAPCS ABI
>> +  constraints are valid exception handlers.
>> +- If the CPU is not M-class, the prologue and epilogue are modified to save all
>> +  non-banked registers that are used, so that upon return the user-mode state
>> +  will not be corrupted. Note that to avoid unnecessary overhead, only
>> +  general-purpose (integer) registers are saved in this way. If VFP operations
>> +  are needed, that state must be saved manually.
>> +
>> +  Specifically, interrupt kinds other than "FIQ" will save all core registers
>> +  except "lr" and "sp". "FIQ" interrupts will save r0-r7.
>> +- If the CPU is not M-class, the return instruction is changed to one of the
>> +  canonical sequences permitted by the architecture for exception return. Where
>> +  possible the function itself will make the necessary "lr" adjustments so that
>> +  the "preferred return address" is selected.
>> +
>> +  Unfortunately the compiler is unable to make this guarantee for nn "UNDEF"
>> +  handler, where the offset from "lr" to the preferred return address depends on
>> +  the execution state of the code which generated the exception. In this case
>> +  a sequence equivalent to "movs pc, lr" will be used.
>> +
>>  Extensions for Static Analysis
>>  ==============================
>>
>>
>> Modified: cfe/trunk/include/clang/Basic/Attr.td
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=191769&r1=191768&r2=191769&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/Basic/Attr.td (original)
>> +++ cfe/trunk/include/clang/Basic/Attr.td Tue Oct  1 09:34:25 2013
>> @@ -210,6 +210,14 @@ def Annotate : InheritableParamAttr {
>>    let Args = [StringArgument<"Annotation">];
>>  }
>>
>> +def ARMInterrupt : InheritableAttr, TargetSpecificAttr {
>> +  let Spellings = [GNU<"interrupt">];
>> +  let Args = [EnumArgument<"Interrupt", "InterruptType",
>> +                           ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
>> +                           ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
>> +                           1>];
>> +}
>> +
>>  def AsmLabel : InheritableAttr {
>>    let Spellings = [];
>>    let Args = [StringArgument<"Label">];
>>
>> Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=191769&r1=191768&r2=191769&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
>> +++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Tue Oct  1 09:34:25 2013
>> @@ -3056,9 +3056,9 @@ public:
>>              Env == "android" || Env == "androideabi");
>>    }
>>
>> -private:
>>    ABIKind getABIKind() const { return Kind; }
>>
>> +private:
>>    ABIArgInfo classifyReturnType(QualType RetTy) const;
>>    ABIArgInfo classifyArgumentType(QualType RetTy, int *VFPRegs,
>>                                    unsigned &AllocatedVFP,
>> @@ -3105,6 +3105,45 @@ public:
>>      if (getABIInfo().isEABI()) return 88;
>>      return TargetCodeGenInfo::getSizeOfUnwindException();
>>    }
>> +
>> +  void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
>> +                           CodeGen::CodeGenModule &CGM) const {
>> +    const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
>> +    if (!FD)
>> +      return;
>> +
>> +    const ARMInterruptAttr *Attr = FD->getAttr<ARMInterruptAttr>();
>> +    if (!Attr)
>> +      return;
>> +
>> +    const char *Kind;
>> +    switch (Attr->getInterrupt()) {
>> +    case ARMInterruptAttr::Generic: Kind = ""; break;
>> +    case ARMInterruptAttr::IRQ:     Kind = "IRQ"; break;
>> +    case ARMInterruptAttr::FIQ:     Kind = "FIQ"; break;
>> +    case ARMInterruptAttr::SWI:     Kind = "SWI"; break;
>> +    case ARMInterruptAttr::ABORT:   Kind = "ABORT"; break;
>> +    case ARMInterruptAttr::UNDEF:   Kind = "UNDEF"; break;
>> +    }
>> +
>> +    llvm::Function *Fn = cast<llvm::Function>(GV);
>> +
>> +    Fn->addFnAttr("interrupt", Kind);
>> +
>> +    if (cast<ARMABIInfo>(getABIInfo()).getABIKind() == ARMABIInfo::APCS)
>> +      return;
>> +
>> +    // AAPCS guarantees that sp will be 8-byte aligned on any public interface,
>> +    // however this is not necessarily true on taking any interrupt. Instruct
>> +    // the backend to perform a realignment as part of the function prologue.
>> +    llvm::AttrBuilder B;
>> +    B.addStackAlignmentAttr(8);
>> +    Fn->addAttributes(llvm::AttributeSet::FunctionIndex,
>> +                      llvm::AttributeSet::get(CGM.getLLVMContext(),
>> +                                              llvm::AttributeSet::FunctionIndex,
>> +                                              B));
>> +  }
>> +
>>  };
>>
>>  }
>>
>> Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=191769&r1=191768&r2=191769&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue Oct  1 09:34:25 2013
>> @@ -289,7 +289,7 @@ static bool checkFunctionOrMethodArgumen
>>  /// literal.
>>  bool Sema::checkStringLiteralArgumentAttr(const AttributeList &Attr,
>>                                            unsigned ArgNum, StringRef &Str,
>> -                                          SourceLocation *ArgLocation = 0) {
>> +                                          SourceLocation *ArgLocation) {
>>    // Look for identifiers. If we have one emit a hint to fix it to a literal.
>>    if (Attr.isArgIdent(ArgNum)) {
>>      IdentifierLoc *Loc = Attr.getArgAsIdent(ArgNum);
>>
>> Modified: cfe/trunk/lib/Sema/TargetAttributesSema.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TargetAttributesSema.cpp?rev=191769&r1=191768&r2=191769&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/TargetAttributesSema.cpp (original)
>> +++ cfe/trunk/lib/Sema/TargetAttributesSema.cpp Tue Oct  1 09:34:25 2013
>> @@ -26,6 +26,50 @@ bool TargetAttributesSema::ProcessDeclAt
>>    return false;
>>  }
>>
>> +static void HandleARMInterruptAttr(Decl *d,
>> +                                   const AttributeList &Attr, Sema &S) {
>> +  // Check the attribute arguments.
>> +  if (Attr.getNumArgs() > 1) {
>> +    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments)
>> +        << 1;
>> +    return;
>> +  }
>> +
>> +  StringRef Str;
>> +  SourceLocation ArgLoc;
>> +
>> +  if (Attr.getNumArgs() == 0)
>> +    Str = "";
>> +  else if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &ArgLoc))
>> +    return;
>> +
>> +  ARMInterruptAttr::InterruptType Kind;
>> +  if (!ARMInterruptAttr::ConvertStrToInterruptType(Str, Kind)) {
>> +    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
>> +        << Attr.getName() << Str << ArgLoc;
>> +    return;
>> +  }
>> +
>> +  unsigned Index = Attr.getAttributeSpellingListIndex();
>> +  d->addAttr(::new (S.Context)
>> +             ARMInterruptAttr(Attr.getLoc(), S.Context, Kind, Index));
>> +}
>> +
>> +namespace {
>> +  class ARMAttributesSema : public TargetAttributesSema {
>> +  public:
>> +    ARMAttributesSema() { }
>> +    bool ProcessDeclAttribute(Scope *scope, Decl *D,
>> +                              const AttributeList &Attr, Sema &S) const {
>> +      if (Attr.getName()->getName() == "interrupt") {
>> +        HandleARMInterruptAttr(D, Attr, S);
>> +        return true;
>> +      }
>> +      return false;
>> +    }
>> +  };
>> +}
>> +
>>  static void HandleMSP430InterruptAttr(Decl *d,
>>                                        const AttributeList &Attr, Sema &S) {
>>      // Check the attribute arguments.
>> @@ -292,6 +336,9 @@ const TargetAttributesSema &Sema::getTar
>>
>>    const llvm::Triple &Triple(Context.getTargetInfo().getTriple());
>>    switch (Triple.getArch()) {
>> +  case llvm::Triple::arm:
>> +  case llvm::Triple::thumb:
>> +    return *(TheTargetAttributesSema = new ARMAttributesSema);
>>    case llvm::Triple::msp430:
>>      return *(TheTargetAttributesSema = new MSP430AttributesSema);
>>    case llvm::Triple::x86:
>>
>> Added: cfe/trunk/test/CodeGen/arm-interrupt-attr.c
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/arm-interrupt-attr.c?rev=191769&view=auto
>> ==============================================================================
>> --- cfe/trunk/test/CodeGen/arm-interrupt-attr.c (added)
>> +++ cfe/trunk/test/CodeGen/arm-interrupt-attr.c Tue Oct  1 09:34:25 2013
>> @@ -0,0 +1,38 @@
>> +// RUN: %clang_cc1 -triple thumb-apple-darwin -target-abi aapcs -target-cpu cortex-m3 -emit-llvm -o - %s | FileCheck %s
>> +// RUN: %clang_cc1 -triple arm-apple-darwin -target-abi apcs-gnu -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-APCS
>> +
>> +__attribute__((interrupt)) void test_generic_interrupt() {
>> +  // CHECK: define arm_aapcscc void @test_generic_interrupt() [[GENERIC_ATTR:#[0-9]+]]
>> +
>> +  // CHECK-APCS: define void @test_generic_interrupt() [[GENERIC_ATTR:#[0-9]+]]
>> +}
>> +
>> +__attribute__((interrupt("IRQ"))) void test_irq_interrupt() {
>> +  // CHECK: define arm_aapcscc void @test_irq_interrupt() [[IRQ_ATTR:#[0-9]+]]
>> +}
>> +
>> +__attribute__((interrupt("FIQ"))) void test_fiq_interrupt() {
>> +  // CHECK: define arm_aapcscc void @test_fiq_interrupt() [[FIQ_ATTR:#[0-9]+]]
>> +}
>> +
>> +__attribute__((interrupt("SWI"))) void test_swi_interrupt() {
>> +  // CHECK: define arm_aapcscc void @test_swi_interrupt() [[SWI_ATTR:#[0-9]+]]
>> +}
>> +
>> +__attribute__((interrupt("ABORT"))) void test_abort_interrupt() {
>> +  // CHECK: define arm_aapcscc void @test_abort_interrupt() [[ABORT_ATTR:#[0-9]+]]
>> +}
>> +
>> +
>> +__attribute__((interrupt("UNDEF"))) void test_undef_interrupt() {
>> +  // CHECK: define arm_aapcscc void @test_undef_interrupt() [[UNDEF_ATTR:#[0-9]+]]
>> +}
>> +
>> +// CHECK: attributes [[GENERIC_ATTR]] = { nounwind alignstack=8 {{"interrupt"[^=]}}
>> +// CHECK: attributes [[IRQ_ATTR]] = { nounwind alignstack=8 "interrupt"="IRQ"
>> +// CHECK: attributes [[FIQ_ATTR]] = { nounwind alignstack=8 "interrupt"="FIQ"
>> +// CHECK: attributes [[SWI_ATTR]] = { nounwind alignstack=8 "interrupt"="SWI"
>> +// CHECK: attributes [[ABORT_ATTR]] = { nounwind alignstack=8 "interrupt"="ABORT"
>> +// CHECK: attributes [[UNDEF_ATTR]] = { nounwind alignstack=8 "interrupt"="UNDEF"
>> +
>> +// CHECK-APCS: attributes [[GENERIC_ATTR]] = { nounwind "interrupt"
>>
>> Added: cfe/trunk/test/Sema/arm-interrupt-attr.c
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/arm-interrupt-attr.c?rev=191769&view=auto
>> ==============================================================================
>> --- cfe/trunk/test/Sema/arm-interrupt-attr.c (added)
>> +++ cfe/trunk/test/Sema/arm-interrupt-attr.c Tue Oct  1 09:34:25 2013
>> @@ -0,0 +1,16 @@
>> +// RUN: %clang_cc1 %s -triple arm-apple-darwin -verify -fsyntax-only
>> +
>> +__attribute__((interrupt(IRQ))) void foo() {} // expected-error {{'interrupt' attribute requires a string}}
>> +__attribute__((interrupt("irq"))) void foo1() {} // expected-warning {{'interrupt' attribute argument not supported: irq}}
>> +
>> +__attribute__((interrupt("IRQ", 1))) void foo2() {} // expected-error {{attribute takes no more than 1 argument}}
>> +
>> +__attribute__((interrupt("IRQ"))) void foo3() {}
>> +__attribute__((interrupt("FIQ"))) void foo4() {}
>> +__attribute__((interrupt("SWI"))) void foo5() {}
>> +__attribute__((interrupt("ABORT"))) void foo6() {}
>> +__attribute__((interrupt("UNDEF"))) void foo7() {}
>> +
>> +__attribute__((interrupt)) void foo8() {}
>> +__attribute__((interrupt())) void foo9() {}
>> +__attribute__((interrupt(""))) void foo10() {}
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits



More information about the cfe-commits mailing list