1/* Copyright (C) 2004-2021 Free Software Foundation, Inc.
2   This file is part of the GNU C Library.
3
4   The GNU C Library is free software; you can redistribute it and/or
5   modify it under the terms of the GNU Lesser General Public
6   License as published by the Free Software Foundation; either
7   version 2.1 of the License, or (at your option) any later version.
8
9   The GNU C Library is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   Lesser General Public License for more details.
13
14   You should have received a copy of the GNU Lesser General Public
15   License along with the GNU C Library.  If not, see
16   <https://www.gnu.org/licenses/>.  */
17
18#include <sysdep.h>
19#include <ucontext-offsets.h>
20
21
22ENTRY(__makecontext)
23	ldgp	$29, 0($27)
24#ifdef PROF
25	.set noat
26	lda     AT, _mcount
27	jsr     AT, (AT), _mcount
28	.set at
29#endif
30	.prologue 1
31
32	/* Compute top of stack, including arguments.  */
33	ldq	$1, UC_STACK+SS_SP($16)
34	ldq	$2, UC_STACK+SS_SIZE($16)
35	addq	$1, $2, $8
36	subq	$18, 6, $1
37	cmovlt	$1, 0, $1
38	s8addq	$1, 0, $2
39	subq	$8, $2, $8
40
41	/* Copy all parameters.  Switch statement header here.  */
42	ldah	$3, $jumptable($29)	!gprelhigh
43	cmple	$18, 6, $1
44	mov	$18, $2
45	cmoveq	$1, 7, $2
46	s4addq	$2, $3, $3
47	ldl	$4, $jumptable($3)	!gprellow
48	addq	$4, $29, $4
49	jmp	$31, ($4), $args1
50
51	.section .rodata
52	.align	2
53$jumptable:
54	.gprel32  $args0
55	.gprel32  $args1
56	.gprel32  $args2
57	.gprel32  $args3
58	.gprel32  $args4
59	.gprel32  $args5
60	.gprel32  $args6
61	.gprel32  $argsN
62	.text
63
64	/* Here we process arguments 7 through N.  This is a straight
65	   stack-to-stack copy.  */
66	.align	4
67$argsN:
68	subq	$18, 6, $1
69	lda	$2, 0($8)
70	lda	$3, 3*8($30)
71	.align	4
721:
73	ldq	$0, 0($3)
74	subq	$1, 1, $1
75	lda	$3, 8($3)
76	stq	$0, 0($2)
77	lda	$2, 8($2)
78	bne	$1, 1b
79
80	/* Here we process arguments 6 through 0.  This involves
81	   copying into the register save areas of the ucontext.  */
82	.align	4
83$args6:
84	ldq	$0, 2*8($30)
85	stq	$0, UC_SIGCTX+SC_REGS+21*8($16)
86	unop
87	stq	$0, UC_SIGCTX+SC_FPREGS+21*8($16)
88$args5:
89	ldq	$0, 1*8($30)
90	stq	$0, UC_SIGCTX+SC_REGS+20*8($16)
91	unop
92	stq	$0, UC_SIGCTX+SC_FPREGS+20*8($16)
93$args4:
94	ldq	$0, 0*8($30)
95	stq	$0, UC_SIGCTX+SC_REGS+19*8($16)
96	unop
97	stq	$0, UC_SIGCTX+SC_FPREGS+19*8($16)
98$args3:
99	unop
100	stq	$21, UC_SIGCTX+SC_REGS+18*8($16)
101	unop
102	stt	$f21, UC_SIGCTX+SC_FPREGS+18*8($16)
103$args2:
104	unop
105	stq	$20, UC_SIGCTX+SC_REGS+17*8($16)
106	unop
107	stt	$f20, UC_SIGCTX+SC_FPREGS+17*8($16)
108$args1:
109	unop
110	stq	$19, UC_SIGCTX+SC_REGS+16*8($16)
111	unop
112	stt	$f19, UC_SIGCTX+SC_FPREGS+16*8($16)
113$args0:
114
115	/* Set up the registers ready to invoke __startcontext.
116	   We seed $27 with the target function address, and $9
117	   with the link from ucp.  */
118	ldah	$0, __startcontext($29)		!gprelhigh
119	ldq	$1, UC_LINK($16)
120	lda	$0, __startcontext($0)		!gprellow
121	stq	$17, UC_SIGCTX+SC_REGS+27*8($16)
122	stq	$8, UC_SIGCTX+SC_REGS+30*8($16)
123	stq	$0, UC_SIGCTX+SC_PC($16)
124	stq	$1, UC_SIGCTX+SC_REGS+9*8($16)
125
126	/* No return value from makecontext.  */
127	ret
128
129END(__makecontext)
130weak_alias (__makecontext, makecontext)
131
132/* This function is where a new makecontext "thread" begins life.
133   We have already set up $27 for calling the target function, and
134   we've set $9 to the UC_LINK of the parent context.
135
136   If the function returns, we either jump to the linked context
137   (if non-null) or exit.  */
138
139	.align	4
140	.ent	__startcontext
141__startcontext:
142	.frame $31, 0, $31, 0
143	.prologue 0
144
145	jsr	$26, ($27), 0
146	ldgp	$29, 0($26)
147	mov	$9, $16
148	beq	$9, 1f
149
150#ifdef PIC
151	bsr	$26, __setcontext		!samegp
1521:	mov	$31, $16
153	bsr	$26, HIDDEN_JUMPTARGET(exit)	!samegp
154#else
155	jsr	$26, __setcontext
156	ldgp	$29, 0($26)
1571:	mov	$31, $16
158	jsr	$26, HIDDEN_JUMPTARGET(exit)
159#endif
160
161	halt
162
163	.end __startcontext
164