1 /* Copyright (C) 2008-2015 Free Software Foundation, Inc.
2 Contributed by Richard Henderson <rth@redhat.com>.
4 This file is part of the GNU Transactional Memory Library (libitm).
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.
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
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.
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/>. */
29 #define CONCAT1(a, b) CONCAT2(a, b)
30 #define CONCAT2(a, b) a ## b
32 #ifdef __USER_LABEL_PREFIX__
33 # define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
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)
50 # define HIDDEN(x) .private_extern SYM(x)
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
66 #define _XABORT_EXPLICIT (1 << 0)
67 #define _XABORT_RETRY (1 << 1)
72 .globl SYM(_ITM_beginTransaction)
74 SYM(_ITM_beginTransaction):
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,
84 we have to explicitly save/restore the first argument (edi). */
85 cmpl $0, SYM(gtm_htm_fastpath)(%rip)
87 testl $pr_hasNoAbort, %edi
91 /* Monitor the serial lock (specifically, the 32b writer/summary field
92 at its start), and only continue if there is no serial-mode
93 transaction. Note that we might be just a nested transaction and
94 our outermost transaction might be in serial mode; we check for
95 this case in the retry policy implementation. */
96 cmpl $0, SYM(gtm_serial_lock)(%rip)
98 /* Everything is good. Run the transaction, preferably using the
99 uninstrumented code path. Note that the following works because
100 pr_uninstrumentedCode == a_runUninstrumentedCode. */
101 andl $pr_uninstrumentedCode, %edi
102 mov $a_runInstrumentedCode, %eax
105 /* There is a serial-mode transaction, so abort (see htm_abort()
106 regarding the abort code). */
109 /* If it might make sense to retry the HTM fast path, let the C++
111 testl $(_XABORT_RETRY|_XABORT_EXPLICIT), %eax
113 orl $pr_HTMRetryableAbort, %edi
114 /* Let the C++ code handle the retry policy. */
119 cfi_adjust_cfa_offset(72)
120 /* Store edi for future HTM fast path retries. We use a stack slot
121 lower than the jmpbuf so that the jmpbuf's rip field will overlap
122 with the proper return address on the stack. */
124 /* Save the jmpbuf for any non-HTM-fastpath execution method.
125 Because rsp-based addressing is 1 byte larger and we've got rax
135 call SYM(GTM_begin_transaction)
138 cfi_adjust_cfa_offset(-72)
140 /* If a_tryHTMFastPath was returned, then we need to retry the
141 fast path. We also restore edi and set pr_HTMRetriedAfterAbort
142 to state that we have retried the fast path already (it's harmless
143 if this bit is set even if we don't retry the fast path because it
144 is checked iff pr_HTMRetryableAbort is set). We clear
145 pr_HTMRetryableAbort because it applies to a previous HW
146 transaction attempt. */
147 cmpl $a_tryHTMFastPath, %eax
149 andl $(0xffffffff-pr_HTMRetryableAbort), %edi
150 orl $pr_HTMRetriedAfterAbort, %edi
158 cfi_def_cfa_offset(32)
165 #if defined HAVE_ATTRIBUTE_VISIBILITY || !defined __PIC__
166 call SYM(GTM_begin_transaction)
167 #elif defined __ELF__
170 addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
171 call SYM(GTM_begin_transaction)@PLT
174 # error "Unsupported PIC sequence"
177 cfi_def_cfa_offset(4)
182 TYPE(_ITM_beginTransaction)
183 SIZE(_ITM_beginTransaction)
186 .globl SYM(GTM_longjmp)
201 cfi_register(%rsp, %rcx)
212 cfi_register(%esp, %ecx)
223 .section .note.GNU-stack, "", @progbits