[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2024-09-06 Thread Benson Chu via cfe-commits

https://github.com/pestctrl updated 
https://github.com/llvm/llvm-project/pull/89654

>From bf936c53e3a2052a945787dc2efc17218e0352d5 Mon Sep 17 00:00:00 2001
From: Jake Vossen 
Date: Wed, 30 Jun 2021 15:13:13 -0500
Subject: [PATCH 1/3] [ARM] Save floating point registers with save_fp function
 attribute

[ARM] and interrupt_save_fp attribute

interupt_save_fp update name; fix bugs

[ARM] fix typos and register class name

used better push / pop instructions

change epilog emitting order

WIP with FPSCR

save just d regs

cleaned up docs and ARMRegisterInfo td

change m3 to m4

fix reg tests

Minor format changes on top of Jake Vossen's support for
interrupt_save_fp function attribute which preserves VFP D
registers at the moment. FPSCR and FPEXC registers to follow.
---
 clang/include/clang/Basic/Attr.td |  16 ++
 clang/include/clang/Basic/AttrDocs.td |  14 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   8 +-
 clang/lib/CodeGen/Targets/ARM.cpp |   6 +
 clang/lib/Sema/SemaARM.cpp|   8 +-
 clang/lib/Sema/SemaDeclAttr.cpp   |  23 ++-
 .../test/CodeGen/arm-interrupt-save-fp-attr.c |  39 
 clang/test/Sema/arm-interrupt-attr.c  |   2 +-
 clang/test/Sema/arm-interrupt-save-fp-attr.c  |  59 ++
 llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp   |  30 ++-
 llvm/lib/Target/ARM/ARMCallingConv.td |  28 +++
 .../CodeGen/ARM/interrupt-save-fp-attr.ll | 171 ++
 12 files changed, 393 insertions(+), 11 deletions(-)
 create mode 100644 clang/test/CodeGen/arm-interrupt-save-fp-attr.c
 create mode 100644 clang/test/Sema/arm-interrupt-save-fp-attr.c
 create mode 100644 llvm/test/CodeGen/ARM/interrupt-save-fp-attr.ll

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 79d77b4d49b8fe..3dfcf3bcad99db 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -970,6 +970,22 @@ def ARMInterrupt : InheritableAttr, 
TargetSpecificAttr {
   let Documentation = [ARMInterruptDocs];
 }
 
+def ARMInterruptSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [GNU<"interrupt_save_fp">];
+  let Args = [EnumArgument<"Interrupt", "InterruptType", /*is_string=*/true,
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
+   1>];
+  let HasCustomParsing = 0;
+  let Documentation = [ARMInterruptSaveFPDocs];
+}
+
+def ARMSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [InternalOnly];
+}
+
 def AVRInterrupt : InheritableAttr, TargetSpecificAttr {
   let Spellings = [GCC<"interrupt">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index ef077db298831f..adaf4505cd31c5 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2295,6 +2295,20 @@ The semantics are as follows:
   }];
 }
 
+def ARMInterruptSaveFPDocs : Documentation {
+let Category = DocCatFunction;
+  let Heading = "interrupt_save_fp (ARM)";
+  let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt_save_fp("TYPE")))``
+on ARM targets. This attribute behaves the same way as the ARM interrupt
+attribute, except the general purpose floating point registers are also saved. 
+If the FPEXC or FPSCR are needed, that state must be saved manually. Note, 
even 
+on M-class CPUs, where the floating point context can be automatically saved 
+depending on the FPCCR, the general purpose floating point registers will be 
+saved.
+  }];
+}
+
 def BPFPreserveAccessIndexDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index dcb49d8a67604a..ad548fe96fe9ec 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -338,10 +338,16 @@ def warn_anyx86_excessive_regsave : Warning<
   InGroup>;
 def warn_arm_interrupt_vfp_clobber : Warning<
   "interrupt service routine with vfp enabled may clobber the "
-  "interruptee's vfp state">,
+  "interruptee's vfp state; "
+  "consider using the `interrupt_save_fp` attribute to prevent this behavior">,
   InGroup>;
 def err_arm_interrupt_called : Error<
   "interrupt service routine cannot be called directly">;
+def warn_arm_interrupt_save_fp_without_vfp_unit : Warning<
+   "`interrupt_save_fp` only applies to targets that have a VFP unit enabled "
+   "for this compilation; this will be treated as a regular `interrupt` "
+   "attribute">,
+   InGroup;
 def warn_interrupt_attribute_invalid : Warning<
"%select{MIPS|MSP430|RISC-V}0 'interrupt' attribute only applies to "
"functions that have %select{no parameters|a 'vo

[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2024-09-06 Thread Benson Chu via cfe-commits

pestctrl wrote:

ping

https://github.com/llvm/llvm-project/pull/89654
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2024-09-06 Thread Benson Chu via cfe-commits

https://github.com/pestctrl updated 
https://github.com/llvm/llvm-project/pull/89654

>From b7117c5940b018f33f99b449cecbd928a36665af Mon Sep 17 00:00:00 2001
From: Jake Vossen 
Date: Wed, 30 Jun 2021 15:13:13 -0500
Subject: [PATCH 1/3] [ARM] Save floating point registers with save_fp function
 attribute

[ARM] and interrupt_save_fp attribute

interupt_save_fp update name; fix bugs

[ARM] fix typos and register class name

used better push / pop instructions

change epilog emitting order

WIP with FPSCR

save just d regs

cleaned up docs and ARMRegisterInfo td

change m3 to m4

fix reg tests

Minor format changes on top of Jake Vossen's support for
interrupt_save_fp function attribute which preserves VFP D
registers at the moment. FPSCR and FPEXC registers to follow.
---
 clang/include/clang/Basic/Attr.td |  16 ++
 clang/include/clang/Basic/AttrDocs.td |  14 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   8 +-
 clang/lib/CodeGen/Targets/ARM.cpp |   6 +
 clang/lib/Sema/SemaARM.cpp|   8 +-
 clang/lib/Sema/SemaDeclAttr.cpp   |  17 ++
 .../test/CodeGen/arm-interrupt-save-fp-attr.c |  39 
 clang/test/Sema/arm-interrupt-attr.c  |   2 +-
 clang/test/Sema/arm-interrupt-save-fp-attr.c  |  59 ++
 llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp   |  30 ++-
 llvm/lib/Target/ARM/ARMCallingConv.td |  28 +++
 .../CodeGen/ARM/interrupt-save-fp-attr.ll | 171 ++
 12 files changed, 390 insertions(+), 8 deletions(-)
 create mode 100644 clang/test/CodeGen/arm-interrupt-save-fp-attr.c
 create mode 100644 clang/test/Sema/arm-interrupt-save-fp-attr.c
 create mode 100644 llvm/test/CodeGen/ARM/interrupt-save-fp-attr.ll

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 79d77b4d49b8fe..3dfcf3bcad99db 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -970,6 +970,22 @@ def ARMInterrupt : InheritableAttr, 
TargetSpecificAttr {
   let Documentation = [ARMInterruptDocs];
 }
 
+def ARMInterruptSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [GNU<"interrupt_save_fp">];
+  let Args = [EnumArgument<"Interrupt", "InterruptType", /*is_string=*/true,
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
+   1>];
+  let HasCustomParsing = 0;
+  let Documentation = [ARMInterruptSaveFPDocs];
+}
+
+def ARMSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [InternalOnly];
+}
+
 def AVRInterrupt : InheritableAttr, TargetSpecificAttr {
   let Spellings = [GCC<"interrupt">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index ef077db298831f..adaf4505cd31c5 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2295,6 +2295,20 @@ The semantics are as follows:
   }];
 }
 
+def ARMInterruptSaveFPDocs : Documentation {
+let Category = DocCatFunction;
+  let Heading = "interrupt_save_fp (ARM)";
+  let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt_save_fp("TYPE")))``
+on ARM targets. This attribute behaves the same way as the ARM interrupt
+attribute, except the general purpose floating point registers are also saved. 
+If the FPEXC or FPSCR are needed, that state must be saved manually. Note, 
even 
+on M-class CPUs, where the floating point context can be automatically saved 
+depending on the FPCCR, the general purpose floating point registers will be 
+saved.
+  }];
+}
+
 def BPFPreserveAccessIndexDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index dcb49d8a67604a..8a0c573e354f80 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -338,8 +338,14 @@ def warn_anyx86_excessive_regsave : Warning<
   InGroup>;
 def warn_arm_interrupt_vfp_clobber : Warning<
   "interrupt service routine with vfp enabled may clobber the "
-  "interruptee's vfp state">,
+  "interruptee's vfp state; "
+  "consider using the `interrupt_save_fp` attribute to prevent this behavior">,
   InGroup>;
+def warn_arm_interrupt_save_fp_without_vfp_unit : Warning<
+   "`interrupt_save_fp` only applies to targets that have a VFP unit enabled "
+   "for this compilation; this will be treated as a regular `interrupt` "
+   "attribute">,
+   InGroup>;
 def err_arm_interrupt_called : Error<
   "interrupt service routine cannot be called directly">;
 def warn_interrupt_attribute_invalid : Warning<
diff --git a/clang/lib/CodeGen/Targets/ARM.cpp 
b/clang/lib/CodeGen/Targets/ARM.cpp
index d032b88d7683cd..85b934aa2e1d8f 100644

