1 //===--------- inline implementation of riscv syscalls ------------* C++ *-===// 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 #ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_RISCV_SYSCALL_H 10 #define LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_RISCV_SYSCALL_H 11 12 #include "src/__support/common.h" 13 #include "src/__support/macros/config.h" 14 15 #define REGISTER_DECL_0 \ 16 register long a7 __asm__("a7") = number; \ 17 register long a0 __asm__("a0"); 18 #define REGISTER_DECL_1 \ 19 register long a7 __asm__("a7") = number; \ 20 register long a0 __asm__("a0") = arg1; 21 #define REGISTER_DECL_2 REGISTER_DECL_1 register long a1 __asm__("a1") = arg2; 22 #define REGISTER_DECL_3 \ 23 REGISTER_DECL_2 \ 24 register long a2 __asm__("a2") = arg3; 25 #define REGISTER_DECL_4 \ 26 REGISTER_DECL_3 \ 27 register long a3 __asm__("a3") = arg4; 28 #define REGISTER_DECL_5 \ 29 REGISTER_DECL_4 \ 30 register long a4 __asm__("a4") = arg5; 31 #define REGISTER_DECL_6 \ 32 REGISTER_DECL_5 \ 33 register long a5 __asm__("a5") = arg6; 34 35 #define REGISTER_CONSTRAINT_0 "r"(a7) 36 #define REGISTER_CONSTRAINT_1 REGISTER_CONSTRAINT_0, "r"(a0) 37 #define REGISTER_CONSTRAINT_2 REGISTER_CONSTRAINT_1, "r"(a1) 38 #define REGISTER_CONSTRAINT_3 REGISTER_CONSTRAINT_2, "r"(a2) 39 #define REGISTER_CONSTRAINT_4 REGISTER_CONSTRAINT_3, "r"(a3) 40 #define REGISTER_CONSTRAINT_5 REGISTER_CONSTRAINT_4, "r"(a4) 41 #define REGISTER_CONSTRAINT_6 REGISTER_CONSTRAINT_5, "r"(a5) 42 43 #define SYSCALL_INSTR(input_constraint) \ 44 LIBC_INLINE_ASM("ecall\n\t" : "=r"(a0) : input_constraint : "memory") 45 46 namespace LIBC_NAMESPACE_DECL { 47 48 LIBC_INLINE long syscall_impl(long number) { 49 REGISTER_DECL_0; 50 SYSCALL_INSTR(REGISTER_CONSTRAINT_0); 51 return a0; 52 } 53 54 LIBC_INLINE long syscall_impl(long number, long arg1) { 55 REGISTER_DECL_1; 56 SYSCALL_INSTR(REGISTER_CONSTRAINT_1); 57 return a0; 58 } 59 60 LIBC_INLINE long syscall_impl(long number, long arg1, long arg2) { 61 REGISTER_DECL_2; 62 SYSCALL_INSTR(REGISTER_CONSTRAINT_2); 63 return a0; 64 } 65 66 LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3) { 67 REGISTER_DECL_3; 68 SYSCALL_INSTR(REGISTER_CONSTRAINT_3); 69 return a0; 70 } 71 72 LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3, 73 long arg4) { 74 REGISTER_DECL_4; 75 SYSCALL_INSTR(REGISTER_CONSTRAINT_4); 76 return a0; 77 } 78 79 LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3, 80 long arg4, long arg5) { 81 REGISTER_DECL_5; 82 SYSCALL_INSTR(REGISTER_CONSTRAINT_5); 83 return a0; 84 } 85 86 LIBC_INLINE long syscall_impl(long number, long arg1, long arg2, long arg3, 87 long arg4, long arg5, long arg6) { 88 REGISTER_DECL_6; 89 SYSCALL_INSTR(REGISTER_CONSTRAINT_6); 90 return a0; 91 } 92 93 } // namespace LIBC_NAMESPACE_DECL 94 95 #undef REGISTER_DECL_0 96 #undef REGISTER_DECL_1 97 #undef REGISTER_DECL_2 98 #undef REGISTER_DECL_3 99 #undef REGISTER_DECL_4 100 #undef REGISTER_DECL_5 101 #undef REGISTER_DECL_6 102 103 #undef REGISTER_CONSTRAINT_0 104 #undef REGISTER_CONSTRAINT_1 105 #undef REGISTER_CONSTRAINT_2 106 #undef REGISTER_CONSTRAINT_3 107 #undef REGISTER_CONSTRAINT_4 108 #undef REGISTER_CONSTRAINT_5 109 #undef REGISTER_CONSTRAINT_6 110 111 #endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_RISCV_SYSCALL_H 112