]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/i386/sysdep.h
Formatting change, define @pounds, etc.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / i386 / sysdep.h
CommitLineData
a182affd 1/* Copyright (C) 1992, 93, 95, 96 Free Software Foundation, Inc.
d2f5be2a
UD
2This file is part of the GNU C Library.
3Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>, August 1995.
4
5The GNU C Library is free software; you can redistribute it and/or
6modify it under the terms of the GNU Library General Public License as
7published by the Free Software Foundation; either version 2 of the
8License, or (at your option) any later version.
9
10The GNU C Library is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13Library General Public License for more details.
14
15You should have received a copy of the GNU Library General Public
16License along with the GNU C Library; see the file COPYING.LIB. If
17not, write to the Free Software Foundation, Inc., 675 Mass Ave,
18Cambridge, MA 02139, USA. */
19
d2f5be2a
UD
20/* There is some commonality. */
21#include <sysdeps/unix/i386/sysdep.h>
22
23/* For Linux we can use the system call table in the header file
24 /usr/include/asm/unistd.h
25 of the kernel. But these symbols do not follow the SYS_* syntax
26 so we have to redefine the `SYS_ify' macro here. */
27#undef SYS_ify
28#ifdef __STDC__
29# define SYS_ify(syscall_name) __NR_##syscall_name
30#else
31# define SYS_ify(syscall_name) __NR_/**/syscall_name
32#endif
33
34
35#ifdef ASSEMBLER
36
37/* Linux uses a negative return value to indicate syscall errors, unlike
38 most Unices, which use the condition codes' carry flag. */
39#undef PSEUDO
40#define PSEUDO(name, syscall_name, args) \
41 .text; \
03a75825 42 SYSCALL_ERROR_HANDLER \
d2f5be2a 43 ENTRY (name) \
c14e4c32 44 DO_CALL (args, syscall_name); \
d2f5be2a 45 testl %eax, %eax; \
03a75825 46 jl syscall_error;
d2f5be2a 47
03a75825
RM
48#ifndef PIC
49#define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */
50#else
51/* Store (- %eax) into errno through the GOT. */
52#define SYSCALL_ERROR_HANDLER \
53syscall_error: \
54 call 0f; \
550:popl %ecx; \
56 negl %eax; \
57 addl $_GLOBAL_OFFSET_TABLE_+[.-0b], %ecx; \
58 movl errno@GOT(%ecx), %ecx; \
59 movl %eax, (%ecx); \
60 movl $-1, %eax; \
c14e4c32 61 ret;
03a75825
RM
62#endif
63
d2f5be2a
UD
64/* Linux takes system call arguments in registers:
65
66 syscall number %eax call-clobbered
67 arg 1 %ebx call-saved
68 arg 2 %ecx call-clobbered
69 arg 3 %edx call-clobbered
70 arg 4 %esi call-saved
71 arg 5 %edi call-saved
72
73 The stack layout upon entering the function is:
74
75 20(%esp) Arg# 5
76 16(%esp) Arg# 4
77 12(%esp) Arg# 3
78 8(%esp) Arg# 2
79 4(%esp) Arg# 1
80 (%esp) Return address
81
82 (Of course a function with say 3 arguments does not have entries for
83 arguments 4 and 5.)
84
85 The following code tries hard to be optimal. A general assuption
03a75825 86 (which is true according to the data books I have) is that
d2f5be2a
UD
87
88 2 * xchg is more expensive than pushl + movl + popl
89
90 Beside this a neat trick is used. The calling conventions for Linux
91 tell that among the registers used for parameters %ecx and %edx need
92 not be saved. Beside this we may clobber this registers even when
93 they are not used for parameter passing.
94
95 As a result one can see below that we save the content of the %ebx
96 register in the %edx register when we have less than 3 arguments
97 (2 * movl is less expensive than pushl + popl).
98
99 Second unlike for the other registers we don't save the content of
8f5ca04b
RM
100 %ecx and %edx when we have than 1 and 2 registers resp.
101
102 The code below might look a bit long but we have to take care for
103 the pipelined processors (i586 and up). Here the `pushl' and `popl'
104 instructions are marked as NP (not pairable) but the exception is
105 two consecutive of these instruction. This gives no penalty on
106 i386 and i486 processors though. */
d2f5be2a
UD
107
108#undef DO_CALL
c14e4c32 109#define DO_CALL(args, syscall_name) \
8f5ca04b 110 PUSHARGS_##args \
d2f5be2a 111 DOARGS_##args \
c14e4c32 112 movl $SYS_ify (syscall_name), %eax; \
8f5ca04b
RM
113 int $0x80 \
114 POPARGS_##args
d2f5be2a 115
8f5ca04b 116#define PUSHARGS_0 /* No arguments to push. */
d2f5be2a 117#define DOARGS_0 /* No arguments to frob. */
8f5ca04b
RM
118#define POPARGS_0 /* No arguments to pop. */
119#define _PUSHARGS_0 /* No arguments to push. */
120#define _DOARGS_0(n) /* No arguments to frob. */
121#define _POPARGS_0 /* No arguments to pop. */
122
123#define PUSHARGS_1 movl %ebx, %edx; PUSHARGS_0
124#define DOARGS_1 _DOARGS_1 (4)
125#define POPARGS_1 POPARGS_0; movl %edx, %ebx
126#define _PUSHARGS_1 pushl %ebx; _PUSHARGS_0
127#define _DOARGS_1(n) movl n(%esp), %ebx; _DOARGS_0(n-4)
128#define _POPARGS_1 _POPARGS_0; popl %ebx
129
130#define PUSHARGS_2 PUSHARGS_1
131#define DOARGS_2 _DOARGS_2 (8)
132#define POPARGS_2 POPARGS_1
133#define _PUSHARGS_2 _PUSHARGS_1
d2f5be2a 134#define _DOARGS_2(n) movl n(%esp), %ecx; _DOARGS_1 (n-4)
8f5ca04b 135#define _POPARGS_2 _POPARGS_1
d2f5be2a 136
8f5ca04b
RM
137#define PUSHARGS_3 _PUSHARGS_2
138#define DOARGS_3 _DOARGS_3 (16)
139#define POPARGS_3 _POPARGS_3
140#define _PUSHARGS_3 _PUSHARGS_2
d2f5be2a 141#define _DOARGS_3(n) movl n(%esp), %edx; _DOARGS_2 (n-4)
8f5ca04b
RM
142#define _POPARGS_3 _POPARGS_2
143
144#define PUSHARGS_4 _PUSHARGS_4
145#define DOARGS_4 _DOARGS_4 (24)
146#define POPARGS_4 _POPARGS_4
147#define _PUSHARGS_4 pushl %esi; _PUSHARGS_3
148#define _DOARGS_4(n) movl n(%esp), %esi; _DOARGS_3 (n-4)
149#define _POPARGS_4 _POPARGS_3; popl %esi
150
151#define PUSHARGS_5 _PUSHARGS_5
152#define DOARGS_5 _DOARGS_5 (32)
153#define POPARGS_5 _POPARGS_5
154#define _PUSHARGS_5 pushl %edi; _PUSHARGS_4
155#define _DOARGS_5(n) movl n(%esp), %edi; _DOARGS_4 (n-4)
156#define _POPARGS_5 _POPARGS_4; popl %edi
d2f5be2a
UD
157
158#endif /* ASSEMBLER */