]> 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-2020 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 li r8,trampoline_size /* verify that the trampoline is big enough */
68 cmpw cr1,r8,r4
69 srwi r4,r4,2 /* # words to move */
70 addi r9,r3,-4 /* adjust pointer for lwzu */
71 mtctr r4
72 blt cr1,.Labort
73
74 mtlr r0
75
76 /* Copy the instructions to the stack */
77 .Lmove:
78 lwzu r10,4(r7)
79 stwu r10,4(r9)
80 bdnz .Lmove
81
82 /* Store correct function and static chain */
83 stw r5,.Lfunc(r3)
84 stw r6,.Lchain(r3)
85
86 /* Now flush both caches */
87 mtctr r4
88 .Lcache:
89 icbi 0,r3
90 dcbf 0,r3
91 addi r3,r3,4
92 bdnz .Lcache
93
94 /* Finally synchronize things & return */
95 sync
96 isync
97 blr
98
99 .Labort:
100 /* Use a longcall sequence in the non PIC case on VxWorks, to prevent
101 possible relocation errors if this is module-loaded very far away from
102 the 'abort' entry point. */
103 #if defined (__VXWORKS__) && ! (defined __PIC__ || defined __pic__)
104 lis r11,JUMP_TARGET(abort)@ha
105 addic r11,r11,JUMP_TARGET(abort)@l
106 mtlr r11
107 blrl
108 #else
109
110 #if (defined __PIC__ || defined __pic__) && defined HAVE_AS_REL16
111 bcl 20,31,1f
112 1: mflr r30
113 addis r30,r30,_GLOBAL_OFFSET_TABLE_-1b@ha
114 addi r30,r30,_GLOBAL_OFFSET_TABLE_-1b@l
115 #endif
116 bl JUMP_TARGET(abort)
117 #endif
118 .cfi_endproc
119 FUNC_END(__trampoline_setup)
120
121 #elif _CALL_ELF == 2
122 .type trampoline_initial,@object
123 .align 3
124 trampoline_initial:
125 ld r11,.Lchain(r12)
126 ld r12,.Lfunc(r12)
127 mtctr r12
128 bctr
129 .Lfunc = .-trampoline_initial
130 .quad 0 /* will be replaced with function address */
131 .Lchain = .-trampoline_initial
132 .quad 0 /* will be replaced with static chain */
133
134 trampoline_size = .-trampoline_initial
135 .size trampoline_initial,trampoline_size
136
137
138 /* R3 = stack address to store trampoline */
139 /* R4 = length of trampoline area */
140 /* R5 = function address */
141 /* R6 = static chain */
142
143 .pushsection ".toc","aw"
144 .LC0:
145 .quad trampoline_initial-8
146 .popsection
147
148 FUNC_START(__trampoline_setup)
149 .cfi_startproc
150 addis 7,2,.LC0@toc@ha
151 ld 7,.LC0@toc@l(7) /* trampoline address -8 */
152
153 li r8,trampoline_size /* verify that the trampoline is big enough */
154 cmpw cr1,r8,r4
155 srwi r4,r4,3 /* # doublewords to move */
156 addi r9,r3,-8 /* adjust pointer for stdu */
157 mtctr r4
158 blt cr1,.Labort
159
160 /* Copy the instructions to the stack */
161 .Lmove:
162 ldu r10,8(r7)
163 stdu r10,8(r9)
164 bdnz .Lmove
165
166 /* Store correct function and static chain */
167 std r5,.Lfunc(r3)
168 std r6,.Lchain(r3)
169
170 /* Now flush both caches */
171 mtctr r4
172 .Lcache:
173 icbi 0,r3
174 dcbf 0,r3
175 addi r3,r3,8
176 bdnz .Lcache
177
178 /* Finally synchronize things & return */
179 sync
180 isync
181 blr
182
183 .Labort:
184 bl JUMP_TARGET(abort)
185 nop
186 .cfi_endproc
187 FUNC_END(__trampoline_setup)
188
189 #endif