]> gcc.gnu.org Git - gcc.git/blame - libitm/config/x86/sjlj.S
libitm: Fix HTM fastpath.
[gcc.git] / libitm / config / x86 / sjlj.S
CommitLineData
818ab71a 1/* Copyright (C) 2008-2016 Free Software Foundation, Inc.
0a35513e
AH
2 Contributed by Richard Henderson <rth@redhat.com>.
3
4 This file is part of the GNU Transactional Memory Library (libitm).
5
6 Libitm is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 Libitm is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 more details.
15
16 Under Section 7 of GPL version 3, you are granted additional
17 permissions described in the GCC Runtime Library Exception, version
18 3.1, as published by the Free Software Foundation.
19
20 You should have received a copy of the GNU General Public License and
21 a copy of the GCC Runtime Library Exception along with this program;
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 <http://www.gnu.org/licenses/>. */
24
4bdd090f
RH
25
26#include "asmcfi.h"
bec9ec3f 27#include "config.h"
4bdd090f 28
0b41ebef
IS
29#define CONCAT1(a, b) CONCAT2(a, b)
30#define CONCAT2(a, b) a ## b
31
32#ifdef __USER_LABEL_PREFIX__
33# define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
34#else
35# define SYM(x) x
36#endif
37
38#ifdef __ELF__
39# define TYPE(x) .type SYM(x), @function
40# define SIZE(x) .size SYM(x), . - SYM(x)
41# ifdef HAVE_ATTRIBUTE_VISIBILITY
42# define HIDDEN(x) .hidden SYM(x)
43# else
44# define HIDDEN(x)
45# endif
46#else
47# define TYPE(x)
48# define SIZE(x)
49# ifdef __MACH__
50# define HIDDEN(x) .private_extern SYM(x)
51# else
52# define HIDDEN(x)
53# endif
54#endif
55
bec9ec3f
TR
56/* These are duplicates of the canonical definitions in libitm.h. Note that
57 the code relies on pr_uninstrumentedCode == a_runUninstrumentedCode. */
58#define pr_uninstrumentedCode 0x02
59#define pr_hasNoAbort 0x08
60#define pr_HTMRetryableAbort 0x800000
61#define pr_HTMRetriedAfterAbort 0x1000000
62#define a_runInstrumentedCode 0x01
63#define a_runUninstrumentedCode 0x02
64#define a_tryHTMFastPath 0x20
65
66#define _XABORT_EXPLICIT (1 << 0)
67#define _XABORT_RETRY (1 << 1)
68
0a35513e 69 .text
9bdc6343
RH
70
71 .align 4
0b41ebef 72 .globl SYM(_ITM_beginTransaction)
0a35513e 73
0b41ebef 74SYM(_ITM_beginTransaction):
4bdd090f 75 cfi_startproc
0a35513e 76#ifdef __x86_64__
bec9ec3f
TR
77#ifdef HAVE_AS_RTM
78 /* Custom HTM fast path. We start the HW transaction here and let
79 gtm_thread::begin_transaction (aka GTM_begin_transaction) decide
80 how to proceed on aborts: We either retry the fast path, or fall
81 back to another execution method. RTM restores all registers after
82 a HW transaction abort, so we can do the SW setjmp after aborts,
83 and we have to because we might choose a SW fall back. However,
6041f70a
TR
84 we have to explicitly save/restore the first argument (edi).
85 The htm_fastpath field is the second int in gtm_rwlock. */
86 cmpl $0, (SYM(gtm_serial_lock)+4)(%rip)
bec9ec3f
TR
87 jz .Lno_htm
88 testl $pr_hasNoAbort, %edi
89 jz .Lno_htm
90.Lhtm_fastpath:
91 xbegin .Ltxn_abort
92 /* Monitor the serial lock (specifically, the 32b writer/summary field
93 at its start), and only continue if there is no serial-mode
94 transaction. Note that we might be just a nested transaction and
95 our outermost transaction might be in serial mode; we check for
96 this case in the retry policy implementation. */
97 cmpl $0, SYM(gtm_serial_lock)(%rip)
98 jnz 1f
6041f70a
TR
99 /* Now also check that HW transactions are still allowed to run (see
100 gtm_thread::begin_transaction for why this is necessary). */
101 cmpl $0, (SYM(gtm_serial_lock)+4)(%rip)
102 jz 1f
bec9ec3f
TR
103 /* Everything is good. Run the transaction, preferably using the
104 uninstrumented code path. Note that the following works because
105 pr_uninstrumentedCode == a_runUninstrumentedCode. */
106 andl $pr_uninstrumentedCode, %edi
107 mov $a_runInstrumentedCode, %eax
108 cmovnz %edi, %eax
109 ret
6041f70a
TR
110 /* There is a serial-mode transaction or HW transactions are not
111 allowed anymore, so abort (see htm_abort() regarding the abort
112 code). */
bec9ec3f
TR
1131: xabort $0xff
114.Ltxn_abort:
115 /* If it might make sense to retry the HTM fast path, let the C++
116 code decide. */
117 testl $(_XABORT_RETRY|_XABORT_EXPLICIT), %eax
118 jz .Lno_htm
119 orl $pr_HTMRetryableAbort, %edi
120 /* Let the C++ code handle the retry policy. */
121.Lno_htm:
122#endif
0a35513e 123 leaq 8(%rsp), %rax
bec9ec3f
TR
124 subq $72, %rsp
125 cfi_adjust_cfa_offset(72)
126 /* Store edi for future HTM fast path retries. We use a stack slot
127 lower than the jmpbuf so that the jmpbuf's rip field will overlap
128 with the proper return address on the stack. */
129 movl %edi, 8(%rsp)
130 /* Save the jmpbuf for any non-HTM-fastpath execution method.
131 Because rsp-based addressing is 1 byte larger and we've got rax
132 handy, use it. */
133 movq %rax, -64(%rax)
134 movq %rbx, -56(%rax)
135 movq %rbp, -48(%rax)
136 movq %r12, -40(%rax)
137 movq %r13, -32(%rax)
138 movq %r14, -24(%rax)
139 movq %r15, -16(%rax)
140 leaq -64(%rax), %rsi
0b41ebef 141 call SYM(GTM_begin_transaction)
bec9ec3f
TR
142 movl 8(%rsp), %edi
143 addq $72, %rsp
144 cfi_adjust_cfa_offset(-72)
145#ifdef HAVE_AS_RTM
146 /* If a_tryHTMFastPath was returned, then we need to retry the
147 fast path. We also restore edi and set pr_HTMRetriedAfterAbort
148 to state that we have retried the fast path already (it's harmless
149 if this bit is set even if we don't retry the fast path because it
150 is checked iff pr_HTMRetryableAbort is set). We clear
151 pr_HTMRetryableAbort because it applies to a previous HW
152 transaction attempt. */
153 cmpl $a_tryHTMFastPath, %eax
154 jnz 2f
155 andl $(0xffffffff-pr_HTMRetryableAbort), %edi
156 orl $pr_HTMRetriedAfterAbort, %edi
157 jmp .Lhtm_fastpath
1582:
159#endif
0a35513e
AH
160#else
161 leal 4(%esp), %ecx
5752c591 162 movl 4(%esp), %eax
0a35513e 163 subl $28, %esp
4bdd090f 164 cfi_def_cfa_offset(32)
0a35513e
AH
165 movl %ecx, 8(%esp)
166 movl %ebx, 12(%esp)
167 movl %esi, 16(%esp)
168 movl %edi, 20(%esp)
169 movl %ebp, 24(%esp)
170 leal 8(%esp), %edx
59659b59 171#if defined HAVE_ATTRIBUTE_VISIBILITY || !defined __PIC__
0b41ebef 172 call SYM(GTM_begin_transaction)
59659b59
RO
173#elif defined __ELF__
174 call 1f
1751: popl %ebx
176 addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
0b41ebef 177 call SYM(GTM_begin_transaction)@PLT
59659b59
RO
178 movl 12(%esp), %ebx
179#else
180# error "Unsupported PIC sequence"
181#endif
0a35513e 182 addl $28, %esp
4bdd090f 183 cfi_def_cfa_offset(4)
0a35513e 184#endif
0c609a21 185 ret
4bdd090f 186 cfi_endproc
9bdc6343 187
0b41ebef
IS
188 TYPE(_ITM_beginTransaction)
189 SIZE(_ITM_beginTransaction)
0a35513e 190
9bdc6343 191 .align 4
0b41ebef 192 .globl SYM(GTM_longjmp)
0a35513e 193
0b41ebef 194SYM(GTM_longjmp):
4bdd090f 195 cfi_startproc
0a35513e 196#ifdef __x86_64__
062f93f2 197 movq (%rsi), %rcx
9848887a
UB
198 movq 8(%rsi), %rbx
199 movq 16(%rsi), %rbp
200 movq 24(%rsi), %r12
201 movq 32(%rsi), %r13
202 movq 40(%rsi), %r14
203 movq 48(%rsi), %r15
1f319dba 204 movl %edi, %eax
72824d5e
RH
205 cfi_def_cfa(%rsi, 0)
206 cfi_offset(%rip, 56)
1f319dba 207 cfi_register(%rsp, %rcx)
72824d5e 208 movq %rcx, %rsp
d4a698d4 209 jmp *56(%rsi)
0a35513e 210#else
0a35513e
AH
211 movl (%edx), %ecx
212 movl 4(%edx), %ebx
213 movl 8(%edx), %esi
214 movl 12(%edx), %edi
215 movl 16(%edx), %ebp
72824d5e 216 cfi_def_cfa(%edx, 0)
d4a698d4 217 cfi_offset(%eip, 20)
1f319dba 218 cfi_register(%esp, %ecx)
72824d5e 219 movl %ecx, %esp
d4a698d4 220 jmp *20(%edx)
0a35513e 221#endif
4bdd090f 222 cfi_endproc
9bdc6343 223
0b41ebef
IS
224 TYPE(GTM_longjmp)
225 HIDDEN(GTM_longjmp)
226 SIZE(GTM_longjmp)
0a35513e 227
9bdc6343 228#ifdef __linux__
0a35513e 229.section .note.GNU-stack, "", @progbits
9bdc6343 230#endif
This page took 0.403178 seconds and 5 git commands to generate.