]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libc/sysdeps/linux/i386/bits/syscalls.h
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libc / sysdeps / linux / i386 / bits / syscalls.h
1 #ifndef _BITS_SYSCALLS_H
2 #define _BITS_SYSCALLS_H
3
4 #ifndef _SYSCALL_H
5 # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
6 #endif
7
8 /*
9  * Some of the sneaky macros in the code were taken from
10  * glibc-2.2.5/sysdeps/unix/sysv/linux/i386/sysdep.h
11  */
12
13 #ifndef __ASSEMBLER__
14
15 #include <errno.h>
16
17 #define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
18 ({ \
19         register unsigned int resultvar; \
20         __asm__ __volatile__ ( \
21                 LOADARGS_##nr                                   \
22                 "movl   %1, %%eax\n\t"                          \
23                 "int    $0x80\n\t"                              \
24                 RESTOREARGS_##nr                                \
25                 : "=a" (resultvar)                              \
26                 : "g" (name) ASMFMT_##nr(args) : "memory", "cc" \
27         ); \
28         (int) resultvar; \
29 })
30
31
32 #if 1 /* defined __PIC__ || defined __pic__ */
33
34 /* This code avoids pushing/popping ebx as much as possible.
35  * I think the main reason was that older GCCs had problems
36  * with proper saving/restoring of ebx if "b" constraint was used,
37  * which was breaking -fPIC code really badly.
38  * At least gcc 4.2.x seems to not need these tricks anymore,
39  * but this code is still useful because it often avoids
40  * using stack for saving ebx.
41  * Keeping it unconditionally enabled for now.
42  */
43
44 /* We need some help from the assembler to generate optimal code.
45  * We define some macros here which later will be used.  */
46
47 __asm__ (
48 #ifdef __DOMULTI__
49         /* Protect against asm macro redefinition (happens in __DOMULTI__ mode).
50          * Unfortunately, it ends up visible in .o files. */
51         ".ifndef _BITS_SYSCALLS_ASM\n\t"
52         ".set _BITS_SYSCALLS_ASM,1\n\t"
53 #endif
54         ".L__X'%ebx = 1\n\t"
55         ".L__X'%ecx = 2\n\t"
56         ".L__X'%edx = 2\n\t"
57         ".L__X'%eax = 3\n\t"
58         ".L__X'%esi = 3\n\t"
59         ".L__X'%edi = 3\n\t"
60         ".L__X'%ebp = 3\n\t"
61         ".L__X'%esp = 3\n\t"
62
63         /* Loading param #1 (ebx) is done by loading it into
64          * another register, and then performing bpushl+bmovl,
65          * since we must preserve ebx */
66
67         ".macro bpushl name reg\n\t"
68         ".if 1 - \\name\n\t"    /* if reg!=ebx... */
69         ".if 2 - \\name\n\t"    /* if reg can't be clobbered... */
70         "pushl %ebx\n\t"        /* save ebx on stack */
71         ".else\n\t"
72         "xchgl \\reg, %ebx\n\t" /* else save ebx in reg, and load reg to ebx */
73         ".endif\n\t"
74         ".endif\n\t"
75         ".endm\n\t"
76
77         ".macro bmovl name reg\n\t"
78         ".if 1 - \\name\n\t"
79         ".if 2 - \\name\n\t"    /* if reg can't be clobbered... */
80         "movl \\reg, %ebx\n\t"  /* load reg to ebx */
81         ".endif\n\t"
82         ".endif\n\t"
83         ".endm\n\t"
84
85         ".macro bpopl name reg\n\t"
86         ".if 1 - \\name\n\t"
87         ".if 2 - \\name\n\t"    /* if reg can't be clobbered... */
88         "popl %ebx\n\t"         /* restore ebx from stack */
89         ".else\n\t"
90         "xchgl \\reg, %ebx\n\t" /* else restore ebx from reg */
91         ".endif\n\t"
92         ".endif\n\t"
93         ".endm\n\t"
94
95 #ifdef __DOMULTI__
96         ".endif\n\t" /* _BITS_SYSCALLS_ASM */
97 #endif
98 );
99
100 #define LOADARGS_0
101 #define LOADARGS_1  "bpushl .L__X'%k2, %k2\n\t" "bmovl .L__X'%k2, %k2\n\t"
102 #define LOADARGS_2  LOADARGS_1
103 #define LOADARGS_3  LOADARGS_1
104 #define LOADARGS_4  LOADARGS_1
105 #define LOADARGS_5  LOADARGS_1
106 #define LOADARGS_6  LOADARGS_1 "push %%ebp\n\t" "movl %7, %%ebp\n\t"
107
108 #define RESTOREARGS_0
109 #define RESTOREARGS_1  "bpopl .L__X'%k2, %k2\n\t"
110 #define RESTOREARGS_2  RESTOREARGS_1
111 #define RESTOREARGS_3  RESTOREARGS_1
112 #define RESTOREARGS_4  RESTOREARGS_1
113 #define RESTOREARGS_5  RESTOREARGS_1
114 #define RESTOREARGS_6  "pop %%ebp\n\t" RESTOREARGS_1
115
116 #define ASMFMT_0()
117 /* "acdSD" constraint would work too, but "SD" would use esi/edi and cause
118  * them to be pushed/popped by compiler, "a" would use eax and cause ebx
119  * to be saved/restored on stack, not in register. Narrowing choice down
120  * to "ecx or edx" results in smaller and faster code: */
121 #define ASMFMT_1(arg1) \
122         , "cd" (arg1)
123 /* Can use "adSD" constraint here: */
124 #define ASMFMT_2(arg1, arg2) \
125         , "d" (arg1), "c" (arg2)
126 /* Can use "aSD" constraint here: */
127 #define ASMFMT_3(arg1, arg2, arg3) \
128         , "a" (arg1), "c" (arg2), "d" (arg3)
129 /* Can use "aD" constraint here: */
130 #define ASMFMT_4(arg1, arg2, arg3, arg4) \
131         , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
132 #define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \
133         , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
134 #define ASMFMT_6(arg1, arg2, arg3, arg4, arg5, arg6) \
135         , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5), "m" (arg6)
136
137 #else /* !PIC */
138
139 /* Simpler code which just uses "b" constraint to load ebx.
140  * Seems to work with gc 4.2.x, and generates slightly smaller,
141  * but slightly slower code. Example (time syscall):
142  *
143  * -    8b 4c 24 04            mov    0x4(%esp),%ecx
144  * -    87 cb                  xchg   %ecx,%ebx
145  * +    53                     push   %ebx
146  * +    8b 5c 24 08            mov    0x8(%esp),%ebx
147  *      b8 0d 00 00 00         mov    $0xd,%eax
148  *      cd 80                  int    $0x80
149  * -    87 cb                  xchg   %ecx,%ebx
150  * +    5b                     pop    %ebx
151  *      c3                     ret
152  *
153  * 2 bytes smaller, but uses stack via "push/pop ebx"
154  */
155
156 #define LOADARGS_0
157 #define LOADARGS_1
158 #define LOADARGS_2
159 #define LOADARGS_3
160 #define LOADARGS_4
161 #define LOADARGS_5
162 #define LOADARGS_6  "push %%ebp\n\t" "movl %7, %%ebp\n\t"
163
164 #define RESTOREARGS_0
165 #define RESTOREARGS_1
166 #define RESTOREARGS_2
167 #define RESTOREARGS_3
168 #define RESTOREARGS_4
169 #define RESTOREARGS_5
170 #define RESTOREARGS_6  "pop %%ebp\n\t"
171
172 #define ASMFMT_0()
173 #define ASMFMT_1(arg1) \
174         , "b" (arg1)
175 #define ASMFMT_2(arg1, arg2) \
176         , "b" (arg1), "c" (arg2)
177 #define ASMFMT_3(arg1, arg2, arg3) \
178         , "b" (arg1), "c" (arg2), "d" (arg3)
179 #define ASMFMT_4(arg1, arg2, arg3, arg4) \
180         , "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
181 #define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \
182         , "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
183 #define ASMFMT_6(arg1, arg2, arg3, arg4, arg5, arg6) \
184         , "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5), "m" (arg6)
185
186 #endif /* !PIC */
187
188 #endif /* __ASSEMBLER__ */
189 #endif /* _BITS_SYSCALLS_H */