xref: /netbsd/sys/arch/ia64/ia64/context.S (revision 1461fe36)
1/*	$NetBSD: context.S,v 1.8 2017/04/08 17:38:43 scole Exp $	*/
2
3/*
4 * Copyright (c) 2003 Marcel Moolenaar
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $FreeBSD: releng/10.1/sys/ia64/ia64/context.S 204184 2010-02-22 01:23:41Z marcel $
29 */
30
31#include <machine/asm.h>
32#include "assym.h"
33
34	.text
35
36/*
37 * void restorectx(struct pcb *)
38 */
39ENTRY(restorectx, 1)
40{	.mmi
41	invala
42	mov		ar.rsc=0
43	add		r31=8,r32
44	;;
45}
46{	.mmi
47	ld8		r12=[r32]		// sp
48	ld8		r16=[r31],16		// unat (before)
49	add		r30=16,r32
50	;;
51}
52{	.mmi
53	ld8		r17=[r30],16		// rp
54	ld8		r18=[r31],16		// pr
55	add		r14=SIZEOF_SPECIAL,r32
56	;;
57}
58{	.mmi
59	ld8		r19=[r30],16		// pfs
60	ld8		r20=[r31],16		// bspstore
61	mov		rp=r17
62	;;
63}
64{	.mmi
65	loadrs
66	ld8		r21=[r30],16		// rnat
67	mov		pr=r18,0x1fffe
68	;;
69}
70{	.mmi
71	ld8		r17=[r14],8		// unat (after)
72	mov		ar.bspstore=r20
73	mov		ar.pfs=r19
74	;;
75}
76{	.mmi
77	mov		ar.unat=r17
78	mov		ar.rnat=r21
79	add		r15=8,r14
80	;;
81}
82{	.mmi
83	ld8.fill	r4=[r14],16		// r4
84	ld8.fill	r5=[r15],16		// r5
85	nop		0
86	;;
87}
88{	.mmi
89	ld8.fill	r6=[r14],16		// r6
90	ld8.fill	r7=[r15],16		// r7
91	nop		0
92	;;
93}
94{	.mmi
95	mov		ar.unat=r16
96	mov		ar.rsc=3
97	nop		0
98}
99{	.mmi
100	ld8		r17=[r14],16		// b1
101	ld8		r18=[r15],16		// b2
102	nop		0
103	;;
104}
105{	.mmi
106	ld8		r19=[r14],16		// b3
107	ld8		r20=[r15],16		// b4
108	mov		b1=r17
109	;;
110}
111{	.mmi
112	ld8		r16=[r14],24		// b5
113	ld8		r17=[r15],32		// lc
114	mov		b2=r18
115	;;
116}
117{	.mmi
118	ldf.fill	f2=[r14],32
119	ldf.fill	f3=[r15],32
120	mov		b3=r19
121	;;
122}
123{	.mmi
124	ldf.fill	f4=[r14],32
125	ldf.fill	f5=[r15],32
126	mov		b4=r20
127	;;
128}
129{	.mmi
130	ldf.fill	f16=[r14],32
131	ldf.fill	f17=[r15],32
132	mov		b5=r16
133	;;
134}
135{	.mmi
136	ldf.fill	f18=[r14],32
137	ldf.fill	f19=[r15],32
138	mov		ar.lc=r17
139	;;
140}
141	ldf.fill	f20=[r14],32
142	ldf.fill	f21=[r15],32
143	;;
144	ldf.fill	f22=[r14],32
145	ldf.fill	f23=[r15],32
146	;;
147	ldf.fill	f24=[r14],32
148	ldf.fill	f25=[r15],32
149	;;
150	ldf.fill	f26=[r14],32
151	ldf.fill	f27=[r15],32
152	;;
153{	.mmi
154	ldf.fill	f28=[r14],32
155	ldf.fill	f29=[r15],32
156	add		r8=1,r0
157	;;
158}
159{	.mmb
160	ldf.fill	f30=[r14]
161	ldf.fill	f31=[r15]
162	br.ret.sptk	rp
163	;;
164}
165END(restorectx)
166
167/*
168 * void swapctx(struct pcb *old, struct pcb *new)
169 */
170
171ENTRY(swapctx, 2)
172{	.mmi
173	mov		ar.rsc=0
174	mov		r16=ar.unat
175	add		r31=8,r32
176	;;
177}
178{	.mmi
179	flushrs
180	st8		[r32]=sp,16		// sp
181	mov		r17=rp
182	;;
183}
184{	.mmi
185	st8		[r31]=r16,16		// unat (before)
186	st8		[r32]=r17,16		// rp
187	mov		r16=pr
188	;;
189}
190{	.mmi
191	st8		[r31]=r16,16		// pr
192	mov		r17=ar.bsp
193	mov		r16=ar.pfs
194	;;
195}
196{	.mmi
197	st8		[r32]=r16,16		// pfs
198	st8		[r31]=r17,16		// bspstore
199	cmp.eq		p15,p0=0,r33
200	;;
201}
202{	.mmi
203	mov		r16=ar.rnat
204(p15)	mov		ar.rsc=3
205	add		r30=SIZEOF_SPECIAL-(6*8),r32
206	;;
207}
208{	.mmi
209	st8		[r32]=r16,SIZEOF_SPECIAL-(4*8)		// rnat
210	st8		[r31]=r0,SIZEOF_SPECIAL-(6*8)		// __spare
211	mov		r16=b1
212	;;
213}
214	/* callee_saved */
215{	.mmi
216	.mem.offset	8,0
217	st8.spill	[r31]=r4,16		// r4
218	.mem.offset	16,0
219	st8.spill	[r32]=r5,16		// r5
220	mov		r17=b2
221	;;
222}
223{	.mmi
224	.mem.offset	24,0
225	st8.spill	[r31]=r6,16		// r6
226	.mem.offset	32,0
227	st8.spill	[r32]=r7,16		// r7
228	mov		r18=b3
229	;;
230}
231{	.mmi
232	st8		[r31]=r16,16		// b1
233	mov		r16=ar.unat
234	mov		r19=b4
235	;;
236}
237{	.mmi
238	st8		[r30]=r16		// unat (after)
239	st8		[r32]=r17,16		// b2
240	mov		r16=b5
241	;;
242}
243{	.mmi
244	st8		[r31]=r18,16		// b3
245	st8		[r32]=r19,16		// b4
246	mov		r17=ar.lc
247	;;
248}
249	st8		[r31]=r16,16		// b5
250	st8		[r32]=r17,16		// lc
251	;;
252	st8		[r31]=r0,24		// __spare
253	stf.spill	[r32]=f2,32
254	;;
255	stf.spill	[r31]=f3,32
256	stf.spill	[r32]=f4,32
257	;;
258	stf.spill	[r31]=f5,32
259	stf.spill	[r32]=f16,32
260	;;
261	stf.spill	[r31]=f17,32
262	stf.spill	[r32]=f18,32
263	;;
264	stf.spill	[r31]=f19,32
265	stf.spill	[r32]=f20,32
266	;;
267	stf.spill	[r31]=f21,32
268	stf.spill	[r32]=f22,32
269	;;
270	stf.spill	[r31]=f23,32
271	stf.spill	[r32]=f24,32
272	;;
273	stf.spill	[r31]=f25,32
274	stf.spill	[r32]=f26,32
275	;;
276	stf.spill	[r31]=f27,32
277	stf.spill	[r32]=f28,32
278	;;
279{	.mmi
280	stf.spill	[r31]=f29,32
281	stf.spill	[r32]=f30
282(p15)	add		r8=0,r0
283	;;
284}
285{	.mmb
286	stf.spill	[r31]=f31
287	mf
288(p15)	br.ret.sptk	rp
289	;;
290}
291{	.mib
292	mov		r32=r33
293	nop		0
294	br.sptk		restorectx
295	;;
296}
297END(swapctx)
298
299/*
300 * save_callee_saved(struct _callee_saved *)
301 */
302ENTRY(save_callee_saved, 1)
303{	.mii
304	nop		0
305	add		r14=8,r32
306	add		r15=16,r32
307	;;
308}
309{	.mmi
310	.mem.offset	8,0
311	st8.spill	[r14]=r4,16		// r4
312	.mem.offset	16,0
313	st8.spill	[r15]=r5,16		// r5
314	mov		r16=b1
315	;;
316}
317{	.mmi
318	.mem.offset	24,0
319	st8.spill	[r14]=r6,16		// r6
320	.mem.offset	32,0
321	st8.spill	[r15]=r7,16		// r7
322	mov		r17=b2
323	;;
324}
325{	.mmi
326	st8		[r14]=r16,16		// b1
327	mov		r18=ar.unat
328	mov		r19=b3
329	;;
330}
331{	.mmi
332	st8		[r32]=r18		// nat (after)
333	st8		[r15]=r17,16		// b2
334	mov		r16=b4
335	;;
336}
337{	.mmi
338	st8		[r14]=r19,16		// b3
339	st8		[r15]=r16,16		// b4
340	mov		r17=b5
341	;;
342}
343{	.mii
344	st8		[r14]=r17,16		// b5
345	mov		r16=ar.lc
346	nop		0
347	;;
348}
349{	.mmb
350	st8		[r15]=r16		// ar.lc
351	st8		[r14]=r0		// __spare
352	br.ret.sptk	rp
353	;;
354}
355END(save_callee_saved)
356
357/*
358 * restore_callee_saved(struct _callee_saved *)
359 */
360ENTRY(restore_callee_saved, 1)
361{	.mmi
362	ld8		r30=[r32],16		// nat (after)
363	;;
364	mov		ar.unat=r30
365	add		r31=-8,r32
366	;;
367}
368{	.mmi
369	ld8.fill	r4=[r31],16		// r4
370	ld8.fill	r5=[r32],16		// r5
371	nop		0
372	;;
373}
374{	.mmi
375	ld8.fill	r6=[r31],16		// r6
376	ld8.fill	r7=[r32],16		// r7
377	nop		0
378	;;
379}
380{	.mmi
381	ld8		r30=[r31],16		// b1
382	ld8		r29=[r32],16		// b2
383	nop		0
384	;;
385}
386{	.mmi
387	ld8		r28=[r31],16		// b3
388	ld8		r27=[r32],16		// b4
389	mov		b1=r30
390	;;
391}
392{	.mii
393	ld8		r26=[r31]		// b5
394	mov		b2=r29
395	mov		b3=r28
396	;;
397}
398{	.mii
399	ld8		r25=[r32]		// lc
400	mov		b4=r27
401	mov		b5=r26
402	;;
403}
404{	.mib
405	nop		0
406	mov		ar.lc=r25
407	br.ret.sptk	rp
408	;;
409}
410END(restore_callee_saved)
411
412/*
413 * save_callee_saved_fp(struct _callee_saved_fp *)
414 */
415ENTRY(save_callee_saved_fp, 1)
416	add		r31=16,r32
417	stf.spill	[r32]=f2,32
418	;;
419	stf.spill	[r31]=f3,32
420	stf.spill	[r32]=f4,32
421	;;
422	stf.spill	[r31]=f5,32
423	stf.spill	[r32]=f16,32
424	;;
425	stf.spill	[r31]=f17,32
426	stf.spill	[r32]=f18,32
427	;;
428	stf.spill	[r31]=f19,32
429	stf.spill	[r32]=f20,32
430	;;
431	stf.spill	[r31]=f21,32
432	stf.spill	[r32]=f22,32
433	;;
434	stf.spill	[r31]=f23,32
435	stf.spill	[r32]=f24,32
436	;;
437	stf.spill	[r31]=f25,32
438	stf.spill	[r32]=f26,32
439	;;
440	stf.spill	[r31]=f27,32
441	stf.spill	[r32]=f28,32
442	;;
443	stf.spill	[r31]=f29,32
444	stf.spill	[r32]=f30
445	;;
446	stf.spill	[r31]=f31
447	br.ret.sptk	rp
448	;;
449END(save_callee_saved_fp)
450
451/*
452 * restore_callee_saved_fp(struct _callee_saved_fp *)
453 */
454ENTRY(restore_callee_saved_fp, 1)
455	add		r31=16,r32
456	ldf.fill	f2=[r32],32
457	;;
458	ldf.fill	f3=[r31],32
459	ldf.fill	f4=[r32],32
460	;;
461	ldf.fill	f5=[r31],32
462	ldf.fill	f16=[r32],32
463	;;
464	ldf.fill	f17=[r31],32
465	ldf.fill	f18=[r32],32
466	;;
467	ldf.fill	f19=[r31],32
468	ldf.fill	f20=[r32],32
469	;;
470	ldf.fill	f21=[r31],32
471	ldf.fill	f22=[r32],32
472	;;
473	ldf.fill	f23=[r31],32
474	ldf.fill	f24=[r32],32
475	;;
476	ldf.fill	f25=[r31],32
477	ldf.fill	f26=[r32],32
478	;;
479	ldf.fill	f27=[r31],32
480	ldf.fill	f28=[r32],32
481	;;
482	ldf.fill	f29=[r31],32
483	ldf.fill	f30=[r32]
484	;;
485	ldf.fill	f31=[r31]
486	br.ret.sptk	rp
487	;;
488END(restore_callee_saved_fp)
489
490/*
491 * save_high_fp(struct _high_fp *)
492 */
493ENTRY(save_high_fp, 1)
494	rsm		psr.dfh
495	;;
496	srlz.d
497	add		r31=16,r32
498	stf.spill	[r32]=f32,32
499	;;
500	stf.spill	[r31]=f33,32
501	stf.spill	[r32]=f34,32
502	;;
503	stf.spill	[r31]=f35,32
504	stf.spill	[r32]=f36,32
505	;;
506	stf.spill	[r31]=f37,32
507	stf.spill	[r32]=f38,32
508	;;
509	stf.spill	[r31]=f39,32
510	stf.spill	[r32]=f40,32
511	;;
512	stf.spill	[r31]=f41,32
513	stf.spill	[r32]=f42,32
514	;;
515	stf.spill	[r31]=f43,32
516	stf.spill	[r32]=f44,32
517	;;
518	stf.spill	[r31]=f45,32
519	stf.spill	[r32]=f46,32
520	;;
521	stf.spill	[r31]=f47,32
522	stf.spill	[r32]=f48,32
523	;;
524	stf.spill	[r31]=f49,32
525	stf.spill	[r32]=f50,32
526	;;
527	stf.spill	[r31]=f51,32
528	stf.spill	[r32]=f52,32
529	;;
530	stf.spill	[r31]=f53,32
531	stf.spill	[r32]=f54,32
532	;;
533	stf.spill	[r31]=f55,32
534	stf.spill	[r32]=f56,32
535	;;
536	stf.spill	[r31]=f57,32
537	stf.spill	[r32]=f58,32
538	;;
539	stf.spill	[r31]=f59,32
540	stf.spill	[r32]=f60,32
541	;;
542	stf.spill	[r31]=f61,32
543	stf.spill	[r32]=f62,32
544	;;
545	stf.spill	[r31]=f63,32
546	stf.spill	[r32]=f64,32
547	;;
548	stf.spill	[r31]=f65,32
549	stf.spill	[r32]=f66,32
550	;;
551	stf.spill	[r31]=f67,32
552	stf.spill	[r32]=f68,32
553	;;
554	stf.spill	[r31]=f69,32
555	stf.spill	[r32]=f70,32
556	;;
557	stf.spill	[r31]=f71,32
558	stf.spill	[r32]=f72,32
559	;;
560	stf.spill	[r31]=f73,32
561	stf.spill	[r32]=f74,32
562	;;
563	stf.spill	[r31]=f75,32
564	stf.spill	[r32]=f76,32
565	;;
566	stf.spill	[r31]=f77,32
567	stf.spill	[r32]=f78,32
568	;;
569	stf.spill	[r31]=f79,32
570	stf.spill	[r32]=f80,32
571	;;
572	stf.spill	[r31]=f81,32
573	stf.spill	[r32]=f82,32
574	;;
575	stf.spill	[r31]=f83,32
576	stf.spill	[r32]=f84,32
577	;;
578	stf.spill	[r31]=f85,32
579	stf.spill	[r32]=f86,32
580	;;
581	stf.spill	[r31]=f87,32
582	stf.spill	[r32]=f88,32
583	;;
584	stf.spill	[r31]=f89,32
585	stf.spill	[r32]=f90,32
586	;;
587	stf.spill	[r31]=f91,32
588	stf.spill	[r32]=f92,32
589	;;
590	stf.spill	[r31]=f93,32
591	stf.spill	[r32]=f94,32
592	;;
593	stf.spill	[r31]=f95,32
594	stf.spill	[r32]=f96,32
595	;;
596	stf.spill	[r31]=f97,32
597	stf.spill	[r32]=f98,32
598	;;
599	stf.spill	[r31]=f99,32
600	stf.spill	[r32]=f100,32
601	;;
602	stf.spill	[r31]=f101,32
603	stf.spill	[r32]=f102,32
604	;;
605	stf.spill	[r31]=f103,32
606	stf.spill	[r32]=f104,32
607	;;
608	stf.spill	[r31]=f105,32
609	stf.spill	[r32]=f106,32
610	;;
611	stf.spill	[r31]=f107,32
612	stf.spill	[r32]=f108,32
613	;;
614	stf.spill	[r31]=f109,32
615	stf.spill	[r32]=f110,32
616	;;
617	stf.spill	[r31]=f111,32
618	stf.spill	[r32]=f112,32
619	;;
620	stf.spill	[r31]=f113,32
621	stf.spill	[r32]=f114,32
622	;;
623	stf.spill	[r31]=f115,32
624	stf.spill	[r32]=f116,32
625	;;
626	stf.spill	[r31]=f117,32
627	stf.spill	[r32]=f118,32
628	;;
629	stf.spill	[r31]=f119,32
630	stf.spill	[r32]=f120,32
631	;;
632	stf.spill	[r31]=f121,32
633	stf.spill	[r32]=f122,32
634	;;
635	stf.spill	[r31]=f123,32
636	stf.spill	[r32]=f124,32
637	;;
638	stf.spill	[r31]=f125,32
639	stf.spill	[r32]=f126
640	;;
641	stf.spill	[r31]=f127
642	ssm		psr.dfh
643	;;
644	srlz.d
645	br.ret.sptk	rp
646	;;
647END(save_high_fp)
648
649/*
650 * restore_high_fp(struct _high_fp *)
651 */
652ENTRY(restore_high_fp, 1)
653	rsm		psr.dfh
654	;;
655	srlz.d
656	add		r31=16,r32
657	ldf.fill	f32=[r32],32
658	;;
659	ldf.fill	f33=[r31],32
660	ldf.fill	f34=[r32],32
661	;;
662	ldf.fill	f35=[r31],32
663	ldf.fill	f36=[r32],32
664	;;
665	ldf.fill	f37=[r31],32
666	ldf.fill	f38=[r32],32
667	;;
668	ldf.fill	f39=[r31],32
669	ldf.fill	f40=[r32],32
670	;;
671	ldf.fill	f41=[r31],32
672	ldf.fill	f42=[r32],32
673	;;
674	ldf.fill	f43=[r31],32
675	ldf.fill	f44=[r32],32
676	;;
677	ldf.fill	f45=[r31],32
678	ldf.fill	f46=[r32],32
679	;;
680	ldf.fill	f47=[r31],32
681	ldf.fill	f48=[r32],32
682	;;
683	ldf.fill	f49=[r31],32
684	ldf.fill	f50=[r32],32
685	;;
686	ldf.fill	f51=[r31],32
687	ldf.fill	f52=[r32],32
688	;;
689	ldf.fill	f53=[r31],32
690	ldf.fill	f54=[r32],32
691	;;
692	ldf.fill	f55=[r31],32
693	ldf.fill	f56=[r32],32
694	;;
695	ldf.fill	f57=[r31],32
696	ldf.fill	f58=[r32],32
697	;;
698	ldf.fill	f59=[r31],32
699	ldf.fill	f60=[r32],32
700	;;
701	ldf.fill	f61=[r31],32
702	ldf.fill	f62=[r32],32
703	;;
704	ldf.fill	f63=[r31],32
705	ldf.fill	f64=[r32],32
706	;;
707	ldf.fill	f65=[r31],32
708	ldf.fill	f66=[r32],32
709	;;
710	ldf.fill	f67=[r31],32
711	ldf.fill	f68=[r32],32
712	;;
713	ldf.fill	f69=[r31],32
714	ldf.fill	f70=[r32],32
715	;;
716	ldf.fill	f71=[r31],32
717	ldf.fill	f72=[r32],32
718	;;
719	ldf.fill	f73=[r31],32
720	ldf.fill	f74=[r32],32
721	;;
722	ldf.fill	f75=[r31],32
723	ldf.fill	f76=[r32],32
724	;;
725	ldf.fill	f77=[r31],32
726	ldf.fill	f78=[r32],32
727	;;
728	ldf.fill	f79=[r31],32
729	ldf.fill	f80=[r32],32
730	;;
731	ldf.fill	f81=[r31],32
732	ldf.fill	f82=[r32],32
733	;;
734	ldf.fill	f83=[r31],32
735	ldf.fill	f84=[r32],32
736	;;
737	ldf.fill	f85=[r31],32
738	ldf.fill	f86=[r32],32
739	;;
740	ldf.fill	f87=[r31],32
741	ldf.fill	f88=[r32],32
742	;;
743	ldf.fill	f89=[r31],32
744	ldf.fill	f90=[r32],32
745	;;
746	ldf.fill	f91=[r31],32
747	ldf.fill	f92=[r32],32
748	;;
749	ldf.fill	f93=[r31],32
750	ldf.fill	f94=[r32],32
751	;;
752	ldf.fill	f95=[r31],32
753	ldf.fill	f96=[r32],32
754	;;
755	ldf.fill	f97=[r31],32
756	ldf.fill	f98=[r32],32
757	;;
758	ldf.fill	f99=[r31],32
759	ldf.fill	f100=[r32],32
760	;;
761	ldf.fill	f101=[r31],32
762	ldf.fill	f102=[r32],32
763	;;
764	ldf.fill	f103=[r31],32
765	ldf.fill	f104=[r32],32
766	;;
767	ldf.fill	f105=[r31],32
768	ldf.fill	f106=[r32],32
769	;;
770	ldf.fill	f107=[r31],32
771	ldf.fill	f108=[r32],32
772	;;
773	ldf.fill	f109=[r31],32
774	ldf.fill	f110=[r32],32
775	;;
776	ldf.fill	f111=[r31],32
777	ldf.fill	f112=[r32],32
778	;;
779	ldf.fill	f113=[r31],32
780	ldf.fill	f114=[r32],32
781	;;
782	ldf.fill	f115=[r31],32
783	ldf.fill	f116=[r32],32
784	;;
785	ldf.fill	f117=[r31],32
786	ldf.fill	f118=[r32],32
787	;;
788	ldf.fill	f119=[r31],32
789	ldf.fill	f120=[r32],32
790	;;
791	ldf.fill	f121=[r31],32
792	ldf.fill	f122=[r32],32
793	;;
794	ldf.fill	f123=[r31],32
795	ldf.fill	f124=[r32],32
796	;;
797	ldf.fill	f125=[r31],32
798	ldf.fill	f126=[r32]
799	;;
800	ldf.fill	f127=[r31]
801	ssm		psr.dfh
802	;;
803	srlz.d
804	br.ret.sptk	rp
805	;;
806END(restore_high_fp)
807
808/*
809 * lwp_trampoline()
810 *
811 * Arrange for a function to be invoked neatly, after a cpu_switchto().
812 *
813 * Invokes fork_exit() passing in three arguments: a callout function, an
814 * argument to the callout, and a trapframe pointer.  For child processes
815 * returning from fork(2), the argument is a pointer to the child process.
816 *
817 * The callout function and its argument is in the trapframe in scratch
818 * registers r2 and r3.
819 */
820ENTRY(lwp_trampoline, 0)
821	.prologue
822	.save	rp,r0
823
824	.body
825{	.mmi
826	alloc		r14=ar.pfs,0,1,2,0
827	add		r2=PC_CURLWP,r13	// r2 = &ci->ci_curlwp
828	;;
829}
830{	.mmi
831	mov		out0=ret1		// oldlwp
832	ld8		out1=[r2]		// newlwp = ci->ci_curlwp
833	add		loc0=32+SIZEOF_SPECIAL+8,sp	// tf_scratch.gr2(func)
834	;;
835}
836{	.mmb
837	ld8		loc0=[loc0]
838	add		r4=32+SIZEOF_SPECIAL+16,sp	// tf_scratch.gr3(arg)
839	br.call.sptk	rp=_C_LABEL(lwp_startup)
840	;;
841}
842{	.mib
843	ld8		out0=[r4]
844	mov		b1=loc0
845	br.call.sptk	rp=b1
846	;;
847}
848	/*
849	 * If we get back here, it means we're a user space process that's
850	 * the immediate result of fork(2).
851	 */
852	.global		enter_userland
853	.type		enter_userland, @function
854enter_userland:
855{	.mfb
856	nop		0
857	nop		0
858#if 0
859	br.sptk		epc_syscall_return
860#endif
861	;;
862}
863END(lwp_trampoline)
864