summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/microblaze/sysdep.h
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps/linux/microblaze/sysdep.h')
-rw-r--r--libc/sysdeps/linux/microblaze/sysdep.h83
1 files changed, 81 insertions, 2 deletions
diff --git a/libc/sysdeps/linux/microblaze/sysdep.h b/libc/sysdeps/linux/microblaze/sysdep.h
index 1f01a2a1d..a463d339e 100644
--- a/libc/sysdeps/linux/microblaze/sysdep.h
+++ b/libc/sysdeps/linux/microblaze/sysdep.h
@@ -1,9 +1,25 @@
+/* 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
+ <http://www.gnu.org/licenses/>. */
+
#include <common/sysdep.h>
#ifdef __ASSEMBLER__
-/* Syntactic details of assembler. */
-
# define ALIGNARG(log2) log2
# define ASM_SIZE_DIRECTIVE(name) .size name,.-name
@@ -22,4 +38,67 @@
# 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)
+
+#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