]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgcc/config/rs6000/tramp.S
Update copyright years.
[thirdparty/gcc.git] / libgcc / config / rs6000 / tramp.S
1 /* Special support for trampolines
2 *
3 * Copyright (C) 1996-2024 Free Software Foundation, Inc.
4 * Written By Michael Meissner
5 *
6 * This file is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 3, or (at your option) any
9 * later version.
10 *
11 * This file is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * Under Section 7 of GPL version 3, you are granted additional
17 * permissions described in the GCC Runtime Library Exception, version
18 * 3.1, as published by the Free Software Foundation.
19 *
20 * You should have received a copy of the GNU General Public License and
21 * a copy of the GCC Runtime Library Exception along with this program;
22 * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 * <http://www.gnu.org/licenses/>.
24 */
25
26 /* Set up trampolines. */
27
28 .section ".text"
29 #include "ppc-asm.h"
30 #include "config.h"
31
32 #ifndef __powerpc64__
33 .type trampoline_initial,@object
34 .align 2
35 trampoline_initial:
36 mflr r0
37 bcl 20,31,1f
38 .Lfunc = .-trampoline_initial
39 .long 0 /* will be replaced with function address */
40 .Lchain = .-trampoline_initial
41 .long 0 /* will be replaced with static chain */
42 1: mflr r11
43 mtlr r0
44 lwz r0,0(r11) /* function address */
45 lwz r11,4(r11) /* static chain */
46 mtctr r0
47 bctr
48
49 trampoline_size = .-trampoline_initial
50 .size trampoline_initial,trampoline_size
51
52
53 /* R3 = stack address to store trampoline */
54 /* R4 = length of trampoline area */
55 /* R5 = function address */
56 /* R6 = static chain */
57
58 FUNC_START(__trampoline_setup)
59 .cfi_startproc
60 mflr r0 /* save return address */
61 bcl 20,31,.LCF0 /* load up __trampoline_initial into r7 */
62 .cfi_register lr,r0
63 .LCF0:
64 mflr r11
65 addi r7,r11,trampoline_initial-4-.LCF0 /* trampoline address -4 */
66
67 cmpwi cr1,r4,trampoline_size /* verify that the trampoline is big enough */
68 srwi r4,r4,2 /* # words to move */
69 addi r9,r3,-4 /* adjust pointer for lwzu */
70 mtctr r4
71 blt cr1,.Labort
72
73 mtlr r0
74
75 /* Copy the instructions to the stack */
76 .Lmove:
77 lwzu r10,4(r7)
78 stwu r10,4(r9)
79 bdnz .Lmove
80
81 /* Store correct function and static chain */
82 stw r5,.Lfunc(r3)
83 stw r6,.Lchain(r3)
84
85 /* Now flush both caches */
86 mtctr r4
87 .Lcache:
88 icbi 0,r3
89 dcbf 0,r3
90 addi r3,r3,4
91 bdnz .Lcache
92
93 /* Finally synchronize things & return */
94 sync
95 isync
96 blr
97
98 .Labort:
99 /* Use a longcall sequence in the non PIC case on VxWorks, to prevent
100 possible relocation errors if this is module-loaded very far away from
101 the 'abort' entry point. */
102 #if defined (__VXWORKS__) && ! (defined __PIC__ || defined __pic__)
103 lis r11,JUMP_TARGET(abort)@ha
104 addic r11,r11,JUMP_TARGET(abort)@l
105 mtlr r11
106 blrl
107 #else
108
109 #if (defined __PIC__ || defined __pic__) && defined HAVE_AS_REL16
110 bcl 20,31,1f
111 1: mflr r30
112 addis r30,r30,_GLOBAL_OFFSET_TABLE_-1b@ha
113 addi r30,r30,_GLOBAL_OFFSET_TABLE_-1b@l
114 #endif
115 bl JUMP_TARGET(abort)
116 #endif
117 .cfi_endproc
118 FUNC_END(__trampoline_setup)
119
120 #elif _CALL_ELF == 2
121 .type trampoline_initial,@object
122 .align 3
123 trampoline_initial:
124 ld r11,.Lchain(r12)
125 ld r12,.Lfunc(r12)
126 mtctr r12
127 bctr
128 .Lfunc = .-trampoline_initial
129 .quad 0 /* will be replaced with function address */
130 .Lchain = .-trampoline_initial
131 .quad 0 /* will be replaced with static chain */
132
133 trampoline_size = .-trampoline_initial
134 .size trampoline_initial,trampoline_size
135
136
137 /* R3 = stack address to store trampoline */
138 /* R4 = length of trampoline area */
139 /* R5 = function address */
140 /* R6 = static chain */
141
142 #ifndef __PCREL__
143 .pushsection ".toc","aw"
144 .LC0:
145 .quad trampoline_initial-8
146 .popsection
147 #endif
148
149 FUNC_START(__trampoline_setup)
150 .cfi_startproc
151 #ifdef __PCREL__
152 pla 7,(trampoline_initial-8)@pcrel
153 #else
154 addis 7,2,.LC0@toc@ha
155 ld 7,.LC0@toc@l(7) /* trampoline address -8 */
156 #endif
157
158 cmpwi cr1,r4,trampoline_size /* verify that the trampoline is big enough */
159 srwi r4,r4,3 /* # doublewords to move */
160 addi r9,r3,-8 /* adjust pointer for stdu */
161 mtctr r4
162 blt cr1,.Labort
163
164 /* Copy the instructions to the stack */
165 .Lmove:
166 ldu r10,8(r7)
167 stdu r10,8(r9)
168 bdnz .Lmove
169
170 /* Store correct function and static chain */
171 std r5,.Lfunc(r3)
172 std r6,.Lchain(r3)
173
174 /* Now flush both caches */
175 mtctr r4
176 .Lcache:
177 icbi 0,r3
178 dcbf 0,r3
179 addi r3,r3,8
180 bdnz .Lcache
181
182 /* Finally synchronize things & return */
183 sync
184 isync
185 blr
186
187 .Labort:
188 bl JUMP_TARGET(abort)
189 nop
190 .cfi_endproc
191 FUNC_END(__trampoline_setup)
192
193 #endif