diff --git a/libc/src/__support/OSUtil/linux/i386/syscall.h b/libc/src/__support/OSUtil/linux/i386/syscall.h new file mode 100644 index 000000000000000..88d7f2fb2c49fff --- /dev/null +++ b/libc/src/__support/OSUtil/linux/i386/syscall.h @@ -0,0 +1,88 @@ +//===---------- inline implementation of i386 syscalls ------------* C++ *-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_I386_SYSCALL_H +#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_I386_SYSCALL_H + +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LIBC_INLINE long syscall_impl(long num) { + long ret; + LIBC_INLINE_ASM("int $128" : "=a"(ret) : "a"(num) : "memory"); + return ret; +} + +LIBC_INLINE long syscall_impl(long num, long arg1) { + long ret; + LIBC_INLINE_ASM("int $128" : "=a"(ret) : "a"(num), "b"(arg1) : "memory"); + return ret; +} + +LIBC_INLINE long syscall_impl(long num, long arg1, long arg2) { + long ret; + LIBC_INLINE_ASM("int $128" + : "=a"(ret) + : "a"(num), "b"(arg1), "c"(arg2) + : "memory"); + return ret; +} + +LIBC_INLINE long syscall_impl(long num, long arg1, long arg2, long arg3) { + long ret; + LIBC_INLINE_ASM("int $128" + : "=a"(ret) + : "a"(num), "b"(arg1), "c"(arg2), "d"(arg3) + : "memory"); + return ret; +} + +LIBC_INLINE long syscall_impl(long num, long arg1, long arg2, long arg3, + long arg4) { + long ret; + LIBC_INLINE_ASM("int $128" + : "=a"(ret) + : "a"(num), "b"(arg1), "c"(arg2), "d"(arg3), "S"(arg4) + : "memory"); + return ret; +} + +LIBC_INLINE long syscall_impl(long num, long arg1, long arg2, long arg3, + long arg4, long arg5) { + long ret; + LIBC_INLINE_ASM("int $128" + : "=a"(ret) + : "a"(num), "b"(arg1), "c"(arg2), "d"(arg3), "S"(arg4), + "D"(arg5) + : "memory"); + return ret; +} + +LIBC_INLINE long syscall_impl(long num, long arg1, long arg2, long arg3, + long arg4, long arg5, long arg6) { + long ret; + LIBC_INLINE_ASM(R"( + push %[arg6] + push %%ebp + mov 4(%%esp), %%ebp + int $128 + pop %%ebp + add $4, %%esp + )" + : "=a"(ret) + : "a"(num), "b"(arg1), "c"(arg2), "d"(arg3), "S"(arg4), + "D"(arg5), [arg6] "m"(arg6) + : "memory"); + return ret; +} + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_I386_SYSCALL_H diff --git a/libc/src/__support/OSUtil/linux/syscall.h b/libc/src/__support/OSUtil/linux/syscall.h index ad3f6947d0a06a9..24e0fca73c1678e 100644 --- a/libc/src/__support/OSUtil/linux/syscall.h +++ b/libc/src/__support/OSUtil/linux/syscall.h @@ -14,7 +14,9 @@ #include "src/__support/macros/config.h" #include "src/__support/macros/properties/architectures.h" -#ifdef LIBC_TARGET_ARCH_IS_X86_64 +#ifdef LIBC_TARGET_ARCH_IS_X86_32 +#include "i386/syscall.h" +#elif defined(LIBC_TARGET_ARCH_IS_X86_64) #include "x86_64/syscall.h" #elif defined(LIBC_TARGET_ARCH_IS_AARCH64) #include "aarch64/syscall.h"