1/* PLT trampolines.  m68k version.
2   Copyright (C) 2005-2021 Free Software Foundation, Inc.
3   This file is part of the GNU C Library.
4
5   The GNU C Library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9
10   The GNU C Library is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Lesser General Public License for more details.
14
15   You should have received a copy of the GNU Lesser General Public
16   License along with the GNU C Library.  If not, see
17   <https://www.gnu.org/licenses/>.  */
18
19#include <sysdep.h>
20
21#if !defined (__mcoldfire__)
22# define FMOVE		fmove.x
23# define FPSPACE	12
24#elif defined (__mcffpu__)
25# define FMOVE		fmove.d
26# define FPSPACE	8
27#else
28# define FPSPACE	0
29#endif
30
31	.text
32	.globl _dl_runtime_resolve
33	.type _dl_runtime_resolve, @function
34_dl_runtime_resolve:
35	cfi_startproc
36	cfi_adjust_cfa_offset (8)
37	| Save %a0 (struct return address) and %a1.
38	move.l %a0, -(%sp)
39	cfi_adjust_cfa_offset (4)
40	move.l %a1, -(%sp)
41	cfi_adjust_cfa_offset (4)
42	| Call the real address resolver.
43	jbsr _dl_fixup
44	| Restore register %a0 and %a1.
45	move.l (%sp)+, %a1
46	cfi_adjust_cfa_offset (-4)
47	move.l (%sp)+, %a0
48	cfi_adjust_cfa_offset (-4)
49	| Pop parameters
50	addq.l #8, %sp
51	cfi_adjust_cfa_offset (-8)
52	| Call real function.
53#ifdef __mcoldfire__
54	move.l %d0,-(%sp)
55	cfi_adjust_cfa_offset (4)
56	rts
57#else
58	jmp (%d0)
59#endif
60	cfi_endproc
61	.size _dl_runtime_resolve, . - _dl_runtime_resolve
62
63	.text
64	.globl _dl_runtime_profile
65	.type _dl_runtime_profile, @function
66_dl_runtime_profile:
67	cfi_startproc
68	cfi_adjust_cfa_offset (8)
69	pea 8(%sp)
70	cfi_adjust_cfa_offset (4)
71	move.l %a1, -(%sp)
72	cfi_adjust_cfa_offset (4)
73	move.l %a0, -(%sp)
74	cfi_adjust_cfa_offset (4)
75	pea -1.w
76	cfi_adjust_cfa_offset (4)
77	| Push parameters for _dl_profile_fixup
78	pea (%sp)
79	cfi_adjust_cfa_offset (4)
80	pea 8(%sp)
81	cfi_adjust_cfa_offset (4)
82	move.l 32(%sp), -(%sp)
83	cfi_adjust_cfa_offset (4)
84	move.l 32(%sp), -(%sp)
85	cfi_adjust_cfa_offset (4)
86	move.l 32(%sp), -(%sp)
87	cfi_adjust_cfa_offset (4)
88	subq.l #8, %sp
89	cfi_adjust_cfa_offset (8)
90	| Call the real address resolver.
91	jbsr _dl_profile_fixup
92	| Pop parameters
93	lea 28(%sp), %sp
94	cfi_adjust_cfa_offset (-28)
95	move.l (%sp), %d1
96	jpl 1f
97	addq.l #4, %sp
98	cfi_adjust_cfa_offset (-4)
99	| Restore register %a0 and %a1.
100	move.l (%sp)+, %a0
101	cfi_adjust_cfa_offset (-4)
102	move.l (%sp)+, %a1
103	cfi_adjust_cfa_offset (-4)
104	lea 12(%sp), %sp
105	cfi_adjust_cfa_offset (-12)
106	| Call real function.
107#ifdef __mcoldfire__
108	move.l %d0,-(%sp)
109	cfi_adjust_cfa_offset (4)
110	rts
111#else
112	jmp (%d0)
113#endif
114
115	/*
116	    +24     return address
117	    +20     PLT1
118	    +16     PLT2
119	    +12     %sp
120	    +8      %a1
121	    +4      %a0
122	   %sp      free
123	*/
124#ifdef __mcoldfire__
125	cfi_adjust_cfa_offset (20)
126#else
127	cfi_adjust_cfa_offset (24)
128#endif
1291:	move.l %a2, (%sp)
130	cfi_rel_offset (%a2, 0)
131	move.l %sp, %a2
132	move.l %sp, %a0
133	lea 28(%sp), %a1
134	| Round framesize up to longword alignment
135	addq.l #3, %d1
136	and.l #-3, %d1
137	sub.l %d1, %a0
138	move.l %a0, %sp
139	cfi_def_cfa_register (%a2)
140#ifdef __mcoldfire__
141	tst.l %d1
142	beq 2f
1431:	move.l (%a1)+, (%a0)+
144	subq.l #4,%d1
145	bne 1b
1462:
147#else
148	lsr.l #2,%d1
149	jra 2f
1501:	move.l (%a1)+, (%a0)+
1512:	dbra %d1,1b
152#endif
153	/*
154	   %a2+24  return address
155	   %a2+20  PLT1
156	   %a2+16  PLT2
157	   %a2+12  %sp
158	   %a2+8   %a1
159	   %a2+4   %a0
160	   %a2     %a2
161	   %sp     copied stack frame
162	*/
163
164	move.l 4(%a2), %a0
165	move.l 8(%a2), %a1
166#ifdef __mcoldfire__
167	pea 2f(%pc)
168	move.l %d0,-(%sp)
169	rts
1702:
171#else
172	jsr (%d0)
173#endif
174	move.l %a2, %sp
175	cfi_def_cfa_register (%sp)
176	move.l (%sp)+, %a2
177	cfi_adjust_cfa_offset (4)
178	cfi_restore (%a2)
179	/*
180	    +20     return address
181	    +16     PLT1
182	    +12     PLT2
183	    +8      %sp
184	    +4      %a1
185	   %sp      %a0
186	*/
187#ifdef FMOVE
188	FMOVE %fp0, -(%sp)
189	cfi_adjust_cfa_offset (FPSPACE)
190#endif
191	move.l %a0, -(%sp)
192	cfi_adjust_cfa_offset (4)
193	move.l %d1, -(%sp)
194	cfi_adjust_cfa_offset (4)
195	move.l %d0, -(%sp)
196	cfi_adjust_cfa_offset (4)
197	pea (%sp)
198	cfi_adjust_cfa_offset (4)
199	pea (16+FPSPACE)(%sp)
200	cfi_adjust_cfa_offset (4)
201	move.l (32+FPSPACE)(%sp), -(%sp)
202	cfi_adjust_cfa_offset (4)
203	move.l (32+FPSPACE)(%sp), -(%sp)
204	cfi_adjust_cfa_offset (4)
205	jbsr _dl_audit_pltexit
206	lea 16(%sp), %sp
207	cfi_adjust_cfa_offset (-16)
208	move.l (%sp)+, %d0
209	cfi_adjust_cfa_offset (-4)
210	move.l (%sp)+, %d1
211	cfi_adjust_cfa_offset (-4)
212	move.l (%sp)+, %a0
213	cfi_adjust_cfa_offset (-4)
214#ifdef FMOVE
215	FMOVE (%sp)+, %fp0
216	cfi_adjust_cfa_offset (-FPSPACE)
217#endif
218	lea 20(%sp), %sp
219	cfi_adjust_cfa_offset (-20)
220	rts
221	cfi_endproc
222	.size _dl_runtime_profile, . - _dl_runtime_profile
223