sjlj.S 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /* Copyright (C) 2011-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 "hwcap.h"
  20. #include "asmcfi.h"
  21. .syntax unified
  22. #if defined(__thumb2__)
  23. # define PC_OFS 4
  24. .thumb
  25. .thumb_func
  26. #else
  27. # define PC_OFS 8
  28. #endif
  29. #if defined (__thumb2__) && defined(__ARM_ARCH_6T2__)
  30. # define HAVE_MOVT
  31. .arch armv6t2
  32. #elif defined (__ARM_ARCH_7A__)
  33. # define HAVE_MOVT
  34. .arch armv7-a
  35. #elif defined (__ARM_ARCH_7R__)
  36. # define HAVE_MOVT
  37. .arch armv7-r
  38. #elif defined (__ARM_ARCH_7M__)
  39. # define HAVE_MOVT
  40. .arch armv7-m
  41. #endif
  42. #if defined(HAVE_MOVT) && defined(PIC)
  43. .macro ldaddr reg, addr
  44. movw \reg, #:lower16:(\addr - (98f + PC_OFS))
  45. movt \reg, #:upper16:(\addr - (98f + PC_OFS))
  46. 98: add \reg, \reg, pc
  47. .endm
  48. #elif defined(HAVE_MOVT)
  49. .macro ldaddr reg, addr
  50. movw \reg, #:lower16:\addr
  51. movt \reg, #:upper16:\addr
  52. .endm
  53. #elif defined(PIC)
  54. .macro ldaddr reg, addr
  55. ldr \reg, 99f
  56. 98: add \reg, \reg, pc
  57. .subsection 1
  58. .align 2
  59. 99: .word \addr - (98b + PC_OFS)
  60. .subsection 0
  61. .endm
  62. #else
  63. .macro ldaddr reg, addr
  64. ldr \reg, =\addr
  65. .endm
  66. #endif
  67. .text
  68. .align 2
  69. .global _ITM_beginTransaction
  70. .type _ITM_beginTransaction, %function
  71. _ITM_beginTransaction:
  72. .fnstart
  73. cfi_startproc
  74. mov ip, sp
  75. push { r4-r11, ip, lr }
  76. .save { lr }
  77. .pad #(9*4)
  78. cfi_adjust_cfa_offset(40)
  79. cfi_rel_offset(lr, 36)
  80. sub sp, sp, #(14*8)
  81. .pad #(14*8)
  82. cfi_adjust_cfa_offset(14*8)
  83. ldaddr r2, GTM_hwcap
  84. ldr r2, [r2]
  85. /* Store the VFP registers. Don't use VFP instructions directly
  86. because this code is used in non-VFP multilibs. */
  87. tst r2, #HWCAP_ARM_VFP
  88. beq 1f
  89. stc p11, cr8, [sp], {16} /* vstm sp, {d8-d15} */
  90. 1:
  91. /* Save the call-preserved iWMMXt registers. */
  92. tst r2, #HWCAP_ARM_IWMMXT
  93. beq 1f
  94. stcl p1, cr10, [sp, #64] /* wstrd wr10, [sp, #64] */
  95. stcl p1, cr11, [sp, #72]
  96. stcl p1, cr12, [sp, #80]
  97. stcl p1, cr13, [sp, #88]
  98. stcl p1, cr14, [sp, #96]
  99. stcl p1, cr15, [sp, #104]
  100. 1:
  101. /* Invoke GTM_begin_transaction with the struct we just built. */
  102. mov r1, sp
  103. bl GTM_begin_transaction
  104. /* Return; we don't need to restore any of the call-saved regs. */
  105. add sp, sp, #(14*8 + 9*4)
  106. cfi_adjust_cfa_offset(-(14*8 + 9*4))
  107. pop { pc }
  108. .fnend
  109. cfi_endproc
  110. .size _ITM_beginTransaction, . - _ITM_beginTransaction
  111. .align 2
  112. .global GTM_longjmp
  113. .hidden GTM_longjmp
  114. .type GTM_longjmp, %function
  115. GTM_longjmp:
  116. cfi_startproc
  117. ldaddr r2, GTM_hwcap
  118. ldr r2, [r2]
  119. tst r2, #HWCAP_ARM_VFP
  120. beq 1f
  121. ldc p11, cr8, [r1], {16} /* vldmia r1, {d8-d15} */
  122. 1:
  123. tst r2, #HWCAP_ARM_IWMMXT
  124. beq 1f
  125. ldcl p1, cr10, [r1, #64] /* wldrd wr10, [r1, #64] */
  126. ldcl p1, cr11, [r1, #72]
  127. ldcl p1, cr12, [r1, #80]
  128. ldcl p1, cr13, [r1, #88]
  129. ldcl p1, cr14, [r1, #96]
  130. ldcl p1, cr15, [r1, #104]
  131. 1:
  132. add r1, r1, #(14*8) /* Skip both VFP and iWMMXt blocks */
  133. #ifdef __thumb2__
  134. ldm r1, { r4-r11, ip, lr }
  135. cfi_def_cfa(ip, 0)
  136. mov sp, ip
  137. bx lr
  138. #else
  139. ldm r1, { r4-r11, sp, pc }
  140. #endif
  141. cfi_endproc
  142. .size GTM_longjmp, . - GTM_longjmp
  143. #ifdef __linux__
  144. .section .note.GNU-stack, "", %progbits
  145. #endif