1 /* Copyright (C) 1992, 1995, 1997, 1999, 2000, 2002, 2003, 2004
2    Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Brendan Kehoe (brendan@zen.org).
5 
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10 
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15 
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, see
18    <http://www.gnu.org/licenses/>.  */
19 
20 #ifndef _LINUX_MIPS_SYSDEP_H
21 #define _LINUX_MIPS_SYSDEP_H 1
22 
23 #include <sgidefs.h>
24 #include <common/sysdep.h>
25 
26 /* For Linux we can use the system call table in the header file
27    /usr/include/asm/unistd.h
28    of the kernel.  But these symbols do not follow the SYS_* syntax
29    so we have to redefine the `SYS_ify' macro here.  */
30 
31 #undef SYS_ify
32 #ifdef __STDC__
33 # define SYS_ify(syscall_name)	__NR_##syscall_name
34 #else
35 # define SYS_ify(syscall_name)	__NR_/**/syscall_name
36 #endif
37 
38 #ifdef __ASSEMBLER__
39 
40 #include <sys/regdef.h>
41 
42 #define ENTRY(name) 					\
43   .globl name;						\
44   .align 2;						\
45   .ent name,0;						\
46   name##:
47 
48 #undef END
49 #define	END(function)					\
50 		.end	function;			\
51 		.size	function,.-function
52 
53 #define ret	j ra ; nop
54 
55 #undef PSEUDO_END
56 #define PSEUDO_END(sym) .end sym; .size sym,.-sym
57 
58 #define PSEUDO_NOERRNO(name, syscall_name, args)	\
59   .align 2;						\
60   ENTRY(name)						\
61   .set noreorder;					\
62   li v0, SYS_ify(syscall_name);				\
63   syscall
64 
65 #undef PSEUDO_END_NOERRNO
66 #define PSEUDO_END_NOERRNO(sym) .end sym; .size sym,.-sym
67 
68 #define ret_NOERRNO ret
69 
70 #define PSEUDO_ERRVAL(name, syscall_name, args)		\
71   .align 2;						\
72   ENTRY(name)						\
73   .set noreorder;					\
74   li v0, SYS_ify(syscall_name);				\
75   syscall
76 
77 #undef PSEUDO_END_ERRVAL
78 #define PSEUDO_END_ERRVAL(sym) .end sym; .size sym,.-sym
79 
80 #define r0	v0
81 #define r1	v1
82 /* The mips move insn is d,s.  */
83 #define MOVE(x,y)	move y , x
84 
85 #if _MIPS_SIM == _ABIO32
86 # define L(label) $L ## label
87 #else
88 # define L(label) .L ## label
89 #endif
90 
91 /* Note that while it's better structurally, going back to call __syscall_error
92    can make things confusing if you're debugging---it looks like it's jumping
93    backwards into the previous fn.  */
94 
95 #ifdef __PIC__
96 #define PSEUDO(name, syscall_name, args) 		\
97   .align 2;						\
98   99: move a0, v0;					\
99   la t9,__syscall_error;				\
100   jr t9;						\
101   ENTRY(name)						\
102   .set noreorder;					\
103   .cpload t9;						\
104   li v0, SYS_ify(syscall_name);				\
105   syscall;						\
106   .set reorder;						\
107   bne a3, zero, 99b;					\
108 L(syse1):
109 #else
110 #define PSEUDO(name, syscall_name, args) 		\
111   .set noreorder;					\
112   .align 2;						\
113   99: move a0, v0;					\
114   j __syscall_error;					\
115   nop;							\
116   ENTRY(name)						\
117   .set noreorder;					\
118   li v0, SYS_ify(syscall_name);				\
119   syscall;						\
120   .set reorder;						\
121   bne a3, zero, 99b;					\
122 L(syse1):
123 #endif
124 
125 /* We don't want the label for the error handler to be visible in the symbol
126    table when we define it here.  */
127 #ifdef __PIC__
128 # define SYSCALL_ERROR_LABEL 99b
129 #endif
130 
131 #endif  /* __ASSEMBLER__ */
132 #endif /* _LINUX_MIPS_SYSDEP_H */
133