diff options
Diffstat (limited to 'gcc-4.8.3/libitm/config/arm/sjlj.S')
-rw-r--r-- | gcc-4.8.3/libitm/config/arm/sjlj.S | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/gcc-4.8.3/libitm/config/arm/sjlj.S b/gcc-4.8.3/libitm/config/arm/sjlj.S new file mode 100644 index 000000000..b6b6f5799 --- /dev/null +++ b/gcc-4.8.3/libitm/config/arm/sjlj.S @@ -0,0 +1,164 @@ +/* Copyright (C) 2011-2013 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@redhat.com>. + + This file is part of the GNU Transactional Memory Library (libitm). + + Libitm is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Libitm is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +#include "hwcap.h" +#include "asmcfi.h" + + .syntax unified + +#if defined(__thumb2__) +# define PC_OFS 4 + .thumb + .thumb_func +#else +# define PC_OFS 8 +#endif + +#if defined (__thumb2__) && defined(__ARM_ARCH_6T2__) +# define HAVE_MOVT + .arch armv6t2 +#elif defined (__ARM_ARCH_7A__) +# define HAVE_MOVT + .arch armv7-a +#elif defined (__ARM_ARCH_7R__) +# define HAVE_MOVT + .arch armv7-r +#elif defined (__ARM_ARCH_7M__) +# define HAVE_MOVT + .arch armv7-m +#endif + +#if defined(HAVE_MOVT) && defined(PIC) +.macro ldaddr reg, addr + movw \reg, #:lower16:(\addr - (98f + PC_OFS)) + movt \reg, #:upper16:(\addr - (98f + PC_OFS)) +98: add \reg, \reg, pc +.endm +#elif defined(HAVE_MOVT) +.macro ldaddr reg, addr + movw \reg, #:lower16:\addr + movt \reg, #:upper16:\addr +.endm +#elif defined(PIC) +.macro ldaddr reg, addr + ldr \reg, 99f +98: add \reg, \reg, pc +.subsection 1 + .align 2 +99: .word \addr - (98b + PC_OFS) +.subsection 0 +.endm +#else +.macro ldaddr reg, addr + ldr \reg, =\addr +.endm +#endif + + .text + .align 2 + .global _ITM_beginTransaction + .type _ITM_beginTransaction, %function + +_ITM_beginTransaction: + .fnstart + cfi_startproc + mov ip, sp + push { r4-r11, ip, lr } + .save { lr } + .pad #(9*4) + cfi_adjust_cfa_offset(40) + cfi_rel_offset(lr, 36) + sub sp, sp, #(14*8) + .pad #(14*8) + cfi_adjust_cfa_offset(14*8) + + ldaddr r2, GTM_hwcap + ldr r2, [r2] + + /* Store the VFP registers. Don't use VFP instructions directly + because this code is used in non-VFP multilibs. */ + tst r2, #HWCAP_ARM_VFP + beq 1f + stc p11, cr8, [sp], {16} /* vstm sp, {d8-d15} */ +1: + /* Save the call-preserved iWMMXt registers. */ + tst r2, #HWCAP_ARM_IWMMXT + beq 1f + stcl p1, cr10, [sp, #64] /* wstrd wr10, [sp, #64] */ + stcl p1, cr11, [sp, #72] + stcl p1, cr12, [sp, #80] + stcl p1, cr13, [sp, #88] + stcl p1, cr14, [sp, #96] + stcl p1, cr15, [sp, #104] +1: + /* Invoke GTM_begin_transaction with the struct we just built. */ + mov r1, sp + bl GTM_begin_transaction + + /* Return; we don't need to restore any of the call-saved regs. */ + add sp, sp, #(14*8 + 9*4) + cfi_adjust_cfa_offset(-(14*8 + 9*4)) + pop { pc } + .fnend + cfi_endproc + .size _ITM_beginTransaction, . - _ITM_beginTransaction + + .align 2 + .global GTM_longjmp + .hidden GTM_longjmp + .type GTM_longjmp, %function + +GTM_longjmp: + cfi_startproc + ldaddr r2, GTM_hwcap + ldr r2, [r2] + + tst r2, #HWCAP_ARM_VFP + beq 1f + ldc p11, cr8, [r1], {16} /* vldmia r1, {d8-d15} */ +1: + tst r2, #HWCAP_ARM_IWMMXT + beq 1f + ldcl p1, cr10, [r1, #64] /* wldrd wr10, [r1, #64] */ + ldcl p1, cr11, [r1, #72] + ldcl p1, cr12, [r1, #80] + ldcl p1, cr13, [r1, #88] + ldcl p1, cr14, [r1, #96] + ldcl p1, cr15, [r1, #104] +1: + add r1, r1, #(14*8) /* Skip both VFP and iWMMXt blocks */ +#ifdef __thumb2__ + ldm r1, { r4-r11, ip, lr } + cfi_def_cfa(ip, 0) + mov sp, ip + bx lr +#else + ldm r1, { r4-r11, sp, pc } +#endif + cfi_endproc + .size GTM_longjmp, . - GTM_longjmp + +#ifdef __linux__ +.section .note.GNU-stack, "", %progbits +#endif |