1 /* Assembly macros for RISC-V.
2    Copyright (C) 2011-2018
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    <http://www.gnu.org/licenses/>.  */
18 
19 #ifndef _LINUX_RISCV_SYSDEP_H
20 #define _LINUX_RISCV_SYSDEP_H 1
21 
22 #include <common/sysdep.h>
23 #include <sys/syscall.h>
24 
25 #ifdef __ASSEMBLER__
26 
27 # include <sys/asm.h>
28 
29 # define ENTRY(name) LEAF(name)
30 
31 # define L(label) .L ## label
32 
33 /* Performs a system call, handling errors by setting errno.  Linux indicates
34    errors by setting a0 to a value between -1 and -4095.  */
35 # undef PSEUDO
36 # define PSEUDO(name, syscall_name, args)			\
37   .text;							\
38   .align 2;							\
39   ENTRY (name);							\
40   li a7, SYS_ify (syscall_name);				\
41   scall;							\
42   li a7, -4096;							\
43   bgtu a0, a7, .Lsyscall_error ## name;
44 
45 # undef PSEUDO_END
46 # define PSEUDO_END(sym) 					\
47   SYSCALL_ERROR_HANDLER (sym)					\
48   ret;								\
49   END (sym)
50 
51 # if !IS_IN_libc
52 #  if defined (__PIC__)
53 #   define SYSCALL_ERROR_HANDLER(name)				\
54 .Lsyscall_error ## name:					\
55         la.tls.ie t1, errno;					\
56 	add t1, t1, tp;						\
57 	neg a0, a0;						\
58 	sw a0, 0(t1);						\
59         li a0, -1;
60 #  else
61 #   define SYSCALL_ERROR_HANDLER(name)				\
62 .Lsyscall_error ## name:					\
63         lui t1, %tprel_hi(errno);				\
64         add t1, t1, tp, %tprel_add(errno);			\
65 	neg a0, a0;						\
66         sw a0, %tprel_lo(errno)(t1);				\
67         li a0, -1;
68 #  endif
69 # else
70 #  define SYSCALL_ERROR_HANDLER(name)				\
71 .Lsyscall_error ## name:					\
72         j       __syscall_error;
73 # endif
74 
75 /* Performs a system call, not setting errno.  */
76 # undef PSEUDO_NEORRNO
77 # define PSEUDO_NOERRNO(name, syscall_name, args)	\
78   .align 2;						\
79   ENTRY (name);						\
80   li a7, SYS_ify (syscall_name);			\
81   scall;
82 
83 # undef PSEUDO_END_NOERRNO
84 # define PSEUDO_END_NOERRNO(name)			\
85   END (name)
86 
87 # undef ret_NOERRNO
88 # define ret_NOERRNO ret
89 
90 /* Perfroms a system call, returning the error code.  */
91 # undef PSEUDO_ERRVAL
92 # define PSEUDO_ERRVAL(name, syscall_name, args) 	\
93   PSEUDO_NOERRNO (name, syscall_name, args)		\
94   neg a0, a0;
95 
96 # undef PSEUDO_END_ERRVAL
97 # define PSEUDO_END_ERRVAL(name)			\
98   END (name)
99 
100 # undef ret_ERRVAL
101 # define ret_ERRVAL ret
102 
103 #endif /* __ASSEMBLER__ */
104 
105 /* In order to get __set_errno() definition in INLINE_SYSCALL.  */
106 #ifndef __ASSEMBLER__
107 # include <errno.h>
108 #endif
109 
110 #undef SYS_ify
111 #define SYS_ify(syscall_name)	__NR_##syscall_name
112 
113 #ifndef __ASSEMBLER__
114 
115 /* List of system calls which are supported as vsyscalls.  */
116 # define HAVE_CLOCK_GETRES_VSYSCALL	1
117 # define HAVE_CLOCK_GETTIME_VSYSCALL	1
118 # define HAVE_GETTIMEOFDAY_VSYSCALL	1
119 # define HAVE_GETCPU_VSYSCALL		1
120 
121 
122 extern long int __syscall_error (long int neg_errno);
123 
124 #endif /* ! __ASSEMBLER__ */
125 
126 #endif /* linux/riscv/sysdep.h */
127