1 /* Copyright (C) 1992, 93, 95, 96, 97 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>, August 1995.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
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 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
20 #ifndef _LINUX_I386_SYSDEP_H
21 #define _LINUX_I386_SYSDEP_H 1
23 /* There is some commonality. */
24 #include <sysdeps/unix/i386/sysdep.h>
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. */
31 #define SYS_ify(syscall_name) __NR_##syscall_name
36 /* Linux uses a negative return value to indicate syscall errors,
37 unlike most Unices, which use the condition codes' carry flag.
39 Since version 2.1 the return value of a system call might be
40 negative even if the call succeeded. E.g., the `lseek' system call
41 might return a large offset. Therefore we must not anymore test
42 for < 0, but test for a real error by making sure the value in %eax
43 is a real error number. Linus said he will make sure the no syscall
44 returns a value in -1 .. -4095 as a valid result so we can savely
47 #define PSEUDO(name, syscall_name, args) \
50 DO_CALL (args, syscall_name); \
55 #define PSEUDO_END(name) \
56 SYSCALL_ERROR_HANDLER \
60 #define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */
62 /* Store (- %eax) into errno through the GOT. */
63 #ifdef _LIBC_REENTRANT
64 #define SYSCALL_ERROR_HANDLER \
65 .type syscall_error,@function; \
71 addl $_GLOBAL_OFFSET_TABLE_+[.-0b], %ebx; \
73 movl errno@GOT(%ebx), %ecx; \
76 call __errno_location@PLT; \
82 .size syscall_error,.-syscall_error;
83 /* A quick note: it is assumed that the call to `__errno_location' does
84 not modify the stack! */
86 #define SYSCALL_ERROR_HANDLER \
87 .type syscall_error,@function; \
92 addl $_GLOBAL_OFFSET_TABLE_+[.-0b], %ecx; \
94 movl errno@GOT(%ecx), %ecx; \
98 .size syscall_error,.-syscall_error;
99 #endif /* _LIBC_REENTRANT */
102 /* Linux takes system call arguments in registers:
104 syscall number %eax call-clobbered
105 arg 1 %ebx call-saved
106 arg 2 %ecx call-clobbered
107 arg 3 %edx call-clobbered
108 arg 4 %esi call-saved
109 arg 5 %edi call-saved
111 The stack layout upon entering the function is:
118 (%esp) Return address
120 (Of course a function with say 3 arguments does not have entries for
123 The following code tries hard to be optimal. A general assumption
124 (which is true according to the data books I have) is that
126 2 * xchg is more expensive than pushl + movl + popl
128 Beside this a neat trick is used. The calling conventions for Linux
129 tell that among the registers used for parameters %ecx and %edx need
130 not be saved. Beside this we may clobber this registers even when
131 they are not used for parameter passing.
133 As a result one can see below that we save the content of the %ebx
134 register in the %edx register when we have less than 3 arguments
135 (2 * movl is less expensive than pushl + popl).
137 Second unlike for the other registers we don't save the content of
138 %ecx and %edx when we have more than 1 and 2 registers resp.
140 The code below might look a bit long but we have to take care for
141 the pipelined processors (i586 and up). Here the `pushl' and `popl'
142 instructions are marked as NP (not pairable) but the exception is
143 two consecutive of these instruction. This gives no penalty on
144 i386 and i486 processors though. */
147 #define DO_CALL(args, syscall_name) \
150 movl $SYS_ify (syscall_name), %eax; \
154 #define PUSHARGS_0 /* No arguments to push. */
155 #define DOARGS_0 /* No arguments to frob. */
156 #define POPARGS_0 /* No arguments to pop. */
157 #define _PUSHARGS_0 /* No arguments to push. */
158 #define _DOARGS_0(n) /* No arguments to frob. */
159 #define _POPARGS_0 /* No arguments to pop. */
161 #define PUSHARGS_1 movl %ebx, %edx; PUSHARGS_0
162 #define DOARGS_1 _DOARGS_1 (4)
163 #define POPARGS_1 POPARGS_0; movl %edx, %ebx
164 #define _PUSHARGS_1 pushl %ebx; _PUSHARGS_0
165 #define _DOARGS_1(n) movl n(%esp), %ebx; _DOARGS_0(n-4)
166 #define _POPARGS_1 _POPARGS_0; popl %ebx
168 #define PUSHARGS_2 PUSHARGS_1
169 #define DOARGS_2 _DOARGS_2 (8)
170 #define POPARGS_2 POPARGS_1
171 #define _PUSHARGS_2 _PUSHARGS_1
172 #define _DOARGS_2(n) movl n(%esp), %ecx; _DOARGS_1 (n-4)
173 #define _POPARGS_2 _POPARGS_1
175 #define PUSHARGS_3 _PUSHARGS_2
176 #define DOARGS_3 _DOARGS_3 (16)
177 #define POPARGS_3 _POPARGS_3
178 #define _PUSHARGS_3 _PUSHARGS_2
179 #define _DOARGS_3(n) movl n(%esp), %edx; _DOARGS_2 (n-4)
180 #define _POPARGS_3 _POPARGS_2
182 #define PUSHARGS_4 _PUSHARGS_4
183 #define DOARGS_4 _DOARGS_4 (24)
184 #define POPARGS_4 _POPARGS_4
185 #define _PUSHARGS_4 pushl %esi; _PUSHARGS_3
186 #define _DOARGS_4(n) movl n(%esp), %esi; _DOARGS_3 (n-4)
187 #define _POPARGS_4 _POPARGS_3; popl %esi
189 #define PUSHARGS_5 _PUSHARGS_5
190 #define DOARGS_5 _DOARGS_5 (32)
191 #define POPARGS_5 _POPARGS_5
192 #define _PUSHARGS_5 pushl %edi; _PUSHARGS_4
193 #define _DOARGS_5(n) movl n(%esp), %edi; _DOARGS_4 (n-4)
194 #define _POPARGS_5 _POPARGS_4; popl %edi
196 #endif /* ASSEMBLER */
198 #endif /* linux/i386/sysdep.h */