[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2024-09-06 Thread Benson Chu via cfe-commits


@@ -338,10 +338,16 @@ def warn_anyx86_excessive_regsave : Warning<
   InGroup>;
 def warn_arm_interrupt_vfp_clobber : Warning<
   "interrupt service routine with vfp enabled may clobber the "
-  "interruptee's vfp state">,
+  "interruptee's vfp state; "
+  "consider using the `interrupt_save_fp` attribute to prevent this behavior">,
   InGroup>;
 def err_arm_interrupt_called : Error<
   "interrupt service routine cannot be called directly">;
+def warn_arm_interrupt_save_fp_without_vfp_unit : Warning<
+   "`interrupt_save_fp` only applies to targets that have a VFP unit enabled "
+   "for this compilation; this will be treated as a regular `interrupt` "
+   "attribute">,
+   InGroup;

pestctrl wrote:

Done

https://github.com/llvm/llvm-project/pull/89654
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2024-09-06 Thread Benson Chu via cfe-commits


@@ -0,0 +1,34 @@
+// REQUIRES: arm-registered-target
+// RUN: %clang -target arm-none-none-eabihf -mcpu=cortex-r5 -mfpu=vfpv3-d16 
-marm -S -o - %s \
+// RUN: | FileCheck %s --check-prefix=CHECK-R
+// RUN: %clang -target arm-none-none-eabihf -mcpu=cortex-r5 -mfpu=vfpv3-d16 
-mthumb -S -o - %s \
+// RUN: | FileCheck %s --check-prefix=CHECK-R
+// RUN: %clang -target arm-none-none-eabihf -mcpu=cortex-r4 -mfpu=vfpv3-d16 
-marm -S -o - %s \
+// RUN: | FileCheck %s --check-prefix=CHECK-R
+// RUN: %clang -target arm-none-none-eabihf -mcpu=cortex-r4 -mfpu=vfpv3-d16 
-mthumb -S -o - %s \
+// RUN: | FileCheck %s --check-prefix=CHECK-R
+// RUN: %clang -target arm-none-none-eabihf -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 
-S -o - %s \
+// RUN: | FileCheck %s --check-prefix=CHECK-M
+// RUN: %clang -target arm-none-none-eabihf -mcpu=cortex-m33 -mfpu=fpv5-sp-d16 
-S -o - %s \
+// RUN: | FileCheck %s --check-prefix=CHECK-M
+
+void bar();
+
+__attribute__((interrupt_save_fp)) void test_generic_interrupt() {
+// CHECK-R:  vmrs  r4, fpscr
+// CHECK-R-NEXT: vmrs  r5, fpexc
+// CHECK-R-NEXT: .save  {fpscr, fpexc}

pestctrl wrote:

I have reverted that syntax change. We had initially rolled it out internally, 
and later found that our assembler didn't like that syntax change, so we rolled 
it back. I forgot to roll it back on the upstream branch. 

To our understanding, the .save directive is for unwinding, and only accepts 
GPR's. .vsave isn't the correct directive to use either, since those only 
accept DPR's. In the end, we decided to just have those .save's refer to the 
actual GPR's. 

https://github.com/llvm/llvm-project/pull/89654
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2024-04-22 Thread Benson Chu via cfe-commits

https://github.com/pestctrl created 
https://github.com/llvm/llvm-project/pull/89654

The interrupt attribute currently doesn't save floating-point related registers 
in the frame setup and destroy. 

This patch adds a new interrupt_save_fp attribute that will save floating-point 
registers as well.

>From bb587d6a98409914e1ba54c4bb2edebc7db7eefe Mon Sep 17 00:00:00 2001
From: Jake Vossen 
Date: Wed, 30 Jun 2021 15:13:13 -0500
Subject: [PATCH 1/2] [ARM] Save floating point registers with save_fp function
 attribute

[ARM] and interrupt_save_fp attribute

interupt_save_fp update name; fix bugs

[ARM] fix typos and register class name

used better push / pop instructions

change epilog emitting order

WIP with FPSCR

save just d regs

cleaned up docs and ARMRegisterInfo td

change m3 to m4

fix reg tests

Minor format changes on top of Jake Vossen's support for
interrupt_save_fp function attribute which preserves VFP D
registers at the moment. FPSCR and FPEXC registers to follow.
---
 clang/include/clang/Basic/Attr.td |  16 ++
 clang/include/clang/Basic/AttrDocs.td |  14 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   9 +-
 clang/lib/CodeGen/Targets/ARM.cpp |   6 +
 clang/lib/Sema/SemaDeclAttr.cpp   |  24 ++-
 clang/lib/Sema/SemaExpr.cpp   |   3 +-
 .../test/CodeGen/arm-interrupt-save-fp-attr.c |  39 
 clang/test/Sema/arm-interrupt-attr.c  |   4 +-
 clang/test/Sema/arm-interrupt-save-fp-attr.c  |  59 ++
 llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp   |  30 ++-
 llvm/lib/Target/ARM/ARMCallingConv.td |  28 +++
 .../CodeGen/ARM/interrupt-save-fp-attr.ll | 171 ++
 12 files changed, 392 insertions(+), 11 deletions(-)
 create mode 100644 clang/test/CodeGen/arm-interrupt-save-fp-attr.c
 create mode 100644 clang/test/Sema/arm-interrupt-save-fp-attr.c
 create mode 100644 llvm/test/CodeGen/ARM/interrupt-save-fp-attr.ll

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index dc87a8c6f022dc..71775ce1e12461 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -914,6 +914,22 @@ def ARMInterrupt : InheritableAttr, 
TargetSpecificAttr {
   let Documentation = [ARMInterruptDocs];
 }
 
+def ARMInterruptSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [GNU<"interrupt_save_fp">];
+  let Args = [EnumArgument<"Interrupt", "InterruptType",
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
+   1>];
+  let HasCustomParsing = 0;
+  let Documentation = [ARMInterruptSaveFPDocs];
+}
+
+def ARMSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [ARMInterruptSaveFPDocs];
+}
+
 def AVRInterrupt : InheritableAttr, TargetSpecificAttr {
   let Spellings = [GCC<"interrupt">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index a0bbe5861c5722..1cd642ba90aa9e 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2239,6 +2239,20 @@ The semantics are as follows:
   }];
 }
 
+def ARMInterruptSaveFPDocs : Documentation {
+let Category = DocCatFunction;
+  let Heading = "interrupt_save_fp (ARM)";
+  let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt_save_fp("TYPE")))``
+on ARM targets. This attribute behaves the same way as the ARM interrupt
+attribute, except the general purpose floating point registers are also saved. 
+If the FPEXC or FPSCR are needed, that state must be saved manually. Note, 
even 
+on M-class CPUs, where the floating point context can be automatically saved 
+depending on the FPCCR, the general purpose floating point registers will be 
+saved.
+  }];
+}
+
 def BPFPreserveAccessIndexDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 63e951daec7477..1f519d0fc1cc35 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -335,7 +335,14 @@ def warn_anyx86_excessive_regsave : Warning<
   " or be compiled with '-mgeneral-regs-only'">,
   InGroup>;
 def warn_arm_interrupt_calling_convention : Warning<
-   "call to function without interrupt attribute could clobber interruptee's 
VFP registers">,
+  "call to function without interrupt attribute could clobber interruptee's "
+  "VFP registers; consider using the `interrupt_save_fp` attribute to prevent "
+  "this behavior">,
+   InGroup;
+def warn_arm_interrupt_save_fp_without_vfp_unit : Warning<
+   "`interrupt_save_fp` only applies to targets that have a VFP unit enabled "
+   "for this compilation; this will be treated 

[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2024-04-22 Thread Benson Chu via cfe-commits

https://github.com/pestctrl updated 
https://github.com/llvm/llvm-project/pull/89654

>From bcd01dbcbbb8950228005fadfa73bbeb49b7381d Mon Sep 17 00:00:00 2001
From: Jake Vossen 
Date: Wed, 30 Jun 2021 15:13:13 -0500
Subject: [PATCH 1/2] [ARM] Save floating point registers with save_fp function
 attribute

[ARM] and interrupt_save_fp attribute

interupt_save_fp update name; fix bugs

[ARM] fix typos and register class name

used better push / pop instructions

change epilog emitting order

WIP with FPSCR

save just d regs

cleaned up docs and ARMRegisterInfo td

change m3 to m4

fix reg tests

Minor format changes on top of Jake Vossen's support for
interrupt_save_fp function attribute which preserves VFP D
registers at the moment. FPSCR and FPEXC registers to follow.
---
 clang/include/clang/Basic/Attr.td |  16 ++
 clang/include/clang/Basic/AttrDocs.td |  14 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   9 +-
 clang/lib/CodeGen/Targets/ARM.cpp |   6 +
 clang/lib/Sema/SemaDeclAttr.cpp   |  23 ++-
 clang/lib/Sema/SemaExpr.cpp   |   3 +-
 .../test/CodeGen/arm-interrupt-save-fp-attr.c |  39 
 clang/test/Sema/arm-interrupt-attr.c  |   4 +-
 clang/test/Sema/arm-interrupt-save-fp-attr.c  |  59 ++
 llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp   |  30 ++-
 llvm/lib/Target/ARM/ARMCallingConv.td |  28 +++
 .../CodeGen/ARM/interrupt-save-fp-attr.ll | 171 ++
 12 files changed, 392 insertions(+), 10 deletions(-)
 create mode 100644 clang/test/CodeGen/arm-interrupt-save-fp-attr.c
 create mode 100644 clang/test/Sema/arm-interrupt-save-fp-attr.c
 create mode 100644 llvm/test/CodeGen/ARM/interrupt-save-fp-attr.ll

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index dc87a8c6f022dc..71775ce1e12461 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -914,6 +914,22 @@ def ARMInterrupt : InheritableAttr, 
TargetSpecificAttr {
   let Documentation = [ARMInterruptDocs];
 }
 
+def ARMInterruptSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [GNU<"interrupt_save_fp">];
+  let Args = [EnumArgument<"Interrupt", "InterruptType",
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
+   1>];
+  let HasCustomParsing = 0;
+  let Documentation = [ARMInterruptSaveFPDocs];
+}
+
+def ARMSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [ARMInterruptSaveFPDocs];
+}
+
 def AVRInterrupt : InheritableAttr, TargetSpecificAttr {
   let Spellings = [GCC<"interrupt">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index a0bbe5861c5722..1cd642ba90aa9e 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2239,6 +2239,20 @@ The semantics are as follows:
   }];
 }
 
+def ARMInterruptSaveFPDocs : Documentation {
+let Category = DocCatFunction;
+  let Heading = "interrupt_save_fp (ARM)";
+  let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt_save_fp("TYPE")))``
+on ARM targets. This attribute behaves the same way as the ARM interrupt
+attribute, except the general purpose floating point registers are also saved. 
+If the FPEXC or FPSCR are needed, that state must be saved manually. Note, 
even 
+on M-class CPUs, where the floating point context can be automatically saved 
+depending on the FPCCR, the general purpose floating point registers will be 
+saved.
+  }];
+}
+
 def BPFPreserveAccessIndexDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 63e951daec7477..1f519d0fc1cc35 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -335,7 +335,14 @@ def warn_anyx86_excessive_regsave : Warning<
   " or be compiled with '-mgeneral-regs-only'">,
   InGroup>;
 def warn_arm_interrupt_calling_convention : Warning<
-   "call to function without interrupt attribute could clobber interruptee's 
VFP registers">,
+  "call to function without interrupt attribute could clobber interruptee's "
+  "VFP registers; consider using the `interrupt_save_fp` attribute to prevent "
+  "this behavior">,
+   InGroup;
+def warn_arm_interrupt_save_fp_without_vfp_unit : Warning<
+   "`interrupt_save_fp` only applies to targets that have a VFP unit enabled "
+   "for this compilation; this will be treated as a regular `interrupt` "
+   "attribute">,
InGroup;
 def warn_interrupt_attribute_invalid : Warning<
"%select{MIPS|MSP430|RISC-V}0 'interrupt' attribute only applies to "
diff --git a/clang/lib/CodeGen/Targ

[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2024-04-22 Thread Benson Chu via cfe-commits

https://github.com/pestctrl updated 
https://github.com/llvm/llvm-project/pull/89654

>From bcd01dbcbbb8950228005fadfa73bbeb49b7381d Mon Sep 17 00:00:00 2001
From: Jake Vossen 
Date: Wed, 30 Jun 2021 15:13:13 -0500
Subject: [PATCH 1/2] [ARM] Save floating point registers with save_fp function
 attribute

[ARM] and interrupt_save_fp attribute

interupt_save_fp update name; fix bugs

[ARM] fix typos and register class name

used better push / pop instructions

change epilog emitting order

WIP with FPSCR

save just d regs

cleaned up docs and ARMRegisterInfo td

change m3 to m4

fix reg tests

Minor format changes on top of Jake Vossen's support for
interrupt_save_fp function attribute which preserves VFP D
registers at the moment. FPSCR and FPEXC registers to follow.
---
 clang/include/clang/Basic/Attr.td |  16 ++
 clang/include/clang/Basic/AttrDocs.td |  14 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   9 +-
 clang/lib/CodeGen/Targets/ARM.cpp |   6 +
 clang/lib/Sema/SemaDeclAttr.cpp   |  23 ++-
 clang/lib/Sema/SemaExpr.cpp   |   3 +-
 .../test/CodeGen/arm-interrupt-save-fp-attr.c |  39 
 clang/test/Sema/arm-interrupt-attr.c  |   4 +-
 clang/test/Sema/arm-interrupt-save-fp-attr.c  |  59 ++
 llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp   |  30 ++-
 llvm/lib/Target/ARM/ARMCallingConv.td |  28 +++
 .../CodeGen/ARM/interrupt-save-fp-attr.ll | 171 ++
 12 files changed, 392 insertions(+), 10 deletions(-)
 create mode 100644 clang/test/CodeGen/arm-interrupt-save-fp-attr.c
 create mode 100644 clang/test/Sema/arm-interrupt-save-fp-attr.c
 create mode 100644 llvm/test/CodeGen/ARM/interrupt-save-fp-attr.ll

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index dc87a8c6f022dc..71775ce1e12461 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -914,6 +914,22 @@ def ARMInterrupt : InheritableAttr, 
TargetSpecificAttr {
   let Documentation = [ARMInterruptDocs];
 }
 
+def ARMInterruptSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [GNU<"interrupt_save_fp">];
+  let Args = [EnumArgument<"Interrupt", "InterruptType",
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
+   1>];
+  let HasCustomParsing = 0;
+  let Documentation = [ARMInterruptSaveFPDocs];
+}
+
+def ARMSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [ARMInterruptSaveFPDocs];
+}
+
 def AVRInterrupt : InheritableAttr, TargetSpecificAttr {
   let Spellings = [GCC<"interrupt">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index a0bbe5861c5722..1cd642ba90aa9e 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2239,6 +2239,20 @@ The semantics are as follows:
   }];
 }
 
