yuezonghe | 824eb0c | 2024-06-27 02:32:26 -0700 | [diff] [blame^] | 1 | /* |
| 2 | * libc/sysdeps/linux/v850/syscall.c -- generic syscall function for linux/v850 |
| 3 | * |
| 4 | * Copyright (C) 2002 NEC Corporation |
| 5 | * Copyright (C) 2002 Miles Bader <miles@gnu.org> |
| 6 | * |
| 7 | * This file is subject to the terms and conditions of the GNU Lesser |
| 8 | * General Public License. See the file COPYING.LIB in the main |
| 9 | * directory of this archive for more details. |
| 10 | * |
| 11 | * Written by Miles Bader <miles@gnu.org> |
| 12 | */ |
| 13 | |
| 14 | #include <errno.h> |
| 15 | #include <sys/syscall.h> |
| 16 | |
| 17 | typedef unsigned long arg_t; |
| 18 | |
| 19 | /* Invoke `system call' NUM, passing it the remaining arguments. |
| 20 | This is completely system-dependent, and not often useful. */ |
| 21 | long |
| 22 | syscall (long num, arg_t a1, arg_t a2, arg_t a3, arg_t a4, arg_t a5, arg_t a6) |
| 23 | { |
| 24 | /* We don't know how many arguments are valid, so A5 and A6 are fetched |
| 25 | off the stack even for (the majority of) system calls with fewer |
| 26 | arguments; hopefully this won't cause any problems. A1-A4 are in |
| 27 | registers, so they're OK. */ |
| 28 | register arg_t a __asm__ (SYSCALL_ARG0) = a1; |
| 29 | register arg_t b __asm__ (SYSCALL_ARG1) = a2; |
| 30 | register arg_t c __asm__ (SYSCALL_ARG2) = a3; |
| 31 | register arg_t d __asm__ (SYSCALL_ARG3) = a4; |
| 32 | register arg_t e __asm__ (SYSCALL_ARG4) = a5; |
| 33 | register arg_t f __asm__ (SYSCALL_ARG5) = a6; |
| 34 | register unsigned long syscall __asm__ (SYSCALL_NUM) = num; |
| 35 | register unsigned long ret __asm__ (SYSCALL_RET); |
| 36 | |
| 37 | __asm__ ("trap " SYSCALL_LONG_TRAP |
| 38 | : "=r" (ret) |
| 39 | : "r" (syscall), "r" (a), "r" (b), "r" (c), "r" (d), "r" (e), "r" (f) |
| 40 | : SYSCALL_CLOBBERS); |
| 41 | |
| 42 | __syscall_return (long, ret); |
| 43 | } |