1/* Copyright (c) 2005-2006 Russ Cox, MIT; see COPYRIGHT */
2
3#if defined(__FreeBSD__) && defined(__i386__) && __FreeBSD__ < 5
4#define NEEDX86CONTEXT 1
5#define SET setmcontext
6#define GET getmcontext
7#endif
8
9#if defined(__OpenBSD__) && defined(__i386__)
10#define NEEDX86CONTEXT 1
11#define SET setmcontext
12#define GET getmcontext
13#endif
14
15#if defined(__APPLE__)
16#if defined(__i386__)
17#define NEEDX86CONTEXT 1
18#define SET _setmcontext
19#define GET _getmcontext
20#elif defined(__x86_64__)
21#define NEEDAMD64CONTEXT 1
22#define SET _setmcontext
23#define GET _getmcontext
24#else
25#define NEEDPOWERCONTEXT 1
26#define SET __setmcontext
27#define GET __getmcontext
28#endif
29#endif
30
31#if defined(__linux__) && defined(__arm__)
32#define NEEDARMCONTEXT 1
33#define SET setmcontext
34#define GET getmcontext
35#endif
36
37#ifdef NEEDX86CONTEXT
38.globl SET
39SET:
40	movl	4(%esp), %eax
41
42	movl	8(%eax), %fs
43	movl	12(%eax), %es
44	movl	16(%eax), %ds
45	movl	76(%eax), %ss
46	movl	20(%eax), %edi
47	movl	24(%eax), %esi
48	movl	28(%eax), %ebp
49	movl	36(%eax), %ebx
50	movl	40(%eax), %edx
51	movl	44(%eax), %ecx
52
53	movl	72(%eax), %esp
54	pushl	60(%eax)	/* new %eip */
55	movl	48(%eax), %eax
56	ret
57
58.globl GET
59GET:
60	movl	4(%esp), %eax
61
62	movl	%fs, 8(%eax)
63	movl	%es, 12(%eax)
64	movl	%ds, 16(%eax)
65	movl	%ss, 76(%eax)
66	movl	%edi, 20(%eax)
67	movl	%esi, 24(%eax)
68	movl	%ebp, 28(%eax)
69	movl	%ebx, 36(%eax)
70	movl	%edx, 40(%eax)
71	movl	%ecx, 44(%eax)
72
73	movl	$1, 48(%eax)	/* %eax */
74	movl	(%esp), %ecx	/* %eip */
75	movl	%ecx, 60(%eax)
76	leal	4(%esp), %ecx	/* %esp */
77	movl	%ecx, 72(%eax)
78
79	movl	44(%eax), %ecx	/* restore %ecx */
80	movl	$0, %eax
81	ret
82#endif
83
84#ifdef NEEDAMD64CONTEXT
85.globl SET
86SET:
87	movq	16(%rdi), %rsi
88	movq	24(%rdi), %rdx
89	movq	32(%rdi), %rcx
90	movq	40(%rdi), %r8
91	movq	48(%rdi), %r9
92	movq	56(%rdi), %rax
93	movq	64(%rdi), %rbx
94	movq	72(%rdi), %rbp
95	movq	80(%rdi), %r10
96	movq	88(%rdi), %r11
97	movq	96(%rdi), %r12
98	movq	104(%rdi), %r13
99	movq	112(%rdi), %r14
100	movq	120(%rdi), %r15
101	movq	184(%rdi), %rsp
102	pushq	160(%rdi)	/* new %eip */
103	movq	8(%rdi), %rdi
104	ret
105
106.globl GET
107GET:
108	movq	%rdi, 8(%rdi)
109	movq	%rsi, 16(%rdi)
110	movq	%rdx, 24(%rdi)
111	movq	%rcx, 32(%rdi)
112	movq	%r8, 40(%rdi)
113	movq	%r9, 48(%rdi)
114	movq	$1, 56(%rdi)	/* %rax */
115	movq	%rbx, 64(%rdi)
116	movq	%rbp, 72(%rdi)
117	movq	%r10, 80(%rdi)
118	movq	%r11, 88(%rdi)
119	movq	%r12, 96(%rdi)
120	movq	%r13, 104(%rdi)
121	movq	%r14, 112(%rdi)
122	movq	%r15, 120(%rdi)
123
124	movq	(%rsp), %rcx	/* %rip */
125	movq	%rcx, 160(%rdi)
126	leaq	8(%rsp), %rcx	/* %rsp */
127	movq	%rcx, 184(%rdi)
128
129	movq	32(%rdi), %rcx	/* restore %rcx */
130	movq	$0, %rax
131	ret
132#endif
133
134#ifdef NEEDPOWERCONTEXT
135/* get FPR and VR use flags with sc 0x7FF3 */
136/* get vsave with mfspr reg, 256 */
137
138.text
139.align 2
140
141.globl GET
142GET:				/* xxx: instruction scheduling */
143	mflr	r0
144	mfcr	r5
145	mfctr	r6
146	mfxer	r7
147	stw	r0, 0*4(r3)
148	stw	r5, 1*4(r3)
149	stw	r6, 2*4(r3)
150	stw	r7, 3*4(r3)
151
152	stw	r1, 4*4(r3)
153	stw	r2, 5*4(r3)
154	li	r5, 1			/* return value for setmcontext */
155	stw	r5, 6*4(r3)
156
157	stw	r13, (0+7)*4(r3)	/* callee-save GPRs */
158	stw	r14, (1+7)*4(r3)	/* xxx: block move */
159	stw	r15, (2+7)*4(r3)
160	stw	r16, (3+7)*4(r3)
161	stw	r17, (4+7)*4(r3)
162	stw	r18, (5+7)*4(r3)
163	stw	r19, (6+7)*4(r3)
164	stw	r20, (7+7)*4(r3)
165	stw	r21, (8+7)*4(r3)
166	stw	r22, (9+7)*4(r3)
167	stw	r23, (10+7)*4(r3)
168	stw	r24, (11+7)*4(r3)
169	stw	r25, (12+7)*4(r3)
170	stw	r26, (13+7)*4(r3)
171	stw	r27, (14+7)*4(r3)
172	stw	r28, (15+7)*4(r3)
173	stw	r29, (16+7)*4(r3)
174	stw	r30, (17+7)*4(r3)
175	stw	r31, (18+7)*4(r3)
176
177	li	r3, 0			/* return */
178	blr
179
180.globl SET
181SET:
182	lwz	r13, (0+7)*4(r3)	/* callee-save GPRs */
183	lwz	r14, (1+7)*4(r3)	/* xxx: block move */
184	lwz	r15, (2+7)*4(r3)
185	lwz	r16, (3+7)*4(r3)
186	lwz	r17, (4+7)*4(r3)
187	lwz	r18, (5+7)*4(r3)
188	lwz	r19, (6+7)*4(r3)
189	lwz	r20, (7+7)*4(r3)
190	lwz	r21, (8+7)*4(r3)
191	lwz	r22, (9+7)*4(r3)
192	lwz	r23, (10+7)*4(r3)
193	lwz	r24, (11+7)*4(r3)
194	lwz	r25, (12+7)*4(r3)
195	lwz	r26, (13+7)*4(r3)
196	lwz	r27, (14+7)*4(r3)
197	lwz	r28, (15+7)*4(r3)
198	lwz	r29, (16+7)*4(r3)
199	lwz	r30, (17+7)*4(r3)
200	lwz	r31, (18+7)*4(r3)
201
202	lwz	r1, 4*4(r3)
203	lwz	r2, 5*4(r3)
204
205	lwz	r0, 0*4(r3)
206	mtlr	r0
207	lwz	r0, 1*4(r3)
208	mtcr	r0			/* mtcrf 0xFF, r0 */
209	lwz	r0, 2*4(r3)
210	mtctr	r0
211	lwz	r0, 3*4(r3)
212	mtxer	r0
213
214	lwz	r3,	6*4(r3)
215	blr
216#endif
217
218#ifdef NEEDARMCONTEXT
219.globl GET
220GET:
221	str	r1, [r0,#4]
222	str	r2, [r0,#8]
223	str	r3, [r0,#12]
224	str	r4, [r0,#16]
225	str	r5, [r0,#20]
226	str	r6, [r0,#24]
227	str	r7, [r0,#28]
228	str	r8, [r0,#32]
229	str	r9, [r0,#36]
230	str	r10, [r0,#40]
231	str	r11, [r0,#44]
232	str	r12, [r0,#48]
233	str	r13, [r0,#52]
234	str	r14, [r0,#56]
235	/* store 1 as r0-to-restore */
236	mov	r1, #1
237	str	r1, [r0]
238	/* return 0 */
239	mov	r0, #0
240	mov	pc, lr
241
242.globl SET
243SET:
244	ldr	r1, [r0,#4]
245	ldr	r2, [r0,#8]
246	ldr	r3, [r0,#12]
247	ldr	r4, [r0,#16]
248	ldr	r5, [r0,#20]
249	ldr	r6, [r0,#24]
250	ldr	r7, [r0,#28]
251	ldr	r8, [r0,#32]
252	ldr	r9, [r0,#36]
253	ldr	r10, [r0,#40]
254	ldr	r11, [r0,#44]
255	ldr	r12, [r0,#48]
256	ldr	r13, [r0,#52]
257	ldr	r14, [r0,#56]
258	ldr	r0, [r0]
259	mov	pc, lr
260#endif
261