summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/riscv32/sysdep.h
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps/linux/riscv32/sysdep.h')
-rw-r--r--libc/sysdeps/linux/riscv32/sysdep.h126
1 files changed, 126 insertions, 0 deletions
diff --git a/libc/sysdeps/linux/riscv32/sysdep.h b/libc/sysdeps/linux/riscv32/sysdep.h
new file mode 100644
index 000000000..3fa04bb57
--- /dev/null
+++ b/libc/sysdeps/linux/riscv32/sysdep.h
@@ -0,0 +1,126 @@
+/* Assembly macros for RISC-V.
+ Copyright (C) 2011-2018
+ 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/>. */
+
+#ifndef _LINUX_RISCV_SYSDEP_H
+#define _LINUX_RISCV_SYSDEP_H 1
+
+#include <common/sysdep.h>
+#include <sys/syscall.h>
+
+#ifdef __ASSEMBLER__
+
+# include <sys/asm.h>
+
+# define ENTRY(name) LEAF(name)
+
+# define L(label) .L ## label
+
+/* Performs a system call, handling errors by setting errno. Linux indicates
+ errors by setting a0 to a value between -1 and -4095. */
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
+ .text; \
+ .align 2; \
+ ENTRY (name); \
+ li a7, SYS_ify (syscall_name); \
+ scall; \
+ li a7, -4096; \
+ bgtu a0, a7, .Lsyscall_error ## name;
+
+# undef PSEUDO_END
+# define PSEUDO_END(sym) \
+ SYSCALL_ERROR_HANDLER (sym) \
+ ret; \
+ END (sym)
+
+# if !IS_IN_libc
+# if defined (__PIC__)
+# define SYSCALL_ERROR_HANDLER(name) \
+.Lsyscall_error ## name: \
+ la.tls.ie t1, errno; \
+ add t1, t1, tp; \
+ neg a0, a0; \
+ sw a0, 0(t1); \
+ li a0, -1;
+# else
+# define SYSCALL_ERROR_HANDLER(name) \
+.Lsyscall_error ## name: \
+ lui t1, %tprel_hi(errno); \
+ add t1, t1, tp, %tprel_add(errno); \
+ neg a0, a0; \
+ sw a0, %tprel_lo(errno)(t1); \
+ li a0, -1;
+# endif
+# else
+# define SYSCALL_ERROR_HANDLER(name) \
+.Lsyscall_error ## name: \
+ j __syscall_error;
+# endif
+
+/* Performs a system call, not setting errno. */
+# undef PSEUDO_NEORRNO
+# define PSEUDO_NOERRNO(name, syscall_name, args) \
+ .align 2; \
+ ENTRY (name); \
+ li a7, SYS_ify (syscall_name); \
+ scall;
+
+# undef PSEUDO_END_NOERRNO
+# define PSEUDO_END_NOERRNO(name) \
+ END (name)
+
+# undef ret_NOERRNO
+# define ret_NOERRNO ret
+
+/* Perfroms a system call, returning the error code. */
+# undef PSEUDO_ERRVAL
+# define PSEUDO_ERRVAL(name, syscall_name, args) \
+ PSEUDO_NOERRNO (name, syscall_name, args) \
+ neg a0, a0;
+
+# undef PSEUDO_END_ERRVAL
+# define PSEUDO_END_ERRVAL(name) \
+ END (name)
+
+# undef ret_ERRVAL
+# define ret_ERRVAL ret
+
+#endif /* __ASSEMBLER__ */
+
+/* In order to get __set_errno() definition in INLINE_SYSCALL. */
+#ifndef __ASSEMBLER__
+# include <errno.h>
+#endif
+
+#undef SYS_ify
+#define SYS_ify(syscall_name) __NR_##syscall_name
+
+#ifndef __ASSEMBLER__
+
+/* List of system calls which are supported as vsyscalls. */
+# define HAVE_CLOCK_GETRES_VSYSCALL 1
+# define HAVE_CLOCK_GETTIME_VSYSCALL 1
+# define HAVE_GETTIMEOFDAY_VSYSCALL 1
+# define HAVE_GETCPU_VSYSCALL 1
+
+
+extern long int __syscall_error (long int neg_errno);
+
+#endif /* ! __ASSEMBLER__ */
+
+#endif /* linux/riscv/sysdep.h */