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>
5 This file is part of libunwind.
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
15 The above copyright notice and this permission notice shall be
16 included in all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
26 #include "ucontext_i.h"
29 # include "Lcursor_i.h"
30 # define ia64_install_cursor _ULia64_install_cursor
32 # include "Gcursor_i.h"
33 # define ia64_install_cursor _Uia64_install_cursor
36 #define SYS_sigreturn 1181
38 #ifndef UNW_REMOTE_ONLY
40 /* ia64_install_cursor (const cursor *c, long pri_unat, long *extra,
41 long bspstore, long dirty_size, long *dirty_partition,
44 Restores the machine-state represented by C and thereby resumes execution
45 in that frame. If the frame or one of its descendants was interrupted
46 by a signal, all registers are restored (including the signal mask).
47 Otherwise, only the preserved registers, the global-pointer (r1), and
48 the exception-arguments (r15-r18) are restored. */
54 .hidden ia64_install_cursor
55 .global ia64_install_cursor
56 .proc ia64_install_cursor
58 alloc r3 = ar.pfs, 7, 0, 0, 0
60 add r2 = FR_LOC_OFF, in0
63 ld8 r16 = [r2], LOC_SIZE // r16 = loc[IA64_REG_FR16]
64 mov.m r10 = ar.rsc // (ar.rsc: ~ 12 cycle latency)
65 add r3 = FR_LOC_OFF + 16, in0
68 ld8 r17 = [r2], 2*LOC_SIZE // r17 = loc[IA64_REG_FR17]
69 ld8 r18 = [r3], 2*LOC_SIZE // r18 = loc[IA64_REG_FR18]
73 ld8 r19 = [r2], 2*LOC_SIZE // r19 = loc[IA64_REG_FR19]
74 ld8 r20 = [r3], 2*LOC_SIZE // r20 = loc[IA64_REG_FR20]
78 ldf.fill f16 = [r16] // f16 restored (don't touch no more)
79 ldf.fill f17 = [r17] // f17 restored (don't touch no more)
82 ld8 r21 = [r2], 2*LOC_SIZE // r21 = loc[IA64_REG_FR21]
83 ld8 r22 = [r3], 2*LOC_SIZE // r22 = loc[IA64_REG_FR22]
87 ldf.fill f18 = [r18] // f18 restored (don't touch no more)
88 ldf.fill f19 = [r19] // f19 restored (don't touch no more)
91 ld8 r23 = [r2], 2*LOC_SIZE // r23 = loc[IA64_REG_FR23]
92 ld8 r24 = [r3], 2*LOC_SIZE // r24 = loc[IA64_REG_FR24]
96 ldf.fill f20 = [r20] // f20 restored (don't touch no more)
97 ldf.fill f21 = [r21] // f21 restored (don't touch no more)
100 ld8 r25 = [r2], 2*LOC_SIZE // r25 = loc[IA64_REG_FR25]
101 ld8 r26 = [r3], 2*LOC_SIZE // r26 = loc[IA64_REG_FR26]
105 ldf.fill f22 = [r22] // f22 restored (don't touch no more)
106 ldf.fill f23 = [r23] // f23 restored (don't touch no more)
109 ld8 r27 = [r2], 2*LOC_SIZE // r27 = loc[IA64_REG_FR27]
110 ld8 r28 = [r3], 2*LOC_SIZE // r28 = loc[IA64_REG_FR28]
114 ldf.fill f24 = [r24] // f24 restored (don't touch no more)
115 ldf.fill f25 = [r25] // f25 restored (don't touch no more)
118 ld8 r29 = [r2], 2*LOC_SIZE // r29 = loc[IA64_REG_FR29]
119 ld8 r30 = [r3], 2*LOC_SIZE // r30 = loc[IA64_REG_FR30]
123 ldf.fill f26 = [r26] // f26 restored (don't touch no more)
124 ldf.fill f27 = [r27] // f27 restored (don't touch no more)
127 ld8 r31 = [r2] // r31 = loc[IA64_REG_FR31]
132 ldf.fill f28 = [r28] // f28 restored (don't touch no more)
133 ldf.fill f29 = [r29] // f29 restored (don't touch no more)
136 ld8 r1 = [in2], 8 // gp restored (don't touch no more)
137 add r8 = SIGCONTEXT_ADDR_OFF, in0
141 ld8 r8 = [r8] // r8 = sigcontext_addr
142 and r11 = 0x1c, r10 // clear all but rsc.be and rsc.pl
143 add r2 = PFS_LOC_OFF, in0
145 ldf.fill f30 = [r30] // f30 restored (don't touch no more)
146 ldf.fill f31 = [r31] // f31 restored (don't touch no more)
150 ld8.fill r4 = [in2], 16 // r4 restored (don't touch no more)
151 ld8.fill r5 = [r3], 16 // r5 restored (don't touch no more)
152 cmp.eq pRet, pSig = r0, r8 // sigcontext_addr == NULL?
154 ld8.fill r6 = [in2], 16 // r6 restored (don't touch no more)
155 ld8.fill r7 = [r3] // r7 restored (don't touch no more)
159 ld8 r14 = [r2], (B1_LOC_OFF - PFS_LOC_OFF) // r14 = pfs_loc
160 ld8 r15 = [r3] // r15 = ip
161 add r3 = (B2_LOC_OFF - IP_OFF), r3
164 ld8 r16 = [r2], (B3_LOC_OFF - B1_LOC_OFF) // r16 = b1_loc
165 ld8 r17= [r3], (B4_LOC_OFF - B2_LOC_OFF) // r17 = b2_loc
169 ld8 r18 = [r2], (B5_LOC_OFF - B3_LOC_OFF) // r18 = b3_loc
170 ld8 r19 = [r3], (F2_LOC_OFF - B4_LOC_OFF) // r19 = b4_loc
174 ld8 r20 = [r2], (F3_LOC_OFF - B5_LOC_OFF) // r20 = b5_loc
175 ld8 r21 = [r3], (F4_LOC_OFF - F2_LOC_OFF) // r21 = f2_loc
179 ld8 r16 = [r16] // r16 = *b1_loc
180 ld8 r17 = [r17] // r17 = *b2_loc
183 ld8 r22 = [r2], (F5_LOC_OFF - F3_LOC_OFF) // r21 = f3_loc
184 ld8 r23 = [r3], (UNAT_LOC_OFF - F4_LOC_OFF) // r22 = f4_loc
188 ld8 r18 = [r18] // r18 = *b3_loc
189 ld8 r19 = [r19] // r19 = *b4_loc
192 ld8 r24 = [r2], (LC_LOC_OFF - F5_LOC_OFF) // r24 = f5_loc
193 ld8 r25 = [r3], (FPSR_LOC_OFF - UNAT_LOC_OFF) // r25 = unat_loc
201 ld8 r20 = [r20] // r20 = *b5_loc
202 ldf.fill f2 = [r21] // f2 restored (don't touch no more)
203 mov b1 = r16 // b1 restored (don't touch no more)
206 ldf.fill f3 = [r22] // f3 restored (don't touch no more)
207 ldf.fill f4 = [r23] // f4 restored (don't touch no more)
208 mov b2 = r17 // b2 restored (don't touch no more)
210 ld8 r26 = [r2], (RNAT_LOC_OFF - LC_LOC_OFF) // r26 = lc_loc
211 ld8 r27 = [r3] // r27 = fpsr_loc
214 add r3 = (PSP_OFF - FPSR_LOC_OFF), r3
219 ldf.fill f5 = [r24] // f5 restored (don't touch no more)
220 (pRet) ld8 r25 = [r25] // r25 = *unat_loc
221 mov b3 = r18 // b3 restored (don't touch no more)
223 ld8 r28 = [r2], (BSP_OFF - RNAT_LOC_OFF) // r28 = rnat_loc
224 ld8 r29 = [r3], (PR_OFF - PSP_OFF) // r29 = sp
225 mov b4 = r19 // b4 restored (don't touch no more)
229 mov b5 = r20 // b5 restored (don't touch no more)
232 ld8 r26 = [r26] // r26 = *lc_loc
233 ld8 r27 = [r27] // r27 = *fpsr_loc
236 mov r30 = in3 // make backup-copy of new bsp
237 ld8 r31 = [r3] // r31 = pr
241 ld8 r28 = [r28] // r28 = rnat
242 mov.m ar.rsc = r11 // put RSE into enforced lazy mode
243 mov.i ar.lc = r26 // lc restored (don't touch no more)
246 loadrs // drop dirty partition
247 mov r9 = in2 // make backup-copy of &extra[r16]
248 cmp.eq p8, p0 = in4, r0 // dirty-size == 0?
249 (p8) br.cond.dpnt.many .skip_load_dirty
251 mov r2 = in4 // make backup-copy of dirty_size
252 mov r15 = in5 // make backup-copy of dirty_partition
253 mov r16 = in6 // make backup-copy of dirty_rnat
256 alloc r3 = ar.pfs, 0, 0, 0, 0 // drop register frame
257 dep r11 = r2, r11, 16, 16
259 mov.m ar.bspstore = r15
262 mov.m ar.rsc = r11 // 14 cycles latency to loadrs
264 loadrs // loadup new dirty partition
268 mov.m ar.bspstore = r30 // restore register backing-store
269 add r3 = 8, r9 // r3 = &extra[r16]
272 (pRet) mov.m ar.fpsr = r27 // fpsr restored (don't touch no more)
274 (pSig) br.cond.dpnt.many .next
276 /****** Return via br.ret: */
278 ld8 r14 = [r14] // r14 = *pfs_loc
279 ld8 r15 = [r9], 16 // r15 restored (don't touch no more)
280 mov pr = r31, -1 // pr restored (don't touch no more)
283 ld8 r16 = [r3], 16 // r16 restored (don't touch no more)
284 ld8 r17 = [r9] // r17 restored (don't touch no more)
288 ld8 r18 = [r3] // r18 restored (don't touch no more)
289 mov.m ar.rsc = r10 // restore original ar.rsc
292 mov.m ar.unat = r25 // unat restored (don't touch no more)
297 /****** Return via sigreturn(): */
299 .next: mov.m ar.rsc = r10 // restore original ar.rsc
300 add r2 = (SC_FR + 6*16), r8
301 add r3 = (SC_FR + 7*16), r8
304 ldf.fill f6 = [r2], 32
305 ldf.fill f7 = [r3], 32
309 ldf.fill f8 = [r2], 32
310 ldf.fill f9 = [r3], 32
314 ldf.fill f10 = [r2], 32
315 ldf.fill f11 = [r3], 32
319 ldf.fill f12 = [r2], 32
320 ldf.fill f13 = [r3], 32
324 ldf.fill f14 = [r2], 32
325 ldf.fill f15 = [r3], 32
332 mov r15 = SYS_sigreturn
334 br.call.sptk.many b6 = b7
337 mov r15 = SYS_sigreturn
340 break 0 // bug out if sigreturn() returns
342 .endp ia64_install_cursor
344 #endif /* !UNW_REMOTE_ONLY */
346 /* We do not need executable stack. */
347 .section .note.GNU-stack,"",@progbits