+def ARMInterruptSaveFPDocs : Documentation {
+let Category = DocCatFunction;
+  let Heading = "interrupt_save_fp (ARM)";
+  let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt_save_fp("TYPE")))``
+on ARM targets. This attribute behaves the same way as the ARM interrupt
+attribute, except the general purpose floating point registers are also saved. 
+If the FPEXC or FPSCR are needed, that state must be saved manually. Note, 
even 
+on M-class CPUs, where the floating point context can be automatically saved 
+depending on the FPCCR, the general purpose floating point registers will be 
+saved.
+  }];
+}
+
 def BPFPreserveAccessIndexDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 63e951daec7477..1f519d0fc1cc35 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -335,7 +335,14 @@ def warn_anyx86_excessive_regsave : Warning<
   " or be compiled with '-mgeneral-regs-only'">,
   InGroup>;
 def warn_arm_interrupt_calling_convention : Warning<
-   "call to function without interrupt attribute could clobber interruptee's 
VFP registers">,
+  "call to function without interrupt attribute could clobber interruptee's "
+  "VFP registers; consider using the `interrupt_save_fp` attribute to prevent "
+  "this behavior">,
+   InGroup;
+def warn_arm_interrupt_save_fp_without_vfp_unit : Warning<
+   "`interrupt_save_fp` only applies to targets that have a VFP unit enabled "
+   "for this compilation; this will be treated as a regular `interrupt` "
+   "attribute">,
InGroup;
 def warn_interrupt_attribute_invalid : Warning<
"%select{MIPS|MSP430|RISC-V}0 'interrupt' attribute only applies to "
diff --git a/clang/lib/CodeGen/Targ

[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2024-04-22 Thread Benson Chu via cfe-commits

https://github.com/pestctrl updated 
https://github.com/llvm/llvm-project/pull/89654

>From 45cb75575e807b576476e6822587af5c10c9c77f Mon Sep 17 00:00:00 2001
From: Jake Vossen 
Date: Wed, 30 Jun 2021 15:13:13 -0500
Subject: [PATCH 1/2] [ARM] Save floating point registers with save_fp function
 attribute

[ARM] and interrupt_save_fp attribute

interupt_save_fp update name; fix bugs

[ARM] fix typos and register class name

used better push / pop instructions

change epilog emitting order

WIP with FPSCR

save just d regs

cleaned up docs and ARMRegisterInfo td

change m3 to m4

fix reg tests

Minor format changes on top of Jake Vossen's support for
interrupt_save_fp function attribute which preserves VFP D
registers at the moment. FPSCR and FPEXC registers to follow.
---
 clang/include/clang/Basic/Attr.td |  16 ++
 clang/include/clang/Basic/AttrDocs.td |  14 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   9 +-
 clang/lib/CodeGen/Targets/ARM.cpp |   6 +
 clang/lib/Sema/SemaDeclAttr.cpp   |  23 ++-
 clang/lib/Sema/SemaExpr.cpp   |   3 +-
 .../test/CodeGen/arm-interrupt-save-fp-attr.c |  39 
 clang/test/Sema/arm-interrupt-attr.c  |   4 +-
 clang/test/Sema/arm-interrupt-save-fp-attr.c  |  59 ++
 llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp   |  30 ++-
 llvm/lib/Target/ARM/ARMCallingConv.td |  28 +++
 .../CodeGen/ARM/interrupt-save-fp-attr.ll | 171 ++
 12 files changed, 392 insertions(+), 10 deletions(-)
 create mode 100644 clang/test/CodeGen/arm-interrupt-save-fp-attr.c
 create mode 100644 clang/test/Sema/arm-interrupt-save-fp-attr.c
 create mode 100644 llvm/test/CodeGen/ARM/interrupt-save-fp-attr.ll

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index dc87a8c6f022dc..0edb6e95850694 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -914,6 +914,22 @@ def ARMInterrupt : InheritableAttr, 
TargetSpecificAttr {
   let Documentation = [ARMInterruptDocs];
 }
 
+def ARMInterruptSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [GNU<"interrupt_save_fp">];
+  let Args = [EnumArgument<"Interrupt", "InterruptType", /*is_string=*/true,
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
+   1>];
+  let HasCustomParsing = 0;
+  let Documentation = [ARMInterruptSaveFPDocs];
+}
+
+def ARMSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [ARMInterruptSaveFPDocs];
+}
+
 def AVRInterrupt : InheritableAttr, TargetSpecificAttr {
   let Spellings = [GCC<"interrupt">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index a0bbe5861c5722..1cd642ba90aa9e 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2239,6 +2239,20 @@ The semantics are as follows:
   }];
 }
 
+def ARMInterruptSaveFPDocs : Documentation {
+let Category = DocCatFunction;
+  let Heading = "interrupt_save_fp (ARM)";
+  let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt_save_fp("TYPE")))``
+on ARM targets. This attribute behaves the same way as the ARM interrupt
+attribute, except the general purpose floating point registers are also saved. 
+If the FPEXC or FPSCR are needed, that state must be saved manually. Note, 
even 
+on M-class CPUs, where the floating point context can be automatically saved 
+depending on the FPCCR, the general purpose floating point registers will be 
+saved.
+  }];
+}
+
 def BPFPreserveAccessIndexDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 63e951daec7477..1f519d0fc1cc35 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -335,7 +335,14 @@ def warn_anyx86_excessive_regsave : Warning<
   " or be compiled with '-mgeneral-regs-only'">,
   InGroup>;
 def warn_arm_interrupt_calling_convention : Warning<
-   "call to function without interrupt attribute could clobber interruptee's 
VFP registers">,
+  "call to function without interrupt attribute could clobber interruptee's "
+  "VFP registers; consider using the `interrupt_save_fp` attribute to prevent "
+  "this behavior">,
+   InGroup;
+def warn_arm_interrupt_save_fp_without_vfp_unit : Warning<
+   "`interrupt_save_fp` only applies to targets that have a VFP unit enabled "
+   "for this compilation; this will be treated as a regular `interrupt` "
+   "attribute">,
InGroup;
 def warn_interrupt_attribute_invalid : Warning<
"%select{MIPS|MSP430|RISC-V}0 'interrupt' attribute only applies to "
diff --git a/cl

[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2024-04-22 Thread Benson Chu via cfe-commits

https://github.com/pestctrl updated 
https://github.com/llvm/llvm-project/pull/89654

>From 45cb75575e807b576476e6822587af5c10c9c77f Mon Sep 17 00:00:00 2001
From: Jake Vossen 
Date: Wed, 30 Jun 2021 15:13:13 -0500
Subject: [PATCH 1/2] [ARM] Save floating point registers with save_fp function
 attribute

[ARM] and interrupt_save_fp attribute

interupt_save_fp update name; fix bugs

[ARM] fix typos and register class name

used better push / pop instructions

change epilog emitting order

WIP with FPSCR

save just d regs

cleaned up docs and ARMRegisterInfo td

change m3 to m4

fix reg tests

Minor format changes on top of Jake Vossen's support for
interrupt_save_fp function attribute which preserves VFP D
registers at the moment. FPSCR and FPEXC registers to follow.
---
 clang/include/clang/Basic/Attr.td |  16 ++
 clang/include/clang/Basic/AttrDocs.td |  14 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   9 +-
 clang/lib/CodeGen/Targets/ARM.cpp |   6 +
 clang/lib/Sema/SemaDeclAttr.cpp   |  23 ++-
 clang/lib/Sema/SemaExpr.cpp   |   3 +-
 .../test/CodeGen/arm-interrupt-save-fp-attr.c |  39 
 clang/test/Sema/arm-interrupt-attr.c  |   4 +-
 clang/test/Sema/arm-interrupt-save-fp-attr.c  |  59 ++
 llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp   |  30 ++-
 llvm/lib/Target/ARM/ARMCallingConv.td |  28 +++
 .../CodeGen/ARM/interrupt-save-fp-attr.ll | 171 ++
 12 files changed, 392 insertions(+), 10 deletions(-)
 create mode 100644 clang/test/CodeGen/arm-interrupt-save-fp-attr.c
 create mode 100644 clang/test/Sema/arm-interrupt-save-fp-attr.c
 create mode 100644 llvm/test/CodeGen/ARM/interrupt-save-fp-attr.ll

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index dc87a8c6f022dc..0edb6e95850694 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -914,6 +914,22 @@ def ARMInterrupt : InheritableAttr, 
TargetSpecificAttr {
   let Documentation = [ARMInterruptDocs];
 }
 
+def ARMInterruptSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [GNU<"interrupt_save_fp">];
+  let Args = [EnumArgument<"Interrupt", "InterruptType", /*is_string=*/true,
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
+   1>];
+  let HasCustomParsing = 0;
+  let Documentation = [ARMInterruptSaveFPDocs];
+}
+
+def ARMSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [ARMInterruptSaveFPDocs];
+}
+
 def AVRInterrupt : InheritableAttr, TargetSpecificAttr {
   let Spellings = [GCC<"interrupt">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index a0bbe5861c5722..1cd642ba90aa9e 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2239,6 +2239,20 @@ The semantics are as follows:
   }];
 }
 
+def ARMInterruptSaveFPDocs : Documentation {
+let Category = DocCatFunction;
+  let Heading = "interrupt_save_fp (ARM)";
+  let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt_save_fp("TYPE")))``
+on ARM targets. This attribute behaves the same way as the ARM interrupt
+attribute, except the general purpose floating point registers are also saved. 
+If the FPEXC or FPSCR are needed, that state must be saved manually. Note, 
even 
+on M-class CPUs, where the floating point context can be automatically saved 
+depending on the FPCCR, the general purpose floating point registers will be 
+saved.
+  }];
+}
+
 def BPFPreserveAccessIndexDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 63e951daec7477..1f519d0fc1cc35 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -335,7 +335,14 @@ def warn_anyx86_excessive_regsave : Warning<
   " or be compiled with '-mgeneral-regs-only'">,
   InGroup>;
 def warn_arm_interrupt_calling_convention : Warning<
-   "call to function without interrupt attribute could clobber interruptee's 
VFP registers">,
+  "call to function without interrupt attribute could clobber interruptee's "
+  "VFP registers; consider using the `interrupt_save_fp` attribute to prevent "
+  "this behavior">,
+   InGroup;
+def warn_arm_interrupt_save_fp_without_vfp_unit : Warning<
+   "`interrupt_save_fp` only applies to targets that have a VFP unit enabled "
+   "for this compilation; this will be treated as a regular `interrupt` "
+   "attribute">,
InGroup;
 def warn_interrupt_attribute_invalid : Warning<
"%select{MIPS|MSP430|RISC-V}0 'interrupt' attribute only applies to "
diff --git a/cl

