authorgravatar for yangxudong@ymatrix.cnYANG Xudong <yangxudong@ymatrix.cn> 2024-08-15 05:32:03+08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-08-14 21:32:03+00:00
log0f0f543a9aceca57fe8eac437167667a7a501b1a
tree3e0fe5c555fe5273fae26930069e2e186b5ba2ad
parent9be10ea964f010099124f7aed8e71b0eb1c5d983
signaturebadge-check Signed by PGP key B5690EEEBB952194

loongarch: add glibc start.S to make zig-bootstrap work for loongarch64-linux-gnu (#21015)


5 files changed, 582 insertions(+), 0 deletions(-)

lib/libc/glibc/sysdeps/loongarch/bits/endianness.h created+11
...@@ -0,0 +1,11 @@
1#ifndef _BITS_ENDIANNESS_H
2#define _BITS_ENDIANNESS_H 1
3
4#ifndef _BITS_ENDIAN_H
5#error "Never use <bits/endianness.h> directly; include <endian.h> instead."
6#endif
7
8/* LoongArch is little-endian. */
9#define __BYTE_ORDER __LITTLE_ENDIAN
10
11#endif /* bits/endianness.h */
lib/libc/glibc/sysdeps/loongarch/start.S created+79
...@@ -0,0 +1,79 @@
1/* Startup code compliant to the ELF LoongArch ABI.
2 Copyright (C) 2022-2024 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 In addition to the permissions in the GNU Lesser General Public
11 License, the Free Software Foundation gives you unlimited
12 permission to link the compiled version of this file with other
13 programs, and to distribute those programs without any restriction
14 coming from the use of this file. (The GNU Lesser General Public
15 License restrictions do apply in other respects; for example, they
16 cover modification of the file, and distribution when not linked
17 into another program.)
18
19 Note that people who make modified versions of this file are not
20 obligated to grant this special exception for their modified
21 versions; it is their choice whether to do so. The GNU Lesser
22 General Public License gives permission to release a modified
23 version without this exception; this exception also makes it
24 possible to release a modified version which carries forward this
25 exception.
26
27 The GNU C Library is distributed in the hope that it will be useful,
28 but WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30 Lesser General Public License for more details.
31
32 You should have received a copy of the GNU Lesser General Public
33 License along with the GNU C Library; if not, see
34 <https://www.gnu.org/licenses/>. */
35
36#define __ASSEMBLY__ 1
37#include <entry.h>
38#include <sys/asm.h>
39
40/* The entry point's job is to call __libc_start_main. Per the ABI,
41 a0 contains the address of a function to be passed to atexit.
42 __libc_start_main wants this in a5. */
43
44/*
45int
46__libc_start_main (int (*main) (int, char **, char **),
47 int argc,
48 char **argv,
49 __typeof (main) init,
50 void (*fini) (void),
51 void (*rtld_fini) (void),
52 void *stack_end);
53 */
54
55ENTRY (ENTRY_POINT)
56
57/* Terminate call stack by noting ra is undefined. Use a dummy
58 .cfi_label to force starting the FDE. */
59 .cfi_label .Ldummy
60 cfi_undefined (1)
61 or a5, a0, zero /* rtld_fini */
62
63 la.pcrel a0, t0, main
64 REG_L a1, sp, 0
65 ADDI a2, sp, SZREG
66
67 /* Adjust $sp for 16-aligned */
68 BSTRINS sp, zero, 3, 0
69
70 move a3, zero /* used to be init */
71 move a4, zero /* used to be fini */
72 or a6, sp, zero /* stack_end */
73
74 la.pcrel ra, t0, __libc_start_main
75 jirl ra, ra, 0
76
77 la.pcrel ra, t0, abort
78 jirl ra, ra, 0
79END (ENTRY_POINT)
lib/libc/glibc/sysdeps/loongarch/sys/regdef.h created+169
...@@ -0,0 +1,169 @@
1/* Register Macro definitions
2 Copyright (C) 2022-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library. If not, see
18 <https://www.gnu.org/licenses/>. */
19
20#ifndef _SYS_REGDEF_H
21#define _SYS_REGDEF_H
22
23#define zero $r0
24#define ra $r1
25#define tp $r2
26#define sp $r3
27#define a0 $r4
28#define a1 $r5
29#define a2 $r6
30#define a3 $r7
31#define a4 $r8
32#define a5 $r9
33#define a6 $r10
34#define a7 $r11
35#define v0 $r4
36#define v1 $r5
37#define t0 $r12
38#define t1 $r13
39#define t2 $r14
40#define t3 $r15
41#define t4 $r16
42#define t5 $r17
43#define t6 $r18
44#define t7 $r19
45#define t8 $r20
46#define x $r21
47#define fp $r22
48#define s0 $r23
49#define s1 $r24
50#define s2 $r25
51#define s3 $r26
52#define s4 $r27
53#define s5 $r28
54#define s6 $r29
55#define s7 $r30
56#define s8 $r31
57
58#define fa0 $f0
59#define fa1 $f1
60#define fa2 $f2
61#define fa3 $f3
62#define fa4 $f4
63#define fa5 $f5
64#define fa6 $f6
65#define fa7 $f7
66#define fv0 $f0
67#define fv1 $f1
68#define ft0 $f8
69#define ft1 $f9
70#define ft2 $f10
71#define ft3 $f11
72#define ft4 $f12
73#define ft5 $f13
74#define ft6 $f14
75#define ft7 $f15
76#define ft8 $f16
77#define ft9 $f17
78#define ft10 $f18
79#define ft11 $f19
80#define ft12 $f20
81#define ft13 $f21
82#define ft14 $f22
83#define ft15 $f23
84#define fs0 $f24
85#define fs1 $f25
86#define fs2 $f26
87#define fs3 $f27
88#define fs4 $f28
89#define fs5 $f29
90#define fs6 $f30
91#define fs7 $f31
92#define fcc0 $fcc0
93#define fcc1 $fcc1
94#define fcc2 $fcc2
95#define fcc3 $fcc3
96#define fcc4 $fcc4
97#define fcc5 $fcc5
98#define fcc6 $fcc6
99#define fcc7 $fcc7
100#define fcsr0 $fcsr0
101
102#define vr0 $vr0
103#define vr1 $vr1
104#define vr2 $vr2
105#define vr3 $vr3
106#define vr4 $vr4
107#define vr5 $vr5
108#define vr6 $vr6
109#define vr7 $vr7
110#define vr8 $vr8
111#define vr9 $vr9
112#define vr10 $vr10
113#define vr11 $vr11
114#define vr12 $vr12
115#define vr13 $vr13
116#define vr14 $vr14
117#define vr15 $vr15
118#define vr16 $vr16
119#define vr17 $vr17
120#define vr18 $vr18
121#define vr19 $vr19
122#define vr20 $vr20
123#define vr21 $vr21
124#define vr22 $vr22
125#define vr23 $vr23
126#define vr24 $vr24
127#define vr25 $vr25
128#define vr26 $vr26
129#define vr27 $vr27
130#define vr28 $vr28
131#define vr29 $vr29
132#define vr30 $vr30
133#define vr31 $vr31
134
135#define xr0 $xr0
136#define xr1 $xr1
137#define xr2 $xr2
138#define xr3 $xr3
139#define xr4 $xr4
140#define xr5 $xr5
141#define xr6 $xr6
142#define xr7 $xr7
143#define xr7 $xr7
144#define xr8 $xr8
145#define xr9 $xr9
146#define xr10 $xr10
147#define xr11 $xr11
148#define xr12 $xr12
149#define xr13 $xr13
150#define xr14 $xr14
151#define xr15 $xr15
152#define xr16 $xr16
153#define xr17 $xr17
154#define xr18 $xr18
155#define xr19 $xr19
156#define xr20 $xr20
157#define xr21 $xr21
158#define xr22 $xr22
159#define xr23 $xr23
160#define xr24 $xr24
161#define xr25 $xr25
162#define xr26 $xr26
163#define xr27 $xr27
164#define xr28 $xr28
165#define xr29 $xr29
166#define xr30 $xr30
167#define xr31 $xr31
168
169#endif /* _SYS_REGDEF_H */
lib/libc/glibc/sysdeps/unix/sysv/linux/loongarch/sysdep.h created+318
...@@ -0,0 +1,318 @@
1/* Assembly macros for LoongArch.
2 Copyright (C) 2022-2024 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#ifndef _LINUX_LOONGARCH_SYSDEP_H
20#define _LINUX_LOONGARCH_SYSDEP_H 1
21
22#include <sysdeps/unix/sysv/linux/sysdep.h>
23#include <sysdeps/unix/sysdep.h>
24#include <tls.h>
25
26#ifdef __ASSEMBLER__
27
28#include <sys/asm.h>
29#define ret jirl zero, ra, 0
30#define L(label) .L##label
31
32/* Performs a system call, handling errors by setting errno. Linux indicates
33 errors by setting a0 to a value between -1 and -4095. */
34#undef PSEUDO
35#define PSEUDO(name, syscall_name, args) \
36 ENTRY (name); \
37 li.d a7, SYS_ify (syscall_name); \
38 syscall 0; \
39 li.d a7, -4096; \
40 bltu a7, a0, .Lsyscall_error##name;
41
42#undef PSEUDO_END
43#define PSEUDO_END(sym) \
44 SYSCALL_ERROR_HANDLER (sym); \
45 ret; \
46 END (sym);
47
48#if !IS_IN(libc)
49#if RTLD_PRIVATE_ERRNO
50
51#define SYSCALL_ERROR_HANDLER(name) \
52 .Lsyscall_error##name : la t0, rtld_errno; \
53 sub.w a0, zero, a0; \
54 st.w a0, t0, 0; \
55 li.d a0, -1;
56
57#else
58
59#define SYSCALL_ERROR_HANDLER(name) \
60 .Lsyscall_error##name : la.tls.ie t0, errno; \
61 add.d t0, tp, t0; \
62 sub.w a0, zero, a0; \
63 st.w a0, t0, 0; \
64 li.d a0, -1;
65
66#endif
67#else
68
69#define SYSCALL_ERROR_HANDLER(name) .Lsyscall_error##name : b __syscall_error;
70
71#endif
72
73/* Performs a system call, not setting errno. */
74#undef PSEUDO_NEORRNO
75#define PSEUDO_NOERRNO(name, syscall_name, args) \
76 ENTRY (name); \
77 li.d a7, SYS_ify (syscall_name); \
78 syscall 0;
79
80#undef PSEUDO_END_NOERRNO
81#define PSEUDO_END_NOERRNO(name) END (name);
82
83#undef ret_NOERRNO
84#define ret_NOERRNO ret
85
86/* Performs a system call, returning the error code. */
87#undef PSEUDO_ERRVAL
88#define PSEUDO_ERRVAL(name, syscall_name, args) \
89 PSEUDO_NOERRNO (name, syscall_name, args); \
90 slli.d a0, a0, 32; \
91 srai.d a0, a0, 32; /* sign_ext */ \
92 sub.d a0, zero, a0;
93
94#undef PSEUDO_END_ERRVAL
95#define PSEUDO_END_ERRVAL(name) END (name);
96
97#undef ret_ERRVAL
98#define ret_ERRVAL ret
99
100#endif /* __ASSEMBLER__ */
101
102/* In order to get __set_errno() definition in INLINE_SYSCALL. */
103#ifndef __ASSEMBLER__
104#include <errno.h>
105#endif
106
107#include <sysdeps/unix/sysdep.h>
108
109#undef SYS_ify
110#define SYS_ify(syscall_name) __NR_##syscall_name
111
112#ifndef __ASSEMBLER__
113
114#define VDSO_NAME "LINUX_5.10"
115#define VDSO_HASH 182947696
116
117/* List of system calls which are supported as vsyscalls. */
118#define HAVE_CLOCK_GETRES64_VSYSCALL "__vdso_clock_getres"
119#define HAVE_CLOCK_GETTIME64_VSYSCALL "__vdso_clock_gettime"
120#define HAVE_GETTIMEOFDAY_VSYSCALL "__vdso_gettimeofday"
121#define HAVE_GETCPU_VSYSCALL "__vdso_getcpu"
122
123#define HAVE_CLONE3_WRAPPER 1
124
125#define INTERNAL_SYSCALL(name, nr, args...) \
126 internal_syscall##nr (SYS_ify (name), args)
127
128#define INTERNAL_SYSCALL_NCS(number, nr, args...) \
129 internal_syscall##nr (number, args)
130
131#define internal_syscall0(number, dummy...) \
132 ({ \
133 long int _sys_result; \
134\
135 { \
136 register long int __a7 asm ("$a7") = number; \
137 register long int __a0 asm ("$a0"); \
138 __asm__ volatile ("syscall 0\n\t" \
139 : "=r"(__a0) \
140 : "r"(__a7) \
141 : __SYSCALL_CLOBBERS); \
142 _sys_result = __a0; \
143 } \
144 _sys_result; \
145 })
146
147#define internal_syscall1(number, arg0) \
148 ({ \
149 long int _sys_result; \
150\
151 { \
152 long int _arg0 = (long int) (arg0); \
153 register long int __a7 asm ("$a7") = number; \
154 register long int __a0 asm ("$a0") = _arg0; \
155 __asm__ volatile ("syscall 0\n\t" \
156 : "+r"(__a0) \
157 : "r"(__a7) \
158 : __SYSCALL_CLOBBERS); \
159 _sys_result = __a0; \
160 } \
161 _sys_result; \
162 })
163
164#define internal_syscall2(number, arg0, arg1) \
165 ({ \
166 long int _sys_result; \
167\
168 { \
169 long int _arg0 = (long int) (arg0); \
170 long int _arg1 = (long int) (arg1); \
171 register long int __a7 asm ("$a7") = number; \
172 register long int __a0 asm ("$a0") = _arg0; \
173 register long int __a1 asm ("$a1") = _arg1; \
174 __asm__ volatile ("syscall 0\n\t" \
175 : "+r"(__a0) \
176 : "r"(__a7), "r"(__a1) \
177 : __SYSCALL_CLOBBERS); \
178 _sys_result = __a0; \
179 } \
180 _sys_result; \
181 })
182
183#define internal_syscall3(number, arg0, arg1, arg2) \
184 ({ \
185 long int _sys_result; \
186\
187 { \
188 long int _arg0 = (long int) (arg0); \
189 long int _arg1 = (long int) (arg1); \
190 long int _arg2 = (long int) (arg2); \
191 register long int __a7 asm ("$a7") = number; \
192 register long int __a0 asm ("$a0") = _arg0; \
193 register long int __a1 asm ("$a1") = _arg1; \
194 register long int __a2 asm ("$a2") = _arg2; \
195 __asm__ volatile ("syscall 0\n\t" \
196 : "+r"(__a0) \
197 : "r"(__a7), "r"(__a1), "r"(__a2) \
198 : __SYSCALL_CLOBBERS); \
199 _sys_result = __a0; \
200 } \
201 _sys_result; \
202 })
203
204#define internal_syscall4(number, arg0, arg1, arg2, arg3) \
205 ({ \
206 long int _sys_result; \
207\
208 { \
209 long int _arg0 = (long int) (arg0); \
210 long int _arg1 = (long int) (arg1); \
211 long int _arg2 = (long int) (arg2); \
212 long int _arg3 = (long int) (arg3); \
213 register long int __a7 asm ("$a7") = number; \
214 register long int __a0 asm ("$a0") = _arg0; \
215 register long int __a1 asm ("$a1") = _arg1; \
216 register long int __a2 asm ("$a2") = _arg2; \
217 register long int __a3 asm ("$a3") = _arg3; \
218 __asm__ volatile ("syscall 0\n\t" \
219 : "+r"(__a0) \
220 : "r"(__a7), "r"(__a1), "r"(__a2), "r"(__a3) \
221 : __SYSCALL_CLOBBERS); \
222 _sys_result = __a0; \
223 } \
224 _sys_result; \
225 })
226
227#define internal_syscall5(number, arg0, arg1, arg2, arg3, arg4) \
228 ({ \
229 long int _sys_result; \
230\
231 { \
232 long int _arg0 = (long int) (arg0); \
233 long int _arg1 = (long int) (arg1); \
234 long int _arg2 = (long int) (arg2); \
235 long int _arg3 = (long int) (arg3); \
236 long int _arg4 = (long int) (arg4); \
237 register long int __a7 asm ("$a7") = number; \
238 register long int __a0 asm ("$a0") = _arg0; \
239 register long int __a1 asm ("$a1") = _arg1; \
240 register long int __a2 asm ("$a2") = _arg2; \
241 register long int __a3 asm ("$a3") = _arg3; \
242 register long int __a4 asm ("$a4") = _arg4; \
243 __asm__ volatile ("syscall 0\n\t" \
244 : "+r"(__a0) \
245 : "r"(__a7), "r"(__a1), "r"(__a2), \
246 "r"(__a3), "r"(__a4) \
247 : __SYSCALL_CLOBBERS); \
248 _sys_result = __a0; \
249 } \
250 _sys_result; \
251 })
252
253#define internal_syscall6(number, arg0, arg1, arg2, arg3, arg4, arg5) \
254 ({ \
255 long int _sys_result; \
256\
257 { \
258 long int _arg0 = (long int) (arg0); \
259 long int _arg1 = (long int) (arg1); \
260 long int _arg2 = (long int) (arg2); \
261 long int _arg3 = (long int) (arg3); \
262 long int _arg4 = (long int) (arg4); \
263 long int _arg5 = (long int) (arg5); \
264 register long int __a7 asm ("$a7") = number; \
265 register long int __a0 asm ("$a0") = _arg0; \
266 register long int __a1 asm ("$a1") = _arg1; \
267 register long int __a2 asm ("$a2") = _arg2; \
268 register long int __a3 asm ("$a3") = _arg3; \
269 register long int __a4 asm ("$a4") = _arg4; \
270 register long int __a5 asm ("$a5") = _arg5; \
271 __asm__ volatile ("syscall 0\n\t" \
272 : "+r"(__a0) \
273 : "r"(__a7), "r"(__a1), "r"(__a2), "r"(__a3), \
274 "r"(__a4), "r"(__a5) \
275 : __SYSCALL_CLOBBERS); \
276 _sys_result = __a0; \
277 } \
278 _sys_result; \
279 })
280
281#define internal_syscall7(number, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
282 ({ \
283 long int _sys_result; \
284\
285 { \
286 long int _arg0 = (long int) (arg0); \
287 long int _arg1 = (long int) (arg1); \
288 long int _arg2 = (long int) (arg2); \
289 long int _arg3 = (long int) (arg3); \
290 long int _arg4 = (long int) (arg4); \
291 long int _arg5 = (long int) (arg5); \
292 long int _arg6 = (long int) (arg6); \
293 register long int __a7 asm ("$a7") = number; \
294 register long int __a0 asm ("$a0") = _arg0; \
295 register long int __a1 asm ("$a1") = _arg1; \
296 register long int __a2 asm ("$a2") = _arg2; \
297 register long int __a3 asm ("$a3") = _arg3; \
298 register long int __a4 asm ("$a4") = _arg4; \
299 register long int __a5 asm ("$a5") = _arg5; \
300 register long int __a6 asm ("$a6") = _arg6; \
301 __asm__ volatile ("syscall 0\n\t" \
302 : "+r"(__a0) \
303 : "r"(__a7), "r"(__a1), "r"(__a2), "r"(__a3), \
304 "r"(__a4), "r"(__a5), "r"(__a6) \
305 : __SYSCALL_CLOBBERS); \
306 _sys_result = __a0; \
307 } \
308 _sys_result; \
309 })
310
311#define __SYSCALL_CLOBBERS \
312 "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8", "memory"
313
314extern long int __syscall_error (long int neg_errno);
315
316#endif /* ! __ASSEMBLER__ */
317
318#endif /* linux/loongarch/sysdep.h */
src/glibc.zig+5
...@@ -461,6 +461,8 @@ fn start_asm_path(comp: *Compilation, arena: Allocator, basename: []const u8) ![...@@ -461,6 +461,8 @@ fn start_asm_path(comp: *Compilation, arena: Allocator, basename: []const u8) ![
461 } else {461 } else {
462 try result.appendSlice("powerpc" ++ s ++ "powerpc32");462 try result.appendSlice("powerpc" ++ s ++ "powerpc32");
463 }463 }
464 } else if (arch.isLoongArch()) {
465 try result.appendSlice("loongarch");
464 }466 }
465467
466 try result.appendSlice(s);468 try result.appendSlice(s);
...@@ -649,6 +651,9 @@ fn add_include_dirs_arch(...@@ -649,6 +651,9 @@ fn add_include_dirs_arch(
649 try args.append("-I");651 try args.append("-I");
650 try args.append(try path.join(arena, &[_][]const u8{ dir, "riscv" }));652 try args.append(try path.join(arena, &[_][]const u8{ dir, "riscv" }));
651 }653 }
654 } else if (arch.isLoongArch()) {
655 try args.append("-I");
656 try args.append(try path.join(arena, &[_][]const u8{ dir, "loongarch" }));
652 }657 }
653}658}
654659