• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5This file is part of libunwind.
6
7Permission is hereby granted, free of charge, to any person obtaining
8a copy of this software and associated documentation files (the
9"Software"), to deal in the Software without restriction, including
10without limitation the rights to use, copy, modify, merge, publish,
11distribute, sublicense, and/or sell copies of the Software, and to
12permit persons to whom the Software is furnished to do so, subject to
13the following conditions:
14
15The above copyright notice and this permission notice shall be
16included in all copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
25
26#include "ucontext_i.h"
27
28#ifdef UNW_LOCAL_ONLY
29# include "Lcursor_i.h"
30# define ia64_install_cursor	_ULia64_install_cursor
31#else
32# include "Gcursor_i.h"
33# define ia64_install_cursor	_Uia64_install_cursor
34#endif
35
36#define SYS_sigreturn	1181
37
38#ifndef UNW_REMOTE_ONLY
39
40/*  ia64_install_cursor (const cursor *c, long pri_unat, long *extra,
41			 long bspstore, long dirty_size, long *dirty_partition,
42			 long dirty_rnat)
43
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.  */
49
50#define pRet	p6
51#define pSig	p7
52
53	.align 32
54	.hidden ia64_install_cursor
55	.global ia64_install_cursor
56	.proc ia64_install_cursor
57ia64_install_cursor:
58	alloc r3 = ar.pfs, 7, 0, 0, 0
59	invala
60	add r2 = FR_LOC_OFF, in0
61	;;
62
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
66	;;
67
68	ld8 r17 = [r2], 2*LOC_SIZE	// r17 = loc[IA64_REG_FR17]
69	ld8 r18 = [r3], 2*LOC_SIZE	// r18 = loc[IA64_REG_FR18]
70	and r16 = -4, r16
71	;;
72
73	ld8 r19 = [r2], 2*LOC_SIZE	// r19 = loc[IA64_REG_FR19]
74	ld8 r20 = [r3], 2*LOC_SIZE	// r20 = loc[IA64_REG_FR20]
75	and r17 = -4, r17
76	;;
77
78	ldf.fill f16 = [r16]		// f16 restored (don't touch no more)
79	ldf.fill f17 = [r17]		// f17 restored (don't touch no more)
80	and r18 = -4, r18
81
82	ld8 r21 = [r2], 2*LOC_SIZE	// r21 = loc[IA64_REG_FR21]
83	ld8 r22 = [r3], 2*LOC_SIZE	// r22 = loc[IA64_REG_FR22]
84	and r19 = -4, r19
85	;;
86
87	ldf.fill f18 = [r18]		// f18 restored (don't touch no more)
88	ldf.fill f19 = [r19]		// f19 restored (don't touch no more)
89	and r20 = -4, r20
90
91	ld8 r23 = [r2], 2*LOC_SIZE	// r23 = loc[IA64_REG_FR23]
92	ld8 r24 = [r3], 2*LOC_SIZE	// r24 = loc[IA64_REG_FR24]
93	and r21 = -4, r21
94	;;
95
96	ldf.fill f20 = [r20]		// f20 restored (don't touch no more)
97	ldf.fill f21 = [r21]		// f21 restored (don't touch no more)
98	and r22 = -4, r22
99
100	ld8 r25 = [r2], 2*LOC_SIZE	// r25 = loc[IA64_REG_FR25]
101	ld8 r26 = [r3], 2*LOC_SIZE	// r26 = loc[IA64_REG_FR26]
102	and r23 = -4, r23
103	;;
104
105	ldf.fill f22 = [r22]		// f22 restored (don't touch no more)
106	ldf.fill f23 = [r23]		// f23 restored (don't touch no more)
107	and r24 = -4, r24
108
109	ld8 r27 = [r2], 2*LOC_SIZE	// r27 = loc[IA64_REG_FR27]
110	ld8 r28 = [r3], 2*LOC_SIZE	// r28 = loc[IA64_REG_FR28]
111	and r25 = -4, r25
112	;;
113
114	ldf.fill f24 = [r24]		// f24 restored (don't touch no more)
115	ldf.fill f25 = [r25]		// f25 restored (don't touch no more)
116	and r26 = -4, r26
117
118	ld8 r29 = [r2], 2*LOC_SIZE	// r29 = loc[IA64_REG_FR29]
119	ld8 r30 = [r3], 2*LOC_SIZE	// r30 = loc[IA64_REG_FR30]
120	and r27 = -4, r27
121	;;
122
123	ldf.fill f26 = [r26]		// f26 restored (don't touch no more)
124	ldf.fill f27 = [r27]		// f27 restored (don't touch no more)
125	and r28 = -4, r28
126
127	ld8 r31 = [r2]			// r31 = loc[IA64_REG_FR31]
128	mov.m ar.unat = in1
129	and r29 = -4, r29
130	;;
131
132	ldf.fill f28 = [r28]		// f28 restored (don't touch no more)
133	ldf.fill f29 = [r29]		// f29 restored (don't touch no more)
134	and r30 = -4, r30
135
136	ld8 r1 = [in2], 8		// gp restored (don't touch no more)
137	add r8 = SIGCONTEXT_ADDR_OFF, in0
138	and r31 = -4, r31
139	;;
140
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
144
145	ldf.fill f30 = [r30]		// f30 restored (don't touch no more)
146	ldf.fill f31 = [r31]		// f31 restored (don't touch no more)
147	add r3 = 8, in2
148	;;
149
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?
153	;;
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)
156	add r3 = IP_OFF, in0
157	;;
158
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
162	;;
163
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
166	and r14 = -4, r14
167	;;
168
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
171	and r16 = -4, r16
172	;;
173
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
176	and r17 = -4, r17
177	;;
178
179	ld8 r16 = [r16]			// r16 = *b1_loc
180	ld8 r17 = [r17]			// r17 = *b2_loc
181	and r18 = -4, r18
182
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
185	and r19 = -4, r19
186	;;
187
188	ld8 r18 = [r18]			// r18 = *b3_loc
189	ld8 r19 = [r19]			// r19 = *b4_loc
190	and r20 = -4, r20
191
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
194	and r21 = -4, r21
195	;;
196
197	and r22 = -4, r22
198	and r23 = -4, r23
199	and r24 = -4, r24
200
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)
204	;;
205
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)
209
210	ld8 r26 = [r2], (RNAT_LOC_OFF - LC_LOC_OFF)	// r26 = lc_loc
211	ld8 r27 = [r3]			// r27 = fpsr_loc
212	and r25 = -4, r25
213
214	add r3 = (PSP_OFF - FPSR_LOC_OFF), r3
215	nop 0
216	nop 0
217	;;
218
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)
222
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)
226
227	and r26 = -4, r26
228	and r27 = -4, r27
229	mov b5 = r20			// b5 restored (don't touch no more)
230	;;
231
232	ld8 r26 = [r26]			// r26 = *lc_loc
233	ld8 r27 = [r27]			// r27 = *fpsr_loc
234	and r28 = -4, r28
235
236	mov r30 = in3			// make backup-copy of new bsp
237	ld8 r31 = [r3]			// r31 = pr
238	mov rp = r15
239	;;
240
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)
244	;;
245
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
250
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
254	;;
255
256	alloc r3 = ar.pfs, 0, 0, 0, 0	// drop register frame
257	dep r11 = r2, r11, 16, 16
258	;;
259	mov.m ar.bspstore = r15
260	;;
261	mov.m ar.rnat = r16
262	mov.m ar.rsc = r11		// 14 cycles latency to loadrs
263	;;
264	loadrs				// loadup new dirty partition
265	;;
266
267.skip_load_dirty:
268	mov.m ar.bspstore = r30		// restore register backing-store
269	add r3 = 8, r9			// r3 = &extra[r16]
270	;;
271
272(pRet)	mov.m ar.fpsr = r27		// fpsr restored (don't touch no more)
273	mov.m ar.rnat = r28
274(pSig)	br.cond.dpnt.many .next
275
276/****** Return via br.ret: */
277
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)
281	;;
282
283	ld8 r16 = [r3], 16		// r16 restored (don't touch no more)
284	ld8 r17 = [r9]			// r17 restored (don't touch no more)
285	nop.i 0
286	;;
287
288	ld8 r18 = [r3]			// r18 restored (don't touch no more)
289	mov.m ar.rsc = r10		// restore original ar.rsc
290	mov sp = r29
291
292	mov.m ar.unat = r25		// unat restored (don't touch no more)
293	mov.i ar.pfs = r14
294	br.ret.sptk.many rp
295	;;
296
297/****** Return via sigreturn(): */
298
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
302	;;
303
304	ldf.fill f6 = [r2], 32
305	ldf.fill f7 = [r3], 32
306	nop 0
307	;;
308
309	ldf.fill f8 = [r2], 32
310	ldf.fill f9 = [r3], 32
311	nop 0
312	;;
313
314	ldf.fill f10 = [r2], 32
315	ldf.fill f11 = [r3], 32
316	nop 0
317	;;
318
319	ldf.fill f12 = [r2], 32
320	ldf.fill f13 = [r3], 32
321	nop 0
322	;;
323
324	ldf.fill f14 = [r2], 32
325	ldf.fill f15 = [r3], 32
326	mov sp = r29
327	;;
328
329#if NEW_SYSCALL
330	add r2 = 8, tp;;
331	ld8 r2 = [r2]
332	mov r15 = SYS_sigreturn
333	mov b7 = r2
334	br.call.sptk.many b6 = b7
335	;;
336#else
337	mov r15 = SYS_sigreturn
338	break 0x100000
339#endif
340	break 0				// bug out if sigreturn() returns
341
342	.endp ia64_install_cursor
343
344#endif /* !UNW_REMOTE_ONLY */
345#ifdef __linux__
346	/* We do not need executable stack.  */
347	.section	.note.GNU-stack,"",@progbits
348#endif
349