(SETUP_PIC_REG): Use .ifndef/.endif to allow use of this macro more
[kopensolaris-gnu/glibc.git] / sysdeps / unix / sysv / linux / i386 / sysdep.h
1 /* Copyright (C) 1992,1993,1995,1996,1997,1998,1999,2000,2002,2003,2004,2005
2         Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Ulrich Drepper, <drepper@gnu.org>, August 1995.
5
6    The GNU C Library is free software; you can redistribute it and/or
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.
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
14    Lesser General Public License for more details.
15
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.  */
20
21 #ifndef _LINUX_I386_SYSDEP_H
22 #define _LINUX_I386_SYSDEP_H 1
23
24 /* There is some commonality.  */
25 #include <sysdeps/unix/i386/sysdep.h>
26 #include <bp-sym.h>
27 #include <bp-asm.h>
28 /* Defines RTLD_PRIVATE_ERRNO and USE_DL_SYSINFO.  */
29 #include <dl-sysdep.h>
30 #include <tls.h>
31
32
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
38 #define SYS_ify(syscall_name)   __NR_##syscall_name
39
40 #if defined USE_DL_SYSINFO \
41     && (!defined NOT_IN_libc || defined IS_IN_libpthread)
42 # define I386_USE_SYSENTER      1
43 #else
44 # undef I386_USE_SYSENTER
45 #endif
46
47 #ifdef __ASSEMBLER__
48
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
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.  */
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
68 #undef  PSEUDO
69 #define PSEUDO(name, syscall_name, args)                                      \
70   .text;                                                                      \
71   ENTRY (name)                                                                \
72     DO_CALL (syscall_name, args);                                             \
73     cmpl $-4095, %eax;                                                        \
74     jae SYSCALL_ERROR_LABEL;                                                  \
75   L(pseudo_end):
76
77 #undef  PSEUDO_END
78 #define PSEUDO_END(name)                                                      \
79   SYSCALL_ERROR_HANDLER                                                       \
80   END (name)
81
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
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
108 #ifndef PIC
109 # define SYSCALL_ERROR_HANDLER  /* Nothing here; code in sysdep.S is used.  */
110 #else
111
112 # ifndef HAVE_HIDDEN
113 #  define SETUP_PIC_REG(reg) \
114   call 1f;                                                                    \
115   .subsection 1;                                                              \
116 1:movl (%esp), %e##reg;                                                       \
117   ret;                                                                        \
118   .previous
119 # else
120 #  define SETUP_PIC_REG(reg) \
121   .ifndef __i686.get_pc_thunk.reg;                                            \
122   .section .gnu.linkonce.t.__i686.get_pc_thunk.reg,"ax",@progbits;            \
123   .globl __i686.get_pc_thunk.reg;                                             \
124   .hidden __i686.get_pc_thunk.reg;                                            \
125   .type __i686.get_pc_thunk.reg,@function;                                    \
126 __i686.get_pc_thunk.reg:                                                      \
127   movl (%esp), %e##reg;                                                       \
128   ret;                                                                        \
129   .size __i686.get_pc_thunk.reg, . - __i686.get_pc_thunk.reg;                 \
130   .previous;                                                                  \
131   .endif;                                                                     \
132   call __i686.get_pc_thunk.reg
133 # endif
134
135 # define LOAD_PIC_REG(reg) \
136   SETUP_PIC_REG(reg); addl $_GLOBAL_OFFSET_TABLE_, %e##reg
137
138 # if RTLD_PRIVATE_ERRNO
139 #  define SYSCALL_ERROR_HANDLER                                               \
140 0:SETUP_PIC_REG(cx);                                                          \
141   addl $_GLOBAL_OFFSET_TABLE_, %ecx;                                          \
142   xorl %edx, %edx;                                                            \
143   subl %eax, %edx;                                                            \
144   movl %edx, rtld_errno@GOTOFF(%ecx);                                         \
145   orl $-1, %eax;                                                              \
146   jmp L(pseudo_end);
147
148 # elif defined _LIBC_REENTRANT
149
150 #  if USE___THREAD
151 #   ifndef NOT_IN_libc
152 #    define SYSCALL_ERROR_ERRNO __libc_errno
153 #   else
154 #    define SYSCALL_ERROR_ERRNO errno
155 #   endif
156 #   define SYSCALL_ERROR_HANDLER                                              \
157 0:SETUP_PIC_REG (cx);                                                         \
158   addl $_GLOBAL_OFFSET_TABLE_, %ecx;                                          \
159   movl SYSCALL_ERROR_ERRNO@GOTNTPOFF(%ecx), %ecx;                             \
160   xorl %edx, %edx;                                                            \
161   subl %eax, %edx;                                                            \
162   SYSCALL_ERROR_HANDLER_TLS_STORE (%edx, %ecx);                               \
163   orl $-1, %eax;                                                              \
164   jmp L(pseudo_end);
165 #   ifndef NO_TLS_DIRECT_SEG_REFS
166 #    define SYSCALL_ERROR_HANDLER_TLS_STORE(src, destoff)                     \
167   movl src, %gs:(destoff)
168 #   else
169 #    define SYSCALL_ERROR_HANDLER_TLS_STORE(src, destoff)                     \
170   addl %gs:0, destoff;                                                        \
171   movl src, (destoff)
172 #   endif
173 #  else
174 #   define SYSCALL_ERROR_HANDLER                                              \
175 0:pushl %ebx;                                                                 \
176   cfi_adjust_cfa_offset (4);                                                  \
177   cfi_rel_offset (ebx, 0);                                                    \
178   SETUP_PIC_REG (bx);                                                         \
179   addl $_GLOBAL_OFFSET_TABLE_, %ebx;                                          \
180   xorl %edx, %edx;                                                            \
181   subl %eax, %edx;                                                            \
182   pushl %edx;                                                                 \
183   cfi_adjust_cfa_offset (4);                                                  \
184   PUSH_ERRNO_LOCATION_RETURN;                                                 \
185   call BP_SYM (__errno_location)@PLT;                                         \
186   POP_ERRNO_LOCATION_RETURN;                                                  \
187   popl %ecx;                                                                  \
188   cfi_adjust_cfa_offset (-4);                                                 \
189   popl %ebx;                                                                  \
190   cfi_adjust_cfa_offset (-4);                                                 \
191   cfi_restore (ebx);                                                          \
192   movl %ecx, (%eax);                                                          \
193   orl $-1, %eax;                                                              \
194   jmp L(pseudo_end);
195 /* A quick note: it is assumed that the call to `__errno_location' does
196    not modify the stack!  */
197 #  endif
198 # else
199 /* Store (- %eax) into errno through the GOT.  */
200 #  define SYSCALL_ERROR_HANDLER                                               \
201 0:SETUP_PIC_REG(cx);                                                          \
202   addl $_GLOBAL_OFFSET_TABLE_, %ecx;                                          \
203   xorl %edx, %edx;                                                            \
204   subl %eax, %edx;                                                            \
205   movl errno@GOT(%ecx), %ecx;                                                 \
206   movl %edx, (%ecx);                                                          \
207   orl $-1, %eax;                                                              \
208   jmp L(pseudo_end);
209 # endif /* _LIBC_REENTRANT */
210 #endif  /* PIC */
211
212
213 /* The original calling convention for system calls on Linux/i386 is
214    to use int $0x80.  */
215 #ifdef I386_USE_SYSENTER
216 # ifdef SHARED
217 #  define ENTER_KERNEL call *%gs:SYSINFO_OFFSET
218 # else
219 #  define ENTER_KERNEL call *_dl_sysinfo
220 # endif
221 #else
222 # define ENTER_KERNEL int $0x80
223 #endif
224
225 /* Linux takes system call arguments in registers:
226
227         syscall number  %eax         call-clobbered
228         arg 1           %ebx         call-saved
229         arg 2           %ecx         call-clobbered
230         arg 3           %edx         call-clobbered
231         arg 4           %esi         call-saved
232         arg 5           %edi         call-saved
233
234    The stack layout upon entering the function is:
235
236         20(%esp)        Arg# 5
237         16(%esp)        Arg# 4
238         12(%esp)        Arg# 3
239          8(%esp)        Arg# 2
240          4(%esp)        Arg# 1
241           (%esp)        Return address
242
243    (Of course a function with say 3 arguments does not have entries for
244    arguments 4 and 5.)
245
246    The following code tries hard to be optimal.  A general assumption
247    (which is true according to the data books I have) is that
248
249         2 * xchg        is more expensive than  pushl + movl + popl
250
251    Beside this a neat trick is used.  The calling conventions for Linux
252    tell that among the registers used for parameters %ecx and %edx need
253    not be saved.  Beside this we may clobber this registers even when
254    they are not used for parameter passing.
255
256    As a result one can see below that we save the content of the %ebx
257    register in the %edx register when we have less than 3 arguments
258    (2 * movl is less expensive than pushl + popl).
259
260    Second unlike for the other registers we don't save the content of
261    %ecx and %edx when we have more than 1 and 2 registers resp.
262
263    The code below might look a bit long but we have to take care for
264    the pipelined processors (i586).  Here the `pushl' and `popl'
265    instructions are marked as NP (not pairable) but the exception is
266    two consecutive of these instruction.  This gives no penalty on
267    other processors though.  */
268
269 #undef  DO_CALL
270 #define DO_CALL(syscall_name, args)                                           \
271     PUSHARGS_##args                                                           \
272     DOARGS_##args                                                             \
273     movl $SYS_ify (syscall_name), %eax;                                       \
274     ENTER_KERNEL                                                              \
275     POPARGS_##args
276
277 #define PUSHARGS_0      /* No arguments to push.  */
278 #define DOARGS_0        /* No arguments to frob.  */
279 #define POPARGS_0       /* No arguments to pop.  */
280 #define _PUSHARGS_0     /* No arguments to push.  */
281 #define _DOARGS_0(n)    /* No arguments to frob.  */
282 #define _POPARGS_0      /* No arguments to pop.  */
283
284 #define PUSHARGS_1      movl %ebx, %edx; L(SAVEBX1): PUSHARGS_0
285 #define DOARGS_1        _DOARGS_1 (4)
286 #define POPARGS_1       POPARGS_0; movl %edx, %ebx; L(RESTBX1):
287 #define _PUSHARGS_1     pushl %ebx; cfi_adjust_cfa_offset (4); \
288                         cfi_rel_offset (ebx, 0); L(PUSHBX1): _PUSHARGS_0
289 #define _DOARGS_1(n)    movl n(%esp), %ebx; _DOARGS_0(n-4)
290 #define _POPARGS_1      _POPARGS_0; popl %ebx; cfi_adjust_cfa_offset (-4); \
291                         cfi_restore (ebx); L(POPBX1):
292
293 #define PUSHARGS_2      PUSHARGS_1
294 #define DOARGS_2        _DOARGS_2 (8)
295 #define POPARGS_2       POPARGS_1
296 #define _PUSHARGS_2     _PUSHARGS_1
297 #define _DOARGS_2(n)    movl n(%esp), %ecx; _DOARGS_1 (n-4)
298 #define _POPARGS_2      _POPARGS_1
299
300 #define PUSHARGS_3      _PUSHARGS_2
301 #define DOARGS_3        _DOARGS_3 (16)
302 #define POPARGS_3       _POPARGS_3
303 #define _PUSHARGS_3     _PUSHARGS_2
304 #define _DOARGS_3(n)    movl n(%esp), %edx; _DOARGS_2 (n-4)
305 #define _POPARGS_3      _POPARGS_2
306
307 #define PUSHARGS_4      _PUSHARGS_4
308 #define DOARGS_4        _DOARGS_4 (24)
309 #define POPARGS_4       _POPARGS_4
310 #define _PUSHARGS_4     pushl %esi; cfi_adjust_cfa_offset (4); \
311                         cfi_rel_offset (esi, 0); L(PUSHSI1): _PUSHARGS_3
312 #define _DOARGS_4(n)    movl n(%esp), %esi; _DOARGS_3 (n-4)
313 #define _POPARGS_4      _POPARGS_3; popl %esi; cfi_adjust_cfa_offset (-4); \
314                         cfi_restore (esi); L(POPSI1):
315
316 #define PUSHARGS_5      _PUSHARGS_5
317 #define DOARGS_5        _DOARGS_5 (32)
318 #define POPARGS_5       _POPARGS_5
319 #define _PUSHARGS_5     pushl %edi; cfi_adjust_cfa_offset (4); \
320                         cfi_rel_offset (edi, 0); L(PUSHDI1): _PUSHARGS_4
321 #define _DOARGS_5(n)    movl n(%esp), %edi; _DOARGS_4 (n-4)
322 #define _POPARGS_5      _POPARGS_4; popl %edi; cfi_adjust_cfa_offset (-4); \
323                         cfi_restore (edi); L(POPDI1):
324
325 #define PUSHARGS_6      _PUSHARGS_6
326 #define DOARGS_6        _DOARGS_6 (36)
327 #define POPARGS_6       _POPARGS_6
328 #define _PUSHARGS_6     pushl %ebp; cfi_adjust_cfa_offset (4); \
329                         cfi_rel_offset (ebp, 0); L(PUSHBP1): _PUSHARGS_5
330 #define _DOARGS_6(n)    movl n(%esp), %ebp; _DOARGS_5 (n-4)
331 #define _POPARGS_6      _POPARGS_5; popl %ebp; cfi_adjust_cfa_offset (-4); \
332                         cfi_restore (ebp); L(POPBP1):
333
334 #else   /* !__ASSEMBLER__ */
335
336 /* We need some help from the assembler to generate optimal code.  We
337    define some macros here which later will be used.  */
338 asm (".L__X'%ebx = 1\n\t"
339      ".L__X'%ecx = 2\n\t"
340      ".L__X'%edx = 2\n\t"
341      ".L__X'%eax = 3\n\t"
342      ".L__X'%esi = 3\n\t"
343      ".L__X'%edi = 3\n\t"
344      ".L__X'%ebp = 3\n\t"
345      ".L__X'%esp = 3\n\t"
346      ".macro bpushl name reg\n\t"
347      ".if 1 - \\name\n\t"
348      ".if 2 - \\name\n\t"
349      "error\n\t"
350      ".else\n\t"
351      "xchgl \\reg, %ebx\n\t"
352      ".endif\n\t"
353      ".endif\n\t"
354      ".endm\n\t"
355      ".macro bpopl name reg\n\t"
356      ".if 1 - \\name\n\t"
357      ".if 2 - \\name\n\t"
358      "error\n\t"
359      ".else\n\t"
360      "xchgl \\reg, %ebx\n\t"
361      ".endif\n\t"
362      ".endif\n\t"
363      ".endm\n\t");
364
365 /* Define a macro which expands inline into the wrapper code for a system
366    call.  */
367 #undef INLINE_SYSCALL
368 #define INLINE_SYSCALL(name, nr, args...) \
369   ({                                                                          \
370     unsigned int resultvar = INTERNAL_SYSCALL (name, , nr, args);             \
371     if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (resultvar, ), 0))         \
372       {                                                                       \
373         __set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, ));                   \
374         resultvar = 0xffffffff;                                               \
375       }                                                                       \
376     (int) resultvar; })
377
378 /* Define a macro which expands inline into the wrapper code for a system
379    call.  This use is for internal calls that do not need to handle errors
380    normally.  It will never touch errno.  This returns just what the kernel
381    gave back.
382
383    The _NCS variant allows non-constant syscall numbers but it is not
384    possible to use more than four parameters.  */
385 #undef INTERNAL_SYSCALL
386 #ifdef I386_USE_SYSENTER
387 # ifdef SHARED
388 #  define INTERNAL_SYSCALL(name, err, nr, args...) \
389   ({                                                                          \
390     register unsigned int resultvar;                                          \
391     EXTRAVAR_##nr                                                             \
392     asm volatile (                                                            \
393     LOADARGS_##nr                                                             \
394     "movl %1, %%eax\n\t"                                                      \
395     "call *%%gs:%P2\n\t"                                                      \
396     RESTOREARGS_##nr                                                          \
397     : "=a" (resultvar)                                                        \
398     : "i" (__NR_##name), "i" (offsetof (tcbhead_t, sysinfo))                  \
399       ASMFMT_##nr(args) : "memory", "cc");                                    \
400     (int) resultvar; })
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     "call *%%gs:%P2\n\t"                                                      \
408     RESTOREARGS_##nr                                                          \
409     : "=a" (resultvar)                                                        \
410     : "0" (name), "i" (offsetof (tcbhead_t, sysinfo))                         \
411       ASMFMT_##nr(args) : "memory", "cc");                                    \
412     (int) resultvar; })
413 # else
414 #  define INTERNAL_SYSCALL(name, err, nr, args...) \
415   ({                                                                          \
416     register unsigned int resultvar;                                          \
417     EXTRAVAR_##nr                                                             \
418     asm volatile (                                                            \
419     LOADARGS_##nr                                                             \
420     "movl %1, %%eax\n\t"                                                      \
421     "call *_dl_sysinfo\n\t"                                                   \
422     RESTOREARGS_##nr                                                          \
423     : "=a" (resultvar)                                                        \
424     : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc");                  \
425     (int) resultvar; })
426 #  define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
427   ({                                                                          \
428     register unsigned int resultvar;                                          \
429     EXTRAVAR_##nr                                                             \
430     asm volatile (                                                            \
431     LOADARGS_##nr                                                             \
432     "call *_dl_sysinfo\n\t"                                                   \
433     RESTOREARGS_##nr                                                          \
434     : "=a" (resultvar)                                                        \
435     : "0" (name) ASMFMT_##nr(args) : "memory", "cc");                         \
436     (int) resultvar; })
437 # endif
438 #else
439 # define INTERNAL_SYSCALL(name, err, nr, args...) \
440   ({                                                                          \
441     register unsigned int resultvar;                                          \
442     EXTRAVAR_##nr                                                             \
443     asm volatile (                                                            \
444     LOADARGS_##nr                                                             \
445     "movl %1, %%eax\n\t"                                                      \
446     "int $0x80\n\t"                                                           \
447     RESTOREARGS_##nr                                                          \
448     : "=a" (resultvar)                                                        \
449     : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc");                  \
450     (int) resultvar; })
451 # define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
452   ({                                                                          \
453     register unsigned int resultvar;                                          \
454     EXTRAVAR_##nr                                                             \
455     asm volatile (                                                            \
456     LOADARGS_##nr                                                             \
457     "int $0x80\n\t"                                                           \
458     RESTOREARGS_##nr                                                          \
459     : "=a" (resultvar)                                                        \
460     : "0" (name) ASMFMT_##nr(args) : "memory", "cc");                         \
461     (int) resultvar; })
462 #endif
463
464 #undef INTERNAL_SYSCALL_DECL
465 #define INTERNAL_SYSCALL_DECL(err) do { } while (0)
466
467 #undef INTERNAL_SYSCALL_ERROR_P
468 #define INTERNAL_SYSCALL_ERROR_P(val, err) \
469   ((unsigned int) (val) >= 0xfffff001u)
470
471 #undef INTERNAL_SYSCALL_ERRNO
472 #define INTERNAL_SYSCALL_ERRNO(val, err)        (-(val))
473
474 #define LOADARGS_0
475 #ifdef __PIC__
476 # if defined I386_USE_SYSENTER
477 #  define LOADARGS_1 \
478     "bpushl .L__X'%k3, %k3\n\t"
479 #  define LOADARGS_5 \
480     "movl %%ebx, %4\n\t"                                                      \
481     "movl %3, %%ebx\n\t"
482 # else
483 #  define LOADARGS_1 \
484     "bpushl .L__X'%k2, %k2\n\t"
485 #  define LOADARGS_5 \
486     "movl %%ebx, %3\n\t"                                                      \
487     "movl %2, %%ebx\n\t"
488 # endif
489 # define LOADARGS_2     LOADARGS_1
490 # define LOADARGS_3 \
491     "xchgl %%ebx, %%edi\n\t"
492 # define LOADARGS_4     LOADARGS_3
493 #else
494 # define LOADARGS_1
495 # define LOADARGS_2
496 # define LOADARGS_3
497 # define LOADARGS_4
498 # define LOADARGS_5
499 #endif
500
501 #define RESTOREARGS_0
502 #ifdef __PIC__
503 # if defined I386_USE_SYSENTER && defined SHARED
504 #  define RESTOREARGS_1 \
505     "bpopl .L__X'%k3, %k3\n\t"
506 #  define RESTOREARGS_5 \
507     "movl %4, %%ebx"
508 # else
509 #  define RESTOREARGS_1 \
510     "bpopl .L__X'%k2, %k2\n\t"
511 #  define RESTOREARGS_5 \
512     "movl %3, %%ebx"
513 # endif
514 # define RESTOREARGS_2  RESTOREARGS_1
515 # define RESTOREARGS_3 \
516     "xchgl %%edi, %%ebx\n\t"
517 # define RESTOREARGS_4  RESTOREARGS_3
518 #else
519 # define RESTOREARGS_1
520 # define RESTOREARGS_2
521 # define RESTOREARGS_3
522 # define RESTOREARGS_4
523 # define RESTOREARGS_5
524 #endif
525
526 #define ASMFMT_0()
527 #ifdef __PIC__
528 # define ASMFMT_1(arg1) \
529         , "cd" (arg1)
530 # define ASMFMT_2(arg1, arg2) \
531         , "d" (arg1), "c" (arg2)
532 # define ASMFMT_3(arg1, arg2, arg3) \
533         , "D" (arg1), "c" (arg2), "d" (arg3)
534 # define ASMFMT_4(arg1, arg2, arg3, arg4) \
535         , "D" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
536 # define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \
537         , "0" (arg1), "m" (_xv), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
538 #else
539 # define ASMFMT_1(arg1) \
540         , "b" (arg1)
541 # define ASMFMT_2(arg1, arg2) \
542         , "b" (arg1), "c" (arg2)
543 # define ASMFMT_3(arg1, arg2, arg3) \
544         , "b" (arg1), "c" (arg2), "d" (arg3)
545 # define ASMFMT_4(arg1, arg2, arg3, arg4) \
546         , "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
547 # define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \
548         , "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
549 #endif
550
551 #define EXTRAVAR_0
552 #define EXTRAVAR_1
553 #define EXTRAVAR_2
554 #define EXTRAVAR_3
555 #define EXTRAVAR_4
556 #ifdef __PIC__
557 # define EXTRAVAR_5 int _xv;
558 #else
559 # define EXTRAVAR_5
560 #endif
561
562 /* Consistency check for position-independent code.  */
563 #ifdef __PIC__
564 # define check_consistency()                                                  \
565   ({ int __res;                                                               \
566      __asm__ __volatile__                                                     \
567        ("call __i686.get_pc_thunk.cx;"                                        \
568         "addl $_GLOBAL_OFFSET_TABLE_, %%ecx;"                                 \
569         "subl %%ebx, %%ecx;"                                                  \
570         "je 1f;"                                                              \
571         "ud2;"                                                                \
572         "1:\n"                                                                \
573         ".section .gnu.linkonce.t.__i686.get_pc_thunk.cx,\"ax\",@progbits;"   \
574         ".globl __i686.get_pc_thunk.cx;"                                      \
575         ".hidden __i686.get_pc_thunk.cx;"                                     \
576         ".type __i686.get_pc_thunk.cx,@function;"                             \
577         "__i686.get_pc_thunk.cx:"                                             \
578         "movl (%%esp), %%ecx;"                                                \
579         "ret;"                                                                \
580         ".previous"                                                           \
581         : "=c" (__res));                                                      \
582      __res; })
583 #endif
584
585 #endif  /* __ASSEMBLER__ */
586
587 #endif /* linux/i386/sysdep.h */