/src/core/threadasm.S

http://github.com/AlexeyProkhin/druntime · Assembly · 335 lines · 243 code · 31 blank · 61 comment · 4 complexity · ea8772f349b98f6baa75160e9d96139a MD5 · raw file

  1. /**
  2. * Support code for mutithreading.
  3. *
  4. * Copyright: Copyright Mikola Lysenko 2005 - 2012.
  5. * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
  6. * Authors: Mikola Lysenko, Martin Nowak, Kai Nacke
  7. */
  8. /*
  9. * Copyright Mikola Lysenko 2005 - 2012.
  10. * Distributed under the Boost Software License, Version 1.0.
  11. * (See accompanying file LICENSE_1_0.txt or copy at
  12. * http://www.boost.org/LICENSE_1_0.txt)
  13. */
  14. /************************************************************************************
  15. * POWER PC ASM BITS
  16. ************************************************************************************/
  17. #if defined( __PPC64__ )
  18. .text
  19. .globl _D4core6thread18callWithStackShellFMDFPvZvZv
  20. .align 2
  21. .type _D4core6thread18callWithStackShellFMDFPvZvZv,@function
  22. .section .opd,"aw",@progbits
  23. _D4core6thread18callWithStackShellFMDFPvZvZv:
  24. .align 3
  25. .quad .L._D4core6thread18callWithStackShellFMDFPvZvZv
  26. .quad .TOC.@tocbase
  27. .quad 0
  28. .text
  29. /*
  30. * Called with:
  31. * r3: pointer context
  32. * r4: pointer to function
  33. */
  34. .L._D4core6thread18callWithStackShellFMDFPvZvZv:
  35. .cfi_startproc
  36. mflr 0
  37. std 0, 16(1) // save LR
  38. stdu 1, -256(1) // stack size: 18*8 + 112 = 256
  39. .cfi_def_cfa_offset 256
  40. .cfi_offset lr, 16
  41. /* Save r14-r31 in general register save area */
  42. std 14, (112 + 0 * 8)(1)
  43. std 15, (112 + 1 * 8)(1)
  44. std 16, (112 + 2 * 8)(1)
  45. std 17, (112 + 3 * 8)(1)
  46. std 18, (112 + 4 * 8)(1)
  47. std 19, (112 + 5 * 8)(1)
  48. std 20, (112 + 6 * 8)(1)
  49. std 21, (112 + 7 * 8)(1)
  50. std 22, (112 + 8 * 8)(1)
  51. std 23, (112 + 9 * 8)(1)
  52. std 24, (112 + 10 * 8)(1)
  53. std 25, (112 + 11 * 8)(1)
  54. std 26, (112 + 12 * 8)(1)
  55. std 27, (112 + 13 * 8)(1)
  56. std 28, (112 + 14 * 8)(1)
  57. std 29, (112 + 15 * 8)(1)
  58. std 30, (112 + 16 * 8)(1)
  59. std 31, (112 + 17 * 8)(1)
  60. /* Save r3-r10 in parameter save area of caller */
  61. std 3, (256 + 48 + 0 * 8)(1)
  62. std 4, (256 + 48 + 1 * 8)(1)
  63. std 5, (256 + 48 + 2 * 8)(1)
  64. std 6, (256 + 48 + 3 * 8)(1)
  65. std 7, (256 + 48 + 4 * 8)(1)
  66. std 8, (256 + 48 + 5 * 8)(1)
  67. std 9, (256 + 48 + 6 * 8)(1)
  68. std 10, (256 + 48 + 7 * 8)(1)
  69. /* Save r2 in TOC save area */
  70. std 2, 40(1)
  71. /* Do not save r11, r12 and r13. */
  72. /* Call delegate:
  73. * r3: pointer to context
  74. * r4: pointer to stack
  75. */
  76. mr 5, 4
  77. mr 4, 1
  78. ld 6, 0(5)
  79. ld 11, 16(5)
  80. ld 2, 8(5)
  81. mtctr 6
  82. bctrl
  83. nop
  84. /* Restore r2 from TOC save area */
  85. ld 2, 40(1)
  86. /* Restore r3-r10 from local variable space */
  87. ld 3, (256 + 48 + 0 * 8)(1)
  88. ld 4, (256 + 48 + 1 * 8)(1)
  89. ld 5, (256 + 48 + 2 * 8)(1)
  90. ld 6, (256 + 48 + 3 * 8)(1)
  91. ld 7, (256 + 48 + 4 * 8)(1)
  92. ld 8, (256 + 48 + 5 * 8)(1)
  93. ld 9, (256 + 48 + 6 * 8)(1)
  94. ld 10, (256 + 48 + 7 * 8)(1)
  95. /* Restore r14-r31 from general register save area */
  96. ld 14, (112 + 0 * 8)(1)
  97. ld 15, (112 + 1 * 8)(1)
  98. ld 16, (112 + 2 * 8)(1)
  99. ld 17, (112 + 3 * 8)(1)
  100. ld 18, (112 + 4 * 8)(1)
  101. ld 19, (112 + 5 * 8)(1)
  102. ld 20, (112 + 6 * 8)(1)
  103. ld 21, (112 + 7 * 8)(1)
  104. ld 22, (112 + 8 * 8)(1)
  105. ld 23, (112 + 9 * 8)(1)
  106. ld 24, (112 + 10 * 8)(1)
  107. ld 25, (112 + 11 * 8)(1)
  108. ld 26, (112 + 12 * 8)(1)
  109. ld 27, (112 + 13 * 8)(1)
  110. ld 28, (112 + 14 * 8)(1)
  111. ld 29, (112 + 15 * 8)(1)
  112. ld 30, (112 + 16 * 8)(1)
  113. ld 31, (112 + 17 * 8)(1)
  114. addi 1, 1, 256
  115. ld 0, 16(1)
  116. mtlr 0
  117. blr
  118. .long 0
  119. .quad 0
  120. .Lend:
  121. .size _D4core6thread18callWithStackShellFMDFPvZvZv, .Lend-.L._D4core6thread18callWithStackShellFMDFPvZvZv
  122. .cfi_endproc
  123. #elif defined( __ppc__ ) || defined( __PPC__ ) || defined( __powerpc__ )
  124. /**
  125. * Performs a context switch.
  126. *
  127. * r3 - old context pointer
  128. * r4 - new context pointer
  129. *
  130. */
  131. .text
  132. .align 2
  133. .globl _fiber_switchContext
  134. _fiber_switchContext:
  135. /* Save linkage area */
  136. mflr 0
  137. mfcr 5
  138. stw 0, 8(1)
  139. stw 5, 4(1)
  140. /* Save GPRs */
  141. stw 11, (-1 * 4)(1)
  142. stw 13, (-2 * 4)(1)
  143. stw 14, (-3 * 4)(1)
  144. stw 15, (-4 * 4)(1)
  145. stw 16, (-5 * 4)(1)
  146. stw 17, (-6 * 4)(1)
  147. stw 18, (-7 * 4)(1)
  148. stw 19, (-8 * 4)(1)
  149. stw 20, (-9 * 4)(1)
  150. stw 21, (-10 * 4)(1)
  151. stw 22, (-11 * 4)(1)
  152. stw 23, (-12 * 4)(1)
  153. stw 24, (-13 * 4)(1)
  154. stw 25, (-14 * 4)(1)
  155. stw 26, (-15 * 4)(1)
  156. stw 27, (-16 * 4)(1)
  157. stw 28, (-17 * 4)(1)
  158. stw 29, (-18 * 4)(1)
  159. stw 30, (-19 * 4)(1)
  160. stwu 31, (-20 * 4)(1)
  161. /* We update the stack pointer here, since we do not want the GC to
  162. scan the floating point registers. */
  163. /* Save FPRs */
  164. stfd 14, (-1 * 8)(1)
  165. stfd 15, (-2 * 8)(1)
  166. stfd 16, (-3 * 8)(1)
  167. stfd 17, (-4 * 8)(1)
  168. stfd 18, (-5 * 8)(1)
  169. stfd 19, (-6 * 8)(1)
  170. stfd 20, (-7 * 8)(1)
  171. stfd 21, (-8 * 8)(1)
  172. stfd 22, (-9 * 8)(1)
  173. stfd 23, (-10 * 8)(1)
  174. stfd 24, (-11 * 8)(1)
  175. stfd 25, (-12 * 8)(1)
  176. stfd 26, (-13 * 8)(1)
  177. stfd 27, (-14 * 8)(1)
  178. stfd 28, (-15 * 8)(1)
  179. stfd 29, (-16 * 8)(1)
  180. stfd 30, (-17 * 8)(1)
  181. stfd 31, (-18 * 8)(1)
  182. /* Update the old stack pointer */
  183. stw 1, 0(3)
  184. /* Set new stack pointer */
  185. addi 1, 4, 20 * 4
  186. /* Restore linkage area */
  187. lwz 0, 8(1)
  188. lwz 5, 4(1)
  189. /* Restore GPRs */
  190. lwz 11, (-1 * 4)(1)
  191. lwz 13, (-2 * 4)(1)
  192. lwz 14, (-3 * 4)(1)
  193. lwz 15, (-4 * 4)(1)
  194. lwz 16, (-5 * 4)(1)
  195. lwz 17, (-6 * 4)(1)
  196. lwz 18, (-7 * 4)(1)
  197. lwz 19, (-8 * 4)(1)
  198. lwz 20, (-9 * 4)(1)
  199. lwz 21, (-10 * 4)(1)
  200. lwz 22, (-11 * 4)(1)
  201. lwz 23, (-12 * 4)(1)
  202. lwz 24, (-13 * 4)(1)
  203. lwz 25, (-14 * 4)(1)
  204. lwz 26, (-15 * 4)(1)
  205. lwz 27, (-16 * 4)(1)
  206. lwz 28, (-17 * 4)(1)
  207. lwz 29, (-18 * 4)(1)
  208. lwz 30, (-19 * 4)(1)
  209. lwz 31, (-20 * 4)(1)
  210. /* Restore FPRs */
  211. lfd 14, (-1 * 8)(4)
  212. lfd 15, (-2 * 8)(4)
  213. lfd 16, (-3 * 8)(4)
  214. lfd 17, (-4 * 8)(4)
  215. lfd 18, (-5 * 8)(4)
  216. lfd 19, (-6 * 8)(4)
  217. lfd 20, (-7 * 8)(4)
  218. lfd 21, (-8 * 8)(4)
  219. lfd 22, (-9 * 8)(4)
  220. lfd 23, (-10 * 8)(4)
  221. lfd 24, (-11 * 8)(4)
  222. lfd 25, (-12 * 8)(4)
  223. lfd 26, (-13 * 8)(4)
  224. lfd 27, (-14 * 8)(4)
  225. lfd 28, (-15 * 8)(4)
  226. lfd 29, (-16 * 8)(4)
  227. lfd 30, (-17 * 8)(4)
  228. lfd 31, (-18 * 8)(4)
  229. /* Set condition and link register */
  230. mtcr 5
  231. mtlr 0
  232. /* Return and switch context */
  233. blr
  234. #elif defined(__mips__) && _MIPS_SIM == _ABIO32
  235. /************************************************************************************
  236. * MIPS ASM BITS
  237. ************************************************************************************/
  238. /**
  239. * Performs a context switch.
  240. *
  241. * $a0 - void** - ptr to old stack pointer
  242. * $a1 - void* - new stack pointer
  243. *
  244. */
  245. .text
  246. .globl fiber_switchContext
  247. fiber_switchContext:
  248. addiu $sp, $sp, -(10 * 4)
  249. // fp regs and return address are stored below the stack
  250. // because we don't want the GC to scan them.
  251. #ifdef __mips_hard_float
  252. #define ALIGN8(val) (val + (-val & 7))
  253. #define BELOW (ALIGN8(6 * 8 + 4))
  254. sdcl $f20, (0 * 8 - BELOW)($sp)
  255. sdcl $f22, (1 * 8 - BELOW)($sp)
  256. sdcl $f24, (2 * 8 - BELOW)($sp)
  257. sdcl $f26, (3 * 8 - BELOW)($sp)
  258. sdcl $f28, (4 * 8 - BELOW)($sp)
  259. sdcl $f30, (5 * 8 - BELOW)($sp)
  260. #endif
  261. sw $ra, -4($sp)
  262. sw $s0, (0 * 4)($sp)
  263. sw $s1, (1 * 4)($sp)
  264. sw $s2, (2 * 4)($sp)
  265. sw $s3, (3 * 4)($sp)
  266. sw $s4, (4 * 4)($sp)
  267. sw $s5, (5 * 4)($sp)
  268. sw $s6, (6 * 4)($sp)
  269. sw $s7, (7 * 4)($sp)
  270. sw $s8, (8 * 4)($sp)
  271. sw $gp, (9 * 4)($sp)
  272. // swap stack pointer
  273. sw $sp, 0($a0)
  274. move $sp, $a1
  275. #ifdef __mips_hard_float
  276. ldcl $f20, (0 * 8 - BELOW)($sp)
  277. ldcl $f22, (1 * 8 - BELOW)($sp)
  278. ldcl $f24, (2 * 8 - BELOW)($sp)
  279. ldcl $f26, (3 * 8 - BELOW)($sp)
  280. ldcl $f28, (4 * 8 - BELOW)($sp)
  281. ldcl $f30, (5 * 8 - BELOW)($sp)
  282. #endif
  283. lw $ra, -4($sp)
  284. lw $s0, (0 * 4)($sp)
  285. lw $s1, (1 * 4)($sp)
  286. lw $s2, (2 * 4)($sp)
  287. lw $s3, (3 * 4)($sp)
  288. lw $s4, (4 * 4)($sp)
  289. lw $s5, (5 * 4)($sp)
  290. lw $s6, (6 * 4)($sp)
  291. lw $s7, (7 * 4)($sp)
  292. lw $s8, (8 * 4)($sp)
  293. lw $gp, (9 * 4)($sp)
  294. addiu $sp, $sp, (10 * 4)
  295. jr $ra // return
  296. #endif