]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/tile/dl-trampoline.S
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / sysdeps / tile / dl-trampoline.S
CommitLineData
688903eb 1/* Copyright (C) 2011-2018 Free Software Foundation, Inc.
63d143a2
CM
2 This file is part of the GNU C Library.
3 Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
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
ab84e3ff
PE
16 License along with the GNU C Library. If not, see
17 <http://www.gnu.org/licenses/>. */
63d143a2
CM
18
19#include <sysdep.h>
20#include <arch/abi.h>
21
22/* This function is called via the PLT header, which is called
23 from an individual PLT entry.
24
25 At this point we have several values passed in:
26
27 lr: return address to original user code
28 r28: the tpnt value to pass to _dl_runtime_resolver
29 r29: the PLT index of the invoked jump table entry.
30
31 We set up a frame entry that looks like this (in int_reg_t units):
32
33 +57: r25 return values from function...
34 +56: r24
35 [...]
36 +33: r1
37 +32: r0
38 +31: PLT index
39 +30: tpnt
40 +29: stackframe
41 +28: caller lr
42 +27: r25 arguments to function...
43 +26: r24
44 [...]
45 +3: r1
46 +2: r0
47 +1: standard ABI slot (sp)
48 +0: standard ABI slot (callee lr)
49
50 The entries from "stackframe" up are only used in _dl_profile_resolve.
51 We save and restore r0 through r25, rather than the strictly
52 architected r0 through r9, to support unusual calling conventions;
53 for example, __tls_get_addr takes r0 and returns r0, but promises
54 not to clobber r1 through r24 to support its usual fast path. */
55
56#define FRAME_SP (1 * REGSIZE)
57#define FRAME_REGS (2 * REGSIZE)
58#define FRAME_LR (28 * REGSIZE) /* Must follow FRAME_REGS */
59#define FRAME_STACKFRAME (29 * REGSIZE)
60#define FRAME_TPNT (30 * REGSIZE)
61#define FRAME_INDEX (31 * REGSIZE)
62#define FRAME_RETVAL (32 * REGSIZE)
63
64#define FRAME_SIZE_SMALL (30 * REGSIZE)
65#define FRAME_SIZE_LARGE (58 * REGSIZE)
66
67#define FOR_EACH_REG(f) \
68 f(r0); f(r1); f(r2); f(r3); \
69 f(r4); f(r5); f(r6); f(r7); \
70 f(r8); f(r9); f(r10); f(r11); \
71 f(r12); f(r13); f(r14); f(r15); \
72 f(r16); f(r17); f(r18); f(r19); \
73 f(r20); f(r21); f(r22); f(r23); \
74 f(r24); f(r25)
75
8d2d239c
AZ
76#define SAVE(REG) { st r27, REG; ADDI_PTR r27, r27, REGSIZE }
77#define RESTORE(REG) { ld REG, r27; ADDI_PTR r27, r27, REGSIZE }
63d143a2
CM
78
79 .macro dl_resolve, name, profile, framesize
80.text
81.global \name
82.hidden \name
83/* Note that cpp expands ENTRY(\name) incorrectly. */
84.type \name,@function
85.align 8
86\name:
87 cfi_startproc
88 {
8d2d239c 89 st sp, lr
63d143a2
CM
90 move r26, sp
91 }
92 {
93 ADDLI_PTR sp, sp, -\framesize
94 ADDLI_PTR r27, sp, FRAME_SP - \framesize
95 }
96 cfi_def_cfa_offset (\framesize)
97 {
8d2d239c 98 st r27, r26
63d143a2
CM
99 ADDI_PTR r27, r27, FRAME_REGS - FRAME_SP
100 }
101 FOR_EACH_REG(SAVE)
102 {
8d2d239c 103 st r27, lr
63d143a2
CM
104 ADDLI_PTR r27, sp, FRAME_TPNT
105 }
106 cfi_offset (lr, FRAME_LR - \framesize)
107 .if \profile
108 {
109 move r0, r28 /* tpnt value */
8d2d239c 110 st r27, r28
63d143a2
CM
111 ADDI_PTR r27, r27, FRAME_INDEX - FRAME_TPNT
112 }
113 {
114 move r1, r29 /* PLT index */
8d2d239c 115 st r27, r29
63d143a2
CM
116 }
117 {
118 move r2, lr /* retaddr */
119 ADDI_PTR r3, sp, FRAME_REGS /* La_tile_regs pointer */
120 }
121 {
122 ADDLI_PTR r4, sp, FRAME_STACKFRAME /* framesize pointer */
123 jal _dl_profile_fixup
124 }
125 ADDLI_PTR r28, sp, FRAME_STACKFRAME
126 LD_PTR r28, r28
8d2d239c 127 bgtz r28, 1f
63d143a2
CM
128 .else
129 {
130 move r0, r28 /* tpnt value 1 */
131 move r1, r29 /* PLT index 2 */
132 }
133 jal _dl_fixup
134 .endif
135 {
136 /* Copy aside the return value so we can restore r0 below. */
137 move r29, r0
138 /* Set up r27 to let us start restoring registers. */
139 ADDLI_PTR r27, sp, FRAME_REGS
140 }
141 FOR_EACH_REG(RESTORE)
142 .if \profile
143 ADDLI_PTR r28, sp, FRAME_STACKFRAME
8d2d239c
AZ
144 ld r28, r28
145 bgtz r28, 1f
63d143a2
CM
146 .endif
147 {
148 /* Restore original user return address. */
8d2d239c 149 ld lr, r27
63d143a2
CM
150 /* Pop off our stack frame. */
151 ADDLI_PTR sp, sp, \framesize
152 }
153 cfi_def_cfa_offset (0)
154 jr r29 /* Transfer control to freshly loaded code. */
155 jrp lr /* Keep backtracer happy. */
156
157 .if \profile
1581: jalr r29 /* Call resolved function. */
159 {
160 ADDLI_PTR r28, sp, FRAME_TPNT
161 ADDLI_PTR r27, sp, FRAME_RETVAL
162 }
163 FOR_EACH_REG(SAVE)
164 {
8d2d239c 165 ld r0, r28
63d143a2
CM
166 ADDI_PTR r28, r28, FRAME_INDEX - FRAME_TPNT
167 }
168 {
8d2d239c 169 ld r1, r28
63d143a2
CM
170 ADDLI_PTR r2, sp, FRAME_REGS
171 }
172 {
173 ADDLI_PTR r3, sp, FRAME_RETVAL
174 jal _dl_call_pltexit
175 }
176 {
177 ADDLI_PTR lr, sp, FRAME_LR
178 ADDLI_PTR r27, sp, FRAME_RETVAL
179 }
180 FOR_EACH_REG(RESTORE)
181 {
8d2d239c 182 ld lr, lr
63d143a2
CM
183 ADDLI_PTR sp, sp, \framesize
184 }
185 jrp lr
186 .endif
187END (\name)
188 .endm
189
190 dl_resolve _dl_runtime_resolve, 0, FRAME_SIZE_SMALL
191#ifndef PROF
192 dl_resolve _dl_runtime_profile, 1, FRAME_SIZE_LARGE
193#endif