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