1/* Copyright (C) 1993-2022 Free Software Foundation, Inc.
2   This file is part of the GNU C Library.
3
4   The GNU C Library is free software; you can redistribute it and/or
5   modify it under the terms of the GNU Lesser General Public
6   License as published by the Free Software Foundation; either
7   version 2.1 of the License, or (at your option) any later version.
8
9   The GNU C Library is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   Lesser General Public License for more details.
13
14   You should have received a copy of the GNU Lesser General Public
15   License along with the GNU C Library.  If not, see
16   <https://www.gnu.org/licenses/>.  */
17
18#include <sysdep.h>
19#include <features.h>
20
21#if defined(PIC)
22	/* Put this at the end of libc's text segment so that all of
23	   the direct branches from the syscalls are forward, and
24	   thus predicted not taken.  */
25	.section .text.last, "ax", @progbits
26#else
27	.text
28#endif
29
30#if IS_IN (libc)
31# define SYSCALL_ERROR_ERRNO __libc_errno
32#else
33# define SYSCALL_ERROR_ERRNO errno
34#endif
35
36	.align 4
37	.globl	__syscall_error
38	.ent	__syscall_error
39__syscall_error:
40	/* When building a shared library, we branch here without having
41	   loaded the GP.  Nor, since it was a direct branch, have we
42	   loaded PV with our address.
43
44	   When building a static library, we tail call here from another
45	   object file, possibly with a different GP, and must return with
46	   the GP of our caller in place so that linker relaxation works.
47
48	   Both issues are solved by computing the GP into T1 instead of
49	   clobbering the traditional GP register.  */
50	.prologue 0
51	mov	v0, t0
52	br	t1, 1f
531:	ldah	t1, 0(t1) !gpdisp!1
54	call_pal PAL_rduniq
55
56	lda	t1, 0(t1) !gpdisp!1
57	ldq	t1, SYSCALL_ERROR_ERRNO(t1) !gottprel
58	addq	v0, t1, t1
59	lda	v0, -1
60
61	stl	t0, 0(t1)
62	ret
63
64	.end __syscall_error
65