(root)/
glibc-2.38/
sysdeps/
unix/
sysv/
linux/
nios2/
sysdep.h
       1  /* Assembler macros for Nios II.
       2     Copyright (C) 2000-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_NIOS2_SYSDEP_H
      20  #define _LINUX_NIOS2_SYSDEP_H 1
      21  
      22  #include <sysdeps/unix/sysv/linux/sysdep.h>
      23  #include <sysdeps/unix/sysdep.h>
      24  #include <sysdeps/nios2/sysdep.h>
      25  
      26  /* For RTLD_PRIVATE_ERRNO.  */
      27  #include <dl-sysdep.h>
      28  
      29  #include <tls.h>
      30  
      31  /* For Linux we can use the system call table in the header file
      32          /usr/include/asm/unistd.h
      33     of the kernel.  But these symbols do not follow the SYS_* syntax
      34     so we have to redefine the `SYS_ify' macro here.  */
      35  #undef SYS_ify
      36  #define SYS_ify(syscall_name)   __NR_##syscall_name
      37  
      38  #ifdef __ASSEMBLER__
      39  
      40  #undef SYSCALL_ERROR_LABEL
      41  #define SYSCALL_ERROR_LABEL __local_syscall_error
      42  
      43  #undef PSEUDO
      44  #define PSEUDO(name, syscall_name, args) \
      45    ENTRY (name)                           \
      46      DO_CALL (syscall_name, args)         \
      47      bne r7, zero, SYSCALL_ERROR_LABEL;   \
      48  
      49  #undef PSEUDO_END
      50  #define PSEUDO_END(name) \
      51    SYSCALL_ERROR_HANDLER  \
      52    END (name)
      53  
      54  #undef PSEUDO_NOERRNO
      55  #define PSEUDO_NOERRNO(name, syscall_name, args) \
      56    ENTRY (name)                                   \
      57      DO_CALL (syscall_name, args)
      58  
      59  #undef PSEUDO_END_NOERRNO
      60  #define PSEUDO_END_NOERRNO(name) \
      61    END (name)
      62  
      63  #undef ret_NOERRNO
      64  #define ret_NOERRNO ret
      65  
      66  #undef DO_CALL
      67  #define DO_CALL(syscall_name, args) \
      68      DOARGS_##args                   \
      69      movi r2, SYS_ify(syscall_name);  \
      70      trap;
      71  
      72  #if defined(__PIC__) || defined(PIC)
      73  
      74  # if RTLD_PRIVATE_ERRNO
      75  
      76  #  define SYSCALL_ERROR_HANDLER			\
      77    SYSCALL_ERROR_LABEL:				\
      78    nextpc r3;					\
      79  1:						\
      80    movhi r8, %hiadj(rtld_errno - 1b);		\
      81    addi r8, r8, %lo(rtld_errno - 1b);		\
      82    add r3, r3, r8;				\
      83    stw r2, 0(r3);				\
      84    movi r2, -1;					\
      85    ret;
      86  
      87  # else
      88  
      89  #  if IS_IN (libc)
      90  #   define SYSCALL_ERROR_ERRNO __libc_errno
      91  #  else
      92  #   define SYSCALL_ERROR_ERRNO errno
      93  #  endif
      94  #  define SYSCALL_ERROR_HANDLER			\
      95    SYSCALL_ERROR_LABEL:				\
      96    nextpc r3;					\
      97  1:						\
      98    movhi r8, %hiadj(_gp_got - 1b);		\
      99    addi r8, r8, %lo(_gp_got - 1b);		\
     100    add r3, r3, r8;				\
     101    ldw r3, %tls_ie(SYSCALL_ERROR_ERRNO)(r3);	\
     102    add r3, r23, r3;				\
     103    stw r2, 0(r3);				\
     104    movi r2, -1;					\
     105    ret;
     106  
     107  # endif
     108  
     109  #else
     110  
     111  /* We can use a single error handler in the static library.  */
     112  #define SYSCALL_ERROR_HANDLER			\
     113    SYSCALL_ERROR_LABEL:				\
     114    jmpi __syscall_error;
     115  
     116  #endif
     117  
     118  #define DOARGS_0 /* nothing */
     119  #define DOARGS_1 /* nothing */
     120  #define DOARGS_2 /* nothing */
     121  #define DOARGS_3 /* nothing */
     122  #define DOARGS_4 /* nothing */
     123  #define DOARGS_5 ldw r8, 0(sp);
     124  #define DOARGS_6 ldw r9, 4(sp); ldw r8, 0(sp);
     125  
     126  /* The function has to return the error code.  */
     127  #undef  PSEUDO_ERRVAL
     128  #define PSEUDO_ERRVAL(name, syscall_name, args) \
     129    ENTRY (name)                                  \
     130      DO_CALL (syscall_name, args)
     131  
     132  #undef  PSEUDO_END_ERRVAL
     133  #define PSEUDO_END_ERRVAL(name) \
     134    END (name)
     135  
     136  #define ret_ERRVAL ret
     137  
     138  #else /* __ASSEMBLER__ */
     139  
     140  /* In order to get __set_errno() definition in INLINE_SYSCALL.  */
     141  #include <errno.h>
     142  
     143  #undef INTERNAL_SYSCALL_RAW
     144  #define INTERNAL_SYSCALL_RAW(name, nr, args...)                 \
     145    ({ unsigned int _sys_result;                                  \
     146       {                                                          \
     147         /* Load argument values in temporary variables
     148  	  to perform side effects like function calls
     149  	  before the call-used registers are set.  */		\
     150         LOAD_ARGS_##nr (args)					\
     151         LOAD_REGS_##nr						\
     152         register int _r2 asm ("r2") = (int)(name);               \
     153         register int _err asm ("r7");                            \
     154         asm volatile ("trap"                                     \
     155                       : "+r" (_r2), "=r" (_err)                  \
     156                       : ASM_ARGS_##nr				\
     157                       : __SYSCALL_CLOBBERS);                     \
     158         _sys_result = _err != 0 ? -_r2 : _r2;                    \
     159       }                                                          \
     160       (int) _sys_result; })
     161  
     162  #undef INTERNAL_SYSCALL
     163  #define INTERNAL_SYSCALL(name, nr, args...) \
     164  	INTERNAL_SYSCALL_RAW(SYS_ify(name), nr, args)
     165  
     166  #undef INTERNAL_SYSCALL_NCS
     167  #define INTERNAL_SYSCALL_NCS(number, nr, args...) \
     168  	INTERNAL_SYSCALL_RAW(number, nr, args)
     169  
     170  #define LOAD_ARGS_0()
     171  #define LOAD_REGS_0
     172  #define ASM_ARGS_0
     173  #define LOAD_ARGS_1(a1)				\
     174    LOAD_ARGS_0 ()				\
     175    int __arg1 = (int) (a1);
     176  #define LOAD_REGS_1				\
     177    register int _r4 asm ("r4") = __arg1;		\
     178    LOAD_REGS_0
     179  #define ASM_ARGS_1                  "r" (_r4)
     180  #define LOAD_ARGS_2(a1, a2)			\
     181    LOAD_ARGS_1 (a1)				\
     182    int __arg2 = (int) (a2);
     183  #define LOAD_REGS_2				\
     184    register int _r5 asm ("r5") = __arg2;		\
     185    LOAD_REGS_1
     186  #define ASM_ARGS_2      ASM_ARGS_1, "r" (_r5)
     187  #define LOAD_ARGS_3(a1, a2, a3)			\
     188    LOAD_ARGS_2 (a1, a2)				\
     189    int __arg3 = (int) (a3);
     190  #define LOAD_REGS_3				\
     191    register int _r6 asm ("r6") = __arg3;		\
     192    LOAD_REGS_2
     193  #define ASM_ARGS_3      ASM_ARGS_2, "r" (_r6)
     194  #define LOAD_ARGS_4(a1, a2, a3, a4)		\
     195    LOAD_ARGS_3 (a1, a2, a3)			\
     196    int __arg4 = (int) (a4);
     197  #define LOAD_REGS_4				\
     198    register int _r7 asm ("r7") = __arg4;		\
     199    LOAD_REGS_3
     200  #define ASM_ARGS_4      ASM_ARGS_3, "r" (_r7)
     201  #define LOAD_ARGS_5(a1, a2, a3, a4, a5)		\
     202    LOAD_ARGS_4 (a1, a2, a3, a4)			\
     203    int __arg5 = (int) (a5);
     204  #define LOAD_REGS_5				\
     205    register int _r8 asm ("r8") = __arg5;		\
     206    LOAD_REGS_4
     207  #define ASM_ARGS_5      ASM_ARGS_4, "r" (_r8)
     208  #define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6)	\
     209    LOAD_ARGS_5 (a1, a2, a3, a4, a5)		\
     210    int __arg6 = (int) (a6);
     211  #define LOAD_REGS_6			    \
     212    register int _r9 asm ("r9") = __arg6;     \
     213    LOAD_REGS_5
     214  #define ASM_ARGS_6      ASM_ARGS_5, "r" (_r9)
     215  
     216  #define __SYSCALL_CLOBBERS "memory"
     217  
     218  #undef HAVE_INTERNAL_BRK_ADDR_SYMBOL
     219  #define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1
     220  
     221  #endif /* __ASSEMBLER__ */
     222  
     223  #endif /* linux/nios2/sysdep.h */