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