/* Copyright (C) 2000-2016 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
. */
#include
#ifdef __ASSEMBLER__
# define ALIGNARG(log2) log2
# define ASM_SIZE_DIRECTIVE(name) .size name,.-name
/* Define an entry point visible from C. */
# define ENTRY(name) \
.globl C_SYMBOL_NAME(name); \
.type C_SYMBOL_NAME(name),@function; \
.align ALIGNARG(2); \
C_LABEL(name)
# undef END
# define END(name) ASM_SIZE_DIRECTIVE(name)
/* Local label name for asm code. */
# ifndef L
# define L(name) $L##name
# endif
/* We don't want the label for the error handler to be visible in the symbol
table when we define it here. */
# ifdef __PIC__
# define SYSCALL_ERROR_LABEL 0f
# else
# define SYSCALL_ERROR_LABEL __syscall_error
# endif
# define DO_CALL(syscall_name, args) \
addik r12,r0,SYS_ify (syscall_name); \
brki r14,8; \
addk r0,r0,r0;
# undef PSEUDO
# define PSEUDO(name, syscall_name, args) \
.text; \
ENTRY (name) \
DO_CALL (syscall_name, args); \
addik r12,r0,-4095; \
cmpu r12,r12,r3; \
bgei r12,SYSCALL_ERROR_LABEL;
# undef PSEUDO_END
# define PSEUDO_END(name) \
SYSCALL_ERROR_HANDLER; \
END (name)
# undef PSEUDO_NOERRNO
# define PSEUDO_NOERRNO(name, syscall_name, args) \
.text; \
ENTRY (name) \
DO_CALL (syscall_name, args);
# undef PSEUDO_END_NOERRNO
# define PSEUDO_END_NOERRNO(name) \
END (name)
/* The function has to return the error code. */
# undef PSEUDO_ERRVAL
# define PSEUDO_ERRVAL(name, syscall_name, args) \
.text; \
ENTRY (name) \
DO_CALL (syscall_name, args); \
# undef PSEUDO_END_ERRVAL
# define PSEUDO_END_ERRVAL(name) \
END (name)
# undef ret_NOERRNO
# define ret_NOERRNO \
rtsd r15,8; addk r0,r0,r0;
# undef ret_ERRVAL
# define ret_ERRVAL \
rtsd r15,8; rsubk r3,r3,r0;
#ifdef __PIC__
# define SYSCALL_ERROR_LABEL_DCL 0
# if defined _LIBC_REENTRANT
# define SYSCALL_ERROR_HANDLER \
SYSCALL_ERROR_LABEL_DCL: \
addik r1,r1,-16; \
swi r15,r1,0; \
swi r20,r1,8; \
rsubk r3,r3,r0; \
swi r3,r1,12; \
mfs r20,rpc; \
addik r20,r20,_GLOBAL_OFFSET_TABLE_+8; \
brlid r15,__errno_location@PLT; \
nop; \
lwi r4,r1,12; \
swi r4,r3,0; \
lwi r20,r1,8; \
lwi r15,r1,0; \
addik r1,r1,16; \
rtsd r15,8; \
addik r3,r0,-1;
# else /* !_LIBC_REENTRANT. */
# define SYSCALL_ERROR_HANDLER \
SYSCALL_ERROR_LABEL_DCL: \
mfs r12,rpc; \
addik r12,r12,_GLOBAL_OFFSET_TABLE_+8; \
lwi r12,r12,errno@GOT; \
rsubk r3,r3,r0; \
swi r3,r12,0; \
rtsd r15,8; \
addik r3,r0,-1;
# endif /* _LIBC_REENTRANT. */
#else
# define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */
#endif /* PIC. */
#endif