(root)/
glibc-2.38/
sysdeps/
unix/
sysv/
linux/
loongarch/
sysdep.h
       1  /* Assembly macros for LoongArch.
       2     Copyright (C) 2022-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library.  If not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #ifndef _LINUX_LOONGARCH_SYSDEP_H
      20  #define _LINUX_LOONGARCH_SYSDEP_H 1
      21  
      22  #include <sysdeps/unix/sysv/linux/sysdep.h>
      23  #include <sysdeps/unix/sysdep.h>
      24  #include <tls.h>
      25  
      26  #ifdef __ASSEMBLER__
      27  
      28  #include <sys/asm.h>
      29  #define ret jirl zero, ra, 0
      30  #define L(label) .L##label
      31  
      32  /* Performs a system call, handling errors by setting errno.  Linux indicates
      33     errors by setting a0 to a value between -1 and -4095.  */
      34  #undef PSEUDO
      35  #define PSEUDO(name, syscall_name, args) \
      36    ENTRY (name); \
      37    li.d a7, SYS_ify (syscall_name); \
      38    syscall 0; \
      39    li.d a7, -4096; \
      40    bltu a7, a0, .Lsyscall_error##name;
      41  
      42  #undef PSEUDO_END
      43  #define PSEUDO_END(sym) \
      44    SYSCALL_ERROR_HANDLER (sym); \
      45    ret; \
      46    END (sym);
      47  
      48  #if !IS_IN(libc)
      49  #if RTLD_PRIVATE_ERRNO
      50  
      51  #define SYSCALL_ERROR_HANDLER(name) \
      52    .Lsyscall_error##name : la t0, rtld_errno; \
      53    sub.w a0, zero, a0; \
      54    st.w a0, t0, 0; \
      55    li.d a0, -1;
      56  
      57  #else
      58  
      59  #define SYSCALL_ERROR_HANDLER(name) \
      60    .Lsyscall_error##name : la.tls.ie t0, errno; \
      61    add.d t0, tp, t0; \
      62    sub.w a0, zero, a0; \
      63    st.w a0, t0, 0; \
      64    li.d a0, -1;
      65  
      66  #endif
      67  #else
      68  
      69  #define SYSCALL_ERROR_HANDLER(name) .Lsyscall_error##name : b __syscall_error;
      70  
      71  #endif
      72  
      73  /* Performs a system call, not setting errno.  */
      74  #undef PSEUDO_NEORRNO
      75  #define PSEUDO_NOERRNO(name, syscall_name, args) \
      76    ENTRY (name); \
      77    li.d a7, SYS_ify (syscall_name); \
      78    syscall 0;
      79  
      80  #undef PSEUDO_END_NOERRNO
      81  #define PSEUDO_END_NOERRNO(name) END (name);
      82  
      83  #undef ret_NOERRNO
      84  #define ret_NOERRNO ret
      85  
      86  /* Performs a system call, returning the error code.  */
      87  #undef PSEUDO_ERRVAL
      88  #define PSEUDO_ERRVAL(name, syscall_name, args) \
      89    PSEUDO_NOERRNO (name, syscall_name, args); \
      90    slli.d a0, a0, 32; \
      91    srai.d a0, a0, 32; /* sign_ext */ \
      92    sub.d a0, zero, a0;
      93  
      94  #undef PSEUDO_END_ERRVAL
      95  #define PSEUDO_END_ERRVAL(name) END (name);
      96  
      97  #undef ret_ERRVAL
      98  #define ret_ERRVAL ret
      99  
     100  #endif /* __ASSEMBLER__ */
     101  
     102  /* In order to get __set_errno() definition in INLINE_SYSCALL.  */
     103  #ifndef __ASSEMBLER__
     104  #include <errno.h>
     105  #endif
     106  
     107  #include <sysdeps/unix/sysdep.h>
     108  
     109  #undef SYS_ify
     110  #define SYS_ify(syscall_name) __NR_##syscall_name
     111  
     112  #ifndef __ASSEMBLER__
     113  
     114  #define VDSO_NAME "LINUX_5.10"
     115  #define VDSO_HASH 182947696
     116  
     117  /* List of system calls which are supported as vsyscalls.  */
     118  #define HAVE_CLOCK_GETRES64_VSYSCALL "__vdso_clock_getres"
     119  #define HAVE_CLOCK_GETTIME64_VSYSCALL "__vdso_clock_gettime"
     120  #define HAVE_GETTIMEOFDAY_VSYSCALL "__vdso_gettimeofday"
     121  #define HAVE_GETCPU_VSYSCALL "__vdso_getcpu"
     122  
     123  #define HAVE_CLONE3_WRAPPER 1
     124  
     125  #define INTERNAL_SYSCALL(name, nr, args...) \
     126    internal_syscall##nr (SYS_ify (name), args)
     127  
     128  #define INTERNAL_SYSCALL_NCS(number, nr, args...) \
     129    internal_syscall##nr (number, args)
     130  
     131  #define internal_syscall0(number, dummy...) \
     132    ({ \
     133      long int _sys_result; \
     134  \
     135      { \
     136        register long int __a7 asm ("$a7") = number; \
     137        register long int __a0 asm ("$a0"); \
     138        __asm__ volatile ("syscall 0\n\t" \
     139  		       : "=r"(__a0) \
     140  		       : "r"(__a7) \
     141  		       : __SYSCALL_CLOBBERS); \
     142        _sys_result = __a0; \
     143      } \
     144      _sys_result; \
     145    })
     146  
     147  #define internal_syscall1(number, arg0) \
     148    ({ \
     149      long int _sys_result; \
     150  \
     151      { \
     152        long int _arg0 = (long int) (arg0); \
     153        register long int __a7 asm ("$a7") = number; \
     154        register long int __a0 asm ("$a0") = _arg0; \
     155        __asm__ volatile ("syscall 0\n\t" \
     156  		       : "+r"(__a0) \
     157  		       : "r"(__a7) \
     158  		       : __SYSCALL_CLOBBERS); \
     159        _sys_result = __a0; \
     160      } \
     161      _sys_result; \
     162    })
     163  
     164  #define internal_syscall2(number, arg0, arg1) \
     165    ({ \
     166      long int _sys_result; \
     167  \
     168      { \
     169        long int _arg0 = (long int) (arg0); \
     170        long int _arg1 = (long int) (arg1); \
     171        register long int __a7 asm ("$a7") = number; \
     172        register long int __a0 asm ("$a0") = _arg0; \
     173        register long int __a1 asm ("$a1") = _arg1; \
     174        __asm__ volatile ("syscall 0\n\t" \
     175  		       : "+r"(__a0) \
     176  		       : "r"(__a7), "r"(__a1) \
     177  		       : __SYSCALL_CLOBBERS); \
     178        _sys_result = __a0; \
     179      } \
     180      _sys_result; \
     181    })
     182  
     183  #define internal_syscall3(number, arg0, arg1, arg2) \
     184    ({ \
     185      long int _sys_result; \
     186  \
     187      { \
     188        long int _arg0 = (long int) (arg0); \
     189        long int _arg1 = (long int) (arg1); \
     190        long int _arg2 = (long int) (arg2); \
     191        register long int __a7 asm ("$a7") = number; \
     192        register long int __a0 asm ("$a0") = _arg0; \
     193        register long int __a1 asm ("$a1") = _arg1; \
     194        register long int __a2 asm ("$a2") = _arg2; \
     195        __asm__ volatile ("syscall 0\n\t" \
     196  		       : "+r"(__a0) \
     197  		       : "r"(__a7), "r"(__a1), "r"(__a2) \
     198  		       : __SYSCALL_CLOBBERS); \
     199        _sys_result = __a0; \
     200      } \
     201      _sys_result; \
     202    })
     203  
     204  #define internal_syscall4(number, arg0, arg1, arg2, arg3) \
     205    ({ \
     206      long int _sys_result; \
     207  \
     208      { \
     209        long int _arg0 = (long int) (arg0); \
     210        long int _arg1 = (long int) (arg1); \
     211        long int _arg2 = (long int) (arg2); \
     212        long int _arg3 = (long int) (arg3); \
     213        register long int __a7 asm ("$a7") = number; \
     214        register long int __a0 asm ("$a0") = _arg0; \
     215        register long int __a1 asm ("$a1") = _arg1; \
     216        register long int __a2 asm ("$a2") = _arg2; \
     217        register long int __a3 asm ("$a3") = _arg3; \
     218        __asm__ volatile ("syscall 0\n\t" \
     219  		       : "+r"(__a0) \
     220  		       : "r"(__a7), "r"(__a1), "r"(__a2), "r"(__a3) \
     221  		       : __SYSCALL_CLOBBERS); \
     222        _sys_result = __a0; \
     223      } \
     224      _sys_result; \
     225    })
     226  
     227  #define internal_syscall5(number, arg0, arg1, arg2, arg3, arg4) \
     228    ({ \
     229      long int _sys_result; \
     230  \
     231      { \
     232        long int _arg0 = (long int) (arg0); \
     233        long int _arg1 = (long int) (arg1); \
     234        long int _arg2 = (long int) (arg2); \
     235        long int _arg3 = (long int) (arg3); \
     236        long int _arg4 = (long int) (arg4); \
     237        register long int __a7 asm ("$a7") = number; \
     238        register long int __a0 asm ("$a0") = _arg0; \
     239        register long int __a1 asm ("$a1") = _arg1; \
     240        register long int __a2 asm ("$a2") = _arg2; \
     241        register long int __a3 asm ("$a3") = _arg3; \
     242        register long int __a4 asm ("$a4") = _arg4; \
     243        __asm__ volatile ("syscall 0\n\t" \
     244  		       : "+r"(__a0) \
     245  		       : "r"(__a7), "r"(__a1), "r"(__a2), \
     246  			 "r"(__a3), "r"(__a4) \
     247  		       : __SYSCALL_CLOBBERS); \
     248        _sys_result = __a0; \
     249      } \
     250      _sys_result; \
     251    })
     252  
     253  #define internal_syscall6(number, arg0, arg1, arg2, arg3, arg4, arg5) \
     254    ({ \
     255      long int _sys_result; \
     256  \
     257      { \
     258        long int _arg0 = (long int) (arg0); \
     259        long int _arg1 = (long int) (arg1); \
     260        long int _arg2 = (long int) (arg2); \
     261        long int _arg3 = (long int) (arg3); \
     262        long int _arg4 = (long int) (arg4); \
     263        long int _arg5 = (long int) (arg5); \
     264        register long int __a7 asm ("$a7") = number; \
     265        register long int __a0 asm ("$a0") = _arg0; \
     266        register long int __a1 asm ("$a1") = _arg1; \
     267        register long int __a2 asm ("$a2") = _arg2; \
     268        register long int __a3 asm ("$a3") = _arg3; \
     269        register long int __a4 asm ("$a4") = _arg4; \
     270        register long int __a5 asm ("$a5") = _arg5; \
     271        __asm__ volatile ("syscall 0\n\t" \
     272  		       : "+r"(__a0) \
     273  		       : "r"(__a7), "r"(__a1), "r"(__a2), "r"(__a3), \
     274  			 "r"(__a4), "r"(__a5) \
     275  		       : __SYSCALL_CLOBBERS); \
     276        _sys_result = __a0; \
     277      } \
     278      _sys_result; \
     279    })
     280  
     281  #define internal_syscall7(number, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
     282    ({ \
     283      long int _sys_result; \
     284  \
     285      { \
     286        long int _arg0 = (long int) (arg0); \
     287        long int _arg1 = (long int) (arg1); \
     288        long int _arg2 = (long int) (arg2); \
     289        long int _arg3 = (long int) (arg3); \
     290        long int _arg4 = (long int) (arg4); \
     291        long int _arg5 = (long int) (arg5); \
     292        long int _arg6 = (long int) (arg6); \
     293        register long int __a7 asm ("$a7") = number; \
     294        register long int __a0 asm ("$a0") = _arg0; \
     295        register long int __a1 asm ("$a1") = _arg1; \
     296        register long int __a2 asm ("$a2") = _arg2; \
     297        register long int __a3 asm ("$a3") = _arg3; \
     298        register long int __a4 asm ("$a4") = _arg4; \
     299        register long int __a5 asm ("$a5") = _arg5; \
     300        register long int __a6 asm ("$a6") = _arg6; \
     301        __asm__ volatile ("syscall 0\n\t" \
     302  		       : "+r"(__a0) \
     303  		       : "r"(__a7), "r"(__a1), "r"(__a2), "r"(__a3), \
     304  			 "r"(__a4), "r"(__a5), "r"(__a6) \
     305  		       : __SYSCALL_CLOBBERS); \
     306        _sys_result = __a0; \
     307      } \
     308      _sys_result; \
     309    })
     310  
     311  #define __SYSCALL_CLOBBERS \
     312    "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8", "memory"
     313  
     314  extern long int __syscall_error (long int neg_errno);
     315  
     316  #endif /* ! __ASSEMBLER__ */
     317  
     318  #endif /* linux/loongarch/sysdep.h */