diff options
| author | Ana Pazos <apazos@codeaurora.org> | 2018-07-26 17:37:45 +0000 |
|---|---|---|
| committer | Ana Pazos <apazos@codeaurora.org> | 2018-07-26 17:37:45 +0000 |
| commit | 1eee1b771f43761e39c1e3bc9e0c31b078290240 (patch) | |
| tree | f1afb19d81b8f16649ecca26a839687f85c0f3aa /clang/lib/CodeGen/TargetInfo.cpp | |
| parent | 41ba5c1455386c87c4b20aa7a1342e80261b7f79 (diff) | |
| download | bcm5719-llvm-1eee1b771f43761e39c1e3bc9e0c31b078290240.tar.gz bcm5719-llvm-1eee1b771f43761e39c1e3bc9e0c31b078290240.zip | |
[RISCV] Add support for interrupt attribute
Summary:
Clang supports the GNU style ``__attribute__((interrupt))`` attribute on RISCV targets.
Permissible values for this parameter are user, supervisor, and machine.
If there is no parameter, then it defaults to machine.
Reference: https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Function-Attributes.html
Based on initial patch by Zhaoshi Zheng.
Reviewers: asb, aaron.ballman
Reviewed By: asb, aaron.ballman
Subscribers: rkruppe, the_o, aaron.ballman, MartinMosbeck, brucehoult, rbar, johnrusso, simoncook, sabuasal, niosHD, kito-cheng, shiva0217, zzheng, edward-jones, mgrang, rogfer01, cfe-commits
Differential Revision: https://reviews.llvm.org/D48412
llvm-svn: 338045
Diffstat (limited to 'clang/lib/CodeGen/TargetInfo.cpp')
| -rw-r--r-- | clang/lib/CodeGen/TargetInfo.cpp | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 2078ea1fea0..fa9b0a27af2 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -8971,6 +8971,27 @@ class RISCVTargetCodeGenInfo : public TargetCodeGenInfo { public: RISCVTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, unsigned XLen) : TargetCodeGenInfo(new RISCVABIInfo(CGT, XLen)) {} + + 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; + + const auto *Attr = FD->getAttr<RISCVInterruptAttr>(); + if (!Attr) + return; + + const char *Kind; + switch (Attr->getInterrupt()) { + case RISCVInterruptAttr::user: Kind = "user"; break; + case RISCVInterruptAttr::supervisor: Kind = "supervisor"; break; + case RISCVInterruptAttr::machine: Kind = "machine"; break; + } + + auto *Fn = cast<llvm::Function>(GV); + + Fn->addFnAttr("interrupt", Kind); + } }; } // namespace |

