1//===------------ inline implementation of x86_64 syscalls ----------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9%%begin() 10 11#include "src/__support/common.h" 12 13#define SYSCALL_CLOBBER_LIST "rcx", "r11", "memory" 14 15namespace __llvm_libc { 16 17__attribute__((always_inline)) inline long syscall(long __number) { 18 long retcode; 19 LIBC_INLINE_ASM("syscall" 20 : "=a"(retcode) 21 : "a"(__number) 22 : SYSCALL_CLOBBER_LIST); 23 return retcode; 24} 25 26__attribute__((always_inline)) inline long syscall(long __number, long __arg1) { 27 long retcode; 28 LIBC_INLINE_ASM("syscall" 29 : "=a"(retcode) 30 : "a"(__number), "D"(__arg1) 31 : SYSCALL_CLOBBER_LIST); 32 return retcode; 33} 34 35__attribute__((always_inline)) inline long syscall(long __number, long __arg1, 36 long __arg2) { 37 long retcode; 38 LIBC_INLINE_ASM("syscall" 39 : "=a"(retcode) 40 : "a"(__number), "D"(__arg1), "S"(__arg2) 41 : SYSCALL_CLOBBER_LIST); 42 return retcode; 43} 44 45__attribute__((always_inline)) inline long syscall(long __number, long __arg1, 46 long __arg2, long __arg3) { 47 long retcode; 48 LIBC_INLINE_ASM("syscall" 49 : "=a"(retcode) 50 : "a"(__number), "D"(__arg1), "S"(__arg2), "d"(__arg3) 51 : SYSCALL_CLOBBER_LIST); 52 return retcode; 53} 54 55__attribute__((always_inline)) inline long 56syscall(long __number, long __arg1, long __arg2, long __arg3, long __arg4) { 57 long retcode; 58 register long r10 __asm__("r10") = __arg4; 59 LIBC_INLINE_ASM("syscall" 60 : "=a"(retcode) 61 : "a"(__number), "D"(__arg1), "S"(__arg2), "d"(__arg3), 62 "r"(r10) 63 : SYSCALL_CLOBBER_LIST); 64 return retcode; 65} 66 67__attribute__((always_inline)) inline long syscall(long __number, long __arg1, 68 long __arg2, long __arg3, 69 long __arg4, long __arg5) { 70 long retcode; 71 register long r10 __asm__("r10") = __arg4; 72 register long r8 __asm__("r8") = __arg5; 73 LIBC_INLINE_ASM("syscall" 74 : "=a"(retcode) 75 : "a"(__number), "D"(__arg1), "S"(__arg2), "d"(__arg3), 76 "r"(r10), "r"(r8) 77 : SYSCALL_CLOBBER_LIST); 78 return retcode; 79} 80 81__attribute__((always_inline)) inline long syscall(long __number, long __arg1, 82 long __arg2, long __arg3, 83 long __arg4, long __arg5, 84 long __arg6) { 85 long retcode; 86 register long r10 __asm__("r10") = __arg4; 87 register long r8 __asm__("r8") = __arg5; 88 register long r9 __asm__("r9") = __arg6; 89 LIBC_INLINE_ASM("syscall" 90 : "=a"(retcode) 91 : "a"(__number), "D"(__arg1), "S"(__arg2), "d"(__arg3), 92 "r"(r10), "r"(r8), "r"(r9) 93 : SYSCALL_CLOBBER_LIST); 94 return retcode; 95} 96 97template <typename... Ts> 98__attribute__((always_inline)) inline long syscall(long __number, Ts... ts) { 99 static_assert(sizeof...(Ts) <= 6, "Too many arguments for syscall"); 100 return syscall(__number, (long)ts...); 101} 102 103 104#undef SYSCALL_CLOBBER_LIST 105 106} // namespace __llvm_libc 107