]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/i386/sysdep.h
Remove support for !USE___THREAD
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / i386 / sysdep.h
CommitLineData
d063d164
UD
1/* Copyright (C) 1992,1993,1995-2000,2002-2006,2007,2011
2 Free Software Foundation, Inc.
bfbc5754 3 This file is part of the GNU C Library.
44129238 4 Contributed by Ulrich Drepper, <drepper@gnu.org>, August 1995.
bfbc5754
UD
5
6 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
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.
bfbc5754
UD
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
41bdb6e2 14 Lesser General Public License for more details.
bfbc5754 15
41bdb6e2
AJ
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
d2f5be2a 20
ec4b0518
UD
21#ifndef _LINUX_I386_SYSDEP_H
22#define _LINUX_I386_SYSDEP_H 1
23
d2f5be2a
UD
24/* There is some commonality. */
25#include <sysdeps/unix/i386/sysdep.h>
ee63ca21
GM
26#include <bp-sym.h>
27#include <bp-asm.h>
131fd126 28/* Defines RTLD_PRIVATE_ERRNO and USE_DL_SYSINFO. */
5f5843e3 29#include <dl-sysdep.h>
739d440d 30#include <tls.h>
d2f5be2a 31
ce460d04 32
d2f5be2a
UD
33/* For Linux we can use the system call table in the header file
34 /usr/include/asm/unistd.h
35 of the kernel. But these symbols do not follow the SYS_* syntax
36 so we have to redefine the `SYS_ify' macro here. */
37#undef SYS_ify
6ed0492f 38#define SYS_ify(syscall_name) __NR_##syscall_name
d2f5be2a 39
131fd126
UD
40#if defined USE_DL_SYSINFO \
41 && (!defined NOT_IN_libc || defined IS_IN_libpthread)
5f5843e3
UD
42# define I386_USE_SYSENTER 1
43#else
44# undef I386_USE_SYSENTER
45#endif
46
c2afe833
RM
47#ifdef __ASSEMBLER__
48
cccda09f
UD
49/* Linux uses a negative return value to indicate syscall errors,
50 unlike most Unices, which use the condition codes' carry flag.
51
52 Since version 2.1 the return value of a system call might be
53 negative even if the call succeeded. E.g., the `lseek' system call
54 might return a large offset. Therefore we must not anymore test
55 for < 0, but test for a real error by making sure the value in %eax
b5791037
UD
56 is a real error number. Linus said he will make sure the no syscall
57 returns a value in -1 .. -4095 as a valid result so we can savely
58 test with -4095. */
c0fb8a56
UD
59
60/* We don't want the label for the error handle to be global when we define
61 it here. */
62#ifdef PIC
63# define SYSCALL_ERROR_LABEL 0f
64#else
65# define SYSCALL_ERROR_LABEL syscall_error
66#endif
67
d2f5be2a
UD
68#undef PSEUDO
69#define PSEUDO(name, syscall_name, args) \
70 .text; \
d2f5be2a 71 ENTRY (name) \
ffa8d2a0 72 DO_CALL (syscall_name, args); \
b5791037 73 cmpl $-4095, %eax; \
c0fb8a56 74 jae SYSCALL_ERROR_LABEL; \
ae828bc6 75 L(pseudo_end):
d2f5be2a 76
6ed0492f
UD
77#undef PSEUDO_END
78#define PSEUDO_END(name) \
79 SYSCALL_ERROR_HANDLER \
80 END (name)
81
9eb88290
UD
82#undef PSEUDO_NOERRNO
83#define PSEUDO_NOERRNO(name, syscall_name, args) \
84 .text; \
85 ENTRY (name) \
86 DO_CALL (syscall_name, args)
87
88#undef PSEUDO_END_NOERRNO
89#define PSEUDO_END_NOERRNO(name) \
90 END (name)
91
92#define ret_NOERRNO ret
93
bfef9264
UD
94/* The function has to return the error code. */
95#undef PSEUDO_ERRVAL
96#define PSEUDO_ERRVAL(name, syscall_name, args) \
97 .text; \
98 ENTRY (name) \
99 DO_CALL (syscall_name, args); \
100 negl %eax
101
102#undef PSEUDO_END_ERRVAL
103#define PSEUDO_END_ERRVAL(name) \
104 END (name)
105
106#define ret_ERRVAL ret
107
edf5b2d7 108#ifndef PIC
739d440d 109# define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */
03a75825 110#else
9bd64602 111
ce460d04
RM
112# if RTLD_PRIVATE_ERRNO
113# define SYSCALL_ERROR_HANDLER \
1140:SETUP_PIC_REG(cx); \
115 addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
116 xorl %edx, %edx; \
117 subl %eax, %edx; \
96c82b3f 118 movl %edx, rtld_errno@GOTOFF(%ecx); \
ce460d04
RM
119 orl $-1, %eax; \
120 jmp L(pseudo_end);
739d440d 121
ce460d04
RM
122# elif defined _LIBC_REENTRANT
123
d063d164
UD
124# ifndef NOT_IN_libc
125# define SYSCALL_ERROR_ERRNO __libc_errno
126# else
127# define SYSCALL_ERROR_ERRNO errno
128# endif
129# define SYSCALL_ERROR_HANDLER \
739d440d
UD
1300:SETUP_PIC_REG (cx); \
131 addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
ac2dc598 132 movl SYSCALL_ERROR_ERRNO@GOTNTPOFF(%ecx), %ecx; \
739d440d
UD
133 xorl %edx, %edx; \
134 subl %eax, %edx; \
70a8119b 135 SYSCALL_ERROR_HANDLER_TLS_STORE (%edx, %ecx); \
739d440d
UD
136 orl $-1, %eax; \
137 jmp L(pseudo_end);
d063d164
UD
138# ifndef NO_TLS_DIRECT_SEG_REFS
139# define SYSCALL_ERROR_HANDLER_TLS_STORE(src, destoff) \
24992143 140 movl src, %gs:(destoff)
d063d164
UD
141# else
142# define SYSCALL_ERROR_HANDLER_TLS_STORE(src, destoff) \
70a8119b
RM
143 addl %gs:0, destoff; \
144 movl src, (destoff)
739d440d 145# endif
9bd64602 146# else
ce460d04 147/* Store (- %eax) into errno through the GOT. */
739d440d 148# define SYSCALL_ERROR_HANDLER \
09d65ff3 1490:SETUP_PIC_REG(cx); \
b44e3016 150 addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
edf5b2d7 151 xorl %edx, %edx; \
edf5b2d7 152 subl %eax, %edx; \
03a75825 153 movl errno@GOT(%ecx), %ecx; \
edf5b2d7 154 movl %edx, (%ecx); \
b259e746 155 orl $-1, %eax; \
c0fb8a56 156 jmp L(pseudo_end);
739d440d 157# endif /* _LIBC_REENTRANT */
edf5b2d7 158#endif /* PIC */
03a75825 159
f051627f
UD
160
161/* The original calling convention for system calls on Linux/i386 is
162 to use int $0x80. */
5f5843e3
UD
163#ifdef I386_USE_SYSENTER
164# ifdef SHARED
165# define ENTER_KERNEL call *%gs:SYSINFO_OFFSET
166# else
167# define ENTER_KERNEL call *_dl_sysinfo
168# endif
169#else
170# define ENTER_KERNEL int $0x80
171#endif
f051627f 172
d2f5be2a
UD
173/* Linux takes system call arguments in registers:
174
175 syscall number %eax call-clobbered
176 arg 1 %ebx call-saved
177 arg 2 %ecx call-clobbered
178 arg 3 %edx call-clobbered
179 arg 4 %esi call-saved
180 arg 5 %edi call-saved
b2bcd249 181 arg 6 %ebp call-saved
d2f5be2a
UD
182
183 The stack layout upon entering the function is:
184
b2bcd249 185 24(%esp) Arg# 6
d2f5be2a
UD
186 20(%esp) Arg# 5
187 16(%esp) Arg# 4
188 12(%esp) Arg# 3
189 8(%esp) Arg# 2
190 4(%esp) Arg# 1
191 (%esp) Return address
192
193 (Of course a function with say 3 arguments does not have entries for
b2bcd249 194 arguments 4, 5, and 6.)
d2f5be2a 195
6ed0492f 196 The following code tries hard to be optimal. A general assumption
03a75825 197 (which is true according to the data books I have) is that
d2f5be2a
UD
198
199 2 * xchg is more expensive than pushl + movl + popl
200
201 Beside this a neat trick is used. The calling conventions for Linux
202 tell that among the registers used for parameters %ecx and %edx need
203 not be saved. Beside this we may clobber this registers even when
204 they are not used for parameter passing.
205
206 As a result one can see below that we save the content of the %ebx
207 register in the %edx register when we have less than 3 arguments
208 (2 * movl is less expensive than pushl + popl).
209
210 Second unlike for the other registers we don't save the content of
6ed0492f 211 %ecx and %edx when we have more than 1 and 2 registers resp.
8f5ca04b
RM
212
213 The code below might look a bit long but we have to take care for
63bda0c1 214 the pipelined processors (i586). Here the `pushl' and `popl'
8f5ca04b
RM
215 instructions are marked as NP (not pairable) but the exception is
216 two consecutive of these instruction. This gives no penalty on
63bda0c1 217 other processors though. */
d2f5be2a
UD
218
219#undef DO_CALL
ffa8d2a0 220#define DO_CALL(syscall_name, args) \
8f5ca04b 221 PUSHARGS_##args \
d2f5be2a 222 DOARGS_##args \
c14e4c32 223 movl $SYS_ify (syscall_name), %eax; \
f051627f 224 ENTER_KERNEL \
8f5ca04b 225 POPARGS_##args
d2f5be2a 226
8f5ca04b 227#define PUSHARGS_0 /* No arguments to push. */
d2f5be2a 228#define DOARGS_0 /* No arguments to frob. */
8f5ca04b
RM
229#define POPARGS_0 /* No arguments to pop. */
230#define _PUSHARGS_0 /* No arguments to push. */
231#define _DOARGS_0(n) /* No arguments to frob. */
232#define _POPARGS_0 /* No arguments to pop. */
233
bd4f43b4 234#define PUSHARGS_1 movl %ebx, %edx; L(SAVEBX1): PUSHARGS_0
8f5ca04b 235#define DOARGS_1 _DOARGS_1 (4)
bd4f43b4 236#define POPARGS_1 POPARGS_0; movl %edx, %ebx; L(RESTBX1):
62d01985
UD
237#define _PUSHARGS_1 pushl %ebx; cfi_adjust_cfa_offset (4); \
238 cfi_rel_offset (ebx, 0); L(PUSHBX1): _PUSHARGS_0
8f5ca04b 239#define _DOARGS_1(n) movl n(%esp), %ebx; _DOARGS_0(n-4)
62d01985
UD
240#define _POPARGS_1 _POPARGS_0; popl %ebx; cfi_adjust_cfa_offset (-4); \
241 cfi_restore (ebx); L(POPBX1):
8f5ca04b
RM
242
243#define PUSHARGS_2 PUSHARGS_1
244#define DOARGS_2 _DOARGS_2 (8)
245#define POPARGS_2 POPARGS_1
246#define _PUSHARGS_2 _PUSHARGS_1
d2f5be2a 247#define _DOARGS_2(n) movl n(%esp), %ecx; _DOARGS_1 (n-4)
8f5ca04b 248#define _POPARGS_2 _POPARGS_1
d2f5be2a 249
8f5ca04b
RM
250#define PUSHARGS_3 _PUSHARGS_2
251#define DOARGS_3 _DOARGS_3 (16)
252#define POPARGS_3 _POPARGS_3
253#define _PUSHARGS_3 _PUSHARGS_2
d2f5be2a 254#define _DOARGS_3(n) movl n(%esp), %edx; _DOARGS_2 (n-4)
8f5ca04b
RM
255#define _POPARGS_3 _POPARGS_2
256
257#define PUSHARGS_4 _PUSHARGS_4
258#define DOARGS_4 _DOARGS_4 (24)
259#define POPARGS_4 _POPARGS_4
62d01985
UD
260#define _PUSHARGS_4 pushl %esi; cfi_adjust_cfa_offset (4); \
261 cfi_rel_offset (esi, 0); L(PUSHSI1): _PUSHARGS_3
8f5ca04b 262#define _DOARGS_4(n) movl n(%esp), %esi; _DOARGS_3 (n-4)
62d01985
UD
263#define _POPARGS_4 _POPARGS_3; popl %esi; cfi_adjust_cfa_offset (-4); \
264 cfi_restore (esi); L(POPSI1):
8f5ca04b
RM
265
266#define PUSHARGS_5 _PUSHARGS_5
267#define DOARGS_5 _DOARGS_5 (32)
268#define POPARGS_5 _POPARGS_5
62d01985
UD
269#define _PUSHARGS_5 pushl %edi; cfi_adjust_cfa_offset (4); \
270 cfi_rel_offset (edi, 0); L(PUSHDI1): _PUSHARGS_4
8f5ca04b 271#define _DOARGS_5(n) movl n(%esp), %edi; _DOARGS_4 (n-4)
62d01985
UD
272#define _POPARGS_5 _POPARGS_4; popl %edi; cfi_adjust_cfa_offset (-4); \
273 cfi_restore (edi); L(POPDI1):
d2f5be2a 274
0da7bcc5 275#define PUSHARGS_6 _PUSHARGS_6
46c38bd7 276#define DOARGS_6 _DOARGS_6 (40)
0da7bcc5 277#define POPARGS_6 _POPARGS_6
62d01985
UD
278#define _PUSHARGS_6 pushl %ebp; cfi_adjust_cfa_offset (4); \
279 cfi_rel_offset (ebp, 0); L(PUSHBP1): _PUSHARGS_5
0da7bcc5 280#define _DOARGS_6(n) movl n(%esp), %ebp; _DOARGS_5 (n-4)
62d01985
UD
281#define _POPARGS_6 _POPARGS_5; popl %ebp; cfi_adjust_cfa_offset (-4); \
282 cfi_restore (ebp); L(POPBP1):
0da7bcc5 283
adcb550c
UD
284#else /* !__ASSEMBLER__ */
285
78e5779b
UD
286/* We need some help from the assembler to generate optimal code. We
287 define some macros here which later will be used. */
e3e35cfc
UD
288asm (".L__X'%ebx = 1\n\t"
289 ".L__X'%ecx = 2\n\t"
290 ".L__X'%edx = 2\n\t"
291 ".L__X'%eax = 3\n\t"
292 ".L__X'%esi = 3\n\t"
293 ".L__X'%edi = 3\n\t"
294 ".L__X'%ebp = 3\n\t"
295 ".L__X'%esp = 3\n\t"
78e5779b
UD
296 ".macro bpushl name reg\n\t"
297 ".if 1 - \\name\n\t"
298 ".if 2 - \\name\n\t"
7a114794 299 "error\n\t"
78e5779b
UD
300 ".else\n\t"
301 "xchgl \\reg, %ebx\n\t"
302 ".endif\n\t"
303 ".endif\n\t"
304 ".endm\n\t"
305 ".macro bpopl name reg\n\t"
306 ".if 1 - \\name\n\t"
307 ".if 2 - \\name\n\t"
7a114794 308 "error\n\t"
78e5779b
UD
309 ".else\n\t"
310 "xchgl \\reg, %ebx\n\t"
311 ".endif\n\t"
312 ".endif\n\t"
78e5779b
UD
313 ".endm\n\t");
314
adcb550c
UD
315/* Define a macro which expands inline into the wrapper code for a system
316 call. */
317#undef INLINE_SYSCALL
318#define INLINE_SYSCALL(name, nr, args...) \
ce460d04 319 ({ \
6aca81bb
UD
320 unsigned int resultvar = INTERNAL_SYSCALL (name, , nr, args); \
321 if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (resultvar, ), 0)) \
ce460d04 322 { \
6aca81bb 323 __set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, )); \
ce460d04
RM
324 resultvar = 0xffffffff; \
325 } \
326 (int) resultvar; })
327
328/* Define a macro which expands inline into the wrapper code for a system
329 call. This use is for internal calls that do not need to handle errors
330 normally. It will never touch errno. This returns just what the kernel
2edb61e3
UD
331 gave back.
332
333 The _NCS variant allows non-constant syscall numbers but it is not
334 possible to use more than four parameters. */
ce460d04 335#undef INTERNAL_SYSCALL
5f5843e3
UD
336#ifdef I386_USE_SYSENTER
337# ifdef SHARED
6aca81bb 338# define INTERNAL_SYSCALL(name, err, nr, args...) \
5f5843e3 339 ({ \
7a114794
UD
340 register unsigned int resultvar; \
341 EXTRAVAR_##nr \
5f5843e3
UD
342 asm volatile ( \
343 LOADARGS_##nr \
344 "movl %1, %%eax\n\t" \
345 "call *%%gs:%P2\n\t" \
346 RESTOREARGS_##nr \
347 : "=a" (resultvar) \
348 : "i" (__NR_##name), "i" (offsetof (tcbhead_t, sysinfo)) \
349 ASMFMT_##nr(args) : "memory", "cc"); \
350 (int) resultvar; })
2edb61e3
UD
351# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
352 ({ \
353 register unsigned int resultvar; \
354 EXTRAVAR_##nr \
355 asm volatile ( \
356 LOADARGS_##nr \
357 "call *%%gs:%P2\n\t" \
358 RESTOREARGS_##nr \
359 : "=a" (resultvar) \
360 : "0" (name), "i" (offsetof (tcbhead_t, sysinfo)) \
361 ASMFMT_##nr(args) : "memory", "cc"); \
362 (int) resultvar; })
5f5843e3 363# else
6aca81bb 364# define INTERNAL_SYSCALL(name, err, nr, args...) \
adcb550c 365 ({ \
7a114794
UD
366 register unsigned int resultvar; \
367 EXTRAVAR_##nr \
adcb550c 368 asm volatile ( \
44129238 369 LOADARGS_##nr \
78e5779b 370 "movl %1, %%eax\n\t" \
5f5843e3 371 "call *_dl_sysinfo\n\t" \
44129238 372 RESTOREARGS_##nr \
adcb550c 373 : "=a" (resultvar) \
78e5779b 374 : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc"); \
adcb550c 375 (int) resultvar; })
2edb61e3
UD
376# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
377 ({ \
378 register unsigned int resultvar; \
379 EXTRAVAR_##nr \
380 asm volatile ( \
381 LOADARGS_##nr \
382 "call *_dl_sysinfo\n\t" \
383 RESTOREARGS_##nr \
384 : "=a" (resultvar) \
385 : "0" (name) ASMFMT_##nr(args) : "memory", "cc"); \
386 (int) resultvar; })
5f5843e3
UD
387# endif
388#else
6aca81bb 389# define INTERNAL_SYSCALL(name, err, nr, args...) \
5f5843e3 390 ({ \
7a114794
UD
391 register unsigned int resultvar; \
392 EXTRAVAR_##nr \
5f5843e3
UD
393 asm volatile ( \
394 LOADARGS_##nr \
395 "movl %1, %%eax\n\t" \
7a114794 396 "int $0x80\n\t" \
5f5843e3
UD
397 RESTOREARGS_##nr \
398 : "=a" (resultvar) \
399 : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc"); \
400 (int) resultvar; })
2edb61e3
UD
401# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
402 ({ \
403 register unsigned int resultvar; \
404 EXTRAVAR_##nr \
405 asm volatile ( \
406 LOADARGS_##nr \
407 "int $0x80\n\t" \
408 RESTOREARGS_##nr \
409 : "=a" (resultvar) \
410 : "0" (name) ASMFMT_##nr(args) : "memory", "cc"); \
411 (int) resultvar; })
5f5843e3 412#endif
adcb550c 413
6aca81bb
UD
414#undef INTERNAL_SYSCALL_DECL
415#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
416
f4447671 417#undef INTERNAL_SYSCALL_ERROR_P
6aca81bb
UD
418#define INTERNAL_SYSCALL_ERROR_P(val, err) \
419 ((unsigned int) (val) >= 0xfffff001u)
f4447671
UD
420
421#undef INTERNAL_SYSCALL_ERRNO
6aca81bb 422#define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
f4447671 423
44129238 424#define LOADARGS_0
7a114794 425#ifdef __PIC__
a44cffaa 426# if defined I386_USE_SYSENTER && defined SHARED
7a114794
UD
427# define LOADARGS_1 \
428 "bpushl .L__X'%k3, %k3\n\t"
429# define LOADARGS_5 \
430 "movl %%ebx, %4\n\t" \
431 "movl %3, %%ebx\n\t"
432# else
433# define LOADARGS_1 \
434 "bpushl .L__X'%k2, %k2\n\t"
435# define LOADARGS_5 \
436 "movl %%ebx, %3\n\t" \
437 "movl %2, %%ebx\n\t"
438# endif
439# define LOADARGS_2 LOADARGS_1
440# define LOADARGS_3 \
441 "xchgl %%ebx, %%edi\n\t"
442# define LOADARGS_4 LOADARGS_3
5f5843e3 443#else
7a114794
UD
444# define LOADARGS_1
445# define LOADARGS_2
446# define LOADARGS_3
447# define LOADARGS_4
448# define LOADARGS_5
5f5843e3 449#endif
44129238
UD
450
451#define RESTOREARGS_0
7a114794
UD
452#ifdef __PIC__
453# if defined I386_USE_SYSENTER && defined SHARED
454# define RESTOREARGS_1 \
5f5843e3 455 "bpopl .L__X'%k3, %k3\n\t"
7a114794
UD
456# define RESTOREARGS_5 \
457 "movl %4, %%ebx"
458# else
459# define RESTOREARGS_1 \
44129238 460 "bpopl .L__X'%k2, %k2\n\t"
7a114794
UD
461# define RESTOREARGS_5 \
462 "movl %3, %%ebx"
463# endif
464# define RESTOREARGS_2 RESTOREARGS_1
465# define RESTOREARGS_3 \
466 "xchgl %%edi, %%ebx\n\t"
467# define RESTOREARGS_4 RESTOREARGS_3
468#else
469# define RESTOREARGS_1
470# define RESTOREARGS_2
471# define RESTOREARGS_3
472# define RESTOREARGS_4
473# define RESTOREARGS_5
5f5843e3 474#endif
44129238 475
7bb38c70 476#define ASMFMT_0()
7a114794
UD
477#ifdef __PIC__
478# define ASMFMT_1(arg1) \
479 , "cd" (arg1)
480# define ASMFMT_2(arg1, arg2) \
3a370de8 481 , "d" (arg1), "c" (arg2)
7a114794
UD
482# define ASMFMT_3(arg1, arg2, arg3) \
483 , "D" (arg1), "c" (arg2), "d" (arg3)
484# define ASMFMT_4(arg1, arg2, arg3, arg4) \
485 , "D" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
486# define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \
487 , "0" (arg1), "m" (_xv), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
488#else
489# define ASMFMT_1(arg1) \
490 , "b" (arg1)
491# define ASMFMT_2(arg1, arg2) \
492 , "b" (arg1), "c" (arg2)
493# define ASMFMT_3(arg1, arg2, arg3) \
494 , "b" (arg1), "c" (arg2), "d" (arg3)
495# define ASMFMT_4(arg1, arg2, arg3, arg4) \
496 , "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
497# define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \
498 , "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
499#endif
500
501#define EXTRAVAR_0
502#define EXTRAVAR_1
503#define EXTRAVAR_2
504#define EXTRAVAR_3
505#define EXTRAVAR_4
506#ifdef __PIC__
507# define EXTRAVAR_5 int _xv;
508#else
509# define EXTRAVAR_5
510#endif
adcb550c 511
dbfc1e02
UD
512/* Consistency check for position-independent code. */
513#ifdef __PIC__
514# define check_consistency() \
515 ({ int __res; \
516 __asm__ __volatile__ \
517 ("call __i686.get_pc_thunk.cx;" \
518 "addl $_GLOBAL_OFFSET_TABLE_, %%ecx;" \
519 "subl %%ebx, %%ecx;" \
520 "je 1f;" \
521 "ud2;" \
522 "1:\n" \
523 ".section .gnu.linkonce.t.__i686.get_pc_thunk.cx,\"ax\",@progbits;" \
524 ".globl __i686.get_pc_thunk.cx;" \
525 ".hidden __i686.get_pc_thunk.cx;" \
526 ".type __i686.get_pc_thunk.cx,@function;" \
527 "__i686.get_pc_thunk.cx:" \
528 "movl (%%esp), %%ecx;" \
529 "ret;" \
530 ".previous" \
531 : "=c" (__res)); \
532 __res; })
533#endif
534
66715f83 535#endif /* __ASSEMBLER__ */
ec4b0518 536
827b7087
UD
537
538/* Pointer mangling support. */
539#if defined NOT_IN_libc && defined IS_IN_rtld
540/* We cannot use the thread descriptor because in ld.so we use setjmp
541 earlier than the descriptor is initialized. Using a global variable
542 is too complicated here since we have no PC-relative addressing mode. */
543#else
3467f5c3 544# ifdef __ASSEMBLER__
4a44ce79
UD
545# define PTR_MANGLE(reg) xorl %gs:POINTER_GUARD, reg; \
546 roll $9, reg
547# define PTR_DEMANGLE(reg) rorl $9, reg; \
548 xorl %gs:POINTER_GUARD, reg
3467f5c3 549# else
4a44ce79
UD
550# define PTR_MANGLE(var) asm ("xorl %%gs:%c2, %0\n" \
551 "roll $9, %0" \
552 : "=r" (var) \
553 : "0" (var), \
554 "i" (offsetof (tcbhead_t, \
555 pointer_guard)))
556# define PTR_DEMANGLE(var) asm ("rorl $9, %0\n" \
557 "xorl %%gs:%c2, %0" \
3467f5c3
UD
558 : "=r" (var) \
559 : "0" (var), \
560 "i" (offsetof (tcbhead_t, \
561 pointer_guard)))
3467f5c3 562# endif
827b7087
UD
563#endif
564
ec4b0518 565#endif /* linux/i386/sysdep.h */