switchcontext.S 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /* i386 support code for fibers and multithreading.
  2. Copyright (C) 2019-2022 Free Software Foundation, Inc.
  3. This file is part of GCC.
  4. GCC is free software; you can redistribute it and/or modify it under
  5. the terms of the GNU General Public License as published by the Free
  6. Software Foundation; either version 3, or (at your option) any later
  7. version.
  8. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  9. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  11. for 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 "../common/threadasm.S"
  20. /* NB: Generate the CET marker for -fcf-protection. */
  21. #ifdef __CET__
  22. # include <cet.h>
  23. #endif
  24. #if !defined(__CET__)
  25. # if defined(__ELF__)
  26. # if defined(__i386__)
  27. .text
  28. .globl CSYM(fiber_switchContext)
  29. .type CSYM(fiber_switchContext), @function
  30. .align 16
  31. CSYM(fiber_switchContext):
  32. .cfi_startproc
  33. // save current stack state
  34. push %ebp
  35. mov %esp, %ebp
  36. push %edi
  37. push %esi
  38. push %ebx
  39. push %eax
  40. // store oldp again with more accurate address
  41. mov 8(%ebp), %eax
  42. mov %esp, (%eax)
  43. // load newp to begin context switch
  44. mov 12(%ebp), %esp
  45. // load saved state from new stack
  46. pop %eax
  47. pop %ebx
  48. pop %esi
  49. pop %edi
  50. pop %ebp
  51. // 'return' to complete switch
  52. ret
  53. .cfi_endproc
  54. .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
  55. # endif /* defined(__ELF__) && defined(__i386__) */
  56. # if defined(__x86_64__) && !defined(__ILP32__)
  57. .text
  58. .globl CSYM(fiber_switchContext)
  59. .type CSYM(fiber_switchContext), @function
  60. .align 16
  61. CSYM(fiber_switchContext):
  62. .cfi_startproc
  63. // Save current stack state.save current stack state
  64. push %rbp
  65. mov %rsp, %rbp
  66. push %rbx
  67. push %r12
  68. push %r13
  69. push %r14
  70. push %r15
  71. // store oldp again with more accurate address
  72. mov %rsp, (%rdi)
  73. // load newp to begin context switch
  74. mov %rsi, %rsp
  75. // load saved state from new stack
  76. pop %r15
  77. pop %r14
  78. pop %r13
  79. pop %r12
  80. pop %rbx
  81. pop %rbp
  82. // 'return' to complete switch
  83. ret
  84. .cfi_endproc
  85. .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext)
  86. # endif /* defined(__ELF__) && defined(__x86_64__) && !defined(__ILP32__) */
  87. # endif /* defined(__ELF__) */
  88. # if defined(__MACH__)
  89. # if defined(__i386__)
  90. .text
  91. .globl CSYM(fiber_switchContext)
  92. .p2align 4
  93. CSYM(fiber_switchContext):
  94. LFB0:
  95. // save current stack state
  96. push %ebp
  97. mov %esp, %ebp
  98. push %edi
  99. push %esi
  100. push %ebx
  101. push %eax
  102. // store oldp again with more accurate address
  103. mov 8(%ebp), %eax
  104. mov %esp, (%eax)
  105. // load newp to begin context switch
  106. mov 12(%ebp), %esp
  107. // load saved state from new stack
  108. pop %eax
  109. pop %ebx
  110. pop %esi
  111. pop %edi
  112. pop %ebp
  113. // 'return' to complete switch
  114. ret
  115. LFE0:
  116. /* CFI */
  117. .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
  118. EH_frame1:
  119. .set L$set$0,LECIE1-LSCIE1
  120. .long L$set$0 # Length of Common Information Entry
  121. LSCIE1:
  122. .long 0 # CIE Identifier Tag
  123. .byte 0x1 # CIE Version
  124. .ascii "zR\0" # CIE Augmentation
  125. .byte 0x1 # uleb128 0x1; CIE Code Alignment Factor
  126. .byte 0x7c # sleb128 -4; CIE Data Alignment Factor
  127. .byte 0x8 # CIE RA Column
  128. .byte 0x1 # uleb128 0x1; Augmentation size
  129. .byte 0x10 # FDE Encoding (pcrel)
  130. .byte 0xc # DW_CFA_def_cfa
  131. .byte 0x5 # uleb128 0x5
  132. .byte 0x4 # uleb128 0x4
  133. .byte 0x88 # DW_CFA_offset, column 0x8
  134. .byte 0x1 # uleb128 0x1
  135. .p2align 2,0
  136. LECIE1:
  137. /* minimal FDE - does not record the stack frame changes. */
  138. LSFDE1:
  139. .set L$set$1,LEFDE1-LASFDE1
  140. .long L$set$1 # FDE Length
  141. LASFDE1:
  142. .long LASFDE1-EH_frame1 # FDE CIE offset
  143. .long LFB0-. # FDE initial location
  144. .set L$set$2,LFE0-LFB0
  145. .long L$set$2 # FDE address range
  146. .byte 0 # uleb128 0; Augmentation size
  147. .p2align 2,0
  148. LEFDE1:
  149. # endif /* defined(__MACH__) && defined(__i386__) */
  150. # if defined(__x86_64__) && !defined(__ILP32__)
  151. .text
  152. .globl CSYM(fiber_switchContext)
  153. .p2align 4
  154. CSYM(fiber_switchContext):
  155. LFB0:
  156. // Save current stack state.save current stack state
  157. push %rbp
  158. mov %rsp, %rbp
  159. push %r15
  160. push %r14
  161. push %r13
  162. push %r12
  163. push %rbx
  164. // store oldp again with more accurate address
  165. mov %rsp, (%rdi)
  166. // load newp to begin context switch
  167. mov %rsi, %rsp
  168. // load saved state from new stack
  169. pop %rbx
  170. pop %r12
  171. pop %r13
  172. pop %r14
  173. pop %r15
  174. pop %rbp
  175. // 'return' to complete switch
  176. ret
  177. LFE0:
  178. /* CFI */
  179. .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
  180. EH_frame1:
  181. .set L$set$0,LECIE1-LSCIE1
  182. .long L$set$0 # Length of Common Information Entry
  183. LSCIE1:
  184. .long 0 # CIE Identifier Tag
  185. .byte 0x1 # CIE Version
  186. .ascii "zR\0" # CIE Augmentation
  187. .byte 0x1 # uleb128 0x1; CIE Code Alignment Factor
  188. .byte 0x78 # sleb128 -8; CIE Data Alignment Factor
  189. .byte 0x10 # CIE RA Column
  190. .byte 0x1 # uleb128 0x1; Augmentation size
  191. .byte 0x10 # FDE Encoding (pcrel)
  192. .byte 0xc # DW_CFA_def_cfa
  193. .byte 0x7 # uleb128 0x7
  194. .byte 0x8 # uleb128 0x8
  195. .byte 0x90 # DW_CFA_offset, column 0x10
  196. .byte 0x1 # uleb128 0x1
  197. .p2align 3,0
  198. LECIE1:
  199. /* minimal FDE - does not record the stack frame changes. */
  200. LSFDE1:
  201. .set L$set$1,LEFDE1-LASFDE1
  202. .long L$set$1 # FDE Length
  203. LASFDE1:
  204. .long LASFDE1-EH_frame1 # FDE CIE offset
  205. .quad LFB0-. # FDE initial location
  206. .set L$set$2,LFE0-LFB0
  207. .quad L$set$2 # FDE address range
  208. .byte 0 # uleb128 0; Augmentation size
  209. .p2align 3,0
  210. LEFDE1:
  211. # endif /* defined(__MACH__) && defined(__x86_64__) && !defined(__ILP32__) */
  212. # endif /* defined (__MACH__) */
  213. #endif /* !defined(__CET__) */