1 /* PLT trampolines.
2 Copyright (C) 2022-2023 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 /* Assembler veneer called from the PLT header code for lazy loading.
20 The PLT header passes its own args in t0-t2. */
21 #ifdef USE_LASX
22 # define FRAME_SIZE (-((-9 * SZREG - 8 * SZFREG - 8 * SZXREG) & ALMASK))
23 #elif defined USE_LSX
24 # define FRAME_SIZE (-((-9 * SZREG - 8 * SZFREG - 8 * SZVREG) & ALMASK))
25 #elif !defined __loongarch_soft_float
26 # define FRAME_SIZE (-((-9 * SZREG - 8 * SZFREG) & ALMASK))
27 #else
28 # define FRAME_SIZE (-((-9 * SZREG) & ALMASK))
29 #endif
30
31 ENTRY (_dl_runtime_resolve)
32
33 /* Save arguments to stack. */
34 ADDI sp, sp, -FRAME_SIZE
35
36 REG_S ra, sp, 0*SZREG
37 REG_S a0, sp, 1*SZREG
38 REG_S a1, sp, 2*SZREG
39 REG_S a2, sp, 3*SZREG
40 REG_S a3, sp, 4*SZREG
41 REG_S a4, sp, 5*SZREG
42 REG_S a5, sp, 6*SZREG
43 REG_S a6, sp, 7*SZREG
44 REG_S a7, sp, 8*SZREG
45
46 #ifdef USE_LASX
47 xvst xr0, sp, 9*SZREG + 8*SZFREG + 0*SZXREG
48 xvst xr1, sp, 9*SZREG + 8*SZFREG + 1*SZXREG
49 xvst xr2, sp, 9*SZREG + 8*SZFREG + 2*SZXREG
50 xvst xr3, sp, 9*SZREG + 8*SZFREG + 3*SZXREG
51 xvst xr4, sp, 9*SZREG + 8*SZFREG + 4*SZXREG
52 xvst xr5, sp, 9*SZREG + 8*SZFREG + 5*SZXREG
53 xvst xr6, sp, 9*SZREG + 8*SZFREG + 6*SZXREG
54 xvst xr7, sp, 9*SZREG + 8*SZFREG + 7*SZXREG
55 #elif defined USE_LSX
56 vst vr0, sp, 9*SZREG + 8*SZFREG + 0*SZVREG
57 vst vr1, sp, 9*SZREG + 8*SZFREG + 1*SZVREG
58 vst vr2, sp, 9*SZREG + 8*SZFREG + 2*SZVREG
59 vst vr3, sp, 9*SZREG + 8*SZFREG + 3*SZVREG
60 vst vr4, sp, 9*SZREG + 8*SZFREG + 4*SZVREG
61 vst vr5, sp, 9*SZREG + 8*SZFREG + 5*SZVREG
62 vst vr6, sp, 9*SZREG + 8*SZFREG + 6*SZVREG
63 vst vr7, sp, 9*SZREG + 8*SZFREG + 7*SZVREG
64 #elif !defined __loongarch_soft_float
65 FREG_S fa0, sp, 9*SZREG + 0*SZFREG
66 FREG_S fa1, sp, 9*SZREG + 1*SZFREG
67 FREG_S fa2, sp, 9*SZREG + 2*SZFREG
68 FREG_S fa3, sp, 9*SZREG + 3*SZFREG
69 FREG_S fa4, sp, 9*SZREG + 4*SZFREG
70 FREG_S fa5, sp, 9*SZREG + 5*SZFREG
71 FREG_S fa6, sp, 9*SZREG + 6*SZFREG
72 FREG_S fa7, sp, 9*SZREG + 7*SZFREG
73 #endif
74
75 /* Update .got.plt and obtain runtime address of callee */
76 SLLI a1, t1, 1
77 or a0, t0, zero
78 ADD a1, a1, t1
79 la a2, _dl_fixup
80 jirl ra, a2, 0
81 or t1, v0, zero
82
83 /* Restore arguments from stack. */
84 REG_L ra, sp, 0*SZREG
85 REG_L a0, sp, 1*SZREG
86 REG_L a1, sp, 2*SZREG
87 REG_L a2, sp, 3*SZREG
88 REG_L a3, sp, 4*SZREG
89 REG_L a4, sp, 5*SZREG
90 REG_L a5, sp, 6*SZREG
91 REG_L a6, sp, 7*SZREG
92 REG_L a7, sp, 8*SZREG
93
94 #ifdef USE_LASX
95 xvld xr0, sp, 9*SZREG + 8*SZFREG + 0*SZXREG
96 xvld xr1, sp, 9*SZREG + 8*SZFREG + 1*SZXREG
97 xvld xr2, sp, 9*SZREG + 8*SZFREG + 2*SZXREG
98 xvld xr3, sp, 9*SZREG + 8*SZFREG + 3*SZXREG
99 xvld xr4, sp, 9*SZREG + 8*SZFREG + 4*SZXREG
100 xvld xr5, sp, 9*SZREG + 8*SZFREG + 5*SZXREG
101 xvld xr6, sp, 9*SZREG + 8*SZFREG + 6*SZXREG
102 xvld xr7, sp, 9*SZREG + 8*SZFREG + 7*SZXREG
103 #elif defined USE_LSX
104 vld vr0, sp, 9*SZREG + 8*SZFREG + 0*SZVREG
105 vld vr1, sp, 9*SZREG + 8*SZFREG + 1*SZVREG
106 vld vr2, sp, 9*SZREG + 8*SZFREG + 2*SZVREG
107 vld vr3, sp, 9*SZREG + 8*SZFREG + 3*SZVREG
108 vld vr4, sp, 9*SZREG + 8*SZFREG + 4*SZVREG
109 vld vr5, sp, 9*SZREG + 8*SZFREG + 5*SZVREG
110 vld vr6, sp, 9*SZREG + 8*SZFREG + 6*SZVREG
111 vld vr7, sp, 9*SZREG + 8*SZFREG + 7*SZVREG
112 #elif !defined __loongarch_soft_float
113 FREG_L fa0, sp, 9*SZREG + 0*SZFREG
114 FREG_L fa1, sp, 9*SZREG + 1*SZFREG
115 FREG_L fa2, sp, 9*SZREG + 2*SZFREG
116 FREG_L fa3, sp, 9*SZREG + 3*SZFREG
117 FREG_L fa4, sp, 9*SZREG + 4*SZFREG
118 FREG_L fa5, sp, 9*SZREG + 5*SZFREG
119 FREG_L fa6, sp, 9*SZREG + 6*SZFREG
120 FREG_L fa7, sp, 9*SZREG + 7*SZFREG
121 #endif
122
123 ADDI sp, sp, FRAME_SIZE
124
125 /* Invoke the callee. */
126 jirl zero, t1, 0
127 END (_dl_runtime_resolve)