[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2024-04-22 Thread Benson Chu via cfe-commits

https://github.com/pestctrl updated 
https://github.com/llvm/llvm-project/pull/89654

>From b9efa107018daba0d45248d42043c191b28f190c Mon Sep 17 00:00:00 2001
From: Jake Vossen 
Date: Wed, 30 Jun 2021 15:13:13 -0500
Subject: [PATCH 1/2] [ARM] Save floating point registers with save_fp function
 attribute

[ARM] and interrupt_save_fp attribute

interupt_save_fp update name; fix bugs

[ARM] fix typos and register class name

used better push / pop instructions

change epilog emitting order

WIP with FPSCR

save just d regs

cleaned up docs and ARMRegisterInfo td

change m3 to m4

fix reg tests

Minor format changes on top of Jake Vossen's support for
interrupt_save_fp function attribute which preserves VFP D
registers at the moment. FPSCR and FPEXC registers to follow.
---
 clang/include/clang/Basic/Attr.td |  16 ++
 clang/include/clang/Basic/AttrDocs.td |  14 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   9 +-
 clang/lib/CodeGen/Targets/ARM.cpp |   6 +
 clang/lib/Sema/SemaDeclAttr.cpp   |  23 ++-
 clang/lib/Sema/SemaExpr.cpp   |   3 +-
 .../test/CodeGen/arm-interrupt-save-fp-attr.c |  39 
 clang/test/Sema/arm-interrupt-attr.c  |   4 +-
 clang/test/Sema/arm-interrupt-save-fp-attr.c  |  59 ++
 llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp   |  30 ++-
 llvm/lib/Target/ARM/ARMCallingConv.td |  28 +++
 .../CodeGen/ARM/interrupt-save-fp-attr.ll | 171 ++
 12 files changed, 392 insertions(+), 10 deletions(-)
 create mode 100644 clang/test/CodeGen/arm-interrupt-save-fp-attr.c
 create mode 100644 clang/test/Sema/arm-interrupt-save-fp-attr.c
 create mode 100644 llvm/test/CodeGen/ARM/interrupt-save-fp-attr.ll

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index dc87a8c6f022dc..1187e4c1c5aac1 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -914,6 +914,22 @@ def ARMInterrupt : InheritableAttr, 
TargetSpecificAttr {
   let Documentation = [ARMInterruptDocs];
 }
 
+def ARMInterruptSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [GNU<"interrupt_save_fp">];
+  let Args = [EnumArgument<"Interrupt", "InterruptType", /*is_string=*/true,
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
+   1>];
+  let HasCustomParsing = 0;
+  let Documentation = [ARMInterruptSaveFPDocs];
+}
+
+def ARMSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [InternalOnly];
+}
+
 def AVRInterrupt : InheritableAttr, TargetSpecificAttr {
   let Spellings = [GCC<"interrupt">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index a0bbe5861c5722..1cd642ba90aa9e 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2239,6 +2239,20 @@ The semantics are as follows:
   }];
 }
 
+def ARMInterruptSaveFPDocs : Documentation {
+let Category = DocCatFunction;
+  let Heading = "interrupt_save_fp (ARM)";
+  let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt_save_fp("TYPE")))``
+on ARM targets. This attribute behaves the same way as the ARM interrupt
+attribute, except the general purpose floating point registers are also saved. 
+If the FPEXC or FPSCR are needed, that state must be saved manually. Note, 
even 
+on M-class CPUs, where the floating point context can be automatically saved 
+depending on the FPCCR, the general purpose floating point registers will be 
+saved.
+  }];
+}
+
 def BPFPreserveAccessIndexDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 63e951daec7477..1f519d0fc1cc35 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -335,7 +335,14 @@ def warn_anyx86_excessive_regsave : Warning<
   " or be compiled with '-mgeneral-regs-only'">,
   InGroup>;
 def warn_arm_interrupt_calling_convention : Warning<
-   "call to function without interrupt attribute could clobber interruptee's 
VFP registers">,
+  "call to function without interrupt attribute could clobber interruptee's "
+  "VFP registers; consider using the `interrupt_save_fp` attribute to prevent "
+  "this behavior">,
+   InGroup;
+def warn_arm_interrupt_save_fp_without_vfp_unit : Warning<
+   "`interrupt_save_fp` only applies to targets that have a VFP unit enabled "
+   "for this compilation; this will be treated as a regular `interrupt` "
+   "attribute">,
InGroup;
 def warn_interrupt_attribute_invalid : Warning<
"%select{MIPS|MSP430|RISC-V}0 'interrupt' attribute only applies to "
diff --git a/clang/lib/Co

[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2024-04-23 Thread Benson Chu via cfe-commits

https://github.com/pestctrl updated 
https://github.com/llvm/llvm-project/pull/89654

>From b9efa107018daba0d45248d42043c191b28f190c Mon Sep 17 00:00:00 2001
From: Jake Vossen 
Date: Wed, 30 Jun 2021 15:13:13 -0500
Subject: [PATCH 1/2] [ARM] Save floating point registers with save_fp function
 attribute

[ARM] and interrupt_save_fp attribute

interupt_save_fp update name; fix bugs

[ARM] fix typos and register class name

used better push / pop instructions

change epilog emitting order

WIP with FPSCR

save just d regs

cleaned up docs and ARMRegisterInfo td

change m3 to m4

fix reg tests

Minor format changes on top of Jake Vossen's support for
interrupt_save_fp function attribute which preserves VFP D
registers at the moment. FPSCR and FPEXC registers to follow.
---
 clang/include/clang/Basic/Attr.td |  16 ++
 clang/include/clang/Basic/AttrDocs.td |  14 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   9 +-
 clang/lib/CodeGen/Targets/ARM.cpp |   6 +
 clang/lib/Sema/SemaDeclAttr.cpp   |  23 ++-
 clang/lib/Sema/SemaExpr.cpp   |   3 +-
 .../test/CodeGen/arm-interrupt-save-fp-attr.c |  39 
 clang/test/Sema/arm-interrupt-attr.c  |   4 +-
 clang/test/Sema/arm-interrupt-save-fp-attr.c  |  59 ++
 llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp   |  30 ++-
 llvm/lib/Target/ARM/ARMCallingConv.td |  28 +++
 .../CodeGen/ARM/interrupt-save-fp-attr.ll | 171 ++
 12 files changed, 392 insertions(+), 10 deletions(-)
 create mode 100644 clang/test/CodeGen/arm-interrupt-save-fp-attr.c
 create mode 100644 clang/test/Sema/arm-interrupt-save-fp-attr.c
 create mode 100644 llvm/test/CodeGen/ARM/interrupt-save-fp-attr.ll

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index dc87a8c6f022dc..1187e4c1c5aac1 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -914,6 +914,22 @@ def ARMInterrupt : InheritableAttr, 
TargetSpecificAttr {
   let Documentation = [ARMInterruptDocs];
 }
 
+def ARMInterruptSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [GNU<"interrupt_save_fp">];
+  let Args = [EnumArgument<"Interrupt", "InterruptType", /*is_string=*/true,
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
+   1>];
+  let HasCustomParsing = 0;
+  let Documentation = [ARMInterruptSaveFPDocs];
+}
+
+def ARMSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [InternalOnly];
+}
+
 def AVRInterrupt : InheritableAttr, TargetSpecificAttr {
   let Spellings = [GCC<"interrupt">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index a0bbe5861c5722..1cd642ba90aa9e 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2239,6 +2239,20 @@ The semantics are as follows:
   }];
 }
 
+def ARMInterruptSaveFPDocs : Documentation {
+let Category = DocCatFunction;
+  let Heading = "interrupt_save_fp (ARM)";
+  let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt_save_fp("TYPE")))``
+on ARM targets. This attribute behaves the same way as the ARM interrupt
+attribute, except the general purpose floating point registers are also saved. 
+If the FPEXC or FPSCR are needed, that state must be saved manually. Note, 
even 
+on M-class CPUs, where the floating point context can be automatically saved 
+depending on the FPCCR, the general purpose floating point registers will be 
+saved.
+  }];
+}
+
 def BPFPreserveAccessIndexDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 63e951daec7477..1f519d0fc1cc35 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -335,7 +335,14 @@ def warn_anyx86_excessive_regsave : Warning<
   " or be compiled with '-mgeneral-regs-only'">,
   InGroup>;
 def warn_arm_interrupt_calling_convention : Warning<
-   "call to function without interrupt attribute could clobber interruptee's 
VFP registers">,
+  "call to function without interrupt attribute could clobber interruptee's "
+  "VFP registers; consider using the `interrupt_save_fp` attribute to prevent "
+  "this behavior">,
+   InGroup;
+def warn_arm_interrupt_save_fp_without_vfp_unit : Warning<
+   "`interrupt_save_fp` only applies to targets that have a VFP unit enabled "
+   "for this compilation; this will be treated as a regular `interrupt` "
+   "attribute">,
InGroup;
 def warn_interrupt_attribute_invalid : Warning<
"%select{MIPS|MSP430|RISC-V}0 'interrupt' attribute only applies to "
diff --git a/clang/lib/Co

[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2024-04-23 Thread Benson Chu via cfe-commits

https://github.com/pestctrl updated 
https://github.com/llvm/llvm-project/pull/89654

>From b9efa107018daba0d45248d42043c191b28f190c Mon Sep 17 00:00:00 2001
From: Jake Vossen 
Date: Wed, 30 Jun 2021 15:13:13 -0500
Subject: [PATCH 1/2] [ARM] Save floating point registers with save_fp function
 attribute

[ARM] and interrupt_save_fp attribute

interupt_save_fp update name; fix bugs

[ARM] fix typos and register class name

used better push / pop instructions

change epilog emitting order

WIP with FPSCR

save just d regs

cleaned up docs and ARMRegisterInfo td

change m3 to m4

fix reg tests

Minor format changes on top of Jake Vossen's support for
interrupt_save_fp function attribute which preserves VFP D
registers at the moment. FPSCR and FPEXC registers to follow.
---
 clang/include/clang/Basic/Attr.td |  16 ++
 clang/include/clang/Basic/AttrDocs.td |  14 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   9 +-
 clang/lib/CodeGen/Targets/ARM.cpp |   6 +
 clang/lib/Sema/SemaDeclAttr.cpp   |  23 ++-
 clang/lib/Sema/SemaExpr.cpp   |   3 +-
 .../test/CodeGen/arm-interrupt-save-fp-attr.c |  39 
 clang/test/Sema/arm-interrupt-attr.c  |   4 +-
 clang/test/Sema/arm-interrupt-save-fp-attr.c  |  59 ++
 llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp   |  30 ++-
 llvm/lib/Target/ARM/ARMCallingConv.td |  28 +++
 .../CodeGen/ARM/interrupt-save-fp-attr.ll | 171 ++
 12 files changed, 392 insertions(+), 10 deletions(-)
 create mode 100644 clang/test/CodeGen/arm-interrupt-save-fp-attr.c
 create mode 100644 clang/test/Sema/arm-interrupt-save-fp-attr.c
 create mode 100644 llvm/test/CodeGen/ARM/interrupt-save-fp-attr.ll

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index dc87a8c6f022dc..1187e4c1c5aac1 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -914,6 +914,22 @@ def ARMInterrupt : InheritableAttr, 
TargetSpecificAttr {
   let Documentation = [ARMInterruptDocs];
 }
 
+def ARMInterruptSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [GNU<"interrupt_save_fp">];
+  let Args = [EnumArgument<"Interrupt", "InterruptType", /*is_string=*/true,
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
+   1>];
+  let HasCustomParsing = 0;
+  let Documentation = [ARMInterruptSaveFPDocs];
+}
+
+def ARMSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [InternalOnly];
+}
+
 def AVRInterrupt : InheritableAttr, TargetSpecificAttr {
   let Spellings = [GCC<"interrupt">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index a0bbe5861c5722..1cd642ba90aa9e 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2239,6 +2239,20 @@ The semantics are as follows:
   }];
 }
 
+def ARMInterruptSaveFPDocs : Documentation {
+let Category = DocCatFunction;
+  let Heading = "interrupt_save_fp (ARM)";
+  let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt_save_fp("TYPE")))``
+on ARM targets. This attribute behaves the same way as the ARM interrupt
+attribute, except the general purpose floating point registers are also saved. 
+If the FPEXC or FPSCR are needed, that state must be saved manually. Note, 
even 
+on M-class CPUs, where the floating point context can be automatically saved 
+depending on the FPCCR, the general purpose floating point registers will be 
+saved.
+  }];
+}
+
 def BPFPreserveAccessIndexDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 63e951daec7477..1f519d0fc1cc35 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -335,7 +335,14 @@ def warn_anyx86_excessive_regsave : Warning<
   " or be compiled with '-mgeneral-regs-only'">,
   InGroup>;
 def warn_arm_interrupt_calling_convention : Warning<
