Update.
[platform/upstream/glibc.git] / sysdeps / unix / sysv / linux / i386 / sysdep.h
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.
4
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.
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    Library General Public License for more details.
14
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.  */
19
20 #ifndef _LINUX_I386_SYSDEP_H
21 #define _LINUX_I386_SYSDEP_H 1
22
23 /* There is some commonality.  */
24 #include <sysdeps/unix/i386/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 #undef SYS_ify
31 #define SYS_ify(syscall_name)   __NR_##syscall_name
32
33
34 #ifdef ASSEMBLER
35
36 /* Linux uses a negative return value to indicate syscall errors,
37    unlike most Unices, which use the condition codes' carry flag.
38
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
45    test with -4095.  */
46 #undef  PSEUDO
47 #define PSEUDO(name, syscall_name, args)                                      \
48   .text;                                                                      \
49   ENTRY (name)                                                                \
50     DO_CALL (args, syscall_name);                                             \
51     cmpl $-4095, %eax;                                                        \
52     jae syscall_error;
53
54 #undef  PSEUDO_END
55 #define PSEUDO_END(name)                                                      \
56   SYSCALL_ERROR_HANDLER                                                       \
57   END (name)
58
59 #ifndef PIC
60 #define SYSCALL_ERROR_HANDLER   /* Nothing here; code in sysdep.S is used.  */
61 #else
62 /* Store (- %eax) into errno through the GOT.  */
63 #ifdef _LIBC_REENTRANT
64 #define SYSCALL_ERROR_HANDLER                                                 \
65   .type syscall_error,@function;                                              \
66 syscall_error:                                                                \
67   pushl %ebx;                                                                 \
68   call 0f;                                                                    \
69 0:popl %ebx;                                                                  \
70   xorl %edx, %edx;                                                            \
71   addl $_GLOBAL_OFFSET_TABLE_+[.-0b], %ebx;                                   \
72   subl %eax, %edx;                                                            \
73   movl errno@GOT(%ebx), %ecx;                                                 \
74   movl %edx, (%ecx);                                                          \
75   pushl %edx;                                                                 \
76   call __errno_location@PLT;                                                  \
77   popl %ecx;                                                                  \
78   popl %ebx;                                                                  \
79   movl %ecx, (%eax);                                                          \
80   movl $-1, %eax;                                                             \
81   ret;                                                                        \
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!  */
85 #else
86 #define SYSCALL_ERROR_HANDLER                                                 \
87   .type syscall_error,@function;                                              \
88 syscall_error:                                                                \
89   call 0f;                                                                    \
90 0:popl %ecx;                                                                  \
91   xorl %edx, %edx;                                                            \
92   addl $_GLOBAL_OFFSET_TABLE_+[.-0b], %ecx;                                   \
93   subl %eax, %edx;                                                            \
94   movl errno@GOT(%ecx), %ecx;                                                 \
95   movl %edx, (%ecx);                                                          \
96   movl $-1, %eax;                                                             \
97   ret;                                                                        \
98   .size syscall_error,.-syscall_error;
99 #endif  /* _LIBC_REENTRANT */
100 #endif  /* PIC */
101
102 /* Linux takes system call arguments in registers:
103
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
110
111    The stack layout upon entering the function is:
112
113         20(%esp)        Arg# 5
114         16(%esp)        Arg# 4
115         12(%esp)        Arg# 3
116          8(%esp)        Arg# 2
117          4(%esp)        Arg# 1
118           (%esp)        Return address
119
120    (Of course a function with say 3 arguments does not have entries for
121    arguments 4 and 5.)
122
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
125
126         2 * xchg        is more expensive than  pushl + movl + popl
127
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.
132
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).
136
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.
139
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.  */
145
146 #undef  DO_CALL
147 #define DO_CALL(args, syscall_name)                                           \
148     PUSHARGS_##args                                                           \
149     DOARGS_##args                                                             \
150     movl $SYS_ify (syscall_name), %eax;                                       \
151     int $0x80                                                                 \
152     POPARGS_##args
153
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.  */
160
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
167
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
174
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
181
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
188
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
195
196 #endif  /* ASSEMBLER */
197
198 #endif /* linux/i386/sysdep.h */