gcc50: Disconnect from buildworld.
[dragonfly.git] / contrib / gcc-5.0 / libitm / config / x86 / sjlj.S
1 /* Copyright (C) 2008-2015 Free Software Foundation, Inc.
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
25
26 #include "asmcfi.h"
27 #include "config.h"
28
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
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
69         .text
70
71         .align 4
72         .globl  SYM(_ITM_beginTransaction)
73
74 SYM(_ITM_beginTransaction):
75         cfi_startproc
76 #ifdef __x86_64__
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,
84            we have to explicitly save/restore the first argument (edi).  */
85         cmpl    $0, SYM(gtm_htm_fastpath)(%rip)
86         jz      .Lno_htm
87         testl   $pr_hasNoAbort, %edi
88         jz      .Lno_htm
89 .Lhtm_fastpath:
90         xbegin  .Ltxn_abort
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)
97         jnz     1f
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
103         cmovnz  %edi, %eax
104         ret
105         /* There is a serial-mode transaction, so abort (see htm_abort()
106            regarding the abort code).  */
107 1:      xabort  $0xff
108 .Ltxn_abort:
109         /* If it might make sense to retry the HTM fast path, let the C++
110            code decide.  */
111         testl   $(_XABORT_RETRY|_XABORT_EXPLICIT), %eax
112         jz      .Lno_htm
113         orl     $pr_HTMRetryableAbort, %edi
114         /* Let the C++ code handle the retry policy.  */
115 .Lno_htm:
116 #endif
117         leaq    8(%rsp), %rax
118         subq    $72, %rsp
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.  */
123         movl    %edi, 8(%rsp)
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
126            handy, use it.  */
127         movq    %rax, -64(%rax)
128         movq    %rbx, -56(%rax)
129         movq    %rbp, -48(%rax)
130         movq    %r12, -40(%rax)
131         movq    %r13, -32(%rax)
132         movq    %r14, -24(%rax)
133         movq    %r15, -16(%rax)
134         leaq    -64(%rax), %rsi
135         call    SYM(GTM_begin_transaction)
136         movl    8(%rsp), %edi
137         addq    $72, %rsp
138         cfi_adjust_cfa_offset(-72)
139 #ifdef HAVE_AS_RTM
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
148         jnz     2f
149         andl    $(0xffffffff-pr_HTMRetryableAbort), %edi
150         orl     $pr_HTMRetriedAfterAbort, %edi
151         jmp     .Lhtm_fastpath
152 2:
153 #endif
154 #else
155         leal    4(%esp), %ecx
156         movl    4(%esp), %eax
157         subl    $28, %esp
158         cfi_def_cfa_offset(32)
159         movl    %ecx, 8(%esp)
160         movl    %ebx, 12(%esp)
161         movl    %esi, 16(%esp)
162         movl    %edi, 20(%esp)
163         movl    %ebp, 24(%esp)
164         leal    8(%esp), %edx
165 #if defined HAVE_ATTRIBUTE_VISIBILITY || !defined __PIC__
166         call    SYM(GTM_begin_transaction)
167 #elif defined __ELF__
168         call    1f
169 1:      popl    %ebx
170         addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
171         call    SYM(GTM_begin_transaction)@PLT
172         movl    12(%esp), %ebx
173 #else
174 # error "Unsupported PIC sequence"
175 #endif
176         addl    $28, %esp
177         cfi_def_cfa_offset(4)
178 #endif
179         ret
180         cfi_endproc
181
182         TYPE(_ITM_beginTransaction)
183         SIZE(_ITM_beginTransaction)
184
185         .align 4
186         .globl  SYM(GTM_longjmp)
187
188 SYM(GTM_longjmp):
189         cfi_startproc
190 #ifdef __x86_64__
191         movq    (%rsi), %rcx
192         movq    8(%rsi), %rbx
193         movq    16(%rsi), %rbp
194         movq    24(%rsi), %r12
195         movq    32(%rsi), %r13
196         movq    40(%rsi), %r14
197         movq    48(%rsi), %r15
198         movl    %edi, %eax
199         cfi_def_cfa(%rsi, 0)
200         cfi_offset(%rip, 56)
201         cfi_register(%rsp, %rcx)
202         movq    %rcx, %rsp
203         jmp     *56(%rsi)
204 #else
205         movl    (%edx), %ecx
206         movl    4(%edx), %ebx
207         movl    8(%edx), %esi
208         movl    12(%edx), %edi
209         movl    16(%edx), %ebp
210         cfi_def_cfa(%edx, 0)
211         cfi_offset(%eip, 20)
212         cfi_register(%esp, %ecx)
213         movl    %ecx, %esp
214         jmp     *20(%edx)
215 #endif
216         cfi_endproc
217
218         TYPE(GTM_longjmp)
219         HIDDEN(GTM_longjmp)
220         SIZE(GTM_longjmp)
221
222 #ifdef __linux__
223 .section .note.GNU-stack, "", @progbits
224 #endif