Ginstall_cursor.S 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. /* libunwind - a platform-independent unwind library
  2. Copyright (C) 2001-2003 Hewlett-Packard Co
  3. Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
  4. This file is part of libunwind.
  5. Permission is hereby granted, free of charge, to any person obtaining
  6. a copy of this software and associated documentation files (the
  7. "Software"), to deal in the Software without restriction, including
  8. without limitation the rights to use, copy, modify, merge, publish,
  9. distribute, sublicense, and/or sell copies of the Software, and to
  10. permit persons to whom the Software is furnished to do so, subject to
  11. the following conditions:
  12. The above copyright notice and this permission notice shall be
  13. included in all copies or substantial portions of the Software.
  14. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  15. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  17. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  18. LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  19. OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  20. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  21. #include "ucontext_i.h"
  22. #ifdef UNW_LOCAL_ONLY
  23. # include "Lcursor_i.h"
  24. # define ia64_install_cursor _ULia64_install_cursor
  25. #else
  26. # include "Gcursor_i.h"
  27. # define ia64_install_cursor _Uia64_install_cursor
  28. #endif
  29. #define SYS_sigreturn 1181
  30. #ifndef UNW_REMOTE_ONLY
  31. /* ia64_install_cursor (const cursor *c, long pri_unat, long *extra,
  32. long bspstore, long dirty_size, long *dirty_partition,
  33. long dirty_rnat)
  34. Restores the machine-state represented by C and thereby resumes execution
  35. in that frame. If the frame or one of its descendants was interrupted
  36. by a signal, all registers are restored (including the signal mask).
  37. Otherwise, only the preserved registers, the global-pointer (r1), and
  38. the exception-arguments (r15-r18) are restored. */
  39. #define pRet p6
  40. #define pSig p7
  41. .align 32
  42. .hidden ia64_install_cursor
  43. .global ia64_install_cursor
  44. .proc ia64_install_cursor
  45. ia64_install_cursor:
  46. alloc r3 = ar.pfs, 7, 0, 0, 0
  47. invala
  48. add r2 = FR_LOC_OFF, in0
  49. ;;
  50. ld8 r16 = [r2], LOC_SIZE // r16 = loc[IA64_REG_FR16]
  51. mov.m r10 = ar.rsc // (ar.rsc: ~ 12 cycle latency)
  52. add r3 = FR_LOC_OFF + 16, in0
  53. ;;
  54. ld8 r17 = [r2], 2*LOC_SIZE // r17 = loc[IA64_REG_FR17]
  55. ld8 r18 = [r3], 2*LOC_SIZE // r18 = loc[IA64_REG_FR18]
  56. and r16 = -4, r16
  57. ;;
  58. ld8 r19 = [r2], 2*LOC_SIZE // r19 = loc[IA64_REG_FR19]
  59. ld8 r20 = [r3], 2*LOC_SIZE // r20 = loc[IA64_REG_FR20]
  60. and r17 = -4, r17
  61. ;;
  62. ldf.fill f16 = [r16] // f16 restored (don't touch no more)
  63. ldf.fill f17 = [r17] // f17 restored (don't touch no more)
  64. and r18 = -4, r18
  65. ld8 r21 = [r2], 2*LOC_SIZE // r21 = loc[IA64_REG_FR21]
  66. ld8 r22 = [r3], 2*LOC_SIZE // r22 = loc[IA64_REG_FR22]
  67. and r19 = -4, r19
  68. ;;
  69. ldf.fill f18 = [r18] // f18 restored (don't touch no more)
  70. ldf.fill f19 = [r19] // f19 restored (don't touch no more)
  71. and r20 = -4, r20
  72. ld8 r23 = [r2], 2*LOC_SIZE // r23 = loc[IA64_REG_FR23]
  73. ld8 r24 = [r3], 2*LOC_SIZE // r24 = loc[IA64_REG_FR24]
  74. and r21 = -4, r21
  75. ;;
  76. ldf.fill f20 = [r20] // f20 restored (don't touch no more)
  77. ldf.fill f21 = [r21] // f21 restored (don't touch no more)
  78. and r22 = -4, r22
  79. ld8 r25 = [r2], 2*LOC_SIZE // r25 = loc[IA64_REG_FR25]
  80. ld8 r26 = [r3], 2*LOC_SIZE // r26 = loc[IA64_REG_FR26]
  81. and r23 = -4, r23
  82. ;;
  83. ldf.fill f22 = [r22] // f22 restored (don't touch no more)
  84. ldf.fill f23 = [r23] // f23 restored (don't touch no more)
  85. and r24 = -4, r24
  86. ld8 r27 = [r2], 2*LOC_SIZE // r27 = loc[IA64_REG_FR27]
  87. ld8 r28 = [r3], 2*LOC_SIZE // r28 = loc[IA64_REG_FR28]
  88. and r25 = -4, r25
  89. ;;
  90. ldf.fill f24 = [r24] // f24 restored (don't touch no more)
  91. ldf.fill f25 = [r25] // f25 restored (don't touch no more)
  92. and r26 = -4, r26
  93. ld8 r29 = [r2], 2*LOC_SIZE // r29 = loc[IA64_REG_FR29]
  94. ld8 r30 = [r3], 2*LOC_SIZE // r30 = loc[IA64_REG_FR30]
  95. and r27 = -4, r27
  96. ;;
  97. ldf.fill f26 = [r26] // f26 restored (don't touch no more)
  98. ldf.fill f27 = [r27] // f27 restored (don't touch no more)
  99. and r28 = -4, r28
  100. ld8 r31 = [r2] // r31 = loc[IA64_REG_FR31]
  101. mov.m ar.unat = in1
  102. and r29 = -4, r29
  103. ;;
  104. ldf.fill f28 = [r28] // f28 restored (don't touch no more)
  105. ldf.fill f29 = [r29] // f29 restored (don't touch no more)
  106. and r30 = -4, r30
  107. ld8 r1 = [in2], 8 // gp restored (don't touch no more)
  108. add r8 = SIGCONTEXT_ADDR_OFF, in0
  109. and r31 = -4, r31
  110. ;;
  111. ld8 r8 = [r8] // r8 = sigcontext_addr
  112. and r11 = 0x1c, r10 // clear all but rsc.be and rsc.pl
  113. add r2 = PFS_LOC_OFF, in0
  114. ldf.fill f30 = [r30] // f30 restored (don't touch no more)
  115. ldf.fill f31 = [r31] // f31 restored (don't touch no more)
  116. add r3 = 8, in2
  117. ;;
  118. ld8.fill r4 = [in2], 16 // r4 restored (don't touch no more)
  119. ld8.fill r5 = [r3], 16 // r5 restored (don't touch no more)
  120. cmp.eq pRet, pSig = r0, r8 // sigcontext_addr == NULL?
  121. ;;
  122. ld8.fill r6 = [in2], 16 // r6 restored (don't touch no more)
  123. ld8.fill r7 = [r3] // r7 restored (don't touch no more)
  124. add r3 = IP_OFF, in0
  125. ;;
  126. ld8 r14 = [r2], (B1_LOC_OFF - PFS_LOC_OFF) // r14 = pfs_loc
  127. ld8 r15 = [r3] // r15 = ip
  128. add r3 = (B2_LOC_OFF - IP_OFF), r3
  129. ;;
  130. ld8 r16 = [r2], (B3_LOC_OFF - B1_LOC_OFF) // r16 = b1_loc
  131. ld8 r17= [r3], (B4_LOC_OFF - B2_LOC_OFF) // r17 = b2_loc
  132. and r14 = -4, r14
  133. ;;
  134. ld8 r18 = [r2], (B5_LOC_OFF - B3_LOC_OFF) // r18 = b3_loc
  135. ld8 r19 = [r3], (F2_LOC_OFF - B4_LOC_OFF) // r19 = b4_loc
  136. and r16 = -4, r16
  137. ;;
  138. ld8 r20 = [r2], (F3_LOC_OFF - B5_LOC_OFF) // r20 = b5_loc
  139. ld8 r21 = [r3], (F4_LOC_OFF - F2_LOC_OFF) // r21 = f2_loc
  140. and r17 = -4, r17
  141. ;;
  142. ld8 r16 = [r16] // r16 = *b1_loc
  143. ld8 r17 = [r17] // r17 = *b2_loc
  144. and r18 = -4, r18
  145. ld8 r22 = [r2], (F5_LOC_OFF - F3_LOC_OFF) // r21 = f3_loc
  146. ld8 r23 = [r3], (UNAT_LOC_OFF - F4_LOC_OFF) // r22 = f4_loc
  147. and r19 = -4, r19
  148. ;;
  149. ld8 r18 = [r18] // r18 = *b3_loc
  150. ld8 r19 = [r19] // r19 = *b4_loc
  151. and r20 = -4, r20
  152. ld8 r24 = [r2], (LC_LOC_OFF - F5_LOC_OFF) // r24 = f5_loc
  153. ld8 r25 = [r3], (FPSR_LOC_OFF - UNAT_LOC_OFF) // r25 = unat_loc
  154. and r21 = -4, r21
  155. ;;
  156. and r22 = -4, r22
  157. and r23 = -4, r23
  158. and r24 = -4, r24
  159. ld8 r20 = [r20] // r20 = *b5_loc
  160. ldf.fill f2 = [r21] // f2 restored (don't touch no more)
  161. mov b1 = r16 // b1 restored (don't touch no more)
  162. ;;
  163. ldf.fill f3 = [r22] // f3 restored (don't touch no more)
  164. ldf.fill f4 = [r23] // f4 restored (don't touch no more)
  165. mov b2 = r17 // b2 restored (don't touch no more)
  166. ld8 r26 = [r2], (RNAT_LOC_OFF - LC_LOC_OFF) // r26 = lc_loc
  167. ld8 r27 = [r3] // r27 = fpsr_loc
  168. and r25 = -4, r25
  169. add r3 = (PSP_OFF - FPSR_LOC_OFF), r3
  170. nop 0
  171. nop 0
  172. ;;
  173. ldf.fill f5 = [r24] // f5 restored (don't touch no more)
  174. (pRet) ld8 r25 = [r25] // r25 = *unat_loc
  175. mov b3 = r18 // b3 restored (don't touch no more)
  176. ld8 r28 = [r2], (BSP_OFF - RNAT_LOC_OFF) // r28 = rnat_loc
  177. ld8 r29 = [r3], (PR_OFF - PSP_OFF) // r29 = sp
  178. mov b4 = r19 // b4 restored (don't touch no more)
  179. and r26 = -4, r26
  180. and r27 = -4, r27
  181. mov b5 = r20 // b5 restored (don't touch no more)
  182. ;;
  183. ld8 r26 = [r26] // r26 = *lc_loc
  184. ld8 r27 = [r27] // r27 = *fpsr_loc
  185. and r28 = -4, r28
  186. mov r30 = in3 // make backup-copy of new bsp
  187. ld8 r31 = [r3] // r31 = pr
  188. mov rp = r15
  189. ;;
  190. ld8 r28 = [r28] // r28 = rnat
  191. mov.m ar.rsc = r11 // put RSE into enforced lazy mode
  192. mov.i ar.lc = r26 // lc restored (don't touch no more)
  193. ;;
  194. loadrs // drop dirty partition
  195. mov r9 = in2 // make backup-copy of &extra[r16]
  196. cmp.eq p8, p0 = in4, r0 // dirty-size == 0?
  197. (p8) br.cond.dpnt.many .skip_load_dirty
  198. mov r2 = in4 // make backup-copy of dirty_size
  199. mov r15 = in5 // make backup-copy of dirty_partition
  200. mov r16 = in6 // make backup-copy of dirty_rnat
  201. ;;
  202. alloc r3 = ar.pfs, 0, 0, 0, 0 // drop register frame
  203. dep r11 = r2, r11, 16, 16
  204. ;;
  205. mov.m ar.bspstore = r15
  206. ;;
  207. mov.m ar.rnat = r16
  208. mov.m ar.rsc = r11 // 14 cycles latency to loadrs
  209. ;;
  210. loadrs // loadup new dirty partition
  211. ;;
  212. .skip_load_dirty:
  213. mov.m ar.bspstore = r30 // restore register backing-store
  214. add r3 = 8, r9 // r3 = &extra[r16]
  215. ;;
  216. (pRet) mov.m ar.fpsr = r27 // fpsr restored (don't touch no more)
  217. mov.m ar.rnat = r28
  218. (pSig) br.cond.dpnt.many .next
  219. /****** Return via br.ret: */
  220. ld8 r14 = [r14] // r14 = *pfs_loc
  221. ld8 r15 = [r9], 16 // r15 restored (don't touch no more)
  222. mov pr = r31, -1 // pr restored (don't touch no more)
  223. ;;
  224. ld8 r16 = [r3], 16 // r16 restored (don't touch no more)
  225. ld8 r17 = [r9] // r17 restored (don't touch no more)
  226. nop.i 0
  227. ;;
  228. ld8 r18 = [r3] // r18 restored (don't touch no more)
  229. mov.m ar.rsc = r10 // restore original ar.rsc
  230. mov sp = r29
  231. mov.m ar.unat = r25 // unat restored (don't touch no more)
  232. mov.i ar.pfs = r14
  233. br.ret.sptk.many rp
  234. ;;
  235. /****** Return via sigreturn(): */
  236. .next: mov.m ar.rsc = r10 // restore original ar.rsc
  237. add r2 = (SC_FR + 6*16), r8
  238. add r3 = (SC_FR + 7*16), r8
  239. ;;
  240. ldf.fill f6 = [r2], 32
  241. ldf.fill f7 = [r3], 32
  242. nop 0
  243. ;;
  244. ldf.fill f8 = [r2], 32
  245. ldf.fill f9 = [r3], 32
  246. nop 0
  247. ;;
  248. ldf.fill f10 = [r2], 32
  249. ldf.fill f11 = [r3], 32
  250. nop 0
  251. ;;
  252. ldf.fill f12 = [r2], 32
  253. ldf.fill f13 = [r3], 32
  254. nop 0
  255. ;;
  256. ldf.fill f14 = [r2], 32
  257. ldf.fill f15 = [r3], 32
  258. mov sp = r29
  259. ;;
  260. #if NEW_SYSCALL
  261. add r2 = 8, tp;;
  262. ld8 r2 = [r2]
  263. mov r15 = SYS_sigreturn
  264. mov b7 = r2
  265. br.call.sptk.many b6 = b7
  266. ;;
  267. #else
  268. mov r15 = SYS_sigreturn
  269. break 0x100000
  270. #endif
  271. break 0 // bug out if sigreturn() returns
  272. .endp ia64_install_cursor
  273. #endif /* !UNW_REMOTE_ONLY */
  274. #ifdef __linux__
  275. /* We do not need executable stack. */
  276. .section .note.GNU-stack,"",@progbits
  277. #endif