-   "call to function without interrupt attribute could clobber interruptee's 
VFP registers">,
+  "call to function without interrupt attribute could clobber interruptee's "
+  "VFP registers; consider using the `interrupt_save_fp` attribute to prevent "
+  "this behavior">,
+   InGroup;
+def warn_arm_interrupt_save_fp_without_vfp_unit : Warning<
+   "`interrupt_save_fp` only applies to targets that have a VFP unit enabled "
+   "for this compilation; this will be treated as a regular `interrupt` "
+   "attribute">,
InGroup;
 def warn_interrupt_attribute_invalid : Warning<
"%select{MIPS|MSP430|RISC-V}0 'interrupt' attribute only applies to "
diff --git a/clang/lib/Co

[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2024-05-06 Thread Benson Chu via cfe-commits

pestctrl wrote:

ping!

https://github.com/llvm/llvm-project/pull/89654
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2024-05-06 Thread Benson Chu via cfe-commits

https://github.com/pestctrl updated 
https://github.com/llvm/llvm-project/pull/89654

>From 0e0fcca8752ff4e9478cc2e6710e188e65da71e6 Mon Sep 17 00:00:00 2001
From: Jake Vossen 
Date: Wed, 30 Jun 2021 15:13:13 -0500
Subject: [PATCH 1/2] [ARM] Save floating point registers with save_fp function
 attribute

[ARM] and interrupt_save_fp attribute

interupt_save_fp update name; fix bugs

[ARM] fix typos and register class name

used better push / pop instructions

change epilog emitting order

WIP with FPSCR

save just d regs

cleaned up docs and ARMRegisterInfo td

change m3 to m4

fix reg tests

Minor format changes on top of Jake Vossen's support for
interrupt_save_fp function attribute which preserves VFP D
registers at the moment. FPSCR and FPEXC registers to follow.
---
 clang/include/clang/Basic/Attr.td |  16 ++
 clang/include/clang/Basic/AttrDocs.td |  14 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   9 +-
 clang/lib/CodeGen/Targets/ARM.cpp |   6 +
 clang/lib/Sema/SemaDeclAttr.cpp   |  23 ++-
 clang/lib/Sema/SemaExpr.cpp   |   3 +-
 .../test/CodeGen/arm-interrupt-save-fp-attr.c |  39 
 clang/test/Sema/arm-interrupt-attr.c  |   4 +-
 clang/test/Sema/arm-interrupt-save-fp-attr.c  |  59 ++
 llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp   |  30 ++-
 llvm/lib/Target/ARM/ARMCallingConv.td |  28 +++
 .../CodeGen/ARM/interrupt-save-fp-attr.ll | 171 ++
 12 files changed, 392 insertions(+), 10 deletions(-)
 create mode 100644 clang/test/CodeGen/arm-interrupt-save-fp-attr.c
 create mode 100644 clang/test/Sema/arm-interrupt-save-fp-attr.c
 create mode 100644 llvm/test/CodeGen/ARM/interrupt-save-fp-attr.ll

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 0225598cbbe8ad..c13b886ff08bd6 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -957,6 +957,22 @@ def ARMInterrupt : InheritableAttr, 
TargetSpecificAttr {
   let Documentation = [ARMInterruptDocs];
 }
 
+def ARMInterruptSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [GNU<"interrupt_save_fp">];
+  let Args = [EnumArgument<"Interrupt", "InterruptType", /*is_string=*/true,
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
+   1>];
+  let HasCustomParsing = 0;
+  let Documentation = [ARMInterruptSaveFPDocs];
+}
+
+def ARMSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [InternalOnly];
+}
+
 def AVRInterrupt : InheritableAttr, TargetSpecificAttr {
   let Spellings = [GCC<"interrupt">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 8e6faabfae647a..3ba43eb27e9584 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2239,6 +2239,20 @@ The semantics are as follows:
   }];
 }
 
+def ARMInterruptSaveFPDocs : Documentation {
+let Category = DocCatFunction;
+  let Heading = "interrupt_save_fp (ARM)";
+  let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt_save_fp("TYPE")))``
+on ARM targets. This attribute behaves the same way as the ARM interrupt
+attribute, except the general purpose floating point registers are also saved. 
+If the FPEXC or FPSCR are needed, that state must be saved manually. Note, 
even 
+on M-class CPUs, where the floating point context can be automatically saved 
+depending on the FPCCR, the general purpose floating point registers will be 
+saved.
+  }];
+}
+
 def BPFPreserveAccessIndexDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9a0bae9c216de9..f3e2f07b873d37 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -337,7 +337,14 @@ def warn_anyx86_excessive_regsave : Warning<
   " or be compiled with '-mgeneral-regs-only'">,
   InGroup>;
 def warn_arm_interrupt_calling_convention : Warning<
-   "call to function without interrupt attribute could clobber interruptee's 
VFP registers">,
+  "call to function without interrupt attribute could clobber interruptee's "
+  "VFP registers; consider using the `interrupt_save_fp` attribute to prevent "
+  "this behavior">,
+   InGroup;
+def warn_arm_interrupt_save_fp_without_vfp_unit : Warning<
+   "`interrupt_save_fp` only applies to targets that have a VFP unit enabled "
+   "for this compilation; this will be treated as a regular `interrupt` "
+   "attribute">,
InGroup;
 def warn_interrupt_attribute_invalid : Warning<
"%select{MIPS|MSP430|RISC-V}0 'interrupt' attribute only applies to "
diff --git a/clang/lib/Co

[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2024-05-14 Thread Benson Chu via cfe-commits


@@ -2239,6 +2239,20 @@ The semantics are as follows:
   }];
 }
 
+def ARMInterruptSaveFPDocs : Documentation {
+let Category = DocCatFunction;
+  let Heading = "interrupt_save_fp (ARM)";
+  let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt_save_fp("TYPE")))``
+on ARM targets. This attribute behaves the same way as the ARM interrupt
+attribute, except the general purpose floating point registers are also saved. 
+If the FPEXC or FPSCR are needed, that state must be saved manually. Note, 
even 

pestctrl wrote:

The FPSCR is in fact saved, along with the FPEXC.

https://github.com/llvm/llvm-project/pull/89654
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2024-05-21 Thread Benson Chu via cfe-commits

pestctrl wrote:

ping!

https://github.com/llvm/llvm-project/pull/89654
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2024-05-21 Thread Benson Chu via cfe-commits

https://github.com/pestctrl updated 
https://github.com/llvm/llvm-project/pull/89654

>From 0e0fcca8752ff4e9478cc2e6710e188e65da71e6 Mon Sep 17 00:00:00 2001
From: Jake Vossen 
Date: Wed, 30 Jun 2021 15:13:13 -0500
Subject: [PATCH 1/2] [ARM] Save floating point registers with save_fp function
 attribute

[ARM] and interrupt_save_fp attribute

interupt_save_fp update name; fix bugs

[ARM] fix typos and register class name

used better push / pop instructions

change epilog emitting order

WIP with FPSCR

save just d regs

cleaned up docs and ARMRegisterInfo td

change m3 to m4

fix reg tests

Minor format changes on top of Jake Vossen's support for
interrupt_save_fp function attribute which preserves VFP D
registers at the moment. FPSCR and FPEXC registers to follow.
---
 clang/include/clang/Basic/Attr.td |  16 ++
 clang/include/clang/Basic/AttrDocs.td |  14 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   9 +-
 clang/lib/CodeGen/Targets/ARM.cpp |   6 +
 clang/lib/Sema/SemaDeclAttr.cpp   |  23 ++-
 clang/lib/Sema/SemaExpr.cpp   |   3 +-
 .../test/CodeGen/arm-interrupt-save-fp-attr.c |  39 
 clang/test/Sema/arm-interrupt-attr.c  |   4 +-
 clang/test/Sema/arm-interrupt-save-fp-attr.c  |  59 ++
 llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp   |  30 ++-
 llvm/lib/Target/ARM/ARMCallingConv.td |  28 +++
 .../CodeGen/ARM/interrupt-save-fp-attr.ll | 171 ++
 12 files changed, 392 insertions(+), 10 deletions(-)
 create mode 100644 clang/test/CodeGen/arm-interrupt-save-fp-attr.c
 create mode 100644 clang/test/Sema/arm-interrupt-save-fp-attr.c
 create mode 100644 llvm/test/CodeGen/ARM/interrupt-save-fp-attr.ll

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 0225598cbbe8a..c13b886ff08bd 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -957,6 +957,22 @@ def ARMInterrupt : InheritableAttr, 
TargetSpecificAttr {
   let Documentation = [ARMInterruptDocs];
 }
 
+def ARMInterruptSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [GNU<"interrupt_save_fp">];
+  let Args = [EnumArgument<"Interrupt", "InterruptType", /*is_string=*/true,
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
+   1>];
+  let HasCustomParsing = 0;
+  let Documentation = [ARMInterruptSaveFPDocs];
+}
+
+def ARMSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [InternalOnly];
+}
+
 def AVRInterrupt : InheritableAttr, TargetSpecificAttr {
   let Spellings = [GCC<"interrupt">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 8e6faabfae647..3ba43eb27e958 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2239,6 +2239,20 @@ The semantics are as follows:
   }];
 }
 
+def ARMInterruptSaveFPDocs : Documentation {
+let Category = DocCatFunction;
+  let Heading = "interrupt_save_fp (ARM)";
+  let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt_save_fp("TYPE")))``
+on ARM targets. This attribute behaves the same way as the ARM interrupt
+attribute, except the general purpose floating point registers are also saved. 
+If the FPEXC or FPSCR are needed, that state must be saved manually. Note, 
even 
+on M-class CPUs, where the floating point context can be automatically saved 
+depending on the FPCCR, the general purpose floating point registers will be 
+saved.
+  }];
+}
+
 def BPFPreserveAccessIndexDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9a0bae9c216de..f3e2f07b873d3 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -337,7 +337,14 @@ def warn_anyx86_excessive_regsave : Warning<
   " or be compiled with '-mgeneral-regs-only'">,
   InGroup>;
 def warn_arm_interrupt_calling_convention : Warning<
-   "call to function without interrupt attribute could clobber interruptee's 
VFP registers">,
+  "call to function without interrupt attribute could clobber interruptee's "
+  "VFP registers; consider using the `interrupt_save_fp` attribute to prevent "
+  "this behavior">,
+   InGroup;
+def warn_arm_interrupt_save_fp_without_vfp_unit : Warning<
+   "`interrupt_save_fp` only applies to targets that have a VFP unit enabled "
+   "for this compilation; this will be treated as a regular `interrupt` "
+   "attribute">,
InGroup;
 def warn_interrupt_attribute_invalid : Warning<
"%select{MIPS|MSP430|RISC-V}0 'interrupt' attribute only applies to "
diff --git a/clang/lib/CodeGen/

[clang] 9a5f388 - [AST] Pick last tentative definition as the acting definition

2021-08-24 Thread Benson Chu via cfe-commits

Author: Benson Chu
Date: 2021-08-24T08:51:50-05:00
New Revision: 9a5f3888505630cea88f8372d3068b2d63cfb381

URL: 
https://github.com/llvm/llvm-project/commit/9a5f3888505630cea88f8372d3068b2d63cfb381
DIFF: 
https://github.com/llvm/llvm-project/commit/9a5f3888505630cea88f8372d3068b2d63cfb381.diff

LOG: [AST] Pick last tentative definition as the acting definition

Clang currently picks the second tentative definition when
VarDecl::getActingDefinition is called.

This can lead to attributes being dropped if they are attached to
tentative definitions that appear after the second one. This is
because VarDecl::getActingDefinition loops through VarDecl::redecls
assuming that the last tentative definition is the last element in the
iterator. However, it is the second element that would be the last
tentative definition.

This changeset modifies getActingDefinition to iterate through the
declaration chain in reverse, so that it can immediately return when
it encounters a tentative definition.

Differential Revision: https://reviews.llvm.org/D99732

Added: 
clang/test/CodeGen/attr-tentative-definition.c

Modified: 
clang/lib/AST/Decl.cpp

Removed: 




diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index aa9fba519642..835e28c0bc9f 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2216,14 +2216,18 @@ VarDecl *VarDecl::getActingDefinition() {
 return nullptr;
 
   VarDecl *LastTentative = nullptr;
-  VarDecl *First = getFirstDecl();
-  for (auto I : First->redecls()) {
-Kind = I->isThisDeclarationADefinition();
+
+  // Loop through the declaration chain, starting with the most recent.
+  for (VarDecl *Decl = getMostRecentDecl(); Decl;
+   Decl = Decl->getPreviousDecl()) {
+Kind = Decl->isThisDeclarationADefinition();
 if (Kind == Definition)
   return nullptr;
-if (Kind == TentativeDefinition)
-  LastTentative = I;
+// Record the first (most recent) TentativeDefinition that is encountered.
+if (Kind == TentativeDefinition && !LastTentative)
+  LastTentative = Decl;
   }
+
   return LastTentative;
 }
 

diff  --git a/clang/test/CodeGen/attr-tentative-definition.c 
b/clang/test/CodeGen/attr-tentative-definition.c
new file mode 100644
index ..7405e8079b22
--- /dev/null
+++ b/clang/test/CodeGen/attr-tentative-definition.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm < %s | FileCheck %s
+
+char arr[10];
+char arr[10] __attribute__((section("datadata")));
+char arr[10] __attribute__((aligned(16)));
+
+// CHECK: @arr ={{.*}}section "datadata", align 16



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 1b19f90 - Revert "[AST] Pick last tentative definition as the acting definition"

2021-08-24 Thread Benson Chu via cfe-commits

Author: Benson Chu
Date: 2021-08-24T11:41:50-05:00
New Revision: 1b19f90a2390b60852c0ff5e1671c76dd82dac83

URL: 
https://github.com/llvm/llvm-project/commit/1b19f90a2390b60852c0ff5e1671c76dd82dac83
DIFF: 
https://github.com/llvm/llvm-project/commit/1b19f90a2390b60852c0ff5e1671c76dd82dac83.diff

LOG: Revert "[AST] Pick last tentative definition as the acting definition"

This reverts commit 9a5f3888505630cea88f8372d3068b2d63cfb381.

The written test breaks some builds on Mach-O.

Added: 


Modified: 
clang/lib/AST/Decl.cpp

Removed: 
clang/test/CodeGen/attr-tentative-definition.c



diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 835e28c0bc9fc..aa9fba519642a 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2216,18 +2216,14 @@ VarDecl *VarDecl::getActingDefinition() {
 return nullptr;
 
   VarDecl *LastTentative = nullptr;
-
-  // Loop through the declaration chain, starting with the most recent.
-  for (VarDecl *Decl = getMostRecentDecl(); Decl;
-   Decl = Decl->getPreviousDecl()) {
-Kind = Decl->isThisDeclarationADefinition();
+  VarDecl *First = getFirstDecl();
+  for (auto I : First->redecls()) {
+Kind = I->isThisDeclarationADefinition();
 if (Kind == Definition)
   return nullptr;
-// Record the first (most recent) TentativeDefinition that is encountered.
-if (Kind == TentativeDefinition && !LastTentative)
-  LastTentative = Decl;
+if (Kind == TentativeDefinition)
+  LastTentative = I;
   }
-
   return LastTentative;
 }
 

diff  --git a/clang/test/CodeGen/attr-tentative-definition.c 
b/clang/test/CodeGen/attr-tentative-definition.c
deleted file mode 100644
index 7405e8079b220..0
--- a/clang/test/CodeGen/attr-tentative-definition.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: %clang_cc1 -emit-llvm < %s | FileCheck %s
-
-char arr[10];
-char arr[10] __attribute__((section("datadata")));
-char arr[10] __attribute__((aligned(16)));
-
-// CHECK: @arr ={{.*}}section "datadata", align 16



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 7bd92f5 - [AST] Pick last tentative definition as the acting definition

2021-08-26 Thread Benson Chu via cfe-commits

Author: Benson Chu
Date: 2021-08-26T16:49:54-05:00
New Revision: 7bd92f5911dc7ec54200d37552d364f87ad03dfb

URL: 
https://github.com/llvm/llvm-project/commit/7bd92f5911dc7ec54200d37552d364f87ad03dfb
DIFF: 
https://github.com/llvm/llvm-project/commit/7bd92f5911dc7ec54200d37552d364f87ad03dfb.diff

LOG: [AST] Pick last tentative definition as the acting definition

Clang currently picks the second tentative definition when
VarDecl::getActingDefinition is called.

This can lead to attributes being dropped if they are attached to
tentative definitions that appear after the second one. This is
because VarDecl::getActingDefinition loops through VarDecl::redecls
assuming that the last tentative definition is the last element in the
iterator. However, it is the second element that would be the last
tentative definition.

This changeset modifies getActingDefinition to iterate through the
declaration chain in reverse, so that it can immediately return when
it encounters a tentative definition.

Originally the unit test for this changeset did not have a -triple
flag for the clang invocation, leading to this test being broken on
MacOS, since Mach-O does not support the section attribute.

Differential Revision: https://reviews.llvm.org/D99732

Added: 
clang/test/CodeGen/attr-tentative-definition.c

Modified: 
clang/lib/AST/Decl.cpp

Removed: 




diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index aa9fba519642a..835e28c0bc9fc 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2216,14 +2216,18 @@ VarDecl *VarDecl::getActingDefinition() {
 return nullptr;
 
   VarDecl *LastTentative = nullptr;
-  VarDecl *First = getFirstDecl();
-  for (auto I : First->redecls()) {
-Kind = I->isThisDeclarationADefinition();
+
+  // Loop through the declaration chain, starting with the most recent.
+  for (VarDecl *Decl = getMostRecentDecl(); Decl;
+   Decl = Decl->getPreviousDecl()) {
+Kind = Decl->isThisDeclarationADefinition();
 if (Kind == Definition)
   return nullptr;
-if (Kind == TentativeDefinition)
-  LastTentative = I;
+// Record the first (most recent) TentativeDefinition that is encountered.
+if (Kind == TentativeDefinition && !LastTentative)
+  LastTentative = Decl;
   }
+
   return LastTentative;
 }
 

diff  --git a/clang/test/CodeGen/attr-tentative-definition.c 
b/clang/test/CodeGen/attr-tentative-definition.c
new file mode 100644
index 0..0c49894e9bbc0
--- /dev/null
+++ b/clang/test/CodeGen/attr-tentative-definition.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-linux-unknown < %s | FileCheck %s
+
+char arr[10];
+char arr[10] __attribute__((section("datadata")));
+char arr[10] __attribute__((aligned(16)));
+
+// CHECK: @arr ={{.*}}section "datadata", align 16



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2024-10-22 Thread Benson Chu via cfe-commits

https://github.com/pestctrl updated 
https://github.com/llvm/llvm-project/pull/89654

>From c95cabceac9daa7fe927127ec57d9b31232941fe Mon Sep 17 00:00:00 2001
From: Jake Vossen 
Date: Wed, 30 Jun 2021 15:13:13 -0500
Subject: [PATCH 1/3] [ARM] Save floating point registers with save_fp function
 attribute

[ARM] and interrupt_save_fp attribute

interupt_save_fp update name; fix bugs

[ARM] fix typos and register class name

used better push / pop instructions

change epilog emitting order

WIP with FPSCR

save just d regs

cleaned up docs and ARMRegisterInfo td

change m3 to m4

fix reg tests

Minor format changes on top of Jake Vossen's support for
interrupt_save_fp function attribute which preserves VFP D
registers at the moment. FPSCR and FPEXC registers to follow.
---
 clang/include/clang/Basic/Attr.td |  16 ++
 clang/include/clang/Basic/AttrDocs.td |  14 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   8 +-
 clang/lib/CodeGen/Targets/ARM.cpp |   6 +
 clang/lib/Sema/SemaARM.cpp|   8 +-
 clang/lib/Sema/SemaDeclAttr.cpp   |  17 ++
 .../test/CodeGen/arm-interrupt-save-fp-attr.c |  39 
 clang/test/Sema/arm-interrupt-attr.c  |   2 +-
 clang/test/Sema/arm-interrupt-save-fp-attr.c  |  59 ++
 llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp   |  34 +++-
 llvm/lib/Target/ARM/ARMCallingConv.td |  28 +++
 .../CodeGen/ARM/interrupt-save-fp-attr.ll | 171 ++
 12 files changed, 392 insertions(+), 10 deletions(-)
 create mode 100644 clang/test/CodeGen/arm-interrupt-save-fp-attr.c
 create mode 100644 clang/test/Sema/arm-interrupt-save-fp-attr.c
 create mode 100644 llvm/test/CodeGen/ARM/interrupt-save-fp-attr.ll

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 0259b6e40ca962..2b149aeb13e71f 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -975,6 +975,22 @@ def ARMInterrupt : InheritableAttr, 
TargetSpecificAttr {
   let Documentation = [ARMInterruptDocs];
 }
 
+def ARMInterruptSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [GNU<"interrupt_save_fp">];
+  let Args = [EnumArgument<"Interrupt", "InterruptType", /*is_string=*/true,
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
+   1>];
+  let HasCustomParsing = 0;
+  let Documentation = [ARMInterruptSaveFPDocs];
+}
+
+def ARMSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [InternalOnly];
+}
+
 def AVRInterrupt : InheritableAttr, TargetSpecificAttr {
   let Spellings = [GCC<"interrupt">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index ee8126cadae232..0f105abf5eb433 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2301,6 +2301,20 @@ The semantics are as follows:
   }];
 }
 
+def ARMInterruptSaveFPDocs : Documentation {
+let Category = DocCatFunction;
+  let Heading = "interrupt_save_fp (ARM)";
+  let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt_save_fp("TYPE")))``
+on ARM targets. This attribute behaves the same way as the ARM interrupt
+attribute, except the general purpose floating point registers are also saved. 
+If the FPEXC or FPSCR are needed, that state must be saved manually. Note, 
even 
+on M-class CPUs, where the floating point context can be automatically saved 
+depending on the FPCCR, the general purpose floating point registers will be 
+saved.
+  }];
+}
+
 def BPFPreserveAccessIndexDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 883db838ca0147..08037e0bce03d5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -346,8 +346,14 @@ def warn_anyx86_excessive_regsave : Warning<
   InGroup>;
 def warn_arm_interrupt_vfp_clobber : Warning<
   "interrupt service routine with vfp enabled may clobber the "
-  "interruptee's vfp state">,
+  "interruptee's vfp state; "
+  "consider using the `interrupt_save_fp` attribute to prevent this behavior">,
   InGroup>;
+def warn_arm_interrupt_save_fp_without_vfp_unit : Warning<
+   "`interrupt_save_fp` only applies to targets that have a VFP unit enabled "
+   "for this compilation; this will be treated as a regular `interrupt` "
+   "attribute">,
+   InGroup>;
 def err_arm_interrupt_called : Error<
   "interrupt service routine cannot be called directly">;
 def warn_interrupt_attribute_invalid : Warning<
diff --git a/clang/lib/CodeGen/Targets/ARM.cpp 
b/clang/lib/CodeGen/Targets/ARM.cpp
index 49ac1a76e767aa..f0d43d93bbdfee 10064

