[clang] 3b33560 - Revert "[ARM][Thumb] Save FPSCR + FPEXC for save-vfp attribute"
Benson Chu via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 10 08:11:47 PDT 2025
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<TargetARM> {
let Documentation = [ARMInterruptDocs];
}
-def ARMInterruptSaveFP : InheritableAttr, TargetSpecificAttr<TargetARM> {
- 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<TargetARM> {
- let Spellings = [];
- let Subjects = SubjectList<[Function]>;
- let Documentation = [InternalOnly];
-}
-
def AVRInterrupt : InheritableAttr, TargetSpecificAttr<TargetAVR> {
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<DiagGroup<"excessive-regsave">>;
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<DiagGroup<"arm-interrupt-vfp-clobber">>;
-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<DiagGroup<"arm-interrupt-vfp-clobber">>;
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 interrupt
- // attribute
- const ARMSaveFPAttr *SaveFPAttr = FD->getAttr<ARMSaveFPAttr>();
- if (SaveFPAttr)
- Fn->addFnAttr("save-fp");
-
ARMABIKind ABI = getABIInfo<ARMABIInfo>().getABIKind();
if (ABI == ARMABIKind::APCS)
return;
diff --git a/clang/lib/Sema/SemaARM.cpp b/clang/lib/Sema/SemaARM.cpp
index 62802254b3ef2..3f53fb200a93d 100644
--- a/clang/lib/Sema/SemaARM.cpp
+++ b/clang/lib/Sema/SemaARM.cpp
@@ -1307,11 +1307,9 @@ void SemaARM::handleInterruptAttr(Decl *D, const ParsedAttr &AL) {
return;
}
- if (!D->hasAttr<ARMSaveFPAttr>()) {
- const TargetInfo &TI = getASTContext().getTargetInfo();
- if (TI.hasFeature("vfp"))
- Diag(D->getLocation(), diag::warn_arm_interrupt_vfp_clobber);
- }
+ const TargetInfo &TI = getASTContext().getTargetInfo();
+ if (TI.hasFeature("vfp"))
+ Diag(D->getLocation(), diag::warn_arm_interrupt_vfp_clobber);
D->addAttr(::new (getASTContext())
ARMInterruptAttr(getASTContext(), AL, Kind));
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 7bb471d9c3b21..de2696ea62e3b 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -5993,20 +5993,6 @@ static void handleAbiTagAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
AbiTagAttr(S.Context, AL, Tags.data(), Tags.size()));
}
-static void handleARMInterruptSaveFPAttr(Sema &S, Decl *D,
- const ParsedAttr &AL) {
- handleARMInterruptAttr(S, D, AL);
-
- bool VFP = S.Context.getTargetInfo().hasFeature("vfp");
-
- if (!VFP) {
- S.Diag(D->getLocation(), diag::warn_arm_interrupt_save_fp_without_vfp_unit);
- return;
- }
-
- D->addAttr(::new (S.Context) ARMSaveFPAttr(S.Context, AL));
-}
-
static bool hasBTFDeclTagAttr(Decl *D, StringRef Tag) {
for (const auto *I : D->specific_attrs<BTFDeclTagAttr>()) {
if (I->getBTFDeclTag() == Tag)
@@ -6911,9 +6897,6 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
case ParsedAttr::AT_Interrupt:
handleInterruptAttr(S, D, AL);
break;
- case ParsedAttr::AT_ARMInterruptSaveFP:
- handleARMInterruptSaveFPAttr(S, D, AL);
- break;
case ParsedAttr::AT_X86ForceAlignArgPointer:
S.X86().handleForceAlignArgPointerAttr(D, AL);
break;
diff --git a/clang/test/CodeGen/arm-interrupt-save-fp-attr-status-regs.c b/clang/test/CodeGen/arm-interrupt-save-fp-attr-status-regs.c
deleted file mode 100644
index 4e7cafabdc6c2..0000000000000
--- a/clang/test/CodeGen/arm-interrupt-save-fp-attr-status-regs.c
+++ /dev/null
@@ -1,34 +0,0 @@
-// 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 {r4, r5}
- // CHECK-R-NEXT: push {r4, r5}
- // .....
- // CHECK-R: pop {r4, r5}
- // CHECK-R-NEXT: vmsr fpscr, r4
- // CHECK-R-NEXT: vmsr fpexc, r5
-
- // CHECK-M: vmrs r4, fpscr
- // CHECK-M-NEXT: .save {r4}
- // CHECK-M-NEXT: push {r4}
- // .....
- // CHECK-M: pop {r4}
- // CHECK-M-NEXT: vmsr fpscr, r4
- bar();
-}
diff --git a/clang/test/CodeGen/arm-interrupt-save-fp-attr.c b/clang/test/CodeGen/arm-interrupt-save-fp-attr.c
deleted file mode 100644
index 5db8b3daa7212..0000000000000
--- a/clang/test/CodeGen/arm-interrupt-save-fp-attr.c
+++ /dev/null
@@ -1,39 +0,0 @@
-// RUN: %clang_cc1 -triple thumb-apple-darwin -target-abi aapcs -target-feature +vfp4 -target-cpu cortex-m3 -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple arm-apple-darwin -target-abi apcs-gnu -target-feature +vfp4 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-APCS
-
-__attribute__((interrupt_save_fp)) void test_generic_interrupt() {
- // CHECK: define{{.*}} arm_aapcscc void @test_generic_interrupt() [[GENERIC_ATTR:#[0-9]+]]
-
- // CHECK-APCS: define{{.*}} void @test_generic_interrupt() [[GENERIC_ATTR:#[0-9]+]]
-}
-
-__attribute__((interrupt_save_fp("IRQ"))) void test_irq_interrupt() {
- // CHECK: define{{.*}} arm_aapcscc void @test_irq_interrupt() [[IRQ_ATTR:#[0-9]+]]
-}
-
-__attribute__((interrupt_save_fp("FIQ"))) void test_fiq_interrupt() {
- // CHECK: define{{.*}} arm_aapcscc void @test_fiq_interrupt() [[FIQ_ATTR:#[0-9]+]]
-}
-
-__attribute__((interrupt_save_fp("SWI"))) void test_swi_interrupt() {
- // CHECK: define{{.*}} arm_aapcscc void @test_swi_interrupt() [[SWI_ATTR:#[0-9]+]]
-}
-
-__attribute__((interrupt_save_fp("ABORT"))) void test_abort_interrupt() {
- // CHECK: define{{.*}} arm_aapcscc void @test_abort_interrupt() [[ABORT_ATTR:#[0-9]+]]
-}
-
-
-__attribute__((interrupt_save_fp("UNDEF"))) void test_undef_interrupt() {
- // CHECK: define{{.*}} arm_aapcscc void @test_undef_interrupt() [[UNDEF_ATTR:#[0-9]+]]
-}
-
-
-// CHECK: attributes [[GENERIC_ATTR]] = { {{.*}} {{"interrupt"[^=]}}{{.*}} "save-fp"
-// CHECK: attributes [[IRQ_ATTR]] = { {{.*}} "interrupt"="IRQ" {{.*}} "save-fp"
-// CHECK: attributes [[FIQ_ATTR]] = { {{.*}} "interrupt"="FIQ" {{.*}} "save-fp"
-// CHECK: attributes [[SWI_ATTR]] = { {{.*}} "interrupt"="SWI" {{.*}} "save-fp"
-// CHECK: attributes [[ABORT_ATTR]] = { {{.*}} "interrupt"="ABORT" {{.*}} "save-fp"
-// CHECK: attributes [[UNDEF_ATTR]] = { {{.*}} "interrupt"="UNDEF" {{.*}} "save-fp"
-
-// CHECK-APCS: attributes [[GENERIC_ATTR]] = { {{.*}} "interrupt" {{.*}} "save-fp"
\ No newline at end of file
diff --git a/clang/test/Sema/arm-interrupt-attr.c b/clang/test/Sema/arm-interrupt-attr.c
index b0bf031a573fa..f2698eedacea1 100644
--- a/clang/test/Sema/arm-interrupt-attr.c
+++ b/clang/test/Sema/arm-interrupt-attr.c
@@ -3,7 +3,7 @@
#ifdef __ARM_FP
-__attribute__((interrupt("IRQ"))) void float_irq(void); // expected-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}}
+__attribute__((interrupt("IRQ"))) void float_irq(void); // expected-warning {{interrupt service routine with vfp enabled may clobber the interruptee's vfp state}}
#else // !defined(__ARM_FP)
__attribute__((interrupt("irq"))) void foo1(void) {} // expected-warning {{'interrupt' attribute argument not supported: irq}}
__attribute__((interrupt(IRQ))) void foo(void) {} // expected-error {{'interrupt' attribute requires a string}}
diff --git a/clang/test/Sema/arm-interrupt-save-fp-attr.c b/clang/test/Sema/arm-interrupt-save-fp-attr.c
deleted file mode 100644
index e0fd4e2c4d128..0000000000000
--- a/clang/test/Sema/arm-interrupt-save-fp-attr.c
+++ /dev/null
@@ -1,59 +0,0 @@
-// RUN: %clang_cc1 %s -triple arm-apple-darwin -target-feature +vfp2 -verify -fsyntax-only
-// RUN: %clang_cc1 %s -triple thumb-apple-darwin -target-feature +vfp3 -verify -fsyntax-only
-// RUN: %clang_cc1 %s -triple armeb-none-eabi -target-feature +vfp4 -verify -fsyntax-only
-// RUN: %clang_cc1 %s -triple thumbeb-none-eabi -target-feature +neon -verify -fsyntax-only
-// RUN: %clang_cc1 %s -triple thumbeb-none-eabi -target-feature +neon -target-feature +soft-float -DSOFT -verify -fsyntax-only
-
-#ifndef SOFT
-__attribute__((interrupt_save_fp(IRQ))) void foo() {} // expected-error {{'interrupt_save_fp' attribute requires a string}}
-__attribute__((interrupt_save_fp("irq"))) void foo1() {} // expected-warning {{'interrupt_save_fp' attribute argument not supported: irq}}
-
-__attribute__((interrupt_save_fp("IRQ", 1))) void foo2() {} // expected-error {{'interrupt_save_fp' attribute takes no more than 1 argument}}
-__attribute__((interrupt_save_fp("IRQ"))) void foo3() {}
-__attribute__((interrupt_save_fp("FIQ"))) void foo4() {}
-__attribute__((interrupt_save_fp("SWI"))) void foo5() {}
-__attribute__((interrupt_save_fp("ABORT"))) void foo6() {}
-__attribute__((interrupt_save_fp("UNDEF"))) void foo7() {}
-__attribute__((interrupt_save_fp)) void foo8() {}
-__attribute__((interrupt_save_fp())) void foo9() {}
-__attribute__((interrupt_save_fp(""))) void foo10() {}
-void callee1();
-__attribute__((interrupt_save_fp("IRQ"))) void callee2();
-void caller1() {
- callee1();
- callee2();
-}
-__attribute__((interrupt_save_fp("IRQ"))) void caller2() {
- callee1();
- callee2();
-}
-
-void (*callee3)();
-__attribute__((interrupt_save_fp("IRQ"))) void caller3() {
- callee3();
-}
-#else
-__attribute__((interrupt_save_fp("IRQ"))) void foo3() {} // expected-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}}
-__attribute__((interrupt_save_fp("FIQ"))) void foo4() {} // expected-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}}
-__attribute__((interrupt_save_fp("SWI"))) void foo5() {} // expected-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}}
-__attribute__((interrupt_save_fp("ABORT"))) void foo6() {} // expected-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}}
-__attribute__((interrupt_save_fp("UNDEF"))) void foo7() {} // expected-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}}
-__attribute__((interrupt_save_fp)) void foo8() {} // expected-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}}
-__attribute__((interrupt_save_fp())) void foo9() {} // expected-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}}
-__attribute__((interrupt_save_fp(""))) void foo10() {} // expected-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}}
-void callee1();
-__attribute__((interrupt_save_fp("IRQ"))) void callee2(); // expected-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}}
-void caller1() {
- callee1();
- callee2();
-}
-__attribute__((interrupt_save_fp("IRQ"))) void caller2() { // expected-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}}
- callee1();
- callee2();
-}
-
-void (*callee3)();
-__attribute__((interrupt_save_fp("IRQ"))) void caller3() { // expected-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}}
- callee3();
-}
-#endif
\ No newline at end of file
diff --git a/llvm/include/llvm/IR/IntrinsicsARM.td b/llvm/include/llvm/IR/IntrinsicsARM.td
index 9b7dd8099368d..b18d3fcc9e3f4 100644
--- a/llvm/include/llvm/IR/IntrinsicsARM.td
+++ b/llvm/include/llvm/IR/IntrinsicsARM.td
@@ -311,7 +311,7 @@ def int_arm_isb : ClangBuiltin<"__builtin_arm_isb">, MSBuiltin<"__isb">,
// VFP
def int_arm_get_fpscr : ClangBuiltin<"__builtin_arm_get_fpscr">,
- DefaultAttrsIntrinsic<[llvm_i32_ty], [], [IntrReadMem]>;
+ DefaultAttrsIntrinsic<[llvm_i32_ty], [], []>;
def int_arm_set_fpscr : ClangBuiltin<"__builtin_arm_set_fpscr">,
DefaultAttrsIntrinsic<[], [llvm_i32_ty], []>;
def int_arm_vcvtr : DefaultAttrsIntrinsic<[llvm_float_ty],
diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
index 07ef2c11a9947..b8772e1665f8a 100644
--- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -1207,14 +1207,6 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
SrcReg = ~0U;
DstReg = MI->getOperand(0).getReg();
break;
- case ARM::VMRS:
- SrcReg = ARM::FPSCR;
- DstReg = MI->getOperand(0).getReg();
- break;
- case ARM::VMRS_FPEXC:
- SrcReg = ARM::FPEXC;
- DstReg = MI->getOperand(0).getReg();
- break;
default:
SrcReg = MI->getOperand(1).getReg();
DstReg = MI->getOperand(0).getReg();
@@ -1381,14 +1373,6 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
// correct ".save" later.
AFI->EHPrologueRemappedRegs[DstReg] = SrcReg;
break;
- case ARM::VMRS:
- case ARM::VMRS_FPEXC:
- // If a function spills FPSCR or FPEXC, we copy the values to low
- // registers before pushing them. However, we can't issue annotations
- // for FP status registers because ".save" requires GPR registers, and
- // ".vsave" requires DPR registers, so don't record the copy and simply
- // emit annotations for the source registers used for the store.
- break;
case ARM::tLDRpci: {
// Grab the constpool index and check, whether it corresponds to
// original or cloned constpool entry.
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index 3ec6a7ddaf708..9ae0054521b05 100644
--- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -80,47 +80,13 @@ 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")) {
- bool HasNEON = STI.hasNEON();
-
- if (STI.isMClass()) {
- assert(!HasNEON && "NEON is only for Cortex-R/A");
- return UseSplitPush ? CSR_ATPCS_SplitPush_FP_SaveList
- : CSR_AAPCS_FP_SaveList;
- }
- if (F.getFnAttribute("interrupt").getValueAsString() == "FIQ") {
- return HasNEON ? CSR_FIQ_FP_NEON_SaveList : CSR_FIQ_FP_SaveList;
- }
- return HasNEON ? CSR_GenericInt_FP_NEON_SaveList
- : CSR_GenericInt_FP_SaveList;
- }
-
if (STI.isMClass()) {
// M-class CPUs have hardware which saves the registers needed to allow a
// function conforming to the AAPCS to function as a handler.
- // Additionally, M Class has hardware support for saving VFP registers,
- // but the option can be disabled
- if (SaveFP) {
- if (HasNEON) {
- return UseSplitPush ? CSR_AAPCS_SplitPush_FP_NEON_SaveList
- : CSR_AAPCS_FP_NEON_SaveList;
- } else {
- return UseSplitPush ? CSR_AAPCS_SplitPush_FP_SaveList
- : CSR_AAPCS_FP_SaveList;
- }
- } else {
- return PushPopSplit == ARMSubtarget::SplitR7
- ? CSR_ATPCS_SplitPush_SaveList
- : CSR_AAPCS_SaveList;
- }
- }
-
- if (F.getFnAttribute("interrupt").getValueAsString() == "FIQ") {
+ return PushPopSplit == ARMSubtarget::SplitR7
+ ? CSR_ATPCS_SplitPush_SaveList
+ : CSR_AAPCS_SaveList;
+ } else if (F.getFnAttribute("interrupt").getValueAsString() == "FIQ") {
// Fast interrupt mode gives the handler a private copy of R8-R14, so less
// need to be saved to restore user-mode state.
return CSR_FIQ_SaveList;
diff --git a/llvm/lib/Target/ARM/ARMCallingConv.td b/llvm/lib/Target/ARM/ARMCallingConv.td
index ca3e827659c24..f1ab1c3103740 100644
--- a/llvm/lib/Target/ARM/ARMCallingConv.td
+++ b/llvm/lib/Target/ARM/ARMCallingConv.td
@@ -268,14 +268,19 @@ def CC_ARM_Win32_CFGuard_Check : CallingConv<[
def CSR_NoRegs : CalleeSavedRegs<(add)>;
def CSR_FPRegs : CalleeSavedRegs<(add (sequence "D%u", 0, 31))>;
-def CSR_FP_Interrupt_Regs : CalleeSavedRegs<(add FPSCR, FPEXC, (sequence "D%u", 15, 0))>;
-def CSR_FP_NEON_Interrupt_Regs : CalleeSavedRegs<(add CSR_FP_Interrupt_Regs,
- (sequence "D%u", 31, 16))>;
-
def CSR_AAPCS : CalleeSavedRegs<(add LR, R11, R10, R9, R8, R7, R6, R5, R4,
(sequence "D%u", 15, 8))>;
-def CSR_AAPCS_FP : CalleeSavedRegs<(add CSR_AAPCS, CSR_FP_Interrupt_Regs)>;
+// The Windows Control Flow Guard Check function preserves the same registers as
+// AAPCS, and also preserves all floating point registers.
+def CSR_Win_AAPCS_CFGuard_Check : CalleeSavedRegs<(add LR, R11, R10, R9, R8, R7,
+ R6, R5, R4, (sequence "D%u", 15, 0))>;
+
+// R8 is used to pass swifterror, remove it from CSR.
+def CSR_AAPCS_SwiftError : CalleeSavedRegs<(sub CSR_AAPCS, R8)>;
+
+// R10 is used to pass swiftself, remove it from CSR.
+def CSR_AAPCS_SwiftTail : CalleeSavedRegs<(sub CSR_AAPCS, R10)>;
// The order of callee-saved registers needs to match the order we actually push
// them in FrameLowering, because this order is what's used by
@@ -289,21 +294,6 @@ def CSR_Win_SplitFP : CalleeSavedRegs<(add R10, R9, R8, R7, R6, R5, R4,
(sequence "D%u", 15, 8),
LR, R11)>;
-def CSR_ATPCS_SplitPush_FP : CalleeSavedRegs<(add CSR_ATPCS_SplitPush,
- CSR_FP_Interrupt_Regs)>;
-
-// The Windows Control Flow Guard Check function preserves the same registers as
-// AAPCS, and also preserves all floating point registers.
-def CSR_Win_AAPCS_CFGuard_Check : CalleeSavedRegs<(add LR, R11, R10, R9, R8, R7,
- R6, R5, R4, (sequence "D%u", 15, 0))>;
-
-// R8 is used to pass swifterror, remove it from CSR.
-def CSR_AAPCS_SwiftError : CalleeSavedRegs<(sub CSR_AAPCS, R8)>;
-
-// R10 is used to pass swiftself, remove it from CSR.
-def CSR_AAPCS_SwiftTail : CalleeSavedRegs<(sub CSR_AAPCS, R10)>;
-
-
// R8 is used to pass swifterror, remove it from CSR.
def CSR_ATPCS_SplitPush_SwiftError : CalleeSavedRegs<(sub CSR_ATPCS_SplitPush,
R8)>;
@@ -371,13 +361,6 @@ def CSR_iOS_CXX_TLS_ViaCopy : CalleeSavedRegs<(sub CSR_iOS_CXX_TLS,
// generally does rather than tracking its liveness as a normal register.
def CSR_GenericInt : CalleeSavedRegs<(add LR, (sequence "R%u", 12, 0))>;
-def CSR_GenericInt_FP : CalleeSavedRegs<(add CSR_GenericInt,
- CSR_FP_Interrupt_Regs)>;
-
-def CSR_GenericInt_FP_NEON : CalleeSavedRegs<(add CSR_GenericInt_FP,
- CSR_FP_NEON_Interrupt_Regs)>;
-
-
// The fast interrupt handlers have more private state and get their own copies
// of R8-R12, in addition to SP and LR. As before, mark LR for saving too.
@@ -386,9 +369,4 @@ def CSR_GenericInt_FP_NEON : CalleeSavedRegs<(add CSR_GenericInt_FP,
// registers.
def CSR_FIQ : CalleeSavedRegs<(add LR, R11, (sequence "R%u", 7, 0))>;
-def CSR_FIQ_FP : CalleeSavedRegs<(add CSR_FIQ, CSR_FP_Interrupt_Regs)>;
-
-def CSR_FIQ_FP_NEON : CalleeSavedRegs<(add CSR_FIQ_FP,
- CSR_FP_NEON_Interrupt_Regs)>;
-
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
index 5be39734468bf..6e885ab574cea 100644
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
@@ -917,8 +917,8 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
// Determine the sizes of each callee-save spill areas and record which frame
// belongs to which callee-save spill areas.
- unsigned GPRCS1Size = 0, GPRCS2Size = 0, FPStatusSize = 0, DPRCS1Size = 0,
- GPRCS3Size = 0, DPRCS2Size = 0;
+ unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCS1Size = 0, GPRCS3Size = 0,
+ DPRCS2Size = 0;
int FramePtrSpillFI = 0;
int D8SpillFI = 0;
@@ -981,9 +981,6 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
case SpillArea::GPRCS3:
GPRCS3Size += 4;
break;
- case SpillArea::GPRCS3:
- GPRCS3Size += 4;
- break;
case SpillArea::DPRCS2:
DPRCS2Size += 4;
break;
@@ -1026,14 +1023,13 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
unsigned FPCXTOffset = NumBytes - ArgRegsSaveSize - FPCXTSaveSize;
unsigned GPRCS1Offset = FPCXTOffset - GPRCS1Size;
unsigned GPRCS2Offset = GPRCS1Offset - GPRCS2Size;
- unsigned FPStatusOffset = GPRCS2Offset - FPStatusSize;
Align DPRAlign = DPRCS1Size ? std::min(Align(8), Alignment) : Align(4);
- unsigned DPRGapSize = (ArgRegsSaveSize + FPCXTSaveSize + GPRCS1Size +
- GPRCS2Size + FPStatusSize) %
- DPRAlign.value();
+ unsigned DPRGapSize =
+ (ArgRegsSaveSize + FPCXTSaveSize + GPRCS1Size + GPRCS2Size) %
+ DPRAlign.value();
- unsigned DPRCS1Offset = FPStatusOffset - DPRGapSize - DPRCS1Size;
+ unsigned DPRCS1Offset = GPRCS2Offset - DPRGapSize - DPRCS1Size;
if (HasFP) {
// Offset from the CFA to the saved frame pointer, will be negative.
@@ -1058,19 +1054,6 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
BeforeFPPush = false;
}
- // Move past FP status save area.
- if (FPStatusSize > 0) {
- while (MBBI != MBB.end()) {
- unsigned Opc = MBBI->getOpcode();
- if (Opc == ARM::VMRS || Opc == ARM::VMRS_FPEXC)
- MBBI++;
- else
- break;
- }
- LastPush = MBBI++;
- DefCFAOffsetCandidates.addInst(LastPush, FPStatusSize);
- }
-
// Prolog/epilog inserter assumes we correctly align DPRs on the stack, so our
// .cfi_offset operations will reflect that.
if (DPRGapSize) {
@@ -1241,7 +1224,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
FPPushInst = GPRCS3Push;
FPOffsetAfterPush = MFI.getObjectOffset(FramePtrSpillFI) +
ArgRegsSaveSize + FPCXTSaveSize + GPRCS1Size +
- GPRCS2Size + FPStatusSize + DPRCS1Size + DPRGapSize +
+ GPRCS2Size + DPRCS1Size + DPRGapSize +
sizeOfSPAdjustment(*FPPushInst);
LLVM_DEBUG(dbgs() << "Frame pointer in GPRCS3, offset "
<< FPOffsetAfterPush << " after that push\n");
@@ -1349,7 +1332,6 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
AFI->setFPCXTSaveAreaSize(FPCXTSaveSize);
AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
- AFI->setFPStatusSavesSize(FPStatusSize);
AFI->setDPRCalleeSavedGapSize(DPRGapSize);
AFI->setDPRCalleeSavedArea1Size(DPRCS1Size);
AFI->setGPRCalleeSavedArea3Size(GPRCS3Size);
@@ -1476,8 +1458,8 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
NumBytes -=
(ReservedArgStack + AFI->getFPCXTSaveAreaSize() +
AFI->getGPRCalleeSavedArea1Size() + AFI->getGPRCalleeSavedArea2Size() +
- AFI->getFPStatusSavesSize() + AFI->getDPRCalleeSavedGapSize() +
- AFI->getDPRCalleeSavedArea1Size() + AFI->getGPRCalleeSavedArea3Size());
+ AFI->getDPRCalleeSavedGapSize() + AFI->getDPRCalleeSavedArea1Size() +
+ AFI->getGPRCalleeSavedArea3Size());
// Reset SP based on frame pointer only if the stack frame extends beyond
// frame pointer stack slot or target is ELF and the function has FP.
@@ -1853,108 +1835,6 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
}
}
-void ARMFrameLowering::emitFPStatusSaves(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MI,
- ArrayRef<CalleeSavedInfo> CSI,
- unsigned PushOpc) const {
- MachineFunction &MF = *MBB.getParent();
- const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
-
- SmallVector<Register> Regs;
- auto RegPresent = [&CSI](Register Reg) {
- return llvm::any_of(CSI, [Reg](const CalleeSavedInfo &C) {
- return C.getReg() == Reg;
- });
- };
-
- // If we need to save FPSCR, then we must move FPSCR into R4 with the VMRS
- // instruction.
- if (RegPresent(ARM::FPSCR)) {
- BuildMI(MBB, MI, DebugLoc(), TII.get(ARM::VMRS), ARM::R4)
- .add(predOps(ARMCC::AL))
- .setMIFlags(MachineInstr::FrameSetup);
-
- Regs.push_back(ARM::R4);
- }
-
- // If we need to save FPEXC, then we must move FPEXC into R5 with the
- // VMRS_FPEXC instruction.
- if (RegPresent(ARM::FPEXC)) {
- BuildMI(MBB, MI, DebugLoc(), TII.get(ARM::VMRS_FPEXC), ARM::R5)
- .add(predOps(ARMCC::AL))
- .setMIFlags(MachineInstr::FrameSetup);
-
- Regs.push_back(ARM::R5);
- }
-
- // If neither FPSCR and FPEXC are present, then do nothing.
- if (Regs.size() == 0)
- return;
-
- // Push both R4 and R5 onto the stack, if present.
- MachineInstrBuilder MIB =
- BuildMI(MBB, MI, DebugLoc(), TII.get(PushOpc), ARM::SP)
- .addReg(ARM::SP)
- .add(predOps(ARMCC::AL))
- .setMIFlags(MachineInstr::FrameSetup);
-
- for (Register Reg : Regs) {
- MIB.addReg(Reg);
- }
-}
-
-void ARMFrameLowering::emitFPStatusRestores(
- MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
- MutableArrayRef<CalleeSavedInfo> CSI, unsigned LdmOpc) const {
- MachineFunction &MF = *MBB.getParent();
- const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
-
- SmallVector<Register> Regs;
- auto RegPresent = [&CSI](Register Reg) {
- return llvm::any_of(CSI, [Reg](const CalleeSavedInfo &C) {
- return C.getReg() == Reg;
- });
- };
-
- // Do nothing if we don't need to restore any FP status registers.
- if (!RegPresent(ARM::FPSCR) && !RegPresent(ARM::FPEXC))
- return;
-
- // Pop registers off of the stack.
- MachineInstrBuilder MIB =
- BuildMI(MBB, MI, DebugLoc(), TII.get(LdmOpc), ARM::SP)
- .addReg(ARM::SP)
- .add(predOps(ARMCC::AL))
- .setMIFlags(MachineInstr::FrameDestroy);
-
- // If FPSCR was saved, it will be popped into R4.
- if (RegPresent(ARM::FPSCR)) {
- MIB.addReg(ARM::R4, RegState::Define);
- }
-
- // If FPEXC was saved, it will be popped into R5.
- if (RegPresent(ARM::FPEXC)) {
- MIB.addReg(ARM::R5, RegState::Define);
- }
-
- // Move the FPSCR value back into the register with the VMSR instruction.
- if (RegPresent(ARM::FPSCR)) {
- BuildMI(MBB, MI, DebugLoc(), STI.getInstrInfo()->get(ARM::VMSR))
- .addReg(ARM::R4)
- .add(predOps(ARMCC::AL))
- .setMIFlags(MachineInstr::FrameDestroy);
- }
-
- // Move the FPEXC value back into the register with the VMSR_FPEXC
- // instruction.
- if (RegPresent(ARM::FPEXC)) {
- BuildMI(MBB, MI, DebugLoc(), STI.getInstrInfo()->get(ARM::VMSR_FPEXC))
- .addReg(ARM::R5)
- .add(predOps(ARMCC::AL))
- .setMIFlags(MachineInstr::FrameDestroy);
- }
-}
-
/// Emit aligned spill instructions for NumAlignedDPRCS2Regs D-registers
/// starting from d8. Also insert stack realignment code and leave the stack
/// pointer pointing to the d8 spill slot.
@@ -2274,7 +2154,6 @@ bool ARMFrameLowering::spillCalleeSavedRegisters(
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, IsGPRCS1);
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, IsGPRCS2);
- emitFPStatusSaves(MBB, MI, CSI, PushOpc);
emitPushInst(MBB, MI, CSI, FltOpc, 0, true, IsDPRCS1);
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, IsGPRCS3);
@@ -2332,7 +2211,6 @@ bool ARMFrameLowering::restoreCalleeSavedRegisters(
emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false, IsGPRCS3);
emitPopInst(MBB, MI, CSI, FltOpc, 0, isVarArg, true, IsDPRCS1);
- emitFPStatusRestores(MBB, MI, CSI, PopOpc);
emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false, IsGPRCS2);
emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false, IsGPRCS1);
@@ -2549,7 +2427,6 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
unsigned NumFPRSpills = 0;
SmallVector<unsigned, 4> UnspilledCS1GPRs;
SmallVector<unsigned, 4> UnspilledCS2GPRs;
- const Function &F = MF.getFunction();
const ARMBaseRegisterInfo *RegInfo = static_cast<const ARMBaseRegisterInfo *>(
MF.getSubtarget().getRegisterInfo());
const ARMBaseInstrInfo &TII =
@@ -2563,21 +2440,6 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
ARMSubtarget::PushPopSplitVariation PushPopSplit =
STI.getPushPopSplitVariation(MF);
- // For a floating point interrupt, save these registers always, since LLVM
- // currently doesn't model reads/writes to these registers.
- if (F.hasFnAttribute("interrupt") && F.hasFnAttribute("save-fp")) {
- SavedRegs.set(ARM::FPSCR);
- SavedRegs.set(ARM::R4);
-
- // This register will only be present on non-MClass registers.
- if (STI.isMClass()) {
- SavedRegs.reset(ARM::FPEXC);
- } else {
- SavedRegs.set(ARM::FPEXC);
- SavedRegs.set(ARM::R5);
- }
- }
-
// Spill R4 if Thumb2 function requires stack realignment - it will be used as
// scratch register. Also spill R4 if Thumb2 function has varsized objects,
// since it's not always possible to restore sp from fp in a single
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.h b/llvm/lib/Target/ARM/ARMFrameLowering.h
index 9dc88d4671c38..ff51f1a7af022 100644
--- a/llvm/lib/Target/ARM/ARMFrameLowering.h
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.h
@@ -99,15 +99,6 @@ class ARMFrameLowering : public TargetFrameLowering {
unsigned LdrOpc, bool isVarArg, bool NoGap,
function_ref<bool(unsigned)> Func) const;
- void emitFPStatusSaves(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
- ArrayRef<CalleeSavedInfo> CSI,
- unsigned PushOneOpc) const;
-
- void emitFPStatusRestores(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MI,
- MutableArrayRef<CalleeSavedInfo> CSI,
- unsigned LdrOpc) const;
-
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
diff --git a/llvm/lib/Target/ARM/ARMInstrVFP.td b/llvm/lib/Target/ARM/ARMInstrVFP.td
index 2ee2cb2fda4a0..754517f3bc4d5 100644
--- a/llvm/lib/Target/ARM/ARMInstrVFP.td
+++ b/llvm/lib/Target/ARM/ARMInstrVFP.td
@@ -2513,9 +2513,6 @@ class MovFromVFP<bits<4> opc19_16, dag oops, dag iops, string opc, string asm,
let Inst{3-0} = 0b0000;
let Unpredictable{7-5} = 0b111;
let Unpredictable{3-0} = 0b1111;
-
- // Needed to avoid errors when a MachineInstrt::FrameSetup flag is set.
- let mayStore = 0;
}
let DecoderMethod = "DecodeForVMRSandVMSR" in {
diff --git a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h
index a9c4b53f9ae64..e330d83cd80d5 100644
--- a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h
+++ b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h
@@ -89,7 +89,6 @@ class ARMFunctionInfo : public MachineFunctionInfo {
unsigned FRSaveSize = 0;
unsigned GPRCS1Size = 0;
unsigned GPRCS2Size = 0;
- unsigned FPStatusSize = 0;
unsigned DPRCSAlignGapSize = 0;
unsigned DPRCS1Size = 0;
unsigned GPRCS3Size = 0;
@@ -206,7 +205,6 @@ class ARMFunctionInfo : public MachineFunctionInfo {
unsigned getFrameRecordSavedAreaSize() const { return FRSaveSize; }
unsigned getGPRCalleeSavedArea1Size() const { return GPRCS1Size; }
unsigned getGPRCalleeSavedArea2Size() const { return GPRCS2Size; }
- unsigned getFPStatusSavesSize() const { return FPStatusSize; }
unsigned getDPRCalleeSavedGapSize() const { return DPRCSAlignGapSize; }
unsigned getDPRCalleeSavedArea1Size() const { return DPRCS1Size; }
unsigned getGPRCalleeSavedArea3Size() const { return GPRCS3Size; }
@@ -215,7 +213,6 @@ class ARMFunctionInfo : public MachineFunctionInfo {
void setFrameRecordSavedAreaSize(unsigned s) { FRSaveSize = s; }
void setGPRCalleeSavedArea1Size(unsigned s) { GPRCS1Size = s; }
void setGPRCalleeSavedArea2Size(unsigned s) { GPRCS2Size = s; }
- void setFPStatusSavesSize(unsigned s) { FPStatusSize = s; }
void setDPRCalleeSavedGapSize(unsigned s) { DPRCSAlignGapSize = s; }
void setDPRCalleeSavedArea1Size(unsigned s) { DPRCS1Size = s; }
void setGPRCalleeSavedArea3Size(unsigned s) { GPRCS3Size = s; }
diff --git a/llvm/lib/Target/ARM/ARMRegisterInfo.td b/llvm/lib/Target/ARM/ARMRegisterInfo.td
index 5a31b88ba7f70..f5a675e2976bb 100644
--- a/llvm/lib/Target/ARM/ARMRegisterInfo.td
+++ b/llvm/lib/Target/ARM/ARMRegisterInfo.td
@@ -417,13 +417,6 @@ def cl_FPSCR_NZCV : RegisterClass<"ARM", [i32], 32, (add FPSCR_NZCV)> {
let CopyCost = -1;
}
-// This RegisterClass is required to add FPSCR and FPEXC into a calling
-// convention.
-def FP_STATUS_REGS : RegisterClass<"ARM", [i32], 32, (add FPSCR, FPEXC)> {
- let CopyCost = -1; // Don't allow copying of status registers.
- let isAllocatable = 0;
-}
-
// Scalar single precision floating point register class..
// FIXME: Allocation order changed to s0, s2, ... or s0, s4, ... as a quick hack
// to avoid partial-write dependencies on D or Q (depending on platform)
diff --git a/llvm/test/CodeGen/ARM/interrupt-save-fp-attr-status-regs.mir b/llvm/test/CodeGen/ARM/interrupt-save-fp-attr-status-regs.mir
deleted file mode 100644
index e94790ab71411..0000000000000
--- a/llvm/test/CodeGen/ARM/interrupt-save-fp-attr-status-regs.mir
+++ /dev/null
@@ -1,280 +0,0 @@
-# RUN: llc -mtriple=armv7-ti-none-eabihf -mcpu=cortex-r5 -o - %s -run-pass=prologepilog \
-# RUN: | FileCheck --check-prefix=CHECK-R-ARM %s
-# RUN: llc -mtriple=armv7-ti-none-eabihf -mcpu=cortex-r4 -o - %s -run-pass=prologepilog \
-# RUN: | FileCheck --check-prefix=CHECK-R-ARM %s
-# RUN: llc -mtriple=thumbv7-ti-none-eabihf -mcpu=cortex-r5 -o - %s -run-pass=prologepilog \
-# RUN: | FileCheck --check-prefix=CHECK-R-THUMB %s
-# RUN: llc -mtriple=thumbv7-ti-none-eabihf -mcpu=cortex-r4 -o - %s -run-pass=prologepilog \
-# RUN: | FileCheck --check-prefix=CHECK-R-THUMB %s
-# RUN: llc -mtriple=thumbv7-ti-none-eabihf -mcpu=cortex-m3 -o - %s -run-pass=prologepilog \
-# RUN: | FileCheck --check-prefix=CHECK-M-THUMB %s
-# RUN: llc -mtriple=thumbv7-ti-none-eabihf -mcpu=cortex-m4 -o - %s -run-pass=prologepilog \
-# RUN: | FileCheck --check-prefix=CHECK-M-THUMB %s
-# RUN: llc -mtriple=thumbv8-ti-none-eabihf -mcpu=cortex-m33 -o - %s -run-pass=prologepilog \
-# RUN: | FileCheck --check-prefix=CHECK-M-THUMB %s
-
-# =============================================================================
-# ============================ cortex-r arm-mode ==============================
-# =============================================================================
-# This IRQ will save 112 bytes:
-#
-# |---------+------+----------|
-# | reg | size | zone |
-# |---------+------+----------|
-# | LR | 4x1 | GPR |
-# | R12-R10 | 4x3 | |
-# | R5-R0 | 4x6 | |
-# |---------+------+----------|
-# | FPEXC | 4x1 | FPStatus |
-# | FPSCR | 4x1 | |
-# |---------+------+----------|
-# | D7-D0 | 8x8 | FPRegs |
-# |---------+------+----------|
-# | | 112 | |
-# |---------+------+----------|
-#
-# ================================= Prologue =================================
-#
-# Frame pointer (r11) will be store at $original_sp - 12, but we can't save the
-# FP until after we save the GPR zone of registers. The GPR zone of registers
-# moves the stack by 40 bytes. So $original_sp = $current_sp + 40. Thus,
-# $current_sp + 40 - 12 = $current_sp + 28. Thus, we see the instruction:
-#
-# $r11 = ADDri $sp, 28
-#
-# We don't have dwarf information for the FPEXC and FPSCR registers, so there's
-# no CFI_INSTRUCTION for those saves. So, we should see an 8 byte disparity in
-# the register offsets. $r0 is -40, and $d7 is -56.
-#
-# (-40) - (-56) = 16.
-# 16 = 8 (bytes from $d7) + 8 (bytes from FPSCR + FPEXC)
-#
-# There's an extra BFC to force the stack to be aligned.
-#
-# $sp = BFC $sp, 4294967288 /* ~0x7 */
-#
-# ================================= Epilogue =================================
-#
-# We use the frame pointer to restore the SP. Since $r11 is currently pointing
-# to the previous $r11's stack position (aka base_of_stack - 12), and we
-# allocated 112 bytes, $sp = $r11 - (112 - 12), or $sp = $r11 - 100, which is
-# why we see this instruction:
-#
-# $sp = SUBri $r11, 92
-
-# CHECK-R-ARM-LABEL: name: irq_fn
-# CHECK-R-ARM-LABEL: bb.0 (%ir-block.0):
-# CHECK-R-ARM: $sp = frame-setup STMDB_UPD $sp, 14 /* CC::al */, $noreg, killed $r0, killed $r1, killed $r2, killed $r3, killed $r4, killed $r5, killed $r10, killed $r11, killed $r12, killed $lr
-# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 40
-# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -4
-# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $r12, -8
-# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $r11, -12
-# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $r10, -16
-# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $r5, -20
-# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $r4, -24
-# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $r3, -28
-# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $r2, -32
-# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $r1, -36
-# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $r0, -40
-# CHECK-R-ARM-NEXT: $r11 = frame-setup ADDri killed $sp, 28, 14 /* CC::al */, $noreg, $noreg
-# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION def_cfa $r11, 12
-# CHECK-R-ARM-NEXT: $r4 = frame-setup VMRS 14 /* CC::al */, $noreg, implicit $fpscr
-# CHECK-R-ARM-NEXT: $r5 = frame-setup VMRS_FPEXC 14 /* CC::al */, $noreg, implicit $fpscr
-# CHECK-R-ARM-NEXT: $sp = frame-setup STMDB_UPD $sp, 14 /* CC::al */, $noreg, $r4, $r5
-# CHECK-R-ARM-NEXT: $sp = frame-setup VSTMDDB_UPD $sp, 14 /* CC::al */, $noreg, killed $d0, killed $d1, killed $d2, killed $d3, killed $d4, killed $d5, killed $d6, killed $d7
-# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $d7, -56
-# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $d6, -64
-# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $d5, -72
-# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $d4, -80
-# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $d3, -88
-# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $d2, -96
-# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $d1, -104
-# CHECK-R-ARM-NEXT: frame-setup CFI_INSTRUCTION offset $d0, -112
-# CHECK-R-ARM-NEXT: $sp = BFC killed $sp, 4294967288, 14 /* CC::al */, $noreg
-# CHECK-R-ARM-NEXT: BL @bar, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
-# CHECK-R-ARM-NEXT: $sp = frame-destroy SUBri killed $r11, 100, 14 /* CC::al */, $noreg, $noreg
-# CHECK-R-ARM-NEXT: $sp = frame-destroy VLDMDIA_UPD $sp, 14 /* CC::al */, $noreg, def $d0, def $d1, def $d2, def $d3, def $d4, def $d5, def $d6, def $d7
-# CHECK-R-ARM-NEXT: $sp = frame-destroy LDMIA_UPD $sp, 14 /* CC::al */, $noreg, def $r4, def $r5
-# CHECK-R-ARM-NEXT: frame-destroy VMSR $r4, 14 /* CC::al */, $noreg, implicit-def $fpscr
-# CHECK-R-ARM-NEXT: frame-destroy VMSR_FPEXC $r5, 14 /* CC::al */, $noreg, implicit-def $fpscr
-
-# =============================================================================
-# =========================== cortex-r thumb-mode =============================
-# =============================================================================
-# This IRQ will save 112 bytes:
-#
-# |-------+------+----------|
-# | reg | size | zone |
-# |-------+------+----------|
-# | LR | 4x1 | GPR |
-# | R12 | 4x1 | |
-# | R7-R0 | 4x8 | |
-# |-------+------+----------|
-# | FPEXC | 4x1 | FPStatus |
-# | FPSCR | 4x1 | |
-# |-------+------+----------|
-# | D7-D0 | 8x8 | FPRegs |
-# |-------+------+----------|
-# | | 112 | |
-# |-------+------+----------|
-#
-# ================================= Prologue =================================
-#
-# Frame pointer (r7) will be store at $original_sp - 12, but we can't save the
-# FP until after we save the GPR zone of registers. The GPR zone of registers
-# moves the stack by 40 bytes. So $original_sp = $current_sp + 40. Thus,
-# $current_sp + 40 - 12 = $current_sp + 28. Thus, we see the instruction:
-#
-# $r7 = t2ADDri $sp, 28
-#
-# We don't have dwarf information for the FPEXC and FPSCR registers, so there's
-# no CFI_INSTRUCTION for those saves. So, we should see an 8 byte disparity in
-# the register offsets. $r0 is -40, and $d7 is -56.
-#
-# (-40) - (-56) = 16.
-# 16 = 8 (bytes from $d7) + 8 (bytes from FPSCR + FPEXC)
-#
-# There's an extra BFC to force the stack to be aligned. This is done in 3
-# steps, because the value of $sp needs to be moved into a low register
-# (r0-r7), and then operated on, and then moved back.
-#
-# $r4 = tMOVr $sp, 14
-# $r4 = t2BFC $r4, 4294967288 /* ~0x7 */, 14
-# $sp = tMOVr $r4, 14
-#
-# ================================= Epilogue =================================
-#
-# We use the frame pointer to restore the SP. Since $r7 is currently pointing
-# to the previous $r7's stack position (aka base_of_stack - 12), and we
-# allocated 112 bytes, $sp = $r7 - (112 - 12), or $sp = $r7 - 100, which is
-# why we see this instruction:
-#
-# $r4 = t2SUBri $r7, 100
-# $sp = tMOVr $r4
-
-# CHECK-R-THUMB-LABEL: name: irq_fn
-# CHECK-R-THUMB-LABEL: bb.0 (%ir-block.0):
-# CHECK-R-THUMB: $sp = frame-setup t2STMDB_UPD $sp, 14 /* CC::al */, $noreg, killed $r0, killed $r1, killed $r2, killed $r3, killed $r4, killed $r5, killed $r6, killed $r7, killed $r12, killed $lr
-# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 40
-# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -4
-# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r12, -8
-# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r7, -12
-# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r6, -16
-# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r5, -20
-# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r4, -24
-# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r3, -28
-# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r2, -32
-# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r1, -36
-# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r0, -40
-# CHECK-R-THUMB-NEXT: $r7 = frame-setup t2ADDri killed $sp, 28, 14 /* CC::al */, $noreg, $noreg
-# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION def_cfa $r7, 12
-# CHECK-R-THUMB-NEXT: $r4 = frame-setup VMRS 14 /* CC::al */, $noreg, implicit $fpscr
-# CHECK-R-THUMB-NEXT: $r5 = frame-setup VMRS_FPEXC 14 /* CC::al */, $noreg, implicit $fpscr
-# CHECK-R-THUMB-NEXT: $sp = frame-setup t2STMDB_UPD $sp, 14 /* CC::al */, $noreg, $r4, $r5
-# CHECK-R-THUMB-NEXT: $sp = frame-setup VSTMDDB_UPD $sp, 14 /* CC::al */, $noreg, killed $d0, killed $d1, killed $d2, killed $d3, killed $d4, killed $d5, killed $d6, killed $d7
-# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d7, -56
-# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d6, -64
-# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d5, -72
-# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d4, -80
-# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d3, -88
-# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d2, -96
-# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d1, -104
-# CHECK-R-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d0, -112
-# CHECK-R-THUMB-NEXT: $r4 = tMOVr killed $sp, 14 /* CC::al */, $noreg
-# CHECK-R-THUMB-NEXT: $r4 = t2BFC killed $r4, 4294967288, 14 /* CC::al */, $noreg
-# CHECK-R-THUMB-NEXT: $sp = tMOVr killed $r4, 14 /* CC::al */, $noreg
-# CHECK-R-THUMB-NEXT: BL @bar, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
-# CHECK-R-THUMB-NEXT: $r4 = frame-destroy t2SUBri killed $r7, 100, 14 /* CC::al */, $noreg, $noreg
-# CHECK-R-THUMB-NEXT: $sp = frame-destroy tMOVr $r4, 14 /* CC::al */, $noreg
-# CHECK-R-THUMB-NEXT: $sp = frame-destroy VLDMDIA_UPD $sp, 14 /* CC::al */, $noreg, def $d0, def $d1, def $d2, def $d3, def $d4, def $d5, def $d6, def $d7
-# CHECK-R-THUMB-NEXT: $sp = frame-destroy t2LDMIA_UPD $sp, 14 /* CC::al */, $noreg, def $r4, def $r5
-# CHECK-R-THUMB-NEXT: frame-destroy VMSR $r4, 14 /* CC::al */, $noreg, implicit-def $fpscr
-# CHECK-R-THUMB-NEXT: frame-destroy VMSR_FPEXC $r5, 14 /* CC::al */, $noreg, implicit-def $fpscr
-# CHECK-R-THUMB-NEXT: $sp = frame-destroy t2LDMIA_UPD $sp, 14 /* CC::al */, $noreg, def $r0, def $r1, def $r2, def $r3, def $r4, def $r5, def $r6, def $r7, def $r12, def $lr
-# CHECK-R-THUMB-NEXT: SUBS_PC_LR 4, 14 /* CC::al */, $noreg
-
-# =============================================================================
-# ============================== cortex-m thumb ===============================
-# =============================================================================
-# This IRQ will save 88 bytes:
-#
-# |---------+------+----------|
-# | reg | size | zone |
-# |---------+------+----------|
-# | LR | 4x1 | GPR |
-# | R7-R6 | 4x2 | |
-# | R4 | 4x1 | |
-# |---------+------+----------|
-# | FPSCR | 4x1 | FPStatus |
-# |---------+------+----------|
-# | EMPTY | 4x1 | Align |
-# |---------+------+----------|
-# | D7-D0 | 8x8 | FPRegs |
-# |---------+------+----------|
-# | | 88 | |
-# |---------+------+----------|
-
-# CHECK-M-THUMB-LABEL: name: irq_fn
-# CHECK-M-THUMB-LABEL: bb.0 (%ir-block.0):
-# CHECK-M-THUMB: $sp = frame-setup t2STMDB_UPD $sp, 14 /* CC::al */, $noreg, killed $r4, killed $r6, killed $r7, killed $lr
-# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 16
-# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -4
-# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r7, -8
-# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r6, -12
-# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $r4, -16
-# CHECK-M-THUMB-NEXT: $r7 = frame-setup t2ADDri killed $sp, 8, 14 /* CC::al */, $noreg, $noreg
-# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION def_cfa $r7, 8
-# CHECK-M-THUMB-NEXT: $r4 = frame-setup VMRS 14 /* CC::al */, $noreg, implicit $fpscr
-# CHECK-M-THUMB-NEXT: $sp = frame-setup t2STMDB_UPD $sp, 14 /* CC::al */, $noreg, $r4
-# CHECK-M-THUMB-NEXT: $sp = frame-setup tSUBspi $sp, 1, 14 /* CC::al */, $noreg
-# CHECK-M-THUMB-NEXT: $sp = frame-setup VSTMDDB_UPD $sp, 14 /* CC::al */, $noreg, killed $d0, killed $d1, killed $d2, killed $d3, killed $d4, killed $d5, killed $d6, killed $d7
-# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d7, -32
-# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d6, -40
-# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d5, -48
-# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d4, -56
-# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d3, -64
-# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d2, -72
-# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d1, -80
-# CHECK-M-THUMB-NEXT: frame-setup CFI_INSTRUCTION offset $d0, -88
-# CHECK-M-THUMB-NEXT: $r4 = tMOVr killed $sp, 14 /* CC::al */, $noreg
-# CHECK-M-THUMB-NEXT: $r4 = t2BFC killed $r4, 4294967288, 14 /* CC::al */, $noreg
-# CHECK-M-THUMB-NEXT: $sp = tMOVr killed $r4, 14 /* CC::al */, $noreg
-# CHECK-M-THUMB-NEXT: BL @bar, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
-# CHECK-M-THUMB-NEXT: $r4 = frame-destroy t2SUBri killed $r7, 80, 14 /* CC::al */, $noreg, $noreg
-# CHECK-M-THUMB-NEXT: $sp = frame-destroy tMOVr $r4, 14 /* CC::al */, $noreg
-# CHECK-M-THUMB-NEXT: $sp = frame-destroy VLDMDIA_UPD $sp, 14 /* CC::al */, $noreg, def $d0, def $d1, def $d2, def $d3, def $d4, def $d5, def $d6, def $d7
-# CHECK-M-THUMB-NEXT: $sp = frame-destroy tADDspi $sp, 1, 14 /* CC::al */, $noreg
-# CHECK-M-THUMB-NEXT: $sp = frame-destroy t2LDMIA_UPD $sp, 14 /* CC::al */, $noreg, def $r4
-# CHECK-M-THUMB-NEXT: frame-destroy VMSR $r4, 14 /* CC::al */, $noreg, implicit-def $fpscr
-# CHECK-M-THUMB-NEXT: $sp = frame-destroy t2LDMIA_UPD $sp, 14 /* CC::al */, $noreg, def $r4, def $r6, def $r7, def $lr
-# CHECK-M-THUMB-NEXT: SUBS_PC_LR 4, 14 /* CC::al */, $noreg
-
---- |
- ; ModuleID = '/scratch/benson/tools2/llvm_cgt/llvm-project/llvm/test/CodeGen/ARM/fp-attr-fpscr.ll'
- source_filename = "/scratch/benson/tools2/llvm_cgt/llvm-project/llvm/test/CodeGen/ARM/fp-attr-fpscr.ll"
- target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
-
- declare arm_aapcscc void @bar()
-
- ; Function Attrs: alignstack(8)
- define arm_aapcscc void @irq_fn() #1 {
- call arm_aapcscc void @bar()
- ret void
- }
-
- attributes #1 = { alignstack=8 "interrupt"="IRQ" "save-fp" }
-
-...
----
-name: irq_fn
-alignment: 16
-frameInfo:
- adjustsStack: true
- hasCalls: true
-body: |
- bb.0 (%ir-block.0):
- ADJCALLSTACKDOWN 0, 0, 14 /* CC::al */, $noreg, implicit-def dead $sp, implicit $sp
- BL @bar, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
- ADJCALLSTACKUP 0, -1, 14 /* CC::al */, $noreg, implicit-def dead $sp, implicit $sp
- SUBS_PC_LR 4, 14 /* CC::al */, $noreg
-...
diff --git a/llvm/test/CodeGen/ARM/interrupt-save-fp-attr.ll b/llvm/test/CodeGen/ARM/interrupt-save-fp-attr.ll
deleted file mode 100644
index e96dfa4a38e12..0000000000000
--- a/llvm/test/CodeGen/ARM/interrupt-save-fp-attr.ll
+++ /dev/null
@@ -1,303 +0,0 @@
-; RUN: llc -mtriple=arm-ti-none-eabihf -mcpu=cortex-a15 -o - %s | FileCheck --check-prefix=CHECK-A %s
-; RUN: llc -mtriple=thumb-ti-none-eabihf -mcpu=cortex-a15 -o - %s | FileCheck --check-prefix=CHECK-A-THUMB %s
-; RUN: llc -mtriple=thumb-ti-none-eabihf -mcpu=cortex-m4 -o - %s | FileCheck --check-prefix=CHECK-M %s
-; RUN: llc -mtriple=thumbv7em-ti-none-eabihf -mcpu=cortex-m4 -o - %s | FileCheck --check-prefix=CHECK-M %s
-; RUN: llc -mtriple=thumbv7r5-ti-none-eabihf -mcpu=cortex-r5 -o - %s | FileCheck --check-prefix=CHECK-R-THUMB %s
-; RUN: llc -mtriple=armv7r5-ti-none-eabihf -mcpu=cortex-r5 -o - %s | FileCheck --check-prefix=CHECK-R %s
-
-declare arm_aapcscc void @bar()
-
- at bigvar = global [16 x i32] zeroinitializer
-
-define arm_aapcscc void @irq_fn() alignstack(8) "interrupt"="IRQ" "save-fp"{
- ; Must save all registers except banked sp and lr (we save lr anyway because
- ; we actually need it at the end to execute the return ourselves).
-
- ; Also need special function return setting pc and CPSR simultaneously.
- ; CHECK-A-LABEL: irq_fn:
- ; CHECK-A: push {r0, r1, r2, r3, r4, r5, r10, r11, r12, lr}
- ; CHECK-A: add r11, sp, #28
- ; CHECK-A: vpush {d0, d1, d2, d3, d4, d5, d6, d7}
- ; CHECK-A: vpush {d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
- ; [...]
- ; CHECK-A: sub sp, r11, #228
- ; CHECK-A: vpop {d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
- ; CHECK-A: vpop {d0, d1, d2, d3, d4, d5, d6, d7}
- ; CHECK-A: pop {r0, r1, r2, r3, r4, r5, r10, r11, r12, lr}
- ; CHECK-A-LABEL: .Lfunc_end0
-
- ; CHECK-A-THUMB-LABEL: irq_fn:
- ; CHECK-A-THUMB: push.w {r0, r1, r2, r3, r4, r5, r6, r7, r12, lr}
- ; CHECK-A-THUMB: add r7, sp, #28
- ; CHECK-A-THUMB: vpush {d0, d1, d2, d3, d4, d5, d6, d7}
- ; CHECK-A-THUMB: vpush {d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
- ; [...]
- ; CHECK-A-THUMB: sub.w r4, r7, #228
- ; CHECK-A-THUMB: mov sp, r4
- ; CHECK-A-THUMB: vpop {d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
- ; CHECK-A-THUMB: vpop {d0, d1, d2, d3, d4, d5, d6, d7}
- ; CHECK-A-THUMB: pop.w {r0, r1, r2, r3, r4, r5, r6, r7, r12, lr}
- ; CHECK-A-THUMB-LABEL: .Lfunc_end0
-
- ; CHECK-R-LABEL: irq_fn:
- ; CHECK-R: push {r0, r1, r2, r3, r4, r5, r10, r11, r12, lr}
- ; CHECK-R: add r11, sp, #28
- ; CHECK-R: vpush {d0, d1, d2, d3, d4, d5, d6, d7}
- ; [...]
- ; CHECK-R: sub sp, r11, #100
- ; CHECK-R: vpop {d0, d1, d2, d3, d4, d5, d6, d7}
- ; CHECK-R: pop {r0, r1, r2, r3, r4, r5, r10, r11, r12, lr}
- ; CHECK-R-LABEL: .Lfunc_end0
-
- ; CHECK-R-THUMB-LABEL: irq_fn:
- ; CHECK-R-THUMB: push.w {r0, r1, r2, r3, r4, r5, r6, r7, r12, lr}
- ; CHECK-R-THUMB: add r7, sp, #28
- ; CHECK-R-THUMB: vpush {d0, d1, d2, d3, d4, d5, d6, d7}
- ; [...]
- ; CHECK-R-THUMB: sub.w r4, r7, #100
- ; CHECK-R-THUMB: mov sp, r4
- ; CHECK-R-THUMB: vpop {d0, d1, d2, d3, d4, d5, d6, d7}
- ; CHECK-R-THUMB: pop.w {r0, r1, r2, r3, r4, r5, r6, r7, r12, lr}
- ; CHECK-R-THUMB-LABEL: .Lfunc_end0
-
- ; Normal AAPCS function (r0-r3 pushed onto stack by hardware, lr set to
- ; appropriate sentinel so no special return needed).
- ; CHECK-M-LABEL: irq_fn:
- ; CHECK-M: push {r4, r6, r7, lr}
- ; CHECK-M: add r7, sp, #8
- ; CHECK-M: vpush {d0, d1, d2, d3, d4, d5, d6, d7}
- ; [...]
- ; CHECK-M: sub.w r4, r7, #80
- ; CHECK-M: mov sp, r4
- ; CHECK-M: vpop {d0, d1, d2, d3, d4, d5, d6, d7}
- ; CHECK-M: pop {r4, r6, r7, pc}
- ; CHECK-M-LABEL: .Lfunc_end0
-
- call arm_aapcscc void @bar()
- ret void
-}
-
-; We don't push/pop r12, as it is banked for FIQ
-define arm_aapcscc void @fiq_fn() alignstack(8) "interrupt"="FIQ" "save-fp" {
- ; CHECK-A-LABEL: fiq_fn:
- ; CHECK-A: push {r0, r1, r2, r3, r4, r5, r6, r7, r11, lr}
- ; CHECK-A: add r11, sp, #32
- ; [...]
- ; CHECK-A: sub sp, r11, #40
- ; CHECK-A: pop {r0, r1, r2, r3, r4, r5, r6, r7, r11, lr}
- ; CHECK-A-LABEL: .Lfunc_end1
-
- ; CHECK-A-THUMB-LABEL: fiq_fn:
- ; CHECK-A-THUMB: push.w {r0, r1, r2, r3, r4, r5, r6, r7, r11, lr}
- ; CHECK-A-THUMB: add r7, sp, #28
- ; [...]
- ; CHECK-A-THUMB: sub.w r4, r7, #36
- ; CHECK-A-THUMB: mov sp, r4
- ; CHECK-A-THUMB: pop.w {r0, r1, r2, r3, r4, r5, r6, r7, r11, lr}
- ; CHECK-A-THUMB-LABEL: .Lfunc_end1
-
- ; CHECK-R-LABEL: fiq_fn:
- ; CHECK-R: push {r0, r1, r2, r3, r4, r5, r6, r7, r11, lr}
- ; CHECK-R: add r11, sp, #32
- ; [...]
- ; CHECK-R: sub sp, r11, #40
- ; CHECK-R: pop {r0, r1, r2, r3, r4, r5, r6, r7, r11, lr}
- ; CHECK-R-LABEL: .Lfunc_end1
-
- ; CHECK-R-THUMB-LABEL: fiq_fn:
- ; CHECK-R-THUMB: push.w {r0, r1, r2, r3, r4, r5, r6, r7, r11, lr}
- ; CHECK-R-THUMB: add r7, sp, #28
- ; [...]
- ; CHECK-R-THUMB: sub.w r4, r7, #36
- ; CHECK-R-THUMB: mov sp, r4
- ; CHECK-R-THUMB: pop.w {r0, r1, r2, r3, r4, r5, r6, r7, r11, lr}
- ; CHECK-R-THUMB-LABEL: .Lfunc_end1
-
- ; CHECK-M-LABEL: fiq_fn:
- ; CHECK-M: push.w {r4, r5, r6, r7, r8, r9, r10, r11, lr}
- ; CHECK-M: add r7, sp, #12
- ; [...]
- ; CHECK-M: sub.w r4, r7, #16
- ; CHECK-M: mov sp, r4
- ; CHECK-M: pop.w {r4, r5, r6, r7, r8, r9, r10, r11, pc}
- ; CHECK-M-LABEL: .Lfunc_end1
-
- %val = load volatile [16 x i32], [16 x i32]* @bigvar
- store volatile [16 x i32] %val, [16 x i32]* @bigvar
- ret void
-}
-
-define arm_aapcscc void @swi_fn() alignstack(8) "interrupt"="SWI" "save-fp" {
- ; CHECK-A-LABEL: swi_fn:
- ; CHECK-A: push {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}
- ; CHECK-A: add r11, sp, #44
- ; [...]
- ; CHECK-A: sub sp, r11, #52
- ; CHECK-A: pop {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}
- ; CHECK-A-LABEL: .Lfunc_end2
-
- ; CHECK-A-THUMB-LABEL: swi_fn:
- ; CHECK-A-THUMB: push.w {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}
- ; CHECK-A-THUMB: add r7, sp, #28
- ; [...]
- ; CHECK-A-THUMB: sub.w r4, r7, #36
- ; CHECK-A-THUMB: mov sp, r4
- ; CHECK-A-THUMB: pop.w {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}
- ; CHECK-A-THUMB-LABEL: .Lfunc_end2
-
- ; CHECK-R-LABEL: swi_fn:
- ; CHECK-R: push {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}
- ; CHECK-R: add r11, sp, #44
- ; [...]
- ; CHECK-R: sub sp, r11, #52
- ; CHECK-R: pop {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}
- ; CHECK-R-LABEL: .Lfunc_end2
-
- ; CHECK-R-THUMB-LABEL: swi_fn:
- ; CHECK-R-THUMB: push.w {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}
- ; CHECK-R-THUMB: add r7, sp, #28
- ; [...]
- ; CHECK-R-THUMB: sub.w r4, r7, #36
- ; CHECK-R-THUMB: mov sp, r4
- ; CHECK-R-THUMB: pop.w {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}
- ; CHECK-R-THUMB-LABEL: .Lfunc_end2
-
- ; CHECK-M-LABEL: swi_fn:
- ; CHECK-M: push.w {r4, r5, r6, r7, r8, r9, r10, r11, lr}
- ; CHECK-M: add r7, sp, #12
- ; [...]
- ; CHECK-M: sub.w r4, r7, #16
- ; CHECK-M: mov sp, r4
- ; CHECK-M: pop.w {r4, r5, r6, r7, r8, r9, r10, r11, pc}
- ; CHECK-M-LABEL: .Lfunc_end2
-
- %val = load volatile [16 x i32], [16 x i32]* @bigvar
- store volatile [16 x i32] %val, [16 x i32]* @bigvar
- ret void
-}
-
-define arm_aapcscc void @undef_fn() alignstack(8) "interrupt"="UNDEF" "save-fp" {
- ; CHECK-A-LABEL: undef_fn:
- ; CHECK-A: push {r0, r1, r2, r3, r4, r5, r10, r11, r12, lr}
- ; CHECK-A: add r11, sp, #28
- ; CHECK-A: vpush {d0, d1, d2, d3, d4, d5, d6, d7}
- ; CHECK-A: vpush {d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
- ; [...]
- ; CHECK-A: sub sp, r11, #228
- ; CHECK-A: vpop {d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
- ; CHECK-A: vpop {d0, d1, d2, d3, d4, d5, d6, d7}
- ; CHECK-A: pop {r0, r1, r2, r3, r4, r5, r10, r11, r12, lr}
- ; CHECK-A-LABEL: .Lfunc_end3
-
- ; CHECK-A-THUMB-LABEL: undef_fn:
- ; CHECK-A-THUMB: push.w {r0, r1, r2, r3, r4, r5, r6, r7, r12, lr}
- ; CHECK-A-THUMB: add r7, sp, #28
- ; CHECK-A-THUMB: vpush {d0, d1, d2, d3, d4, d5, d6, d7}
- ; CHECK-A-THUMB: vpush {d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
- ; [...]
- ; CHECK-A-THUMB: sub.w r4, r7, #228
- ; CHECK-A-THUMB: mov sp, r4
- ; CHECK-A-THUMB: vpop {d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
- ; CHECK-A-THUMB: vpop {d0, d1, d2, d3, d4, d5, d6, d7}
- ; CHECK-A-THUMB: pop.w {r0, r1, r2, r3, r4, r5, r6, r7, r12, lr}
- ; CHECK-A-THUMB-LABEL: .Lfunc_end3
-
- ; CHECK-R-LABEL: undef_fn:
- ; CHECK-R: push {r0, r1, r2, r3, r4, r5, r10, r11, r12, lr}
- ; CHECK-R: add r11, sp, #28
- ; CHECK-R: vpush {d0, d1, d2, d3, d4, d5, d6, d7}
- ; [...]
- ; CHECK-R: sub sp, r11, #100
- ; CHECK-R: vpop {d0, d1, d2, d3, d4, d5, d6, d7}
- ; CHECK-R: pop {r0, r1, r2, r3, r4, r5, r10, r11, r12, lr}
- ; CHECK-R-LABEL: .Lfunc_end3
-
- ; CHECK-R-THUMB-LABEL: undef_fn:
- ; CHECK-R-THUMB: push.w {r0, r1, r2, r3, r4, r5, r6, r7, r12, lr}
- ; CHECK-R-THUMB: add r7, sp, #28
- ; CHECK-R-THUMB: vpush {d0, d1, d2, d3, d4, d5, d6, d7}
- ; [...]
- ; CHECK-R-THUMB: sub.w r4, r7, #100
- ; CHECK-R-THUMB: mov sp, r4
- ; CHECK-R-THUMB: vpop {d0, d1, d2, d3, d4, d5, d6, d7}
- ; CHECK-R-THUMB: pop.w {r0, r1, r2, r3, r4, r5, r6, r7, r12, lr}
- ; CHECK-R-THUMB-LABEL: .Lfunc_end3
-
- ; CHECK-M-LABEL: undef_fn:
- ; CHECK-M: push {r4, r6, r7, lr}
- ; CHECK-M: add r7, sp, #8
- ; CHECK-M: vpush {d0, d1, d2, d3, d4, d5, d6, d7}
- ; [...]
- ; CHECK-M: sub.w r4, r7, #80
- ; CHECK-M: mov sp, r4
- ; CHECK-M: vpop {d0, d1, d2, d3, d4, d5, d6, d7}
- ; CHECK-M: pop {r4, r6, r7, pc}
- ; CHECK-M-LABEL: .Lfunc_end3
-
- call void @bar()
- ret void
-}
-
-define arm_aapcscc void @abort_fn() alignstack(8) "interrupt"="ABORT" "save-fp" {
- ; CHECK-A-LABEL: abort_fn:
- ; CHECK-A: push {r0, r1, r2, r3, r4, r5, r10, r11, r12, lr}
- ; CHECK-A: add r11, sp, #28
- ; CHECK-A: vpush {d0, d1, d2, d3, d4, d5, d6, d7}
- ; CHECK-A: vpush {d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
- ; [...]
- ; CHECK-A: sub sp, r11, #228
- ; CHECK-A: vpop {d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
- ; CHECK-A: vpop {d0, d1, d2, d3, d4, d5, d6, d7}
- ; CHECK-A: pop {r0, r1, r2, r3, r4, r5, r10, r11, r12, lr}
- ; CHECK-A-LABEL: .Lfunc_end4
-
- ; CHECK-A-THUMB-LABEL: abort_fn:
- ; CHECK-A-THUMB: push.w {r0, r1, r2, r3, r4, r5, r6, r7, r12, lr}
- ; CHECK-A-THUMB: add r7, sp, #28
- ; CHECK-A-THUMB: vpush {d0, d1, d2, d3, d4, d5, d6, d7}
- ; CHECK-A-THUMB: vpush {d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
- ; [...]
- ; CHECK-A-THUMB: sub.w r4, r7, #228
- ; CHECK-A-THUMB: mov sp, r4
- ; CHECK-A-THUMB: vpop {d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
- ; CHECK-A-THUMB: vpop {d0, d1, d2, d3, d4, d5, d6, d7}
- ; CHECK-A-THUMB: pop.w {r0, r1, r2, r3, r4, r5, r6, r7, r12, lr}
- ; CHECK-A-THUMB-LABEL: .Lfunc_end4
-
- ; CHECK-R-LABEL: abort_fn:
- ; CHECK-R: push {r0, r1, r2, r3, r4, r5, r10, r11, r12, lr}
- ; CHECK-R: add r11, sp, #28
- ; CHECK-R: vpush {d0, d1, d2, d3, d4, d5, d6, d7}
- ; [...]
- ; CHECK-R: sub sp, r11, #100
- ; CHECK-R: vpop {d0, d1, d2, d3, d4, d5, d6, d7}
- ; CHECK-R: pop {r0, r1, r2, r3, r4, r5, r10, r11, r12, lr}
- ; CHECK-R-LABEL: .Lfunc_end4
-
- ; CHECK-R-THUMB-LABEL: abort_fn:
- ; CHECK-R-THUMB: push.w {r0, r1, r2, r3, r4, r5, r6, r7, r12, lr}
- ; CHECK-R-THUMB: add r7, sp, #28
- ; CHECK-R-THUMB: vpush {d0, d1, d2, d3, d4, d5, d6, d7}
- ; [...]
- ; CHECK-R-THUMB: sub.w r4, r7, #100
- ; CHECK-R-THUMB: mov sp, r4
- ; CHECK-R-THUMB: vpop {d0, d1, d2, d3, d4, d5, d6, d7}
- ; CHECK-R-THUMB: pop.w {r0, r1, r2, r3, r4, r5, r6, r7, r12, lr}
- ; CHECK-R-THUMB-LABEL: .Lfunc_end4
-
- ; CHECK-M-LABEL: abort_fn:
- ; CHECK-M: push {r4, r6, r7, lr}
- ; CHECK-M: add r7, sp, #8
- ; CHECK-M: vpush {d0, d1, d2, d3, d4, d5, d6, d7}
- ; [...]
- ; CHECK-M: sub.w r4, r7, #80
- ; CHECK-M: mov sp, r4
- ; CHECK-M: vpop {d0, d1, d2, d3, d4, d5, d6, d7}
- ; CHECK-M: pop {r4, r6, r7, pc}
- ; CHECK-M-LABEL: .Lfunc_end4
-
- call void @bar()
- ret void
-}
-
- at var = global double 0.0
More information about the cfe-commits
mailing list