sjlj.S 6.4 KB

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