diff --git a/libcxxabi/src/cxa_exception.cpp b/libcxxabi/src/cxa_exception.cpp index 593fdbec2b1b3a..35956f197f59d5 100644 --- a/libcxxabi/src/cxa_exception.cpp +++ b/libcxxabi/src/cxa_exception.cpp @@ -341,10 +341,8 @@ unwinding with _Unwind_Resume. According to ARM EHABI 8.4.1, __cxa_end_cleanup() should not clobber any register, thus we have to write this function in assembly so that we can save {r1, r2, r3}. We don't have to save r0 because it is the return value and the -first argument to _Unwind_Resume(). In addition, we are saving lr in order to -align the stack to 16 bytes and lr will be used to identify the caller and its -frame information. _Unwind_Resume never return and we need to keep the original -lr so just branch to it. +first argument to _Unwind_Resume(). In addition, we are saving r4 in order to +align the stack to 16 bytes, even though it is a callee-save register. */ __attribute__((used)) static _Unwind_Exception * __cxa_end_cleanup_impl() @@ -374,15 +372,18 @@ __cxa_end_cleanup_impl() return &exception_header->unwindHeader; } -asm(" .pushsection .text.__cxa_end_cleanup,\"ax\",%progbits\n" +asm ( + " .pushsection .text.__cxa_end_cleanup,\"ax\",%progbits\n" " .globl __cxa_end_cleanup\n" " .type __cxa_end_cleanup,%function\n" "__cxa_end_cleanup:\n" - " push {r1, r2, r3, lr}\n" + " push {r1, r2, r3, r4}\n" " bl __cxa_end_cleanup_impl\n" - " pop {r1, r2, r3, lr}\n" - " b _Unwind_Resume\n" - " .popsection"); + " pop {r1, r2, r3, r4}\n" + " bl _Unwind_Resume\n" + " bl abort\n" + " .popsection" +); #endif // defined(_LIBCXXABI_ARM_EHABI) /* diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h index 27eada6a3e3c42..e18fbf5c8457fc 100644 --- a/llvm/include/llvm/ADT/Triple.h +++ b/llvm/include/llvm/ADT/Triple.h @@ -721,18 +721,6 @@ class Triple { return getArch() == Triple::arm || getArch() == Triple::armeb; } - /// Tests whether the target supports the EHABI exception - /// handling standard. - bool isTargetEHABICompatible() const { - return (getEnvironment() == Triple::EABI || - getEnvironment() == Triple::GNUEABI || - getEnvironment() == Triple::MuslEABI || - getEnvironment() == Triple::EABIHF || - getEnvironment() == Triple::GNUEABIHF || - getEnvironment() == Triple::MuslEABIHF || isAndroid()) && - isOSBinFormatELF(); - } - /// Tests whether the target is AArch64 (little and big endian). bool isAArch64() const { return getArch() == Triple::aarch64 || getArch() == Triple::aarch64_be || diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.def b/llvm/include/llvm/IR/RuntimeLibcalls.def index 5f295660557ad0..dd28780ac946ff 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.def +++ b/llvm/include/llvm/IR/RuntimeLibcalls.def @@ -432,7 +432,6 @@ HANDLE_LIBCALL(MEMSET_ELEMENT_UNORDERED_ATOMIC_16, "__llvm_memset_element_unorde // Exception handling HANDLE_LIBCALL(UNWIND_RESUME, "_Unwind_Resume") -HANDLE_LIBCALL(CXA_END_CLEANUP, "__cxa_end_cleanup") // Note: there are two sets of atomics libcalls; see // for more info on the diff --git a/llvm/lib/CodeGen/DwarfEHPrepare.cpp b/llvm/lib/CodeGen/DwarfEHPrepare.cpp index fb8a3e383950cf..fde7b942665d4a 100644 --- a/llvm/lib/CodeGen/DwarfEHPrepare.cpp +++ b/llvm/lib/CodeGen/DwarfEHPrepare.cpp @@ -14,7 +14,6 @@ #include "llvm/ADT/BitVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" -#include "llvm/ADT/Triple.h" #include "llvm/Analysis/CFG.h" #include "llvm/Analysis/DomTreeUpdater.h" #include "llvm/Analysis/EHPersonalities.h" @@ -55,11 +54,13 @@ namespace { class DwarfEHPrepare { CodeGenOpt::Level OptLevel; + // RewindFunction - _Unwind_Resume or the target equivalent. + FunctionCallee &RewindFunction; + Function &F; const TargetLowering &TLI; DomTreeUpdater *DTU; const TargetTransformInfo *TTI; - const Triple &TargetTriple; /// Return the exception object from the value passed into /// the 'resume' instruction (typically an aggregate). Clean up any dead @@ -77,11 +78,11 @@ class DwarfEHPrepare { bool InsertUnwindResumeCalls(); public: - DwarfEHPrepare(CodeGenOpt::Level OptLevel_, Function &F_, - const TargetLowering &TLI_, DomTreeUpdater *DTU_, - const TargetTransformInfo *TTI_, const Triple &TargetTriple_) - : OptLevel(OptLevel_), F(F_), TLI(TLI_), DTU(DTU_), TTI(TTI_), - TargetTriple(TargetTriple_) {} + DwarfEHPrepare(CodeGenOpt::Level OptLevel_, FunctionCallee &RewindFunction_, + Function &F_, const TargetLowering &TLI_, DomTreeUpdater *DTU_, + const TargetTransformInfo *TTI_) + : OptLevel(OptLevel_), RewindFunction(RewindFunction_), F(F_), TLI(TLI_), + DTU(DTU_), TTI(TTI_) {} bool run(); }; @@ -210,28 +211,13 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls() { if (ResumesLeft == 0) return true; // We pruned them all. - // RewindFunction - _Unwind_Resume or the target equivalent. - FunctionCallee RewindFunction; - CallingConv::ID RewindFunctionCallingConv; - FunctionType *FTy; - const char *RewindName; - bool DoesRewindFunctionNeedExceptionObject; - - if ((Pers == EHPersonality::GNU_CXX || Pers == EHPersonality::GNU_CXX_SjLj) && - TargetTriple.isTargetEHABICompatible()) { - RewindName = TLI.getLibcallName(RTLIB::CXA_END_CLEANUP); - FTy = FunctionType::get(Type::getVoidTy(Ctx), false); - RewindFunctionCallingConv = - TLI.getLibcallCallingConv(RTLIB::CXA_END_CLEANUP); - DoesRewindFunctionNeedExceptionObject = false; - } else { - RewindName = TLI.getLibcallName(RTLIB::UNWIND_RESUME); - FTy = + // Find the rewind function if we didn't already. + if (!RewindFunction) { + FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx), Type::getInt8PtrTy(Ctx), false); - RewindFunctionCallingConv = TLI.getLibcallCallingConv(RTLIB::UNWIND_RESUME); - DoesRewindFunctionNeedExceptionObject = true; + const char *RewindName = TLI.getLibcallName(RTLIB::UNWIND_RESUME); + RewindFunction = F.getParent()->getOrInsertFunction(RewindName, FTy); } - RewindFunction = F.getParent()->getOrInsertFunction(RewindName, FTy); // Create the basic block where the _Unwind_Resume call will live. if (ResumesLeft == 1) { @@ -240,14 +226,10 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls() { ResumeInst *RI = Resumes.front(); BasicBlock *UnwindBB = RI->getParent(); Value *ExnObj = GetExceptionObject(RI); - llvm::SmallVector RewindFunctionArgs; - if (DoesRewindFunctionNeedExceptionObject) - RewindFunctionArgs.push_back(ExnObj); - // Call the rewind function. - CallInst *CI = - CallInst::Create(RewindFunction, RewindFunctionArgs, "", UnwindBB); - CI->setCallingConv(RewindFunctionCallingConv); + // Call the _Unwind_Resume function. + CallInst *CI = CallInst::Create(RewindFunction, ExnObj, "", UnwindBB); + CI->setCallingConv(TLI.getLibcallCallingConv(RTLIB::UNWIND_RESUME)); // We never expect _Unwind_Resume to return. CI->setDoesNotReturn(); @@ -258,8 +240,6 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls() { std::vector Updates; Updates.reserve(Resumes.size()); - llvm::SmallVector RewindFunctionArgs; - BasicBlock *UnwindBB = BasicBlock::Create(Ctx, "unwind_resume", &F); PHINode *PN = PHINode::Create(Type::getInt8PtrTy(Ctx), ResumesLeft, "exn.obj", UnwindBB); @@ -277,13 +257,9 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls() { ++NumResumesLowered; } - if (DoesRewindFunctionNeedExceptionObject) - RewindFunctionArgs.push_back(PN); - // Call the function. - CallInst *CI = - CallInst::Create(RewindFunction, RewindFunctionArgs, "", UnwindBB); - CI->setCallingConv(RewindFunctionCallingConv); + CallInst *CI = CallInst::Create(RewindFunction, PN, "", UnwindBB); + CI->setCallingConv(TLI.getLibcallCallingConv(RTLIB::UNWIND_RESUME)); // We never expect _Unwind_Resume to return. CI->setDoesNotReturn(); @@ -301,20 +277,22 @@ bool DwarfEHPrepare::run() { return Changed; } -static bool prepareDwarfEH(CodeGenOpt::Level OptLevel, Function &F, +static bool prepareDwarfEH(CodeGenOpt::Level OptLevel, + FunctionCallee &RewindFunction, Function &F, const TargetLowering &TLI, DominatorTree *DT, - const TargetTransformInfo *TTI, - const Triple &TargetTriple) { + const TargetTransformInfo *TTI) { DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy); - return DwarfEHPrepare(OptLevel, F, TLI, DT ? &DTU : nullptr, TTI, - TargetTriple) + return DwarfEHPrepare(OptLevel, RewindFunction, F, TLI, DT ? &DTU : nullptr, + TTI) .run(); } namespace { class DwarfEHPrepareLegacyPass : public FunctionPass { + // RewindFunction - _Unwind_Resume or the target equivalent. + FunctionCallee RewindFunction = nullptr; CodeGenOpt::Level OptLevel; @@ -337,7 +315,12 @@ class DwarfEHPrepareLegacyPass : public FunctionPass { DT = &getAnalysis().getDomTree(); TTI = &getAnalysis().getTTI(F); } - return prepareDwarfEH(OptLevel, F, TLI, DT, TTI, TM.getTargetTriple()); + return prepareDwarfEH(OptLevel, RewindFunction, F, TLI, DT, TTI); + } + + bool doFinalization(Module &M) override { + RewindFunction = nullptr; + return false; } void getAnalysisUsage(AnalysisUsage &AU) const override { diff --git a/llvm/lib/Target/ARM/ARMSubtarget.h b/llvm/lib/Target/ARM/ARMSubtarget.h index 68390c9902686a..807bbc11bd9485 100644 --- a/llvm/lib/Target/ARM/ARMSubtarget.h +++ b/llvm/lib/Target/ARM/ARMSubtarget.h @@ -792,7 +792,14 @@ class ARMSubtarget : public ARMGenSubtargetInfo { // ARM Targets that support EHABI exception handling standard // Darwin uses SjLj. Other targets might need more checks. bool isTargetEHABICompatible() const { - return TargetTriple.isTargetEHABICompatible(); + return (TargetTriple.getEnvironment() == Triple::EABI || + TargetTriple.getEnvironment() == Triple::GNUEABI || + TargetTriple.getEnvironment() == Triple::MuslEABI || + TargetTriple.getEnvironment() == Triple::EABIHF || + TargetTriple.getEnvironment() == Triple::GNUEABIHF || + TargetTriple.getEnvironment() == Triple::MuslEABIHF || + isTargetAndroid()) && + !isTargetDarwin() && !isTargetWindows(); } bool isTargetHardFloat() const; diff --git a/llvm/test/CodeGen/ARM/debug-frame.ll b/llvm/test/CodeGen/ARM/debug-frame.ll index b7660443a7d326..b561be465d25d5 100644 --- a/llvm/test/CodeGen/ARM/debug-frame.ll +++ b/llvm/test/CodeGen/ARM/debug-frame.ll @@ -197,27 +197,29 @@ declare void @_ZSt9terminatev() ; CHECK-V7-FP-LABEL: _Z4testiiiiiddddd: ; CHECK-V7-FP: .cfi_startproc -; CHECK-V7-FP: push {r11, lr} -; CHECK-V7-FP: .cfi_def_cfa_offset 8 +; CHECK-V7-FP: push {r4, r10, r11, lr} +; CHECK-V7-FP: .cfi_def_cfa_offset 16 ; CHECK-V7-FP: .cfi_offset lr, -4 ; CHECK-V7-FP: .cfi_offset r11, -8 -; CHECK-V7-FP: mov r11, sp -; CHECK-V7-FP: .cfi_def_cfa_register r11 +; CHECK-V7-FP: .cfi_offset r10, -12 +; CHECK-V7-FP: .cfi_offset r4, -16 +; CHECK-V7-FP: add r11, sp, #8 +; CHECK-V7-FP: .cfi_def_cfa r11, 8 ; CHECK-V7-FP: vpush {d8, d9, d10, d11, d12} -; CHECK-V7-FP: .cfi_offset d12, -16 -; CHECK-V7-FP: .cfi_offset d11, -24 -; CHECK-V7-FP: .cfi_offset d10, -32 -; CHECK-V7-FP: .cfi_offset d9, -40 -; CHECK-V7-FP: .cfi_offset d8, -48 +; CHECK-V7-FP: .cfi_offset d12, -24 +; CHECK-V7-FP: .cfi_offset d11, -32 +; CHECK-V7-FP: .cfi_offset d10, -40 +; CHECK-V7-FP: .cfi_offset d9, -48 +; CHECK-V7-FP: .cfi_offset d8, -56 ; CHECK-V7-FP: sub sp, sp, #24 ; CHECK-V7-FP: .cfi_endproc ; CHECK-V7-FP-ELIM-LABEL: _Z4testiiiiiddddd: ; CHECK-V7-FP-ELIM: .cfi_startproc -; CHECK-V7-FP-ELIM: push {r11, lr} +; CHECK-V7-FP-ELIM: push {r4, lr} ; CHECK-V7-FP-ELIM: .cfi_def_cfa_offset 8 ; CHECK-V7-FP-ELIM: .cfi_offset lr, -4 -; CHECK-V7-FP-ELIM: .cfi_offset r11, -8 +; CHECK-V7-FP-ELIM: .cfi_offset r4, -8 ; CHECK-V7-FP-ELIM: vpush {d8, d9, d10, d11, d12} ; CHECK-V7-FP-ELIM: .cfi_def_cfa_offset 48 ; CHECK-V7-FP-ELIM: .cfi_offset d12, -16 @@ -258,27 +260,29 @@ declare void @_ZSt9terminatev() ; CHECK-THUMB-V7-FP-LABEL: _Z4testiiiiiddddd: ; CHECK-THUMB-V7-FP: .cfi_startproc -; CHECK-THUMB-V7-FP: push {r7, lr} -; CHECK-THUMB-V7-FP: .cfi_def_cfa_offset 8 +; CHECK-THUMB-V7-FP: push {r4, r6, r7, lr} +; CHECK-THUMB-V7-FP: .cfi_def_cfa_offset 16 ; CHECK-THUMB-V7-FP: .cfi_offset lr, -4 ; CHECK-THUMB-V7-FP: .cfi_offset r7, -8 -; CHECK-THUMB-V7-FP: mov r7, sp -; CHECK-THUMB-V7-FP: .cfi_def_cfa_register r7 +; CHECK-THUMB-V7-FP: .cfi_offset r6, -12 +; CHECK-THUMB-V7-FP: .cfi_offset r4, -16 +; CHECK-THUMB-V7-FP: add r7, sp, #8 +; CHECK-THUMB-V7-FP: .cfi_def_cfa r7, 8 ; CHECK-THUMB-V7-FP: vpush {d8, d9, d10, d11, d12} -; CHECK-THUMB-V7-FP: .cfi_offset d12, -16 -; CHECK-THUMB-V7-FP: .cfi_offset d11, -24 -; CHECK-THUMB-V7-FP: .cfi_offset d10, -32 -; CHECK-THUMB-V7-FP: .cfi_offset d9, -40 -; CHECK-THUMB-V7-FP: .cfi_offset d8, -48 +; CHECK-THUMB-V7-FP: .cfi_offset d12, -24 +; CHECK-THUMB-V7-FP: .cfi_offset d11, -32 +; CHECK-THUMB-V7-FP: .cfi_offset d10, -40 +; CHECK-THUMB-V7-FP: .cfi_offset d9, -48 +; CHECK-THUMB-V7-FP: .cfi_offset d8, -56 ; CHECK-THUMB-V7-FP: sub sp, #24 ; CHECK-THUMB-V7-FP: .cfi_endproc ; CHECK-THUMB-V7-FP-ELIM-LABEL: _Z4testiiiiiddddd: ; CHECK-THUMB-V7-FP-ELIM: .cfi_startproc -; CHECK-THUMB-V7-FP-ELIM: push {r7, lr} +; CHECK-THUMB-V7-FP-ELIM: push {r4, lr} ; CHECK-THUMB-V7-FP-ELIM: .cfi_def_cfa_offset 8 ; CHECK-THUMB-V7-FP-ELIM: .cfi_offset lr, -4 -; CHECK-THUMB-V7-FP-ELIM: .cfi_offset r7, -8 +; CHECK-THUMB-V7-FP-ELIM: .cfi_offset r4, -8 ; CHECK-THUMB-V7-FP-ELIM: vpush {d8, d9, d10, d11, d12} ; CHECK-THUMB-V7-FP-ELIM: .cfi_def_cfa_offset 48 ; CHECK-THUMB-V7-FP-ELIM: .cfi_offset d12, -16 @@ -292,18 +296,20 @@ declare void @_ZSt9terminatev() ; CHECK-THUMB-V7-FP-NOIAS-LABEL: _Z4testiiiiiddddd: ; CHECK-THUMB-V7-FP-NOIAS: .cfi_startproc -; CHECK-THUMB-V7-FP-NOIAS: push {r7, lr} -; CHECK-THUMB-V7-FP-NOIAS: .cfi_def_cfa_offset 8 +; CHECK-THUMB-V7-FP-NOIAS: push {r4, r6, r7, lr} +; CHECK-THUMB-V7-FP-NOIAS: .cfi_def_cfa_offset 16 ; CHECK-THUMB-V7-FP-NOIAS: .cfi_offset 14, -4 ; CHECK-THUMB-V7-FP-NOIAS: .cfi_offset 7, -8 -; CHECK-THUMB-V7-FP-NOIAS: mov r7, sp -; CHECK-THUMB-V7-FP-NOIAS: .cfi_def_cfa_register 7 +; CHECK-THUMB-V7-FP-NOIAS: .cfi_offset 6, -12 +; CHECK-THUMB-V7-FP-NOIAS: .cfi_offset 4, -16 +; CHECK-THUMB-V7-FP-NOIAS: add r7, sp, #8 +; CHECK-THUMB-V7-FP-NOIAS: .cfi_def_cfa 7, 8 ; CHECK-THUMB-V7-FP-NOIAS: vpush {d8, d9, d10, d11, d12} -; CHECK-THUMB-V7-FP-NOIAS: .cfi_offset 268, -16 -; CHECK-THUMB-V7-FP-NOIAS: .cfi_offset 267, -24 -; CHECK-THUMB-V7-FP-NOIAS: .cfi_offset 266, -32 -; CHECK-THUMB-V7-FP-NOIAS: .cfi_offset 265, -40 -; CHECK-THUMB-V7-FP-NOIAS: .cfi_offset 264, -48 +; CHECK-THUMB-V7-FP-NOIAS: .cfi_offset 268, -24 +; CHECK-THUMB-V7-FP-NOIAS: .cfi_offset 267, -32 +; CHECK-THUMB-V7-FP-NOIAS: .cfi_offset 266, -40 +; CHECK-THUMB-V7-FP-NOIAS: .cfi_offset 265, -48 +; CHECK-THUMB-V7-FP-NOIAS: .cfi_offset 264, -56 ; CHECK-THUMB-V7-FP-NOIAS: sub sp, #24 ; CHECK-THUMB-V7-FP-NOIAS: .cfi_endproc diff --git a/llvm/test/CodeGen/ARM/eh-resume.ll b/llvm/test/CodeGen/ARM/eh-resume-darwin.ll similarity index 76% rename from llvm/test/CodeGen/ARM/eh-resume.ll rename to llvm/test/CodeGen/ARM/eh-resume-darwin.ll index 12fe2667b8f0c0..6c2716bffa6d4f 100644 --- a/llvm/test/CodeGen/ARM/eh-resume.ll +++ b/llvm/test/CodeGen/ARM/eh-resume-darwin.ll @@ -2,8 +2,6 @@ ; RUN: llc < %s -mtriple=armv7-apple-watchos -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=IOS ; RUN: llc < %s -mtriple=armv7k-apple-ios -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=WATCHABI ; RUN: llc < %s -mtriple=armv7k-apple-watchos -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=WATCHABI -; RUN: llc < %s -mtriple=armv7-none-gnueabihf -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=EABI -; RUN: llc < %s -mtriple=armv7-none-none -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=ABI declare void @func() @@ -25,5 +23,3 @@ lpad: ; IOS: __Unwind_SjLj_Resume ; WATCHABI: __Unwind_Resume -; EABI: __cxa_end_cleanup -; ABI: _Unwind_Resume diff --git a/llvm/test/CodeGen/ARM/eh-resume2.ll b/llvm/test/CodeGen/ARM/eh-resume2.ll deleted file mode 100644 index d30b507255c4d8..00000000000000 --- a/llvm/test/CodeGen/ARM/eh-resume2.ll +++ /dev/null @@ -1,32 +0,0 @@ -; RUN: llc < %s -mtriple=armv7-apple-ios -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=IOS -; RUN: llc < %s -mtriple=armv7-apple-watchos -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=IOS -; RUN: llc < %s -mtriple=armv7k-apple-ios -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=WATCHABI -; RUN: llc < %s -mtriple=armv7k-apple-watchos -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=WATCHABI -; RUN: llc < %s -mtriple=armv7-none-gnueabihf -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=EABI -; RUN: llc < %s -mtriple=armv7-none-none -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=ABI - -; ARM EABI for C++/__gxx_personality* specifies __cxa_end_cleanup, but for C code / __gcc_personality* -; the _Unwind_Resume is required. - -declare void @func() - -declare i32 @__gcc_personality_v0(...) - -define void @test0() personality i8* bitcast (i32 (...)* @__gcc_personality_v0 to i8*) { -entry: - invoke void @func() - to label %cont unwind label %lpad - -cont: - ret void - -lpad: - %exn = landingpad { i8*, i32 } - cleanup - resume { i8*, i32 } %exn -} - -; IOS: __Unwind_SjLj_Resume -; WATCHABI: __Unwind_Resume -; EABI: _Unwind_Resume -; ABI: _Unwind_Resume diff --git a/llvm/test/CodeGen/ARM/ehabi.ll b/llvm/test/CodeGen/ARM/ehabi.ll index c8c0b5b61980ab..5c4a2b620a1f01 100644 --- a/llvm/test/CodeGen/ARM/ehabi.ll +++ b/llvm/test/CodeGen/ARM/ehabi.ll @@ -181,10 +181,10 @@ declare void @_ZSt9terminatev() ; CHECK-V7-FP-LABEL: _Z4testiiiiiddddd: ; CHECK-V7-FP: .fnstart -; CHECK-V7-FP: .save {r11, lr} -; CHECK-V7-FP: push {r11, lr} -; CHECK-V7-FP: .setfp r11, sp -; CHECK-V7-FP: mov r11, sp +; CHECK-V7-FP: .save {r4, r10, r11, lr} +; CHECK-V7-FP: push {r4, r10, r11, lr} +; CHECK-V7-FP: .setfp r11, sp, #8 +; CHECK-V7-FP: add r11, sp, #8 ; CHECK-V7-FP: .vsave {d8, d9, d10, d11, d12} ; CHECK-V7-FP: vpush {d8, d9, d10, d11, d12} ; CHECK-V7-FP: .pad #24 @@ -195,8 +195,8 @@ declare void @_ZSt9terminatev() ; CHECK-V7-FP-ELIM-LABEL: _Z4testiiiiiddddd: ; CHECK-V7-FP-ELIM: .fnstart -; CHECK-V7-FP-ELIM: .save {r11, lr} -; CHECK-V7-FP-ELIM: push {r11, lr} +; CHECK-V7-FP-ELIM: .save {r4, lr} +; CHECK-V7-FP-ELIM: push {r4, lr} ; CHECK-V7-FP-ELIM: .vsave {d8, d9, d10, d11, d12} ; CHECK-V7-FP-ELIM: vpush {d8, d9, d10, d11, d12} ; CHECK-V7-FP-ELIM: .pad #24 @@ -254,31 +254,33 @@ declare void @_ZSt9terminatev() ; DWARF-V7-FP: .cfi_startproc ; DWARF-V7-FP: .cfi_personality 0, __gxx_personality_v0 ; DWARF-V7-FP: .cfi_lsda 0, .Lexception0 -; DWARF-V7-FP: push {r11, lr} -; DWARF-V7-FP: .cfi_def_cfa_offset 8 +; DWARF-V7-FP: push {r4, r10, r11, lr} +; DWARF-V7-FP: .cfi_def_cfa_offset 16 ; DWARF-V7-FP: .cfi_offset lr, -4 ; DWARF-V7-FP: .cfi_offset r11, -8 -; DWARF-V7-FP: mov r11, sp -; DWARF-V7-FP: .cfi_def_cfa_register r11 +; DWARF-V7-FP: .cfi_offset r10, -12 +; DWARF-V7-FP: .cfi_offset r4, -16 +; DWARF-V7-FP: add r11, sp, #8 +; DWARF-V7-FP: .cfi_def_cfa r11, 8 ; DWARF-V7-FP: vpush {d8, d9, d10, d11, d12} -; DWARF-V7-FP: .cfi_offset d12, -16 -; DWARF-V7-FP: .cfi_offset d11, -24 -; DWARF-V7-FP: .cfi_offset d10, -32 -; DWARF-V7-FP: .cfi_offset d9, -40 +; DWARF-V7-FP: .cfi_offset d12, -24 +; DWARF-V7-FP: .cfi_offset d11, -32 +; DWARF-V7-FP: .cfi_offset d10, -40 +; DWARF-V7-FP: .cfi_offset d9, -48 ; DWARF-V7-FP: sub sp, sp, #24 -; DWARF-V7-FP: sub sp, r11, #40 +; DWARF-V7-FP: sub sp, r11, #48 ; DWARF-V7-FP: vpop {d8, d9, d10, d11, d12} -; DWARF-V7-FP: pop {r11, pc} +; DWARF-V7-FP: pop {r4, r10, r11, pc} ; DWARF-V7-FP: .cfi_endproc ; DWARF-V7-FP-ELIM-LABEL: _Z4testiiiiiddddd: ; DWARF-V7-FP-ELIM: .cfi_startproc ; DWARF-V7-FP-ELIM: .cfi_personality 0, __gxx_personality_v0 ; DWARF-V7-FP-ELIM: .cfi_lsda 0, .Lexception0 -; DWARF-V7-FP-ELIM: push {r11, lr} +; DWARF-V7-FP-ELIM: push {r4, lr} ; DWARF-V7-FP-ELIM: .cfi_def_cfa_offset 8 ; DWARF-V7-FP-ELIM: .cfi_offset lr, -4 -; DWARF-V7-FP-ELIM: .cfi_offset r11, -8 +; DWARF-V7-FP-ELIM: .cfi_offset r4, -8 ; DWARF-V7-FP-ELIM: vpush {d8, d9, d10, d11, d12} ; DWARF-V7-FP-ELIM: .cfi_offset d12, -16 ; DWARF-V7-FP-ELIM: .cfi_offset d11, -24 @@ -288,7 +290,7 @@ declare void @_ZSt9terminatev() ; DWARF-V7-FP-ELIM: .cfi_def_cfa_offset 72 ; DWARF-V7-FP-ELIM: add sp, sp, #24 ; DWARF-V7-FP-ELIM: vpop {d8, d9, d10, d11, d12} -; DWARF-V7-FP-ELIM: pop {r11, pc} +; DWARF-V7-FP-ELIM: pop {r4, pc} ; DWARF-V7-FP-ELIM: .cfi_endproc ; DWARF-WIN-FP-ELIM-LABEL: _Z4testiiiiiddddd: