xref: /openbsd/lib/libc/arch/sparc64/SYS.h (revision 3bef86f7)
1 /*	$OpenBSD: SYS.h,v 1.18 2023/12/10 16:45:52 deraadt Exp $	*/
2 /*-
3  * Copyright (c) 1992, 1993
4  *	The Regents of the University of California.  All rights reserved.
5  *
6  * This software was developed by the Computer Systems Engineering group
7  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
8  * contributed to Berkeley.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  *	@(#)SYS.h	8.1 (Berkeley) 6/4/93
35  *
36  *	from: Header: SYS.h,v 1.2 92/07/03 18:57:00 torek Exp
37  *	$NetBSD: SYS.h,v 1.6 2001/07/23 07:26:50 thorpej Exp $
38  */
39 
40 #include "DEFS.h"
41 #include <sys/syscall.h>
42 #include <machine/trap.h>
43 
44 /* offsetof(struct tib, tib_errno) - offsetof(struct tib, __tib_tcb) */
45 #define	TCB_OFFSET_ERRNO	24
46 
47 #define _CAT(x,y) x##y
48 
49 #define	__ENTRY(p,x)		ENTRY(_CAT(p,x)) ; .weak x; x = _CAT(p,x)
50 #define	__ENTRY_HIDDEN(p,x)	ENTRY(_CAT(p,x))
51 
52 #define __END_HIDDEN(p,x)	END(_CAT(p,x));			\
53 				_HIDDEN_FALIAS(x, _CAT(p,x));	\
54 				END(_HIDDEN(x))
55 #define __END(p,x)		__END_HIDDEN(p,x); END(x)
56 
57 /*
58  * ERROR sets the thread's errno and returns
59  */
60 #define	ERROR()							\
61 	st	%o0, [%g7 + TCB_OFFSET_ERRNO];			\
62 	retl;							\
63 	 mov	-1, %o0
64 
65 /*
66  * SYSCALL is used when further action must be taken before returning.
67  * Note that it adds a `nop' over what we could do, if we only knew what
68  * came at label 1....
69  */
70 #define	_SYSCALL(p,x,y)						\
71 	__ENTRY(p,x);						\
72 	mov _CAT(SYS_,y),%g1;					\
73 97:	t ST_SYSCALL;						\
74 	PINSYSCALL(_CAT(SYS_,y), 97b);				\
75 	bcc 1f;							\
76 	nop;							\
77 	ERROR();						\
78 1:
79 
80 #define	_SYSCALL_HIDDEN(p,x,y)					\
81 	__ENTRY_HIDDEN(p,x);					\
82 	mov _CAT(SYS_,y),%g1;					\
83 97:	t ST_SYSCALL;						\
84 	PINSYSCALL(_CAT(SYS_,y), 97b);				\
85 	bcc 1f;							\
86 	nop;							\
87 	ERROR();						\
88 1:
89 
90 #define	__SYSCALL(p,x)						\
91 	_SYSCALL(p,x,x)
92 
93 #define	__SYSCALL_HIDDEN(p,x)					\
94 	_SYSCALL_HIDDEN(p,x,x)
95 
96 /*
97  * RSYSCALL is used when the system call should just return.  Here
98  * we use the SYSCALL_G2RFLAG to put the `success' return address in %g2
99  * and avoid a branch.
100  */
101 #define	__RSYSCALL(p,x)						\
102 	__ENTRY(p,x);						\
103 	mov (_CAT(SYS_,x))|SYSCALL_G2RFLAG,%g1;			\
104 	add %o7,8,%g2;						\
105 97:	t ST_SYSCALL;						\
106 	PINSYSCALL(_CAT(SYS_,x), 97b);				\
107 	ERROR();						\
108 	__END(p,x)
109 #define	__RSYSCALL_HIDDEN(p,x)					\
110 	__ENTRY_HIDDEN(p,x);					\
111 	mov (_CAT(SYS_,x))|SYSCALL_G2RFLAG,%g1;			\
112 	add %o7,8,%g2;						\
113 97:	t ST_SYSCALL;						\
114 	PINSYSCALL(_CAT(SYS_,x), 97b);				\
115 	ERROR();						\
116 	__END_HIDDEN(p,x)
117 
118 /*
119  * PSEUDO(x,y) is like RSYSCALL(y) except that the name is x.
120  */
121 #define	__PSEUDO(p,x,y)						\
122 	__ENTRY(p,x);						\
123 	mov (_CAT(SYS_,y))|SYSCALL_G2RFLAG,%g1;			\
124 	add %o7,8,%g2;						\
125 97:	t ST_SYSCALL;						\
126 	PINSYSCALL(_CAT(SYS_,y), 97b);				\
127 	ERROR();						\
128 	__END(p,x)
129 
130 /*
131  * SYSCALL_NOERROR is like SYSCALL, except it's used for syscalls
132  * that never fail.
133  *
134  * XXX - This should be optimized.
135  */
136 #define __SYSCALL_NOERROR(p,x)					\
137 	__ENTRY(p,x);						\
138 	mov _CAT(SYS_,x),%g1;					\
139 97:	t ST_SYSCALL;						\
140 	PINSYSCALL(_CAT(SYS_,x), 97b)
141 
142 /*
143  * RSYSCALL_NOERROR is like RSYSCALL, except it's used for syscalls
144  * that never fail.
145  *
146  * XXX - This should be optimized.
147  */
148 #define __RSYSCALL_NOERROR(p,x)					\
149 	__ENTRY(p,x);						\
150 	mov (_CAT(SYS_,x))|SYSCALL_G2RFLAG,%g1;			\
151 	add %o7,8,%g2;						\
152 97:	t ST_SYSCALL;						\
153 	PINSYSCALL(_CAT(SYS_,x), 97b);				\
154 	__END(p,x)
155 
156 /*
157  * PSEUDO_NOERROR(x,y) is like RSYSCALL_NOERROR(y) except that the name is x.
158  */
159 #define __PSEUDO_NOERROR(p,x,y)					\
160 	__ENTRY(p,x);						\
161 	mov (_CAT(SYS_,y))|SYSCALL_G2RFLAG,%g1;			\
162 	add %o7,8,%g2;						\
163 97:	t ST_SYSCALL;						\
164 	PINSYSCALL(_CAT(SYS_,y), 97b);				\
165 	__END(p,x)
166 
167 /*
168  * SYSENTRY is for functions that pretend to be syscalls.
169  */
170 #define	SYSCALL(x)		__SYSCALL(_thread_sys_,x)
171 #define	RSYSCALL(x)		__RSYSCALL(_thread_sys_,x)
172 #define	RSYSCALL_HIDDEN(x)	__RSYSCALL_HIDDEN(_thread_sys_,x)
173 #define	RSYSCALL_NOERROR(x,y)	__RSYSCALL_NOERROR(_thread_sys_,x,y)
174 #define	PSEUDO(x,y)		__PSEUDO(_thread_sys_,x,y)
175 #define	PSEUDO_NOERROR(x,y)	__PSEUDO_NOERROR(_thread_sys_,x,y)
176 #define	SYSENTRY(x)		__ENTRY(_thread_sys_,x)
177 #define	SYSENTRY_HIDDEN(x)	__ENTRY_HIDDEN(_thread_sys_,x)
178 #define	SYSCALL_END(x)		__END(_thread_sys_,x)
179 #define	SYSCALL_END_HIDDEN(x)	__END_HIDDEN(_thread_sys_,x)
180