123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- /* Copyright (C) 2011-2015 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
|