[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2024-12-27 Thread Benson Chu via cfe-commits


@@ -80,13 +80,47 @@ ARMBaseRegisterInfo::getCalleeSavedRegs(const 
MachineFunction *MF) const {
? CSR_ATPCS_SplitPush_SwiftTail_SaveList
: CSR_AAPCS_SwiftTail_SaveList);
   } else if (F.hasFnAttribute("interrupt")) {
+
+// Don't bother saving the floating point registers if target is not hard
+// float. This will prevent the Thumb1FrameLowering (cortex-m0) from
+// crashing due to an llvm_unreachable being triggered when a D-class
+// register is in the calling convention.
+if (STI.isTargetHardFloat() && F.hasFnAttribute("save-fp")) {

pestctrl wrote:

How about we check for if if the subtarget has FP registers? 

```
if (STI.hasFPRegs() && F.hasFnAttribute("save-fp"))
```

https://github.com/llvm/llvm-project/pull/89654
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2024-12-29 Thread Benson Chu via cfe-commits

https://github.com/pestctrl updated 
https://github.com/llvm/llvm-project/pull/89654

>From a935c458c71fc8186f52d6eeea220ee142cf1d6d Mon Sep 17 00:00:00 2001
From: Jake Vossen 
Date: Wed, 30 Jun 2021 15:13:13 -0500
Subject: [PATCH 1/4] [ARM] Save floating point registers with save_fp function
 attribute

[ARM] and interrupt_save_fp attribute

interupt_save_fp update name; fix bugs

[ARM] fix typos and register class name

used better push / pop instructions

change epilog emitting order

WIP with FPSCR

save just d regs

cleaned up docs and ARMRegisterInfo td

change m3 to m4

fix reg tests

Minor format changes on top of Jake Vossen's support for
interrupt_save_fp function attribute which preserves VFP D
registers at the moment. FPSCR and FPEXC registers to follow.
---
 clang/include/clang/Basic/Attr.td |  16 ++
 clang/include/clang/Basic/AttrDocs.td |  14 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   8 +-
 clang/include/clang/Sema/SemaARM.h|   1 +
 clang/lib/CodeGen/Targets/ARM.cpp |   6 +
 clang/lib/Sema/SemaARM.cpp|  31 +++-
 clang/lib/Sema/SemaDeclAttr.cpp   |   3 +
 .../test/CodeGen/arm-interrupt-save-fp-attr.c |  39 
 clang/test/Sema/arm-interrupt-attr.c  |   2 +-
 clang/test/Sema/arm-interrupt-save-fp-attr.c  |  26 +++
 llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp   |  34 +++-
 llvm/lib/Target/ARM/ARMCallingConv.td |  28 +++
 .../CodeGen/ARM/interrupt-save-fp-attr.ll | 171 ++
 13 files changed, 369 insertions(+), 10 deletions(-)
 create mode 100644 clang/test/CodeGen/arm-interrupt-save-fp-attr.c
 create mode 100644 clang/test/Sema/arm-interrupt-save-fp-attr.c
 create mode 100644 llvm/test/CodeGen/ARM/interrupt-save-fp-attr.ll

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 52ad72eb608c319..ae773086a1674f3 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -984,6 +984,22 @@ def ARMInterrupt : InheritableAttr, 
TargetSpecificAttr {
   let Documentation = [ARMInterruptDocs];
 }
 
+def ARMInterruptSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [GNU<"interrupt_save_fp">];
+  let Args = [EnumArgument<"Interrupt", "InterruptType", /*is_string=*/true,
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
+   1>];
+  let HasCustomParsing = 0;
+  let Documentation = [ARMInterruptSaveFPDocs];
+}
+
+def ARMSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [InternalOnly];
+}
+
 def AVRInterrupt : InheritableAttr, TargetSpecificAttr {
   let Spellings = [GCC<"interrupt">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index fdad4c9a3ea1910..fe265402895bc36 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2484,6 +2484,20 @@ The semantics are as follows:
   }];
 }
 
+def ARMInterruptSaveFPDocs : Documentation {
+let Category = DocCatFunction;
+  let Heading = "interrupt_save_fp (ARM)";
+  let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt_save_fp("TYPE")))``
+on ARM targets. This attribute behaves the same way as the ARM interrupt
+attribute, except the general purpose floating point registers are also saved. 
+If the FPEXC or FPSCR are needed, that state must be saved manually. Note, 
even 
+on M-class CPUs, where the floating point context can be automatically saved 
+depending on the FPCCR, the general purpose floating point registers will be 
+saved.
+  }];
+}
+
 def BPFPreserveAccessIndexDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 330ae045616abaf..58a932ca6f13314 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -346,8 +346,14 @@ def warn_anyx86_excessive_regsave : Warning<
   InGroup>;
 def warn_arm_interrupt_vfp_clobber : Warning<
   "interrupt service routine with vfp enabled may clobber the "
-  "interruptee's vfp state">,
+  "interruptee's vfp state; "
+  "consider using the `interrupt_save_fp` attribute to prevent this behavior">,
   InGroup>;
+def warn_arm_interrupt_save_fp_without_vfp_unit : Warning<
+   "`interrupt_save_fp` only applies to targets that have a VFP unit enabled "
+   "for this compilation; this will be treated as a regular `interrupt` "
+   "attribute">,
+   InGroup>;
 def err_arm_interrupt_called : Error<
   "interrupt service routine cannot be called directly">;
 def warn_interrupt_attribute_invalid : Warning<
diff --git a/clang/include/clang/Sema/SemaARM.h 
b/clang/include/cl

[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2025-03-10 Thread Benson Chu via cfe-commits

https://github.com/pestctrl updated 
https://github.com/llvm/llvm-project/pull/89654

>From 6186aad4de8a25bfeb389163068950d1e2e7fa1f Mon Sep 17 00:00:00 2001
From: Jake Vossen 
Date: Wed, 30 Jun 2021 15:13:13 -0500
Subject: [PATCH 1/3] [ARM] Save floating point registers with save_fp function
 attribute

[ARM] and interrupt_save_fp attribute

interupt_save_fp update name; fix bugs

[ARM] fix typos and register class name

used better push / pop instructions

change epilog emitting order

WIP with FPSCR

save just d regs

cleaned up docs and ARMRegisterInfo td

change m3 to m4

fix reg tests

Minor format changes on top of Jake Vossen's support for
interrupt_save_fp function attribute which preserves VFP D
registers at the moment. FPSCR and FPEXC registers to follow.
---
 clang/include/clang/Basic/Attr.td |  16 ++
 clang/include/clang/Basic/AttrDocs.td |  14 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   8 +-
 clang/lib/CodeGen/Targets/ARM.cpp |   6 +
 clang/lib/Sema/SemaARM.cpp|   8 +-
 clang/lib/Sema/SemaDeclAttr.cpp   |  17 ++
 .../test/CodeGen/arm-interrupt-save-fp-attr.c |  39 
 clang/test/Sema/arm-interrupt-attr.c  |   2 +-
 clang/test/Sema/arm-interrupt-save-fp-attr.c  |  59 ++
 llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp   |  34 +++-
 llvm/lib/Target/ARM/ARMCallingConv.td |  28 +++
 .../CodeGen/ARM/interrupt-save-fp-attr.ll | 171 ++
 12 files changed, 392 insertions(+), 10 deletions(-)
 create mode 100644 clang/test/CodeGen/arm-interrupt-save-fp-attr.c
 create mode 100644 clang/test/Sema/arm-interrupt-save-fp-attr.c
 create mode 100644 llvm/test/CodeGen/ARM/interrupt-save-fp-attr.ll

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 4b4337cf460f3..0b42ed8f03117 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -994,6 +994,22 @@ def ARMInterrupt : InheritableAttr, 
TargetSpecificAttr {
   let Documentation = [ARMInterruptDocs];
 }
 
+def ARMInterruptSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [GNU<"interrupt_save_fp">];
+  let Args = [EnumArgument<"Interrupt", "InterruptType", /*is_string=*/true,
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
+   1>];
+  let HasCustomParsing = 0;
+  let Documentation = [ARMInterruptSaveFPDocs];
+}
+
+def ARMSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [InternalOnly];
+}
+
 def AVRInterrupt : InheritableAttr, TargetSpecificAttr {
   let Spellings = [GCC<"interrupt">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 1f2f02a4453fc..942d3be3ce58e 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2662,6 +2662,20 @@ The semantics are as follows:
   }];
 }
 
+def ARMInterruptSaveFPDocs : Documentation {
+let Category = DocCatFunction;
+  let Heading = "interrupt_save_fp (ARM)";
+  let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt_save_fp("TYPE")))``
+on ARM targets. This attribute behaves the same way as the ARM interrupt
+attribute, except the general purpose floating point registers are also saved. 
+If the FPEXC or FPSCR are needed, that state must be saved manually. Note, 
even 
+on M-class CPUs, where the floating point context can be automatically saved 
+depending on the FPCCR, the general purpose floating point registers will be 
+saved.
+  }];
+}
+
 def BPFPreserveAccessIndexDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b73ac2933b1ca..dd5a71e2bddb5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -346,8 +346,14 @@ def warn_anyx86_excessive_regsave : Warning<
   InGroup>;
 def warn_arm_interrupt_vfp_clobber : Warning<
   "interrupt service routine with vfp enabled may clobber the "
-  "interruptee's vfp state">,
+  "interruptee's vfp state; "
+  "consider using the `interrupt_save_fp` attribute to prevent this behavior">,
   InGroup>;
+def warn_arm_interrupt_save_fp_without_vfp_unit : Warning<
+   "`interrupt_save_fp` only applies to targets that have a VFP unit enabled "
+   "for this compilation; this will be treated as a regular `interrupt` "
+   "attribute">,
+   InGroup>;
 def err_arm_interrupt_called : Error<
   "interrupt service routine cannot be called directly">;
 def warn_interrupt_signal_attribute_invalid : Warning<
diff --git a/clang/lib/CodeGen/Targets/ARM.cpp 
b/clang/lib/CodeGen/Targets/ARM.cpp
index a6d9a5549355c..dddf51a827159 100644

[clang] 3b33560 - Revert "[ARM][Thumb] Save FPSCR + FPEXC for save-vfp attribute"

2025-03-11 Thread Benson Chu via cfe-commits

Author: Benson Chu
Date: 2025-03-10T10:11:23-05:00
New Revision: 3b3356043cb42e2365dcfa6a6e52b00ce7fbde61

URL: 
https://github.com/llvm/llvm-project/commit/3b3356043cb42e2365dcfa6a6e52b00ce7fbde61
DIFF: 
https://github.com/llvm/llvm-project/commit/3b3356043cb42e2365dcfa6a6e52b00ce7fbde61.diff

LOG: Revert "[ARM][Thumb] Save FPSCR + FPEXC for save-vfp attribute"

This reverts commit 1f05703176d43a339b41a474f51c0e8b1a83c9bb.

Added: 


Modified: 
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/CodeGen/Targets/ARM.cpp
clang/lib/Sema/SemaARM.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/test/Sema/arm-interrupt-attr.c
llvm/include/llvm/IR/IntrinsicsARM.td
llvm/lib/Target/ARM/ARMAsmPrinter.cpp
llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
llvm/lib/Target/ARM/ARMCallingConv.td
llvm/lib/Target/ARM/ARMFrameLowering.cpp
llvm/lib/Target/ARM/ARMFrameLowering.h
llvm/lib/Target/ARM/ARMInstrVFP.td
llvm/lib/Target/ARM/ARMMachineFunctionInfo.h
llvm/lib/Target/ARM/ARMRegisterInfo.td

Removed: 
clang/test/CodeGen/arm-interrupt-save-fp-attr-status-regs.c
clang/test/CodeGen/arm-interrupt-save-fp-attr.c
clang/test/Sema/arm-interrupt-save-fp-attr.c
llvm/test/CodeGen/ARM/interrupt-save-fp-attr-status-regs.mir
llvm/test/CodeGen/ARM/interrupt-save-fp-attr.ll



diff  --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 0b42ed8f03117..4b4337cf460f3 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -994,22 +994,6 @@ def ARMInterrupt : InheritableAttr, 
TargetSpecificAttr {
   let Documentation = [ARMInterruptDocs];
 }
 
-def ARMInterruptSaveFP : InheritableAttr, TargetSpecificAttr {
-  let Spellings = [GNU<"interrupt_save_fp">];
-  let Args = [EnumArgument<"Interrupt", "InterruptType", /*is_string=*/true,
-   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
-   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
-   1>];
-  let HasCustomParsing = 0;
-  let Documentation = [ARMInterruptSaveFPDocs];
-}
-
-def ARMSaveFP : InheritableAttr, TargetSpecificAttr {
-  let Spellings = [];
-  let Subjects = SubjectList<[Function]>;
-  let Documentation = [InternalOnly];
-}
-
 def AVRInterrupt : InheritableAttr, TargetSpecificAttr {
   let Spellings = [GCC<"interrupt">];
   let Subjects = SubjectList<[Function]>;

diff  --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 18f2cdf296060..1f2f02a4453fc 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2662,19 +2662,6 @@ The semantics are as follows:
   }];
 }
 
