174 lines
4.1 KiB
ArmAsm
174 lines
4.1 KiB
ArmAsm
/* Copyright (C) 2011-2021 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(__FDPIC__)
|
|
.macro ldaddr reg, addr
|
|
ldr \reg, 99f
|
|
add \reg, \reg, r9
|
|
.subsection 1
|
|
.align 2
|
|
99: .word \addr(GOTOFF)
|
|
.subsection 0
|
|
.endm
|
|
#elif 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
|