Back to index

glibc  2.9
sysdep.h
Go to the documentation of this file.
00001 /* Copyright (C) 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003 
00004    The GNU C Library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Lesser General Public
00006    License as published by the Free Software Foundation; either
00007    version 2.1 of the License, or (at your option) any later version.
00008 
00009    The GNU C Library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Lesser General Public License for more details.
00013 
00014    You should have received a copy of the GNU Lesser General Public
00015    License along with the GNU C Library; if not, write to the Free
00016    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00017    02111-1307 USA.  */
00018 
00019 #ifndef _LINUX_MIPS_MIPS32_SYSDEP_H
00020 #define _LINUX_MIPS_MIPS32_SYSDEP_H 1
00021 
00022 /* There is some commonality.  */
00023 #include <sysdeps/unix/mips/mips32/sysdep.h>
00024 
00025 #include <tls.h>
00026 
00027 /* For Linux we can use the system call table in the header file
00028        /usr/include/asm/unistd.h
00029    of the kernel.  But these symbols do not follow the SYS_* syntax
00030    so we have to redefine the `SYS_ify' macro here.  */
00031 #undef SYS_ify
00032 #ifdef __STDC__
00033 # define SYS_ify(syscall_name)     __NR_##syscall_name
00034 #else
00035 # define SYS_ify(syscall_name)     __NR_syscall_name
00036 #endif
00037 
00038 #ifndef __ASSEMBLER__
00039 
00040 /* Define a macro which expands into the inline wrapper code for a system
00041    call.  */
00042 #undef INLINE_SYSCALL
00043 #define INLINE_SYSCALL(name, nr, args...)                               \
00044   ({ INTERNAL_SYSCALL_DECL(err);                               \
00045      long result_var = INTERNAL_SYSCALL (name, err, nr, args);        \
00046      if ( INTERNAL_SYSCALL_ERROR_P (result_var, err) )                \
00047        {                                                       \
00048         __set_errno (INTERNAL_SYSCALL_ERRNO (result_var, err));       \
00049         result_var = -1L;                                      \
00050        }                                                       \
00051      result_var; })
00052 
00053 #undef INTERNAL_SYSCALL_DECL
00054 #define INTERNAL_SYSCALL_DECL(err) long err
00055 
00056 #undef INTERNAL_SYSCALL_ERROR_P
00057 #define INTERNAL_SYSCALL_ERROR_P(val, err)   ((long) (err))
00058 
00059 #undef INTERNAL_SYSCALL_ERRNO
00060 #define INTERNAL_SYSCALL_ERRNO(val, err)     (val)
00061 
00062 #undef INTERNAL_SYSCALL
00063 #define INTERNAL_SYSCALL(name, err, nr, args...) \
00064        internal_syscall##nr (, "li\t$2, %2\t\t\t# " #name "\n\t",     \
00065                            "i" (SYS_ify (name)), err, args)
00066 
00067 #undef INTERNAL_SYSCALL_NCS
00068 #define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \
00069        internal_syscall##nr (= number, , "r" (__v0), err, args)
00070 
00071 #define internal_syscall0(ncs_init, cs_init, input, err, dummy...)    \
00072 ({                                                             \
00073        long _sys_result;                                       \
00074                                                                \
00075        {                                                       \
00076        register long __v0 asm("$2") ncs_init;                         \
00077        register long __a3 asm("$7");                                  \
00078        __asm__ volatile (                                      \
00079        ".set\tnoreorder\n\t"                                          \
00080        cs_init                                                        \
00081        "syscall\n\t"                                           \
00082        ".set reorder"                                                 \
00083        : "=r" (__v0), "=r" (__a3)                              \
00084        : input                                                        \
00085        : __SYSCALL_CLOBBERS);                                         \
00086        err = __a3;                                             \
00087        _sys_result = __v0;                                     \
00088        }                                                       \
00089        _sys_result;                                            \
00090 })
00091 
00092 #define internal_syscall1(ncs_init, cs_init, input, err, arg1)        \
00093 ({                                                             \
00094        long _sys_result;                                       \
00095                                                                \
00096        {                                                       \
00097        register long __v0 asm("$2") ncs_init;                         \
00098        register long __a0 asm("$4") = (long) arg1;                    \
00099        register long __a3 asm("$7");                                  \
00100        __asm__ volatile (                                      \
00101        ".set\tnoreorder\n\t"                                          \
00102        cs_init                                                        \
00103        "syscall\n\t"                                           \
00104        ".set reorder"                                                 \
00105        : "=r" (__v0), "=r" (__a3)                              \
00106        : input, "r" (__a0)                                     \
00107        : __SYSCALL_CLOBBERS);                                         \
00108        err = __a3;                                             \
00109        _sys_result = __v0;                                     \
00110        }                                                       \
00111        _sys_result;                                            \
00112 })
00113 
00114 #define internal_syscall2(ncs_init, cs_init, input, err, arg1, arg2)  \
00115 ({                                                             \
00116        long _sys_result;                                       \
00117                                                                \
00118        {                                                       \
00119        register long __v0 asm("$2") ncs_init;                         \
00120        register long __a0 asm("$4") = (long) arg1;                    \
00121        register long __a1 asm("$5") = (long) arg2;                    \
00122        register long __a3 asm("$7");                                  \
00123        __asm__ volatile (                                      \
00124        ".set\tnoreorder\n\t"                                          \
00125        cs_init                                                        \
00126        "syscall\n\t"                                           \
00127        ".set\treorder"                                         \
00128        : "=r" (__v0), "=r" (__a3)                              \
00129        : input, "r" (__a0), "r" (__a1)                                \
00130        : __SYSCALL_CLOBBERS);                                         \
00131        err = __a3;                                             \
00132        _sys_result = __v0;                                     \
00133        }                                                       \
00134        _sys_result;                                            \
00135 })
00136 
00137 #define internal_syscall3(ncs_init, cs_init, input, err, arg1, arg2, arg3)\
00138 ({                                                             \
00139        long _sys_result;                                       \
00140                                                                \
00141        {                                                       \
00142        register long __v0 asm("$2") ncs_init;                         \
00143        register long __a0 asm("$4") = (long) arg1;                    \
00144        register long __a1 asm("$5") = (long) arg2;                    \
00145        register long __a2 asm("$6") = (long) arg3;                    \
00146        register long __a3 asm("$7");                                  \
00147        __asm__ volatile (                                      \
00148        ".set\tnoreorder\n\t"                                          \
00149        cs_init                                                        \
00150        "syscall\n\t"                                           \
00151        ".set\treorder"                                         \
00152        : "=r" (__v0), "=r" (__a3)                              \
00153        : input, "r" (__a0), "r" (__a1), "r" (__a2)                    \
00154        : __SYSCALL_CLOBBERS);                                         \
00155        err = __a3;                                             \
00156        _sys_result = __v0;                                     \
00157        }                                                       \
00158        _sys_result;                                            \
00159 })
00160 
00161 #define internal_syscall4(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4)\
00162 ({                                                             \
00163        long _sys_result;                                       \
00164                                                                \
00165        {                                                       \
00166        register long __v0 asm("$2") ncs_init;                         \
00167        register long __a0 asm("$4") = (long) arg1;                    \
00168        register long __a1 asm("$5") = (long) arg2;                    \
00169        register long __a2 asm("$6") = (long) arg3;                    \
00170        register long __a3 asm("$7") = (long) arg4;                    \
00171        __asm__ volatile (                                      \
00172        ".set\tnoreorder\n\t"                                          \
00173        cs_init                                                        \
00174        "syscall\n\t"                                           \
00175        ".set\treorder"                                         \
00176        : "=r" (__v0), "+r" (__a3)                              \
00177        : input, "r" (__a0), "r" (__a1), "r" (__a2)                    \
00178        : __SYSCALL_CLOBBERS);                                         \
00179        err = __a3;                                             \
00180        _sys_result = __v0;                                     \
00181        }                                                       \
00182        _sys_result;                                            \
00183 })
00184 
00185 /* We need to use a frame pointer for the functions in which we
00186    adjust $sp around the syscall, or debug information and unwind
00187    information will be $sp relative and thus wrong during the syscall.  As
00188    of GCC 3.4.3, this is sufficient.  */
00189 #define FORCE_FRAME_POINTER alloca (4)
00190 
00191 #define internal_syscall5(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5)\
00192 ({                                                             \
00193        long _sys_result;                                       \
00194                                                                \
00195        FORCE_FRAME_POINTER;                                    \
00196        {                                                       \
00197        register long __v0 asm("$2") ncs_init;                         \
00198        register long __a0 asm("$4") = (long) arg1;                    \
00199        register long __a1 asm("$5") = (long) arg2;                    \
00200        register long __a2 asm("$6") = (long) arg3;                    \
00201        register long __a3 asm("$7") = (long) arg4;                    \
00202        __asm__ volatile (                                      \
00203        ".set\tnoreorder\n\t"                                          \
00204        "subu\t$29, 32\n\t"                                     \
00205        "sw\t%6, 16($29)\n\t"                                          \
00206        cs_init                                                        \
00207        "syscall\n\t"                                           \
00208        "addiu\t$29, 32\n\t"                                    \
00209        ".set\treorder"                                         \
00210        : "=r" (__v0), "+r" (__a3)                              \
00211        : input, "r" (__a0), "r" (__a1), "r" (__a2),                   \
00212          "r" ((long)arg5)                                      \
00213        : __SYSCALL_CLOBBERS);                                         \
00214        err = __a3;                                             \
00215        _sys_result = __v0;                                     \
00216        }                                                       \
00217        _sys_result;                                            \
00218 })
00219 
00220 #define internal_syscall6(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5, arg6)\
00221 ({                                                             \
00222        long _sys_result;                                       \
00223                                                                \
00224        FORCE_FRAME_POINTER;                                    \
00225        {                                                       \
00226        register long __v0 asm("$2") ncs_init;                         \
00227        register long __a0 asm("$4") = (long) arg1;                    \
00228        register long __a1 asm("$5") = (long) arg2;                    \
00229        register long __a2 asm("$6") = (long) arg3;                    \
00230        register long __a3 asm("$7") = (long) arg4;                    \
00231        __asm__ volatile (                                      \
00232        ".set\tnoreorder\n\t"                                          \
00233        "subu\t$29, 32\n\t"                                     \
00234        "sw\t%6, 16($29)\n\t"                                          \
00235        "sw\t%7, 20($29)\n\t"                                          \
00236        cs_init                                                        \
00237        "syscall\n\t"                                           \
00238        "addiu\t$29, 32\n\t"                                    \
00239        ".set\treorder"                                         \
00240        : "=r" (__v0), "+r" (__a3)                              \
00241        : input, "r" (__a0), "r" (__a1), "r" (__a2),                   \
00242          "r" ((long)arg5), "r" ((long)arg6)                           \
00243        : __SYSCALL_CLOBBERS);                                         \
00244        err = __a3;                                             \
00245        _sys_result = __v0;                                     \
00246        }                                                       \
00247        _sys_result;                                            \
00248 })
00249 
00250 #define internal_syscall7(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5, arg6, arg7)\
00251 ({                                                             \
00252        long _sys_result;                                       \
00253                                                                \
00254        FORCE_FRAME_POINTER;                                    \
00255        {                                                       \
00256        register long __v0 asm("$2") ncs_init;                         \
00257        register long __a0 asm("$4") = (long) arg1;                    \
00258        register long __a1 asm("$5") = (long) arg2;                    \
00259        register long __a2 asm("$6") = (long) arg3;                    \
00260        register long __a3 asm("$7") = (long) arg4;                    \
00261        __asm__ volatile (                                      \
00262        ".set\tnoreorder\n\t"                                          \
00263        "subu\t$29, 32\n\t"                                     \
00264        "sw\t%6, 16($29)\n\t"                                          \
00265        "sw\t%7, 20($29)\n\t"                                          \
00266        "sw\t%8, 24($29)\n\t"                                          \
00267        cs_init                                                        \
00268        "syscall\n\t"                                           \
00269        "addiu\t$29, 32\n\t"                                    \
00270        ".set\treorder"                                         \
00271        : "=r" (__v0), "+r" (__a3)                              \
00272        : input, "r" (__a0), "r" (__a1), "r" (__a2),                   \
00273          "r" ((long)arg5), "r" ((long)arg6), "r" ((long)arg7)         \
00274        : __SYSCALL_CLOBBERS);                                         \
00275        err = __a3;                                             \
00276        _sys_result = __v0;                                     \
00277        }                                                       \
00278        _sys_result;                                            \
00279 })
00280 
00281 #define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
00282        "$14", "$15", "$24", "$25", "memory"
00283 
00284 #endif /* __ASSEMBLER__ */
00285 
00286 /* Pointer mangling is not yet supported for MIPS.  */
00287 #define PTR_MANGLE(var) (void) (var)
00288 #define PTR_DEMANGLE(var) (void) (var)
00289 
00290 #endif /* linux/mips/mips32/sysdep.h */