-def ARMInterruptSaveFPDocs : Documentation {
-let Category = DocCatFunction;
-  let Heading = "interrupt_save_fp (ARM)";
-  let Content = [{
-Clang supports the GNU style ``__attribute__((interrupt_save_fp("TYPE")))``
-on ARM targets. This attribute behaves the same way as the ARM interrupt
-attribute, except the general purpose floating point registers are also saved,
-along with FPEXC and FPSCR. Note, even on M-class CPUs, where the floating
-point context can be automatically saved depending on the FPCCR, the general
-purpose floating point registers will be saved.
-  }];
-}
-
 def BPFPreserveAccessIndexDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index dd5a71e2bddb5..b73ac2933b1ca 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -346,14 +346,8 @@ def warn_anyx86_excessive_regsave : Warning<
   InGroup>;
 def warn_arm_interrupt_vfp_clobber : Warning<
   "interrupt service routine with vfp enabled may clobber the "
-  "interruptee's vfp state; "
-  "consider using the `interrupt_save_fp` attribute to prevent this behavior">,
+  "interruptee's vfp state">,
   InGroup>;
-def warn_arm_interrupt_save_fp_without_vfp_unit : Warning<
-   "`interrupt_save_fp` only applies to targets that have a VFP unit enabled "
-   "for this compilation; this will be treated as a regular `interrupt` "
-   "attribute">,
-   InGroup>;
 def err_arm_interrupt_called : Error<
   "interrupt service routine cannot be called directly">;
 def warn_interrupt_signal_attribute_invalid : Warning<

diff  --git a/clang/lib/CodeGen/Targets/ARM.cpp 
b/clang/lib/CodeGen/Targets/ARM.cpp
index dddf51a827159..a6d9a5549355c 100644
--- a/clang/lib/CodeGen/Targets/ARM.cpp
+++ b/clang/lib/CodeGen/Targets/ARM.cpp
@@ -190,12 +190,6 @@ class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
 
 Fn->addFnAttr("interrupt", Kind);
 
-// Note: the ARMSaveFPAttr can only exist if we also have an inte

[clang] 1f05703 - [ARM][Thumb] Save FPSCR + FPEXC for save-vfp attribute

2025-03-11 Thread Benson Chu via cfe-commits

Author: Benson Chu
Date: 2025-03-10T10:05:15-05:00
New Revision: 1f05703176d43a339b41a474f51c0e8b1a83c9bb

URL: 
https://github.com/llvm/llvm-project/commit/1f05703176d43a339b41a474f51c0e8b1a83c9bb
DIFF: 
https://github.com/llvm/llvm-project/commit/1f05703176d43a339b41a474f51c0e8b1a83c9bb.diff

LOG: [ARM][Thumb] Save FPSCR + FPEXC for save-vfp attribute

FPSCR and FPEXC will be stored in FPStatusRegs, after GPRCS2 has been
saved.

- GPRCS1
- GPRCS2
- FPStatusRegs (new)
- DPRCS
- GPRCS3
- DPRCS2

FPSCR is present on all targets with a VFP, but the FPEXC register is
not present on Cortex-M devices, so different amounts of bytes are
being pushed onto the stack depending on our target, which would
affect alignment for subsequent saves.

DPRCS1 will sum up all previous bytes that were saved, and will emit
extra instructions to ensure that its alignment is correct. My
assumption is that if DPRCS1 is able to correct its alignment to be
correct, then all subsequent saves will also have correct alignment.

Avoid annotating the saving of FPSCR and FPEXC for functions marked
with the interrupt_save_fp attribute, even though this is done as part
of frame setup.  Since these are status registers, there really is no
viable way of annotating this. Since these aren't GPRs or DPRs, they
can't be used with .save or .vsave directives. Instead, just record
that the intermediate registers r4 and r5 are saved to the stack
again.

Co-authored-by: Jake Vossen 
Co-authored-by: Alan Phipps 

Added: 
clang/test/CodeGen/arm-interrupt-save-fp-attr-status-regs.c
clang/test/CodeGen/arm-interrupt-save-fp-attr.c
clang/test/Sema/arm-interrupt-save-fp-attr.c
llvm/test/CodeGen/ARM/interrupt-save-fp-attr-status-regs.mir
llvm/test/CodeGen/ARM/interrupt-save-fp-attr.ll

Modified: 
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/CodeGen/Targets/ARM.cpp
clang/lib/Sema/SemaARM.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/test/Sema/arm-interrupt-attr.c
llvm/include/llvm/IR/IntrinsicsARM.td
llvm/lib/Target/ARM/ARMAsmPrinter.cpp
llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
llvm/lib/Target/ARM/ARMCallingConv.td
llvm/lib/Target/ARM/ARMFrameLowering.cpp
llvm/lib/Target/ARM/ARMFrameLowering.h
llvm/lib/Target/ARM/ARMInstrVFP.td
llvm/lib/Target/ARM/ARMMachineFunctionInfo.h
llvm/lib/Target/ARM/ARMRegisterInfo.td

Removed: 




diff  --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 4b4337cf460f3..0b42ed8f03117 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -994,6 +994,22 @@ def ARMInterrupt : InheritableAttr, 
TargetSpecificAttr {
   let Documentation = [ARMInterruptDocs];
 }
 
+def ARMInterruptSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [GNU<"interrupt_save_fp">];
+  let Args = [EnumArgument<"Interrupt", "InterruptType", /*is_string=*/true,
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
+   1>];
+  let HasCustomParsing = 0;
+  let Documentation = [ARMInterruptSaveFPDocs];
+}
+
+def ARMSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [InternalOnly];
+}
+
 def AVRInterrupt : InheritableAttr, TargetSpecificAttr {
   let Spellings = [GCC<"interrupt">];
   let Subjects = SubjectList<[Function]>;

diff  --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 1f2f02a4453fc..18f2cdf296060 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2662,6 +2662,19 @@ The semantics are as follows:
   }];
 }
 
+def ARMInterruptSaveFPDocs : Documentation {
+let Category = DocCatFunction;
+  let Heading = "interrupt_save_fp (ARM)";
+  let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt_save_fp("TYPE")))``
+on ARM targets. This attribute behaves the same way as the ARM interrupt
+attribute, except the general purpose floating point registers are also saved,
+along with FPEXC and FPSCR. Note, even on M-class CPUs, where the floating
+point context can be automatically saved depending on the FPCCR, the general
+purpose floating point registers will be saved.
+  }];
+}
+
 def BPFPreserveAccessIndexDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b73ac2933b1ca..dd5a71e2bddb5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -346,8 +346,14 @@ def warn_anyx86_excessive_regsave : Warning<
   InGroup>;
 def 

[clang] [llvm] [ARM] Save floating point registers and status registers with save_fp function attribute (PR #89654)

2025-04-09 Thread Benson Chu via cfe-commits

https://github.com/pestctrl updated 
https://github.com/llvm/llvm-project/pull/89654

>From 01c6d6dd84c6cae12f66378017876bee8f71f439 Mon Sep 17 00:00:00 2001
From: Benson Chu 
Date: Mon, 10 Mar 2025 10:51:25 -0500
Subject: [PATCH] [ARM][Thumb] Save FPSCR + FPEXC for save-vfp attribute

FPSCR and FPEXC will be stored in FPStatusRegs, after GPRCS2 has been
saved.

- GPRCS1
- GPRCS2
- FPStatusRegs (new)
- DPRCS
- GPRCS3
- DPRCS2

FPSCR is present on all targets with a VFP, but the FPEXC register is
not present on Cortex-M devices, so different amounts of bytes are
being pushed onto the stack depending on our target, which would
affect alignment for subsequent saves.

DPRCS1 will sum up all previous bytes that were saved, and will emit
extra instructions to ensure that its alignment is correct. My
assumption is that if DPRCS1 is able to correct its alignment to be
correct, then all subsequent saves will also have correct alignment.

Avoid annotating the saving of FPSCR and FPEXC for functions marked
with the interrupt_save_fp attribute, even though this is done as part
of frame setup.  Since these are status registers, there really is no
viable way of annotating this. Since these aren't GPRs or DPRs, they
can't be used with .save or .vsave directives. Instead, just record
that the intermediate registers r4 and r5 are saved to the stack
again.

Co-authored-by: Jake Vossen 
Co-authored-by: Alan Phipps 
---
 clang/include/clang/Basic/Attr.td |  16 +
 clang/include/clang/Basic/AttrDocs.td |  13 +
 .../clang/Basic/DiagnosticSemaKinds.td|   8 +-
 clang/include/clang/Sema/SemaARM.h|   1 +
 clang/lib/CodeGen/Targets/ARM.cpp |   6 +
 clang/lib/Sema/SemaARM.cpp|  30 +-
 clang/lib/Sema/SemaDeclAttr.cpp   |   3 +
 .../arm-interrupt-save-fp-attr-status-regs.c  |  34 ++
 .../test/CodeGen/arm-interrupt-save-fp-attr.c |  39 +++
 clang/test/Sema/arm-interrupt-attr.c  |   2 +-
 clang/test/Sema/arm-interrupt-save-fp-attr.c  |  26 ++
 llvm/include/llvm/IR/IntrinsicsARM.td |   2 +-
 llvm/lib/Target/ARM/ARMAsmPrinter.cpp |  16 +
 llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp   |  19 ++
 llvm/lib/Target/ARM/ARMCallingConv.td |  42 ++-
 llvm/lib/Target/ARM/ARMFrameLowering.cpp  | 164 +-
 llvm/lib/Target/ARM/ARMFrameLowering.h|   9 +
 llvm/lib/Target/ARM/ARMInstrVFP.td|   3 +
 llvm/lib/Target/ARM/ARMMachineFunctionInfo.h  |   3 +
 llvm/lib/Target/ARM/ARMRegisterInfo.td|   7 +
 .../interrupt-save-fp-attr-status-regs.mir| 279 
 .../CodeGen/ARM/interrupt-save-fp-attr.ll | 303 ++
 22 files changed, 999 insertions(+), 26 deletions(-)
 create mode 100644 clang/test/CodeGen/arm-interrupt-save-fp-attr-status-regs.c
 create mode 100644 clang/test/CodeGen/arm-interrupt-save-fp-attr.c
 create mode 100644 clang/test/Sema/arm-interrupt-save-fp-attr.c
 create mode 100644 llvm/test/CodeGen/ARM/interrupt-save-fp-attr-status-regs.mir
 create mode 100644 llvm/test/CodeGen/ARM/interrupt-save-fp-attr.ll

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index b7ad432738b29..4bd7a4e5f6bed 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -999,6 +999,22 @@ def ARMInterrupt : InheritableAttr, 
TargetSpecificAttr {
   let Documentation = [ARMInterruptDocs];
 }
 
+def ARMInterruptSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [GNU<"interrupt_save_fp">];
+  let Args = [EnumArgument<"Interrupt", "InterruptType", /*is_string=*/true,
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
+   ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
+   1>];
+  let HasCustomParsing = 0;
+  let Documentation = [ARMInterruptSaveFPDocs];
+}
+
+def ARMSaveFP : InheritableAttr, TargetSpecificAttr {
+  let Spellings = [];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [InternalOnly];
+}
+
 def AVRInterrupt : InheritableAttr, TargetSpecificAttr {
   let Spellings = [GCC<"interrupt">];
   let Subjects = SubjectList<[Function]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index c8b371280e35d..faefe70a2e63a 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2662,6 +2662,19 @@ The semantics are as follows:
   }];
 }
 
+def ARMInterruptSaveFPDocs : Documentation {
+let Category = DocCatFunction;
+  let Heading = "interrupt_save_fp (ARM)";
+  let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt_save_fp("TYPE")))``
+on ARM targets. This attribute behaves the same way as the ARM interrupt
+attribute, except the general purpose floating point registers are also saved,
+along with FPEXC and FPSCR. Note, even on M-class CPUs, where the floating
+point context can be automatically saved depending on the