(root)/
glibc-2.38/
sysdeps/
unix/
sysv/
linux/
or1k/
sysdep.h
       1  /* Assembler and syscall macros.  OpenRISC version.
       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_OR1K_SYSDEP_H
      20  #define _LINUX_OR1K_SYSDEP_H 1
      21  
      22  #include <sysdeps/unix/sysv/linux/sysdep.h>
      23  #include <sysdeps/or1k/sysdep.h>
      24  #include <sysdeps/unix/sysdep.h>
      25  #include <tls.h>
      26  
      27  /* "workarounds" for generic code needing to handle 64-bit time_t.  */
      28  
      29  #undef __NR_clock_getres
      30  #undef __NR_futex
      31  #undef __NR_ppoll
      32  #undef __NR_pselect6
      33  #undef __NR_recvmmsg
      34  #undef __NR_rt_sigtimedwait
      35  #undef __NR_semtimedop
      36  #undef __NR_utimensat
      37  
      38  /* Fix sysdeps/unix/sysv/linux/clock_getcpuclockid.c.  */
      39  #define __NR_clock_getres	__NR_clock_getres_time64
      40  /* Fix sysdeps/nptl/lowlevellock-futex.h.  */
      41  #define __NR_futex		__NR_futex_time64
      42  /* Fix sysdeps/unix/sysv/linux/pause.c.  */
      43  #define __NR_ppoll		__NR_ppoll_time64
      44  /* Fix sysdeps/unix/sysv/linux/select.c.  */
      45  #define __NR_pselect6		__NR_pselect6_time64
      46  /* Fix sysdeps/unix/sysv/linux/recvmmsg.c.  */
      47  #define __NR_recvmmsg		__NR_recvmmsg_time64
      48  /* Fix sysdeps/unix/sysv/linux/sigtimedwait.c.  */
      49  #define __NR_rt_sigtimedwait	__NR_rt_sigtimedwait_time64
      50  /* Fix sysdeps/unix/sysv/linux/semtimedop.c.  */
      51  #define __NR_semtimedop		__NR_semtimedop_time64
      52  /* Hack sysdeps/unix/sysv/linux/generic/utimes.c.  */
      53  #define __NR_utimensat		__NR_utimensat_time64
      54  
      55  #undef SYS_ify
      56  #define SYS_ify(syscall_name)   (__NR_##syscall_name)
      57  
      58  /* Linux uses a negative return value to indicate syscall errors,
      59     unlike most Unices, which use the condition codes' carry flag.
      60  
      61     Since version 2.1 the return value of a system call might be
      62     negative even if the call succeeded.  E.g., the lseek system call
      63     might return a large offset.  Therefore we must not anymore test
      64     for < 0, but test for a real error by making sure the value in R0
      65     is a real error number.  Linus said he will make sure the no syscall
      66     returns a value in -1 .. -4095 as a valid result so we can safely
      67     test with -4095.  */
      68  
      69  #ifdef __ASSEMBLER__
      70  
      71  /* Macros used in syscall-template.S */
      72  #define ret          l.jr r9; l.nop
      73  #define ret_NOERRNO  l.jr r9; l.nop
      74  
      75  #undef	DO_CALL
      76  #define DO_CALL(syscall_name) \
      77    l.addi r11, r0, SYS_ify (syscall_name); \
      78    l.sys 1; \
      79     l.nop
      80  
      81  #undef	PSEUDO
      82  #define PSEUDO(name, syscall_name, args) \
      83    ENTRY (name); \
      84    DO_CALL(syscall_name); \
      85    /* if -4096 < ret < 0 holds, it's an error */ \
      86    l.sfgeui r11, 0xf001; \
      87    l.bf L(pseudo_end); \
      88     l.nop
      89  
      90  #undef	PSEUDO_NOERRNO
      91  #define PSEUDO_NOERRNO(name, syscall_name, args)  \
      92    ENTRY (name);           \
      93    DO_CALL(syscall_name)
      94  
      95  #undef	PSEUDO_END
      96  #define PSEUDO_END(name) \
      97  L(pseudo_end): \
      98    l.j SYSCALL_ERROR_NAME; \
      99    l.ori r3,r11,0; \
     100    END (name)
     101  
     102  #undef	PSEUDO_END_NOERRNO
     103  #define PSEUDO_END_NOERRNO(name) \
     104    END (name)
     105  
     106  #ifndef PIC
     107  /* For static code, on error jump to __syscall_error directly.  */
     108  # define SYSCALL_ERROR_NAME __syscall_error
     109  #elif !IS_IN (libc)
     110  /* Use the internal name for libc shared objects.  */
     111  # define SYSCALL_ERROR_NAME __GI___syscall_error
     112  #else
     113  /* Otherwise, on error do a full PLT jump.  */
     114  # define SYSCALL_ERROR_NAME plt(__syscall_error)
     115  #endif
     116  
     117  #else /* not __ASSEMBLER__ */
     118  
     119  #include <errno.h>
     120  
     121  extern long int __syscall_error (long int neg_errno);
     122  
     123  #undef INTERNAL_SYSCALL
     124  #define INTERNAL_SYSCALL(name, nr, args...) \
     125  	INTERNAL_SYSCALL_NCS (SYS_ify (name), nr, args)
     126  
     127  /* The _NCS variant allows non-constant syscall numbers.  */
     128  #undef INTERNAL_SYSCALL_NCS
     129  #define INTERNAL_SYSCALL_NCS(number, nr, args...) \
     130  	({ unsigned long int __sys_result;				\
     131  	  {								\
     132  	    long int _sc_ret = (long int) number;			\
     133  	    LOAD_ARGS_##nr (args)					\
     134  	    register long int __sc_ret __asm__ ("r11") = _sc_ret;	\
     135  	    __asm__ __volatile__ ("l.sys 1\n\t"				\
     136  				  " l.nop\n\t"				\
     137  				  : "+r" (__sc_ret)			\
     138  				  : ASM_ARGS_##nr			\
     139  				  : ASM_CLOBBERS_##nr			\
     140  				    "r12", "r13", "r15", "r17", "r19",	\
     141  				    "r21", "r23", "r25", "r27", "r29",	\
     142  				    "r31", "memory");			\
     143  	    __sys_result = __sc_ret;					\
     144  	  }								\
     145  	  (long int) __sys_result; })
     146  
     147  /* From here on we have nested macros that generate code for
     148     setting up syscall arguments.  */
     149  
     150  #define LOAD_ARGS_0()
     151  
     152  #define ASM_ARGS_0
     153  #define ASM_CLOBBERS_0  "r3", ASM_CLOBBERS_1
     154  
     155  #define LOAD_ARGS_1(a) \
     156    long int _a = (long int)(a);                             \
     157    register long int __a __asm__ ("r3") = _a;
     158  #define ASM_ARGS_1 "r" (__a)
     159  #define ASM_CLOBBERS_1  "r4", ASM_CLOBBERS_2
     160  
     161  #define LOAD_ARGS_2(a, b) \
     162    long int _b = (long int)(b);                             \
     163    LOAD_ARGS_1 (a)                                          \
     164    register long int __b __asm__ ("r4") = _b;
     165  #define ASM_ARGS_2 ASM_ARGS_1, "r" (__b)
     166  #define ASM_CLOBBERS_2  "r5", ASM_CLOBBERS_3
     167  
     168  #define LOAD_ARGS_3(a, b, c) \
     169    long int _c = (long int)(c);                             \
     170    LOAD_ARGS_2 (a, b)                                       \
     171    register long int __c __asm__ ("r5") = _c;
     172  #define ASM_ARGS_3 ASM_ARGS_2, "r" (__c)
     173  #define ASM_CLOBBERS_3  "r6", ASM_CLOBBERS_4
     174  
     175  #define LOAD_ARGS_4(a, b, c, d) \
     176      LOAD_ARGS_3 (a, b, c)                                  \
     177    long int _d = (long int)(d);                             \
     178    register long int __d __asm__ ("r6") = _d;
     179  #define ASM_ARGS_4 ASM_ARGS_3, "r" (__d)
     180  #define ASM_CLOBBERS_4  "r7", ASM_CLOBBERS_5
     181  
     182  #define LOAD_ARGS_5(a, b, c, d, e) \
     183    long int _e = (long int)(e);                             \
     184    LOAD_ARGS_4 (a, b, c, d)                                 \
     185    register long int __e __asm__ ("r7") = _e;
     186  #define ASM_ARGS_5 ASM_ARGS_4, "r" (__e)
     187  #define ASM_CLOBBERS_5  "r8", ASM_CLOBBERS_6
     188  
     189  #define LOAD_ARGS_6(a, b, c, d, e, f) \
     190    long int _f = (long int)(f);                             \
     191    LOAD_ARGS_5 (a, b, c, d, e)                              \
     192    register long int __f __asm__ ("r8") = _f;
     193  #define ASM_ARGS_6 ASM_ARGS_5, "r" (__f)
     194  #define ASM_CLOBBERS_6
     195  
     196  #endif /* not __ASSEMBLER__ */
     197  
     198  #endif /* linux/or1k/sysdep.h */